1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Unstable Fou Helpers for TC-BPF hook 2 /* Unstable Fou Helpers for TC-BPF hook 3 * 3 * 4 * These are called from SCHED_CLS BPF program 4 * These are called from SCHED_CLS BPF programs. Note that it is 5 * allowed to break compatibility for these fu 5 * allowed to break compatibility for these functions since the interface they 6 * are exposed through to BPF programs is expl 6 * are exposed through to BPF programs is explicitly unstable. 7 */ 7 */ 8 8 9 #include <linux/bpf.h> 9 #include <linux/bpf.h> 10 #include <linux/btf_ids.h> 10 #include <linux/btf_ids.h> 11 11 12 #include <net/dst_metadata.h> 12 #include <net/dst_metadata.h> 13 #include <net/fou.h> 13 #include <net/fou.h> 14 14 15 struct bpf_fou_encap { 15 struct bpf_fou_encap { 16 __be16 sport; 16 __be16 sport; 17 __be16 dport; 17 __be16 dport; 18 }; 18 }; 19 19 20 enum bpf_fou_encap_type { 20 enum bpf_fou_encap_type { 21 FOU_BPF_ENCAP_FOU, 21 FOU_BPF_ENCAP_FOU, 22 FOU_BPF_ENCAP_GUE, 22 FOU_BPF_ENCAP_GUE, 23 }; 23 }; 24 24 25 __bpf_kfunc_start_defs(); 25 __bpf_kfunc_start_defs(); 26 26 27 /* bpf_skb_set_fou_encap - Set FOU encap param 27 /* bpf_skb_set_fou_encap - Set FOU encap parameters 28 * 28 * 29 * This function allows for using GUE or FOU e 29 * This function allows for using GUE or FOU encapsulation together with an 30 * ipip device in collect-metadata mode. 30 * ipip device in collect-metadata mode. 31 * 31 * 32 * It is meant to be used in BPF tc-hooks and 32 * It is meant to be used in BPF tc-hooks and after a call to the 33 * bpf_skb_set_tunnel_key helper, responsible 33 * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses. 34 * 34 * 35 * Parameters: 35 * Parameters: 36 * @skb_ctx Pointer to ctx (__sk_buff) in 36 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL 37 * @encap Pointer to a `struct bpf_fou_e 37 * @encap Pointer to a `struct bpf_fou_encap` storing UDP src and 38 * dst ports. If sport is set to 38 * dst ports. If sport is set to 0 the kernel will auto-assign a 39 * port. This is similar to using 39 * port. This is similar to using `encap-sport auto`. 40 * Cannot be NULL 40 * Cannot be NULL 41 * @type Encapsulation type for the pac 41 * @type Encapsulation type for the packet. Their definitions are 42 * specified in `enum bpf_fou_enc 42 * specified in `enum bpf_fou_encap_type` 43 */ 43 */ 44 __bpf_kfunc int bpf_skb_set_fou_encap(struct _ 44 __bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx, 45 struct b 45 struct bpf_fou_encap *encap, int type) 46 { 46 { 47 struct sk_buff *skb = (struct sk_buff 47 struct sk_buff *skb = (struct sk_buff *)skb_ctx; 48 struct ip_tunnel_info *info = skb_tunn 48 struct ip_tunnel_info *info = skb_tunnel_info(skb); 49 49 50 if (unlikely(!encap)) 50 if (unlikely(!encap)) 51 return -EINVAL; 51 return -EINVAL; 52 52 53 if (unlikely(!info || !(info->mode & I 53 if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) 54 return -EINVAL; 54 return -EINVAL; 55 55 56 switch (type) { 56 switch (type) { 57 case FOU_BPF_ENCAP_FOU: 57 case FOU_BPF_ENCAP_FOU: 58 info->encap.type = TUNNEL_ENCA 58 info->encap.type = TUNNEL_ENCAP_FOU; 59 break; 59 break; 60 case FOU_BPF_ENCAP_GUE: 60 case FOU_BPF_ENCAP_GUE: 61 info->encap.type = TUNNEL_ENCA 61 info->encap.type = TUNNEL_ENCAP_GUE; 62 break; 62 break; 63 default: 63 default: 64 info->encap.type = TUNNEL_ENCA 64 info->encap.type = TUNNEL_ENCAP_NONE; 65 } 65 } 66 66 67 if (test_bit(IP_TUNNEL_CSUM_BIT, info- !! 67 if (info->key.tun_flags & TUNNEL_CSUM) 68 info->encap.flags |= TUNNEL_EN 68 info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM; 69 69 70 info->encap.sport = encap->sport; 70 info->encap.sport = encap->sport; 71 info->encap.dport = encap->dport; 71 info->encap.dport = encap->dport; 72 72 73 return 0; 73 return 0; 74 } 74 } 75 75 76 /* bpf_skb_get_fou_encap - Get FOU encap param 76 /* bpf_skb_get_fou_encap - Get FOU encap parameters 77 * 77 * 78 * This function allows for reading encap meta 78 * This function allows for reading encap metadata from a packet received 79 * on an ipip device in collect-metadata mode. 79 * on an ipip device in collect-metadata mode. 80 * 80 * 81 * Parameters: 81 * Parameters: 82 * @skb_ctx Pointer to ctx (__sk_buff) in 82 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL 83 * @encap Pointer to a struct bpf_fou_en 83 * @encap Pointer to a struct bpf_fou_encap storing UDP source and 84 * destination port. Cannot be NU 84 * destination port. Cannot be NULL 85 */ 85 */ 86 __bpf_kfunc int bpf_skb_get_fou_encap(struct _ 86 __bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx, 87 struct b 87 struct bpf_fou_encap *encap) 88 { 88 { 89 struct sk_buff *skb = (struct sk_buff 89 struct sk_buff *skb = (struct sk_buff *)skb_ctx; 90 struct ip_tunnel_info *info = skb_tunn 90 struct ip_tunnel_info *info = skb_tunnel_info(skb); 91 91 92 if (unlikely(!info)) 92 if (unlikely(!info)) 93 return -EINVAL; 93 return -EINVAL; 94 94 95 encap->sport = info->encap.sport; 95 encap->sport = info->encap.sport; 96 encap->dport = info->encap.dport; 96 encap->dport = info->encap.dport; 97 97 98 return 0; 98 return 0; 99 } 99 } 100 100 101 __bpf_kfunc_end_defs(); 101 __bpf_kfunc_end_defs(); 102 102 103 BTF_KFUNCS_START(fou_kfunc_set) !! 103 BTF_SET8_START(fou_kfunc_set) 104 BTF_ID_FLAGS(func, bpf_skb_set_fou_encap) 104 BTF_ID_FLAGS(func, bpf_skb_set_fou_encap) 105 BTF_ID_FLAGS(func, bpf_skb_get_fou_encap) 105 BTF_ID_FLAGS(func, bpf_skb_get_fou_encap) 106 BTF_KFUNCS_END(fou_kfunc_set) !! 106 BTF_SET8_END(fou_kfunc_set) 107 107 108 static const struct btf_kfunc_id_set fou_bpf_k 108 static const struct btf_kfunc_id_set fou_bpf_kfunc_set = { 109 .owner = THIS_MODULE, 109 .owner = THIS_MODULE, 110 .set = &fou_kfunc_set, 110 .set = &fou_kfunc_set, 111 }; 111 }; 112 112 113 int register_fou_bpf(void) 113 int register_fou_bpf(void) 114 { 114 { 115 return register_btf_kfunc_id_set(BPF_P 115 return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, 116 &fou_ 116 &fou_bpf_kfunc_set); 117 } 117 } 118 118
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.