From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@kernel.org>,
netdev@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH RFC bpf-next 1/2] bpf_redirect_neigh: Support supplying the nexthop as a helper parameter
Date: Mon, 19 Oct 2020 16:56:36 +0200 [thread overview]
Message-ID: <87tuuqe02j.fsf@toke.dk> (raw)
In-Reply-To: <3d90f3aa-fc09-983f-0e5d-81e889d03b54@iogearbox.net>
Daniel Borkmann <daniel@iogearbox.net> writes:
> On 10/15/20 5:46 PM, Toke Høiland-Jørgensen wrote:
>> From: Toke Høiland-Jørgensen <toke@redhat.com>
>>
>> Based on the discussion in [0], update the bpf_redirect_neigh() helper to
>> accept an optional parameter specifying the nexthop information. This makes
>> it possible to combine bpf_fib_lookup() and bpf_redirect_neigh() without
>> incurring a duplicate FIB lookup - since the FIB lookup helper will return
>> the nexthop information even if no neighbour is present, this can simply be
>> passed on to bpf_redirect_neigh() if bpf_fib_lookup() returns
>> BPF_FIB_LKUP_RET_NO_NEIGH.
>>
>> [0] https://lore.kernel.org/bpf/393e17fc-d187-3a8d-2f0d-a627c7c63fca@iogearbox.net/
>>
>> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>
> Overall looks good from what I can tell, just small nits below on top of
> David's feedback:
>
> [...]
>> -static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev)
>> +static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev,
>> + struct bpf_nh_params *nh)
>> {
>> const struct iphdr *ip4h = ip_hdr(skb);
>> struct net *net = dev_net(dev);
>> int err, ret = NET_XMIT_DROP;
>> - struct rtable *rt;
>> - struct flowi4 fl4 = {
>> - .flowi4_flags = FLOWI_FLAG_ANYSRC,
>> - .flowi4_mark = skb->mark,
>> - .flowi4_tos = RT_TOS(ip4h->tos),
>> - .flowi4_oif = dev->ifindex,
>> - .flowi4_proto = ip4h->protocol,
>> - .daddr = ip4h->daddr,
>> - .saddr = ip4h->saddr,
>> - };
>>
>> - rt = ip_route_output_flow(net, &fl4, NULL);
>> - if (IS_ERR(rt))
>> - goto out_drop;
>> - if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
>> - ip_rt_put(rt);
>> - goto out_drop;
>> - }
>> + if (!nh->nh_family) {
>> + struct rtable *rt;
>> + struct flowi4 fl4 = {
>> + .flowi4_flags = FLOWI_FLAG_ANYSRC,
>> + .flowi4_mark = skb->mark,
>> + .flowi4_tos = RT_TOS(ip4h->tos),
>> + .flowi4_oif = dev->ifindex,
>> + .flowi4_proto = ip4h->protocol,
>> + .daddr = ip4h->daddr,
>> + .saddr = ip4h->saddr,
>> + };
>> +
>> + rt = ip_route_output_flow(net, &fl4, NULL);
>> + if (IS_ERR(rt))
>> + goto out_drop;
>> + if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
>> + ip_rt_put(rt);
>> + goto out_drop;
>> + }
>>
>> - skb_dst_set(skb, &rt->dst);
>> + skb_dst_set(skb, &rt->dst);
>> + nh = NULL;
>> + }
>>
>> - err = bpf_out_neigh_v4(net, skb);
>> + err = bpf_out_neigh_v4(net, skb, dev, nh);
>> if (unlikely(net_xmit_eval(err)))
>> dev->stats.tx_errors++;
>> else
>> @@ -2355,7 +2383,8 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev)
>> }
>> #endif /* CONFIG_INET */
>>
>> -static int __bpf_redirect_neigh(struct sk_buff *skb, struct net_device *dev)
>> +static int __bpf_redirect_neigh(struct sk_buff *skb, struct net_device *dev,
>> + struct bpf_nh_params *nh)
>> {
>> struct ethhdr *ethh = eth_hdr(skb);
>>
>> @@ -2370,9 +2399,9 @@ static int __bpf_redirect_neigh(struct sk_buff *skb, struct net_device *dev)
>> skb_reset_network_header(skb);
>>
>> if (skb->protocol == htons(ETH_P_IP))
>> - return __bpf_redirect_neigh_v4(skb, dev);
>> + return __bpf_redirect_neigh_v4(skb, dev, nh);
>> else if (skb->protocol == htons(ETH_P_IPV6))
>> - return __bpf_redirect_neigh_v6(skb, dev);
>> + return __bpf_redirect_neigh_v6(skb, dev, nh);
>> out:
>> kfree_skb(skb);
>> return -ENOTSUPP;
>> @@ -2455,8 +2484,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, &ri->nh) :
>> + __bpf_redirect(skb, dev, flags);
>> out_drop:
>> kfree_skb(skb);
>> return -EINVAL;
>> @@ -2504,16 +2533,23 @@ 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;
>>
>> ri->flags = BPF_F_NEIGH;
>> 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));
>> + else
>> + ri->nh.nh_family = 0; /* clear previous value */
>
> I'd probably just add an internal flag and do ...
>
> ri->flags = BPF_F_NEIGH | (plen ? BPF_F_NEXTHOP : 0);
>
> ... instead of above clearing, and skb_do_redirect() then becomes:
>
> __bpf_redirect_neigh(skb, dev, flags & BPF_F_NEXTHOP ? &ri->nh : NULL)
>
> ... which would then also avoid this !nh->nh_family check where you later on
> set nh = NULL to pass it onwards.
Ah yes, excellent idea! Will fix :)
-Toke
next prev parent reply other threads:[~2020-10-19 14:56 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-15 15:46 [PATCH RFC bpf-next 0/2] bpf: Rework bpf_redirect_neigh() to allow supplying nexthop from caller Toke Høiland-Jørgensen
2020-10-15 15:46 ` [PATCH RFC bpf-next 1/2] bpf_redirect_neigh: Support supplying the nexthop as a helper parameter Toke Høiland-Jørgensen
2020-10-15 16:27 ` David Ahern
2020-10-15 19:34 ` Toke Høiland-Jørgensen
2020-10-19 13:09 ` Daniel Borkmann
2020-10-19 13:28 ` Toke Høiland-Jørgensen
2020-10-15 18:17 ` kernel test robot
2020-10-15 20:59 ` kernel test robot
2020-10-15 21:27 ` kernel test robot
2020-10-19 14:48 ` Daniel Borkmann
2020-10-19 14:56 ` Toke Høiland-Jørgensen [this message]
2020-10-19 15:01 ` Daniel Borkmann
2020-10-15 15:46 ` [PATCH RFC bpf-next 2/2] selftests: Update test_tc_neigh to use the modified bpf_redirect_neigh() Toke Høiland-Jørgensen
2020-10-19 14:40 ` Daniel Borkmann
2020-10-19 14:48 ` Toke Høiland-Jørgensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87tuuqe02j.fsf@toke.dk \
--to=toke@redhat.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dsahern@kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.