Blame view
net/netfilter/nft_meta.c
11 KB
96518518c netfilter: add nf... |
1 |
/* |
ef1f7df91 netfilter: nf_tab... |
2 |
* Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> |
96518518c netfilter: add nf... |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Development of this code funded by Astaro AG (http://www.astaro.com/) */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/netlink.h> #include <linux/netfilter.h> #include <linux/netfilter/nf_tables.h> |
e2a093ff0 netfilter: nft_me... |
17 18 19 |
#include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> |
afc5be307 netfilter: nft_me... |
20 |
#include <linux/smp.h> |
e639f7ab0 netfilter: nf_tab... |
21 |
#include <linux/static_key.h> |
96518518c netfilter: add nf... |
22 23 24 25 |
#include <net/dst.h> #include <net/sock.h> #include <net/tcp_states.h> /* for TCP_TIME_WAIT */ #include <net/netfilter/nf_tables.h> |
e639f7ab0 netfilter: nf_tab... |
26 |
#include <net/netfilter/nf_tables_core.h> |
aa45660c6 netfilter: nf_tab... |
27 |
#include <net/netfilter/nft_meta.h> |
96518518c netfilter: add nf... |
28 |
|
b4aae759c netfilter: meta: ... |
29 |
#include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */ |
b07edbe1c netfilter: meta: ... |
30 |
static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state); |
aa45660c6 netfilter: nf_tab... |
31 |
void nft_meta_get_eval(const struct nft_expr *expr, |
a55e22e92 netfilter: nf_tab... |
32 |
struct nft_regs *regs, |
aa45660c6 netfilter: nf_tab... |
33 |
const struct nft_pktinfo *pkt) |
96518518c netfilter: add nf... |
34 35 36 |
{ const struct nft_meta *priv = nft_expr_priv(expr); const struct sk_buff *skb = pkt->skb; |
0e5a1c7eb netfilter: nf_tab... |
37 |
const struct net_device *in = nft_in(pkt), *out = nft_out(pkt); |
3aed82259 netfilter: nft_me... |
38 |
struct sock *sk; |
49499c3e6 netfilter: nf_tab... |
39 |
u32 *dest = ®s->data[priv->dreg]; |
96518518c netfilter: add nf... |
40 41 42 |
switch (priv->key) { case NFT_META_LEN: |
fad136ea0 netfilter: nf_tab... |
43 |
*dest = skb->len; |
96518518c netfilter: add nf... |
44 45 |
break; case NFT_META_PROTOCOL: |
10596608c netfilter: nf_tab... |
46 |
nft_reg_store16(dest, (__force u16)skb->protocol); |
96518518c netfilter: add nf... |
47 |
break; |
124edfa9e netfilter: nf_tab... |
48 |
case NFT_META_NFPROTO: |
10596608c netfilter: nf_tab... |
49 |
nft_reg_store8(dest, nft_pf(pkt)); |
124edfa9e netfilter: nf_tab... |
50 |
break; |
4566bf270 netfilter: nft_me... |
51 |
case NFT_META_L4PROTO: |
beac5afa2 netfilter: nf_tab... |
52 53 |
if (!pkt->tprot_set) goto err; |
10596608c netfilter: nf_tab... |
54 |
nft_reg_store8(dest, pkt->tprot); |
4566bf270 netfilter: nft_me... |
55 |
break; |
96518518c netfilter: add nf... |
56 |
case NFT_META_PRIORITY: |
fad136ea0 netfilter: nf_tab... |
57 |
*dest = skb->priority; |
96518518c netfilter: add nf... |
58 59 |
break; case NFT_META_MARK: |
fad136ea0 netfilter: nf_tab... |
60 |
*dest = skb->mark; |
96518518c netfilter: add nf... |
61 62 63 64 |
break; case NFT_META_IIF: if (in == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
65 |
*dest = in->ifindex; |
96518518c netfilter: add nf... |
66 67 68 69 |
break; case NFT_META_OIF: if (out == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
70 |
*dest = out->ifindex; |
96518518c netfilter: add nf... |
71 72 73 74 |
break; case NFT_META_IIFNAME: if (in == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
75 |
strncpy((char *)dest, in->name, IFNAMSIZ); |
96518518c netfilter: add nf... |
76 77 78 79 |
break; case NFT_META_OIFNAME: if (out == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
80 |
strncpy((char *)dest, out->name, IFNAMSIZ); |
96518518c netfilter: add nf... |
81 82 83 84 |
break; case NFT_META_IIFTYPE: if (in == NULL) goto err; |
10596608c netfilter: nf_tab... |
85 |
nft_reg_store16(dest, in->type); |
96518518c netfilter: add nf... |
86 87 88 89 |
break; case NFT_META_OIFTYPE: if (out == NULL) goto err; |
10596608c netfilter: nf_tab... |
90 |
nft_reg_store16(dest, out->type); |
96518518c netfilter: add nf... |
91 92 |
break; case NFT_META_SKUID: |
3aed82259 netfilter: nft_me... |
93 94 |
sk = skb_to_full_sk(skb); if (!sk || !sk_fullsock(sk)) |
96518518c netfilter: add nf... |
95 |
goto err; |
3aed82259 netfilter: nft_me... |
96 97 98 99 |
read_lock_bh(&sk->sk_callback_lock); if (sk->sk_socket == NULL || sk->sk_socket->file == NULL) { read_unlock_bh(&sk->sk_callback_lock); |
96518518c netfilter: add nf... |
100 101 |
goto err; } |
fad136ea0 netfilter: nf_tab... |
102 |
*dest = from_kuid_munged(&init_user_ns, |
3aed82259 netfilter: nft_me... |
103 104 |
sk->sk_socket->file->f_cred->fsuid); read_unlock_bh(&sk->sk_callback_lock); |
96518518c netfilter: add nf... |
105 106 |
break; case NFT_META_SKGID: |
3aed82259 netfilter: nft_me... |
107 108 |
sk = skb_to_full_sk(skb); if (!sk || !sk_fullsock(sk)) |
96518518c netfilter: add nf... |
109 |
goto err; |
3aed82259 netfilter: nft_me... |
110 111 112 113 |
read_lock_bh(&sk->sk_callback_lock); if (sk->sk_socket == NULL || sk->sk_socket->file == NULL) { read_unlock_bh(&sk->sk_callback_lock); |
96518518c netfilter: add nf... |
114 115 |
goto err; } |
fad136ea0 netfilter: nf_tab... |
116 |
*dest = from_kgid_munged(&init_user_ns, |
3aed82259 netfilter: nft_me... |
117 118 |
sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&sk->sk_callback_lock); |
96518518c netfilter: add nf... |
119 |
break; |
06efbd6d5 netfilter: nft_me... |
120 |
#ifdef CONFIG_IP_ROUTE_CLASSID |
96518518c netfilter: add nf... |
121 122 123 124 125 |
case NFT_META_RTCLASSID: { const struct dst_entry *dst = skb_dst(skb); if (dst == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
126 |
*dest = dst->tclassid; |
96518518c netfilter: add nf... |
127 128 129 130 131 |
break; } #endif #ifdef CONFIG_NETWORK_SECMARK case NFT_META_SECMARK: |
fad136ea0 netfilter: nf_tab... |
132 |
*dest = skb->secmark; |
96518518c netfilter: add nf... |
133 134 |
break; #endif |
e2a093ff0 netfilter: nft_me... |
135 136 |
case NFT_META_PKTTYPE: if (skb->pkt_type != PACKET_LOOPBACK) { |
10596608c netfilter: nf_tab... |
137 |
nft_reg_store8(dest, skb->pkt_type); |
e2a093ff0 netfilter: nft_me... |
138 139 |
break; } |
0e5a1c7eb netfilter: nf_tab... |
140 |
switch (nft_pf(pkt)) { |
e2a093ff0 netfilter: nft_me... |
141 142 |
case NFPROTO_IPV4: if (ipv4_is_multicast(ip_hdr(skb)->daddr)) |
10596608c netfilter: nf_tab... |
143 |
nft_reg_store8(dest, PACKET_MULTICAST); |
e2a093ff0 netfilter: nft_me... |
144 |
else |
10596608c netfilter: nf_tab... |
145 |
nft_reg_store8(dest, PACKET_BROADCAST); |
e2a093ff0 netfilter: nft_me... |
146 147 |
break; case NFPROTO_IPV6: |
10596608c netfilter: nf_tab... |
148 |
nft_reg_store8(dest, PACKET_MULTICAST); |
e2a093ff0 netfilter: nft_me... |
149 |
break; |
f169fd695 netfilter: nft_me... |
150 151 152 153 154 155 156 157 158 159 160 161 |
case NFPROTO_NETDEV: switch (skb->protocol) { case htons(ETH_P_IP): { int noff = skb_network_offset(skb); struct iphdr *iph, _iph; iph = skb_header_pointer(skb, noff, sizeof(_iph), &_iph); if (!iph) goto err; if (ipv4_is_multicast(iph->daddr)) |
10596608c netfilter: nf_tab... |
162 |
nft_reg_store8(dest, PACKET_MULTICAST); |
f169fd695 netfilter: nft_me... |
163 |
else |
10596608c netfilter: nf_tab... |
164 |
nft_reg_store8(dest, PACKET_BROADCAST); |
f169fd695 netfilter: nft_me... |
165 166 167 168 |
break; } case htons(ETH_P_IPV6): |
10596608c netfilter: nf_tab... |
169 |
nft_reg_store8(dest, PACKET_MULTICAST); |
f169fd695 netfilter: nft_me... |
170 171 172 173 174 175 |
break; default: WARN_ON_ONCE(1); goto err; } break; |
e2a093ff0 netfilter: nft_me... |
176 |
default: |
f169fd695 netfilter: nft_me... |
177 |
WARN_ON_ONCE(1); |
e2a093ff0 netfilter: nft_me... |
178 179 180 |
goto err; } break; |
afc5be307 netfilter: nft_me... |
181 |
case NFT_META_CPU: |
fad136ea0 netfilter: nf_tab... |
182 |
*dest = raw_smp_processor_id(); |
afc5be307 netfilter: nft_me... |
183 |
break; |
3045d7607 netfilter: nf_tab... |
184 185 186 |
case NFT_META_IIFGROUP: if (in == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
187 |
*dest = in->group; |
3045d7607 netfilter: nf_tab... |
188 189 190 191 |
break; case NFT_META_OIFGROUP: if (out == NULL) goto err; |
fad136ea0 netfilter: nf_tab... |
192 |
*dest = out->group; |
3045d7607 netfilter: nf_tab... |
193 |
break; |
e181a5430 net: #ifdefify sk... |
194 |
#ifdef CONFIG_CGROUP_NET_CLASSID |
ce674173e netfilter: nft_me... |
195 |
case NFT_META_CGROUP: |
3aed82259 netfilter: nft_me... |
196 197 |
sk = skb_to_full_sk(skb); if (!sk || !sk_fullsock(sk)) |
c5035c77f netfilter: nft_me... |
198 |
goto err; |
2a56a1fec net: wrap sock->s... |
199 |
*dest = sock_cgroup_classid(&sk->sk_cgrp_data); |
ce674173e netfilter: nft_me... |
200 |
break; |
e181a5430 net: #ifdefify sk... |
201 |
#endif |
b07edbe1c netfilter: meta: ... |
202 203 204 205 206 |
case NFT_META_PRANDOM: { struct rnd_state *state = this_cpu_ptr(&nft_prandom_state); *dest = prandom_u32_state(state); break; } |
96518518c netfilter: add nf... |
207 208 209 210 211 212 213 |
default: WARN_ON(1); goto err; } return; err: |
a55e22e92 netfilter: nf_tab... |
214 |
regs->verdict.code = NFT_BREAK; |
96518518c netfilter: add nf... |
215 |
} |
aa45660c6 netfilter: nf_tab... |
216 |
EXPORT_SYMBOL_GPL(nft_meta_get_eval); |
96518518c netfilter: add nf... |
217 |
|
aa45660c6 netfilter: nf_tab... |
218 |
void nft_meta_set_eval(const struct nft_expr *expr, |
a55e22e92 netfilter: nf_tab... |
219 |
struct nft_regs *regs, |
aa45660c6 netfilter: nf_tab... |
220 |
const struct nft_pktinfo *pkt) |
e035b77ac netfilter: nf_tab... |
221 222 223 |
{ const struct nft_meta *meta = nft_expr_priv(expr); struct sk_buff *skb = pkt->skb; |
10596608c netfilter: nf_tab... |
224 225 |
u32 *sreg = ®s->data[meta->sreg]; u32 value = *sreg; |
491b1a866 netfilter: nft_me... |
226 |
u8 value8; |
e035b77ac netfilter: nf_tab... |
227 228 229 230 231 232 233 234 |
switch (meta->key) { case NFT_META_MARK: skb->mark = value; break; case NFT_META_PRIORITY: skb->priority = value; break; |
b4aae759c netfilter: meta: ... |
235 |
case NFT_META_PKTTYPE: |
491b1a866 netfilter: nft_me... |
236 |
value8 = nft_reg_load8(sreg); |
10596608c netfilter: nf_tab... |
237 |
|
491b1a866 netfilter: nft_me... |
238 239 |
if (skb->pkt_type != value8 && skb_pkt_type_ok(value8) && |
10596608c netfilter: nf_tab... |
240 |
skb_pkt_type_ok(skb->pkt_type)) |
491b1a866 netfilter: nft_me... |
241 |
skb->pkt_type = value8; |
b4aae759c netfilter: meta: ... |
242 |
break; |
e035b77ac netfilter: nf_tab... |
243 |
case NFT_META_NFTRACE: |
491b1a866 netfilter: nft_me... |
244 245 246 |
value8 = nft_reg_load8(sreg); skb->nf_trace = !!value8; |
e035b77ac netfilter: nf_tab... |
247 248 249 250 251 |
break; default: WARN_ON(1); } } |
aa45660c6 netfilter: nf_tab... |
252 |
EXPORT_SYMBOL_GPL(nft_meta_set_eval); |
e035b77ac netfilter: nf_tab... |
253 |
|
aa45660c6 netfilter: nf_tab... |
254 |
const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { |
96518518c netfilter: add nf... |
255 256 |
[NFTA_META_DREG] = { .type = NLA_U32 }, [NFTA_META_KEY] = { .type = NLA_U32 }, |
e035b77ac netfilter: nf_tab... |
257 |
[NFTA_META_SREG] = { .type = NLA_U32 }, |
96518518c netfilter: add nf... |
258 |
}; |
aa45660c6 netfilter: nf_tab... |
259 |
EXPORT_SYMBOL_GPL(nft_meta_policy); |
96518518c netfilter: add nf... |
260 |
|
aa45660c6 netfilter: nf_tab... |
261 262 263 |
int nft_meta_get_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) |
96518518c netfilter: add nf... |
264 |
{ |
d2caa696a netfilter: nft_me... |
265 |
struct nft_meta *priv = nft_expr_priv(expr); |
45d9bcda2 netfilter: nf_tab... |
266 |
unsigned int len; |
96518518c netfilter: add nf... |
267 |
|
d2caa696a netfilter: nft_me... |
268 269 |
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); switch (priv->key) { |
96518518c netfilter: add nf... |
270 |
case NFT_META_PROTOCOL: |
45d9bcda2 netfilter: nf_tab... |
271 272 273 274 |
case NFT_META_IIFTYPE: case NFT_META_OIFTYPE: len = sizeof(u16); break; |
124edfa9e netfilter: nf_tab... |
275 |
case NFT_META_NFPROTO: |
4566bf270 netfilter: nft_me... |
276 |
case NFT_META_L4PROTO: |
45d9bcda2 netfilter: nf_tab... |
277 |
case NFT_META_LEN: |
96518518c netfilter: add nf... |
278 279 280 281 |
case NFT_META_PRIORITY: case NFT_META_MARK: case NFT_META_IIF: case NFT_META_OIF: |
96518518c netfilter: add nf... |
282 283 |
case NFT_META_SKUID: case NFT_META_SKGID: |
06efbd6d5 netfilter: nft_me... |
284 |
#ifdef CONFIG_IP_ROUTE_CLASSID |
96518518c netfilter: add nf... |
285 286 287 288 289 |
case NFT_META_RTCLASSID: #endif #ifdef CONFIG_NETWORK_SECMARK case NFT_META_SECMARK: #endif |
e2a093ff0 netfilter: nft_me... |
290 |
case NFT_META_PKTTYPE: |
afc5be307 netfilter: nft_me... |
291 |
case NFT_META_CPU: |
3045d7607 netfilter: nf_tab... |
292 293 |
case NFT_META_IIFGROUP: case NFT_META_OIFGROUP: |
e181a5430 net: #ifdefify sk... |
294 |
#ifdef CONFIG_CGROUP_NET_CLASSID |
ce674173e netfilter: nft_me... |
295 |
case NFT_META_CGROUP: |
e181a5430 net: #ifdefify sk... |
296 |
#endif |
45d9bcda2 netfilter: nf_tab... |
297 298 299 300 301 |
len = sizeof(u32); break; case NFT_META_IIFNAME: case NFT_META_OIFNAME: len = IFNAMSIZ; |
d2caa696a netfilter: nft_me... |
302 |
break; |
b07edbe1c netfilter: meta: ... |
303 304 305 306 |
case NFT_META_PRANDOM: prandom_init_once(&nft_prandom_state); len = sizeof(u32); break; |
96518518c netfilter: add nf... |
307 308 309 |
default: return -EOPNOTSUPP; } |
b1c96ed37 netfilter: nf_tab... |
310 |
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); |
27e6d2017 netfilter: nf_tab... |
311 312 |
return nft_validate_register_store(ctx, priv->dreg, NULL, NFT_DATA_VALUE, len); |
e035b77ac netfilter: nf_tab... |
313 |
} |
aa45660c6 netfilter: nf_tab... |
314 |
EXPORT_SYMBOL_GPL(nft_meta_get_init); |
e035b77ac netfilter: nf_tab... |
315 |
|
960fa72f6 netfilter: nft_me... |
316 317 318 |
int nft_meta_set_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nft_data **data) |
b4aae759c netfilter: meta: ... |
319 |
{ |
960fa72f6 netfilter: nft_me... |
320 |
struct nft_meta *priv = nft_expr_priv(expr); |
b4aae759c netfilter: meta: ... |
321 |
unsigned int hooks; |
960fa72f6 netfilter: nft_me... |
322 323 |
if (priv->key != NFT_META_PKTTYPE) return 0; |
b4aae759c netfilter: meta: ... |
324 325 326 327 328 329 330 |
switch (ctx->afi->family) { case NFPROTO_BRIDGE: hooks = 1 << NF_BR_PRE_ROUTING; break; case NFPROTO_NETDEV: hooks = 1 << NF_NETDEV_INGRESS; break; |
96d9f2a72 netfilter: nft_me... |
331 332 333 334 335 |
case NFPROTO_IPV4: case NFPROTO_IPV6: case NFPROTO_INET: hooks = 1 << NF_INET_PRE_ROUTING; break; |
b4aae759c netfilter: meta: ... |
336 337 338 339 340 341 |
default: return -EOPNOTSUPP; } return nft_chain_validate_hooks(ctx->chain, hooks); } |
960fa72f6 netfilter: nft_me... |
342 |
EXPORT_SYMBOL_GPL(nft_meta_set_validate); |
b4aae759c netfilter: meta: ... |
343 |
|
aa45660c6 netfilter: nf_tab... |
344 345 346 |
int nft_meta_set_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) |
e035b77ac netfilter: nf_tab... |
347 348 |
{ struct nft_meta *priv = nft_expr_priv(expr); |
d07db9884 netfilter: nf_tab... |
349 |
unsigned int len; |
e035b77ac netfilter: nf_tab... |
350 351 352 |
int err; priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); |
d2caa696a netfilter: nft_me... |
353 354 355 |
switch (priv->key) { case NFT_META_MARK: case NFT_META_PRIORITY: |
d07db9884 netfilter: nf_tab... |
356 357 |
len = sizeof(u32); break; |
d2caa696a netfilter: nft_me... |
358 |
case NFT_META_NFTRACE: |
d07db9884 netfilter: nf_tab... |
359 |
len = sizeof(u8); |
d2caa696a netfilter: nft_me... |
360 |
break; |
b4aae759c netfilter: meta: ... |
361 |
case NFT_META_PKTTYPE: |
b4aae759c netfilter: meta: ... |
362 363 |
len = sizeof(u8); break; |
d2caa696a netfilter: nft_me... |
364 365 |
default: return -EOPNOTSUPP; |
e035b77ac netfilter: nf_tab... |
366 |
} |
b1c96ed37 netfilter: nf_tab... |
367 |
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); |
d07db9884 netfilter: nf_tab... |
368 |
err = nft_validate_register_load(priv->sreg, len); |
b38895c57 netfilter: nft_me... |
369 370 |
if (err < 0) return err; |
e035b77ac netfilter: nf_tab... |
371 |
|
e639f7ab0 netfilter: nf_tab... |
372 373 |
if (priv->key == NFT_META_NFTRACE) static_branch_inc(&nft_trace_enabled); |
e035b77ac netfilter: nf_tab... |
374 |
return 0; |
96518518c netfilter: add nf... |
375 |
} |
aa45660c6 netfilter: nf_tab... |
376 |
EXPORT_SYMBOL_GPL(nft_meta_set_init); |
96518518c netfilter: add nf... |
377 |
|
aa45660c6 netfilter: nf_tab... |
378 379 |
int nft_meta_get_dump(struct sk_buff *skb, const struct nft_expr *expr) |
96518518c netfilter: add nf... |
380 381 |
{ const struct nft_meta *priv = nft_expr_priv(expr); |
e035b77ac netfilter: nf_tab... |
382 383 |
if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) goto nla_put_failure; |
b1c96ed37 netfilter: nf_tab... |
384 |
if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg)) |
96518518c netfilter: add nf... |
385 |
goto nla_put_failure; |
e035b77ac netfilter: nf_tab... |
386 387 388 389 390 |
return 0; nla_put_failure: return -1; } |
aa45660c6 netfilter: nf_tab... |
391 |
EXPORT_SYMBOL_GPL(nft_meta_get_dump); |
e035b77ac netfilter: nf_tab... |
392 |
|
aa45660c6 netfilter: nf_tab... |
393 394 |
int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr) |
e035b77ac netfilter: nf_tab... |
395 396 |
{ const struct nft_meta *priv = nft_expr_priv(expr); |
96518518c netfilter: add nf... |
397 398 |
if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) goto nla_put_failure; |
b1c96ed37 netfilter: nf_tab... |
399 |
if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg)) |
e035b77ac netfilter: nf_tab... |
400 |
goto nla_put_failure; |
96518518c netfilter: add nf... |
401 402 403 404 405 |
return 0; nla_put_failure: return -1; } |
aa45660c6 netfilter: nf_tab... |
406 |
EXPORT_SYMBOL_GPL(nft_meta_set_dump); |
96518518c netfilter: add nf... |
407 |
|
e639f7ab0 netfilter: nf_tab... |
408 409 410 411 412 413 414 415 416 |
void nft_meta_set_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) { const struct nft_meta *priv = nft_expr_priv(expr); if (priv->key == NFT_META_NFTRACE) static_branch_dec(&nft_trace_enabled); } EXPORT_SYMBOL_GPL(nft_meta_set_destroy); |
ef1f7df91 netfilter: nf_tab... |
417 |
static struct nft_expr_type nft_meta_type; |
e035b77ac netfilter: nf_tab... |
418 |
static const struct nft_expr_ops nft_meta_get_ops = { |
ef1f7df91 netfilter: nf_tab... |
419 |
.type = &nft_meta_type, |
96518518c netfilter: add nf... |
420 |
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), |
e035b77ac netfilter: nf_tab... |
421 |
.eval = nft_meta_get_eval, |
d2caa696a netfilter: nft_me... |
422 |
.init = nft_meta_get_init, |
e035b77ac netfilter: nf_tab... |
423 |
.dump = nft_meta_get_dump, |
ef1f7df91 netfilter: nf_tab... |
424 |
}; |
e035b77ac netfilter: nf_tab... |
425 426 427 428 |
static const struct nft_expr_ops nft_meta_set_ops = { .type = &nft_meta_type, .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), .eval = nft_meta_set_eval, |
d2caa696a netfilter: nft_me... |
429 |
.init = nft_meta_set_init, |
e639f7ab0 netfilter: nf_tab... |
430 |
.destroy = nft_meta_set_destroy, |
e035b77ac netfilter: nf_tab... |
431 |
.dump = nft_meta_set_dump, |
960fa72f6 netfilter: nft_me... |
432 |
.validate = nft_meta_set_validate, |
e035b77ac netfilter: nf_tab... |
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
}; static const struct nft_expr_ops * nft_meta_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) { if (tb[NFTA_META_KEY] == NULL) return ERR_PTR(-EINVAL); if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG]) return ERR_PTR(-EINVAL); if (tb[NFTA_META_DREG]) return &nft_meta_get_ops; if (tb[NFTA_META_SREG]) return &nft_meta_set_ops; return ERR_PTR(-EINVAL); } |
ef1f7df91 netfilter: nf_tab... |
453 454 |
static struct nft_expr_type nft_meta_type __read_mostly = { .name = "meta", |
d4ef38354 netfilter: Remove... |
455 |
.select_ops = nft_meta_select_ops, |
96518518c netfilter: add nf... |
456 457 |
.policy = nft_meta_policy, .maxattr = NFTA_META_MAX, |
ef1f7df91 netfilter: nf_tab... |
458 |
.owner = THIS_MODULE, |
96518518c netfilter: add nf... |
459 460 461 462 |
}; static int __init nft_meta_module_init(void) { |
ef1f7df91 netfilter: nf_tab... |
463 |
return nft_register_expr(&nft_meta_type); |
96518518c netfilter: add nf... |
464 465 466 467 |
} static void __exit nft_meta_module_exit(void) { |
ef1f7df91 netfilter: nf_tab... |
468 |
nft_unregister_expr(&nft_meta_type); |
96518518c netfilter: add nf... |
469 470 471 472 473 474 475 476 |
} module_init(nft_meta_module_init); module_exit(nft_meta_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); MODULE_ALIAS_NFT_EXPR("meta"); |