aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter_bridge/ebtables.h3
-rw-r--r--include/net/netfilter/nf_tables.h103
-rw-r--r--include/net/netfilter/nft_meta.h4
-rw-r--r--include/uapi/linux/netfilter/nf_tables.h40
-rw-r--r--include/uapi/linux/netfilter_bridge/ebtables.h2
-rw-r--r--net/bridge/netfilter/nft_meta_bridge.c26
-rw-r--r--net/bridge/netfilter/nft_reject_bridge.c6
-rw-r--r--net/ipv4/netfilter/nft_masq_ipv4.c9
-rw-r--r--net/ipv4/netfilter/nft_redir_ipv4.c11
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c4
-rw-r--r--net/ipv6/netfilter/nft_masq_ipv6.c7
-rw-r--r--net/ipv6/netfilter/nft_redir_ipv6.c11
-rw-r--r--net/ipv6/netfilter/nft_reject_ipv6.c4
-rw-r--r--net/netfilter/nf_tables_api.c271
-rw-r--r--net/netfilter/nf_tables_core.c41
-rw-r--r--net/netfilter/nft_bitwise.c37
-rw-r--r--net/netfilter/nft_byteorder.c40
-rw-r--r--net/netfilter/nft_cmp.c44
-rw-r--r--net/netfilter/nft_compat.c26
-rw-r--r--net/netfilter/nft_counter.c3
-rw-r--r--net/netfilter/nft_ct.c110
-rw-r--r--net/netfilter/nft_dynset.c79
-rw-r--r--net/netfilter/nft_expr_template.c94
-rw-r--r--net/netfilter/nft_exthdr.c23
-rw-r--r--net/netfilter/nft_hash.c19
-rw-r--r--net/netfilter/nft_immediate.c18
-rw-r--r--net/netfilter/nft_limit.c5
-rw-r--r--net/netfilter/nft_log.c2
-rw-r--r--net/netfilter/nft_lookup.c31
-rw-r--r--net/netfilter/nft_meta.c107
-rw-r--r--net/netfilter/nft_nat.c71
-rw-r--r--net/netfilter/nft_payload.c24
-rw-r--r--net/netfilter/nft_queue.c4
-rw-r--r--net/netfilter/nft_rbtree.c15
-rw-r--r--net/netfilter/nft_redir.c19
-rw-r--r--net/netfilter/nft_reject_inet.c5
36 files changed, 739 insertions, 579 deletions
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 34e7a2b7f867..f1bd3962e6b6 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -12,9 +12,10 @@
12#ifndef __LINUX_BRIDGE_EFF_H 12#ifndef __LINUX_BRIDGE_EFF_H
13#define __LINUX_BRIDGE_EFF_H 13#define __LINUX_BRIDGE_EFF_H
14 14
15#include <linux/if.h>
16#include <linux/if_ether.h>
15#include <uapi/linux/netfilter_bridge/ebtables.h> 17#include <uapi/linux/netfilter_bridge/ebtables.h>
16 18
17
18/* return values for match() functions */ 19/* return values for match() functions */
19#define EBT_MATCH 0 20#define EBT_MATCH 0
20#define EBT_NOMATCH 1 21#define EBT_NOMATCH 1
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d6a2f0ed5130..e6bcf55dcf20 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1,6 +1,7 @@
1#ifndef _NET_NF_TABLES_H 1#ifndef _NET_NF_TABLES_H
2#define _NET_NF_TABLES_H 2#define _NET_NF_TABLES_H
3 3
4#include <linux/module.h>
4#include <linux/list.h> 5#include <linux/list.h>
5#include <linux/netfilter.h> 6#include <linux/netfilter.h>
6#include <linux/netfilter/nfnetlink.h> 7#include <linux/netfilter/nfnetlink.h>
@@ -36,29 +37,43 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
36 pkt->xt.family = ops->pf; 37 pkt->xt.family = ops->pf;
37} 38}
38 39
40/**
41 * struct nft_verdict - nf_tables verdict
42 *
43 * @code: nf_tables/netfilter verdict code
44 * @chain: destination chain for NFT_JUMP/NFT_GOTO
45 */
46struct nft_verdict {
47 u32 code;
48 struct nft_chain *chain;
49};
50
39struct nft_data { 51struct nft_data {
40 union { 52 union {
41 u32 data[4]; 53 u32 data[4];
42 struct { 54 struct nft_verdict verdict;
43 u32 verdict;
44 struct nft_chain *chain;
45 };
46 }; 55 };
47} __attribute__((aligned(__alignof__(u64)))); 56} __attribute__((aligned(__alignof__(u64))));
48 57
49static inline int nft_data_cmp(const struct nft_data *d1, 58/**
50 const struct nft_data *d2, 59 * struct nft_regs - nf_tables register set
51 unsigned int len) 60 *
52{ 61 * @data: data registers
53 return memcmp(d1->data, d2->data, len); 62 * @verdict: verdict register
54} 63 *
64 * The first four data registers alias to the verdict register.
65 */
66struct nft_regs {
67 union {
68 u32 data[20];
69 struct nft_verdict verdict;
70 };
71};
55 72
56static inline void nft_data_copy(struct nft_data *dst, 73static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
57 const struct nft_data *src) 74 unsigned int len)
58{ 75{
59 BUILD_BUG_ON(__alignof__(*dst) != __alignof__(u64)); 76 memcpy(dst, src, len);
60 *(u64 *)&dst->data[0] = *(u64 *)&src->data[0];
61 *(u64 *)&dst->data[2] = *(u64 *)&src->data[2];
62} 77}
63 78
64static inline void nft_data_debug(const struct nft_data *data) 79static inline void nft_data_debug(const struct nft_data *data)
@@ -96,7 +111,8 @@ struct nft_data_desc {
96 unsigned int len; 111 unsigned int len;
97}; 112};
98 113
99int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 114int nft_data_init(const struct nft_ctx *ctx,
115 struct nft_data *data, unsigned int size,
100 struct nft_data_desc *desc, const struct nlattr *nla); 116 struct nft_data_desc *desc, const struct nlattr *nla);
101void nft_data_uninit(const struct nft_data *data, enum nft_data_types type); 117void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
102int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, 118int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
@@ -112,12 +128,14 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
112 return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1; 128 return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
113} 129}
114 130
115int nft_validate_input_register(enum nft_registers reg); 131unsigned int nft_parse_register(const struct nlattr *attr);
116int nft_validate_output_register(enum nft_registers reg); 132int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
117int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
118 const struct nft_data *data,
119 enum nft_data_types type);
120 133
134int nft_validate_register_load(enum nft_registers reg, unsigned int len);
135int nft_validate_register_store(const struct nft_ctx *ctx,
136 enum nft_registers reg,
137 const struct nft_data *data,
138 enum nft_data_types type, unsigned int len);
121 139
122/** 140/**
123 * struct nft_userdata - user defined data associated with an object 141 * struct nft_userdata - user defined data associated with an object
@@ -141,7 +159,10 @@ struct nft_userdata {
141 * @priv: element private data and extensions 159 * @priv: element private data and extensions
142 */ 160 */
143struct nft_set_elem { 161struct nft_set_elem {
144 struct nft_data key; 162 union {
163 u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
164 struct nft_data val;
165 } key;
145 void *priv; 166 void *priv;
146}; 167};
147 168
@@ -216,15 +237,15 @@ struct nft_expr;
216 */ 237 */
217struct nft_set_ops { 238struct nft_set_ops {
218 bool (*lookup)(const struct nft_set *set, 239 bool (*lookup)(const struct nft_set *set,
219 const struct nft_data *key, 240 const u32 *key,
220 const struct nft_set_ext **ext); 241 const struct nft_set_ext **ext);
221 bool (*update)(struct nft_set *set, 242 bool (*update)(struct nft_set *set,
222 const struct nft_data *key, 243 const u32 *key,
223 void *(*new)(struct nft_set *, 244 void *(*new)(struct nft_set *,
224 const struct nft_expr *, 245 const struct nft_expr *,
225 struct nft_data []), 246 struct nft_regs *),
226 const struct nft_expr *expr, 247 const struct nft_expr *expr,
227 struct nft_data data[], 248 struct nft_regs *regs,
228 const struct nft_set_ext **ext); 249 const struct nft_set_ext **ext);
229 250
230 int (*insert)(const struct nft_set *set, 251 int (*insert)(const struct nft_set *set,
@@ -350,6 +371,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
350 * @NFT_SET_EXT_TIMEOUT: element timeout 371 * @NFT_SET_EXT_TIMEOUT: element timeout
351 * @NFT_SET_EXT_EXPIRATION: element expiration time 372 * @NFT_SET_EXT_EXPIRATION: element expiration time
352 * @NFT_SET_EXT_USERDATA: user data associated with the element 373 * @NFT_SET_EXT_USERDATA: user data associated with the element
374 * @NFT_SET_EXT_EXPR: expression assiociated with the element
353 * @NFT_SET_EXT_NUM: number of extension types 375 * @NFT_SET_EXT_NUM: number of extension types
354 */ 376 */
355enum nft_set_extensions { 377enum nft_set_extensions {
@@ -359,6 +381,7 @@ enum nft_set_extensions {
359 NFT_SET_EXT_TIMEOUT, 381 NFT_SET_EXT_TIMEOUT,
360 NFT_SET_EXT_EXPIRATION, 382 NFT_SET_EXT_EXPIRATION,
361 NFT_SET_EXT_USERDATA, 383 NFT_SET_EXT_USERDATA,
384 NFT_SET_EXT_EXPR,
362 NFT_SET_EXT_NUM 385 NFT_SET_EXT_NUM
363}; 386};
364 387
@@ -470,6 +493,11 @@ static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext
470 return nft_set_ext(ext, NFT_SET_EXT_USERDATA); 493 return nft_set_ext(ext, NFT_SET_EXT_USERDATA);
471} 494}
472 495
496static inline struct nft_expr *nft_set_ext_expr(const struct nft_set_ext *ext)
497{
498 return nft_set_ext(ext, NFT_SET_EXT_EXPR);
499}
500
473static inline bool nft_set_elem_expired(const struct nft_set_ext *ext) 501static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
474{ 502{
475 return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) && 503 return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
@@ -484,8 +512,7 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
484 512
485void *nft_set_elem_init(const struct nft_set *set, 513void *nft_set_elem_init(const struct nft_set *set,
486 const struct nft_set_ext_tmpl *tmpl, 514 const struct nft_set_ext_tmpl *tmpl,
487 const struct nft_data *key, 515 const u32 *key, const u32 *data,
488 const struct nft_data *data,
489 u64 timeout, gfp_t gfp); 516 u64 timeout, gfp_t gfp);
490void nft_set_elem_destroy(const struct nft_set *set, void *elem); 517void nft_set_elem_destroy(const struct nft_set *set, void *elem);
491 518
@@ -556,6 +583,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
556 * @policy: netlink attribute policy 583 * @policy: netlink attribute policy
557 * @maxattr: highest netlink attribute number 584 * @maxattr: highest netlink attribute number
558 * @family: address family for AF-specific types 585 * @family: address family for AF-specific types
586 * @flags: expression type flags
559 */ 587 */
560struct nft_expr_type { 588struct nft_expr_type {
561 const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, 589 const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
@@ -567,8 +595,11 @@ struct nft_expr_type {
567 const struct nla_policy *policy; 595 const struct nla_policy *policy;
568 unsigned int maxattr; 596 unsigned int maxattr;
569 u8 family; 597 u8 family;
598 u8 flags;
570}; 599};
571 600
601#define NFT_EXPR_STATEFUL 0x1
602
572/** 603/**
573 * struct nft_expr_ops - nf_tables expression operations 604 * struct nft_expr_ops - nf_tables expression operations
574 * 605 *
@@ -584,7 +615,7 @@ struct nft_expr_type {
584struct nft_expr; 615struct nft_expr;
585struct nft_expr_ops { 616struct nft_expr_ops {
586 void (*eval)(const struct nft_expr *expr, 617 void (*eval)(const struct nft_expr *expr,
587 struct nft_data data[NFT_REG_MAX + 1], 618 struct nft_regs *regs,
588 const struct nft_pktinfo *pkt); 619 const struct nft_pktinfo *pkt);
589 unsigned int size; 620 unsigned int size;
590 621
@@ -622,6 +653,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
622 return (void *)expr->data; 653 return (void *)expr->data;
623} 654}
624 655
656struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
657 const struct nlattr *nla);
658void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
659int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
660 const struct nft_expr *expr);
661
662static inline void nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
663{
664 __module_get(src->ops->type->owner);
665 memcpy(dst, src, src->ops->size);
666}
667
625/** 668/**
626 * struct nft_rule - nf_tables rule 669 * struct nft_rule - nf_tables rule
627 * 670 *
diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
index 0ee47c3e2e31..711887a09e91 100644
--- a/include/net/netfilter/nft_meta.h
+++ b/include/net/netfilter/nft_meta.h
@@ -26,11 +26,11 @@ int nft_meta_set_dump(struct sk_buff *skb,
26 const struct nft_expr *expr); 26 const struct nft_expr *expr);
27 27
28void nft_meta_get_eval(const struct nft_expr *expr, 28void nft_meta_get_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt); 30 const struct nft_pktinfo *pkt);
31 31
32void nft_meta_set_eval(const struct nft_expr *expr, 32void nft_meta_set_eval(const struct nft_expr *expr,
33 struct nft_data data[NFT_REG_MAX + 1], 33 struct nft_regs *regs,
34 const struct nft_pktinfo *pkt); 34 const struct nft_pktinfo *pkt);
35 35
36#endif 36#endif
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 05ee1e0804a3..5fa1cd04762e 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -5,16 +5,45 @@
5#define NFT_CHAIN_MAXNAMELEN 32 5#define NFT_CHAIN_MAXNAMELEN 32
6#define NFT_USERDATA_MAXLEN 256 6#define NFT_USERDATA_MAXLEN 256
7 7
8/**
9 * enum nft_registers - nf_tables registers
10 *
11 * nf_tables used to have five registers: a verdict register and four data
12 * registers of size 16. The data registers have been changed to 16 registers
13 * of size 4. For compatibility reasons, the NFT_REG_[1-4] registers still
14 * map to areas of size 16, the 4 byte registers are addressed using
15 * NFT_REG32_00 - NFT_REG32_15.
16 */
8enum nft_registers { 17enum nft_registers {
9 NFT_REG_VERDICT, 18 NFT_REG_VERDICT,
10 NFT_REG_1, 19 NFT_REG_1,
11 NFT_REG_2, 20 NFT_REG_2,
12 NFT_REG_3, 21 NFT_REG_3,
13 NFT_REG_4, 22 NFT_REG_4,
14 __NFT_REG_MAX 23 __NFT_REG_MAX,
24
25 NFT_REG32_00 = 8,
26 MFT_REG32_01,
27 NFT_REG32_02,
28 NFT_REG32_03,
29 NFT_REG32_04,
30 NFT_REG32_05,
31 NFT_REG32_06,
32 NFT_REG32_07,
33 NFT_REG32_08,
34 NFT_REG32_09,
35 NFT_REG32_10,
36 NFT_REG32_11,
37 NFT_REG32_12,
38 NFT_REG32_13,
39 NFT_REG32_14,
40 NFT_REG32_15,
15}; 41};
16#define NFT_REG_MAX (__NFT_REG_MAX - 1) 42#define NFT_REG_MAX (__NFT_REG_MAX - 1)
17 43
44#define NFT_REG_SIZE 16
45#define NFT_REG32_SIZE 4
46
18/** 47/**
19 * enum nft_verdicts - nf_tables internal verdicts 48 * enum nft_verdicts - nf_tables internal verdicts
20 * 49 *
@@ -209,6 +238,7 @@ enum nft_rule_compat_attributes {
209 * @NFT_SET_INTERVAL: set contains intervals 238 * @NFT_SET_INTERVAL: set contains intervals
210 * @NFT_SET_MAP: set is used as a dictionary 239 * @NFT_SET_MAP: set is used as a dictionary
211 * @NFT_SET_TIMEOUT: set uses timeouts 240 * @NFT_SET_TIMEOUT: set uses timeouts
241 * @NFT_SET_EVAL: set contains expressions for evaluation
212 */ 242 */
213enum nft_set_flags { 243enum nft_set_flags {
214 NFT_SET_ANONYMOUS = 0x1, 244 NFT_SET_ANONYMOUS = 0x1,
@@ -216,6 +246,7 @@ enum nft_set_flags {
216 NFT_SET_INTERVAL = 0x4, 246 NFT_SET_INTERVAL = 0x4,
217 NFT_SET_MAP = 0x8, 247 NFT_SET_MAP = 0x8,
218 NFT_SET_TIMEOUT = 0x10, 248 NFT_SET_TIMEOUT = 0x10,
249 NFT_SET_EVAL = 0x20,
219}; 250};
220 251
221/** 252/**
@@ -293,6 +324,7 @@ enum nft_set_elem_flags {
293 * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64) 324 * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
294 * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64) 325 * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
295 * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) 326 * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
327 * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
296 */ 328 */
297enum nft_set_elem_attributes { 329enum nft_set_elem_attributes {
298 NFTA_SET_ELEM_UNSPEC, 330 NFTA_SET_ELEM_UNSPEC,
@@ -302,6 +334,7 @@ enum nft_set_elem_attributes {
302 NFTA_SET_ELEM_TIMEOUT, 334 NFTA_SET_ELEM_TIMEOUT,
303 NFTA_SET_ELEM_EXPIRATION, 335 NFTA_SET_ELEM_EXPIRATION,
304 NFTA_SET_ELEM_USERDATA, 336 NFTA_SET_ELEM_USERDATA,
337 NFTA_SET_ELEM_EXPR,
305 __NFTA_SET_ELEM_MAX 338 __NFTA_SET_ELEM_MAX
306}; 339};
307#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) 340#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -359,6 +392,9 @@ enum nft_data_attributes {
359}; 392};
360#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1) 393#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
361 394
395/* Maximum length of a value */
396#define NFT_DATA_VALUE_MAXLEN 64
397
362/** 398/**
363 * enum nft_verdict_attributes - nf_tables verdict netlink attributes 399 * enum nft_verdict_attributes - nf_tables verdict netlink attributes
364 * 400 *
@@ -531,6 +567,7 @@ enum nft_dynset_ops {
531 * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32) 567 * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
532 * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32) 568 * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
533 * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64) 569 * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
570 * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
534 */ 571 */
535enum nft_dynset_attributes { 572enum nft_dynset_attributes {
536 NFTA_DYNSET_UNSPEC, 573 NFTA_DYNSET_UNSPEC,
@@ -540,6 +577,7 @@ enum nft_dynset_attributes {
540 NFTA_DYNSET_SREG_KEY, 577 NFTA_DYNSET_SREG_KEY,
541 NFTA_DYNSET_SREG_DATA, 578 NFTA_DYNSET_SREG_DATA,
542 NFTA_DYNSET_TIMEOUT, 579 NFTA_DYNSET_TIMEOUT,
580 NFTA_DYNSET_EXPR,
543 __NFTA_DYNSET_MAX, 581 __NFTA_DYNSET_MAX,
544}; 582};
545#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1) 583#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h
index ba993360dbe9..773dfe8924c7 100644
--- a/include/uapi/linux/netfilter_bridge/ebtables.h
+++ b/include/uapi/linux/netfilter_bridge/ebtables.h
@@ -12,9 +12,7 @@
12 12
13#ifndef _UAPI__LINUX_BRIDGE_EFF_H 13#ifndef _UAPI__LINUX_BRIDGE_EFF_H
14#define _UAPI__LINUX_BRIDGE_EFF_H 14#define _UAPI__LINUX_BRIDGE_EFF_H
15#include <linux/if.h>
16#include <linux/netfilter_bridge.h> 15#include <linux/netfilter_bridge.h>
17#include <linux/if_ether.h>
18 16
19#define EBT_TABLE_MAXNAMELEN 32 17#define EBT_TABLE_MAXNAMELEN 32
20#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN 18#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 4f02109d708f..a21269b83f16 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -19,12 +19,12 @@
19#include "../br_private.h" 19#include "../br_private.h"
20 20
21static void nft_meta_bridge_get_eval(const struct nft_expr *expr, 21static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
22 struct nft_data data[NFT_REG_MAX + 1], 22 struct nft_regs *regs,
23 const struct nft_pktinfo *pkt) 23 const struct nft_pktinfo *pkt)
24{ 24{
25 const struct nft_meta *priv = nft_expr_priv(expr); 25 const struct nft_meta *priv = nft_expr_priv(expr);
26 const struct net_device *in = pkt->in, *out = pkt->out; 26 const struct net_device *in = pkt->in, *out = pkt->out;
27 struct nft_data *dest = &data[priv->dreg]; 27 u32 *dest = &regs->data[priv->dreg];
28 const struct net_bridge_port *p; 28 const struct net_bridge_port *p;
29 29
30 switch (priv->key) { 30 switch (priv->key) {
@@ -40,12 +40,12 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
40 goto out; 40 goto out;
41 } 41 }
42 42
43 strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data)); 43 strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
44 return; 44 return;
45out: 45out:
46 return nft_meta_get_eval(expr, data, pkt); 46 return nft_meta_get_eval(expr, regs, pkt);
47err: 47err:
48 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 48 regs->verdict.code = NFT_BREAK;
49} 49}
50 50
51static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, 51static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
@@ -53,27 +53,21 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
53 const struct nlattr * const tb[]) 53 const struct nlattr * const tb[])
54{ 54{
55 struct nft_meta *priv = nft_expr_priv(expr); 55 struct nft_meta *priv = nft_expr_priv(expr);
56 int err; 56 unsigned int len;
57 57
58 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 58 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
59 switch (priv->key) { 59 switch (priv->key) {
60 case NFT_META_BRI_IIFNAME: 60 case NFT_META_BRI_IIFNAME:
61 case NFT_META_BRI_OIFNAME: 61 case NFT_META_BRI_OIFNAME:
62 len = IFNAMSIZ;
62 break; 63 break;
63 default: 64 default:
64 return nft_meta_get_init(ctx, expr, tb); 65 return nft_meta_get_init(ctx, expr, tb);
65 } 66 }
66 67
67 priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 68 priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
68 err = nft_validate_output_register(priv->dreg); 69 return nft_validate_register_store(ctx, priv->dreg, NULL,
69 if (err < 0) 70 NFT_DATA_VALUE, len);
70 return err;
71
72 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
73 if (err < 0)
74 return err;
75
76 return 0;
77} 71}
78 72
79static struct nft_expr_type nft_meta_bridge_type; 73static struct nft_expr_type nft_meta_bridge_type;
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index ae8141f409d9..858d848564ee 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -257,8 +257,8 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
257} 257}
258 258
259static void nft_reject_bridge_eval(const struct nft_expr *expr, 259static void nft_reject_bridge_eval(const struct nft_expr *expr,
260 struct nft_data data[NFT_REG_MAX + 1], 260 struct nft_regs *regs,
261 const struct nft_pktinfo *pkt) 261 const struct nft_pktinfo *pkt)
262{ 262{
263 struct nft_reject *priv = nft_expr_priv(expr); 263 struct nft_reject *priv = nft_expr_priv(expr);
264 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); 264 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
@@ -310,7 +310,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr,
310 break; 310 break;
311 } 311 }
312out: 312out:
313 data[NFT_REG_VERDICT].verdict = NF_DROP; 313 regs->verdict.code = NF_DROP;
314} 314}
315 315
316static int nft_reject_bridge_validate(const struct nft_ctx *ctx, 316static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c
index 665de06561cd..40e414c4ca56 100644
--- a/net/ipv4/netfilter/nft_masq_ipv4.c
+++ b/net/ipv4/netfilter/nft_masq_ipv4.c
@@ -17,20 +17,17 @@
17#include <net/netfilter/ipv4/nf_nat_masquerade.h> 17#include <net/netfilter/ipv4/nf_nat_masquerade.h>
18 18
19static void nft_masq_ipv4_eval(const struct nft_expr *expr, 19static void nft_masq_ipv4_eval(const struct nft_expr *expr,
20 struct nft_data data[NFT_REG_MAX + 1], 20 struct nft_regs *regs,
21 const struct nft_pktinfo *pkt) 21 const struct nft_pktinfo *pkt)
22{ 22{
23 struct nft_masq *priv = nft_expr_priv(expr); 23 struct nft_masq *priv = nft_expr_priv(expr);
24 struct nf_nat_range range; 24 struct nf_nat_range range;
25 unsigned int verdict;
26 25
27 memset(&range, 0, sizeof(range)); 26 memset(&range, 0, sizeof(range));
28 range.flags = priv->flags; 27 range.flags = priv->flags;
29 28
30 verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, 29 regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
31 &range, pkt->out); 30 &range, pkt->out);
32
33 data[NFT_REG_VERDICT].verdict = verdict;
34} 31}
35 32
36static struct nft_expr_type nft_masq_ipv4_type; 33static struct nft_expr_type nft_masq_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
index 6ecfce63201a..d8d795df9c13 100644
--- a/net/ipv4/netfilter/nft_redir_ipv4.c
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -18,26 +18,25 @@
18#include <net/netfilter/nft_redir.h> 18#include <net/netfilter/nft_redir.h>
19 19
20static void nft_redir_ipv4_eval(const struct nft_expr *expr, 20static void nft_redir_ipv4_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_redir *priv = nft_expr_priv(expr); 24 struct nft_redir *priv = nft_expr_priv(expr);
25 struct nf_nat_ipv4_multi_range_compat mr; 25 struct nf_nat_ipv4_multi_range_compat mr;
26 unsigned int verdict;
27 26
28 memset(&mr, 0, sizeof(mr)); 27 memset(&mr, 0, sizeof(mr));
29 if (priv->sreg_proto_min) { 28 if (priv->sreg_proto_min) {
30 mr.range[0].min.all = 29 mr.range[0].min.all =
31 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 30 *(__be16 *)&regs->data[priv->sreg_proto_min];
32 mr.range[0].max.all = 31 mr.range[0].max.all =
33 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 32 *(__be16 *)&regs->data[priv->sreg_proto_max];
34 mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 33 mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
35 } 34 }
36 35
37 mr.range[0].flags |= priv->flags; 36 mr.range[0].flags |= priv->flags;
38 37
39 verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum); 38 regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr,
40 data[NFT_REG_VERDICT].verdict = verdict; 39 pkt->ops->hooknum);
41} 40}
42 41
43static struct nft_expr_type nft_redir_ipv4_type; 42static struct nft_expr_type nft_redir_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index a7621faa9678..b07e58b51158 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -20,7 +20,7 @@
20#include <net/netfilter/nft_reject.h> 20#include <net/netfilter/nft_reject.h>
21 21
22static void nft_reject_ipv4_eval(const struct nft_expr *expr, 22static void nft_reject_ipv4_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1], 23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt) 24 const struct nft_pktinfo *pkt)
25{ 25{
26 struct nft_reject *priv = nft_expr_priv(expr); 26 struct nft_reject *priv = nft_expr_priv(expr);
@@ -37,7 +37,7 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr,
37 break; 37 break;
38 } 38 }
39 39
40 data[NFT_REG_VERDICT].verdict = NF_DROP; 40 regs->verdict.code = NF_DROP;
41} 41}
42 42
43static struct nft_expr_type nft_reject_ipv4_type; 43static struct nft_expr_type nft_reject_ipv4_type;
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c
index 529c119cbb14..cd1ac1637a05 100644
--- a/net/ipv6/netfilter/nft_masq_ipv6.c
+++ b/net/ipv6/netfilter/nft_masq_ipv6.c
@@ -18,19 +18,16 @@
18#include <net/netfilter/ipv6/nf_nat_masquerade.h> 18#include <net/netfilter/ipv6/nf_nat_masquerade.h>
19 19
20static void nft_masq_ipv6_eval(const struct nft_expr *expr, 20static void nft_masq_ipv6_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_masq *priv = nft_expr_priv(expr); 24 struct nft_masq *priv = nft_expr_priv(expr);
25 struct nf_nat_range range; 25 struct nf_nat_range range;
26 unsigned int verdict;
27 26
28 memset(&range, 0, sizeof(range)); 27 memset(&range, 0, sizeof(range));
29 range.flags = priv->flags; 28 range.flags = priv->flags;
30 29
31 verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); 30 regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
32
33 data[NFT_REG_VERDICT].verdict = verdict;
34} 31}
35 32
36static struct nft_expr_type nft_masq_ipv6_type; 33static struct nft_expr_type nft_masq_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c
index 11820b6b3613..effd393bd517 100644
--- a/net/ipv6/netfilter/nft_redir_ipv6.c
+++ b/net/ipv6/netfilter/nft_redir_ipv6.c
@@ -18,26 +18,25 @@
18#include <net/netfilter/nf_nat_redirect.h> 18#include <net/netfilter/nf_nat_redirect.h>
19 19
20static void nft_redir_ipv6_eval(const struct nft_expr *expr, 20static void nft_redir_ipv6_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_redir *priv = nft_expr_priv(expr); 24 struct nft_redir *priv = nft_expr_priv(expr);
25 struct nf_nat_range range; 25 struct nf_nat_range range;
26 unsigned int verdict;
27 26
28 memset(&range, 0, sizeof(range)); 27 memset(&range, 0, sizeof(range));
29 if (priv->sreg_proto_min) { 28 if (priv->sreg_proto_min) {
30 range.min_proto.all = 29 range.min_proto.all =
31 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 30 *(__be16 *)&regs->data[priv->sreg_proto_min],
32 range.max_proto.all = 31 range.max_proto.all =
33 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 32 *(__be16 *)&regs->data[priv->sreg_proto_max],
34 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 33 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
35 } 34 }
36 35
37 range.flags |= priv->flags; 36 range.flags |= priv->flags;
38 37
39 verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum); 38 regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range,
40 data[NFT_REG_VERDICT].verdict = verdict; 39 pkt->ops->hooknum);
41} 40}
42 41
43static struct nft_expr_type nft_redir_ipv6_type; 42static struct nft_expr_type nft_redir_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 71c7be5ee43a..d0d1540ecf87 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -20,7 +20,7 @@
20#include <net/netfilter/ipv6/nf_reject.h> 20#include <net/netfilter/ipv6/nf_reject.h>
21 21
22static void nft_reject_ipv6_eval(const struct nft_expr *expr, 22static void nft_reject_ipv6_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1], 23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt) 24 const struct nft_pktinfo *pkt)
25{ 25{
26 struct nft_reject *priv = nft_expr_priv(expr); 26 struct nft_reject *priv = nft_expr_priv(expr);
@@ -38,7 +38,7 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr,
38 break; 38 break;
39 } 39 }
40 40
41 data[NFT_REG_VERDICT].verdict = NF_DROP; 41 regs->verdict.code = NF_DROP;
42} 42}
43 43
44static struct nft_expr_type nft_reject_ipv6_type; 44static struct nft_expr_type nft_reject_ipv6_type;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0b96fa0d64b2..78af83bc9c8e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1545,6 +1545,23 @@ nla_put_failure:
1545 return -1; 1545 return -1;
1546}; 1546};
1547 1547
1548int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
1549 const struct nft_expr *expr)
1550{
1551 struct nlattr *nest;
1552
1553 nest = nla_nest_start(skb, attr);
1554 if (!nest)
1555 goto nla_put_failure;
1556 if (nf_tables_fill_expr_info(skb, expr) < 0)
1557 goto nla_put_failure;
1558 nla_nest_end(skb, nest);
1559 return 0;
1560
1561nla_put_failure:
1562 return -1;
1563}
1564
1548struct nft_expr_info { 1565struct nft_expr_info {
1549 const struct nft_expr_ops *ops; 1566 const struct nft_expr_ops *ops;
1550 struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; 1567 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
@@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
1622 module_put(expr->ops->type->owner); 1639 module_put(expr->ops->type->owner);
1623} 1640}
1624 1641
1642struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
1643 const struct nlattr *nla)
1644{
1645 struct nft_expr_info info;
1646 struct nft_expr *expr;
1647 int err;
1648
1649 err = nf_tables_expr_parse(ctx, nla, &info);
1650 if (err < 0)
1651 goto err1;
1652
1653 err = -ENOMEM;
1654 expr = kzalloc(info.ops->size, GFP_KERNEL);
1655 if (expr == NULL)
1656 goto err2;
1657
1658 err = nf_tables_newexpr(ctx, &info, expr);
1659 if (err < 0)
1660 goto err2;
1661
1662 return expr;
1663err2:
1664 module_put(info.ops->type->owner);
1665err1:
1666 return ERR_PTR(err);
1667}
1668
1669void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
1670{
1671 nf_tables_expr_destroy(ctx, expr);
1672 kfree(expr);
1673}
1674
1625/* 1675/*
1626 * Rules 1676 * Rules
1627 */ 1677 */
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
1703 if (list == NULL) 1753 if (list == NULL)
1704 goto nla_put_failure; 1754 goto nla_put_failure;
1705 nft_rule_for_each_expr(expr, next, rule) { 1755 nft_rule_for_each_expr(expr, next, rule) {
1706 struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM); 1756 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
1707 if (elem == NULL)
1708 goto nla_put_failure; 1757 goto nla_put_failure;
1709 if (nf_tables_fill_expr_info(skb, expr) < 0)
1710 goto nla_put_failure;
1711 nla_nest_end(skb, elem);
1712 } 1758 }
1713 nla_nest_end(skb, list); 1759 nla_nest_end(skb, list);
1714 1760
@@ -2608,16 +2654,20 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2608 } 2654 }
2609 2655
2610 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN])); 2656 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
2611 if (desc.klen == 0 || desc.klen > FIELD_SIZEOF(struct nft_data, data)) 2657 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
2612 return -EINVAL; 2658 return -EINVAL;
2613 2659
2614 flags = 0; 2660 flags = 0;
2615 if (nla[NFTA_SET_FLAGS] != NULL) { 2661 if (nla[NFTA_SET_FLAGS] != NULL) {
2616 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS])); 2662 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2617 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT | 2663 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2618 NFT_SET_INTERVAL | NFT_SET_MAP | 2664 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
2619 NFT_SET_TIMEOUT)) 2665 NFT_SET_MAP | NFT_SET_EVAL))
2620 return -EINVAL; 2666 return -EINVAL;
2667 /* Only one of both operations is supported */
2668 if ((flags & (NFT_SET_MAP | NFT_SET_EVAL)) ==
2669 (NFT_SET_MAP | NFT_SET_EVAL))
2670 return -EOPNOTSUPP;
2621 } 2671 }
2622 2672
2623 dtype = 0; 2673 dtype = 0;
@@ -2634,11 +2684,10 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2634 if (nla[NFTA_SET_DATA_LEN] == NULL) 2684 if (nla[NFTA_SET_DATA_LEN] == NULL)
2635 return -EINVAL; 2685 return -EINVAL;
2636 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN])); 2686 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
2637 if (desc.dlen == 0 || 2687 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
2638 desc.dlen > FIELD_SIZEOF(struct nft_data, data))
2639 return -EINVAL; 2688 return -EINVAL;
2640 } else 2689 } else
2641 desc.dlen = sizeof(struct nft_data); 2690 desc.dlen = sizeof(struct nft_verdict);
2642 } else if (flags & NFT_SET_MAP) 2691 } else if (flags & NFT_SET_MAP)
2643 return -EINVAL; 2692 return -EINVAL;
2644 2693
@@ -2797,9 +2846,10 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2797 enum nft_registers dreg; 2846 enum nft_registers dreg;
2798 2847
2799 dreg = nft_type_to_reg(set->dtype); 2848 dreg = nft_type_to_reg(set->dtype);
2800 return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext), 2849 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
2801 set->dtype == NFT_DATA_VERDICT ? 2850 set->dtype == NFT_DATA_VERDICT ?
2802 NFT_DATA_VERDICT : NFT_DATA_VALUE); 2851 NFT_DATA_VERDICT : NFT_DATA_VALUE,
2852 set->dlen);
2803} 2853}
2804 2854
2805int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, 2855int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
@@ -2853,12 +2903,13 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2853 2903
2854const struct nft_set_ext_type nft_set_ext_types[] = { 2904const struct nft_set_ext_type nft_set_ext_types[] = {
2855 [NFT_SET_EXT_KEY] = { 2905 [NFT_SET_EXT_KEY] = {
2856 .len = sizeof(struct nft_data), 2906 .align = __alignof__(u32),
2857 .align = __alignof__(struct nft_data),
2858 }, 2907 },
2859 [NFT_SET_EXT_DATA] = { 2908 [NFT_SET_EXT_DATA] = {
2860 .len = sizeof(struct nft_data), 2909 .align = __alignof__(u32),
2861 .align = __alignof__(struct nft_data), 2910 },
2911 [NFT_SET_EXT_EXPR] = {
2912 .align = __alignof__(struct nft_expr),
2862 }, 2913 },
2863 [NFT_SET_EXT_FLAGS] = { 2914 [NFT_SET_EXT_FLAGS] = {
2864 .len = sizeof(u8), 2915 .len = sizeof(u8),
@@ -2946,6 +2997,10 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
2946 set->dlen) < 0) 2997 set->dlen) < 0)
2947 goto nla_put_failure; 2998 goto nla_put_failure;
2948 2999
3000 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3001 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3002 goto nla_put_failure;
3003
2949 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && 3004 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
2950 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS, 3005 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
2951 htonl(*nft_set_ext_flags(ext)))) 3006 htonl(*nft_set_ext_flags(ext))))
@@ -3200,8 +3255,7 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3200 3255
3201void *nft_set_elem_init(const struct nft_set *set, 3256void *nft_set_elem_init(const struct nft_set *set,
3202 const struct nft_set_ext_tmpl *tmpl, 3257 const struct nft_set_ext_tmpl *tmpl,
3203 const struct nft_data *key, 3258 const u32 *key, const u32 *data,
3204 const struct nft_data *data,
3205 u64 timeout, gfp_t gfp) 3259 u64 timeout, gfp_t gfp)
3206{ 3260{
3207 struct nft_set_ext *ext; 3261 struct nft_set_ext *ext;
@@ -3233,6 +3287,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem)
3233 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE); 3287 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
3234 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) 3288 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3235 nft_data_uninit(nft_set_ext_data(ext), set->dtype); 3289 nft_data_uninit(nft_set_ext_data(ext), set->dtype);
3290 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3291 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3236 3292
3237 kfree(elem); 3293 kfree(elem);
3238} 3294}
@@ -3299,14 +3355,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3299 timeout = set->timeout; 3355 timeout = set->timeout;
3300 } 3356 }
3301 3357
3302 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]); 3358 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
3359 nla[NFTA_SET_ELEM_KEY]);
3303 if (err < 0) 3360 if (err < 0)
3304 goto err1; 3361 goto err1;
3305 err = -EINVAL; 3362 err = -EINVAL;
3306 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen) 3363 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3307 goto err2; 3364 goto err2;
3308 3365
3309 nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY); 3366 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
3310 if (timeout > 0) { 3367 if (timeout > 0) {
3311 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION); 3368 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3312 if (timeout != set->timeout) 3369 if (timeout != set->timeout)
@@ -3314,7 +3371,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3314 } 3371 }
3315 3372
3316 if (nla[NFTA_SET_ELEM_DATA] != NULL) { 3373 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
3317 err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]); 3374 err = nft_data_init(ctx, &data, sizeof(data), &d2,
3375 nla[NFTA_SET_ELEM_DATA]);
3318 if (err < 0) 3376 if (err < 0)
3319 goto err2; 3377 goto err2;
3320 3378
@@ -3333,13 +3391,14 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3333 if (!(binding->flags & NFT_SET_MAP)) 3391 if (!(binding->flags & NFT_SET_MAP))
3334 continue; 3392 continue;
3335 3393
3336 err = nft_validate_data_load(&bind_ctx, dreg, 3394 err = nft_validate_register_store(&bind_ctx, dreg,
3337 &data, d2.type); 3395 &data,
3396 d2.type, d2.len);
3338 if (err < 0) 3397 if (err < 0)
3339 goto err3; 3398 goto err3;
3340 } 3399 }
3341 3400
3342 nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA); 3401 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
3343 } 3402 }
3344 3403
3345 /* The full maximum length of userdata can exceed the maximum 3404 /* The full maximum length of userdata can exceed the maximum
@@ -3355,7 +3414,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3355 } 3414 }
3356 3415
3357 err = -ENOMEM; 3416 err = -ENOMEM;
3358 elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data, 3417 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
3359 timeout, GFP_KERNEL); 3418 timeout, GFP_KERNEL);
3360 if (elem.priv == NULL) 3419 if (elem.priv == NULL)
3361 goto err3; 3420 goto err3;
@@ -3390,7 +3449,7 @@ err3:
3390 if (nla[NFTA_SET_ELEM_DATA] != NULL) 3449 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3391 nft_data_uninit(&data, d2.type); 3450 nft_data_uninit(&data, d2.type);
3392err2: 3451err2:
3393 nft_data_uninit(&elem.key, d1.type); 3452 nft_data_uninit(&elem.key.val, d1.type);
3394err1: 3453err1:
3395 return err; 3454 return err;
3396} 3455}
@@ -3457,7 +3516,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3457 if (nla[NFTA_SET_ELEM_KEY] == NULL) 3516 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3458 goto err1; 3517 goto err1;
3459 3518
3460 err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]); 3519 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
3520 nla[NFTA_SET_ELEM_KEY]);
3461 if (err < 0) 3521 if (err < 0)
3462 goto err1; 3522 goto err1;
3463 3523
@@ -3484,7 +3544,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3484err3: 3544err3:
3485 kfree(trans); 3545 kfree(trans);
3486err2: 3546err2:
3487 nft_data_uninit(&elem.key, desc.type); 3547 nft_data_uninit(&elem.key.val, desc.type);
3488err1: 3548err1:
3489 return err; 3549 return err;
3490} 3550}
@@ -4047,10 +4107,10 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
4047 return 0; 4107 return 0;
4048 4108
4049 data = nft_set_ext_data(ext); 4109 data = nft_set_ext_data(ext);
4050 switch (data->verdict) { 4110 switch (data->verdict.code) {
4051 case NFT_JUMP: 4111 case NFT_JUMP:
4052 case NFT_GOTO: 4112 case NFT_GOTO:
4053 return nf_tables_check_loops(ctx, data->chain); 4113 return nf_tables_check_loops(ctx, data->verdict.chain);
4054 default: 4114 default:
4055 return 0; 4115 return 0;
4056 } 4116 }
@@ -4083,10 +4143,11 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
4083 if (data == NULL) 4143 if (data == NULL)
4084 continue; 4144 continue;
4085 4145
4086 switch (data->verdict) { 4146 switch (data->verdict.code) {
4087 case NFT_JUMP: 4147 case NFT_JUMP:
4088 case NFT_GOTO: 4148 case NFT_GOTO:
4089 err = nf_tables_check_loops(ctx, data->chain); 4149 err = nf_tables_check_loops(ctx,
4150 data->verdict.chain);
4090 if (err < 0) 4151 if (err < 0)
4091 return err; 4152 return err;
4092 default: 4153 default:
@@ -4120,85 +4181,129 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
4120} 4181}
4121 4182
4122/** 4183/**
4123 * nft_validate_input_register - validate an expressions' input register 4184 * nft_parse_register - parse a register value from a netlink attribute
4124 * 4185 *
4125 * @reg: the register number 4186 * @attr: netlink attribute
4126 * 4187 *
4127 * Validate that the input register is one of the general purpose 4188 * Parse and translate a register value from a netlink attribute.
4128 * registers. 4189 * Registers used to be 128 bit wide, these register numbers will be
4190 * mapped to the corresponding 32 bit register numbers.
4129 */ 4191 */
4130int nft_validate_input_register(enum nft_registers reg) 4192unsigned int nft_parse_register(const struct nlattr *attr)
4131{ 4193{
4132 if (reg <= NFT_REG_VERDICT) 4194 unsigned int reg;
4133 return -EINVAL; 4195
4134 if (reg > NFT_REG_MAX) 4196 reg = ntohl(nla_get_be32(attr));
4135 return -ERANGE; 4197 switch (reg) {
4136 return 0; 4198 case NFT_REG_VERDICT...NFT_REG_4:
4199 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
4200 default:
4201 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
4202 }
4137} 4203}
4138EXPORT_SYMBOL_GPL(nft_validate_input_register); 4204EXPORT_SYMBOL_GPL(nft_parse_register);
4139 4205
4140/** 4206/**
4141 * nft_validate_output_register - validate an expressions' output register 4207 * nft_dump_register - dump a register value to a netlink attribute
4208 *
4209 * @skb: socket buffer
4210 * @attr: attribute number
4211 * @reg: register number
4212 *
4213 * Construct a netlink attribute containing the register number. For
4214 * compatibility reasons, register numbers being a multiple of 4 are
4215 * translated to the corresponding 128 bit register numbers.
4216 */
4217int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
4218{
4219 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
4220 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
4221 else
4222 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
4223
4224 return nla_put_be32(skb, attr, htonl(reg));
4225}
4226EXPORT_SYMBOL_GPL(nft_dump_register);
4227
4228/**
4229 * nft_validate_register_load - validate a load from a register
4142 * 4230 *
4143 * @reg: the register number 4231 * @reg: the register number
4232 * @len: the length of the data
4144 * 4233 *
4145 * Validate that the output register is one of the general purpose 4234 * Validate that the input register is one of the general purpose
4146 * registers or the verdict register. 4235 * registers and that the length of the load is within the bounds.
4147 */ 4236 */
4148int nft_validate_output_register(enum nft_registers reg) 4237int nft_validate_register_load(enum nft_registers reg, unsigned int len)
4149{ 4238{
4150 if (reg < NFT_REG_VERDICT) 4239 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
4240 return -EINVAL;
4241 if (len == 0)
4151 return -EINVAL; 4242 return -EINVAL;
4152 if (reg > NFT_REG_MAX) 4243 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
4153 return -ERANGE; 4244 return -ERANGE;
4245
4154 return 0; 4246 return 0;
4155} 4247}
4156EXPORT_SYMBOL_GPL(nft_validate_output_register); 4248EXPORT_SYMBOL_GPL(nft_validate_register_load);
4157 4249
4158/** 4250/**
4159 * nft_validate_data_load - validate an expressions' data load 4251 * nft_validate_register_store - validate an expressions' register store
4160 * 4252 *
4161 * @ctx: context of the expression performing the load 4253 * @ctx: context of the expression performing the load
4162 * @reg: the destination register number 4254 * @reg: the destination register number
4163 * @data: the data to load 4255 * @data: the data to load
4164 * @type: the data type 4256 * @type: the data type
4257 * @len: the length of the data
4165 * 4258 *
4166 * Validate that a data load uses the appropriate data type for 4259 * Validate that a data load uses the appropriate data type for
4167 * the destination register. A value of NULL for the data means 4260 * the destination register and the length is within the bounds.
4168 * that its runtime gathered data, which is always of type 4261 * A value of NULL for the data means that its runtime gathered
4169 * NFT_DATA_VALUE. 4262 * data.
4170 */ 4263 */
4171int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg, 4264int nft_validate_register_store(const struct nft_ctx *ctx,
4172 const struct nft_data *data, 4265 enum nft_registers reg,
4173 enum nft_data_types type) 4266 const struct nft_data *data,
4267 enum nft_data_types type, unsigned int len)
4174{ 4268{
4175 int err; 4269 int err;
4176 4270
4177 switch (reg) { 4271 switch (reg) {
4178 case NFT_REG_VERDICT: 4272 case NFT_REG_VERDICT:
4179 if (data == NULL || type != NFT_DATA_VERDICT) 4273 if (type != NFT_DATA_VERDICT)
4180 return -EINVAL; 4274 return -EINVAL;
4181 4275
4182 if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) { 4276 if (data != NULL &&
4183 err = nf_tables_check_loops(ctx, data->chain); 4277 (data->verdict.code == NFT_GOTO ||
4278 data->verdict.code == NFT_JUMP)) {
4279 err = nf_tables_check_loops(ctx, data->verdict.chain);
4184 if (err < 0) 4280 if (err < 0)
4185 return err; 4281 return err;
4186 4282
4187 if (ctx->chain->level + 1 > data->chain->level) { 4283 if (ctx->chain->level + 1 >
4284 data->verdict.chain->level) {
4188 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE) 4285 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
4189 return -EMLINK; 4286 return -EMLINK;
4190 data->chain->level = ctx->chain->level + 1; 4287 data->verdict.chain->level = ctx->chain->level + 1;
4191 } 4288 }
4192 } 4289 }
4193 4290
4194 return 0; 4291 return 0;
4195 default: 4292 default:
4293 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
4294 return -EINVAL;
4295 if (len == 0)
4296 return -EINVAL;
4297 if (reg * NFT_REG32_SIZE + len >
4298 FIELD_SIZEOF(struct nft_regs, data))
4299 return -ERANGE;
4300
4196 if (data != NULL && type != NFT_DATA_VALUE) 4301 if (data != NULL && type != NFT_DATA_VALUE)
4197 return -EINVAL; 4302 return -EINVAL;
4198 return 0; 4303 return 0;
4199 } 4304 }
4200} 4305}
4201EXPORT_SYMBOL_GPL(nft_validate_data_load); 4306EXPORT_SYMBOL_GPL(nft_validate_register_store);
4202 4307
4203static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = { 4308static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
4204 [NFTA_VERDICT_CODE] = { .type = NLA_U32 }, 4309 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
@@ -4219,11 +4324,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4219 4324
4220 if (!tb[NFTA_VERDICT_CODE]) 4325 if (!tb[NFTA_VERDICT_CODE])
4221 return -EINVAL; 4326 return -EINVAL;
4222 data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); 4327 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
4223 4328
4224 switch (data->verdict) { 4329 switch (data->verdict.code) {
4225 default: 4330 default:
4226 switch (data->verdict & NF_VERDICT_MASK) { 4331 switch (data->verdict.code & NF_VERDICT_MASK) {
4227 case NF_ACCEPT: 4332 case NF_ACCEPT:
4228 case NF_DROP: 4333 case NF_DROP:
4229 case NF_QUEUE: 4334 case NF_QUEUE:
@@ -4249,7 +4354,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4249 return -EOPNOTSUPP; 4354 return -EOPNOTSUPP;
4250 4355
4251 chain->use++; 4356 chain->use++;
4252 data->chain = chain; 4357 data->verdict.chain = chain;
4253 desc->len = sizeof(data); 4358 desc->len = sizeof(data);
4254 break; 4359 break;
4255 } 4360 }
@@ -4260,10 +4365,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4260 4365
4261static void nft_verdict_uninit(const struct nft_data *data) 4366static void nft_verdict_uninit(const struct nft_data *data)
4262{ 4367{
4263 switch (data->verdict) { 4368 switch (data->verdict.code) {
4264 case NFT_JUMP: 4369 case NFT_JUMP:
4265 case NFT_GOTO: 4370 case NFT_GOTO:
4266 data->chain->use--; 4371 data->verdict.chain->use--;
4267 break; 4372 break;
4268 } 4373 }
4269} 4374}
@@ -4276,13 +4381,14 @@ static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
4276 if (!nest) 4381 if (!nest)
4277 goto nla_put_failure; 4382 goto nla_put_failure;
4278 4383
4279 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict))) 4384 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict.code)))
4280 goto nla_put_failure; 4385 goto nla_put_failure;
4281 4386
4282 switch (data->verdict) { 4387 switch (data->verdict.code) {
4283 case NFT_JUMP: 4388 case NFT_JUMP:
4284 case NFT_GOTO: 4389 case NFT_GOTO:
4285 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name)) 4390 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
4391 data->verdict.chain->name))
4286 goto nla_put_failure; 4392 goto nla_put_failure;
4287 } 4393 }
4288 nla_nest_end(skb, nest); 4394 nla_nest_end(skb, nest);
@@ -4292,7 +4398,8 @@ nla_put_failure:
4292 return -1; 4398 return -1;
4293} 4399}
4294 4400
4295static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, 4401static int nft_value_init(const struct nft_ctx *ctx,
4402 struct nft_data *data, unsigned int size,
4296 struct nft_data_desc *desc, const struct nlattr *nla) 4403 struct nft_data_desc *desc, const struct nlattr *nla)
4297{ 4404{
4298 unsigned int len; 4405 unsigned int len;
@@ -4300,10 +4407,10 @@ static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
4300 len = nla_len(nla); 4407 len = nla_len(nla);
4301 if (len == 0) 4408 if (len == 0)
4302 return -EINVAL; 4409 return -EINVAL;
4303 if (len > sizeof(data->data)) 4410 if (len > size)
4304 return -EOVERFLOW; 4411 return -EOVERFLOW;
4305 4412
4306 nla_memcpy(data->data, nla, sizeof(data->data)); 4413 nla_memcpy(data->data, nla, len);
4307 desc->type = NFT_DATA_VALUE; 4414 desc->type = NFT_DATA_VALUE;
4308 desc->len = len; 4415 desc->len = len;
4309 return 0; 4416 return 0;
@@ -4316,8 +4423,7 @@ static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
4316} 4423}
4317 4424
4318static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { 4425static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4319 [NFTA_DATA_VALUE] = { .type = NLA_BINARY, 4426 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
4320 .len = FIELD_SIZEOF(struct nft_data, data) },
4321 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED }, 4427 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
4322}; 4428};
4323 4429
@@ -4326,6 +4432,7 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4326 * 4432 *
4327 * @ctx: context of the expression using the data 4433 * @ctx: context of the expression using the data
4328 * @data: destination struct nft_data 4434 * @data: destination struct nft_data
4435 * @size: maximum data length
4329 * @desc: data description 4436 * @desc: data description
4330 * @nla: netlink attribute containing data 4437 * @nla: netlink attribute containing data
4331 * 4438 *
@@ -4335,7 +4442,8 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4335 * The caller can indicate that it only wants to accept data of type 4442 * The caller can indicate that it only wants to accept data of type
4336 * NFT_DATA_VALUE by passing NULL for the ctx argument. 4443 * NFT_DATA_VALUE by passing NULL for the ctx argument.
4337 */ 4444 */
4338int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 4445int nft_data_init(const struct nft_ctx *ctx,
4446 struct nft_data *data, unsigned int size,
4339 struct nft_data_desc *desc, const struct nlattr *nla) 4447 struct nft_data_desc *desc, const struct nlattr *nla)
4340{ 4448{
4341 struct nlattr *tb[NFTA_DATA_MAX + 1]; 4449 struct nlattr *tb[NFTA_DATA_MAX + 1];
@@ -4346,7 +4454,8 @@ int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
4346 return err; 4454 return err;
4347 4455
4348 if (tb[NFTA_DATA_VALUE]) 4456 if (tb[NFTA_DATA_VALUE])
4349 return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]); 4457 return nft_value_init(ctx, data, size, desc,
4458 tb[NFTA_DATA_VALUE]);
4350 if (tb[NFTA_DATA_VERDICT] && ctx != NULL) 4459 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
4351 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); 4460 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
4352 return -EINVAL; 4461 return -EINVAL;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 7caf08a9225d..f153b07073af 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -65,23 +65,23 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
65} 65}
66 66
67static void nft_cmp_fast_eval(const struct nft_expr *expr, 67static void nft_cmp_fast_eval(const struct nft_expr *expr,
68 struct nft_data data[NFT_REG_MAX + 1]) 68 struct nft_regs *regs)
69{ 69{
70 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); 70 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
71 u32 mask = nft_cmp_fast_mask(priv->len); 71 u32 mask = nft_cmp_fast_mask(priv->len);
72 72
73 if ((data[priv->sreg].data[0] & mask) == priv->data) 73 if ((regs->data[priv->sreg] & mask) == priv->data)
74 return; 74 return;
75 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 75 regs->verdict.code = NFT_BREAK;
76} 76}
77 77
78static bool nft_payload_fast_eval(const struct nft_expr *expr, 78static bool nft_payload_fast_eval(const struct nft_expr *expr,
79 struct nft_data data[NFT_REG_MAX + 1], 79 struct nft_regs *regs,
80 const struct nft_pktinfo *pkt) 80 const struct nft_pktinfo *pkt)
81{ 81{
82 const struct nft_payload *priv = nft_expr_priv(expr); 82 const struct nft_payload *priv = nft_expr_priv(expr);
83 const struct sk_buff *skb = pkt->skb; 83 const struct sk_buff *skb = pkt->skb;
84 struct nft_data *dest = &data[priv->dreg]; 84 u32 *dest = &regs->data[priv->dreg];
85 unsigned char *ptr; 85 unsigned char *ptr;
86 86
87 if (priv->base == NFT_PAYLOAD_NETWORK_HEADER) 87 if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -94,12 +94,13 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
94 if (unlikely(ptr + priv->len >= skb_tail_pointer(skb))) 94 if (unlikely(ptr + priv->len >= skb_tail_pointer(skb)))
95 return false; 95 return false;
96 96
97 *dest = 0;
97 if (priv->len == 2) 98 if (priv->len == 2)
98 *(u16 *)dest->data = *(u16 *)ptr; 99 *(u16 *)dest = *(u16 *)ptr;
99 else if (priv->len == 4) 100 else if (priv->len == 4)
100 *(u32 *)dest->data = *(u32 *)ptr; 101 *(u32 *)dest = *(u32 *)ptr;
101 else 102 else
102 *(u8 *)dest->data = *(u8 *)ptr; 103 *(u8 *)dest = *(u8 *)ptr;
103 return true; 104 return true;
104} 105}
105 106
@@ -116,7 +117,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
116 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet); 117 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
117 const struct nft_rule *rule; 118 const struct nft_rule *rule;
118 const struct nft_expr *expr, *last; 119 const struct nft_expr *expr, *last;
119 struct nft_data data[NFT_REG_MAX + 1]; 120 struct nft_regs regs;
120 unsigned int stackptr = 0; 121 unsigned int stackptr = 0;
121 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; 122 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
122 struct nft_stats *stats; 123 struct nft_stats *stats;
@@ -127,7 +128,7 @@ do_chain:
127 rulenum = 0; 128 rulenum = 0;
128 rule = list_entry(&chain->rules, struct nft_rule, list); 129 rule = list_entry(&chain->rules, struct nft_rule, list);
129next_rule: 130next_rule:
130 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 131 regs.verdict.code = NFT_CONTINUE;
131 list_for_each_entry_continue_rcu(rule, &chain->rules, list) { 132 list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
132 133
133 /* This rule is not active, skip. */ 134 /* This rule is not active, skip. */
@@ -138,18 +139,18 @@ next_rule:
138 139
139 nft_rule_for_each_expr(expr, last, rule) { 140 nft_rule_for_each_expr(expr, last, rule) {
140 if (expr->ops == &nft_cmp_fast_ops) 141 if (expr->ops == &nft_cmp_fast_ops)
141 nft_cmp_fast_eval(expr, data); 142 nft_cmp_fast_eval(expr, &regs);
142 else if (expr->ops != &nft_payload_fast_ops || 143 else if (expr->ops != &nft_payload_fast_ops ||
143 !nft_payload_fast_eval(expr, data, pkt)) 144 !nft_payload_fast_eval(expr, &regs, pkt))
144 expr->ops->eval(expr, data, pkt); 145 expr->ops->eval(expr, &regs, pkt);
145 146
146 if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE) 147 if (regs.verdict.code != NFT_CONTINUE)
147 break; 148 break;
148 } 149 }
149 150
150 switch (data[NFT_REG_VERDICT].verdict) { 151 switch (regs.verdict.code) {
151 case NFT_BREAK: 152 case NFT_BREAK:
152 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 153 regs.verdict.code = NFT_CONTINUE;
153 continue; 154 continue;
154 case NFT_CONTINUE: 155 case NFT_CONTINUE:
155 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 156 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
@@ -158,15 +159,15 @@ next_rule:
158 break; 159 break;
159 } 160 }
160 161
161 switch (data[NFT_REG_VERDICT].verdict & NF_VERDICT_MASK) { 162 switch (regs.verdict.code & NF_VERDICT_MASK) {
162 case NF_ACCEPT: 163 case NF_ACCEPT:
163 case NF_DROP: 164 case NF_DROP:
164 case NF_QUEUE: 165 case NF_QUEUE:
165 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 166 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
166 return data[NFT_REG_VERDICT].verdict; 167 return regs.verdict.code;
167 } 168 }
168 169
169 switch (data[NFT_REG_VERDICT].verdict) { 170 switch (regs.verdict.code) {
170 case NFT_JUMP: 171 case NFT_JUMP:
171 BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE); 172 BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE);
172 jumpstack[stackptr].chain = chain; 173 jumpstack[stackptr].chain = chain;
@@ -177,7 +178,7 @@ next_rule:
177 case NFT_GOTO: 178 case NFT_GOTO:
178 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 179 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
179 180
180 chain = data[NFT_REG_VERDICT].chain; 181 chain = regs.verdict.chain;
181 goto do_chain; 182 goto do_chain;
182 case NFT_CONTINUE: 183 case NFT_CONTINUE:
183 rulenum++; 184 rulenum++;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 4fb6ee2c1106..d71cc18fa35d 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -26,18 +26,16 @@ struct nft_bitwise {
26}; 26};
27 27
28static void nft_bitwise_eval(const struct nft_expr *expr, 28static void nft_bitwise_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_bitwise *priv = nft_expr_priv(expr); 32 const struct nft_bitwise *priv = nft_expr_priv(expr);
33 const struct nft_data *src = &data[priv->sreg]; 33 const u32 *src = &regs->data[priv->sreg];
34 struct nft_data *dst = &data[priv->dreg]; 34 u32 *dst = &regs->data[priv->dreg];
35 unsigned int i; 35 unsigned int i;
36 36
37 for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++) { 37 for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
38 dst->data[i] = (src->data[i] & priv->mask.data[i]) ^ 38 dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
39 priv->xor.data[i];
40 }
41} 39}
42 40
43static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = { 41static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
@@ -63,28 +61,27 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
63 tb[NFTA_BITWISE_XOR] == NULL) 61 tb[NFTA_BITWISE_XOR] == NULL)
64 return -EINVAL; 62 return -EINVAL;
65 63
66 priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG])); 64 priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
67 err = nft_validate_input_register(priv->sreg); 65 priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
66 err = nft_validate_register_load(priv->sreg, priv->len);
68 if (err < 0) 67 if (err < 0)
69 return err; 68 return err;
70 69
71 priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG])); 70 priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
72 err = nft_validate_output_register(priv->dreg); 71 err = nft_validate_register_store(ctx, priv->dreg, NULL,
72 NFT_DATA_VALUE, priv->len);
73 if (err < 0) 73 if (err < 0)
74 return err; 74 return err;
75 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
76 if (err < 0)
77 return err;
78
79 priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
80 75
81 err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]); 76 err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
77 tb[NFTA_BITWISE_MASK]);
82 if (err < 0) 78 if (err < 0)
83 return err; 79 return err;
84 if (d1.len != priv->len) 80 if (d1.len != priv->len)
85 return -EINVAL; 81 return -EINVAL;
86 82
87 err = nft_data_init(NULL, &priv->xor, &d2, tb[NFTA_BITWISE_XOR]); 83 err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
84 tb[NFTA_BITWISE_XOR]);
88 if (err < 0) 85 if (err < 0)
89 return err; 86 return err;
90 if (d2.len != priv->len) 87 if (d2.len != priv->len)
@@ -97,9 +94,9 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
97{ 94{
98 const struct nft_bitwise *priv = nft_expr_priv(expr); 95 const struct nft_bitwise *priv = nft_expr_priv(expr);
99 96
100 if (nla_put_be32(skb, NFTA_BITWISE_SREG, htonl(priv->sreg))) 97 if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
101 goto nla_put_failure; 98 goto nla_put_failure;
102 if (nla_put_be32(skb, NFTA_BITWISE_DREG, htonl(priv->dreg))) 99 if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg))
103 goto nla_put_failure; 100 goto nla_put_failure;
104 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len))) 101 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
105 goto nla_put_failure; 102 goto nla_put_failure;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index c39ed8d29df1..fde5145f2e36 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -26,16 +26,17 @@ struct nft_byteorder {
26}; 26};
27 27
28static void nft_byteorder_eval(const struct nft_expr *expr, 28static void nft_byteorder_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_byteorder *priv = nft_expr_priv(expr); 32 const struct nft_byteorder *priv = nft_expr_priv(expr);
33 struct nft_data *src = &data[priv->sreg], *dst = &data[priv->dreg]; 33 u32 *src = &regs->data[priv->sreg];
34 u32 *dst = &regs->data[priv->dreg];
34 union { u32 u32; u16 u16; } *s, *d; 35 union { u32 u32; u16 u16; } *s, *d;
35 unsigned int i; 36 unsigned int i;
36 37
37 s = (void *)src->data; 38 s = (void *)src;
38 d = (void *)dst->data; 39 d = (void *)dst;
39 40
40 switch (priv->size) { 41 switch (priv->size) {
41 case 4: 42 case 4:
@@ -87,19 +88,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
87 tb[NFTA_BYTEORDER_OP] == NULL) 88 tb[NFTA_BYTEORDER_OP] == NULL)
88 return -EINVAL; 89 return -EINVAL;
89 90
90 priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
91 err = nft_validate_input_register(priv->sreg);
92 if (err < 0)
93 return err;
94
95 priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
96 err = nft_validate_output_register(priv->dreg);
97 if (err < 0)
98 return err;
99 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
100 if (err < 0)
101 return err;
102
103 priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP])); 91 priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP]));
104 switch (priv->op) { 92 switch (priv->op) {
105 case NFT_BYTEORDER_NTOH: 93 case NFT_BYTEORDER_NTOH:
@@ -109,10 +97,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
109 return -EINVAL; 97 return -EINVAL;
110 } 98 }
111 99
112 priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
113 if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
114 return -EINVAL;
115
116 priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE])); 100 priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
117 switch (priv->size) { 101 switch (priv->size) {
118 case 2: 102 case 2:
@@ -122,16 +106,24 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
122 return -EINVAL; 106 return -EINVAL;
123 } 107 }
124 108
125 return 0; 109 priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
110 priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
111 err = nft_validate_register_load(priv->sreg, priv->len);
112 if (err < 0)
113 return err;
114
115 priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
116 return nft_validate_register_store(ctx, priv->dreg, NULL,
117 NFT_DATA_VALUE, priv->len);
126} 118}
127 119
128static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr) 120static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
129{ 121{
130 const struct nft_byteorder *priv = nft_expr_priv(expr); 122 const struct nft_byteorder *priv = nft_expr_priv(expr);
131 123
132 if (nla_put_be32(skb, NFTA_BYTEORDER_SREG, htonl(priv->sreg))) 124 if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg))
133 goto nla_put_failure; 125 goto nla_put_failure;
134 if (nla_put_be32(skb, NFTA_BYTEORDER_DREG, htonl(priv->dreg))) 126 if (nft_dump_register(skb, NFTA_BYTEORDER_DREG, priv->dreg))
135 goto nla_put_failure; 127 goto nla_put_failure;
136 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op))) 128 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op)))
137 goto nla_put_failure; 129 goto nla_put_failure;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e2b3f51c81f1..e25b35d70e4d 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -25,13 +25,13 @@ struct nft_cmp_expr {
25}; 25};
26 26
27static void nft_cmp_eval(const struct nft_expr *expr, 27static void nft_cmp_eval(const struct nft_expr *expr,
28 struct nft_data data[NFT_REG_MAX + 1], 28 struct nft_regs *regs,
29 const struct nft_pktinfo *pkt) 29 const struct nft_pktinfo *pkt)
30{ 30{
31 const struct nft_cmp_expr *priv = nft_expr_priv(expr); 31 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
32 int d; 32 int d;
33 33
34 d = nft_data_cmp(&data[priv->sreg], &priv->data, priv->len); 34 d = memcmp(&regs->data[priv->sreg], &priv->data, priv->len);
35 switch (priv->op) { 35 switch (priv->op) {
36 case NFT_CMP_EQ: 36 case NFT_CMP_EQ:
37 if (d != 0) 37 if (d != 0)
@@ -59,7 +59,7 @@ static void nft_cmp_eval(const struct nft_expr *expr,
59 return; 59 return;
60 60
61mismatch: 61mismatch:
62 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 62 regs->verdict.code = NFT_BREAK;
63} 63}
64 64
65static const struct nla_policy nft_cmp_policy[NFTA_CMP_MAX + 1] = { 65static const struct nla_policy nft_cmp_policy[NFTA_CMP_MAX + 1] = {
@@ -75,12 +75,16 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
75 struct nft_data_desc desc; 75 struct nft_data_desc desc;
76 int err; 76 int err;
77 77
78 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 78 err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc,
79 priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP])); 79 tb[NFTA_CMP_DATA]);
80
81 err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
82 BUG_ON(err < 0); 80 BUG_ON(err < 0);
83 81
82 priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
83 err = nft_validate_register_load(priv->sreg, desc.len);
84 if (err < 0)
85 return err;
86
87 priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
84 priv->len = desc.len; 88 priv->len = desc.len;
85 return 0; 89 return 0;
86} 90}
@@ -89,7 +93,7 @@ static int nft_cmp_dump(struct sk_buff *skb, const struct nft_expr *expr)
89{ 93{
90 const struct nft_cmp_expr *priv = nft_expr_priv(expr); 94 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
91 95
92 if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 96 if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
93 goto nla_put_failure; 97 goto nla_put_failure;
94 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op))) 98 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op)))
95 goto nla_put_failure; 99 goto nla_put_failure;
@@ -122,13 +126,18 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
122 u32 mask; 126 u32 mask;
123 int err; 127 int err;
124 128
125 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 129 err = nft_data_init(NULL, &data, sizeof(data), &desc,
126 130 tb[NFTA_CMP_DATA]);
127 err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
128 BUG_ON(err < 0); 131 BUG_ON(err < 0);
129 desc.len *= BITS_PER_BYTE;
130 132
133 priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
134 err = nft_validate_register_load(priv->sreg, desc.len);
135 if (err < 0)
136 return err;
137
138 desc.len *= BITS_PER_BYTE;
131 mask = nft_cmp_fast_mask(desc.len); 139 mask = nft_cmp_fast_mask(desc.len);
140
132 priv->data = data.data[0] & mask; 141 priv->data = data.data[0] & mask;
133 priv->len = desc.len; 142 priv->len = desc.len;
134 return 0; 143 return 0;
@@ -139,7 +148,7 @@ static int nft_cmp_fast_dump(struct sk_buff *skb, const struct nft_expr *expr)
139 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); 148 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
140 struct nft_data data; 149 struct nft_data data;
141 150
142 if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 151 if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
143 goto nla_put_failure; 152 goto nla_put_failure;
144 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ))) 153 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ)))
145 goto nla_put_failure; 154 goto nla_put_failure;
@@ -167,7 +176,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
167{ 176{
168 struct nft_data_desc desc; 177 struct nft_data_desc desc;
169 struct nft_data data; 178 struct nft_data data;
170 enum nft_registers sreg;
171 enum nft_cmp_ops op; 179 enum nft_cmp_ops op;
172 int err; 180 int err;
173 181
@@ -176,11 +184,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
176 tb[NFTA_CMP_DATA] == NULL) 184 tb[NFTA_CMP_DATA] == NULL)
177 return ERR_PTR(-EINVAL); 185 return ERR_PTR(-EINVAL);
178 186
179 sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
180 err = nft_validate_input_register(sreg);
181 if (err < 0)
182 return ERR_PTR(err);
183
184 op = ntohl(nla_get_be32(tb[NFTA_CMP_OP])); 187 op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
185 switch (op) { 188 switch (op) {
186 case NFT_CMP_EQ: 189 case NFT_CMP_EQ:
@@ -194,7 +197,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
194 return ERR_PTR(-EINVAL); 197 return ERR_PTR(-EINVAL);
195 } 198 }
196 199
197 err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); 200 err = nft_data_init(NULL, &data, sizeof(data), &desc,
201 tb[NFTA_CMP_DATA]);
198 if (err < 0) 202 if (err < 0)
199 return ERR_PTR(err); 203 return ERR_PTR(err);
200 204
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 0d137c1ac889..7f29cfc76349 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -55,7 +55,7 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
55} 55}
56 56
57static void nft_target_eval_xt(const struct nft_expr *expr, 57static void nft_target_eval_xt(const struct nft_expr *expr,
58 struct nft_data data[NFT_REG_MAX + 1], 58 struct nft_regs *regs,
59 const struct nft_pktinfo *pkt) 59 const struct nft_pktinfo *pkt)
60{ 60{
61 void *info = nft_expr_priv(expr); 61 void *info = nft_expr_priv(expr);
@@ -72,16 +72,16 @@ static void nft_target_eval_xt(const struct nft_expr *expr,
72 72
73 switch (ret) { 73 switch (ret) {
74 case XT_CONTINUE: 74 case XT_CONTINUE:
75 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 75 regs->verdict.code = NFT_CONTINUE;
76 break; 76 break;
77 default: 77 default:
78 data[NFT_REG_VERDICT].verdict = ret; 78 regs->verdict.code = ret;
79 break; 79 break;
80 } 80 }
81} 81}
82 82
83static void nft_target_eval_bridge(const struct nft_expr *expr, 83static void nft_target_eval_bridge(const struct nft_expr *expr,
84 struct nft_data data[NFT_REG_MAX + 1], 84 struct nft_regs *regs,
85 const struct nft_pktinfo *pkt) 85 const struct nft_pktinfo *pkt)
86{ 86{
87 void *info = nft_expr_priv(expr); 87 void *info = nft_expr_priv(expr);
@@ -98,19 +98,19 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
98 98
99 switch (ret) { 99 switch (ret) {
100 case EBT_ACCEPT: 100 case EBT_ACCEPT:
101 data[NFT_REG_VERDICT].verdict = NF_ACCEPT; 101 regs->verdict.code = NF_ACCEPT;
102 break; 102 break;
103 case EBT_DROP: 103 case EBT_DROP:
104 data[NFT_REG_VERDICT].verdict = NF_DROP; 104 regs->verdict.code = NF_DROP;
105 break; 105 break;
106 case EBT_CONTINUE: 106 case EBT_CONTINUE:
107 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 107 regs->verdict.code = NFT_CONTINUE;
108 break; 108 break;
109 case EBT_RETURN: 109 case EBT_RETURN:
110 data[NFT_REG_VERDICT].verdict = NFT_RETURN; 110 regs->verdict.code = NFT_RETURN;
111 break; 111 break;
112 default: 112 default:
113 data[NFT_REG_VERDICT].verdict = ret; 113 regs->verdict.code = ret;
114 break; 114 break;
115 } 115 }
116} 116}
@@ -304,7 +304,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
304} 304}
305 305
306static void nft_match_eval(const struct nft_expr *expr, 306static void nft_match_eval(const struct nft_expr *expr,
307 struct nft_data data[NFT_REG_MAX + 1], 307 struct nft_regs *regs,
308 const struct nft_pktinfo *pkt) 308 const struct nft_pktinfo *pkt)
309{ 309{
310 void *info = nft_expr_priv(expr); 310 void *info = nft_expr_priv(expr);
@@ -317,16 +317,16 @@ static void nft_match_eval(const struct nft_expr *expr,
317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt); 317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
318 318
319 if (pkt->xt.hotdrop) { 319 if (pkt->xt.hotdrop) {
320 data[NFT_REG_VERDICT].verdict = NF_DROP; 320 regs->verdict.code = NF_DROP;
321 return; 321 return;
322 } 322 }
323 323
324 switch (ret ? 1 : 0) { 324 switch (ret ? 1 : 0) {
325 case 1: 325 case 1:
326 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 326 regs->verdict.code = NFT_CONTINUE;
327 break; 327 break;
328 case 0: 328 case 0:
329 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 329 regs->verdict.code = NFT_BREAK;
330 break; 330 break;
331 } 331 }
332} 332}
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index c89ee486ce54..17591239229f 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -24,7 +24,7 @@ struct nft_counter {
24}; 24};
25 25
26static void nft_counter_eval(const struct nft_expr *expr, 26static void nft_counter_eval(const struct nft_expr *expr,
27 struct nft_data data[NFT_REG_MAX + 1], 27 struct nft_regs *regs,
28 const struct nft_pktinfo *pkt) 28 const struct nft_pktinfo *pkt)
29{ 29{
30 struct nft_counter *priv = nft_expr_priv(expr); 30 struct nft_counter *priv = nft_expr_priv(expr);
@@ -92,6 +92,7 @@ static struct nft_expr_type nft_counter_type __read_mostly = {
92 .ops = &nft_counter_ops, 92 .ops = &nft_counter_ops,
93 .policy = nft_counter_policy, 93 .policy = nft_counter_policy,
94 .maxattr = NFTA_COUNTER_MAX, 94 .maxattr = NFTA_COUNTER_MAX,
95 .flags = NFT_EXPR_STATEFUL,
95 .owner = THIS_MODULE, 96 .owner = THIS_MODULE,
96}; 97};
97 98
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 18d520e0ca0a..8cbca3432f90 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -31,11 +31,11 @@ struct nft_ct {
31}; 31};
32 32
33static void nft_ct_get_eval(const struct nft_expr *expr, 33static void nft_ct_get_eval(const struct nft_expr *expr,
34 struct nft_data data[NFT_REG_MAX + 1], 34 struct nft_regs *regs,
35 const struct nft_pktinfo *pkt) 35 const struct nft_pktinfo *pkt)
36{ 36{
37 const struct nft_ct *priv = nft_expr_priv(expr); 37 const struct nft_ct *priv = nft_expr_priv(expr);
38 struct nft_data *dest = &data[priv->dreg]; 38 u32 *dest = &regs->data[priv->dreg];
39 enum ip_conntrack_info ctinfo; 39 enum ip_conntrack_info ctinfo;
40 const struct nf_conn *ct; 40 const struct nf_conn *ct;
41 const struct nf_conn_help *help; 41 const struct nf_conn_help *help;
@@ -54,7 +54,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
54 state = NF_CT_STATE_UNTRACKED_BIT; 54 state = NF_CT_STATE_UNTRACKED_BIT;
55 else 55 else
56 state = NF_CT_STATE_BIT(ctinfo); 56 state = NF_CT_STATE_BIT(ctinfo);
57 dest->data[0] = state; 57 *dest = state;
58 return; 58 return;
59 default: 59 default:
60 break; 60 break;
@@ -65,26 +65,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
65 65
66 switch (priv->key) { 66 switch (priv->key) {
67 case NFT_CT_DIRECTION: 67 case NFT_CT_DIRECTION:
68 dest->data[0] = CTINFO2DIR(ctinfo); 68 *dest = CTINFO2DIR(ctinfo);
69 return; 69 return;
70 case NFT_CT_STATUS: 70 case NFT_CT_STATUS:
71 dest->data[0] = ct->status; 71 *dest = ct->status;
72 return; 72 return;
73#ifdef CONFIG_NF_CONNTRACK_MARK 73#ifdef CONFIG_NF_CONNTRACK_MARK
74 case NFT_CT_MARK: 74 case NFT_CT_MARK:
75 dest->data[0] = ct->mark; 75 *dest = ct->mark;
76 return; 76 return;
77#endif 77#endif
78#ifdef CONFIG_NF_CONNTRACK_SECMARK 78#ifdef CONFIG_NF_CONNTRACK_SECMARK
79 case NFT_CT_SECMARK: 79 case NFT_CT_SECMARK:
80 dest->data[0] = ct->secmark; 80 *dest = ct->secmark;
81 return; 81 return;
82#endif 82#endif
83 case NFT_CT_EXPIRATION: 83 case NFT_CT_EXPIRATION:
84 diff = (long)jiffies - (long)ct->timeout.expires; 84 diff = (long)jiffies - (long)ct->timeout.expires;
85 if (diff < 0) 85 if (diff < 0)
86 diff = 0; 86 diff = 0;
87 dest->data[0] = jiffies_to_msecs(diff); 87 *dest = jiffies_to_msecs(diff);
88 return; 88 return;
89 case NFT_CT_HELPER: 89 case NFT_CT_HELPER:
90 if (ct->master == NULL) 90 if (ct->master == NULL)
@@ -95,9 +95,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
95 helper = rcu_dereference(help->helper); 95 helper = rcu_dereference(help->helper);
96 if (helper == NULL) 96 if (helper == NULL)
97 goto err; 97 goto err;
98 if (strlen(helper->name) >= sizeof(dest->data)) 98 strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
99 goto err;
100 strncpy((char *)dest->data, helper->name, sizeof(dest->data));
101 return; 99 return;
102#ifdef CONFIG_NF_CONNTRACK_LABELS 100#ifdef CONFIG_NF_CONNTRACK_LABELS
103 case NFT_CT_LABELS: { 101 case NFT_CT_LABELS: {
@@ -105,17 +103,15 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
105 unsigned int size; 103 unsigned int size;
106 104
107 if (!labels) { 105 if (!labels) {
108 memset(dest->data, 0, sizeof(dest->data)); 106 memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
109 return; 107 return;
110 } 108 }
111 109
112 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data));
113 size = labels->words * sizeof(long); 110 size = labels->words * sizeof(long);
114 111 memcpy(dest, labels->bits, size);
115 memcpy(dest->data, labels->bits, size); 112 if (size < NF_CT_LABELS_MAX_SIZE)
116 if (size < sizeof(dest->data)) 113 memset(((char *) dest) + size, 0,
117 memset(((char *) dest->data) + size, 0, 114 NF_CT_LABELS_MAX_SIZE - size);
118 sizeof(dest->data) - size);
119 return; 115 return;
120 } 116 }
121#endif 117#endif
@@ -126,41 +122,41 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
126 tuple = &ct->tuplehash[priv->dir].tuple; 122 tuple = &ct->tuplehash[priv->dir].tuple;
127 switch (priv->key) { 123 switch (priv->key) {
128 case NFT_CT_L3PROTOCOL: 124 case NFT_CT_L3PROTOCOL:
129 dest->data[0] = nf_ct_l3num(ct); 125 *dest = nf_ct_l3num(ct);
130 return; 126 return;
131 case NFT_CT_SRC: 127 case NFT_CT_SRC:
132 memcpy(dest->data, tuple->src.u3.all, 128 memcpy(dest, tuple->src.u3.all,
133 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 129 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
134 return; 130 return;
135 case NFT_CT_DST: 131 case NFT_CT_DST:
136 memcpy(dest->data, tuple->dst.u3.all, 132 memcpy(dest, tuple->dst.u3.all,
137 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 133 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
138 return; 134 return;
139 case NFT_CT_PROTOCOL: 135 case NFT_CT_PROTOCOL:
140 dest->data[0] = nf_ct_protonum(ct); 136 *dest = nf_ct_protonum(ct);
141 return; 137 return;
142 case NFT_CT_PROTO_SRC: 138 case NFT_CT_PROTO_SRC:
143 dest->data[0] = (__force __u16)tuple->src.u.all; 139 *dest = (__force __u16)tuple->src.u.all;
144 return; 140 return;
145 case NFT_CT_PROTO_DST: 141 case NFT_CT_PROTO_DST:
146 dest->data[0] = (__force __u16)tuple->dst.u.all; 142 *dest = (__force __u16)tuple->dst.u.all;
147 return; 143 return;
148 default: 144 default:
149 break; 145 break;
150 } 146 }
151 return; 147 return;
152err: 148err:
153 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 149 regs->verdict.code = NFT_BREAK;
154} 150}
155 151
156static void nft_ct_set_eval(const struct nft_expr *expr, 152static void nft_ct_set_eval(const struct nft_expr *expr,
157 struct nft_data data[NFT_REG_MAX + 1], 153 struct nft_regs *regs,
158 const struct nft_pktinfo *pkt) 154 const struct nft_pktinfo *pkt)
159{ 155{
160 const struct nft_ct *priv = nft_expr_priv(expr); 156 const struct nft_ct *priv = nft_expr_priv(expr);
161 struct sk_buff *skb = pkt->skb; 157 struct sk_buff *skb = pkt->skb;
162#ifdef CONFIG_NF_CONNTRACK_MARK 158#ifdef CONFIG_NF_CONNTRACK_MARK
163 u32 value = data[priv->sreg].data[0]; 159 u32 value = regs->data[priv->sreg];
164#endif 160#endif
165 enum ip_conntrack_info ctinfo; 161 enum ip_conntrack_info ctinfo;
166 struct nf_conn *ct; 162 struct nf_conn *ct;
@@ -228,12 +224,17 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
228 const struct nlattr * const tb[]) 224 const struct nlattr * const tb[])
229{ 225{
230 struct nft_ct *priv = nft_expr_priv(expr); 226 struct nft_ct *priv = nft_expr_priv(expr);
227 unsigned int len;
231 int err; 228 int err;
232 229
233 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 230 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
234 switch (priv->key) { 231 switch (priv->key) {
235 case NFT_CT_STATE:
236 case NFT_CT_DIRECTION: 232 case NFT_CT_DIRECTION:
233 if (tb[NFTA_CT_DIRECTION] != NULL)
234 return -EINVAL;
235 len = sizeof(u8);
236 break;
237 case NFT_CT_STATE:
237 case NFT_CT_STATUS: 238 case NFT_CT_STATUS:
238#ifdef CONFIG_NF_CONNTRACK_MARK 239#ifdef CONFIG_NF_CONNTRACK_MARK
239 case NFT_CT_MARK: 240 case NFT_CT_MARK:
@@ -241,22 +242,54 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
241#ifdef CONFIG_NF_CONNTRACK_SECMARK 242#ifdef CONFIG_NF_CONNTRACK_SECMARK
242 case NFT_CT_SECMARK: 243 case NFT_CT_SECMARK:
243#endif 244#endif
245 case NFT_CT_EXPIRATION:
246 if (tb[NFTA_CT_DIRECTION] != NULL)
247 return -EINVAL;
248 len = sizeof(u32);
249 break;
244#ifdef CONFIG_NF_CONNTRACK_LABELS 250#ifdef CONFIG_NF_CONNTRACK_LABELS
245 case NFT_CT_LABELS: 251 case NFT_CT_LABELS:
252 if (tb[NFTA_CT_DIRECTION] != NULL)
253 return -EINVAL;
254 len = NF_CT_LABELS_MAX_SIZE;
255 break;
246#endif 256#endif
247 case NFT_CT_EXPIRATION:
248 case NFT_CT_HELPER: 257 case NFT_CT_HELPER:
249 if (tb[NFTA_CT_DIRECTION] != NULL) 258 if (tb[NFTA_CT_DIRECTION] != NULL)
250 return -EINVAL; 259 return -EINVAL;
260 len = NF_CT_HELPER_NAME_LEN;
251 break; 261 break;
262
252 case NFT_CT_L3PROTOCOL: 263 case NFT_CT_L3PROTOCOL:
253 case NFT_CT_PROTOCOL: 264 case NFT_CT_PROTOCOL:
265 if (tb[NFTA_CT_DIRECTION] == NULL)
266 return -EINVAL;
267 len = sizeof(u8);
268 break;
254 case NFT_CT_SRC: 269 case NFT_CT_SRC:
255 case NFT_CT_DST: 270 case NFT_CT_DST:
271 if (tb[NFTA_CT_DIRECTION] == NULL)
272 return -EINVAL;
273
274 switch (ctx->afi->family) {
275 case NFPROTO_IPV4:
276 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
277 src.u3.ip);
278 break;
279 case NFPROTO_IPV6:
280 case NFPROTO_INET:
281 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
282 src.u3.ip6);
283 break;
284 default:
285 return -EAFNOSUPPORT;
286 }
287 break;
256 case NFT_CT_PROTO_SRC: 288 case NFT_CT_PROTO_SRC:
257 case NFT_CT_PROTO_DST: 289 case NFT_CT_PROTO_DST:
258 if (tb[NFTA_CT_DIRECTION] == NULL) 290 if (tb[NFTA_CT_DIRECTION] == NULL)
259 return -EINVAL; 291 return -EINVAL;
292 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
260 break; 293 break;
261 default: 294 default:
262 return -EOPNOTSUPP; 295 return -EOPNOTSUPP;
@@ -273,12 +306,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
273 } 306 }
274 } 307 }
275 308
276 priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG])); 309 priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
277 err = nft_validate_output_register(priv->dreg); 310 err = nft_validate_register_store(ctx, priv->dreg, NULL,
278 if (err < 0) 311 NFT_DATA_VALUE, len);
279 return err;
280
281 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
282 if (err < 0) 312 if (err < 0)
283 return err; 313 return err;
284 314
@@ -294,20 +324,22 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
294 const struct nlattr * const tb[]) 324 const struct nlattr * const tb[])
295{ 325{
296 struct nft_ct *priv = nft_expr_priv(expr); 326 struct nft_ct *priv = nft_expr_priv(expr);
327 unsigned int len;
297 int err; 328 int err;
298 329
299 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 330 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
300 switch (priv->key) { 331 switch (priv->key) {
301#ifdef CONFIG_NF_CONNTRACK_MARK 332#ifdef CONFIG_NF_CONNTRACK_MARK
302 case NFT_CT_MARK: 333 case NFT_CT_MARK:
334 len = FIELD_SIZEOF(struct nf_conn, mark);
303 break; 335 break;
304#endif 336#endif
305 default: 337 default:
306 return -EOPNOTSUPP; 338 return -EOPNOTSUPP;
307 } 339 }
308 340
309 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG])); 341 priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
310 err = nft_validate_input_register(priv->sreg); 342 err = nft_validate_register_load(priv->sreg, len);
311 if (err < 0) 343 if (err < 0)
312 return err; 344 return err;
313 345
@@ -328,7 +360,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
328{ 360{
329 const struct nft_ct *priv = nft_expr_priv(expr); 361 const struct nft_ct *priv = nft_expr_priv(expr);
330 362
331 if (nla_put_be32(skb, NFTA_CT_DREG, htonl(priv->dreg))) 363 if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
332 goto nla_put_failure; 364 goto nla_put_failure;
333 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 365 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
334 goto nla_put_failure; 366 goto nla_put_failure;
@@ -355,7 +387,7 @@ static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
355{ 387{
356 const struct nft_ct *priv = nft_expr_priv(expr); 388 const struct nft_ct *priv = nft_expr_priv(expr);
357 389
358 if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg))) 390 if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
359 goto nla_put_failure; 391 goto nla_put_failure;
360 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 392 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
361 goto nla_put_failure; 393 goto nla_put_failure;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index eeb72dee78ef..513a8ef60a59 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -23,13 +23,15 @@ struct nft_dynset {
23 enum nft_registers sreg_key:8; 23 enum nft_registers sreg_key:8;
24 enum nft_registers sreg_data:8; 24 enum nft_registers sreg_data:8;
25 u64 timeout; 25 u64 timeout;
26 struct nft_expr *expr;
26 struct nft_set_binding binding; 27 struct nft_set_binding binding;
27}; 28};
28 29
29static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr, 30static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1]) 31 struct nft_regs *regs)
31{ 32{
32 const struct nft_dynset *priv = nft_expr_priv(expr); 33 const struct nft_dynset *priv = nft_expr_priv(expr);
34 struct nft_set_ext *ext;
33 u64 timeout; 35 u64 timeout;
34 void *elem; 36 void *elem;
35 37
@@ -38,35 +40,51 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
38 40
39 timeout = priv->timeout ? : set->timeout; 41 timeout = priv->timeout ? : set->timeout;
40 elem = nft_set_elem_init(set, &priv->tmpl, 42 elem = nft_set_elem_init(set, &priv->tmpl,
41 &data[priv->sreg_key], &data[priv->sreg_data], 43 &regs->data[priv->sreg_key],
44 &regs->data[priv->sreg_data],
42 timeout, GFP_ATOMIC); 45 timeout, GFP_ATOMIC);
43 if (elem == NULL) { 46 if (elem == NULL) {
44 if (set->size) 47 if (set->size)
45 atomic_dec(&set->nelems); 48 atomic_dec(&set->nelems);
49 return NULL;
46 } 50 }
51
52 ext = nft_set_elem_ext(set, elem);
53 if (priv->expr != NULL)
54 nft_expr_clone(nft_set_ext_expr(ext), priv->expr);
55
47 return elem; 56 return elem;
48} 57}
49 58
50static void nft_dynset_eval(const struct nft_expr *expr, 59static void nft_dynset_eval(const struct nft_expr *expr,
51 struct nft_data data[NFT_REG_MAX + 1], 60 struct nft_regs *regs,
52 const struct nft_pktinfo *pkt) 61 const struct nft_pktinfo *pkt)
53{ 62{
54 const struct nft_dynset *priv = nft_expr_priv(expr); 63 const struct nft_dynset *priv = nft_expr_priv(expr);
55 struct nft_set *set = priv->set; 64 struct nft_set *set = priv->set;
56 const struct nft_set_ext *ext; 65 const struct nft_set_ext *ext;
66 const struct nft_expr *sexpr;
57 u64 timeout; 67 u64 timeout;
58 68
59 if (set->ops->update(set, &data[priv->sreg_key], nft_dynset_new, 69 if (set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
60 expr, data, &ext)) { 70 expr, regs, &ext)) {
71 sexpr = NULL;
72 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
73 sexpr = nft_set_ext_expr(ext);
74
61 if (priv->op == NFT_DYNSET_OP_UPDATE && 75 if (priv->op == NFT_DYNSET_OP_UPDATE &&
62 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) { 76 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
63 timeout = priv->timeout ? : set->timeout; 77 timeout = priv->timeout ? : set->timeout;
64 *nft_set_ext_expiration(ext) = jiffies + timeout; 78 *nft_set_ext_expiration(ext) = jiffies + timeout;
65 return; 79 } else if (sexpr == NULL)
66 } 80 goto out;
67 }
68 81
69 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 82 if (sexpr != NULL)
83 sexpr->ops->eval(sexpr, regs, pkt);
84 return;
85 }
86out:
87 regs->verdict.code = NFT_BREAK;
70} 88}
71 89
72static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = { 90static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
@@ -76,6 +94,7 @@ static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
76 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 }, 94 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
77 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 }, 95 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
78 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 }, 96 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
97 [NFTA_DYNSET_EXPR] = { .type = NLA_NESTED },
79}; 98};
80 99
81static int nft_dynset_init(const struct nft_ctx *ctx, 100static int nft_dynset_init(const struct nft_ctx *ctx,
@@ -123,8 +142,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
123 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT])); 142 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
124 } 143 }
125 144
126 priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY])); 145 priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
127 err = nft_validate_input_register(priv->sreg_key); 146 err = nft_validate_register_load(priv->sreg_key, set->klen);;
128 if (err < 0) 147 if (err < 0)
129 return err; 148 return err;
130 149
@@ -134,17 +153,36 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
134 if (set->dtype == NFT_DATA_VERDICT) 153 if (set->dtype == NFT_DATA_VERDICT)
135 return -EOPNOTSUPP; 154 return -EOPNOTSUPP;
136 155
137 priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA])); 156 priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
138 err = nft_validate_input_register(priv->sreg_data); 157 err = nft_validate_register_load(priv->sreg_data, set->dlen);
139 if (err < 0) 158 if (err < 0)
140 return err; 159 return err;
141 } else if (set->flags & NFT_SET_MAP) 160 } else if (set->flags & NFT_SET_MAP)
142 return -EINVAL; 161 return -EINVAL;
143 162
163 if (tb[NFTA_DYNSET_EXPR] != NULL) {
164 if (!(set->flags & NFT_SET_EVAL))
165 return -EINVAL;
166 if (!(set->flags & NFT_SET_ANONYMOUS))
167 return -EOPNOTSUPP;
168
169 priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
170 if (IS_ERR(priv->expr))
171 return PTR_ERR(priv->expr);
172
173 err = -EOPNOTSUPP;
174 if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
175 goto err1;
176 } else if (set->flags & NFT_SET_EVAL)
177 return -EINVAL;
178
144 nft_set_ext_prepare(&priv->tmpl); 179 nft_set_ext_prepare(&priv->tmpl);
145 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen); 180 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
146 if (set->flags & NFT_SET_MAP) 181 if (set->flags & NFT_SET_MAP)
147 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen); 182 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen);
183 if (priv->expr != NULL)
184 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_EXPR,
185 priv->expr->ops->size);
148 if (set->flags & NFT_SET_TIMEOUT) { 186 if (set->flags & NFT_SET_TIMEOUT) {
149 if (timeout || set->timeout) 187 if (timeout || set->timeout)
150 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION); 188 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
@@ -154,10 +192,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
154 192
155 err = nf_tables_bind_set(ctx, set, &priv->binding); 193 err = nf_tables_bind_set(ctx, set, &priv->binding);
156 if (err < 0) 194 if (err < 0)
157 return err; 195 goto err1;
158 196
159 priv->set = set; 197 priv->set = set;
160 return 0; 198 return 0;
199
200err1:
201 if (priv->expr != NULL)
202 nft_expr_destroy(ctx, priv->expr);
203 return err;
161} 204}
162 205
163static void nft_dynset_destroy(const struct nft_ctx *ctx, 206static void nft_dynset_destroy(const struct nft_ctx *ctx,
@@ -166,16 +209,18 @@ static void nft_dynset_destroy(const struct nft_ctx *ctx,
166 struct nft_dynset *priv = nft_expr_priv(expr); 209 struct nft_dynset *priv = nft_expr_priv(expr);
167 210
168 nf_tables_unbind_set(ctx, priv->set, &priv->binding); 211 nf_tables_unbind_set(ctx, priv->set, &priv->binding);
212 if (priv->expr != NULL)
213 nft_expr_destroy(ctx, priv->expr);
169} 214}
170 215
171static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr) 216static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
172{ 217{
173 const struct nft_dynset *priv = nft_expr_priv(expr); 218 const struct nft_dynset *priv = nft_expr_priv(expr);
174 219
175 if (nla_put_be32(skb, NFTA_DYNSET_SREG_KEY, htonl(priv->sreg_key))) 220 if (nft_dump_register(skb, NFTA_DYNSET_SREG_KEY, priv->sreg_key))
176 goto nla_put_failure; 221 goto nla_put_failure;
177 if (priv->set->flags & NFT_SET_MAP && 222 if (priv->set->flags & NFT_SET_MAP &&
178 nla_put_be32(skb, NFTA_DYNSET_SREG_DATA, htonl(priv->sreg_data))) 223 nft_dump_register(skb, NFTA_DYNSET_SREG_DATA, priv->sreg_data))
179 goto nla_put_failure; 224 goto nla_put_failure;
180 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op))) 225 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op)))
181 goto nla_put_failure; 226 goto nla_put_failure;
@@ -183,6 +228,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
183 goto nla_put_failure; 228 goto nla_put_failure;
184 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout))) 229 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout)))
185 goto nla_put_failure; 230 goto nla_put_failure;
231 if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
232 goto nla_put_failure;
186 return 0; 233 return 0;
187 234
188nla_put_failure: 235nla_put_failure:
diff --git a/net/netfilter/nft_expr_template.c b/net/netfilter/nft_expr_template.c
deleted file mode 100644
index b6eed4d5a096..000000000000
--- a/net/netfilter/nft_expr_template.c
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/netlink.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter/nf_tables.h>
16#include <net/netfilter/nf_tables.h>
17
18struct nft_template {
19
20};
21
22static void nft_template_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1],
24 const struct nft_pktinfo *pkt)
25{
26 struct nft_template *priv = nft_expr_priv(expr);
27
28}
29
30static const struct nla_policy nft_template_policy[NFTA_TEMPLATE_MAX + 1] = {
31 [NFTA_TEMPLATE_ATTR] = { .type = NLA_U32 },
32};
33
34static int nft_template_init(const struct nft_ctx *ctx,
35 const struct nft_expr *expr,
36 const struct nlattr * const tb[])
37{
38 struct nft_template *priv = nft_expr_priv(expr);
39
40 return 0;
41}
42
43static void nft_template_destroy(const struct nft_ctx *ctx,
44 const struct nft_expr *expr)
45{
46 struct nft_template *priv = nft_expr_priv(expr);
47
48}
49
50static int nft_template_dump(struct sk_buff *skb, const struct nft_expr *expr)
51{
52 const struct nft_template *priv = nft_expr_priv(expr);
53
54 NLA_PUT_BE32(skb, NFTA_TEMPLATE_ATTR, priv->field);
55 return 0;
56
57nla_put_failure:
58 return -1;
59}
60
61static struct nft_expr_type nft_template_type;
62static const struct nft_expr_ops nft_template_ops = {
63 .type = &nft_template_type,
64 .size = NFT_EXPR_SIZE(sizeof(struct nft_template)),
65 .eval = nft_template_eval,
66 .init = nft_template_init,
67 .destroy = nft_template_destroy,
68 .dump = nft_template_dump,
69};
70
71static struct nft_expr_type nft_template_type __read_mostly = {
72 .name = "template",
73 .ops = &nft_template_ops,
74 .policy = nft_template_policy,
75 .maxattr = NFTA_TEMPLATE_MAX,
76 .owner = THIS_MODULE,
77};
78
79static int __init nft_template_module_init(void)
80{
81 return nft_register_expr(&nft_template_type);
82}
83
84static void __exit nft_template_module_exit(void)
85{
86 nft_unregister_expr(&nft_template_type);
87}
88
89module_init(nft_template_module_init);
90module_exit(nft_template_module_exit);
91
92MODULE_LICENSE("GPL");
93MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
94MODULE_ALIAS_NFT_EXPR("template");
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 55c939f5371f..ba7aed13e174 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -26,11 +26,11 @@ struct nft_exthdr {
26}; 26};
27 27
28static void nft_exthdr_eval(const struct nft_expr *expr, 28static void nft_exthdr_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 struct nft_exthdr *priv = nft_expr_priv(expr); 32 struct nft_exthdr *priv = nft_expr_priv(expr);
33 struct nft_data *dest = &data[priv->dreg]; 33 u32 *dest = &regs->data[priv->dreg];
34 unsigned int offset = 0; 34 unsigned int offset = 0;
35 int err; 35 int err;
36 36
@@ -39,11 +39,12 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
39 goto err; 39 goto err;
40 offset += priv->offset; 40 offset += priv->offset;
41 41
42 if (skb_copy_bits(pkt->skb, offset, dest->data, priv->len) < 0) 42 dest[priv->len / NFT_REG32_SIZE] = 0;
43 if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
43 goto err; 44 goto err;
44 return; 45 return;
45err: 46err:
46 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 47 regs->verdict.code = NFT_BREAK;
47} 48}
48 49
49static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { 50static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {
@@ -58,7 +59,6 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
58 const struct nlattr * const tb[]) 59 const struct nlattr * const tb[])
59{ 60{
60 struct nft_exthdr *priv = nft_expr_priv(expr); 61 struct nft_exthdr *priv = nft_expr_priv(expr);
61 int err;
62 62
63 if (tb[NFTA_EXTHDR_DREG] == NULL || 63 if (tb[NFTA_EXTHDR_DREG] == NULL ||
64 tb[NFTA_EXTHDR_TYPE] == NULL || 64 tb[NFTA_EXTHDR_TYPE] == NULL ||
@@ -69,22 +69,17 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
69 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); 69 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
70 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); 70 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
71 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); 71 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
72 if (priv->len == 0 || 72 priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
73 priv->len > FIELD_SIZEOF(struct nft_data, data))
74 return -EINVAL;
75 73
76 priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG])); 74 return nft_validate_register_store(ctx, priv->dreg, NULL,
77 err = nft_validate_output_register(priv->dreg); 75 NFT_DATA_VALUE, priv->len);
78 if (err < 0)
79 return err;
80 return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
81} 76}
82 77
83static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr) 78static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
84{ 79{
85 const struct nft_exthdr *priv = nft_expr_priv(expr); 80 const struct nft_exthdr *priv = nft_expr_priv(expr);
86 81
87 if (nla_put_be32(skb, NFTA_EXTHDR_DREG, htonl(priv->dreg))) 82 if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg))
88 goto nla_put_failure; 83 goto nla_put_failure;
89 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) 84 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type))
90 goto nla_put_failure; 85 goto nla_put_failure;
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index bc23806b7fbe..3f9d45d3d9b7 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -36,7 +36,7 @@ struct nft_hash_elem {
36 36
37struct nft_hash_cmp_arg { 37struct nft_hash_cmp_arg {
38 const struct nft_set *set; 38 const struct nft_set *set;
39 const struct nft_data *key; 39 const u32 *key;
40 u8 genmask; 40 u8 genmask;
41}; 41};
42 42
@@ -62,7 +62,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
62 const struct nft_hash_cmp_arg *x = arg->key; 62 const struct nft_hash_cmp_arg *x = arg->key;
63 const struct nft_hash_elem *he = ptr; 63 const struct nft_hash_elem *he = ptr;
64 64
65 if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen)) 65 if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
66 return 1; 66 return 1;
67 if (nft_set_elem_expired(&he->ext)) 67 if (nft_set_elem_expired(&he->ext))
68 return 1; 68 return 1;
@@ -71,8 +71,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
71 return 0; 71 return 0;
72} 72}
73 73
74static bool nft_hash_lookup(const struct nft_set *set, 74static bool nft_hash_lookup(const struct nft_set *set, const u32 *key,
75 const struct nft_data *key,
76 const struct nft_set_ext **ext) 75 const struct nft_set_ext **ext)
77{ 76{
78 struct nft_hash *priv = nft_set_priv(set); 77 struct nft_hash *priv = nft_set_priv(set);
@@ -90,12 +89,12 @@ static bool nft_hash_lookup(const struct nft_set *set,
90 return !!he; 89 return !!he;
91} 90}
92 91
93static bool nft_hash_update(struct nft_set *set, const struct nft_data *key, 92static bool nft_hash_update(struct nft_set *set, const u32 *key,
94 void *(*new)(struct nft_set *, 93 void *(*new)(struct nft_set *,
95 const struct nft_expr *, 94 const struct nft_expr *,
96 struct nft_data []), 95 struct nft_regs *regs),
97 const struct nft_expr *expr, 96 const struct nft_expr *expr,
98 struct nft_data data[], 97 struct nft_regs *regs,
99 const struct nft_set_ext **ext) 98 const struct nft_set_ext **ext)
100{ 99{
101 struct nft_hash *priv = nft_set_priv(set); 100 struct nft_hash *priv = nft_set_priv(set);
@@ -110,7 +109,7 @@ static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
110 if (he != NULL) 109 if (he != NULL)
111 goto out; 110 goto out;
112 111
113 he = new(set, expr, data); 112 he = new(set, expr, regs);
114 if (he == NULL) 113 if (he == NULL)
115 goto err1; 114 goto err1;
116 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, 115 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -134,7 +133,7 @@ static int nft_hash_insert(const struct nft_set *set,
134 struct nft_hash_cmp_arg arg = { 133 struct nft_hash_cmp_arg arg = {
135 .genmask = nft_genmask_next(read_pnet(&set->pnet)), 134 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
136 .set = set, 135 .set = set,
137 .key = &elem->key, 136 .key = elem->key.val.data,
138 }; 137 };
139 138
140 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, 139 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -158,7 +157,7 @@ static void *nft_hash_deactivate(const struct nft_set *set,
158 struct nft_hash_cmp_arg arg = { 157 struct nft_hash_cmp_arg arg = {
159 .genmask = nft_genmask_next(read_pnet(&set->pnet)), 158 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
160 .set = set, 159 .set = set,
161 .key = &elem->key, 160 .key = elem->key.val.data,
162 }; 161 };
163 162
164 rcu_read_lock(); 163 rcu_read_lock();
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 810385eb7249..db3b746858e3 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -24,12 +24,12 @@ struct nft_immediate_expr {
24}; 24};
25 25
26static void nft_immediate_eval(const struct nft_expr *expr, 26static void nft_immediate_eval(const struct nft_expr *expr,
27 struct nft_data data[NFT_REG_MAX + 1], 27 struct nft_regs *regs,
28 const struct nft_pktinfo *pkt) 28 const struct nft_pktinfo *pkt)
29{ 29{
30 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 30 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
31 31
32 nft_data_copy(&data[priv->dreg], &priv->data); 32 nft_data_copy(&regs->data[priv->dreg], &priv->data, priv->dlen);
33} 33}
34 34
35static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = { 35static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = {
@@ -49,17 +49,15 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
49 tb[NFTA_IMMEDIATE_DATA] == NULL) 49 tb[NFTA_IMMEDIATE_DATA] == NULL)
50 return -EINVAL; 50 return -EINVAL;
51 51
52 priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG])); 52 err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc,
53 err = nft_validate_output_register(priv->dreg); 53 tb[NFTA_IMMEDIATE_DATA]);
54 if (err < 0)
55 return err;
56
57 err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]);
58 if (err < 0) 54 if (err < 0)
59 return err; 55 return err;
60 priv->dlen = desc.len; 56 priv->dlen = desc.len;
61 57
62 err = nft_validate_data_load(ctx, priv->dreg, &priv->data, desc.type); 58 priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
59 err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
60 desc.type, desc.len);
63 if (err < 0) 61 if (err < 0)
64 goto err1; 62 goto err1;
65 63
@@ -81,7 +79,7 @@ static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr)
81{ 79{
82 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 80 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
83 81
84 if (nla_put_be32(skb, NFTA_IMMEDIATE_DREG, htonl(priv->dreg))) 82 if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg))
85 goto nla_put_failure; 83 goto nla_put_failure;
86 84
87 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data, 85 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index 85da5bd02f64..435c1ccd6c0e 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -27,7 +27,7 @@ struct nft_limit {
27}; 27};
28 28
29static void nft_limit_eval(const struct nft_expr *expr, 29static void nft_limit_eval(const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1], 30 struct nft_regs *regs,
31 const struct nft_pktinfo *pkt) 31 const struct nft_pktinfo *pkt)
32{ 32{
33 struct nft_limit *priv = nft_expr_priv(expr); 33 struct nft_limit *priv = nft_expr_priv(expr);
@@ -45,7 +45,7 @@ static void nft_limit_eval(const struct nft_expr *expr,
45 } 45 }
46 spin_unlock_bh(&limit_lock); 46 spin_unlock_bh(&limit_lock);
47 47
48 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 48 regs->verdict.code = NFT_BREAK;
49} 49}
50 50
51static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = { 51static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = {
@@ -98,6 +98,7 @@ static struct nft_expr_type nft_limit_type __read_mostly = {
98 .ops = &nft_limit_ops, 98 .ops = &nft_limit_ops,
99 .policy = nft_limit_policy, 99 .policy = nft_limit_policy,
100 .maxattr = NFTA_LIMIT_MAX, 100 .maxattr = NFTA_LIMIT_MAX,
101 .flags = NFT_EXPR_STATEFUL,
101 .owner = THIS_MODULE, 102 .owner = THIS_MODULE,
102}; 103};
103 104
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index e18af9db2f04..a13d6a386d63 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -27,7 +27,7 @@ struct nft_log {
27}; 27};
28 28
29static void nft_log_eval(const struct nft_expr *expr, 29static void nft_log_eval(const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1], 30 struct nft_regs *regs,
31 const struct nft_pktinfo *pkt) 31 const struct nft_pktinfo *pkt)
32{ 32{
33 const struct nft_log *priv = nft_expr_priv(expr); 33 const struct nft_log *priv = nft_expr_priv(expr);
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index d8cf86fb30fc..b3c31ef8015d 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -26,19 +26,20 @@ struct nft_lookup {
26}; 26};
27 27
28static void nft_lookup_eval(const struct nft_expr *expr, 28static void nft_lookup_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_lookup *priv = nft_expr_priv(expr); 32 const struct nft_lookup *priv = nft_expr_priv(expr);
33 const struct nft_set *set = priv->set; 33 const struct nft_set *set = priv->set;
34 const struct nft_set_ext *ext; 34 const struct nft_set_ext *ext;
35 35
36 if (set->ops->lookup(set, &data[priv->sreg], &ext)) { 36 if (set->ops->lookup(set, &regs->data[priv->sreg], &ext)) {
37 if (set->flags & NFT_SET_MAP) 37 if (set->flags & NFT_SET_MAP)
38 nft_data_copy(&data[priv->dreg], nft_set_ext_data(ext)); 38 nft_data_copy(&regs->data[priv->dreg],
39 nft_set_ext_data(ext), set->dlen);
39 return; 40 return;
40 } 41 }
41 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 42 regs->verdict.code = NFT_BREAK;
42} 43}
43 44
44static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = { 45static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
@@ -70,8 +71,11 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
70 return PTR_ERR(set); 71 return PTR_ERR(set);
71 } 72 }
72 73
73 priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG])); 74 if (set->flags & NFT_SET_EVAL)
74 err = nft_validate_input_register(priv->sreg); 75 return -EOPNOTSUPP;
76
77 priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
78 err = nft_validate_register_load(priv->sreg, set->klen);
75 if (err < 0) 79 if (err < 0)
76 return err; 80 return err;
77 81
@@ -79,16 +83,11 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
79 if (!(set->flags & NFT_SET_MAP)) 83 if (!(set->flags & NFT_SET_MAP))
80 return -EINVAL; 84 return -EINVAL;
81 85
82 priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG])); 86 priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
83 err = nft_validate_output_register(priv->dreg); 87 err = nft_validate_register_store(ctx, priv->dreg, NULL,
88 set->dtype, set->dlen);
84 if (err < 0) 89 if (err < 0)
85 return err; 90 return err;
86
87 if (priv->dreg == NFT_REG_VERDICT) {
88 if (set->dtype != NFT_DATA_VERDICT)
89 return -EINVAL;
90 } else if (set->dtype == NFT_DATA_VERDICT)
91 return -EINVAL;
92 } else if (set->flags & NFT_SET_MAP) 91 } else if (set->flags & NFT_SET_MAP)
93 return -EINVAL; 92 return -EINVAL;
94 93
@@ -116,10 +115,10 @@ static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr)
116 115
117 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name)) 116 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name))
118 goto nla_put_failure; 117 goto nla_put_failure;
119 if (nla_put_be32(skb, NFTA_LOOKUP_SREG, htonl(priv->sreg))) 118 if (nft_dump_register(skb, NFTA_LOOKUP_SREG, priv->sreg))
120 goto nla_put_failure; 119 goto nla_put_failure;
121 if (priv->set->flags & NFT_SET_MAP) 120 if (priv->set->flags & NFT_SET_MAP)
122 if (nla_put_be32(skb, NFTA_LOOKUP_DREG, htonl(priv->dreg))) 121 if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg))
123 goto nla_put_failure; 122 goto nla_put_failure;
124 return 0; 123 return 0;
125 124
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index d79ce88be77f..52561e1c31e2 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -25,62 +25,65 @@
25#include <net/netfilter/nft_meta.h> 25#include <net/netfilter/nft_meta.h>
26 26
27void nft_meta_get_eval(const struct nft_expr *expr, 27void nft_meta_get_eval(const struct nft_expr *expr,
28 struct nft_data data[NFT_REG_MAX + 1], 28 struct nft_regs *regs,
29 const struct nft_pktinfo *pkt) 29 const struct nft_pktinfo *pkt)
30{ 30{
31 const struct nft_meta *priv = nft_expr_priv(expr); 31 const struct nft_meta *priv = nft_expr_priv(expr);
32 const struct sk_buff *skb = pkt->skb; 32 const struct sk_buff *skb = pkt->skb;
33 const struct net_device *in = pkt->in, *out = pkt->out; 33 const struct net_device *in = pkt->in, *out = pkt->out;
34 struct nft_data *dest = &data[priv->dreg]; 34 u32 *dest = &regs->data[priv->dreg];
35 35
36 switch (priv->key) { 36 switch (priv->key) {
37 case NFT_META_LEN: 37 case NFT_META_LEN:
38 dest->data[0] = skb->len; 38 *dest = skb->len;
39 break; 39 break;
40 case NFT_META_PROTOCOL: 40 case NFT_META_PROTOCOL:
41 *(__be16 *)dest->data = skb->protocol; 41 *dest = 0;
42 *(__be16 *)dest = skb->protocol;
42 break; 43 break;
43 case NFT_META_NFPROTO: 44 case NFT_META_NFPROTO:
44 dest->data[0] = pkt->ops->pf; 45 *dest = pkt->ops->pf;
45 break; 46 break;
46 case NFT_META_L4PROTO: 47 case NFT_META_L4PROTO:
47 dest->data[0] = pkt->tprot; 48 *dest = pkt->tprot;
48 break; 49 break;
49 case NFT_META_PRIORITY: 50 case NFT_META_PRIORITY:
50 dest->data[0] = skb->priority; 51 *dest = skb->priority;
51 break; 52 break;
52 case NFT_META_MARK: 53 case NFT_META_MARK:
53 dest->data[0] = skb->mark; 54 *dest = skb->mark;
54 break; 55 break;
55 case NFT_META_IIF: 56 case NFT_META_IIF:
56 if (in == NULL) 57 if (in == NULL)
57 goto err; 58 goto err;
58 dest->data[0] = in->ifindex; 59 *dest = in->ifindex;
59 break; 60 break;
60 case NFT_META_OIF: 61 case NFT_META_OIF:
61 if (out == NULL) 62 if (out == NULL)
62 goto err; 63 goto err;
63 dest->data[0] = out->ifindex; 64 *dest = out->ifindex;
64 break; 65 break;
65 case NFT_META_IIFNAME: 66 case NFT_META_IIFNAME:
66 if (in == NULL) 67 if (in == NULL)
67 goto err; 68 goto err;
68 strncpy((char *)dest->data, in->name, sizeof(dest->data)); 69 strncpy((char *)dest, in->name, IFNAMSIZ);
69 break; 70 break;
70 case NFT_META_OIFNAME: 71 case NFT_META_OIFNAME:
71 if (out == NULL) 72 if (out == NULL)
72 goto err; 73 goto err;
73 strncpy((char *)dest->data, out->name, sizeof(dest->data)); 74 strncpy((char *)dest, out->name, IFNAMSIZ);
74 break; 75 break;
75 case NFT_META_IIFTYPE: 76 case NFT_META_IIFTYPE:
76 if (in == NULL) 77 if (in == NULL)
77 goto err; 78 goto err;
78 *(u16 *)dest->data = in->type; 79 *dest = 0;
80 *(u16 *)dest = in->type;
79 break; 81 break;
80 case NFT_META_OIFTYPE: 82 case NFT_META_OIFTYPE:
81 if (out == NULL) 83 if (out == NULL)
82 goto err; 84 goto err;
83 *(u16 *)dest->data = out->type; 85 *dest = 0;
86 *(u16 *)dest = out->type;
84 break; 87 break;
85 case NFT_META_SKUID: 88 case NFT_META_SKUID:
86 if (skb->sk == NULL || !sk_fullsock(skb->sk)) 89 if (skb->sk == NULL || !sk_fullsock(skb->sk))
@@ -93,8 +96,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
93 goto err; 96 goto err;
94 } 97 }
95 98
96 dest->data[0] = 99 *dest = from_kuid_munged(&init_user_ns,
97 from_kuid_munged(&init_user_ns,
98 skb->sk->sk_socket->file->f_cred->fsuid); 100 skb->sk->sk_socket->file->f_cred->fsuid);
99 read_unlock_bh(&skb->sk->sk_callback_lock); 101 read_unlock_bh(&skb->sk->sk_callback_lock);
100 break; 102 break;
@@ -108,8 +110,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
108 read_unlock_bh(&skb->sk->sk_callback_lock); 110 read_unlock_bh(&skb->sk->sk_callback_lock);
109 goto err; 111 goto err;
110 } 112 }
111 dest->data[0] = 113 *dest = from_kgid_munged(&init_user_ns,
112 from_kgid_munged(&init_user_ns,
113 skb->sk->sk_socket->file->f_cred->fsgid); 114 skb->sk->sk_socket->file->f_cred->fsgid);
114 read_unlock_bh(&skb->sk->sk_callback_lock); 115 read_unlock_bh(&skb->sk->sk_callback_lock);
115 break; 116 break;
@@ -119,33 +120,33 @@ void nft_meta_get_eval(const struct nft_expr *expr,
119 120
120 if (dst == NULL) 121 if (dst == NULL)
121 goto err; 122 goto err;
122 dest->data[0] = dst->tclassid; 123 *dest = dst->tclassid;
123 break; 124 break;
124 } 125 }
125#endif 126#endif
126#ifdef CONFIG_NETWORK_SECMARK 127#ifdef CONFIG_NETWORK_SECMARK
127 case NFT_META_SECMARK: 128 case NFT_META_SECMARK:
128 dest->data[0] = skb->secmark; 129 *dest = skb->secmark;
129 break; 130 break;
130#endif 131#endif
131 case NFT_META_PKTTYPE: 132 case NFT_META_PKTTYPE:
132 if (skb->pkt_type != PACKET_LOOPBACK) { 133 if (skb->pkt_type != PACKET_LOOPBACK) {
133 dest->data[0] = skb->pkt_type; 134 *dest = skb->pkt_type;
134 break; 135 break;
135 } 136 }
136 137
137 switch (pkt->ops->pf) { 138 switch (pkt->ops->pf) {
138 case NFPROTO_IPV4: 139 case NFPROTO_IPV4:
139 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) 140 if (ipv4_is_multicast(ip_hdr(skb)->daddr))
140 dest->data[0] = PACKET_MULTICAST; 141 *dest = PACKET_MULTICAST;
141 else 142 else
142 dest->data[0] = PACKET_BROADCAST; 143 *dest = PACKET_BROADCAST;
143 break; 144 break;
144 case NFPROTO_IPV6: 145 case NFPROTO_IPV6:
145 if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) 146 if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
146 dest->data[0] = PACKET_MULTICAST; 147 *dest = PACKET_MULTICAST;
147 else 148 else
148 dest->data[0] = PACKET_BROADCAST; 149 *dest = PACKET_BROADCAST;
149 break; 150 break;
150 default: 151 default:
151 WARN_ON(1); 152 WARN_ON(1);
@@ -153,22 +154,22 @@ void nft_meta_get_eval(const struct nft_expr *expr,
153 } 154 }
154 break; 155 break;
155 case NFT_META_CPU: 156 case NFT_META_CPU:
156 dest->data[0] = raw_smp_processor_id(); 157 *dest = raw_smp_processor_id();
157 break; 158 break;
158 case NFT_META_IIFGROUP: 159 case NFT_META_IIFGROUP:
159 if (in == NULL) 160 if (in == NULL)
160 goto err; 161 goto err;
161 dest->data[0] = in->group; 162 *dest = in->group;
162 break; 163 break;
163 case NFT_META_OIFGROUP: 164 case NFT_META_OIFGROUP:
164 if (out == NULL) 165 if (out == NULL)
165 goto err; 166 goto err;
166 dest->data[0] = out->group; 167 *dest = out->group;
167 break; 168 break;
168 case NFT_META_CGROUP: 169 case NFT_META_CGROUP:
169 if (skb->sk == NULL || !sk_fullsock(skb->sk)) 170 if (skb->sk == NULL || !sk_fullsock(skb->sk))
170 goto err; 171 goto err;
171 dest->data[0] = skb->sk->sk_classid; 172 *dest = skb->sk->sk_classid;
172 break; 173 break;
173 default: 174 default:
174 WARN_ON(1); 175 WARN_ON(1);
@@ -177,17 +178,17 @@ void nft_meta_get_eval(const struct nft_expr *expr,
177 return; 178 return;
178 179
179err: 180err:
180 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 181 regs->verdict.code = NFT_BREAK;
181} 182}
182EXPORT_SYMBOL_GPL(nft_meta_get_eval); 183EXPORT_SYMBOL_GPL(nft_meta_get_eval);
183 184
184void nft_meta_set_eval(const struct nft_expr *expr, 185void nft_meta_set_eval(const struct nft_expr *expr,
185 struct nft_data data[NFT_REG_MAX + 1], 186 struct nft_regs *regs,
186 const struct nft_pktinfo *pkt) 187 const struct nft_pktinfo *pkt)
187{ 188{
188 const struct nft_meta *meta = nft_expr_priv(expr); 189 const struct nft_meta *meta = nft_expr_priv(expr);
189 struct sk_buff *skb = pkt->skb; 190 struct sk_buff *skb = pkt->skb;
190 u32 value = data[meta->sreg].data[0]; 191 u32 value = regs->data[meta->sreg];
191 192
192 switch (meta->key) { 193 switch (meta->key) {
193 case NFT_META_MARK: 194 case NFT_META_MARK:
@@ -217,22 +218,22 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
217 const struct nlattr * const tb[]) 218 const struct nlattr * const tb[])
218{ 219{
219 struct nft_meta *priv = nft_expr_priv(expr); 220 struct nft_meta *priv = nft_expr_priv(expr);
220 int err; 221 unsigned int len;
221 222
222 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 223 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
223 switch (priv->key) { 224 switch (priv->key) {
224 case NFT_META_LEN:
225 case NFT_META_PROTOCOL: 225 case NFT_META_PROTOCOL:
226 case NFT_META_IIFTYPE:
227 case NFT_META_OIFTYPE:
228 len = sizeof(u16);
229 break;
226 case NFT_META_NFPROTO: 230 case NFT_META_NFPROTO:
227 case NFT_META_L4PROTO: 231 case NFT_META_L4PROTO:
232 case NFT_META_LEN:
228 case NFT_META_PRIORITY: 233 case NFT_META_PRIORITY:
229 case NFT_META_MARK: 234 case NFT_META_MARK:
230 case NFT_META_IIF: 235 case NFT_META_IIF:
231 case NFT_META_OIF: 236 case NFT_META_OIF:
232 case NFT_META_IIFNAME:
233 case NFT_META_OIFNAME:
234 case NFT_META_IIFTYPE:
235 case NFT_META_OIFTYPE:
236 case NFT_META_SKUID: 237 case NFT_META_SKUID:
237 case NFT_META_SKGID: 238 case NFT_META_SKGID:
238#ifdef CONFIG_IP_ROUTE_CLASSID 239#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -246,21 +247,19 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
246 case NFT_META_IIFGROUP: 247 case NFT_META_IIFGROUP:
247 case NFT_META_OIFGROUP: 248 case NFT_META_OIFGROUP:
248 case NFT_META_CGROUP: 249 case NFT_META_CGROUP:
250 len = sizeof(u32);
251 break;
252 case NFT_META_IIFNAME:
253 case NFT_META_OIFNAME:
254 len = IFNAMSIZ;
249 break; 255 break;
250 default: 256 default:
251 return -EOPNOTSUPP; 257 return -EOPNOTSUPP;
252 } 258 }
253 259
254 priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 260 priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
255 err = nft_validate_output_register(priv->dreg); 261 return nft_validate_register_store(ctx, priv->dreg, NULL,
256 if (err < 0) 262 NFT_DATA_VALUE, len);
257 return err;
258
259 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
260 if (err < 0)
261 return err;
262
263 return 0;
264} 263}
265EXPORT_SYMBOL_GPL(nft_meta_get_init); 264EXPORT_SYMBOL_GPL(nft_meta_get_init);
266 265
@@ -269,20 +268,24 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
269 const struct nlattr * const tb[]) 268 const struct nlattr * const tb[])
270{ 269{
271 struct nft_meta *priv = nft_expr_priv(expr); 270 struct nft_meta *priv = nft_expr_priv(expr);
271 unsigned int len;
272 int err; 272 int err;
273 273
274 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 274 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
275 switch (priv->key) { 275 switch (priv->key) {
276 case NFT_META_MARK: 276 case NFT_META_MARK:
277 case NFT_META_PRIORITY: 277 case NFT_META_PRIORITY:
278 len = sizeof(u32);
279 break;
278 case NFT_META_NFTRACE: 280 case NFT_META_NFTRACE:
281 len = sizeof(u8);
279 break; 282 break;
280 default: 283 default:
281 return -EOPNOTSUPP; 284 return -EOPNOTSUPP;
282 } 285 }
283 286
284 priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG])); 287 priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
285 err = nft_validate_input_register(priv->sreg); 288 err = nft_validate_register_load(priv->sreg, len);
286 if (err < 0) 289 if (err < 0)
287 return err; 290 return err;
288 291
@@ -297,7 +300,7 @@ int nft_meta_get_dump(struct sk_buff *skb,
297 300
298 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 301 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
299 goto nla_put_failure; 302 goto nla_put_failure;
300 if (nla_put_be32(skb, NFTA_META_DREG, htonl(priv->dreg))) 303 if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
301 goto nla_put_failure; 304 goto nla_put_failure;
302 return 0; 305 return 0;
303 306
@@ -313,7 +316,7 @@ int nft_meta_set_dump(struct sk_buff *skb,
313 316
314 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 317 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
315 goto nla_put_failure; 318 goto nla_put_failure;
316 if (nla_put_be32(skb, NFTA_META_SREG, htonl(priv->sreg))) 319 if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
317 goto nla_put_failure; 320 goto nla_put_failure;
318 321
319 return 0; 322 return 0;
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index a0837c6c9283..ee2d71753746 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -37,7 +37,7 @@ struct nft_nat {
37}; 37};
38 38
39static void nft_nat_eval(const struct nft_expr *expr, 39static void nft_nat_eval(const struct nft_expr *expr,
40 struct nft_data data[NFT_REG_MAX + 1], 40 struct nft_regs *regs,
41 const struct nft_pktinfo *pkt) 41 const struct nft_pktinfo *pkt)
42{ 42{
43 const struct nft_nat *priv = nft_expr_priv(expr); 43 const struct nft_nat *priv = nft_expr_priv(expr);
@@ -49,33 +49,32 @@ static void nft_nat_eval(const struct nft_expr *expr,
49 if (priv->sreg_addr_min) { 49 if (priv->sreg_addr_min) {
50 if (priv->family == AF_INET) { 50 if (priv->family == AF_INET) {
51 range.min_addr.ip = (__force __be32) 51 range.min_addr.ip = (__force __be32)
52 data[priv->sreg_addr_min].data[0]; 52 regs->data[priv->sreg_addr_min];
53 range.max_addr.ip = (__force __be32) 53 range.max_addr.ip = (__force __be32)
54 data[priv->sreg_addr_max].data[0]; 54 regs->data[priv->sreg_addr_max];
55 55
56 } else { 56 } else {
57 memcpy(range.min_addr.ip6, 57 memcpy(range.min_addr.ip6,
58 data[priv->sreg_addr_min].data, 58 &regs->data[priv->sreg_addr_min],
59 sizeof(struct nft_data)); 59 sizeof(range.min_addr.ip6));
60 memcpy(range.max_addr.ip6, 60 memcpy(range.max_addr.ip6,
61 data[priv->sreg_addr_max].data, 61 &regs->data[priv->sreg_addr_max],
62 sizeof(struct nft_data)); 62 sizeof(range.max_addr.ip6));
63 } 63 }
64 range.flags |= NF_NAT_RANGE_MAP_IPS; 64 range.flags |= NF_NAT_RANGE_MAP_IPS;
65 } 65 }
66 66
67 if (priv->sreg_proto_min) { 67 if (priv->sreg_proto_min) {
68 range.min_proto.all = 68 range.min_proto.all =
69 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 69 *(__be16 *)&regs->data[priv->sreg_proto_min];
70 range.max_proto.all = 70 range.max_proto.all =
71 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 71 *(__be16 *)&regs->data[priv->sreg_proto_max];
72 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 72 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
73 } 73 }
74 74
75 range.flags |= priv->flags; 75 range.flags |= priv->flags;
76 76
77 data[NFT_REG_VERDICT].verdict = 77 regs->verdict.code = nf_nat_setup_info(ct, &range, priv->type);
78 nf_nat_setup_info(ct, &range, priv->type);
79} 78}
80 79
81static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = { 80static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
@@ -119,6 +118,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
119 const struct nlattr * const tb[]) 118 const struct nlattr * const tb[])
120{ 119{
121 struct nft_nat *priv = nft_expr_priv(expr); 120 struct nft_nat *priv = nft_expr_priv(expr);
121 unsigned int alen, plen;
122 u32 family; 122 u32 family;
123 int err; 123 int err;
124 124
@@ -146,25 +146,34 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
146 return -EINVAL; 146 return -EINVAL;
147 147
148 family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY])); 148 family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
149 if (family != AF_INET && family != AF_INET6)
150 return -EAFNOSUPPORT;
151 if (family != ctx->afi->family) 149 if (family != ctx->afi->family)
152 return -EOPNOTSUPP; 150 return -EOPNOTSUPP;
151
152 switch (family) {
153 case NFPROTO_IPV4:
154 alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip);
155 break;
156 case NFPROTO_IPV6:
157 alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
158 break;
159 default:
160 return -EAFNOSUPPORT;
161 }
153 priv->family = family; 162 priv->family = family;
154 163
155 if (tb[NFTA_NAT_REG_ADDR_MIN]) { 164 if (tb[NFTA_NAT_REG_ADDR_MIN]) {
156 priv->sreg_addr_min = 165 priv->sreg_addr_min =
157 ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN])); 166 nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
158 167 err = nft_validate_register_load(priv->sreg_addr_min, alen);
159 err = nft_validate_input_register(priv->sreg_addr_min);
160 if (err < 0) 168 if (err < 0)
161 return err; 169 return err;
162 170
163 if (tb[NFTA_NAT_REG_ADDR_MAX]) { 171 if (tb[NFTA_NAT_REG_ADDR_MAX]) {
164 priv->sreg_addr_max = 172 priv->sreg_addr_max =
165 ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX])); 173 nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]);
166 174
167 err = nft_validate_input_register(priv->sreg_addr_max); 175 err = nft_validate_register_load(priv->sreg_addr_max,
176 alen);
168 if (err < 0) 177 if (err < 0)
169 return err; 178 return err;
170 } else { 179 } else {
@@ -172,19 +181,21 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
172 } 181 }
173 } 182 }
174 183
184 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
175 if (tb[NFTA_NAT_REG_PROTO_MIN]) { 185 if (tb[NFTA_NAT_REG_PROTO_MIN]) {
176 priv->sreg_proto_min = 186 priv->sreg_proto_min =
177 ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN])); 187 nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
178 188
179 err = nft_validate_input_register(priv->sreg_proto_min); 189 err = nft_validate_register_load(priv->sreg_proto_min, plen);
180 if (err < 0) 190 if (err < 0)
181 return err; 191 return err;
182 192
183 if (tb[NFTA_NAT_REG_PROTO_MAX]) { 193 if (tb[NFTA_NAT_REG_PROTO_MAX]) {
184 priv->sreg_proto_max = 194 priv->sreg_proto_max =
185 ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX])); 195 nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]);
186 196
187 err = nft_validate_input_register(priv->sreg_proto_max); 197 err = nft_validate_register_load(priv->sreg_proto_max,
198 plen);
188 if (err < 0) 199 if (err < 0)
189 return err; 200 return err;
190 } else { 201 } else {
@@ -220,18 +231,18 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
220 goto nla_put_failure; 231 goto nla_put_failure;
221 232
222 if (priv->sreg_addr_min) { 233 if (priv->sreg_addr_min) {
223 if (nla_put_be32(skb, NFTA_NAT_REG_ADDR_MIN, 234 if (nft_dump_register(skb, NFTA_NAT_REG_ADDR_MIN,
224 htonl(priv->sreg_addr_min)) || 235 priv->sreg_addr_min) ||
225 nla_put_be32(skb, NFTA_NAT_REG_ADDR_MAX, 236 nft_dump_register(skb, NFTA_NAT_REG_ADDR_MAX,
226 htonl(priv->sreg_addr_max))) 237 priv->sreg_addr_max))
227 goto nla_put_failure; 238 goto nla_put_failure;
228 } 239 }
229 240
230 if (priv->sreg_proto_min) { 241 if (priv->sreg_proto_min) {
231 if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN, 242 if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_MIN,
232 htonl(priv->sreg_proto_min)) || 243 priv->sreg_proto_min) ||
233 nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX, 244 nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX,
234 htonl(priv->sreg_proto_max))) 245 priv->sreg_proto_max))
235 goto nla_put_failure; 246 goto nla_put_failure;
236 } 247 }
237 248
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 85daa84bfdfe..94fb3b27a2c5 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -18,12 +18,12 @@
18#include <net/netfilter/nf_tables.h> 18#include <net/netfilter/nf_tables.h>
19 19
20static void nft_payload_eval(const struct nft_expr *expr, 20static void nft_payload_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 const struct nft_payload *priv = nft_expr_priv(expr); 24 const struct nft_payload *priv = nft_expr_priv(expr);
25 const struct sk_buff *skb = pkt->skb; 25 const struct sk_buff *skb = pkt->skb;
26 struct nft_data *dest = &data[priv->dreg]; 26 u32 *dest = &regs->data[priv->dreg];
27 int offset; 27 int offset;
28 28
29 switch (priv->base) { 29 switch (priv->base) {
@@ -43,11 +43,12 @@ static void nft_payload_eval(const struct nft_expr *expr,
43 } 43 }
44 offset += priv->offset; 44 offset += priv->offset;
45 45
46 if (skb_copy_bits(skb, offset, dest->data, priv->len) < 0) 46 dest[priv->len / NFT_REG32_SIZE] = 0;
47 if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
47 goto err; 48 goto err;
48 return; 49 return;
49err: 50err:
50 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 51 regs->verdict.code = NFT_BREAK;
51} 52}
52 53
53static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = { 54static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
@@ -62,24 +63,21 @@ static int nft_payload_init(const struct nft_ctx *ctx,
62 const struct nlattr * const tb[]) 63 const struct nlattr * const tb[])
63{ 64{
64 struct nft_payload *priv = nft_expr_priv(expr); 65 struct nft_payload *priv = nft_expr_priv(expr);
65 int err;
66 66
67 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); 67 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
68 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); 68 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
69 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); 69 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
70 priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
70 71
71 priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG])); 72 return nft_validate_register_store(ctx, priv->dreg, NULL,
72 err = nft_validate_output_register(priv->dreg); 73 NFT_DATA_VALUE, priv->len);
73 if (err < 0)
74 return err;
75 return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
76} 74}
77 75
78static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr) 76static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
79{ 77{
80 const struct nft_payload *priv = nft_expr_priv(expr); 78 const struct nft_payload *priv = nft_expr_priv(expr);
81 79
82 if (nla_put_be32(skb, NFTA_PAYLOAD_DREG, htonl(priv->dreg)) || 80 if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
83 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) || 81 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
84 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) || 82 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
85 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len))) 83 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
@@ -131,9 +129,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx,
131 } 129 }
132 130
133 offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); 131 offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
134 len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); 132 len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
135 if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data))
136 return ERR_PTR(-EINVAL);
137 133
138 if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) && 134 if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
139 base != NFT_PAYLOAD_LL_HEADER) 135 base != NFT_PAYLOAD_LL_HEADER)
diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
index e8ae2f6bf232..96805d21d618 100644
--- a/net/netfilter/nft_queue.c
+++ b/net/netfilter/nft_queue.c
@@ -28,7 +28,7 @@ struct nft_queue {
28}; 28};
29 29
30static void nft_queue_eval(const struct nft_expr *expr, 30static void nft_queue_eval(const struct nft_expr *expr,
31 struct nft_data data[NFT_REG_MAX + 1], 31 struct nft_regs *regs,
32 const struct nft_pktinfo *pkt) 32 const struct nft_pktinfo *pkt)
33{ 33{
34 struct nft_queue *priv = nft_expr_priv(expr); 34 struct nft_queue *priv = nft_expr_priv(expr);
@@ -51,7 +51,7 @@ static void nft_queue_eval(const struct nft_expr *expr,
51 if (priv->flags & NFT_QUEUE_FLAG_BYPASS) 51 if (priv->flags & NFT_QUEUE_FLAG_BYPASS)
52 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS; 52 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
53 53
54 data[NFT_REG_VERDICT].verdict = ret; 54 regs->verdict.code = ret;
55} 55}
56 56
57static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = { 57static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index 42d0ca45fb9e..1c30f41cff5b 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -30,8 +30,7 @@ struct nft_rbtree_elem {
30}; 30};
31 31
32 32
33static bool nft_rbtree_lookup(const struct nft_set *set, 33static bool nft_rbtree_lookup(const struct nft_set *set, const u32 *key,
34 const struct nft_data *key,
35 const struct nft_set_ext **ext) 34 const struct nft_set_ext **ext)
36{ 35{
37 const struct nft_rbtree *priv = nft_set_priv(set); 36 const struct nft_rbtree *priv = nft_set_priv(set);
@@ -45,7 +44,7 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
45 while (parent != NULL) { 44 while (parent != NULL) {
46 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 45 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
47 46
48 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), key, set->klen); 47 d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen);
49 if (d < 0) { 48 if (d < 0) {
50 parent = parent->rb_left; 49 parent = parent->rb_left;
51 interval = rbe; 50 interval = rbe;
@@ -91,9 +90,9 @@ static int __nft_rbtree_insert(const struct nft_set *set,
91 while (*p != NULL) { 90 while (*p != NULL) {
92 parent = *p; 91 parent = *p;
93 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 92 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
94 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), 93 d = memcmp(nft_set_ext_key(&rbe->ext),
95 nft_set_ext_key(&new->ext), 94 nft_set_ext_key(&new->ext),
96 set->klen); 95 set->klen);
97 if (d < 0) 96 if (d < 0)
98 p = &parent->rb_left; 97 p = &parent->rb_left;
99 else if (d > 0) 98 else if (d > 0)
@@ -153,8 +152,8 @@ static void *nft_rbtree_deactivate(const struct nft_set *set,
153 while (parent != NULL) { 152 while (parent != NULL) {
154 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 153 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
155 154
156 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), &elem->key, 155 d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key.val,
157 set->klen); 156 set->klen);
158 if (d < 0) 157 if (d < 0)
159 parent = parent->rb_left; 158 parent = parent->rb_left;
160 else if (d > 0) 159 else if (d > 0)
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index d7e9e93a4e90..03f7bf40ae75 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -44,25 +44,28 @@ int nft_redir_init(const struct nft_ctx *ctx,
44 const struct nlattr * const tb[]) 44 const struct nlattr * const tb[])
45{ 45{
46 struct nft_redir *priv = nft_expr_priv(expr); 46 struct nft_redir *priv = nft_expr_priv(expr);
47 unsigned int plen;
47 int err; 48 int err;
48 49
49 err = nft_redir_validate(ctx, expr, NULL); 50 err = nft_redir_validate(ctx, expr, NULL);
50 if (err < 0) 51 if (err < 0)
51 return err; 52 return err;
52 53
54 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
53 if (tb[NFTA_REDIR_REG_PROTO_MIN]) { 55 if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
54 priv->sreg_proto_min = 56 priv->sreg_proto_min =
55 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN])); 57 nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
56 58
57 err = nft_validate_input_register(priv->sreg_proto_min); 59 err = nft_validate_register_load(priv->sreg_proto_min, plen);
58 if (err < 0) 60 if (err < 0)
59 return err; 61 return err;
60 62
61 if (tb[NFTA_REDIR_REG_PROTO_MAX]) { 63 if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
62 priv->sreg_proto_max = 64 priv->sreg_proto_max =
63 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX])); 65 nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]);
64 66
65 err = nft_validate_input_register(priv->sreg_proto_max); 67 err = nft_validate_register_load(priv->sreg_proto_max,
68 plen);
66 if (err < 0) 69 if (err < 0)
67 return err; 70 return err;
68 } else { 71 } else {
@@ -85,11 +88,11 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
85 const struct nft_redir *priv = nft_expr_priv(expr); 88 const struct nft_redir *priv = nft_expr_priv(expr);
86 89
87 if (priv->sreg_proto_min) { 90 if (priv->sreg_proto_min) {
88 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN, 91 if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MIN,
89 htonl(priv->sreg_proto_min))) 92 priv->sreg_proto_min))
90 goto nla_put_failure; 93 goto nla_put_failure;
91 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX, 94 if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX,
92 htonl(priv->sreg_proto_max))) 95 priv->sreg_proto_max))
93 goto nla_put_failure; 96 goto nla_put_failure;
94 } 97 }
95 98
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index 92877114aff4..62cabee42fbe 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -18,7 +18,7 @@
18#include <net/netfilter/ipv6/nf_reject.h> 18#include <net/netfilter/ipv6/nf_reject.h>
19 19
20static void nft_reject_inet_eval(const struct nft_expr *expr, 20static void nft_reject_inet_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_reject *priv = nft_expr_priv(expr); 24 struct nft_reject *priv = nft_expr_priv(expr);
@@ -58,7 +58,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
58 } 58 }
59 break; 59 break;
60 } 60 }
61 data[NFT_REG_VERDICT].verdict = NF_DROP; 61
62 regs->verdict.code = NF_DROP;
62} 63}
63 64
64static int nft_reject_inet_init(const struct nft_ctx *ctx, 65static int nft_reject_inet_init(const struct nft_ctx *ctx,