On 4/29/18 7:13 PM, David Ahern wrote: > > The idea here is to fast pass packets that fit a supported profile and > are to be forwarded. Everything else should continue up the stack as it > has wider capabilities. The helper and XDP programs should make no > assumptions on what the broader kernel and userspace might be monitoring > or want to do with packets that can not be forwarded in the fast path. > This is very similar to hardware forwarding when it punts packets to the > CPU for control plane assistance. >
Thinking about this some more and how to return more information to the bpf program about the FIB lookup. bpf_fib_lookup struct is 64-bytes. It can not be expanded without hurting performance. I could do another union on an input parameter and return flags indicating why the returned index is 0. Something like this: diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 360a1168c353..75591522444c 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2314,6 +2314,12 @@ struct bpf_raw_tracepoint_args { #define BPF_FIB_LOOKUP_DIRECT BIT(0) #define BPF_FIB_LOOKUP_OUTPUT BIT(1) +#define BPF_FIB_LKUP_RET_NO_FWD BIT(0) /* pkt is not fwded */ +#define BPF_FIB_LKUP_RET_UNSUPP_LWT BIT(1) /* fwd requires unsupp encap */ +#define BPF_FIB_LKUP_RET_NO_NHDEV BIT(2) /* nh device does not exist */ +#define BPF_FIB_LKUP_RET_NO_NEIGH BIT(3) /* no neigh entry for nh */ +#define BPF_FIB_LKUP_RET_FRAG_NEEDED BIT(4) /* pkt too big to fwd */ + struct bpf_fib_lookup { /* input */ __u8 family; /* network family, AF_INET, AF_INET6, AF_MPLS */ @@ -2325,7 +2331,11 @@ struct bpf_fib_lookup { /* total length of packet from network header - used for MTU check */ __u16 tot_len; - __u32 ifindex; /* L3 device index for lookup */ + + union { + __u32 ifindex; /* in: L3 device index for lookup */ + __u32 ret_flags; /* out: BPF_FIB_LOOKUP_RET flags */ + } union { /* inputs to lookup */ Similarly for the fib result, it could be returned with a union on say family: union { __u8 family; /* in: network family, AF_INET, AF_INET6, AF_MPLS */ __u8 rt_type; /* out: FIB lookup route type */ }; Then if the fib result is -EINVAL/-EHOSTUNREACH/-EACCES, rt_type is set to RTN_BLACKHOLE/RTN_UNREACHABLE/RTN_PROHIBIT allowing the XDP program to make an informed decision on dropping the packet. To avoid performance hits on the forwarding path, these return values would *only* set if the ifindex returned is 0.