Skip to content

Commit 31de410

Browse files
Martin KaFai Lauborkmann
authored andcommitted
bpf: Add BPF_FIB_LOOKUP_SKIP_NEIGH for bpf_fib_lookup
The bpf_fib_lookup() also looks up the neigh table. This was done before bpf_redirect_neigh() was added. In the use case that does not manage the neigh table and requires bpf_fib_lookup() to lookup a fib to decide if it needs to redirect or not, the bpf prog can depend only on using bpf_redirect_neigh() to lookup the neigh. It also keeps the neigh entries fresh and connected. This patch adds a bpf_fib_lookup flag, SKIP_NEIGH, to avoid the double neigh lookup when the bpf prog always call bpf_redirect_neigh() to do the neigh lookup. The params->smac output is skipped together when SKIP_NEIGH is set because bpf_redirect_neigh() will figure out the smac also. Signed-off-by: Martin KaFai Lau <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 49b5e77 commit 31de410

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

include/uapi/linux/bpf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,11 @@ union bpf_attr {
31343134
* **BPF_FIB_LOOKUP_OUTPUT**
31353135
* Perform lookup from an egress perspective (default is
31363136
* ingress).
3137+
* **BPF_FIB_LOOKUP_SKIP_NEIGH**
3138+
* Skip the neighbour table lookup. *params*->dmac
3139+
* and *params*->smac will not be set as output. A common
3140+
* use case is to call **bpf_redirect_neigh**\ () after
3141+
* doing **bpf_fib_lookup**\ ().
31373142
*
31383143
* *ctx* is either **struct xdp_md** for XDP programs or
31393144
* **struct sk_buff** tc cls_act programs.
@@ -6750,6 +6755,7 @@ struct bpf_raw_tracepoint_args {
67506755
enum {
67516756
BPF_FIB_LOOKUP_DIRECT = (1U << 0),
67526757
BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
6758+
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
67536759
};
67546760

67556761
enum {

net/core/filter.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5722,12 +5722,8 @@ static const struct bpf_func_proto bpf_skb_get_xfrm_state_proto = {
57225722
#endif
57235723

57245724
#if IS_ENABLED(CONFIG_INET) || IS_ENABLED(CONFIG_IPV6)
5725-
static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params,
5726-
const struct neighbour *neigh,
5727-
const struct net_device *dev, u32 mtu)
5725+
static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, u32 mtu)
57285726
{
5729-
memcpy(params->dmac, neigh->ha, ETH_ALEN);
5730-
memcpy(params->smac, dev->dev_addr, ETH_ALEN);
57315727
params->h_vlan_TCI = 0;
57325728
params->h_vlan_proto = 0;
57335729
if (mtu)
@@ -5838,21 +5834,29 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
58385834
if (likely(nhc->nhc_gw_family != AF_INET6)) {
58395835
if (nhc->nhc_gw_family)
58405836
params->ipv4_dst = nhc->nhc_gw.ipv4;
5841-
5842-
neigh = __ipv4_neigh_lookup_noref(dev,
5843-
(__force u32)params->ipv4_dst);
58445837
} else {
58455838
struct in6_addr *dst = (struct in6_addr *)params->ipv6_dst;
58465839

58475840
params->family = AF_INET6;
58485841
*dst = nhc->nhc_gw.ipv6;
5849-
neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
58505842
}
58515843

5844+
if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH)
5845+
goto set_fwd_params;
5846+
5847+
if (likely(nhc->nhc_gw_family != AF_INET6))
5848+
neigh = __ipv4_neigh_lookup_noref(dev,
5849+
(__force u32)params->ipv4_dst);
5850+
else
5851+
neigh = __ipv6_neigh_lookup_noref_stub(dev, params->ipv6_dst);
5852+
58525853
if (!neigh || !(neigh->nud_state & NUD_VALID))
58535854
return BPF_FIB_LKUP_RET_NO_NEIGH;
5855+
memcpy(params->dmac, neigh->ha, ETH_ALEN);
5856+
memcpy(params->smac, dev->dev_addr, ETH_ALEN);
58545857

5855-
return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
5858+
set_fwd_params:
5859+
return bpf_fib_set_fwd_params(params, mtu);
58565860
}
58575861
#endif
58585862

@@ -5960,24 +5964,33 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
59605964
params->rt_metric = res.f6i->fib6_metric;
59615965
params->ifindex = dev->ifindex;
59625966

5967+
if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH)
5968+
goto set_fwd_params;
5969+
59635970
/* xdp and cls_bpf programs are run in RCU-bh so rcu_read_lock_bh is
59645971
* not needed here.
59655972
*/
59665973
neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
59675974
if (!neigh || !(neigh->nud_state & NUD_VALID))
59685975
return BPF_FIB_LKUP_RET_NO_NEIGH;
5976+
memcpy(params->dmac, neigh->ha, ETH_ALEN);
5977+
memcpy(params->smac, dev->dev_addr, ETH_ALEN);
59695978

5970-
return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
5979+
set_fwd_params:
5980+
return bpf_fib_set_fwd_params(params, mtu);
59715981
}
59725982
#endif
59735983

5984+
#define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \
5985+
BPF_FIB_LOOKUP_SKIP_NEIGH)
5986+
59745987
BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx,
59755988
struct bpf_fib_lookup *, params, int, plen, u32, flags)
59765989
{
59775990
if (plen < sizeof(*params))
59785991
return -EINVAL;
59795992

5980-
if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT))
5993+
if (flags & ~BPF_FIB_LOOKUP_MASK)
59815994
return -EINVAL;
59825995

59835996
switch (params->family) {
@@ -6015,7 +6028,7 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, skb,
60156028
if (plen < sizeof(*params))
60166029
return -EINVAL;
60176030

6018-
if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT))
6031+
if (flags & ~BPF_FIB_LOOKUP_MASK)
60196032
return -EINVAL;
60206033

60216034
if (params->tot_len)

tools/include/uapi/linux/bpf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,11 @@ union bpf_attr {
31343134
* **BPF_FIB_LOOKUP_OUTPUT**
31353135
* Perform lookup from an egress perspective (default is
31363136
* ingress).
3137+
* **BPF_FIB_LOOKUP_SKIP_NEIGH**
3138+
* Skip the neighbour table lookup. *params*->dmac
3139+
* and *params*->smac will not be set as output. A common
3140+
* use case is to call **bpf_redirect_neigh**\ () after
3141+
* doing **bpf_fib_lookup**\ ().
31373142
*
31383143
* *ctx* is either **struct xdp_md** for XDP programs or
31393144
* **struct sk_buff** tc cls_act programs.
@@ -6750,6 +6755,7 @@ struct bpf_raw_tracepoint_args {
67506755
enum {
67516756
BPF_FIB_LOOKUP_DIRECT = (1U << 0),
67526757
BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
6758+
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
67536759
};
67546760

67556761
enum {

0 commit comments

Comments
 (0)