On 10/20/20 12:51 PM, Toke Høiland-Jørgensen wrote:
From: Toke Høiland-Jørgensen <t...@redhat.com>
[...]
  BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, 
flags)
@@ -2455,8 +2487,8 @@ int skb_do_redirect(struct sk_buff *skb)
                return -EAGAIN;
        }
        return flags & BPF_F_NEIGH ?
-              __bpf_redirect_neigh(skb, dev) :
-              __bpf_redirect(skb, dev, flags);
+               __bpf_redirect_neigh(skb, dev, flags & BPF_F_NEXTHOP ? &ri->nh 
: NULL) :
+               __bpf_redirect(skb, dev, flags);
  out_drop:
        kfree_skb(skb);
        return -EINVAL;
@@ -2504,16 +2536,25 @@ static const struct bpf_func_proto 
bpf_redirect_peer_proto = {
        .arg2_type      = ARG_ANYTHING,
  };
-BPF_CALL_2(bpf_redirect_neigh, u32, ifindex, u64, flags)
+BPF_CALL_4(bpf_redirect_neigh, u32, ifindex, struct bpf_redir_neigh *, params,
+          int, plen, u64, flags)
  {
        struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
- if (unlikely(flags))
+       if (unlikely((plen && plen < sizeof(*params)) || flags))
+               return TC_ACT_SHOT;
+
+       if (unlikely(plen && (params->unused[0] || params->unused[1] ||
+                             params->unused[2])))

small nit: maybe fold this into the prior check that already tests non-zero plen

if (unlikely((plen && (plen < sizeof(*params) ||
                       (params->unused[0] | params->unused[1] |
                        params->unused[2]))) || flags))
        return TC_ACT_SHOT;

                return TC_ACT_SHOT;
- ri->flags = BPF_F_NEIGH;
+       ri->flags = BPF_F_NEIGH | (plen ? BPF_F_NEXTHOP : 0);
        ri->tgt_index = ifindex;
+ BUILD_BUG_ON(sizeof(struct bpf_redir_neigh) != sizeof(struct bpf_nh_params));
+       if (plen)
+               memcpy(&ri->nh, params, sizeof(ri->nh));
+
        return TC_ACT_REDIRECT;
  }

Reply via email to