History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says: ==================== Netfilter updates for net-next A final pull request, I know it's very late but this time I think it's worth a bit of rush. The following patchset contains Netfilter/nf_tables updates for net-next, more specifically concatenation support and dynamic stateful expression instantiation. This also comes with a couple of small patches. One to fix the ebtables.h userspace header and another to get rid of an obsolete example file in tree that describes a nf_tables expression. This time, I decided to paste the original descriptions. This will result in a rather large commit description, but I think these bytes to keep. Patrick McHardy says: ==================== netfilter: nf_tables: concatenation support The following patches add support for concatenations, which allow multi dimensional exact matches in O(1). The basic idea is to split the data registers, currently consisting of 4 registers of 16 bytes each, into smaller units, 16 registers of 4 bytes each, and making sure each register store always leaves the full 32 bit in a well defined state, meaning smaller stores will zero the remaining bits. Based on that, we can load multiple adjacent registers with different values, thereby building a concatenated bigger value, and use that value for set lookups. Sets are changed to use variable sized extensions for their key and data values, removing the fixed limit of 16 bytes while saving memory if less space is needed. As a side effect, these patches will allow some nice optimizations in the future, like using jhash2 in nft_hash, removing the masking in nft_cmp_fast, optimized data comparison using 32 bit word size etc. These are not done so far however. The patches are split up as follows: * the first five patches add length validation to register loads and stores to make sure we stay within bounds and prepare the validation functions for the new addressing mode * the next patches prepare for changing to 32 bit addressing by introducing a struct nft_regs, which holds the verdict register as well as the data registers. The verdict members are moved to a new struct nft_verdict to allow to pull struct nft_data out of the stack. * the next patches contain preparatory conversions of expressions and sets to use 32 bit addressing * the next patch introduces so far unused register conversion helpers for parsing and dumping register numbers over netlink * following is the real conversion to 32 bit addressing, consisting of replacing struct nft_data in struct nft_regs by an array of u32s and actually translating and validating the new register numbers. * the final two patches add support for variable sized data items and variable sized keys / data in set elements The patches have been verified to work correctly with nft binaries using both old and new addressing. ==================== Patrick McHardy says: ==================== netfilter: nf_tables: dynamic stateful expression instantiation The following patches are the grand finale of my nf_tables set work, using all the building blocks put in place by the previous patches to support something like iptables hashlimit, but a lot more powerful. Sets are extended to allow attaching expressions to set elements. The dynset expression dynamically instantiates these expressions based on a template when creating new set elements and evaluates them for all new or updated set members. In combination with concatenations this effectively creates state tables for arbitrary combinations of keys, using the existing expression types to maintain that state. Regular set GC takes care of purging expired states. We currently support two different stateful expressions, counter and limit. Using limit as a template we can express the functionality of hashlimit, but completely unrestricted in the combination of keys. Using counter we can perform accounting for arbitrary flows. The following examples from patch 5/5 show some possibilities. Userspace syntax is still WIP, especially the listing of state tables will most likely be seperated from normal set listings and use a more structured format: 1. Limit the rate of new SSH connections per host, similar to iptables hashlimit: flow ip saddr timeout 60s \ limit 10/second \ accept 2. Account network traffic between each set of /24 networks: flow ip saddr & 255.255.255.0 . ip daddr & 255.255.255.0 \ counter 3. Account traffic to each host per user: flow skuid . ip daddr \ counter 4. Account traffic for each combination of source address and TCP flags: flow ip saddr . tcp flags \ counter The resulting set content after a Xmas-scan look like this: { 192.168.122.1 . fin | psh | urg : counter packets 1001 bytes 40040, 192.168.122.1 . ack : counter packets 74 bytes 3848, 192.168.122.1 . psh | ack : counter packets 35 bytes 3144 } In the future the "expressions attached to elements" will be extended to also support user created non-stateful expressions to allow to efficiently select beween a set of parameter sets, f.i. a set of log statements with different prefixes based on the interface, which currently require one rule each. This will most likely have to wait until the next kernel version though. ====================

David S. Miller committed 11 years ago

Commit bae97d82 parents 87ffabb 97bb43c36 files · +739 −579Browse files

Unified · Split

36 files
  1. include/linux/netfilter_bridge/ebtables.h +2 −1
  2. include/net/netfilter/nf_tables.h +73 −30
  3. include/net/netfilter/nft_meta.h +2 −2
  4. include/uapi/linux/netfilter/nf_tables.h +39 −1
  5. include/uapi/linux/netfilter_bridge/ebtables.h +0 −2
  6. net/bridge/netfilter/nft_meta_bridge.c +10 −16
  7. net/bridge/netfilter/nft_reject_bridge.c +3 −3
  8. net/ipv4/netfilter/nft_masq_ipv4.c +3 −6
  9. net/ipv4/netfilter/nft_redir_ipv4.c +5 −6
  10. net/ipv4/netfilter/nft_reject_ipv4.c +2 −2
  11. net/ipv6/netfilter/nft_masq_ipv6.c +2 −5
  12. net/ipv6/netfilter/nft_redir_ipv6.c +5 −6
  13. net/ipv6/netfilter/nft_reject_ipv6.c +2 −2
  14. net/netfilter/nf_tables_api.c +190 −81
  15. net/netfilter/nf_tables_core.c +21 −20
  16. net/netfilter/nft_bitwise.c +17 −20
  17. net/netfilter/nft_byteorder.c +16 −24
  18. net/netfilter/nft_cmp.c +24 −20
  19. net/netfilter/nft_compat.c +13 −13
  20. net/netfilter/nft_counter.c +2 −1
  21. net/netfilter/nft_ct.c +71 −39
  22. net/netfilter/nft_dynset.c +63 −16
  23. net/netfilter/nft_expr_template.c +0 −94
  24. net/netfilter/nft_exthdr.c +9 −14
  25. net/netfilter/nft_hash.c +9 −10
  26. net/netfilter/nft_immediate.c +8 −10
  27. net/netfilter/nft_limit.c +3 −2
  28. net/netfilter/nft_log.c +1 −1
  29. net/netfilter/nft_lookup.c +15 −16
  30. net/netfilter/nft_meta.c +55 −52
  31. net/netfilter/nft_nat.c +41 −30
  32. net/netfilter/nft_payload.c +10 −14
  33. net/netfilter/nft_queue.c +2 −2
  34. net/netfilter/nft_rbtree.c +7 −8
  35. net/netfilter/nft_redir.c +11 −8
  36. net/netfilter/nft_reject_inet.c +3 −2
include/linux/netfilter_bridge/ebtables.h+2−1
@@ -12,9 +12,10 @@ · 11 unmodified lines
1212 #ifndef __LINUX_BRIDGE_EFF_H
1313 #define __LINUX_BRIDGE_EFF_H
1414
15+#include <linux/if.h>
16+#include <linux/if_ether.h>
1517 #include <uapi/linux/netfilter_bridge/ebtables.h>
1618
17−
1819 /* return values for match() functions */
1920 #define EBT_MATCH 0
2021 #define EBT_NOMATCH 1
include/net/netfilter/nf_tables.h+73−30
@@ -1,6 +1,7 @@
11 #ifndef _NET_NF_TABLES_H
22 #define _NET_NF_TABLES_H
33
4+#include <linux/module.h>
45 #include <linux/list.h>
56 #include <linux/netfilter.h>
67 #include <linux/netfilter/nfnetlink.h>
@@ -36,29 +37,43 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt, · 29 unmodified lines
3637 pkt->xt.family = ops->pf;
3738 }
3839
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+ */
46+struct nft_verdict {
47+ u32 code;
48+ struct nft_chain *chain;
49+};
50+
3951 struct nft_data {
4052 union {
41− u32 data[4];
42− struct {
43− u32 verdict;
44− struct nft_chain *chain;
45− };
53+ u32 data[4];
54+ struct nft_verdict verdict;
4655 };
4756 } __attribute__((aligned(__alignof__(u64))));
4857
49−static inline int nft_data_cmp(const struct nft_data *d1,
50− const struct nft_data *d2,
51− unsigned int len)
52−{
53− return memcmp(d1->data, d2->data, len);
54−}
58+/**
59+ * struct nft_regs - nf_tables register set
60+ *
61+ * @data: data registers
62+ * @verdict: verdict register
63+ *
64+ * The first four data registers alias to the verdict register.
65+ */
66+struct nft_regs {
67+ union {
68+ u32 data[20];
69+ struct nft_verdict verdict;
70+ };
71+};
5572
56−static inline void nft_data_copy(struct nft_data *dst,
57− const struct nft_data *src)
73+static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
74+ unsigned int len)
5875 {
59− BUILD_BUG_ON(__alignof__(*dst) != __alignof__(u64));
60− *(u64 *)&dst->data[0] = *(u64 *)&src->data[0];
61− *(u64 *)&dst->data[2] = *(u64 *)&src->data[2];
76+ memcpy(dst, src, len);
6277 }
6378
6479 static inline void nft_data_debug(const struct nft_data *data)
@@ -96,7 +111,8 @@ struct nft_data_desc { · 31 unmodified lines
96111 unsigned int len;
97112 };
98113
99−int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
114+int nft_data_init(const struct nft_ctx *ctx,
115+ struct nft_data *data, unsigned int size,
100116 struct nft_data_desc *desc, const struct nlattr *nla);
101117 void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
102118 int 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) · 9 unmodified lines
112128 return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
113129 }
114130
115−int nft_validate_input_register(enum nft_registers reg);
116−int nft_validate_output_register(enum nft_registers reg);
117−int 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);
131+unsigned int nft_parse_register(const struct nlattr *attr);
132+int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
120133
134+int nft_validate_register_load(enum nft_registers reg, unsigned int len);
135+int 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);
121139
122140 /**
123141 * struct nft_userdata - user defined data associated with an object
@@ -141,7 +159,10 @@ struct nft_userdata { · 17 unmodified lines
141159 * @priv: element private data and extensions
142160 */
143161 struct 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;
145166 void *priv;
146167 };
147168
@@ -216,15 +237,15 @@ struct nft_expr; · 68 unmodified lines
216237 */
217238 struct nft_set_ops {
218239 bool (*lookup)(const struct nft_set *set,
219− const struct nft_data *key,
240+ const u32 *key,
220241 const struct nft_set_ext **ext);
221242 bool (*update)(struct nft_set *set,
222− const struct nft_data *key,
243+ const u32 *key,
223244 void *(*new)(struct nft_set *,
224245 const struct nft_expr *,
225− struct nft_data []),
246+ struct nft_regs *),
226247 const struct nft_expr *expr,
227− struct nft_data data[],
248+ struct nft_regs *regs,
228249 const struct nft_set_ext **ext);
229250
230251 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, · 119 unmodified lines
350371 * @NFT_SET_EXT_TIMEOUT: element timeout
351372 * @NFT_SET_EXT_EXPIRATION: element expiration time
352373 * @NFT_SET_EXT_USERDATA: user data associated with the element
374+ * @NFT_SET_EXT_EXPR: expression assiociated with the element
353375 * @NFT_SET_EXT_NUM: number of extension types
354376 */
355377 enum nft_set_extensions {
@@ -359,6 +381,7 @@ enum nft_set_extensions { · 3 unmodified lines
359381 NFT_SET_EXT_TIMEOUT,
360382 NFT_SET_EXT_EXPIRATION,
361383 NFT_SET_EXT_USERDATA,
384+ NFT_SET_EXT_EXPR,
362385 NFT_SET_EXT_NUM
363386 };
364387
@@ -470,6 +493,11 @@ static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext · 105 unmodified lines
470493 return nft_set_ext(ext, NFT_SET_EXT_USERDATA);
471494 }
472495
496+static 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+
473501 static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
474502 {
475503 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, · 8 unmodified lines
484512
485513 void *nft_set_elem_init(const struct nft_set *set,
486514 const struct nft_set_ext_tmpl *tmpl,
487− const struct nft_data *key,
488− const struct nft_data *data,
515+ const u32 *key, const u32 *data,
489516 u64 timeout, gfp_t gfp);
490517 void nft_set_elem_destroy(const struct nft_set *set, void *elem);
491518
@@ -556,6 +583,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, · 64 unmodified lines
556583 * @policy: netlink attribute policy
557584 * @maxattr: highest netlink attribute number
558585 * @family: address family for AF-specific types
586+ * @flags: expression type flags
559587 */
560588 struct nft_expr_type {
561589 const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
@@ -567,8 +595,11 @@ struct nft_expr_type { · 5 unmodified lines
567595 const struct nla_policy *policy;
568596 unsigned int maxattr;
569597 u8 family;
598+ u8 flags;
570599 };
571600
601+#define NFT_EXPR_STATEFUL 0x1
602+
572603 /**
573604 * struct nft_expr_ops - nf_tables expression operations
574605 *
@@ -584,7 +615,7 @@ struct nft_expr_type { · 9 unmodified lines
584615 struct nft_expr;
585616 struct nft_expr_ops {
586617 void (*eval)(const struct nft_expr *expr,
587− struct nft_data data[NFT_REG_MAX + 1],
618+ struct nft_regs *regs,
588619 const struct nft_pktinfo *pkt);
589620 unsigned int size;
590621
@@ -622,6 +653,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) · 31 unmodified lines
622653 return (void *)expr->data;
623654 }
624655
656+struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
657+ const struct nlattr *nla);
658+void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
659+int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
660+ const struct nft_expr *expr);
661+
662+static 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+
625668 /**
626669 * struct nft_rule - nf_tables rule
627670 *
include/net/netfilter/nft_meta.h+2−2
@@ -26,11 +26,11 @@ int nft_meta_set_dump(struct sk_buff *skb, · 25 unmodified lines
2626 const struct nft_expr *expr);
2727
2828 void nft_meta_get_eval(const struct nft_expr *expr,
29− struct nft_data data[NFT_REG_MAX + 1],
29+ struct nft_regs *regs,
3030 const struct nft_pktinfo *pkt);
3131
3232 void nft_meta_set_eval(const struct nft_expr *expr,
33− struct nft_data data[NFT_REG_MAX + 1],
33+ struct nft_regs *regs,
3434 const struct nft_pktinfo *pkt);
3535
3636 #endif
include/uapi/linux/netfilter/nf_tables.h+39−1
@@ -5,16 +5,45 @@ · 4 unmodified lines
55 #define NFT_CHAIN_MAXNAMELEN 32
66 #define NFT_USERDATA_MAXLEN 256
77
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+ */
817 enum nft_registers {
918 NFT_REG_VERDICT,
1019 NFT_REG_1,
1120 NFT_REG_2,
1221 NFT_REG_3,
1322 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,
1541 };
1642 #define NFT_REG_MAX (__NFT_REG_MAX - 1)
1743
44+#define NFT_REG_SIZE 16
45+#define NFT_REG32_SIZE 4
46+
1847 /**
1948 * enum nft_verdicts - nf_tables internal verdicts
2049 *
@@ -209,6 +238,7 @@ enum nft_rule_compat_attributes { · 188 unmodified lines
209238 * @NFT_SET_INTERVAL: set contains intervals
210239 * @NFT_SET_MAP: set is used as a dictionary
211240 * @NFT_SET_TIMEOUT: set uses timeouts
241+ * @NFT_SET_EVAL: set contains expressions for evaluation
212242 */
213243 enum nft_set_flags {
214244 NFT_SET_ANONYMOUS = 0x1,
@@ -216,6 +246,7 @@ enum nft_set_flags { · 1 unmodified line
216246 NFT_SET_INTERVAL = 0x4,
217247 NFT_SET_MAP = 0x8,
218248 NFT_SET_TIMEOUT = 0x10,
249+ NFT_SET_EVAL = 0x20,
219250 };
220251
221252 /**
@@ -293,6 +324,7 @@ enum nft_set_elem_flags { · 71 unmodified lines
293324 * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
294325 * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
295326 * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
327+ * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
296328 */
297329 enum nft_set_elem_attributes {
298330 NFTA_SET_ELEM_UNSPEC,
@@ -302,6 +334,7 @@ enum nft_set_elem_attributes { · 3 unmodified lines
302334 NFTA_SET_ELEM_TIMEOUT,
303335 NFTA_SET_ELEM_EXPIRATION,
304336 NFTA_SET_ELEM_USERDATA,
337+ NFTA_SET_ELEM_EXPR,
305338 __NFTA_SET_ELEM_MAX
306339 };
307340 #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -359,6 +392,9 @@ enum nft_data_attributes { · 51 unmodified lines
359392 };
360393 #define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
361394
395+/* Maximum length of a value */
396+#define NFT_DATA_VALUE_MAXLEN 64
397+
362398 /**
363399 * enum nft_verdict_attributes - nf_tables verdict netlink attributes
364400 *
@@ -531,6 +567,7 @@ enum nft_dynset_ops { · 166 unmodified lines
531567 * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
532568 * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
533569 * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
570+ * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
534571 */
535572 enum nft_dynset_attributes {
536573 NFTA_DYNSET_UNSPEC,
@@ -540,6 +577,7 @@ enum nft_dynset_attributes { · 3 unmodified lines
540577 NFTA_DYNSET_SREG_KEY,
541578 NFTA_DYNSET_SREG_DATA,
542579 NFTA_DYNSET_TIMEOUT,
580+ NFTA_DYNSET_EXPR,
543581 __NFTA_DYNSET_MAX,
544582 };
545583 #define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
include/uapi/linux/netfilter_bridge/ebtables.h+0−2
@@ -12,9 +12,7 @@ · 11 unmodified lines
1212
1313 #ifndef _UAPI__LINUX_BRIDGE_EFF_H
1414 #define _UAPI__LINUX_BRIDGE_EFF_H
15−#include <linux/if.h>
1615 #include <linux/netfilter_bridge.h>
17−#include <linux/if_ether.h>
1816
1917 #define EBT_TABLE_MAXNAMELEN 32
2018 #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
net/bridge/netfilter/nft_meta_bridge.c+10−16
@@ -19,12 +19,12 @@ · 18 unmodified lines
1919 #include "../br_private.h"
2020
2121 static 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,
2323 const struct nft_pktinfo *pkt)
2424 {
2525 const struct nft_meta *priv = nft_expr_priv(expr);
2626 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];
2828 const struct net_bridge_port *p;
2929
3030 switch (priv->key) {
@@ -40,12 +40,12 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr, · 9 unmodified lines
4040 goto out;
4141 }
4242
43− strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data));
43+ strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
4444 return;
4545 out:
46− return nft_meta_get_eval(expr, data, pkt);
46+ return nft_meta_get_eval(expr, regs, pkt);
4747 err:
48− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
48+ regs->verdict.code = NFT_BREAK;
4949 }
5050
5151 static 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, · 1 unmodified line
5353 const struct nlattr * const tb[])
5454 {
5555 struct nft_meta *priv = nft_expr_priv(expr);
56− int err;
56+ unsigned int len;
5757
5858 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
5959 switch (priv->key) {
6060 case NFT_META_BRI_IIFNAME:
6161 case NFT_META_BRI_OIFNAME:
62+ len = IFNAMSIZ;
6263 break;
6364 default:
6465 return nft_meta_get_init(ctx, expr, tb);
6566 }
6667
67− priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
68− err = nft_validate_output_register(priv->dreg);
69− if (err < 0)
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;
68+ priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
69+ return nft_validate_register_store(ctx, priv->dreg, NULL,
70+ NFT_DATA_VALUE, len);
7771 }
7872
7973 static struct nft_expr_type nft_meta_bridge_type;
net/bridge/netfilter/nft_reject_bridge.c+3−3
@@ -257,8 +257,8 @@ static void nft_reject_br_send_v6_unreach(struct net *net, · 256 unmodified lines
257257 }
258258
259259 static void nft_reject_bridge_eval(const struct nft_expr *expr,
260− struct nft_data data[NFT_REG_MAX + 1],
261− const struct nft_pktinfo *pkt)
260+ struct nft_regs *regs,
261+ const struct nft_pktinfo *pkt)
262262 {
263263 struct nft_reject *priv = nft_expr_priv(expr);
264264 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, · 45 unmodified lines
310310 break;
311311 }
312312 out:
313− data[NFT_REG_VERDICT].verdict = NF_DROP;
313+ regs->verdict.code = NF_DROP;
314314 }
315315
316316 static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
net/ipv4/netfilter/nft_masq_ipv4.c+3−6
@@ -17,20 +17,17 @@ · 16 unmodified lines
1717 #include <net/netfilter/ipv4/nf_nat_masquerade.h>
1818
1919 static void nft_masq_ipv4_eval(const struct nft_expr *expr,
20− struct nft_data data[NFT_REG_MAX + 1],
20+ struct nft_regs *regs,
2121 const struct nft_pktinfo *pkt)
2222 {
2323 struct nft_masq *priv = nft_expr_priv(expr);
2424 struct nf_nat_range range;
25− unsigned int verdict;
2625
2726 memset(&range, 0, sizeof(range));
2827 range.flags = priv->flags;
2928
30− verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
31− &range, pkt->out);
32−
33− data[NFT_REG_VERDICT].verdict = verdict;
29+ regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
30+ &range, pkt->out);
3431 }
3532
3633 static struct nft_expr_type nft_masq_ipv4_type;
net/ipv4/netfilter/nft_redir_ipv4.c+5−6
@@ -18,26 +18,25 @@ · 17 unmodified lines
1818 #include <net/netfilter/nft_redir.h>
1919
2020 static void nft_redir_ipv4_eval(const struct nft_expr *expr,
21− struct nft_data data[NFT_REG_MAX + 1],
21+ struct nft_regs *regs,
2222 const struct nft_pktinfo *pkt)
2323 {
2424 struct nft_redir *priv = nft_expr_priv(expr);
2525 struct nf_nat_ipv4_multi_range_compat mr;
26− unsigned int verdict;
2726
2827 memset(&mr, 0, sizeof(mr));
2928 if (priv->sreg_proto_min) {
3029 mr.range[0].min.all =
31− *(__be16 *)&data[priv->sreg_proto_min].data[0];
30+ *(__be16 *)&regs->data[priv->sreg_proto_min];
3231 mr.range[0].max.all =
33− *(__be16 *)&data[priv->sreg_proto_max].data[0];
32+ *(__be16 *)&regs->data[priv->sreg_proto_max];
3433 mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
3534 }
3635
3736 mr.range[0].flags |= priv->flags;
3837
39− verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum);
40− data[NFT_REG_VERDICT].verdict = verdict;
38+ regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr,
39+ pkt->ops->hooknum);
4140 }
4241
4342 static struct nft_expr_type nft_redir_ipv4_type;
net/ipv4/netfilter/nft_reject_ipv4.c+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #include <net/netfilter/nft_reject.h>
2121
2222 static void nft_reject_ipv4_eval(const struct nft_expr *expr,
23− struct nft_data data[NFT_REG_MAX + 1],
23+ struct nft_regs *regs,
2424 const struct nft_pktinfo *pkt)
2525 {
2626 struct nft_reject *priv = nft_expr_priv(expr);
@@ -37,7 +37,7 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr, · 10 unmodified lines
3737 break;
3838 }
3939
40− data[NFT_REG_VERDICT].verdict = NF_DROP;
40+ regs->verdict.code = NF_DROP;
4141 }
4242
4343 static struct nft_expr_type nft_reject_ipv4_type;
net/ipv6/netfilter/nft_masq_ipv6.c+2−5
@@ -18,19 +18,16 @@ · 17 unmodified lines
1818 #include <net/netfilter/ipv6/nf_nat_masquerade.h>
1919
2020 static void nft_masq_ipv6_eval(const struct nft_expr *expr,
21− struct nft_data data[NFT_REG_MAX + 1],
21+ struct nft_regs *regs,
2222 const struct nft_pktinfo *pkt)
2323 {
2424 struct nft_masq *priv = nft_expr_priv(expr);
2525 struct nf_nat_range range;
26− unsigned int verdict;
2726
2827 memset(&range, 0, sizeof(range));
2928 range.flags = priv->flags;
3029
31− verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
32−
33− data[NFT_REG_VERDICT].verdict = verdict;
30+ regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
3431 }
3532
3633 static struct nft_expr_type nft_masq_ipv6_type;
net/ipv6/netfilter/nft_redir_ipv6.c+5−6
@@ -18,26 +18,25 @@ · 17 unmodified lines
1818 #include <net/netfilter/nf_nat_redirect.h>
1919
2020 static void nft_redir_ipv6_eval(const struct nft_expr *expr,
21− struct nft_data data[NFT_REG_MAX + 1],
21+ struct nft_regs *regs,
2222 const struct nft_pktinfo *pkt)
2323 {
2424 struct nft_redir *priv = nft_expr_priv(expr);
2525 struct nf_nat_range range;
26− unsigned int verdict;
2726
2827 memset(&range, 0, sizeof(range));
2928 if (priv->sreg_proto_min) {
3029 range.min_proto.all =
31− *(__be16 *)&data[priv->sreg_proto_min].data[0];
30+ *(__be16 *)&regs->data[priv->sreg_proto_min],
3231 range.max_proto.all =
33− *(__be16 *)&data[priv->sreg_proto_max].data[0];
32+ *(__be16 *)&regs->data[priv->sreg_proto_max],
3433 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
3534 }
3635
3736 range.flags |= priv->flags;
3837
39− verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum);
40− data[NFT_REG_VERDICT].verdict = verdict;
38+ regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range,
39+ pkt->ops->hooknum);
4140 }
4241
4342 static struct nft_expr_type nft_redir_ipv6_type;
net/ipv6/netfilter/nft_reject_ipv6.c+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #include <net/netfilter/ipv6/nf_reject.h>
2121
2222 static void nft_reject_ipv6_eval(const struct nft_expr *expr,
23− struct nft_data data[NFT_REG_MAX + 1],
23+ struct nft_regs *regs,
2424 const struct nft_pktinfo *pkt)
2525 {
2626 struct nft_reject *priv = nft_expr_priv(expr);
@@ -38,7 +38,7 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr, · 11 unmodified lines
3838 break;
3939 }
4040
41− data[NFT_REG_VERDICT].verdict = NF_DROP;
41+ regs->verdict.code = NF_DROP;
4242 }
4343
4444 static struct nft_expr_type nft_reject_ipv6_type;
net/netfilter/nf_tables_api.c+190−81
@@ -1545,6 +1545,23 @@ nla_put_failure: · 1544 unmodified lines
15451545 return -1;
15461546 };
15471547
1548+int 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+
1561+nla_put_failure:
1562+ return -1;
1563+}
1564+
15481565 struct nft_expr_info {
15491566 const struct nft_expr_ops *ops;
15501567 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
@@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx, · 71 unmodified lines
16221639 module_put(expr->ops->type->owner);
16231640 }
16241641
1642+struct 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;
1663+err2:
1664+ module_put(info.ops->type->owner);
1665+err1:
1666+ return ERR_PTR(err);
1667+}
1668+
1669+void 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+
16251675 /*
16261676 * Rules
16271677 */
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 75 unmodified lines
17031753 if (list == NULL)
17041754 goto nla_put_failure;
17051755 nft_rule_for_each_expr(expr, next, rule) {
1706− struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
1707− if (elem == NULL)
1756+ if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
17081757 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);
17121758 }
17131759 nla_nest_end(skb, list);
17141760
@@ -2608,16 +2654,20 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb, · 893 unmodified lines
26082654 }
26092655
26102656 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)
26122658 return -EINVAL;
26132659
26142660 flags = 0;
26152661 if (nla[NFTA_SET_FLAGS] != NULL) {
26162662 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
26172663 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2618− NFT_SET_INTERVAL | NFT_SET_MAP |
2619− NFT_SET_TIMEOUT))
2664+ NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
2665+ NFT_SET_MAP | NFT_SET_EVAL))
26202666 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;
26212671 }
26222672
26232673 dtype = 0;
@@ -2634,11 +2684,10 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb, · 10 unmodified lines
26342684 if (nla[NFTA_SET_DATA_LEN] == NULL)
26352685 return -EINVAL;
26362686 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
2637− if (desc.dlen == 0 ||
2638− desc.dlen > FIELD_SIZEOF(struct nft_data, data))
2687+ if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
26392688 return -EINVAL;
26402689 } else
2641− desc.dlen = sizeof(struct nft_data);
2690+ desc.dlen = sizeof(struct nft_verdict);
26422691 } else if (flags & NFT_SET_MAP)
26432692 return -EINVAL;
26442693
@@ -2797,9 +2846,10 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, · 152 unmodified lines
27972846 enum nft_registers dreg;
27982847
27992848 dreg = nft_type_to_reg(set->dtype);
2800− return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext),
2801− set->dtype == NFT_DATA_VERDICT ?
2802− NFT_DATA_VERDICT : NFT_DATA_VALUE);
2849+ return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
2850+ set->dtype == NFT_DATA_VERDICT ?
2851+ NFT_DATA_VERDICT : NFT_DATA_VALUE,
2852+ set->dlen);
28032853 }
28042854
28052855 int 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, · 47 unmodified lines
28532903
28542904 const struct nft_set_ext_type nft_set_ext_types[] = {
28552905 [NFT_SET_EXT_KEY] = {
2856− .len = sizeof(struct nft_data),
2857− .align = __alignof__(struct nft_data),
2906+ .align = __alignof__(u32),
28582907 },
28592908 [NFT_SET_EXT_DATA] = {
2860− .len = sizeof(struct nft_data),
2861− .align = __alignof__(struct nft_data),
2909+ .align = __alignof__(u32),
2910+ },
2911+ [NFT_SET_EXT_EXPR] = {
2912+ .align = __alignof__(struct nft_expr),
28622913 },
28632914 [NFT_SET_EXT_FLAGS] = {
28642915 .len = sizeof(u8),
@@ -2946,6 +2997,10 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, · 81 unmodified lines
29462997 set->dlen) < 0)
29472998 goto nla_put_failure;
29482999
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+
29493004 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
29503005 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
29513006 htonl(*nft_set_ext_flags(ext))))
@@ -3200,8 +3255,7 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx, · 248 unmodified lines
32003255
32013256 void *nft_set_elem_init(const struct nft_set *set,
32023257 const struct nft_set_ext_tmpl *tmpl,
3203− const struct nft_data *key,
3204− const struct nft_data *data,
3258+ const u32 *key, const u32 *data,
32053259 u64 timeout, gfp_t gfp)
32063260 {
32073261 struct nft_set_ext *ext;
@@ -3233,6 +3287,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem) · 25 unmodified lines
32333287 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
32343288 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
32353289 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));
32363292
32373293 kfree(elem);
32383294 }
@@ -3299,14 +3355,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 60 unmodified lines
32993355 timeout = set->timeout;
33003356 }
33013357
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]);
33033360 if (err < 0)
33043361 goto err1;
33053362 err = -EINVAL;
33063363 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
33073364 goto err2;
33083365
3309− nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY);
3366+ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
33103367 if (timeout > 0) {
33113368 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
33123369 if (timeout != set->timeout)
@@ -3314,7 +3371,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 1 unmodified line
33143371 }
33153372
33163373 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]);
33183376 if (err < 0)
33193377 goto err2;
33203378
@@ -3333,13 +3391,14 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 12 unmodified lines
33333391 if (!(binding->flags & NFT_SET_MAP))
33343392 continue;
33353393
3336− err = nft_validate_data_load(&bind_ctx, dreg,
3337− &data, d2.type);
3394+ err = nft_validate_register_store(&bind_ctx, dreg,
3395+ &data,
3396+ d2.type, d2.len);
33383397 if (err < 0)
33393398 goto err3;
33403399 }
33413400
3342− nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA);
3401+ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
33433402 }
33443403
33453404 /* 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, · 9 unmodified lines
33553414 }
33563415
33573416 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,
33593418 timeout, GFP_KERNEL);
33603419 if (elem.priv == NULL)
33613420 goto err3;
@@ -3390,7 +3449,7 @@ err3: · 28 unmodified lines
33903449 if (nla[NFTA_SET_ELEM_DATA] != NULL)
33913450 nft_data_uninit(&data, d2.type);
33923451 err2:
3393− nft_data_uninit(&elem.key, d1.type);
3452+ nft_data_uninit(&elem.key.val, d1.type);
33943453 err1:
33953454 return err;
33963455 }
@@ -3457,7 +3516,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, · 60 unmodified lines
34573516 if (nla[NFTA_SET_ELEM_KEY] == NULL)
34583517 goto err1;
34593518
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]);
34613521 if (err < 0)
34623522 goto err1;
34633523
@@ -3484,7 +3544,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, · 20 unmodified lines
34843544 err3:
34853545 kfree(trans);
34863546 err2:
3487− nft_data_uninit(&elem.key, desc.type);
3547+ nft_data_uninit(&elem.key.val, desc.type);
34883548 err1:
34893549 return err;
34903550 }
@@ -4047,10 +4107,10 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, · 556 unmodified lines
40474107 return 0;
40484108
40494109 data = nft_set_ext_data(ext);
4050− switch (data->verdict) {
4110+ switch (data->verdict.code) {
40514111 case NFT_JUMP:
40524112 case NFT_GOTO:
4053− return nf_tables_check_loops(ctx, data->chain);
4113+ return nf_tables_check_loops(ctx, data->verdict.chain);
40544114 default:
40554115 return 0;
40564116 }
@@ -4083,10 +4143,11 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx, · 26 unmodified lines
40834143 if (data == NULL)
40844144 continue;
40854145
4086− switch (data->verdict) {
4146+ switch (data->verdict.code) {
40874147 case NFT_JUMP:
40884148 case NFT_GOTO:
4089− err = nf_tables_check_loops(ctx, data->chain);
4149+ err = nf_tables_check_loops(ctx,
4150+ data->verdict.chain);
40904151 if (err < 0)
40914152 return err;
40924153 default:
@@ -4120,85 +4181,129 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx, · 27 unmodified lines
41204181 }
41214182
41224183 /**
4123− * nft_validate_input_register - validate an expressions' input register
4184+ * nft_parse_register - parse a register value from a netlink attribute
41244185 *
4125− * @reg: the register number
4186+ * @attr: netlink attribute
41264187 *
4127− * Validate that the input register is one of the general purpose
4128− * registers.
4188+ * Parse and translate a register value from a netlink attribute.
4189+ * Registers used to be 128 bit wide, these register numbers will be
4190+ * mapped to the corresponding 32 bit register numbers.
41294191 */
4130−int nft_validate_input_register(enum nft_registers reg)
4192+unsigned int nft_parse_register(const struct nlattr *attr)
41314193 {
4132− if (reg <= NFT_REG_VERDICT)
4133− return -EINVAL;
4134− if (reg > NFT_REG_MAX)
4135− return -ERANGE;
4136− return 0;
4194+ unsigned int reg;
4195+
4196+ reg = ntohl(nla_get_be32(attr));
4197+ switch (reg) {
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+ }
41374203 }
4138−EXPORT_SYMBOL_GPL(nft_validate_input_register);
4204+EXPORT_SYMBOL_GPL(nft_parse_register);
41394205
41404206 /**
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+ */
4217+int 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+}
4226+EXPORT_SYMBOL_GPL(nft_dump_register);
4227+
4228+/**
4229+ * nft_validate_register_load - validate a load from a register
41424230 *
41434231 * @reg: the register number
4232+ * @len: the length of the data
41444233 *
4145− * Validate that the output register is one of the general purpose
4146− * registers or the verdict register.
4234+ * Validate that the input register is one of the general purpose
4235+ * registers and that the length of the load is within the bounds.
41474236 */
4148−int nft_validate_output_register(enum nft_registers reg)
4237+int nft_validate_register_load(enum nft_registers reg, unsigned int len)
41494238 {
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)
41514242 return -EINVAL;
4152− if (reg > NFT_REG_MAX)
4243+ if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
41534244 return -ERANGE;
4245+
41544246 return 0;
41554247 }
4156−EXPORT_SYMBOL_GPL(nft_validate_output_register);
4248+EXPORT_SYMBOL_GPL(nft_validate_register_load);
41574249
41584250 /**
4159− * nft_validate_data_load - validate an expressions' data load
4251+ * nft_validate_register_store - validate an expressions' register store
41604252 *
41614253 * @ctx: context of the expression performing the load
41624254 * @reg: the destination register number
41634255 * @data: the data to load
41644256 * @type: the data type
4257+ * @len: the length of the data
41654258 *
41664259 * Validate that a data load uses the appropriate data type for
4167− * the destination register. A value of NULL for the data means
4168− * that its runtime gathered data, which is always of type
4169− * NFT_DATA_VALUE.
4260+ * the destination register and the length is within the bounds.
4261+ * A value of NULL for the data means that its runtime gathered
4262+ * data.
41704263 */
4171−int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
4172− const struct nft_data *data,
4173− enum nft_data_types type)
4264+int nft_validate_register_store(const struct nft_ctx *ctx,
4265+ enum nft_registers reg,
4266+ const struct nft_data *data,
4267+ enum nft_data_types type, unsigned int len)
41744268 {
41754269 int err;
41764270
41774271 switch (reg) {
41784272 case NFT_REG_VERDICT:
4179− if (data == NULL || type != NFT_DATA_VERDICT)
4273+ if (type != NFT_DATA_VERDICT)
41804274 return -EINVAL;
41814275
4182− if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) {
4183− err = nf_tables_check_loops(ctx, data->chain);
4276+ if (data != NULL &&
4277+ (data->verdict.code == NFT_GOTO ||
4278+ data->verdict.code == NFT_JUMP)) {
4279+ err = nf_tables_check_loops(ctx, data->verdict.chain);
41844280 if (err < 0)
41854281 return err;
41864282
4187− if (ctx->chain->level + 1 > data->chain->level) {
4283+ if (ctx->chain->level + 1 >
4284+ data->verdict.chain->level) {
41884285 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
41894286 return -EMLINK;
4190− data->chain->level = ctx->chain->level + 1;
4287+ data->verdict.chain->level = ctx->chain->level + 1;
41914288 }
41924289 }
41934290
41944291 return 0;
41954292 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+
41964301 if (data != NULL && type != NFT_DATA_VALUE)
41974302 return -EINVAL;
41984303 return 0;
41994304 }
42004305 }
4201−EXPORT_SYMBOL_GPL(nft_validate_data_load);
4306+EXPORT_SYMBOL_GPL(nft_validate_register_store);
42024307
42034308 static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
42044309 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
@@ -4219,11 +4324,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, · 14 unmodified lines
42194324
42204325 if (!tb[NFTA_VERDICT_CODE])
42214326 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]));
42234328
4224− switch (data->verdict) {
4329+ switch (data->verdict.code) {
42254330 default:
4226− switch (data->verdict & NF_VERDICT_MASK) {
4331+ switch (data->verdict.code & NF_VERDICT_MASK) {
42274332 case NF_ACCEPT:
42284333 case NF_DROP:
42294334 case NF_QUEUE:
@@ -4249,7 +4354,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, · 19 unmodified lines
42494354 return -EOPNOTSUPP;
42504355
42514356 chain->use++;
4252− data->chain = chain;
4357+ data->verdict.chain = chain;
42534358 desc->len = sizeof(data);
42544359 break;
42554360 }
@@ -4260,10 +4365,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, · 4 unmodified lines
42604365
42614366 static void nft_verdict_uninit(const struct nft_data *data)
42624367 {
4263− switch (data->verdict) {
4368+ switch (data->verdict.code) {
42644369 case NFT_JUMP:
42654370 case NFT_GOTO:
4266− data->chain->use--;
4371+ data->verdict.chain->use--;
42674372 break;
42684373 }
42694374 }
@@ -4276,13 +4381,14 @@ static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data) · 6 unmodified lines
42764381 if (!nest)
42774382 goto nla_put_failure;
42784383
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)))
42804385 goto nla_put_failure;
42814386
4282− switch (data->verdict) {
4387+ switch (data->verdict.code) {
42834388 case NFT_JUMP:
42844389 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))
42864392 goto nla_put_failure;
42874393 }
42884394 nla_nest_end(skb, nest);
@@ -4292,7 +4398,8 @@ nla_put_failure: · 3 unmodified lines
42924398 return -1;
42934399 }
42944400
4295−static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
4401+static int nft_value_init(const struct nft_ctx *ctx,
4402+ struct nft_data *data, unsigned int size,
42964403 struct nft_data_desc *desc, const struct nlattr *nla)
42974404 {
42984405 unsigned int len;
@@ -4300,10 +4407,10 @@ static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, · 1 unmodified line
43004407 len = nla_len(nla);
43014408 if (len == 0)
43024409 return -EINVAL;
4303− if (len > sizeof(data->data))
4410+ if (len > size)
43044411 return -EOVERFLOW;
43054412
4306− nla_memcpy(data->data, nla, sizeof(data->data));
4413+ nla_memcpy(data->data, nla, len);
43074414 desc->type = NFT_DATA_VALUE;
43084415 desc->len = len;
43094416 return 0;
@@ -4316,8 +4423,7 @@ static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data, · 6 unmodified lines
43164423 }
43174424
43184425 static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4319− [NFTA_DATA_VALUE] = { .type = NLA_BINARY,
4320− .len = FIELD_SIZEOF(struct nft_data, data) },
4426+ [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
43214427 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
43224428 };
43234429
@@ -4326,6 +4432,7 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { · 2 unmodified lines
43264432 *
43274433 * @ctx: context of the expression using the data
43284434 * @data: destination struct nft_data
4435+ * @size: maximum data length
43294436 * @desc: data description
43304437 * @nla: netlink attribute containing data
43314438 *
@@ -4335,7 +4442,8 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { · 3 unmodified lines
43354442 * The caller can indicate that it only wants to accept data of type
43364443 * NFT_DATA_VALUE by passing NULL for the ctx argument.
43374444 */
4338−int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
4445+int nft_data_init(const struct nft_ctx *ctx,
4446+ struct nft_data *data, unsigned int size,
43394447 struct nft_data_desc *desc, const struct nlattr *nla)
43404448 {
43414449 struct nlattr *tb[NFTA_DATA_MAX + 1];
@@ -4346,7 +4454,8 @@ int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, · 4 unmodified lines
43464454 return err;
43474455
43484456 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]);
43504459 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
43514460 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
43524461 return -EINVAL;
net/netfilter/nf_tables_core.c+21−20
@@ -65,23 +65,23 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt, · 64 unmodified lines
6565 }
6666
6767 static void nft_cmp_fast_eval(const struct nft_expr *expr,
68− struct nft_data data[NFT_REG_MAX + 1])
68+ struct nft_regs *regs)
6969 {
7070 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
7171 u32 mask = nft_cmp_fast_mask(priv->len);
7272
73− if ((data[priv->sreg].data[0] & mask) == priv->data)
73+ if ((regs->data[priv->sreg] & mask) == priv->data)
7474 return;
75− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
75+ regs->verdict.code = NFT_BREAK;
7676 }
7777
7878 static bool nft_payload_fast_eval(const struct nft_expr *expr,
79− struct nft_data data[NFT_REG_MAX + 1],
79+ struct nft_regs *regs,
8080 const struct nft_pktinfo *pkt)
8181 {
8282 const struct nft_payload *priv = nft_expr_priv(expr);
8383 const struct sk_buff *skb = pkt->skb;
84− struct nft_data *dest = &data[priv->dreg];
84+ u32 *dest = &regs->data[priv->dreg];
8585 unsigned char *ptr;
8686
8787 if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -94,12 +94,13 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr, · 6 unmodified lines
9494 if (unlikely(ptr + priv->len >= skb_tail_pointer(skb)))
9595 return false;
9696
97+ *dest = 0;
9798 if (priv->len == 2)
98− *(u16 *)dest->data = *(u16 *)ptr;
99+ *(u16 *)dest = *(u16 *)ptr;
99100 else if (priv->len == 4)
100− *(u32 *)dest->data = *(u32 *)ptr;
101+ *(u32 *)dest = *(u32 *)ptr;
101102 else
102− *(u8 *)dest->data = *(u8 *)ptr;
103+ *(u8 *)dest = *(u8 *)ptr;
103104 return true;
104105 }
105106
@@ -116,7 +117,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) · 10 unmodified lines
116117 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
117118 const struct nft_rule *rule;
118119 const struct nft_expr *expr, *last;
119− struct nft_data data[NFT_REG_MAX + 1];
120+ struct nft_regs regs;
120121 unsigned int stackptr = 0;
121122 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
122123 struct nft_stats *stats;
@@ -127,7 +128,7 @@ do_chain: · 4 unmodified lines
127128 rulenum = 0;
128129 rule = list_entry(&chain->rules, struct nft_rule, list);
129130 next_rule:
130− data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
131+ regs.verdict.code = NFT_CONTINUE;
131132 list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
132133
133134 /* This rule is not active, skip. */
@@ -138,18 +139,18 @@ next_rule: · 4 unmodified lines
138139
139140 nft_rule_for_each_expr(expr, last, rule) {
140141 if (expr->ops == &nft_cmp_fast_ops)
141− nft_cmp_fast_eval(expr, data);
142+ nft_cmp_fast_eval(expr, &regs);
142143 else if (expr->ops != &nft_payload_fast_ops ||
143− !nft_payload_fast_eval(expr, data, pkt))
144− expr->ops->eval(expr, data, pkt);
144+ !nft_payload_fast_eval(expr, &regs, pkt))
145+ expr->ops->eval(expr, &regs, pkt);
145146
146− if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE)
147+ if (regs.verdict.code != NFT_CONTINUE)
147148 break;
148149 }
149150
150− switch (data[NFT_REG_VERDICT].verdict) {
151+ switch (regs.verdict.code) {
151152 case NFT_BREAK:
152− data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
153+ regs.verdict.code = NFT_CONTINUE;
153154 continue;
154155 case NFT_CONTINUE:
155156 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
@@ -158,15 +159,15 @@ next_rule: · 2 unmodified lines
158159 break;
159160 }
160161
161− switch (data[NFT_REG_VERDICT].verdict & NF_VERDICT_MASK) {
162+ switch (regs.verdict.code & NF_VERDICT_MASK) {
162163 case NF_ACCEPT:
163164 case NF_DROP:
164165 case NF_QUEUE:
165166 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
166− return data[NFT_REG_VERDICT].verdict;
167+ return regs.verdict.code;
167168 }
168169
169− switch (data[NFT_REG_VERDICT].verdict) {
170+ switch (regs.verdict.code) {
170171 case NFT_JUMP:
171172 BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE);
172173 jumpstack[stackptr].chain = chain;
@@ -177,7 +178,7 @@ next_rule: · 4 unmodified lines
177178 case NFT_GOTO:
178179 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
179180
180− chain = data[NFT_REG_VERDICT].chain;
181+ chain = regs.verdict.chain;
181182 goto do_chain;
182183 case NFT_CONTINUE:
183184 rulenum++;
net/netfilter/nft_bitwise.c+17−20
@@ -26,18 +26,16 @@ struct nft_bitwise { · 25 unmodified lines
2626 };
2727
2828 static void nft_bitwise_eval(const struct nft_expr *expr,
29− struct nft_data data[NFT_REG_MAX + 1],
29+ struct nft_regs *regs,
3030 const struct nft_pktinfo *pkt)
3131 {
3232 const struct nft_bitwise *priv = nft_expr_priv(expr);
33− const struct nft_data *src = &data[priv->sreg];
34− struct nft_data *dst = &data[priv->dreg];
33+ const u32 *src = &regs->data[priv->sreg];
34+ u32 *dst = &regs->data[priv->dreg];
3535 unsigned int i;
3636
37− for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++) {
38− dst->data[i] = (src->data[i] & priv->mask.data[i]) ^
39− priv->xor.data[i];
40− }
37+ for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
38+ dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
4139 }
4240
4341 static 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, · 19 unmodified lines
6361 tb[NFTA_BITWISE_XOR] == NULL)
6462 return -EINVAL;
6563
66− priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
67− err = nft_validate_input_register(priv->sreg);
64+ priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
65+ priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
66+ err = nft_validate_register_load(priv->sreg, priv->len);
6867 if (err < 0)
6968 return err;
7069
71− priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG]));
72− err = nft_validate_output_register(priv->dreg);
70+ priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
71+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
72+ NFT_DATA_VALUE, priv->len);
7373 if (err < 0)
7474 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]));
8075
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]);
8278 if (err < 0)
8379 return err;
8480 if (d1.len != priv->len)
8581 return -EINVAL;
8682
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]);
8885 if (err < 0)
8986 return err;
9087 if (d2.len != priv->len)
@@ -97,9 +94,9 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr) · 6 unmodified lines
9794 {
9895 const struct nft_bitwise *priv = nft_expr_priv(expr);
9996
100− if (nla_put_be32(skb, NFTA_BITWISE_SREG, htonl(priv->sreg)))
97+ if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
10198 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))
103100 goto nla_put_failure;
104101 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
105102 goto nla_put_failure;
net/netfilter/nft_byteorder.c+16−24
@@ -26,16 +26,17 @@ struct nft_byteorder { · 25 unmodified lines
2626 };
2727
2828 static void nft_byteorder_eval(const struct nft_expr *expr,
29− struct nft_data data[NFT_REG_MAX + 1],
29+ struct nft_regs *regs,
3030 const struct nft_pktinfo *pkt)
3131 {
3232 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];
3435 union { u32 u32; u16 u16; } *s, *d;
3536 unsigned int i;
3637
37− s = (void *)src->data;
38− d = (void *)dst->data;
38+ s = (void *)src;
39+ d = (void *)dst;
3940
4041 switch (priv->size) {
4142 case 4:
@@ -87,19 +88,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, · 45 unmodified lines
8788 tb[NFTA_BYTEORDER_OP] == NULL)
8889 return -EINVAL;
8990
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−
10391 priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP]));
10492 switch (priv->op) {
10593 case NFT_BYTEORDER_NTOH:
@@ -109,10 +97,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, · 3 unmodified lines
10997 return -EINVAL;
11098 }
11199
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−
116100 priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
117101 switch (priv->size) {
118102 case 2:
@@ -122,16 +106,24 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, · 3 unmodified lines
122106 return -EINVAL;
123107 }
124108
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);
126118 }
127119
128120 static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
129121 {
130122 const struct nft_byteorder *priv = nft_expr_priv(expr);
131123
132− if (nla_put_be32(skb, NFTA_BYTEORDER_SREG, htonl(priv->sreg)))
124+ if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg))
133125 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))
135127 goto nla_put_failure;
136128 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op)))
137129 goto nla_put_failure;
net/netfilter/nft_cmp.c+24−20
@@ -25,13 +25,13 @@ struct nft_cmp_expr { · 24 unmodified lines
2525 };
2626
2727 static void nft_cmp_eval(const struct nft_expr *expr,
28− struct nft_data data[NFT_REG_MAX + 1],
28+ struct nft_regs *regs,
2929 const struct nft_pktinfo *pkt)
3030 {
3131 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
3232 int d;
3333
34− d = nft_data_cmp(&data[priv->sreg], &priv->data, priv->len);
34+ d = memcmp(&regs->data[priv->sreg], &priv->data, priv->len);
3535 switch (priv->op) {
3636 case NFT_CMP_EQ:
3737 if (d != 0)
@@ -59,7 +59,7 @@ static void nft_cmp_eval(const struct nft_expr *expr, · 21 unmodified lines
5959 return;
6060
6161 mismatch:
62− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
62+ regs->verdict.code = NFT_BREAK;
6363 }
6464
6565 static 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, · 9 unmodified lines
7575 struct nft_data_desc desc;
7676 int err;
7777
78− priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
79− priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
80−
81− err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
78+ err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc,
79+ tb[NFTA_CMP_DATA]);
8280 BUG_ON(err < 0);
8381
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]));
8488 priv->len = desc.len;
8589 return 0;
8690 }
@@ -89,7 +93,7 @@ static int nft_cmp_dump(struct sk_buff *skb, const struct nft_expr *expr) · 2 unmodified lines
8993 {
9094 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
9195
92− if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg)))
96+ if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
9397 goto nla_put_failure;
9498 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op)))
9599 goto nla_put_failure;
@@ -122,13 +126,18 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, · 26 unmodified lines
122126 u32 mask;
123127 int err;
124128
125− priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
126−
127− err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
129+ err = nft_data_init(NULL, &data, sizeof(data), &desc,
130+ tb[NFTA_CMP_DATA]);
128131 BUG_ON(err < 0);
129− desc.len *= BITS_PER_BYTE;
130132
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;
131139 mask = nft_cmp_fast_mask(desc.len);
140+
132141 priv->data = data.data[0] & mask;
133142 priv->len = desc.len;
134143 return 0;
@@ -139,7 +148,7 @@ static int nft_cmp_fast_dump(struct sk_buff *skb, const struct nft_expr *expr) · 4 unmodified lines
139148 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
140149 struct nft_data data;
141150
142− if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg)))
151+ if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
143152 goto nla_put_failure;
144153 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ)))
145154 goto nla_put_failure;
@@ -167,7 +176,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) · 21 unmodified lines
167176 {
168177 struct nft_data_desc desc;
169178 struct nft_data data;
170− enum nft_registers sreg;
171179 enum nft_cmp_ops op;
172180 int err;
173181
@@ -176,11 +184,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) · 2 unmodified lines
176184 tb[NFTA_CMP_DATA] == NULL)
177185 return ERR_PTR(-EINVAL);
178186
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−
184187 op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
185188 switch (op) {
186189 case NFT_CMP_EQ:
@@ -194,7 +197,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) · 7 unmodified lines
194197 return ERR_PTR(-EINVAL);
195198 }
196199
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]);
198202 if (err < 0)
199203 return ERR_PTR(err);
200204
net/netfilter/nft_compat.c+13−13
@@ -55,7 +55,7 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info) · 54 unmodified lines
5555 }
5656
5757 static void nft_target_eval_xt(const struct nft_expr *expr,
58− struct nft_data data[NFT_REG_MAX + 1],
58+ struct nft_regs *regs,
5959 const struct nft_pktinfo *pkt)
6060 {
6161 void *info = nft_expr_priv(expr);
@@ -72,16 +72,16 @@ static void nft_target_eval_xt(const struct nft_expr *expr, · 10 unmodified lines
7272
7373 switch (ret) {
7474 case XT_CONTINUE:
75− data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
75+ regs->verdict.code = NFT_CONTINUE;
7676 break;
7777 default:
78− data[NFT_REG_VERDICT].verdict = ret;
78+ regs->verdict.code = ret;
7979 break;
8080 }
8181 }
8282
8383 static void nft_target_eval_bridge(const struct nft_expr *expr,
84− struct nft_data data[NFT_REG_MAX + 1],
84+ struct nft_regs *regs,
8585 const struct nft_pktinfo *pkt)
8686 {
8787 void *info = nft_expr_priv(expr);
@@ -98,19 +98,19 @@ static void nft_target_eval_bridge(const struct nft_expr *expr, · 10 unmodified lines
9898
9999 switch (ret) {
100100 case EBT_ACCEPT:
101− data[NFT_REG_VERDICT].verdict = NF_ACCEPT;
101+ regs->verdict.code = NF_ACCEPT;
102102 break;
103103 case EBT_DROP:
104− data[NFT_REG_VERDICT].verdict = NF_DROP;
104+ regs->verdict.code = NF_DROP;
105105 break;
106106 case EBT_CONTINUE:
107− data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
107+ regs->verdict.code = NFT_CONTINUE;
108108 break;
109109 case EBT_RETURN:
110− data[NFT_REG_VERDICT].verdict = NFT_RETURN;
110+ regs->verdict.code = NFT_RETURN;
111111 break;
112112 default:
113− data[NFT_REG_VERDICT].verdict = ret;
113+ regs->verdict.code = ret;
114114 break;
115115 }
116116 }
@@ -304,7 +304,7 @@ static int nft_target_validate(const struct nft_ctx *ctx, · 187 unmodified lines
304304 }
305305
306306 static void nft_match_eval(const struct nft_expr *expr,
307− struct nft_data data[NFT_REG_MAX + 1],
307+ struct nft_regs *regs,
308308 const struct nft_pktinfo *pkt)
309309 {
310310 void *info = nft_expr_priv(expr);
@@ -317,16 +317,16 @@ static void nft_match_eval(const struct nft_expr *expr, · 6 unmodified lines
317317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
318318
319319 if (pkt->xt.hotdrop) {
320− data[NFT_REG_VERDICT].verdict = NF_DROP;
320+ regs->verdict.code = NF_DROP;
321321 return;
322322 }
323323
324324 switch (ret ? 1 : 0) {
325325 case 1:
326− data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
326+ regs->verdict.code = NFT_CONTINUE;
327327 break;
328328 case 0:
329− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
329+ regs->verdict.code = NFT_BREAK;
330330 break;
331331 }
332332 }
net/netfilter/nft_counter.c+2−1
@@ -24,7 +24,7 @@ struct nft_counter { · 23 unmodified lines
2424 };
2525
2626 static void nft_counter_eval(const struct nft_expr *expr,
27− struct nft_data data[NFT_REG_MAX + 1],
27+ struct nft_regs *regs,
2828 const struct nft_pktinfo *pkt)
2929 {
3030 struct nft_counter *priv = nft_expr_priv(expr);
@@ -92,6 +92,7 @@ static struct nft_expr_type nft_counter_type __read_mostly = { · 61 unmodified lines
9292 .ops = &nft_counter_ops,
9393 .policy = nft_counter_policy,
9494 .maxattr = NFTA_COUNTER_MAX,
95+ .flags = NFT_EXPR_STATEFUL,
9596 .owner = THIS_MODULE,
9697 };
9798
net/netfilter/nft_ct.c+71−39
@@ -31,11 +31,11 @@ struct nft_ct { · 30 unmodified lines
3131 };
3232
3333 static void nft_ct_get_eval(const struct nft_expr *expr,
34− struct nft_data data[NFT_REG_MAX + 1],
34+ struct nft_regs *regs,
3535 const struct nft_pktinfo *pkt)
3636 {
3737 const struct nft_ct *priv = nft_expr_priv(expr);
38− struct nft_data *dest = &data[priv->dreg];
38+ u32 *dest = &regs->data[priv->dreg];
3939 enum ip_conntrack_info ctinfo;
4040 const struct nf_conn *ct;
4141 const struct nf_conn_help *help;
@@ -54,7 +54,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 12 unmodified lines
5454 state = NF_CT_STATE_UNTRACKED_BIT;
5555 else
5656 state = NF_CT_STATE_BIT(ctinfo);
57− dest->data[0] = state;
57+ *dest = state;
5858 return;
5959 default:
6060 break;
@@ -65,26 +65,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 4 unmodified lines
6565
6666 switch (priv->key) {
6767 case NFT_CT_DIRECTION:
68− dest->data[0] = CTINFO2DIR(ctinfo);
68+ *dest = CTINFO2DIR(ctinfo);
6969 return;
7070 case NFT_CT_STATUS:
71− dest->data[0] = ct->status;
71+ *dest = ct->status;
7272 return;
7373 #ifdef CONFIG_NF_CONNTRACK_MARK
7474 case NFT_CT_MARK:
75− dest->data[0] = ct->mark;
75+ *dest = ct->mark;
7676 return;
7777 #endif
7878 #ifdef CONFIG_NF_CONNTRACK_SECMARK
7979 case NFT_CT_SECMARK:
80− dest->data[0] = ct->secmark;
80+ *dest = ct->secmark;
8181 return;
8282 #endif
8383 case NFT_CT_EXPIRATION:
8484 diff = (long)jiffies - (long)ct->timeout.expires;
8585 if (diff < 0)
8686 diff = 0;
87− dest->data[0] = jiffies_to_msecs(diff);
87+ *dest = jiffies_to_msecs(diff);
8888 return;
8989 case NFT_CT_HELPER:
9090 if (ct->master == NULL)
@@ -95,9 +95,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 4 unmodified lines
9595 helper = rcu_dereference(help->helper);
9696 if (helper == NULL)
9797 goto err;
98− if (strlen(helper->name) >= sizeof(dest->data))
99− goto err;
100− strncpy((char *)dest->data, helper->name, sizeof(dest->data));
98+ strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
10199 return;
102100 #ifdef CONFIG_NF_CONNTRACK_LABELS
103101 case NFT_CT_LABELS: {
@@ -105,17 +103,15 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 1 unmodified line
105103 unsigned int size;
106104
107105 if (!labels) {
108− memset(dest->data, 0, sizeof(dest->data));
106+ memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
109107 return;
110108 }
111109
112− BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data));
113110 size = labels->words * sizeof(long);
114−
115− memcpy(dest->data, labels->bits, size);
116− if (size < sizeof(dest->data))
117− memset(((char *) dest->data) + size, 0,
118− sizeof(dest->data) - size);
111+ memcpy(dest, labels->bits, size);
112+ if (size < NF_CT_LABELS_MAX_SIZE)
113+ memset(((char *) dest) + size, 0,
114+ NF_CT_LABELS_MAX_SIZE - size);
119115 return;
120116 }
121117 #endif
@@ -126,41 +122,41 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 4 unmodified lines
126122 tuple = &ct->tuplehash[priv->dir].tuple;
127123 switch (priv->key) {
128124 case NFT_CT_L3PROTOCOL:
129− dest->data[0] = nf_ct_l3num(ct);
125+ *dest = nf_ct_l3num(ct);
130126 return;
131127 case NFT_CT_SRC:
132− memcpy(dest->data, tuple->src.u3.all,
128+ memcpy(dest, tuple->src.u3.all,
133129 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
134130 return;
135131 case NFT_CT_DST:
136− memcpy(dest->data, tuple->dst.u3.all,
132+ memcpy(dest, tuple->dst.u3.all,
137133 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
138134 return;
139135 case NFT_CT_PROTOCOL:
140− dest->data[0] = nf_ct_protonum(ct);
136+ *dest = nf_ct_protonum(ct);
141137 return;
142138 case NFT_CT_PROTO_SRC:
143− dest->data[0] = (__force __u16)tuple->src.u.all;
139+ *dest = (__force __u16)tuple->src.u.all;
144140 return;
145141 case NFT_CT_PROTO_DST:
146− dest->data[0] = (__force __u16)tuple->dst.u.all;
142+ *dest = (__force __u16)tuple->dst.u.all;
147143 return;
148144 default:
149145 break;
150146 }
151147 return;
152148 err:
153− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
149+ regs->verdict.code = NFT_BREAK;
154150 }
155151
156152 static void nft_ct_set_eval(const struct nft_expr *expr,
157− struct nft_data data[NFT_REG_MAX + 1],
153+ struct nft_regs *regs,
158154 const struct nft_pktinfo *pkt)
159155 {
160156 const struct nft_ct *priv = nft_expr_priv(expr);
161157 struct sk_buff *skb = pkt->skb;
162158 #ifdef CONFIG_NF_CONNTRACK_MARK
163− u32 value = data[priv->sreg].data[0];
159+ u32 value = regs->data[priv->sreg];
164160 #endif
165161 enum ip_conntrack_info ctinfo;
166162 struct nf_conn *ct;
@@ -228,12 +224,17 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, · 61 unmodified lines
228224 const struct nlattr * const tb[])
229225 {
230226 struct nft_ct *priv = nft_expr_priv(expr);
227+ unsigned int len;
231228 int err;
232229
233230 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
234231 switch (priv->key) {
235− case NFT_CT_STATE:
236232 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:
237238 case NFT_CT_STATUS:
238239 #ifdef CONFIG_NF_CONNTRACK_MARK
239240 case NFT_CT_MARK:
@@ -241,22 +242,54 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, · 1 unmodified line
241242 #ifdef CONFIG_NF_CONNTRACK_SECMARK
242243 case NFT_CT_SECMARK:
243244 #endif
245+ case NFT_CT_EXPIRATION:
246+ if (tb[NFTA_CT_DIRECTION] != NULL)
247+ return -EINVAL;
248+ len = sizeof(u32);
249+ break;
244250 #ifdef CONFIG_NF_CONNTRACK_LABELS
245251 case NFT_CT_LABELS:
252+ if (tb[NFTA_CT_DIRECTION] != NULL)
253+ return -EINVAL;
254+ len = NF_CT_LABELS_MAX_SIZE;
255+ break;
246256 #endif
247− case NFT_CT_EXPIRATION:
248257 case NFT_CT_HELPER:
249258 if (tb[NFTA_CT_DIRECTION] != NULL)
250259 return -EINVAL;
260+ len = NF_CT_HELPER_NAME_LEN;
251261 break;
262+
252263 case NFT_CT_L3PROTOCOL:
253264 case NFT_CT_PROTOCOL:
265+ if (tb[NFTA_CT_DIRECTION] == NULL)
266+ return -EINVAL;
267+ len = sizeof(u8);
268+ break;
254269 case NFT_CT_SRC:
255270 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;
256288 case NFT_CT_PROTO_SRC:
257289 case NFT_CT_PROTO_DST:
258290 if (tb[NFTA_CT_DIRECTION] == NULL)
259291 return -EINVAL;
292+ len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
260293 break;
261294 default:
262295 return -EOPNOTSUPP;
@@ -273,12 +306,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, · 10 unmodified lines
273306 }
274307 }
275308
276− priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
277− err = nft_validate_output_register(priv->dreg);
278− if (err < 0)
279− return err;
280−
281− err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
309+ priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
310+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
311+ NFT_DATA_VALUE, len);
282312 if (err < 0)
283313 return err;
284314
@@ -294,20 +324,22 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, · 9 unmodified lines
294324 const struct nlattr * const tb[])
295325 {
296326 struct nft_ct *priv = nft_expr_priv(expr);
327+ unsigned int len;
297328 int err;
298329
299330 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
300331 switch (priv->key) {
301332 #ifdef CONFIG_NF_CONNTRACK_MARK
302333 case NFT_CT_MARK:
334+ len = FIELD_SIZEOF(struct nf_conn, mark);
303335 break;
304336 #endif
305337 default:
306338 return -EOPNOTSUPP;
307339 }
308340
309− priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
310− err = nft_validate_input_register(priv->sreg);
341+ priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
342+ err = nft_validate_register_load(priv->sreg, len);
311343 if (err < 0)
312344 return err;
313345
@@ -328,7 +360,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr) · 14 unmodified lines
328360 {
329361 const struct nft_ct *priv = nft_expr_priv(expr);
330362
331− if (nla_put_be32(skb, NFTA_CT_DREG, htonl(priv->dreg)))
363+ if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
332364 goto nla_put_failure;
333365 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
334366 goto nla_put_failure;
@@ -355,7 +387,7 @@ static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr) · 20 unmodified lines
355387 {
356388 const struct nft_ct *priv = nft_expr_priv(expr);
357389
358− if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg)))
390+ if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
359391 goto nla_put_failure;
360392 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
361393 goto nla_put_failure;
net/netfilter/nft_dynset.c+63−16
@@ -23,13 +23,15 @@ struct nft_dynset { · 22 unmodified lines
2323 enum nft_registers sreg_key:8;
2424 enum nft_registers sreg_data:8;
2525 u64 timeout;
26+ struct nft_expr *expr;
2627 struct nft_set_binding binding;
2728 };
2829
2930 static 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)
3132 {
3233 const struct nft_dynset *priv = nft_expr_priv(expr);
34+ struct nft_set_ext *ext;
3335 u64 timeout;
3436 void *elem;
3537
@@ -38,35 +40,51 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr, · 2 unmodified lines
3840
3941 timeout = priv->timeout ? : set->timeout;
4042 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],
4245 timeout, GFP_ATOMIC);
4346 if (elem == NULL) {
4447 if (set->size)
4548 atomic_dec(&set->nelems);
49+ return NULL;
4650 }
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+
4756 return elem;
4857 }
4958
5059 static void nft_dynset_eval(const struct nft_expr *expr,
51− struct nft_data data[NFT_REG_MAX + 1],
60+ struct nft_regs *regs,
5261 const struct nft_pktinfo *pkt)
5362 {
5463 const struct nft_dynset *priv = nft_expr_priv(expr);
5564 struct nft_set *set = priv->set;
5665 const struct nft_set_ext *ext;
66+ const struct nft_expr *sexpr;
5767 u64 timeout;
5868
59− if (set->ops->update(set, &data[priv->sreg_key], nft_dynset_new,
60− expr, data, &ext)) {
69+ if (set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
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+
6175 if (priv->op == NFT_DYNSET_OP_UPDATE &&
6276 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
6377 timeout = priv->timeout ? : set->timeout;
6478 *nft_set_ext_expiration(ext) = jiffies + timeout;
65− return;
66− }
67− }
79+ } else if (sexpr == NULL)
80+ goto out;
6881
69− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
82+ if (sexpr != NULL)
83+ sexpr->ops->eval(sexpr, regs, pkt);
84+ return;
85+ }
86+out:
87+ regs->verdict.code = NFT_BREAK;
7088 }
7189
7290 static 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] = { · 3 unmodified lines
7694 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
7795 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
7896 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
97+ [NFTA_DYNSET_EXPR] = { .type = NLA_NESTED },
7998 };
8099
81100 static int nft_dynset_init(const struct nft_ctx *ctx,
@@ -123,8 +142,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, · 41 unmodified lines
123142 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
124143 }
125144
126− priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY]));
127− err = nft_validate_input_register(priv->sreg_key);
145+ priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
146+ err = nft_validate_register_load(priv->sreg_key, set->klen);;
128147 if (err < 0)
129148 return err;
130149
@@ -134,17 +153,36 @@ static int nft_dynset_init(const struct nft_ctx *ctx, · 3 unmodified lines
134153 if (set->dtype == NFT_DATA_VERDICT)
135154 return -EOPNOTSUPP;
136155
137− priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA]));
138− err = nft_validate_input_register(priv->sreg_data);
156+ priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
157+ err = nft_validate_register_load(priv->sreg_data, set->dlen);
139158 if (err < 0)
140159 return err;
141160 } else if (set->flags & NFT_SET_MAP)
142161 return -EINVAL;
143162
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+
144179 nft_set_ext_prepare(&priv->tmpl);
145180 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
146181 if (set->flags & NFT_SET_MAP)
147182 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);
148186 if (set->flags & NFT_SET_TIMEOUT) {
149187 if (timeout || set->timeout)
150188 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
@@ -154,10 +192,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx, · 3 unmodified lines
154192
155193 err = nf_tables_bind_set(ctx, set, &priv->binding);
156194 if (err < 0)
157− return err;
195+ goto err1;
158196
159197 priv->set = set;
160198 return 0;
199+
200+err1:
201+ if (priv->expr != NULL)
202+ nft_expr_destroy(ctx, priv->expr);
203+ return err;
161204 }
162205
163206 static void nft_dynset_destroy(const struct nft_ctx *ctx,
@@ -166,16 +209,18 @@ static void nft_dynset_destroy(const struct nft_ctx *ctx, · 2 unmodified lines
166209 struct nft_dynset *priv = nft_expr_priv(expr);
167210
168211 nf_tables_unbind_set(ctx, priv->set, &priv->binding);
212+ if (priv->expr != NULL)
213+ nft_expr_destroy(ctx, priv->expr);
169214 }
170215
171216 static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
172217 {
173218 const struct nft_dynset *priv = nft_expr_priv(expr);
174219
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))
176221 goto nla_put_failure;
177222 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))
179224 goto nla_put_failure;
180225 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op)))
181226 goto nla_put_failure;
@@ -183,6 +228,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr) · 1 unmodified line
183228 goto nla_put_failure;
184229 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout)))
185230 goto nla_put_failure;
231+ if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
232+ goto nla_put_failure;
186233 return 0;
187234
188235 nla_put_failure:
net/netfilter/nft_expr_template.c+0−94
@@ -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−
18−struct nft_template {
19−
20−};
21−
22−static 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−
30−static const struct nla_policy nft_template_policy[NFTA_TEMPLATE_MAX + 1] = {
31− [NFTA_TEMPLATE_ATTR] = { .type = NLA_U32 },
32−};
33−
34−static 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−
43−static 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−
50−static 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−
57−nla_put_failure:
58− return -1;
59−}
60−
61−static struct nft_expr_type nft_template_type;
62−static 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−
71−static 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−
79−static int __init nft_template_module_init(void)
80−{
81− return nft_register_expr(&nft_template_type);
82−}
83−
84−static void __exit nft_template_module_exit(void)
85−{
86− nft_unregister_expr(&nft_template_type);
87−}
88−
89−module_init(nft_template_module_init);
90−module_exit(nft_template_module_exit);
91−
92−MODULE_LICENSE("GPL");
93−MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
94−MODULE_ALIAS_NFT_EXPR("template");
net/netfilter/nft_exthdr.c+9−14
@@ -26,11 +26,11 @@ struct nft_exthdr { · 25 unmodified lines
2626 };
2727
2828 static void nft_exthdr_eval(const struct nft_expr *expr,
29− struct nft_data data[NFT_REG_MAX + 1],
29+ struct nft_regs *regs,
3030 const struct nft_pktinfo *pkt)
3131 {
3232 struct nft_exthdr *priv = nft_expr_priv(expr);
33− struct nft_data *dest = &data[priv->dreg];
33+ u32 *dest = &regs->data[priv->dreg];
3434 unsigned int offset = 0;
3535 int err;
3636
@@ -39,11 +39,12 @@ static void nft_exthdr_eval(const struct nft_expr *expr, · 2 unmodified lines
3939 goto err;
4040 offset += priv->offset;
4141
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)
4344 goto err;
4445 return;
4546 err:
46− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
47+ regs->verdict.code = NFT_BREAK;
4748 }
4849
4950 static 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, · 8 unmodified lines
5859 const struct nlattr * const tb[])
5960 {
6061 struct nft_exthdr *priv = nft_expr_priv(expr);
61− int err;
6262
6363 if (tb[NFTA_EXTHDR_DREG] == NULL ||
6464 tb[NFTA_EXTHDR_TYPE] == NULL ||
@@ -69,22 +69,17 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, · 4 unmodified lines
6969 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
7070 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
7171 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
72− if (priv->len == 0 ||
73− priv->len > FIELD_SIZEOF(struct nft_data, data))
74− return -EINVAL;
72+ priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
7573
76− priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG]));
77− err = nft_validate_output_register(priv->dreg);
78− if (err < 0)
79− return err;
80− return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
74+ return nft_validate_register_store(ctx, priv->dreg, NULL,
75+ NFT_DATA_VALUE, priv->len);
8176 }
8277
8378 static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
8479 {
8580 const struct nft_exthdr *priv = nft_expr_priv(expr);
8681
87− if (nla_put_be32(skb, NFTA_EXTHDR_DREG, htonl(priv->dreg)))
82+ if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg))
8883 goto nla_put_failure;
8984 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type))
9085 goto nla_put_failure;
net/netfilter/nft_hash.c+9−10
@@ -36,7 +36,7 @@ struct nft_hash_elem { · 35 unmodified lines
3636
3737 struct nft_hash_cmp_arg {
3838 const struct nft_set *set;
39− const struct nft_data *key;
39+ const u32 *key;
4040 u8 genmask;
4141 };
4242
@@ -62,7 +62,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg, · 19 unmodified lines
6262 const struct nft_hash_cmp_arg *x = arg->key;
6363 const struct nft_hash_elem *he = ptr;
6464
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))
6666 return 1;
6767 if (nft_set_elem_expired(&he->ext))
6868 return 1;
@@ -71,8 +71,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg, · 2 unmodified lines
7171 return 0;
7272 }
7373
74−static bool nft_hash_lookup(const struct nft_set *set,
75− const struct nft_data *key,
74+static bool nft_hash_lookup(const struct nft_set *set, const u32 *key,
7675 const struct nft_set_ext **ext)
7776 {
7877 struct nft_hash *priv = nft_set_priv(set);
@@ -90,12 +89,12 @@ static bool nft_hash_lookup(const struct nft_set *set, · 11 unmodified lines
9089 return !!he;
9190 }
9291
93−static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
92+static bool nft_hash_update(struct nft_set *set, const u32 *key,
9493 void *(*new)(struct nft_set *,
9594 const struct nft_expr *,
96− struct nft_data []),
95+ struct nft_regs *regs),
9796 const struct nft_expr *expr,
98− struct nft_data data[],
97+ struct nft_regs *regs,
9998 const struct nft_set_ext **ext)
10099 {
101100 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, · 8 unmodified lines
110109 if (he != NULL)
111110 goto out;
112111
113− he = new(set, expr, data);
112+ he = new(set, expr, regs);
114113 if (he == NULL)
115114 goto err1;
116115 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -134,7 +133,7 @@ static int nft_hash_insert(const struct nft_set *set, · 17 unmodified lines
134133 struct nft_hash_cmp_arg arg = {
135134 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
136135 .set = set,
137− .key = &elem->key,
136+ .key = elem->key.val.data,
138137 };
139138
140139 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -158,7 +157,7 @@ static void *nft_hash_deactivate(const struct nft_set *set, · 17 unmodified lines
158157 struct nft_hash_cmp_arg arg = {
159158 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
160159 .set = set,
161− .key = &elem->key,
160+ .key = elem->key.val.data,
162161 };
163162
164163 rcu_read_lock();
net/netfilter/nft_immediate.c+8−10
@@ -24,12 +24,12 @@ struct nft_immediate_expr { · 23 unmodified lines
2424 };
2525
2626 static void nft_immediate_eval(const struct nft_expr *expr,
27− struct nft_data data[NFT_REG_MAX + 1],
27+ struct nft_regs *regs,
2828 const struct nft_pktinfo *pkt)
2929 {
3030 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
3131
32− nft_data_copy(&data[priv->dreg], &priv->data);
32+ nft_data_copy(&regs->data[priv->dreg], &priv->data, priv->dlen);
3333 }
3434
3535 static 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, · 13 unmodified lines
4949 tb[NFTA_IMMEDIATE_DATA] == NULL)
5050 return -EINVAL;
5151
52− priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG]));
53− err = nft_validate_output_register(priv->dreg);
54− if (err < 0)
55− return err;
56−
57− err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]);
52+ err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc,
53+ tb[NFTA_IMMEDIATE_DATA]);
5854 if (err < 0)
5955 return err;
6056 priv->dlen = desc.len;
6157
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);
6361 if (err < 0)
6462 goto err1;
6563
@@ -81,7 +79,7 @@ static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr) · 15 unmodified lines
8179 {
8280 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
8381
84− if (nla_put_be32(skb, NFTA_IMMEDIATE_DREG, htonl(priv->dreg)))
82+ if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg))
8583 goto nla_put_failure;
8684
8785 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
net/netfilter/nft_limit.c+3−2
@@ -27,7 +27,7 @@ struct nft_limit { · 26 unmodified lines
2727 };
2828
2929 static void nft_limit_eval(const struct nft_expr *expr,
30− struct nft_data data[NFT_REG_MAX + 1],
30+ struct nft_regs *regs,
3131 const struct nft_pktinfo *pkt)
3232 {
3333 struct nft_limit *priv = nft_expr_priv(expr);
@@ -45,7 +45,7 @@ static void nft_limit_eval(const struct nft_expr *expr, · 11 unmodified lines
4545 }
4646 spin_unlock_bh(&limit_lock);
4747
48− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
48+ regs->verdict.code = NFT_BREAK;
4949 }
5050
5151 static 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 = { · 46 unmodified lines
9898 .ops = &nft_limit_ops,
9999 .policy = nft_limit_policy,
100100 .maxattr = NFTA_LIMIT_MAX,
101+ .flags = NFT_EXPR_STATEFUL,
101102 .owner = THIS_MODULE,
102103 };
103104
net/netfilter/nft_log.c+1−1
@@ -27,7 +27,7 @@ struct nft_log { · 26 unmodified lines
2727 };
2828
2929 static void nft_log_eval(const struct nft_expr *expr,
30− struct nft_data data[NFT_REG_MAX + 1],
30+ struct nft_regs *regs,
3131 const struct nft_pktinfo *pkt)
3232 {
3333 const struct nft_log *priv = nft_expr_priv(expr);
net/netfilter/nft_lookup.c+15−16
@@ -26,19 +26,20 @@ struct nft_lookup { · 25 unmodified lines
2626 };
2727
2828 static void nft_lookup_eval(const struct nft_expr *expr,
29− struct nft_data data[NFT_REG_MAX + 1],
29+ struct nft_regs *regs,
3030 const struct nft_pktinfo *pkt)
3131 {
3232 const struct nft_lookup *priv = nft_expr_priv(expr);
3333 const struct nft_set *set = priv->set;
3434 const struct nft_set_ext *ext;
3535
36− if (set->ops->lookup(set, &data[priv->sreg], &ext)) {
36+ if (set->ops->lookup(set, &regs->data[priv->sreg], &ext)) {
3737 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);
3940 return;
4041 }
41− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
42+ regs->verdict.code = NFT_BREAK;
4243 }
4344
4445 static 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, · 25 unmodified lines
7071 return PTR_ERR(set);
7172 }
7273
73− priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG]));
74− err = nft_validate_input_register(priv->sreg);
74+ if (set->flags & NFT_SET_EVAL)
75+ return -EOPNOTSUPP;
76+
77+ priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
78+ err = nft_validate_register_load(priv->sreg, set->klen);
7579 if (err < 0)
7680 return err;
7781
@@ -79,16 +83,11 @@ static int nft_lookup_init(const struct nft_ctx *ctx, · 1 unmodified line
7983 if (!(set->flags & NFT_SET_MAP))
8084 return -EINVAL;
8185
82− priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG]));
83− err = nft_validate_output_register(priv->dreg);
86+ priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
87+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
88+ set->dtype, set->dlen);
8489 if (err < 0)
8590 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;
9291 } else if (set->flags & NFT_SET_MAP)
9392 return -EINVAL;
9493
@@ -116,10 +115,10 @@ static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr) · 21 unmodified lines
116115
117116 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name))
118117 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))
120119 goto nla_put_failure;
121120 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))
123122 goto nla_put_failure;
124123 return 0;
125124
net/netfilter/nft_meta.c+55−52
@@ -25,62 +25,65 @@ · 24 unmodified lines
2525 #include <net/netfilter/nft_meta.h>
2626
2727 void nft_meta_get_eval(const struct nft_expr *expr,
28− struct nft_data data[NFT_REG_MAX + 1],
28+ struct nft_regs *regs,
2929 const struct nft_pktinfo *pkt)
3030 {
3131 const struct nft_meta *priv = nft_expr_priv(expr);
3232 const struct sk_buff *skb = pkt->skb;
3333 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];
3535
3636 switch (priv->key) {
3737 case NFT_META_LEN:
38− dest->data[0] = skb->len;
38+ *dest = skb->len;
3939 break;
4040 case NFT_META_PROTOCOL:
41− *(__be16 *)dest->data = skb->protocol;
41+ *dest = 0;
42+ *(__be16 *)dest = skb->protocol;
4243 break;
4344 case NFT_META_NFPROTO:
44− dest->data[0] = pkt->ops->pf;
45+ *dest = pkt->ops->pf;
4546 break;
4647 case NFT_META_L4PROTO:
47− dest->data[0] = pkt->tprot;
48+ *dest = pkt->tprot;
4849 break;
4950 case NFT_META_PRIORITY:
50− dest->data[0] = skb->priority;
51+ *dest = skb->priority;
5152 break;
5253 case NFT_META_MARK:
53− dest->data[0] = skb->mark;
54+ *dest = skb->mark;
5455 break;
5556 case NFT_META_IIF:
5657 if (in == NULL)
5758 goto err;
58− dest->data[0] = in->ifindex;
59+ *dest = in->ifindex;
5960 break;
6061 case NFT_META_OIF:
6162 if (out == NULL)
6263 goto err;
63− dest->data[0] = out->ifindex;
64+ *dest = out->ifindex;
6465 break;
6566 case NFT_META_IIFNAME:
6667 if (in == NULL)
6768 goto err;
68− strncpy((char *)dest->data, in->name, sizeof(dest->data));
69+ strncpy((char *)dest, in->name, IFNAMSIZ);
6970 break;
7071 case NFT_META_OIFNAME:
7172 if (out == NULL)
7273 goto err;
73− strncpy((char *)dest->data, out->name, sizeof(dest->data));
74+ strncpy((char *)dest, out->name, IFNAMSIZ);
7475 break;
7576 case NFT_META_IIFTYPE:
7677 if (in == NULL)
7778 goto err;
78− *(u16 *)dest->data = in->type;
79+ *dest = 0;
80+ *(u16 *)dest = in->type;
7981 break;
8082 case NFT_META_OIFTYPE:
8183 if (out == NULL)
8284 goto err;
83− *(u16 *)dest->data = out->type;
85+ *dest = 0;
86+ *(u16 *)dest = out->type;
8487 break;
8588 case NFT_META_SKUID:
8689 if (skb->sk == NULL || !sk_fullsock(skb->sk))
@@ -93,8 +96,7 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 6 unmodified lines
9396 goto err;
9497 }
9598
96− dest->data[0] =
97− from_kuid_munged(&init_user_ns,
99+ *dest = from_kuid_munged(&init_user_ns,
98100 skb->sk->sk_socket->file->f_cred->fsuid);
99101 read_unlock_bh(&skb->sk->sk_callback_lock);
100102 break;
@@ -108,8 +110,7 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 7 unmodified lines
108110 read_unlock_bh(&skb->sk->sk_callback_lock);
109111 goto err;
110112 }
111− dest->data[0] =
112− from_kgid_munged(&init_user_ns,
113+ *dest = from_kgid_munged(&init_user_ns,
113114 skb->sk->sk_socket->file->f_cred->fsgid);
114115 read_unlock_bh(&skb->sk->sk_callback_lock);
115116 break;
@@ -119,33 +120,33 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 3 unmodified lines
119120
120121 if (dst == NULL)
121122 goto err;
122− dest->data[0] = dst->tclassid;
123+ *dest = dst->tclassid;
123124 break;
124125 }
125126 #endif
126127 #ifdef CONFIG_NETWORK_SECMARK
127128 case NFT_META_SECMARK:
128− dest->data[0] = skb->secmark;
129+ *dest = skb->secmark;
129130 break;
130131 #endif
131132 case NFT_META_PKTTYPE:
132133 if (skb->pkt_type != PACKET_LOOPBACK) {
133− dest->data[0] = skb->pkt_type;
134+ *dest = skb->pkt_type;
134135 break;
135136 }
136137
137138 switch (pkt->ops->pf) {
138139 case NFPROTO_IPV4:
139140 if (ipv4_is_multicast(ip_hdr(skb)->daddr))
140− dest->data[0] = PACKET_MULTICAST;
141+ *dest = PACKET_MULTICAST;
141142 else
142− dest->data[0] = PACKET_BROADCAST;
143+ *dest = PACKET_BROADCAST;
143144 break;
144145 case NFPROTO_IPV6:
145146 if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
146− dest->data[0] = PACKET_MULTICAST;
147+ *dest = PACKET_MULTICAST;
147148 else
148− dest->data[0] = PACKET_BROADCAST;
149+ *dest = PACKET_BROADCAST;
149150 break;
150151 default:
151152 WARN_ON(1);
@@ -153,22 +154,22 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 1 unmodified line
153154 }
154155 break;
155156 case NFT_META_CPU:
156− dest->data[0] = raw_smp_processor_id();
157+ *dest = raw_smp_processor_id();
157158 break;
158159 case NFT_META_IIFGROUP:
159160 if (in == NULL)
160161 goto err;
161− dest->data[0] = in->group;
162+ *dest = in->group;
162163 break;
163164 case NFT_META_OIFGROUP:
164165 if (out == NULL)
165166 goto err;
166− dest->data[0] = out->group;
167+ *dest = out->group;
167168 break;
168169 case NFT_META_CGROUP:
169170 if (skb->sk == NULL || !sk_fullsock(skb->sk))
170171 goto err;
171− dest->data[0] = skb->sk->sk_classid;
172+ *dest = skb->sk->sk_classid;
172173 break;
173174 default:
174175 WARN_ON(1);
@@ -177,17 +178,17 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 2 unmodified lines
177178 return;
178179
179180 err:
180− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
181+ regs->verdict.code = NFT_BREAK;
181182 }
182183 EXPORT_SYMBOL_GPL(nft_meta_get_eval);
183184
184185 void nft_meta_set_eval(const struct nft_expr *expr,
185− struct nft_data data[NFT_REG_MAX + 1],
186+ struct nft_regs *regs,
186187 const struct nft_pktinfo *pkt)
187188 {
188189 const struct nft_meta *meta = nft_expr_priv(expr);
189190 struct sk_buff *skb = pkt->skb;
190− u32 value = data[meta->sreg].data[0];
191+ u32 value = regs->data[meta->sreg];
191192
192193 switch (meta->key) {
193194 case NFT_META_MARK:
@@ -217,22 +218,22 @@ int nft_meta_get_init(const struct nft_ctx *ctx, · 23 unmodified lines
217218 const struct nlattr * const tb[])
218219 {
219220 struct nft_meta *priv = nft_expr_priv(expr);
220− int err;
221+ unsigned int len;
221222
222223 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
223224 switch (priv->key) {
224− case NFT_META_LEN:
225225 case NFT_META_PROTOCOL:
226+ case NFT_META_IIFTYPE:
227+ case NFT_META_OIFTYPE:
228+ len = sizeof(u16);
229+ break;
226230 case NFT_META_NFPROTO:
227231 case NFT_META_L4PROTO:
232+ case NFT_META_LEN:
228233 case NFT_META_PRIORITY:
229234 case NFT_META_MARK:
230235 case NFT_META_IIF:
231236 case NFT_META_OIF:
232− case NFT_META_IIFNAME:
233− case NFT_META_OIFNAME:
234− case NFT_META_IIFTYPE:
235− case NFT_META_OIFTYPE:
236237 case NFT_META_SKUID:
237238 case NFT_META_SKGID:
238239 #ifdef CONFIG_IP_ROUTE_CLASSID
@@ -246,21 +247,19 @@ int nft_meta_get_init(const struct nft_ctx *ctx, · 7 unmodified lines
246247 case NFT_META_IIFGROUP:
247248 case NFT_META_OIFGROUP:
248249 case NFT_META_CGROUP:
250+ len = sizeof(u32);
251+ break;
252+ case NFT_META_IIFNAME:
253+ case NFT_META_OIFNAME:
254+ len = IFNAMSIZ;
249255 break;
250256 default:
251257 return -EOPNOTSUPP;
252258 }
253259
254− priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
255− err = nft_validate_output_register(priv->dreg);
256− if (err < 0)
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;
260+ priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
261+ return nft_validate_register_store(ctx, priv->dreg, NULL,
262+ NFT_DATA_VALUE, len);
264263 }
265264 EXPORT_SYMBOL_GPL(nft_meta_get_init);
266265
@@ -269,20 +268,24 @@ int nft_meta_set_init(const struct nft_ctx *ctx, · 2 unmodified lines
269268 const struct nlattr * const tb[])
270269 {
271270 struct nft_meta *priv = nft_expr_priv(expr);
271+ unsigned int len;
272272 int err;
273273
274274 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
275275 switch (priv->key) {
276276 case NFT_META_MARK:
277277 case NFT_META_PRIORITY:
278+ len = sizeof(u32);
279+ break;
278280 case NFT_META_NFTRACE:
281+ len = sizeof(u8);
279282 break;
280283 default:
281284 return -EOPNOTSUPP;
282285 }
283286
284− priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG]));
285− err = nft_validate_input_register(priv->sreg);
287+ priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
288+ err = nft_validate_register_load(priv->sreg, len);
286289 if (err < 0)
287290 return err;
288291
@@ -297,7 +300,7 @@ int nft_meta_get_dump(struct sk_buff *skb, · 8 unmodified lines
297300
298301 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
299302 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))
301304 goto nla_put_failure;
302305 return 0;
303306
@@ -313,7 +316,7 @@ int nft_meta_set_dump(struct sk_buff *skb, · 9 unmodified lines
313316
314317 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
315318 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))
317320 goto nla_put_failure;
318321
319322 return 0;
net/netfilter/nft_nat.c+41−30
@@ -37,7 +37,7 @@ struct nft_nat { · 36 unmodified lines
3737 };
3838
3939 static void nft_nat_eval(const struct nft_expr *expr,
40− struct nft_data data[NFT_REG_MAX + 1],
40+ struct nft_regs *regs,
4141 const struct nft_pktinfo *pkt)
4242 {
4343 const struct nft_nat *priv = nft_expr_priv(expr);
@@ -49,33 +49,32 @@ static void nft_nat_eval(const struct nft_expr *expr, · 5 unmodified lines
4949 if (priv->sreg_addr_min) {
5050 if (priv->family == AF_INET) {
5151 range.min_addr.ip = (__force __be32)
52− data[priv->sreg_addr_min].data[0];
52+ regs->data[priv->sreg_addr_min];
5353 range.max_addr.ip = (__force __be32)
54− data[priv->sreg_addr_max].data[0];
54+ regs->data[priv->sreg_addr_max];
5555
5656 } else {
5757 memcpy(range.min_addr.ip6,
58− data[priv->sreg_addr_min].data,
59− sizeof(struct nft_data));
58+ &regs->data[priv->sreg_addr_min],
59+ sizeof(range.min_addr.ip6));
6060 memcpy(range.max_addr.ip6,
61− data[priv->sreg_addr_max].data,
62− sizeof(struct nft_data));
61+ &regs->data[priv->sreg_addr_max],
62+ sizeof(range.max_addr.ip6));
6363 }
6464 range.flags |= NF_NAT_RANGE_MAP_IPS;
6565 }
6666
6767 if (priv->sreg_proto_min) {
6868 range.min_proto.all =
69− *(__be16 *)&data[priv->sreg_proto_min].data[0];
69+ *(__be16 *)&regs->data[priv->sreg_proto_min];
7070 range.max_proto.all =
71− *(__be16 *)&data[priv->sreg_proto_max].data[0];
71+ *(__be16 *)&regs->data[priv->sreg_proto_max];
7272 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
7373 }
7474
7575 range.flags |= priv->flags;
7676
77− data[NFT_REG_VERDICT].verdict =
78− nf_nat_setup_info(ct, &range, priv->type);
77+ regs->verdict.code = nf_nat_setup_info(ct, &range, priv->type);
7978 }
8079
8180 static 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, · 37 unmodified lines
119118 const struct nlattr * const tb[])
120119 {
121120 struct nft_nat *priv = nft_expr_priv(expr);
121+ unsigned int alen, plen;
122122 u32 family;
123123 int err;
124124
@@ -146,25 +146,34 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 21 unmodified lines
146146 return -EINVAL;
147147
148148 family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
149− if (family != AF_INET && family != AF_INET6)
150− return -EAFNOSUPPORT;
151149 if (family != ctx->afi->family)
152150 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+ }
153162 priv->family = family;
154163
155164 if (tb[NFTA_NAT_REG_ADDR_MIN]) {
156165 priv->sreg_addr_min =
157− ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN]));
158−
159− err = nft_validate_input_register(priv->sreg_addr_min);
166+ nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
167+ err = nft_validate_register_load(priv->sreg_addr_min, alen);
160168 if (err < 0)
161169 return err;
162170
163171 if (tb[NFTA_NAT_REG_ADDR_MAX]) {
164172 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]);
166174
167− err = nft_validate_input_register(priv->sreg_addr_max);
175+ err = nft_validate_register_load(priv->sreg_addr_max,
176+ alen);
168177 if (err < 0)
169178 return err;
170179 } else {
@@ -172,19 +181,21 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 1 unmodified line
172181 }
173182 }
174183
184+ plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
175185 if (tb[NFTA_NAT_REG_PROTO_MIN]) {
176186 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]);
178188
179− err = nft_validate_input_register(priv->sreg_proto_min);
189+ err = nft_validate_register_load(priv->sreg_proto_min, plen);
180190 if (err < 0)
181191 return err;
182192
183193 if (tb[NFTA_NAT_REG_PROTO_MAX]) {
184194 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]);
186196
187− err = nft_validate_input_register(priv->sreg_proto_max);
197+ err = nft_validate_register_load(priv->sreg_proto_max,
198+ plen);
188199 if (err < 0)
189200 return err;
190201 } else {
@@ -220,18 +231,18 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr) · 29 unmodified lines
220231 goto nla_put_failure;
221232
222233 if (priv->sreg_addr_min) {
223− if (nla_put_be32(skb, NFTA_NAT_REG_ADDR_MIN,
224− htonl(priv->sreg_addr_min)) ||
225− nla_put_be32(skb, NFTA_NAT_REG_ADDR_MAX,
226− htonl(priv->sreg_addr_max)))
234+ if (nft_dump_register(skb, NFTA_NAT_REG_ADDR_MIN,
235+ priv->sreg_addr_min) ||
236+ nft_dump_register(skb, NFTA_NAT_REG_ADDR_MAX,
237+ priv->sreg_addr_max))
227238 goto nla_put_failure;
228239 }
229240
230241 if (priv->sreg_proto_min) {
231− if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN,
232− htonl(priv->sreg_proto_min)) ||
233− nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX,
234− htonl(priv->sreg_proto_max)))
242+ if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_MIN,
243+ priv->sreg_proto_min) ||
244+ nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX,
245+ priv->sreg_proto_max))
235246 goto nla_put_failure;
236247 }
237248
net/netfilter/nft_payload.c+10−14
@@ -18,12 +18,12 @@ · 17 unmodified lines
1818 #include <net/netfilter/nf_tables.h>
1919
2020 static void nft_payload_eval(const struct nft_expr *expr,
21− struct nft_data data[NFT_REG_MAX + 1],
21+ struct nft_regs *regs,
2222 const struct nft_pktinfo *pkt)
2323 {
2424 const struct nft_payload *priv = nft_expr_priv(expr);
2525 const struct sk_buff *skb = pkt->skb;
26− struct nft_data *dest = &data[priv->dreg];
26+ u32 *dest = &regs->data[priv->dreg];
2727 int offset;
2828
2929 switch (priv->base) {
@@ -43,11 +43,12 @@ static void nft_payload_eval(const struct nft_expr *expr, · 13 unmodified lines
4343 }
4444 offset += priv->offset;
4545
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)
4748 goto err;
4849 return;
4950 err:
50− data[NFT_REG_VERDICT].verdict = NFT_BREAK;
51+ regs->verdict.code = NFT_BREAK;
5152 }
5253
5354 static 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, · 8 unmodified lines
6263 const struct nlattr * const tb[])
6364 {
6465 struct nft_payload *priv = nft_expr_priv(expr);
65− int err;
6666
6767 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
6868 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
6969 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
70+ priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
7071
71− priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG]));
72− err = nft_validate_output_register(priv->dreg);
73− if (err < 0)
74− return err;
75− return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
72+ return nft_validate_register_store(ctx, priv->dreg, NULL,
73+ NFT_DATA_VALUE, priv->len);
7674 }
7775
7876 static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
7977 {
8078 const struct nft_payload *priv = nft_expr_priv(expr);
8179
82− if (nla_put_be32(skb, NFTA_PAYLOAD_DREG, htonl(priv->dreg)) ||
80+ if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
8381 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
8482 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
8583 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
@@ -131,9 +129,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx, · 45 unmodified lines
131129 }
132130
133131 offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
134− 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);
132+ len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
137133
138134 if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
139135 base != NFT_PAYLOAD_LL_HEADER)
net/netfilter/nft_queue.c+2−2
@@ -28,7 +28,7 @@ struct nft_queue { · 27 unmodified lines
2828 };
2929
3030 static void nft_queue_eval(const struct nft_expr *expr,
31− struct nft_data data[NFT_REG_MAX + 1],
31+ struct nft_regs *regs,
3232 const struct nft_pktinfo *pkt)
3333 {
3434 struct nft_queue *priv = nft_expr_priv(expr);
@@ -51,7 +51,7 @@ static void nft_queue_eval(const struct nft_expr *expr, · 16 unmodified lines
5151 if (priv->flags & NFT_QUEUE_FLAG_BYPASS)
5252 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
5353
54− data[NFT_REG_VERDICT].verdict = ret;
54+ regs->verdict.code = ret;
5555 }
5656
5757 static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
net/netfilter/nft_rbtree.c+7−8
@@ -30,8 +30,7 @@ struct nft_rbtree_elem { · 29 unmodified lines
3030 };
3131
3232
33−static bool nft_rbtree_lookup(const struct nft_set *set,
34− const struct nft_data *key,
33+static bool nft_rbtree_lookup(const struct nft_set *set, const u32 *key,
3534 const struct nft_set_ext **ext)
3635 {
3736 const struct nft_rbtree *priv = nft_set_priv(set);
@@ -45,7 +44,7 @@ static bool nft_rbtree_lookup(const struct nft_set *set, · 7 unmodified lines
4544 while (parent != NULL) {
4645 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
4746
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);
4948 if (d < 0) {
5049 parent = parent->rb_left;
5150 interval = rbe;
@@ -91,9 +90,9 @@ static int __nft_rbtree_insert(const struct nft_set *set, · 39 unmodified lines
9190 while (*p != NULL) {
9291 parent = *p;
9392 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
94− d = nft_data_cmp(nft_set_ext_key(&rbe->ext),
95− nft_set_ext_key(&new->ext),
96− set->klen);
93+ d = memcmp(nft_set_ext_key(&rbe->ext),
94+ nft_set_ext_key(&new->ext),
95+ set->klen);
9796 if (d < 0)
9897 p = &parent->rb_left;
9998 else if (d > 0)
@@ -153,8 +152,8 @@ static void *nft_rbtree_deactivate(const struct nft_set *set, · 53 unmodified lines
153152 while (parent != NULL) {
154153 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
155154
156− d = nft_data_cmp(nft_set_ext_key(&rbe->ext), &elem->key,
157− set->klen);
155+ d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key.val,
156+ set->klen);
158157 if (d < 0)
159158 parent = parent->rb_left;
160159 else if (d > 0)
net/netfilter/nft_redir.c+11−8
@@ -44,25 +44,28 @@ int nft_redir_init(const struct nft_ctx *ctx, · 43 unmodified lines
4444 const struct nlattr * const tb[])
4545 {
4646 struct nft_redir *priv = nft_expr_priv(expr);
47+ unsigned int plen;
4748 int err;
4849
4950 err = nft_redir_validate(ctx, expr, NULL);
5051 if (err < 0)
5152 return err;
5253
54+ plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
5355 if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
5456 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]);
5658
57− err = nft_validate_input_register(priv->sreg_proto_min);
59+ err = nft_validate_register_load(priv->sreg_proto_min, plen);
5860 if (err < 0)
5961 return err;
6062
6163 if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
6264 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]);
6466
65− err = nft_validate_input_register(priv->sreg_proto_max);
67+ err = nft_validate_register_load(priv->sreg_proto_max,
68+ plen);
6669 if (err < 0)
6770 return err;
6871 } else {
@@ -85,11 +88,11 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) · 16 unmodified lines
8588 const struct nft_redir *priv = nft_expr_priv(expr);
8689
8790 if (priv->sreg_proto_min) {
88− if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN,
89− htonl(priv->sreg_proto_min)))
91+ if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MIN,
92+ priv->sreg_proto_min))
9093 goto nla_put_failure;
91− if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX,
92− htonl(priv->sreg_proto_max)))
94+ if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX,
95+ priv->sreg_proto_max))
9396 goto nla_put_failure;
9497 }
9598
net/netfilter/nft_reject_inet.c+3−2
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 #include <net/netfilter/ipv6/nf_reject.h>
1919
2020 static void nft_reject_inet_eval(const struct nft_expr *expr,
21− struct nft_data data[NFT_REG_MAX + 1],
21+ struct nft_regs *regs,
2222 const struct nft_pktinfo *pkt)
2323 {
2424 struct nft_reject *priv = nft_expr_priv(expr);
@@ -58,7 +58,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr, · 33 unmodified lines
5858 }
5959 break;
6060 }
61− data[NFT_REG_VERDICT].verdict = NF_DROP;
61+
62+ regs->verdict.code = NF_DROP;
6263 }
6364
6465 static int nft_reject_inet_init(const struct nft_ctx *ctx,