Writing the eBPF datapath

eBPF is an extension of the traditional Berkeley Packet Filter. The Polycube architecture leverages the software abstraction provided by BCC, which is further extended in this project particular with respect to eBPF features that are useful for networking services. In order to get more information about how to use the maps in BCC please read the BCC reference guide, additionally there is a list of the available eBPF helpers.

Polycube architecture adds a wrapper around the user’s code, this wrapper calls the handle_rx function with the following parameters:

  1. ctx: Packet to be processed
  2. md: packet’s metadata:
  • in_port: integer that identifies the ingress port of the packet.

polycube provides a set of functions to handle the packets, the return value of the handle_rx function should be the result of calling one of these functions.

  • pcn_pkt_redirect(struct __sk_buff *skb, struct pkt_metadata *md, u16 port);: sends the packet through an the ifc port. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L86)
  • pcn_pkt_drop(struct __sk_buff *skb, struct pkt_metadata *md);: drops the packet. It is the same that just returning RX_DROP. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L78)
  • pcn_pkt_redirect_ns(struct __sk_buff *skb, struct pkt_metadata *md, u16 port): (it is only available for shadow services) sends the packet to the namespace as if it came from the port indicated as parameter

Processing packets in the slowpath

A copy of the packet can be sent to the controller to be processed by the slowpath using the following helpers:

  • pcn_pkt_controller(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason): sends a copy of the packet to the controller. Reason can be used to indicate why the packet is being sent to the custom code running in the control path. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L82)
  • pcn_pkt_controller_with_metadata(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason, u32 metadata[3]): sends a copy of the packet to the custom code running in the control path. In addition to the reason the user can also send some additional metadata.

The packet will be processed by the packet_in method of the controller.

Checksum calculation

The L3 (IP) and L4 (TCP, UDP) checksums has to be updated when fields in the packets are changed. polycube provides a set of wrappers of the eBPF helpers to do it:

Services as nat and nat show how to use these functions.

Vlan Support

The vlan handling in TC and XDP eBPF programs is a little bit different, so polycube includes a set of helpers to uniform this accross.

  • bool pcn_is_vlan_present(struct CTXTYPE* pkt)
  • int pcn_get_vlan_id(struct CTXTYPE* pkt, uint16_t* vlan_id, uint16_t* eth_proto);
  • uint8_t pcn_vlan_pop_tag(struct CTXTYPE* pkt);
  • uint8_t pcn_vlan_push_tag(struct CTXTYPE* pkt, u16 eth_proto, u32 vlan_id);

Known limitations:

  • It is not possible to send a packet through multiple ports, then multicast, broadcast of any similar functionality has to be implemented in the control path.

TODO:

  • Document support for multiple eBPF programs

Debugging the data plane

See how to debug by logging in the dataplane.