Jesper Dangaard Brouer <bro...@redhat.com> writes:

> On Tue, 04 Jun 2019 17:24:10 +0200
> Toke Høiland-Jørgensen <t...@redhat.com> wrote:
>
>> The bpf_redirect_map() helper used by XDP programs doesn't return any
>> indication of whether it can successfully redirect to the map index it was
>> given. Instead, BPF programs have to track this themselves, leading to
>> programs using duplicate maps to track which entries are populated in the
>> devmap.
>> 
>> This adds a flag to the XDP version of the bpf_redirect_map() helper, which
>> makes the helper do a lookup in the map when called, and return XDP_PASS if
>> there is no value at the provided index. This enables two use cases:
>
> To Jonathan Lemon, notice this approach of adding a flag to the helper
> call, it actually also works for your use-case of XSK AF_XDP maps.
>
>> - A BPF program can check the return code from the helper call and react if
>>   it is XDP_PASS (by, for instance, redirecting out a different interface).
>> 
>> - Programs that just return the value of the bpf_redirect() call will
>>   automatically fall back to the regular networking stack, simplifying
>>   programs that (for instance) build a router with the fib_lookup() helper.
>> 
>> Signed-off-by: Toke Høiland-Jørgensen <t...@redhat.com>
>> ---
>>  include/uapi/linux/bpf.h |    8 ++++++++
>>  net/core/filter.c        |   10 +++++++++-
>>  2 files changed, 17 insertions(+), 1 deletion(-)
>> 
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 7c6aef253173..4c41482b7604 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -3098,6 +3098,14 @@ enum xdp_action {
>>      XDP_REDIRECT,
>>  };
>>  
>> +/* Flags for bpf_xdp_redirect_map helper */
>> +
>> +/* If set, the help will check if the entry exists in the map and return
>> + * XDP_PASS if it doesn't.
>> + */
>> +#define XDP_REDIRECT_PASS_ON_INVALID BIT(0)
>> +#define XDP_REDIRECT_ALL_FLAGS XDP_REDIRECT_PASS_ON_INVALID
>> +
>>  /* user accessible metadata for XDP packet hook
>>   * new fields must be added to the end of this structure
>>   */
>> diff --git a/net/core/filter.c b/net/core/filter.c
>> index 55bfc941d17a..dfab8478f66c 100644
>> --- a/net/core/filter.c
>> +++ b/net/core/filter.c
>> @@ -3755,9 +3755,17 @@ BPF_CALL_3(bpf_xdp_redirect_map, struct bpf_map *, 
>> map, u32, ifindex,
>>  {
>>      struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
>>  
>> -    if (unlikely(flags))
>> +    if (unlikely(flags & ~XDP_REDIRECT_ALL_FLAGS))
>>              return XDP_ABORTED;
>>  
>> +    if (flags & XDP_REDIRECT_PASS_ON_INVALID) {
>> +            struct net_device *fwd;
>
> It is slightly misguiding that '*fwd' is a 'struct net_device', as the
> __xdp_map_lookup_elem() call works for all the supported redirect-map
> types.
>
> People should realize that this patch is a general approach for all the
> redirect-map types.

Good point, will fix! :)

-Toke

Reply via email to