bpf: Add support for passing mark with bpf_fib_lookup
authorAnton Protopopov <aspsk@isovalent.com>
Tue, 26 Mar 2024 10:17:40 +0000 (10:17 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 29 Mar 2024 01:30:52 +0000 (18:30 -0700)
Extend the bpf_fib_lookup() helper by making it to utilize mark if
the BPF_FIB_LOOKUP_MARK flag is set. In order to pass the mark the
four bytes of struct bpf_fib_lookup are used, shared with the
output-only smac/dmac fields.

Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: David Ahern <dsahern@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20240326101742.17421-2-aspsk@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
net/core/filter.c
tools/include/uapi/linux/bpf.h

index 9585f534535359993861e7f23c901664919c177c..96d57e483133fd880d376f7c827095be6afc40d6 100644 (file)
@@ -3394,6 +3394,10 @@ union bpf_attr {
  *                     for the nexthop. If the src addr cannot be derived,
  *                     **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
  *                     case, *params*->dmac and *params*->smac are not set either.
+ *             **BPF_FIB_LOOKUP_MARK**
+ *                     Use the mark present in *params*->mark for the fib lookup.
+ *                     This option should not be used with BPF_FIB_LOOKUP_DIRECT,
+ *                     as it only has meaning for full lookups.
  *
  *             *ctx* is either **struct xdp_md** for XDP programs or
  *             **struct sk_buff** tc cls_act programs.
@@ -7120,6 +7124,7 @@ enum {
        BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
        BPF_FIB_LOOKUP_TBID    = (1U << 3),
        BPF_FIB_LOOKUP_SRC     = (1U << 4),
+       BPF_FIB_LOOKUP_MARK    = (1U << 5),
 };
 
 enum {
@@ -7197,8 +7202,19 @@ struct bpf_fib_lookup {
                __u32   tbid;
        };
 
-       __u8    smac[6];     /* ETH_ALEN */
-       __u8    dmac[6];     /* ETH_ALEN */
+       union {
+               /* input */
+               struct {
+                       __u32   mark;   /* policy routing */
+                       /* 2 4-byte holes for input */
+               };
+
+               /* output: source and dest mac */
+               struct {
+                       __u8    smac[6];        /* ETH_ALEN */
+                       __u8    dmac[6];        /* ETH_ALEN */
+               };
+       };
 };
 
 struct bpf_redir_neigh {
index 0c66e4a3fc5bbeca77ca28db00d64cc1d4923e2d..1205dd777dc2f2b91d3f94042cf7cb5c3f50069b 100644 (file)
@@ -5884,7 +5884,10 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
 
                err = fib_table_lookup(tb, &fl4, &res, FIB_LOOKUP_NOREF);
        } else {
-               fl4.flowi4_mark = 0;
+               if (flags & BPF_FIB_LOOKUP_MARK)
+                       fl4.flowi4_mark = params->mark;
+               else
+                       fl4.flowi4_mark = 0;
                fl4.flowi4_secid = 0;
                fl4.flowi4_tun_key.tun_id = 0;
                fl4.flowi4_uid = sock_net_uid(net, NULL);
@@ -6027,7 +6030,10 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
                err = ipv6_stub->fib6_table_lookup(net, tb, oif, &fl6, &res,
                                                   strict);
        } else {
-               fl6.flowi6_mark = 0;
+               if (flags & BPF_FIB_LOOKUP_MARK)
+                       fl6.flowi6_mark = params->mark;
+               else
+                       fl6.flowi6_mark = 0;
                fl6.flowi6_secid = 0;
                fl6.flowi6_tun_key.tun_id = 0;
                fl6.flowi6_uid = sock_net_uid(net, NULL);
@@ -6105,7 +6111,7 @@ set_fwd_params:
 
 #define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \
                             BPF_FIB_LOOKUP_SKIP_NEIGH | BPF_FIB_LOOKUP_TBID | \
-                            BPF_FIB_LOOKUP_SRC)
+                            BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_MARK)
 
 BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx,
           struct bpf_fib_lookup *, params, int, plen, u32, flags)
index 9585f534535359993861e7f23c901664919c177c..96d57e483133fd880d376f7c827095be6afc40d6 100644 (file)
@@ -3394,6 +3394,10 @@ union bpf_attr {
  *                     for the nexthop. If the src addr cannot be derived,
  *                     **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
  *                     case, *params*->dmac and *params*->smac are not set either.
+ *             **BPF_FIB_LOOKUP_MARK**
+ *                     Use the mark present in *params*->mark for the fib lookup.
+ *                     This option should not be used with BPF_FIB_LOOKUP_DIRECT,
+ *                     as it only has meaning for full lookups.
  *
  *             *ctx* is either **struct xdp_md** for XDP programs or
  *             **struct sk_buff** tc cls_act programs.
@@ -7120,6 +7124,7 @@ enum {
        BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
        BPF_FIB_LOOKUP_TBID    = (1U << 3),
        BPF_FIB_LOOKUP_SRC     = (1U << 4),
+       BPF_FIB_LOOKUP_MARK    = (1U << 5),
 };
 
 enum {
@@ -7197,8 +7202,19 @@ struct bpf_fib_lookup {
                __u32   tbid;
        };
 
-       __u8    smac[6];     /* ETH_ALEN */
-       __u8    dmac[6];     /* ETH_ALEN */
+       union {
+               /* input */
+               struct {
+                       __u32   mark;   /* policy routing */
+                       /* 2 4-byte holes for input */
+               };
+
+               /* output: source and dest mac */
+               struct {
+                       __u8    smac[6];        /* ETH_ALEN */
+                       __u8    dmac[6];        /* ETH_ALEN */
+               };
+       };
 };
 
 struct bpf_redir_neigh {