History

bpf: Derive source IP addr via bpf_*_fib_lookup()

Extend the bpf_fib_lookup() helper by making it to return the source IPv4/IPv6 address if the BPF_FIB_LOOKUP_SRC flag is set. For example, the following snippet can be used to derive the desired source IP address: struct bpf_fib_lookup p = { .ipv4_dst = ip4->daddr }; ret = bpf_skb_fib_lookup(skb, p, sizeof(p), BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH); if (ret != BPF_FIB_LKUP_RET_SUCCESS) return TC_ACT_SHOT; /* the p.ipv4_src now contains the source address */ The inability to derive the proper source address may cause malfunctions in BPF-based dataplanes for hosts containing netdevs with more than one routable IP address or for multi-homed hosts. For example, Cilium implements packet masquerading in BPF. If an egressing netdev to which the Cilium's BPF prog is attached has multiple IP addresses, then only one [hardcoded] IP address can be used for masquerading. This breaks connectivity if any other IP address should have been selected instead, for example, when a public and private addresses are attached to the same egress interface. The change was tested with Cilium [1]. Nikolay Aleksandrov helped to figure out the IPv6 addr selection. [1]: https://github.com/cilium/cilium/pull/28283

Martynas Pumputis committed 3 years ago

Commit dab4e1f1 parent 1be84ca5 files · +43 −1Browse files

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

Unified · Split

include/uapi/linux/bpf.h+10−0
@@ -3264,6 +3264,11 @@ union bpf_attr { · 3263 unmodified lines
3264 * and *params*->smac will not be set as output. A common3264 * and *params*->smac will not be set as output. A common
3265 * use case is to call **bpf_redirect_neigh**\ () after3265 * use case is to call **bpf_redirect_neigh**\ () after
3266 * doing **bpf_fib_lookup**\ ().3266 * doing **bpf_fib_lookup**\ ().
3267 * **BPF_FIB_LOOKUP_SRC**
3268 * Derive and set source IP addr in *params*->ipv{4,6}_src
3269 * for the nexthop. If the src addr cannot be derived,
3270 * **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
3271 * case, *params*->dmac and *params*->smac are not set either.
3267 *3272 *
3268 * *ctx* is either **struct xdp_md** for XDP programs or3273 * *ctx* is either **struct xdp_md** for XDP programs or
3269 * **struct sk_buff** tc cls_act programs.3274 * **struct sk_buff** tc cls_act programs.
@@ -6964,6 +6969,7 @@ enum { · 3694 unmodified lines
6964 BPF_FIB_LOOKUP_OUTPUT = (1U << 1),6969 BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
6965 BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),6970 BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
6966 BPF_FIB_LOOKUP_TBID = (1U << 3),6971 BPF_FIB_LOOKUP_TBID = (1U << 3),
6972 BPF_FIB_LOOKUP_SRC = (1U << 4),
6967};6973};
6968 6974
6969enum {6975enum {
@@ -6976,6 +6982,7 @@ enum { · 6 unmodified lines
6976 BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */6982 BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */
6977 BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */6983 BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */
6978 BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */6984 BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */
6985 BPF_FIB_LKUP_RET_NO_SRC_ADDR, /* failed to derive IP src addr */
6979};6986};
6980 6987
6981struct bpf_fib_lookup {6988struct bpf_fib_lookup {
@@ -7010,6 +7017,9 @@ struct bpf_fib_lookup { · 28 unmodified lines
7010 __u32 rt_metric;7017 __u32 rt_metric;
7011 };7018 };
7012 7019
7020 /* input: source address to consider for lookup
7021 * output: source address result from lookup
7022 */
7013 union {7023 union {
7014 __be32 ipv4_src;7024 __be32 ipv4_src;
7015 __u32 ipv6_src[4]; /* in6_addr; network order */7025 __u32 ipv6_src[4]; /* in6_addr; network order */

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