2023-04-07 16:38:54 +03:00
// SPDX-License-Identifier: GPL-2.0-only
/* Unstable Fou Helpers for TC-BPF hook
*
* These are called from SCHED_CLS BPF programs . Note that it is
* allowed to break compatibility for these functions since the interface they
* are exposed through to BPF programs is explicitly unstable .
*/
# include <linux/bpf.h>
# include <linux/btf_ids.h>
# include <net/dst_metadata.h>
# include <net/fou.h>
struct bpf_fou_encap {
__be16 sport ;
__be16 dport ;
} ;
enum bpf_fou_encap_type {
FOU_BPF_ENCAP_FOU ,
FOU_BPF_ENCAP_GUE ,
} ;
2023-11-01 00:56:24 +03:00
__bpf_kfunc_start_defs ( ) ;
2023-04-07 16:38:54 +03:00
/* bpf_skb_set_fou_encap - Set FOU encap parameters
*
* This function allows for using GUE or FOU encapsulation together with an
* ipip device in collect - metadata mode .
*
* It is meant to be used in BPF tc - hooks and after a call to the
* bpf_skb_set_tunnel_key helper , responsible for setting IP addresses .
*
* Parameters :
* @ skb_ctx Pointer to ctx ( __sk_buff ) in TC program . Cannot be NULL
* @ encap Pointer to a ` struct bpf_fou_encap ` storing UDP src and
* dst ports . If sport is set to 0 the kernel will auto - assign a
* port . This is similar to using ` encap - sport auto ` .
* Cannot be NULL
* @ type Encapsulation type for the packet . Their definitions are
* specified in ` enum bpf_fou_encap_type `
*/
__bpf_kfunc int bpf_skb_set_fou_encap ( struct __sk_buff * skb_ctx ,
struct bpf_fou_encap * encap , int type )
{
struct sk_buff * skb = ( struct sk_buff * ) skb_ctx ;
struct ip_tunnel_info * info = skb_tunnel_info ( skb ) ;
if ( unlikely ( ! encap ) )
return - EINVAL ;
if ( unlikely ( ! info | | ! ( info - > mode & IP_TUNNEL_INFO_TX ) ) )
return - EINVAL ;
switch ( type ) {
case FOU_BPF_ENCAP_FOU :
info - > encap . type = TUNNEL_ENCAP_FOU ;
break ;
case FOU_BPF_ENCAP_GUE :
info - > encap . type = TUNNEL_ENCAP_GUE ;
break ;
default :
info - > encap . type = TUNNEL_ENCAP_NONE ;
}
if ( info - > key . tun_flags & TUNNEL_CSUM )
info - > encap . flags | = TUNNEL_ENCAP_FLAG_CSUM ;
info - > encap . sport = encap - > sport ;
info - > encap . dport = encap - > dport ;
return 0 ;
}
/* bpf_skb_get_fou_encap - Get FOU encap parameters
*
* This function allows for reading encap metadata from a packet received
* on an ipip device in collect - metadata mode .
*
* Parameters :
* @ skb_ctx Pointer to ctx ( __sk_buff ) in TC program . Cannot be NULL
* @ encap Pointer to a struct bpf_fou_encap storing UDP source and
* destination port . Cannot be NULL
*/
__bpf_kfunc int bpf_skb_get_fou_encap ( struct __sk_buff * skb_ctx ,
struct bpf_fou_encap * encap )
{
struct sk_buff * skb = ( struct sk_buff * ) skb_ctx ;
struct ip_tunnel_info * info = skb_tunnel_info ( skb ) ;
if ( unlikely ( ! info ) )
return - EINVAL ;
encap - > sport = info - > encap . sport ;
encap - > dport = info - > encap . dport ;
return 0 ;
}
2023-11-01 00:56:24 +03:00
__bpf_kfunc_end_defs ( ) ;
2023-04-07 16:38:54 +03:00
BTF_SET8_START ( fou_kfunc_set )
BTF_ID_FLAGS ( func , bpf_skb_set_fou_encap )
BTF_ID_FLAGS ( func , bpf_skb_get_fou_encap )
BTF_SET8_END ( fou_kfunc_set )
static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
. owner = THIS_MODULE ,
. set = & fou_kfunc_set ,
} ;
int register_fou_bpf ( void )
{
return register_btf_kfunc_id_set ( BPF_PROG_TYPE_SCHED_CLS ,
& fou_bpf_kfunc_set ) ;
}