• Shmulik Ladkani's avatar
    bpf: Support getting tunnel flags · 44c51472
    Shmulik Ladkani authored
    Existing 'bpf_skb_get_tunnel_key' extracts various tunnel parameters
    (id, ttl, tos, local and remote) but does not expose ip_tunnel_info's
    tun_flags to the BPF program.
    
    It makes sense to expose tun_flags to the BPF program.
    
    Assume for example multiple GRE tunnels maintained on a single GRE
    interface in collect_md mode. The program expects origins to initiate
    over GRE, however different origins use different GRE characteristics
    (e.g. some prefer to use GRE checksum, some do not; some pass a GRE key,
    some do not, etc..).
    
    A BPF program getting tun_flags can therefore remember the relevant
    flags (e.g. TUNNEL_CSUM, TUNNEL_SEQ...) for each initiating remote. In
    the reply path, the program can use 'bpf_skb_set_tunnel_key' in order
    to correctly reply to the remote, using similar characteristics, based
    on the stored tunnel flags.
    
    Introduce BPF_F_TUNINFO_FLAGS flag for bpf_skb_get_tunnel_key. If
    specified, 'bpf_tunnel_key->tunnel_flags' is set with the tun_flags.
    
    Decided to use the existing unused 'tunnel_ext' as the storage for the
    'tunnel_flags' in order to avoid changing bpf_tunnel_key's layout.
    
    Also, the following has been considered during the design:
    
      1. Convert the "interesting" internal TUNNEL_xxx flags back to BPF_F_yyy
         and place into the new 'tunnel_flags' field. This has 2 drawbacks:
    
         - The BPF_F_yyy flags are from *set_tunnel_key* enumeration space,
           e.g. BPF_F_ZERO_CSUM_TX. It is awkward that it is "returned" into
           tunnel_flags from a *get_tunnel_key* call.
         - Not all "interesting" TUNNEL_xxx flags can be mapped to existing
           BPF_F_yyy flags, and it doesn't make sense to create new BPF_F_yyy
           flags just for purposes of the returned tunnel_flags.
    
      2. Place key.tun_flags into 'tunnel_flags' but mask them, keeping only
         "interesting" flags. That's ok, but the drawback is that what's
         "interesting" for my usecase might be limiting for other usecases.
    
    Therefore I decided to expose what's in key.tun_flags *as is*, which seems
    most flexible. The BPF user can just choose to ignore bits he's not
    interested in. The TUNNEL_xxx are also UAPI, so no harm exposing them
    back in the get_tunnel_key call.
    Signed-off-by: default avatarShmulik Ladkani <shmulik.ladkani@gmail.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Link: https://lore.kernel.org/bpf/20220831144010.174110-1-shmulik.ladkani@gmail.com
    44c51472
bpf.h 252 KB