History

netkit, bpf: Add bpf programmable net device

This work adds a new, minimal BPF-programmable device called "netkit" (former PoC code-name "meta") we recently presented at LSF/MM/BPF. The core idea is that BPF programs are executed within the drivers xmit routine and therefore e.g. in case of containers/Pods moving BPF processing closer to the source. One of the goals was that in case of Pod egress traffic, this allows to move BPF programs from hostns tcx ingress into the device itself, providing earlier drop or forward mechanisms, for example, if the BPF program determines that the skb must be sent out of the node, then a redirect to the physical device can take place directly without going through per-CPU backlog queue. This helps to shift processing for such traffic from softirq to process context, leading to better scheduling decisions/performance (see measurements in the slides). In this initial version, the netkit device ships as a pair, but we plan to extend this further so it can also operate in single device mode. The pair comes with a primary and a peer device. Only the primary device, typically residing in hostns, can manage BPF programs for itself and its peer. The peer device is designated for containers/Pods and cannot attach/detach BPF programs. Upon the device creation, the user can set the default policy to 'pass' or 'drop' for the case when no BPF program is attached. Additionally, the device can be operated in L3 (default) or L2 mode. The management of BPF programs is done via bpf_mprog, so that multi-attach is supported right from the beginning with similar API and dependency controls as tcx. For details on the latter see commit 053c8e1f235d ("bpf: Add generic attach/detach/query API for multi-progs"). tc BPF compatibility is provided, so that existing programs can be easily migrated. Going forward, we plan to use netkit devices in Cilium as the main device type for connecting Pods. They will be operated in L3 mode in order to simplify a Pod's neighbor management and the peer will operate in default drop mode, so that no traffic is leaving between the time when a Pod is brought up by the CNI plugin and programs attached by the agent. Additionally, the programs we attach via tcx on the physical devices are using bpf_redirect_peer() for inbound traffic into netkit device, hence the latter is also supporting the ndo_get_peer_dev callback. Similarly, we use bpf_redirect_neigh() for the way out, pushing from netkit peer to phys device directly. Also, BIG TCP is supported on netkit device. For the follow-up work in single device mode, we plan to convert Cilium's cilium_host/_net devices into a single one. An extensive test suite for checking device operations and the BPF program and link management API comes as BPF selftests in this series.

Daniel Borkmann committed 3 years ago

Commit 35dfaad1 parent 42d31dd9 files · +1074 −5Browse files

Showing the changes to include/uapi (2 of 9 files). Show all

Unified · Split

2 files
  1. include/uapi/linux/bpf.h +14 −0
  2. include/uapi/linux/if_link.h +24 −0
include/uapi/linux/bpf.h+14−0
@@ -1052,6 +1052,8 @@ enum bpf_attach_type { · 1051 unmodified lines
10521052 BPF_CGROUP_UNIX_RECVMSG,
10531053 BPF_CGROUP_UNIX_GETPEERNAME,
10541054 BPF_CGROUP_UNIX_GETSOCKNAME,
1055+ BPF_NETKIT_PRIMARY,
1056+ BPF_NETKIT_PEER,
10551057 __MAX_BPF_ATTACH_TYPE
10561058 };
10571059
@@ -1071,6 +1073,7 @@ enum bpf_link_type { · 13 unmodified lines
10711073 BPF_LINK_TYPE_NETFILTER = 10,
10721074 BPF_LINK_TYPE_TCX = 11,
10731075 BPF_LINK_TYPE_UPROBE_MULTI = 12,
1076+ BPF_LINK_TYPE_NETKIT = 13,
10741077 MAX_BPF_LINK_TYPE,
10751078 };
10761079
@@ -1656,6 +1659,13 @@ union bpf_attr { · 579 unmodified lines
16561659 __u32 flags;
16571660 __u32 pid;
16581661 } uprobe_multi;
1662+ struct {
1663+ union {
1664+ __u32 relative_fd;
1665+ __u32 relative_id;
1666+ };
1667+ __u64 expected_revision;
1668+ } netkit;
16591669 };
16601670 } link_create;
16611671
@@ -6576,6 +6586,10 @@ struct bpf_link_info { · 4914 unmodified lines
65766586 __u32 ifindex;
65776587 __u32 attach_type;
65786588 } tcx;
6589+ struct {
6590+ __u32 ifindex;
6591+ __u32 attach_type;
6592+ } netkit;
65796593 };
65806594 } __attribute__((aligned(8)));
65816595
include/uapi/linux/if_link.h+24−0
@@ -756,6 +756,30 @@ struct tunnel_msg { · 755 unmodified lines
756756 __u32 ifindex;
757757 };
758758
759+/* netkit section */
760+enum netkit_action {
761+ NETKIT_NEXT = -1,
762+ NETKIT_PASS = 0,
763+ NETKIT_DROP = 2,
764+ NETKIT_REDIRECT = 7,
765+};
766+
767+enum netkit_mode {
768+ NETKIT_L2,
769+ NETKIT_L3,
770+};
771+
772+enum {
773+ IFLA_NETKIT_UNSPEC,
774+ IFLA_NETKIT_PEER_INFO,
775+ IFLA_NETKIT_PRIMARY,
776+ IFLA_NETKIT_POLICY,
777+ IFLA_NETKIT_PEER_POLICY,
778+ IFLA_NETKIT_MODE,
779+ __IFLA_NETKIT_MAX,
780+};
781+#define IFLA_NETKIT_MAX (__IFLA_NETKIT_MAX - 1)
782+
759783 /* VXLAN section */
760784
761785 /* include statistics in the dump */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t