History

bpf: Provide helper to do forwarding lookups in kernel FIB table

Provide a helper for doing a FIB and neighbor lookup in the kernel tables from an XDP program. The helper provides a fastpath for forwarding packets. If the packet is a local delivery or for any reason is not a simple lookup and forward, the packet continues up the stack. If it is to be forwarded, the forwarding can be done directly if the neighbor is already known. If the neighbor does not exist, the first few packets go up the stack for neighbor resolution. Once resolved, the xdp program provides the fast path. On successful lookup the nexthop dmac, current device smac and egress device index are returned. The API supports IPv4, IPv6 and MPLS protocols, but only IPv4 and IPv6 are implemented in this patch. The API includes layer 4 parameters if the XDP program chooses to do deep packet inspection to allow compare against ACLs implemented as FIB rules. Header rewrite is left to the XDP program. The lookup takes 2 flags: - BPF_FIB_LOOKUP_DIRECT to do a lookup that bypasses FIB rules and goes straight to the table associated with the device (expert setting for those looking to maximize throughput) - BPF_FIB_LOOKUP_OUTPUT to do a lookup from the egress perspective. Default is an ingress lookup. Initial performance numbers collected by Jesper, forwarded packets/sec: Full stack XDP FIB lookup XDP Direct lookup IPv4 1,947,969 7,074,156 7,415,333 IPv6 1,728,000 6,165,504 7,262,720 These number are single CPU core forwarding on a Broadwell E5-1650 v4 @ 3.60GHz.

David Ahern committed 8 years ago

Commit 87f5fc71 parent 65a20222 files · +347 −1Browse files

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

Unified · Split

include/uapi/linux/bpf.h+80−1
@@ -1828,6 +1828,33 @@ union bpf_attr { · 1827 unmodified lines
1828 * Return1828 * Return
1829 * 0 on success, or a negative error in case of failure.1829 * 0 on success, or a negative error in case of failure.
1830 *1830 *
1831 *
1832 * int bpf_fib_lookup(void *ctx, struct bpf_fib_lookup *params, int plen, u32 flags)
1833 * Description
1834 * Do FIB lookup in kernel tables using parameters in *params*.
1835 * If lookup is successful and result shows packet is to be
1836 * forwarded, the neighbor tables are searched for the nexthop.
1837 * If successful (ie., FIB lookup shows forwarding and nexthop
1838 * is resolved), the nexthop address is returned in ipv4_dst,
1839 * ipv6_dst or mpls_out based on family, smac is set to mac
1840 * address of egress device, dmac is set to nexthop mac address,
1841 * rt_metric is set to metric from route.
1842 *
1843 * *plen* argument is the size of the passed in struct.
1844 * *flags* argument can be one or more BPF_FIB_LOOKUP_ flags:
1845 *
1846 * **BPF_FIB_LOOKUP_DIRECT** means do a direct table lookup vs
1847 * full lookup using FIB rules
1848 * **BPF_FIB_LOOKUP_OUTPUT** means do lookup from an egress
1849 * perspective (default is ingress)
1850 *
1851 * *ctx* is either **struct xdp_md** for XDP programs or
1852 * **struct sk_buff** tc cls_act programs.
1853 *
1854 * Return
1855 * Egress device index on success, 0 if packet needs to continue
1856 * up the stack for further processing or a negative error in case
1857 * of failure.
1831 */1858 */
1832#define __BPF_FUNC_MAPPER(FN) \1859#define __BPF_FUNC_MAPPER(FN) \
1833 FN(unspec), \1860 FN(unspec), \
@@ -1898,7 +1925,8 @@ union bpf_attr { · 64 unmodified lines
1898 FN(xdp_adjust_tail), \1925 FN(xdp_adjust_tail), \
1899 FN(skb_get_xfrm_state), \1926 FN(skb_get_xfrm_state), \
1900 FN(get_stack), \1927 FN(get_stack), \
1901 FN(skb_load_bytes_relative),1928 FN(skb_load_bytes_relative), \
1929 FN(fib_lookup),
1902 1930
1903/* integer value in 'imm' field of BPF_CALL instruction selects which helper1931/* integer value in 'imm' field of BPF_CALL instruction selects which helper
1904 * function eBPF program intends to call1932 * function eBPF program intends to call
@@ -2321,4 +2349,55 @@ struct bpf_raw_tracepoint_args { · 416 unmodified lines
2321 __u64 args[0];2349 __u64 args[0];
2322};2350};
2323 2351
2352/* DIRECT: Skip the FIB rules and go to FIB table associated with device
2353 * OUTPUT: Do lookup from egress perspective; default is ingress
2354 */
2355#define BPF_FIB_LOOKUP_DIRECT BIT(0)
2356#define BPF_FIB_LOOKUP_OUTPUT BIT(1)
2357
2358struct bpf_fib_lookup {
2359 /* input */
2360 __u8 family; /* network family, AF_INET, AF_INET6, AF_MPLS */
2361
2362 /* set if lookup is to consider L4 data - e.g., FIB rules */
2363 __u8 l4_protocol;
2364 __be16 sport;
2365 __be16 dport;
2366
2367 /* total length of packet from network header - used for MTU check */
2368 __u16 tot_len;
2369 __u32 ifindex; /* L3 device index for lookup */
2370
2371 union {
2372 /* inputs to lookup */
2373 __u8 tos; /* AF_INET */
2374 __be32 flowlabel; /* AF_INET6 */
2375
2376 /* output: metric of fib result */
2377 __u32 rt_metric;
2378 };
2379
2380 union {
2381 __be32 mpls_in;
2382 __be32 ipv4_src;
2383 __u32 ipv6_src[4]; /* in6_addr; network order */
2384 };
2385
2386 /* input to bpf_fib_lookup, *dst is destination address.
2387 * output: bpf_fib_lookup sets to gateway address
2388 */
2389 union {
2390 /* return for MPLS lookups */
2391 __be32 mpls_out[4]; /* support up to 4 labels */
2392 __be32 ipv4_dst;
2393 __u32 ipv6_dst[4]; /* in6_addr; network order */
2394 };
2395
2396 /* output */
2397 __be16 h_vlan_proto;
2398 __be16 h_vlan_TCI;
2399 __u8 smac[6]; /* ETH_ALEN */
2400 __u8 dmac[6]; /* ETH_ALEN */
2401};
2402
2324#endif /* _UAPI__LINUX_BPF_H__ */2403#endif /* _UAPI__LINUX_BPF_H__ */