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:
- ctx: Packet to be processed
- 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:
pcn_csum_diff(): wrapper of BPF_FUNC_csum_diff
Note: For XDP cubes and kernels version prior to 4.16 this function supports only 4 bytes arguments.
pcn_l3_csum_replace(): wrapper of BPF_FUNC_l3_csum_replace
pcn_l4_csum_replace(): wrapper of BPF_FUNC_l4_csum_replace
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.