*                     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.
        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 {
                __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 {
 
 
                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);
                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);
 
 #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)
 
  *                     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.
        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 {
                __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 {