1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Unstable XFRM Helpers for TC-BPF hook 2 /* Unstable XFRM 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/xfrm.h> 13 #include <net/xfrm.h> 14 14 15 /* bpf_xfrm_info - XFRM metadata information 15 /* bpf_xfrm_info - XFRM metadata information 16 * 16 * 17 * Members: 17 * Members: 18 * @if_id - XFRM if_id: 18 * @if_id - XFRM if_id: 19 * Transmit: if_id to be used 19 * Transmit: if_id to be used in policy and state lookups 20 * Receive: if_id of the stat 20 * Receive: if_id of the state matched for the incoming packet 21 * @link - Underlying device ifindex: 21 * @link - Underlying device ifindex: 22 * Transmit: used as the unde 22 * Transmit: used as the underlying device in VRF routing 23 * Receive: the device on whi 23 * Receive: the device on which the packet had been received 24 */ 24 */ 25 struct bpf_xfrm_info { 25 struct bpf_xfrm_info { 26 u32 if_id; 26 u32 if_id; 27 int link; 27 int link; 28 }; 28 }; 29 29 30 __bpf_kfunc_start_defs(); 30 __bpf_kfunc_start_defs(); 31 31 32 /* bpf_skb_get_xfrm_info - Get XFRM metadata 32 /* bpf_skb_get_xfrm_info - Get XFRM metadata 33 * 33 * 34 * Parameters: 34 * Parameters: 35 * @skb_ctx - Pointer to ctx (__sk_buff) i 35 * @skb_ctx - Pointer to ctx (__sk_buff) in TC program 36 * Cannot be NULL 36 * Cannot be NULL 37 * @to - Pointer to memory to which t 37 * @to - Pointer to memory to which the metadata will be copied 38 * Cannot be NULL 38 * Cannot be NULL 39 */ 39 */ 40 __bpf_kfunc int bpf_skb_get_xfrm_info(struct _ 40 __bpf_kfunc int bpf_skb_get_xfrm_info(struct __sk_buff *skb_ctx, struct bpf_xfrm_info *to) 41 { 41 { 42 struct sk_buff *skb = (struct sk_buff 42 struct sk_buff *skb = (struct sk_buff *)skb_ctx; 43 struct xfrm_md_info *info; 43 struct xfrm_md_info *info; 44 44 45 info = skb_xfrm_md_info(skb); 45 info = skb_xfrm_md_info(skb); 46 if (!info) 46 if (!info) 47 return -EINVAL; 47 return -EINVAL; 48 48 49 to->if_id = info->if_id; 49 to->if_id = info->if_id; 50 to->link = info->link; 50 to->link = info->link; 51 return 0; 51 return 0; 52 } 52 } 53 53 54 /* bpf_skb_get_xfrm_info - Set XFRM metadata 54 /* bpf_skb_get_xfrm_info - Set XFRM metadata 55 * 55 * 56 * Parameters: 56 * Parameters: 57 * @skb_ctx - Pointer to ctx (__sk_buff) i 57 * @skb_ctx - Pointer to ctx (__sk_buff) in TC program 58 * Cannot be NULL 58 * Cannot be NULL 59 * @from - Pointer to memory from which 59 * @from - Pointer to memory from which the metadata will be copied 60 * Cannot be NULL 60 * Cannot be NULL 61 */ 61 */ 62 __bpf_kfunc int bpf_skb_set_xfrm_info(struct _ 62 __bpf_kfunc int bpf_skb_set_xfrm_info(struct __sk_buff *skb_ctx, const struct bpf_xfrm_info *from) 63 { 63 { 64 struct sk_buff *skb = (struct sk_buff 64 struct sk_buff *skb = (struct sk_buff *)skb_ctx; 65 struct metadata_dst *md_dst; 65 struct metadata_dst *md_dst; 66 struct xfrm_md_info *info; 66 struct xfrm_md_info *info; 67 67 68 if (unlikely(skb_metadata_dst(skb))) 68 if (unlikely(skb_metadata_dst(skb))) 69 return -EINVAL; 69 return -EINVAL; 70 70 71 if (!xfrm_bpf_md_dst) { 71 if (!xfrm_bpf_md_dst) { 72 struct metadata_dst __percpu * 72 struct metadata_dst __percpu *tmp; 73 73 74 tmp = metadata_dst_alloc_percp 74 tmp = metadata_dst_alloc_percpu(0, METADATA_XFRM, GFP_ATOMIC); 75 if (!tmp) 75 if (!tmp) 76 return -ENOMEM; 76 return -ENOMEM; 77 if (cmpxchg(&xfrm_bpf_md_dst, 77 if (cmpxchg(&xfrm_bpf_md_dst, NULL, tmp)) 78 metadata_dst_free_perc 78 metadata_dst_free_percpu(tmp); 79 } 79 } 80 md_dst = this_cpu_ptr(xfrm_bpf_md_dst) 80 md_dst = this_cpu_ptr(xfrm_bpf_md_dst); 81 81 82 info = &md_dst->u.xfrm_info; 82 info = &md_dst->u.xfrm_info; 83 83 84 info->if_id = from->if_id; 84 info->if_id = from->if_id; 85 info->link = from->link; 85 info->link = from->link; 86 skb_dst_force(skb); 86 skb_dst_force(skb); 87 info->dst_orig = skb_dst(skb); 87 info->dst_orig = skb_dst(skb); 88 88 89 dst_hold((struct dst_entry *)md_dst); 89 dst_hold((struct dst_entry *)md_dst); 90 skb_dst_set(skb, (struct dst_entry *)m 90 skb_dst_set(skb, (struct dst_entry *)md_dst); 91 return 0; 91 return 0; 92 } 92 } 93 93 94 __bpf_kfunc_end_defs(); 94 __bpf_kfunc_end_defs(); 95 95 96 BTF_KFUNCS_START(xfrm_ifc_kfunc_set) 96 BTF_KFUNCS_START(xfrm_ifc_kfunc_set) 97 BTF_ID_FLAGS(func, bpf_skb_get_xfrm_info) 97 BTF_ID_FLAGS(func, bpf_skb_get_xfrm_info) 98 BTF_ID_FLAGS(func, bpf_skb_set_xfrm_info) 98 BTF_ID_FLAGS(func, bpf_skb_set_xfrm_info) 99 BTF_KFUNCS_END(xfrm_ifc_kfunc_set) 99 BTF_KFUNCS_END(xfrm_ifc_kfunc_set) 100 100 101 static const struct btf_kfunc_id_set xfrm_inte 101 static const struct btf_kfunc_id_set xfrm_interface_kfunc_set = { 102 .owner = THIS_MODULE, 102 .owner = THIS_MODULE, 103 .set = &xfrm_ifc_kfunc_set, 103 .set = &xfrm_ifc_kfunc_set, 104 }; 104 }; 105 105 106 int __init register_xfrm_interface_bpf(void) 106 int __init register_xfrm_interface_bpf(void) 107 { 107 { 108 return register_btf_kfunc_id_set(BPF_P 108 return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, 109 &xfrm 109 &xfrm_interface_kfunc_set); 110 } 110 } 111 111
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.