All of lore.kernel.org
 help / color / mirror / Atom feed
From: Louis DeLosSantos <louis.delos.devel@gmail.com>
To: John Fastabend <john.fastabend@gmail.com>,
	bpf@vger.kernel.org, netdev@vger.kernel.org
Cc: Martin KaFai Lau <martin.lau@linux.dev>,
	Stanislav Fomichev <sdf@google.com>,
	razor@blackwall.org
Subject: Re: [PATCH 1/2] bpf: add table ID to bpf_fib_lookup BPF helper
Date: Fri, 26 May 2023 10:07:03 -0400	[thread overview]
Message-ID: <ZHC9BzCv6KiAUpbj@fedora> (raw)
In-Reply-To: <6470562cac756_2023020893@john.notmuch>

On Thu, May 25, 2023 at 11:48:12PM -0700, John Fastabend wrote:
> Louis DeLosSantos wrote:
> > Add ability to specify routing table ID to the `bpf_fib_lookup` BPF
> > helper.
> > 
> > A new field `tbid` is added to `struct bpf_fib_lookup` used as
> > parameters to the `bpf_fib_lookup` BPF helper.
> > 
> > When the helper is called with the `BPF_FIB_LOOKUP_DIRECT` flag and the
> > `tbid` field in `struct bpf_fib_lookup` is greater then 0, the `tbid`
> > field will be used as the table ID for the fib lookup.
> > 
> > If the `tbid` does not exist the fib lookup will fail with
> > `BPF_FIB_LKUP_RET_NOT_FWDED`.
> > 
> > The `tbid` field becomes a union over the vlan related output fields in
> > `struct bpf_fib_lookup` and will be zeroed immediately after usage.
> > 
> > This functionality is useful in containerized environments.
> > 
> > For instance, if a CNI wants to dictate the next-hop for traffic leaving
> > a container it can create a container-specific routing table and perform
> > a fib lookup against this table in a "host-net-namespace-side" TC program.
> > 
> > This functionality also allows `ip rule` like functionality at the TC
> > layer, allowing an eBPF program to pick a routing table based on some
> > aspect of the sk_buff.
> > 
> > As a concrete use case, this feature will be used in Cilium's SRv6 L3VPN
> > datapath.
> > 
> > When egress traffic leaves a Pod an eBPF program attached by Cilium will
> > determine which VRF the egress traffic should target, and then perform a
> > FIB lookup in a specific table representing this VRF's FIB.
> > 
> > Signed-off-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
> > ---
> >  include/uapi/linux/bpf.h       | 17 ++++++++++++++---
> >  net/core/filter.c              | 12 ++++++++++++
> >  tools/include/uapi/linux/bpf.h | 17 ++++++++++++++---
> >  3 files changed, 40 insertions(+), 6 deletions(-)
> > 
> 
> Looks good one question. Should we hide tbid behind a flag we have
> lots of room. Is there any concern a user could feed a bpf_fib_lookup
> into the helper without clearing the vlan fields? Perhaps by
> pulling the struct from a map or something where it had been
> previously used.
> 
> Thanks,
> John

This is a fair point. 

I could imagine a scenario where an individual is caching bpf_fib_lookup structs,
pulls in a kernel with this change, and is now accidentally feeding the stale vlan
fields as table ID's, since their code is using `BPF_FIB_LOOKUP_DIRECT` with
the old semantics. 

Guarding with a new flag like this (just a quick example, not a full diff)...

```
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 2096fbb328a9b..22095ccaaa64d 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -6823,6 +6823,7 @@ enum {
        BPF_FIB_LOOKUP_DIRECT  = (1U << 0),
        BPF_FIB_LOOKUP_OUTPUT  = (1U << 1),
        BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
+       BPF_FIB_LOOKUP_TBID    = (1U << 3),
 };
 
 enum {
diff --git a/net/core/filter.c b/net/core/filter.c
index 6f710aa0a54b3..9b78460e39af2 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -5803,7 +5803,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
                u32 tbid = l3mdev_fib_table_rcu(dev) ? : RT_TABLE_MAIN;
                struct fib_table *tb;
 
-               if (params->tbid) {
+               if (flags & BPF_FIB_LOOKUP_TBID) {
                        tbid = params->tbid;
                        /* zero out for vlan output */
                        params->tbid = 0;
```

Maybe a bit safer, you're right. 

In this case the semantics around `BPF_FIB_LOOKUP_DIRECT` remain exactly the same,
and if we do `flags = BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID`, only then will
the `tbid` field in the incoming params wil be considered. 

If I squint at this, it technically also allows us to consider `tbid=0` as a 
valid table id, since the caller now explicitly opts into it, where previously
table id 0 was not selectable, tho I don't know if there's a *real* use case 
for selecting the `all` table. 

I'm happy to make this change, what are your thoughts? 

  reply	other threads:[~2023-05-26 14:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-25 14:27 [PATCH 0/2] bpf: utilize table ID in bpf_fib_lookup helper Louis DeLosSantos
2023-05-25 14:27 ` [PATCH 1/2] bpf: add table ID to bpf_fib_lookup BPF helper Louis DeLosSantos
2023-05-26  6:01   ` Yonghong Song
2023-05-26 14:11     ` Louis DeLosSantos
2023-05-26  6:48   ` John Fastabend
2023-05-26 14:07     ` Louis DeLosSantos [this message]
2023-05-26 16:58       ` Yonghong Song
2023-05-25 14:28 ` [PATCH 2/2] bpf: test table ID fib lookup " Louis DeLosSantos
2023-05-26  6:02   ` Yonghong Song
2023-05-26 14:23     ` Louis DeLosSantos

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=ZHC9BzCv6KiAUpbj@fedora \
    --to=louis.delos.devel@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=razor@blackwall.org \
    --cc=sdf@google.com \
    /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.