1// SPDX-License-Identifier: GPL-2.0-only 2/* Unstable NAT Helpers for XDP and TC-BPF hook 3 * 4 * These are called from the XDP and SCHED_CLS BPF programs. Note that it is 5 * allowed to break compatibility for these functions since the interface they 6 * are exposed through to BPF programs is explicitly unstable. 7 */ 8 9#include <linux/bpf.h> 10#include <linux/btf_ids.h> 11#include <net/netfilter/nf_conntrack_bpf.h> 12#include <net/netfilter/nf_conntrack_core.h> 13#include <net/netfilter/nf_nat.h> 14 15__bpf_kfunc_start_defs(); 16 17/* bpf_ct_set_nat_info - Set source or destination nat address 18 * 19 * Set source or destination nat address of the newly allocated 20 * nf_conn before insertion. This must be invoked for referenced 21 * PTR_TO_BTF_ID to nf_conn___init. 22 * 23 * Parameters: 24 * @nfct - Pointer to referenced nf_conn object, obtained using 25 * bpf_xdp_ct_alloc or bpf_skb_ct_alloc. 26 * @addr - Nat source/destination address 27 * @port - Nat source/destination port. Non-positive values are 28 * interpreted as select a random port. 29 * @manip - NF_NAT_MANIP_SRC or NF_NAT_MANIP_DST 30 */ 31__bpf_kfunc int bpf_ct_set_nat_info(struct nf_conn___init *nfct, 32 union nf_inet_addr *addr, int port, 33 enum nf_nat_manip_type manip) 34{ 35 struct nf_conn *ct = (struct nf_conn *)nfct; 36 u16 proto = nf_ct_l3num(ct); 37 struct nf_nat_range2 range; 38 39 if (proto != NFPROTO_IPV4 && proto != NFPROTO_IPV6) 40 return -EINVAL; 41 42 memset(&range, 0, sizeof(struct nf_nat_range2)); 43 range.flags = NF_NAT_RANGE_MAP_IPS; 44 range.min_addr = *addr; 45 range.max_addr = range.min_addr; 46 if (port > 0) { 47 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 48 range.min_proto.all = cpu_to_be16(port); 49 range.max_proto.all = range.min_proto.all; 50 } 51 52 return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0; 53} 54 55__bpf_kfunc_end_defs(); 56 57BTF_KFUNCS_START(nf_nat_kfunc_set) 58BTF_ID_FLAGS(func, bpf_ct_set_nat_info, KF_TRUSTED_ARGS) 59BTF_KFUNCS_END(nf_nat_kfunc_set) 60 61static const struct btf_kfunc_id_set nf_bpf_nat_kfunc_set = { 62 .owner = THIS_MODULE, 63 .set = &nf_nat_kfunc_set, 64}; 65 66int register_nf_nat_bpf(void) 67{ 68 int ret; 69 70 ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, 71 &nf_bpf_nat_kfunc_set); 72 if (ret) 73 return ret; 74 75 return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, 76 &nf_bpf_nat_kfunc_set); 77} 78