Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: netfilter: Reports ct direction in CT lookup helpers for XDP and TC-BPF

Report connection tracking tuple direction in
bpf_skb_ct_lookup/bpf_xdp_ct_lookup helpers. Direction will be used to
implement snat/dnat through xdp ebpf program.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/aa1aaac89191cfc64078ecef36c0a48c302321b9.1648908601.git.lorenzo@kernel.org

authored by

Lorenzo Bianconi and committed by
Alexei Starovoitov
1963c740 2d0df019

+15 -7
+15 -7
net/netfilter/nf_conntrack_bpf.c
··· 38 38 * @l4proto - Layer 4 protocol 39 39 * Values: 40 40 * IPPROTO_TCP, IPPROTO_UDP 41 + * @dir: - connection tracking tuple direction. 41 42 * @reserved - Reserved member, will be reused for more options in future 42 43 * Values: 43 44 * 0 ··· 47 46 s32 netns_id; 48 47 s32 error; 49 48 u8 l4proto; 50 - u8 reserved[3]; 49 + u8 dir; 50 + u8 reserved[2]; 51 51 }; 52 52 53 53 enum { ··· 58 56 static struct nf_conn *__bpf_nf_ct_lookup(struct net *net, 59 57 struct bpf_sock_tuple *bpf_tuple, 60 58 u32 tuple_len, u8 protonum, 61 - s32 netns_id) 59 + s32 netns_id, u8 *dir) 62 60 { 63 61 struct nf_conntrack_tuple_hash *hash; 64 62 struct nf_conntrack_tuple tuple; 63 + struct nf_conn *ct; 65 64 66 65 if (unlikely(protonum != IPPROTO_TCP && protonum != IPPROTO_UDP)) 67 66 return ERR_PTR(-EPROTO); ··· 102 99 put_net(net); 103 100 if (!hash) 104 101 return ERR_PTR(-ENOENT); 105 - return nf_ct_tuplehash_to_ctrack(hash); 102 + 103 + ct = nf_ct_tuplehash_to_ctrack(hash); 104 + if (dir) 105 + *dir = NF_CT_DIRECTION(hash); 106 + 107 + return ct; 106 108 } 107 109 108 110 __diag_push(); ··· 143 135 if (!opts) 144 136 return NULL; 145 137 if (!bpf_tuple || opts->reserved[0] || opts->reserved[1] || 146 - opts->reserved[2] || opts__sz != NF_BPF_CT_OPTS_SZ) { 138 + opts__sz != NF_BPF_CT_OPTS_SZ) { 147 139 opts->error = -EINVAL; 148 140 return NULL; 149 141 } 150 142 caller_net = dev_net(ctx->rxq->dev); 151 143 nfct = __bpf_nf_ct_lookup(caller_net, bpf_tuple, tuple__sz, opts->l4proto, 152 - opts->netns_id); 144 + opts->netns_id, &opts->dir); 153 145 if (IS_ERR(nfct)) { 154 146 opts->error = PTR_ERR(nfct); 155 147 return NULL; ··· 186 178 if (!opts) 187 179 return NULL; 188 180 if (!bpf_tuple || opts->reserved[0] || opts->reserved[1] || 189 - opts->reserved[2] || opts__sz != NF_BPF_CT_OPTS_SZ) { 181 + opts__sz != NF_BPF_CT_OPTS_SZ) { 190 182 opts->error = -EINVAL; 191 183 return NULL; 192 184 } 193 185 caller_net = skb->dev ? dev_net(skb->dev) : sock_net(skb->sk); 194 186 nfct = __bpf_nf_ct_lookup(caller_net, bpf_tuple, tuple__sz, opts->l4proto, 195 - opts->netns_id); 187 + opts->netns_id, &opts->dir); 196 188 if (IS_ERR(nfct)) { 197 189 opts->error = PTR_ERR(nfct); 198 190 return NULL;