History

Merge tag 'nf-next-23-06-26' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next

Pablo Neira Ayuso says: ==================== Netfilter/IPVS updates for net-next 1) Allow slightly larger IPVS connection table size from Kconfig for 64-bit arch, from Abhijeet Rastogi. 2) Since IPVS connection table might be larger than 2^20 after previous patch, allow to limit it depending on the available memory. Moreover, use kvmalloc. From Julian Anastasov. 3) Do not rebuild VLAN header in nft_payload when matching source and destination MAC address. 4) Remove nested rcu read lock side in ip_set_test(), from Florian Westphal. 5) Allow to update set size, also from Florian. 6) Improve NAT tuple selection when connection is closing, from Florian Westphal. 7) Support for resetting set element stateful expression, from Phil Sutter. 8) Use NLA_POLICY_MAX to narrow down maximum attribute value in nf_tables, from Florian Westphal. * tag 'nf-next-23-06-26' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: nf_tables: limit allowed range via nla_policy netfilter: nf_tables: Introduce NFT_MSG_GETSETELEM_RESET netfilter: snat: evict closing tcp entries on reply tuple collision netfilter: nf_tables: permit update of set size netfilter: ipset: remove rcu_read_lock_bh pair from ip_set_test netfilter: nft_payload: rebuild vlan header when needed ipvs: dynamically limit the connection hash table ipvs: increase ip_vs_conn_tab_bits range for 64BIT ====================

Jakub Kicinski committed 3 years ago

Commit 61dc6512 parents 771ca3d a412dbf23 files · +199 −70Browse files

Unified · Split

23 files
  1. include/net/netfilter/nf_tables.h +3 −0
  2. include/uapi/linux/netfilter/nf_tables.h +2 −0
  3. net/netfilter/ipset/ip_set_core.c +0 −2
  4. net/netfilter/ipvs/Kconfig +14 −13
  5. net/netfilter/ipvs/ip_vs_conn.c +17 −9
  6. net/netfilter/nf_nat_core.c +88 −4
  7. net/netfilter/nf_tables_api.c +52 −20
  8. net/netfilter/nft_bitwise.c +1 −1
  9. net/netfilter/nft_byteorder.c +3 −3
  10. net/netfilter/nft_ct.c +1 −1
  11. net/netfilter/nft_dynset.c +1 −1
  12. net/netfilter/nft_exthdr.c +2 −2
  13. net/netfilter/nft_fwd_netdev.c +1 −1
  14. net/netfilter/nft_hash.c +1 −1
  15. net/netfilter/nft_meta.c +1 −1
  16. net/netfilter/nft_payload.c +2 −1
  17. net/netfilter/nft_range.c +1 −1
  18. net/netfilter/nft_reject.c +1 −1
  19. net/netfilter/nft_rt.c +1 −1
  20. net/netfilter/nft_socket.c +2 −2
  21. net/netfilter/nft_tproxy.c +1 −1
  22. net/netfilter/nft_tunnel.c +2 −2
  23. net/netfilter/nft_xfrm.c +2 −2
include/net/netfilter/nf_tables.h+3−0
@@ -1611,6 +1611,7 @@ struct nft_trans_set { · 1610 unmodified lines
16111611 u64 timeout;
16121612 bool update;
16131613 bool bound;
1614+ u32 size;
16141615 };
16151616
16161617 #define nft_trans_set(trans) \
@@ -1625,6 +1626,8 @@ struct nft_trans_set { · 8 unmodified lines
16251626 (((struct nft_trans_set *)trans->data)->timeout)
16261627 #define nft_trans_set_gc_int(trans) \
16271628 (((struct nft_trans_set *)trans->data)->gc_int)
1629+#define nft_trans_set_size(trans) \
1630+ (((struct nft_trans_set *)trans->data)->size)
16281631
16291632 struct nft_trans_chain {
16301633 struct nft_chain *chain;
include/uapi/linux/netfilter/nf_tables.h+2−0
@@ -105,6 +105,7 @@ enum nft_verdicts { · 104 unmodified lines
105105 * @NFT_MSG_DESTROYSETELEM: destroy a set element (enum nft_set_elem_attributes)
106106 * @NFT_MSG_DESTROYOBJ: destroy a stateful object (enum nft_object_attributes)
107107 * @NFT_MSG_DESTROYFLOWTABLE: destroy flow table (enum nft_flowtable_attributes)
108+ * @NFT_MSG_GETSETELEM_RESET: get set elements and reset attached stateful expressions (enum nft_set_elem_attributes)
108109 */
109110 enum nf_tables_msg_types {
110111 NFT_MSG_NEWTABLE,
@@ -140,6 +141,7 @@ enum nf_tables_msg_types { · 29 unmodified lines
140141 NFT_MSG_DESTROYSETELEM,
141142 NFT_MSG_DESTROYOBJ,
142143 NFT_MSG_DESTROYFLOWTABLE,
144+ NFT_MSG_GETSETELEM_RESET,
143145 NFT_MSG_MAX,
144146 };
145147
net/netfilter/ipset/ip_set_core.c+0−2
@@ -739,9 +739,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb, · 738 unmodified lines
739739 !(opt->family == set->family || set->family == NFPROTO_UNSPEC))
740740 return 0;
741741
742− rcu_read_lock_bh();
743742 ret = set->variant->kadt(set, skb, par, IPSET_TEST, opt);
744− rcu_read_unlock_bh();
745743
746744 if (ret == -EAGAIN) {
747745 /* Type requests element to be completed */
net/netfilter/ipvs/Kconfig+14−13
@@ -44,7 +44,8 @@ config IP_VS_DEBUG · 43 unmodified lines
4444
4545 config IP_VS_TAB_BITS
4646 int "IPVS connection table size (the Nth power of 2)"
47− range 8 20
47+ range 8 20 if !64BIT
48+ range 8 27 if 64BIT
4849 default 12
4950 help
5051 The IPVS connection hash table uses the chaining scheme to handle
@@ -54,24 +55,24 @@ config IP_VS_TAB_BITS · 3 unmodified lines
5455
5556 Note the table size must be power of 2. The table size will be the
5657 value of 2 to the your input number power. The number to choose is
57− from 8 to 20, the default number is 12, which means the table size
58− is 4096. Don't input the number too small, otherwise you will lose
59− performance on it. You can adapt the table size yourself, according
60− to your virtual server application. It is good to set the table size
61− not far less than the number of connections per second multiplying
62− average lasting time of connection in the table. For example, your
63− virtual server gets 200 connections per second, the connection lasts
64− for 200 seconds in average in the connection table, the table size
65− should be not far less than 200x200, it is good to set the table
66− size 32768 (2**15).
58+ from 8 to 27 for 64BIT(20 otherwise), the default number is 12,
59+ which means the table size is 4096. Don't input the number too
60+ small, otherwise you will lose performance on it. You can adapt the
61+ table size yourself, according to your virtual server application.
62+ It is good to set the table size not far less than the number of
63+ connections per second multiplying average lasting time of
64+ connection in the table. For example, your virtual server gets 200
65+ connections per second, the connection lasts for 200 seconds in
66+ average in the connection table, the table size should be not far
67+ less than 200x200, it is good to set the table size 32768 (2**15).
6768
6869 Another note that each connection occupies 128 bytes effectively and
6970 each hash entry uses 8 bytes, so you can estimate how much memory is
7071 needed for your box.
7172
7273 You can overwrite this number setting conn_tab_bits module parameter
73− or by appending ip_vs.conn_tab_bits=? to the kernel command line
74− if IP VS was compiled built-in.
74+ or by appending ip_vs.conn_tab_bits=? to the kernel command line if
75+ IP VS was compiled built-in.
7576
7677 comment "IPVS transport protocol load balancing support"
7778
net/netfilter/ipvs/ip_vs_conn.c+17−9
@@ -26,7 +26,6 @@ · 25 unmodified lines
2626 #include <linux/net.h>
2727 #include <linux/kernel.h>
2828 #include <linux/module.h>
29−#include <linux/vmalloc.h>
3029 #include <linux/proc_fs.h> /* for proc_net_* */
3130 #include <linux/slab.h>
3231 #include <linux/seq_file.h>
@@ -1482,13 +1481,21 @@ void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs) · 1449 unmodified lines
14821481 int __init ip_vs_conn_init(void)
14831482 {
14841483 size_t tab_array_size;
1484+ int max_avail;
1485+#if BITS_PER_LONG > 32
1486+ int max = 27;
1487+#else
1488+ int max = 20;
1489+#endif
1490+ int min = 8;
14851491 int idx;
14861492
1487− /* Compute size and mask */
1488− if (ip_vs_conn_tab_bits < 8 || ip_vs_conn_tab_bits > 20) {
1489− pr_info("conn_tab_bits not in [8, 20]. Using default value\n");
1490− ip_vs_conn_tab_bits = CONFIG_IP_VS_TAB_BITS;
1491− }
1493+ max_avail = order_base_2(totalram_pages()) + PAGE_SHIFT;
1494+ max_avail -= 2; /* ~4 in hash row */
1495+ max_avail -= 1; /* IPVS up to 1/2 of mem */
1496+ max_avail -= order_base_2(sizeof(struct ip_vs_conn));
1497+ max = clamp(max, min, max_avail);
1498+ ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
14921499 ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
14931500 ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
14941501
@@ -1497,7 +1504,8 @@ int __init ip_vs_conn_init(void) · 2 unmodified lines
14971504 */
14981505 tab_array_size = array_size(ip_vs_conn_tab_size,
14991506 sizeof(*ip_vs_conn_tab));
1500− ip_vs_conn_tab = vmalloc(tab_array_size);
1507+ ip_vs_conn_tab = kvmalloc_array(ip_vs_conn_tab_size,
1508+ sizeof(*ip_vs_conn_tab), GFP_KERNEL);
15011509 if (!ip_vs_conn_tab)
15021510 return -ENOMEM;
15031511
@@ -1506,7 +1514,7 @@ int __init ip_vs_conn_init(void) · 2 unmodified lines
15061514 sizeof(struct ip_vs_conn), 0,
15071515 SLAB_HWCACHE_ALIGN, NULL);
15081516 if (!ip_vs_conn_cachep) {
1509− vfree(ip_vs_conn_tab);
1517+ kvfree(ip_vs_conn_tab);
15101518 return -ENOMEM;
15111519 }
15121520
@@ -1534,5 +1542,5 @@ void ip_vs_conn_cleanup(void) · 21 unmodified lines
15341542 rcu_barrier();
15351543 /* Release the empty cache */
15361544 kmem_cache_destroy(ip_vs_conn_cachep);
1537− vfree(ip_vs_conn_tab);
1545+ kvfree(ip_vs_conn_tab);
15381546 }
net/netfilter/nf_nat_core.c+88−4
@@ -27,6 +27,9 @@ · 26 unmodified lines
2727
2828 #include "nf_internals.h"
2929
30+#define NF_NAT_MAX_ATTEMPTS 128
31+#define NF_NAT_HARDER_THRESH (NF_NAT_MAX_ATTEMPTS / 4)
32+
3033 static spinlock_t nf_nat_locks[CONNTRACK_LOCKS];
3134
3235 static DEFINE_MUTEX(nf_nat_proto_mutex);
@@ -197,6 +200,88 @@ nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, · 164 unmodified lines
197200 return nf_conntrack_tuple_taken(&reply, ignored_conntrack);
198201 }
199202
203+static bool nf_nat_may_kill(struct nf_conn *ct, unsigned long flags)
204+{
205+ static const unsigned long flags_refuse = IPS_FIXED_TIMEOUT |
206+ IPS_DYING;
207+ static const unsigned long flags_needed = IPS_SRC_NAT;
208+ enum tcp_conntrack old_state;
209+
210+ old_state = READ_ONCE(ct->proto.tcp.state);
211+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
212+ return false;
213+
214+ if (flags & flags_refuse)
215+ return false;
216+
217+ return (flags & flags_needed) == flags_needed;
218+}
219+
220+/* reverse direction will send packets to new source, so
221+ * make sure such packets are invalid.
222+ */
223+static bool nf_seq_has_advanced(const struct nf_conn *old, const struct nf_conn *new)
224+{
225+ return (__s32)(new->proto.tcp.seen[0].td_end -
226+ old->proto.tcp.seen[0].td_end) > 0;
227+}
228+
229+static int
230+nf_nat_used_tuple_harder(const struct nf_conntrack_tuple *tuple,
231+ const struct nf_conn *ignored_conntrack,
232+ unsigned int attempts_left)
233+{
234+ static const unsigned long flags_offload = IPS_OFFLOAD | IPS_HW_OFFLOAD;
235+ struct nf_conntrack_tuple_hash *thash;
236+ const struct nf_conntrack_zone *zone;
237+ struct nf_conntrack_tuple reply;
238+ unsigned long flags;
239+ struct nf_conn *ct;
240+ bool taken = true;
241+ struct net *net;
242+
243+ nf_ct_invert_tuple(&reply, tuple);
244+
245+ if (attempts_left > NF_NAT_HARDER_THRESH ||
246+ tuple->dst.protonum != IPPROTO_TCP ||
247+ ignored_conntrack->proto.tcp.state != TCP_CONNTRACK_SYN_SENT)
248+ return nf_conntrack_tuple_taken(&reply, ignored_conntrack);
249+
250+ /* :ast few attempts to find a free tcp port. Destructive
251+ * action: evict colliding if its in timewait state and the
252+ * tcp sequence number has advanced past the one used by the
253+ * old entry.
254+ */
255+ net = nf_ct_net(ignored_conntrack);
256+ zone = nf_ct_zone(ignored_conntrack);
257+
258+ thash = nf_conntrack_find_get(net, zone, &reply);
259+ if (!thash)
260+ return false;
261+
262+ ct = nf_ct_tuplehash_to_ctrack(thash);
263+
264+ if (thash->tuple.dst.dir == IP_CT_DIR_ORIGINAL)
265+ goto out;
266+
267+ if (WARN_ON_ONCE(ct == ignored_conntrack))
268+ goto out;
269+
270+ flags = READ_ONCE(ct->status);
271+ if (!nf_nat_may_kill(ct, flags))
272+ goto out;
273+
274+ if (!nf_seq_has_advanced(ct, ignored_conntrack))
275+ goto out;
276+
277+ /* Even if we can evict do not reuse if entry is offloaded. */
278+ if (nf_ct_kill(ct))
279+ taken = flags & flags_offload;
280+out:
281+ nf_ct_put(ct);
282+ return taken;
283+}
284+
200285 static bool nf_nat_inet_in_range(const struct nf_conntrack_tuple *t,
201286 const struct nf_nat_range2 *range)
202287 {
@@ -385,7 +470,6 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple, · 182 unmodified lines
385470 unsigned int range_size, min, max, i, attempts;
386471 __be16 *keyptr;
387472 u16 off;
388− static const unsigned int max_attempts = 128;
389473
390474 switch (tuple->dst.protonum) {
391475 case IPPROTO_ICMP:
@@ -471,8 +555,8 @@ find_free_id: · 79 unmodified lines
471555 off = get_random_u16();
472556
473557 attempts = range_size;
474− if (attempts > max_attempts)
475− attempts = max_attempts;
558+ if (attempts > NF_NAT_MAX_ATTEMPTS)
559+ attempts = NF_NAT_MAX_ATTEMPTS;
476560
477561 /* We are in softirq; doing a search of the entire range risks
478562 * soft lockup when all tuples are already used.
@@ -483,7 +567,7 @@ find_free_id: · 4 unmodified lines
483567 another_round:
484568 for (i = 0; i < attempts; i++, off++) {
485569 *keyptr = htons(min + off % range_size);
486− if (!nf_nat_used_tuple(tuple, ct))
570+ if (!nf_nat_used_tuple_harder(tuple, ct, attempts - i))
487571 return;
488572 }
489573
net/netfilter/nf_tables_api.c+52−20
@@ -567,6 +567,7 @@ static int __nft_trans_set_add(const struct nft_ctx *ctx, int msg_type, · 566 unmodified lines
567567 nft_trans_set_update(trans) = true;
568568 nft_trans_set_gc_int(trans) = desc->gc_int;
569569 nft_trans_set_timeout(trans) = desc->timeout;
570+ nft_trans_set_size(trans) = desc->size;
570571 }
571572 nft_trans_commit_list_add_tail(ctx->net, trans);
572573
@@ -5442,7 +5443,8 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + · 4869 unmodified lines
54425443
54435444 static int nft_set_elem_expr_dump(struct sk_buff *skb,
54445445 const struct nft_set *set,
5445− const struct nft_set_ext *ext)
5446+ const struct nft_set_ext *ext,
5447+ bool reset)
54465448 {
54475449 struct nft_set_elem_expr *elem_expr;
54485450 u32 size, num_exprs = 0;
@@ -5455,7 +5457,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb, · 6 unmodified lines
54555457
54565458 if (num_exprs == 1) {
54575459 expr = nft_setelem_expr_at(elem_expr, 0);
5458− if (nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, expr, false) < 0)
5460+ if (nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, expr, reset) < 0)
54595461 return -1;
54605462
54615463 return 0;
@@ -5466,7 +5468,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb, · 4 unmodified lines
54665468
54675469 nft_setelem_expr_foreach(expr, elem_expr, size) {
54685470 expr = nft_setelem_expr_at(elem_expr, size);
5469− if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr, false) < 0)
5471+ if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr, reset) < 0)
54705472 goto nla_put_failure;
54715473 }
54725474 nla_nest_end(skb, nest);
@@ -5479,11 +5481,13 @@ nla_put_failure: · 6 unmodified lines
54795481
54805482 static int nf_tables_fill_setelem(struct sk_buff *skb,
54815483 const struct nft_set *set,
5482− const struct nft_set_elem *elem)
5484+ const struct nft_set_elem *elem,
5485+ bool reset)
54835486 {
54845487 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
54855488 unsigned char *b = skb_tail_pointer(skb);
54865489 struct nlattr *nest;
5490+ u64 timeout = 0;
54875491
54885492 nest = nla_nest_start_noflag(skb, NFTA_LIST_ELEM);
54895493 if (nest == NULL)
@@ -5506,7 +5510,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, · 16 unmodified lines
55065510 goto nla_put_failure;
55075511
55085512 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS) &&
5509− nft_set_elem_expr_dump(skb, set, ext))
5513+ nft_set_elem_expr_dump(skb, set, ext, reset))
55105514 goto nla_put_failure;
55115515
55125516 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
@@ -5519,11 +5523,15 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, · 6 unmodified lines
55195523 htonl(*nft_set_ext_flags(ext))))
55205524 goto nla_put_failure;
55215525
5522− if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
5523− nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
5524− nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
5525− NFTA_SET_ELEM_PAD))
5526− goto nla_put_failure;
5526+ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
5527+ timeout = *nft_set_ext_timeout(ext);
5528+ if (nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
5529+ nf_jiffies64_to_msecs(timeout),
5530+ NFTA_SET_ELEM_PAD))
5531+ goto nla_put_failure;
5532+ } else if (set->flags & NFT_SET_TIMEOUT) {
5533+ timeout = READ_ONCE(set->timeout);
5534+ }
55275535
55285536 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
55295537 u64 expires, now = get_jiffies_64();
@@ -5538,6 +5546,9 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, · 8 unmodified lines
55385546 nf_jiffies64_to_msecs(expires),
55395547 NFTA_SET_ELEM_PAD))
55405548 goto nla_put_failure;
5549+
5550+ if (reset)
5551+ *nft_set_ext_expiration(ext) = now + timeout;
55415552 }
55425553
55435554 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
@@ -5561,6 +5572,7 @@ struct nft_set_dump_args { · 17 unmodified lines
55615572 const struct netlink_callback *cb;
55625573 struct nft_set_iter iter;
55635574 struct sk_buff *skb;
5575+ bool reset;
55645576 };
55655577
55665578 static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
@@ -5571,7 +5583,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx, · 4 unmodified lines
55715583 struct nft_set_dump_args *args;
55725584
55735585 args = container_of(iter, struct nft_set_dump_args, iter);
5574− return nf_tables_fill_setelem(args->skb, set, elem);
5586+ return nf_tables_fill_setelem(args->skb, set, elem, args->reset);
55755587 }
55765588
55775589 struct nft_set_dump_ctx {
@@ -5580,7 +5592,7 @@ struct nft_set_dump_ctx { · 2 unmodified lines
55805592 };
55815593
55825594 static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb,
5583− const struct nft_set *set)
5595+ const struct nft_set *set, bool reset)
55845596 {
55855597 struct nft_set_elem_catchall *catchall;
55865598 u8 genmask = nft_genmask_cur(net);
@@ -5595,7 +5607,7 @@ static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb, · 8 unmodified lines
55955607 continue;
55965608
55975609 elem.priv = catchall->elem;
5598− ret = nf_tables_fill_setelem(skb, set, &elem);
5610+ ret = nf_tables_fill_setelem(skb, set, &elem, reset);
55995611 break;
56005612 }
56015613
@@ -5613,6 +5625,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) · 11 unmodified lines
56135625 bool set_found = false;
56145626 struct nlmsghdr *nlh;
56155627 struct nlattr *nest;
5628+ bool reset = false;
56165629 u32 portid, seq;
56175630 int event;
56185631
@@ -5660,8 +5673,12 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) · 41 unmodified lines
56605673 if (nest == NULL)
56615674 goto nla_put_failure;
56625675
5676+ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
5677+ reset = true;
5678+
56635679 args.cb = cb;
56645680 args.skb = skb;
5681+ args.reset = reset;
56655682 args.iter.genmask = nft_genmask_cur(net);
56665683 args.iter.skip = cb->args[0];
56675684 args.iter.count = 0;
@@ -5670,7 +5687,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) · 2 unmodified lines
56705687 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
56715688
56725689 if (!args.iter.err && args.iter.count == cb->args[0])
5673− args.iter.err = nft_set_catchall_dump(net, skb, set);
5690+ args.iter.err = nft_set_catchall_dump(net, skb, set, reset);
56745691 rcu_read_unlock();
56755692
56765693 nla_nest_end(skb, nest);
@@ -5708,7 +5725,8 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb, · 31 unmodified lines
57085725 const struct nft_ctx *ctx, u32 seq,
57095726 u32 portid, int event, u16 flags,
57105727 const struct nft_set *set,
5711− const struct nft_set_elem *elem)
5728+ const struct nft_set_elem *elem,
5729+ bool reset)
57125730 {
57135731 struct nlmsghdr *nlh;
57145732 struct nlattr *nest;
@@ -5729,7 +5747,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb, · 14 unmodified lines
57295747 if (nest == NULL)
57305748 goto nla_put_failure;
57315749
5732− err = nf_tables_fill_setelem(skb, set, elem);
5750+ err = nf_tables_fill_setelem(skb, set, elem, reset);
57335751 if (err < 0)
57345752 goto nla_put_failure;
57355753
@@ -5835,7 +5853,7 @@ static int nft_setelem_get(struct nft_ctx *ctx, struct nft_set *set, · 99 unmodified lines
58355853 }
58365854
58375855 static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
5838− const struct nlattr *attr)
5856+ const struct nlattr *attr, bool reset)
58395857 {
58405858 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
58415859 struct nft_set_elem elem;
@@ -5879,7 +5897,8 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 37 unmodified lines
58795897 return err;
58805898
58815899 err = nf_tables_fill_setelem_info(skb, ctx, ctx->seq, ctx->portid,
5882− NFT_MSG_NEWSETELEM, 0, set, &elem);
5900+ NFT_MSG_NEWSETELEM, 0, set, &elem,
5901+ reset);
58835902 if (err < 0)
58845903 goto err_fill_setelem;
58855904
@@ -5903,6 +5922,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb, · 17 unmodified lines
59035922 struct nft_set *set;
59045923 struct nlattr *attr;
59055924 struct nft_ctx ctx;
5925+ bool reset = false;
59065926 int rem, err = 0;
59075927
59085928 table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
@@ -5937,8 +5957,11 @@ static int nf_tables_getsetelem(struct sk_buff *skb, · 28 unmodified lines
59375957 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
59385958 return -EINVAL;
59395959
5960+ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
5961+ reset = true;
5962+
59405963 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
5941− err = nft_get_set_elem(&ctx, set, attr);
5964+ err = nft_get_set_elem(&ctx, set, attr, reset);
59425965 if (err < 0) {
59435966 NL_SET_BAD_ATTR(extack, attr);
59445967 break;
@@ -5971,7 +5994,7 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, · 26 unmodified lines
59715994 flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
59725995
59735996 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
5974− set, elem);
5997+ set, elem, false);
59755998 if (err < 0) {
59765999 kfree_skb(skb);
59776000 goto err;
@@ -8920,6 +8943,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { · 2942 unmodified lines
89208943 .attr_count = NFTA_SET_ELEM_LIST_MAX,
89218944 .policy = nft_set_elem_list_policy,
89228945 },
8946+ [NFT_MSG_GETSETELEM_RESET] = {
8947+ .call = nf_tables_getsetelem,
8948+ .type = NFNL_CB_RCU,
8949+ .attr_count = NFTA_SET_ELEM_LIST_MAX,
8950+ .policy = nft_set_elem_list_policy,
8951+ },
89238952 [NFT_MSG_DELSETELEM] = {
89248953 .call = nf_tables_delsetelem,
89258954 .type = NFNL_CB_BATCH,
@@ -9670,6 +9699,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 744 unmodified lines
96709699
96719700 WRITE_ONCE(set->timeout, nft_trans_set_timeout(trans));
96729701 WRITE_ONCE(set->gc_int, nft_trans_set_gc_int(trans));
9702+
9703+ if (nft_trans_set_size(trans))
9704+ WRITE_ONCE(set->size, nft_trans_set_size(trans));
96739705 } else {
96749706 nft_clear(net, nft_trans_set(trans));
96759707 /* This avoids hitting -EBUSY when deleting the table
net/netfilter/nft_bitwise.c+1−1
@@ -86,7 +86,7 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = { · 85 unmodified lines
8686 [NFTA_BITWISE_LEN] = { .type = NLA_U32 },
8787 [NFTA_BITWISE_MASK] = { .type = NLA_NESTED },
8888 [NFTA_BITWISE_XOR] = { .type = NLA_NESTED },
89− [NFTA_BITWISE_OP] = { .type = NLA_U32 },
89+ [NFTA_BITWISE_OP] = NLA_POLICY_MAX(NLA_BE32, 255),
9090 [NFTA_BITWISE_DATA] = { .type = NLA_NESTED },
9191 };
9292
net/netfilter/nft_byteorder.c+3−3
@@ -88,9 +88,9 @@ void nft_byteorder_eval(const struct nft_expr *expr, · 87 unmodified lines
8888 static const struct nla_policy nft_byteorder_policy[NFTA_BYTEORDER_MAX + 1] = {
8989 [NFTA_BYTEORDER_SREG] = { .type = NLA_U32 },
9090 [NFTA_BYTEORDER_DREG] = { .type = NLA_U32 },
91− [NFTA_BYTEORDER_OP] = { .type = NLA_U32 },
92− [NFTA_BYTEORDER_LEN] = { .type = NLA_U32 },
93− [NFTA_BYTEORDER_SIZE] = { .type = NLA_U32 },
91+ [NFTA_BYTEORDER_OP] = NLA_POLICY_MAX(NLA_BE32, 255),
92+ [NFTA_BYTEORDER_LEN] = NLA_POLICY_MAX(NLA_BE32, 255),
93+ [NFTA_BYTEORDER_SIZE] = NLA_POLICY_MAX(NLA_BE32, 255),
9494 };
9595
9696 static int nft_byteorder_init(const struct nft_ctx *ctx,
net/netfilter/nft_ct.c+1−1
@@ -332,7 +332,7 @@ static void nft_ct_set_eval(const struct nft_expr *expr, · 331 unmodified lines
332332
333333 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
334334 [NFTA_CT_DREG] = { .type = NLA_U32 },
335− [NFTA_CT_KEY] = { .type = NLA_U32 },
335+ [NFTA_CT_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
336336 [NFTA_CT_DIRECTION] = { .type = NLA_U8 },
337337 [NFTA_CT_SREG] = { .type = NLA_U32 },
338338 };
net/netfilter/nft_dynset.c+1−1
@@ -148,7 +148,7 @@ static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = { · 147 unmodified lines
148148 [NFTA_DYNSET_SET_NAME] = { .type = NLA_STRING,
149149 .len = NFT_SET_MAXNAMELEN - 1 },
150150 [NFTA_DYNSET_SET_ID] = { .type = NLA_U32 },
151− [NFTA_DYNSET_OP] = { .type = NLA_U32 },
151+ [NFTA_DYNSET_OP] = NLA_POLICY_MAX(NLA_BE32, 255),
152152 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
153153 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
154154 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
net/netfilter/nft_exthdr.c+2−2
@@ -487,9 +487,9 @@ static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { · 486 unmodified lines
487487 [NFTA_EXTHDR_DREG] = { .type = NLA_U32 },
488488 [NFTA_EXTHDR_TYPE] = { .type = NLA_U8 },
489489 [NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 },
490− [NFTA_EXTHDR_LEN] = { .type = NLA_U32 },
490+ [NFTA_EXTHDR_LEN] = NLA_POLICY_MAX(NLA_BE32, 255),
491491 [NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 },
492− [NFTA_EXTHDR_OP] = { .type = NLA_U32 },
492+ [NFTA_EXTHDR_OP] = NLA_POLICY_MAX(NLA_BE32, 255),
493493 [NFTA_EXTHDR_SREG] = { .type = NLA_U32 },
494494 };
495495
net/netfilter/nft_fwd_netdev.c+1−1
@@ -40,7 +40,7 @@ static void nft_fwd_netdev_eval(const struct nft_expr *expr, · 39 unmodified lines
4040 static const struct nla_policy nft_fwd_netdev_policy[NFTA_FWD_MAX + 1] = {
4141 [NFTA_FWD_SREG_DEV] = { .type = NLA_U32 },
4242 [NFTA_FWD_SREG_ADDR] = { .type = NLA_U32 },
43− [NFTA_FWD_NFPROTO] = { .type = NLA_U32 },
43+ [NFTA_FWD_NFPROTO] = NLA_POLICY_MAX(NLA_BE32, 255),
4444 };
4545
4646 static int nft_fwd_netdev_init(const struct nft_ctx *ctx,
net/netfilter/nft_hash.c+1−1
@@ -59,7 +59,7 @@ static void nft_symhash_eval(const struct nft_expr *expr, · 58 unmodified lines
5959 static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
6060 [NFTA_HASH_SREG] = { .type = NLA_U32 },
6161 [NFTA_HASH_DREG] = { .type = NLA_U32 },
62− [NFTA_HASH_LEN] = { .type = NLA_U32 },
62+ [NFTA_HASH_LEN] = NLA_POLICY_MAX(NLA_BE32, 255),
6363 [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
6464 [NFTA_HASH_SEED] = { .type = NLA_U32 },
6565 [NFTA_HASH_OFFSET] = { .type = NLA_U32 },
net/netfilter/nft_meta.c+1−1
@@ -458,7 +458,7 @@ EXPORT_SYMBOL_GPL(nft_meta_set_eval); · 457 unmodified lines
458458
459459 const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
460460 [NFTA_META_DREG] = { .type = NLA_U32 },
461− [NFTA_META_KEY] = { .type = NLA_U32 },
461+ [NFTA_META_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
462462 [NFTA_META_SREG] = { .type = NLA_U32 },
463463 };
464464 EXPORT_SYMBOL_GPL(nft_meta_policy);
net/netfilter/nft_payload.c+2−1
@@ -171,7 +171,8 @@ void nft_payload_eval(const struct nft_expr *expr, · 170 unmodified lines
171171 if (!skb_mac_header_was_set(skb))
172172 goto err;
173173
174− if (skb_vlan_tag_present(skb)) {
174+ if (skb_vlan_tag_present(skb) &&
175+ priv->offset >= offsetof(struct ethhdr, h_proto)) {
175176 if (!nft_payload_copy_vlan(dest, skb,
176177 priv->offset, priv->len))
177178 goto err;
net/netfilter/nft_range.c+1−1
@@ -42,7 +42,7 @@ void nft_range_eval(const struct nft_expr *expr, · 41 unmodified lines
4242
4343 static const struct nla_policy nft_range_policy[NFTA_RANGE_MAX + 1] = {
4444 [NFTA_RANGE_SREG] = { .type = NLA_U32 },
45− [NFTA_RANGE_OP] = { .type = NLA_U32 },
45+ [NFTA_RANGE_OP] = NLA_POLICY_MAX(NLA_BE32, 255),
4646 [NFTA_RANGE_FROM_DATA] = { .type = NLA_NESTED },
4747 [NFTA_RANGE_TO_DATA] = { .type = NLA_NESTED },
4848 };
net/netfilter/nft_reject.c+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 #include <linux/icmpv6.h>
1919
2020 const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
21− [NFTA_REJECT_TYPE] = { .type = NLA_U32 },
21+ [NFTA_REJECT_TYPE] = NLA_POLICY_MAX(NLA_BE32, 255),
2222 [NFTA_REJECT_ICMP_CODE] = { .type = NLA_U8 },
2323 };
2424 EXPORT_SYMBOL_GPL(nft_reject_policy);
net/netfilter/nft_rt.c+1−1
@@ -104,7 +104,7 @@ err: · 103 unmodified lines
104104
105105 static const struct nla_policy nft_rt_policy[NFTA_RT_MAX + 1] = {
106106 [NFTA_RT_DREG] = { .type = NLA_U32 },
107− [NFTA_RT_KEY] = { .type = NLA_U32 },
107+ [NFTA_RT_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
108108 };
109109
110110 static int nft_rt_get_init(const struct nft_ctx *ctx,
net/netfilter/nft_socket.c+2−2
@@ -138,9 +138,9 @@ static void nft_socket_eval(const struct nft_expr *expr, · 137 unmodified lines
138138 }
139139
140140 static const struct nla_policy nft_socket_policy[NFTA_SOCKET_MAX + 1] = {
141− [NFTA_SOCKET_KEY] = { .type = NLA_U32 },
141+ [NFTA_SOCKET_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
142142 [NFTA_SOCKET_DREG] = { .type = NLA_U32 },
143− [NFTA_SOCKET_LEVEL] = { .type = NLA_U32 },
143+ [NFTA_SOCKET_LEVEL] = NLA_POLICY_MAX(NLA_BE32, 255),
144144 };
145145
146146 static int nft_socket_init(const struct nft_ctx *ctx,
net/netfilter/nft_tproxy.c+1−1
@@ -183,7 +183,7 @@ static void nft_tproxy_eval(const struct nft_expr *expr, · 182 unmodified lines
183183 }
184184
185185 static const struct nla_policy nft_tproxy_policy[NFTA_TPROXY_MAX + 1] = {
186− [NFTA_TPROXY_FAMILY] = { .type = NLA_U32 },
186+ [NFTA_TPROXY_FAMILY] = NLA_POLICY_MAX(NLA_BE32, 255),
187187 [NFTA_TPROXY_REG_ADDR] = { .type = NLA_U32 },
188188 [NFTA_TPROXY_REG_PORT] = { .type = NLA_U32 },
189189 };
net/netfilter/nft_tunnel.c+2−2
@@ -66,9 +66,9 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr, · 65 unmodified lines
6666 }
6767
6868 static const struct nla_policy nft_tunnel_policy[NFTA_TUNNEL_MAX + 1] = {
69− [NFTA_TUNNEL_KEY] = { .type = NLA_U32 },
69+ [NFTA_TUNNEL_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
7070 [NFTA_TUNNEL_DREG] = { .type = NLA_U32 },
71− [NFTA_TUNNEL_MODE] = { .type = NLA_U32 },
71+ [NFTA_TUNNEL_MODE] = NLA_POLICY_MAX(NLA_BE32, 255),
7272 };
7373
7474 static int nft_tunnel_get_init(const struct nft_ctx *ctx,
net/netfilter/nft_xfrm.c+2−2
@@ -16,9 +16,9 @@ · 15 unmodified lines
1616 #include <net/xfrm.h>
1717
1818 static const struct nla_policy nft_xfrm_policy[NFTA_XFRM_MAX + 1] = {
19− [NFTA_XFRM_KEY] = { .type = NLA_U32 },
19+ [NFTA_XFRM_KEY] = NLA_POLICY_MAX(NLA_BE32, 255),
2020 [NFTA_XFRM_DIR] = { .type = NLA_U8 },
21− [NFTA_XFRM_SPNUM] = { .type = NLA_U32 },
21+ [NFTA_XFRM_SPNUM] = NLA_POLICY_MAX(NLA_BE32, 255),
2222 [NFTA_XFRM_DREG] = { .type = NLA_U32 },
2323 };
2424