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

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

Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for net-next:

1) Add nfgenmsg field to nfnetlink's struct nfnl_info and use it.

2) Remove nft_ctx_init_from_elemattr() and nft_ctx_init_from_setattr()
helper functions.

3) Add the nf_ct_pernet() helper function to fetch the conntrack
pernetns data area.

4) Expose TCP and UDP flowtable offload timeouts through sysctl,
from Oz Shlomo.

5) Add nfnetlink_hook subsystem to fetch the netfilter hook
pipeline configuration, from Florian Westphal. This also includes
a new field to annotate the hook type as metadata.

6) Fix unsafe memory access to non-linear skbuff in the new SCTP
chunk support for nft_exthdr, from Phil Sutter.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+697 -205
+7 -1
include/linux/netfilter.h
··· 77 77 typedef unsigned int nf_hookfn(void *priv, 78 78 struct sk_buff *skb, 79 79 const struct nf_hook_state *state); 80 + enum nf_hook_ops_type { 81 + NF_HOOK_OP_UNDEFINED, 82 + NF_HOOK_OP_NF_TABLES, 83 + }; 84 + 80 85 struct nf_hook_ops { 81 86 /* User fills in from here down. */ 82 87 nf_hookfn *hook; 83 88 struct net_device *dev; 84 89 void *priv; 85 - u_int8_t pf; 90 + u8 pf; 91 + enum nf_hook_ops_type hook_ops_type:8; 86 92 unsigned int hooknum; 87 93 /* Hooks are ordered in ascending priority. */ 88 94 int priority;
+1
include/linux/netfilter/nfnetlink.h
··· 11 11 struct net *net; 12 12 struct sock *sk; 13 13 const struct nlmsghdr *nlh; 14 + const struct nfgenmsg *nfmsg; 14 15 struct netlink_ext_ack *extack; 15 16 }; 16 17
+7
include/net/netfilter/nf_conntrack.h
··· 346 346 skb_set_nfct(skb, (unsigned long)ct | info); 347 347 } 348 348 349 + extern unsigned int nf_conntrack_net_id; 350 + 351 + static inline struct nf_conntrack_net *nf_ct_pernet(const struct net *net) 352 + { 353 + return net_generic(net, nf_conntrack_net_id); 354 + } 355 + 349 356 #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) 350 357 #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) 351 358 #define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
+2
include/net/netfilter/nf_flow_table.h
··· 177 177 #define NF_FLOW_TIMEOUT (30 * HZ) 178 178 #define nf_flowtable_time_stamp (u32)jiffies 179 179 180 + unsigned long flow_offload_get_timeout(struct flow_offload *flow); 181 + 180 182 static inline __s32 nf_flow_timeout_delta(unsigned int timeout) 181 183 { 182 184 return (__s32)(timeout - nf_flowtable_time_stamp);
+8
include/net/netns/conntrack.h
··· 27 27 u8 tcp_loose; 28 28 u8 tcp_be_liberal; 29 29 u8 tcp_max_retrans; 30 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 31 + unsigned int offload_timeout; 32 + unsigned int offload_pickup; 33 + #endif 30 34 }; 31 35 32 36 enum udp_conntrack { ··· 41 37 42 38 struct nf_udp_net { 43 39 unsigned int timeouts[UDP_CT_MAX]; 40 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 41 + unsigned int offload_timeout; 42 + unsigned int offload_pickup; 43 + #endif 44 44 }; 45 45 46 46 struct nf_icmp_net {
+2 -1
include/uapi/linux/netfilter/nfnetlink.h
··· 60 60 #define NFNL_SUBSYS_CTHELPER 9 61 61 #define NFNL_SUBSYS_NFTABLES 10 62 62 #define NFNL_SUBSYS_NFT_COMPAT 11 63 - #define NFNL_SUBSYS_COUNT 12 63 + #define NFNL_SUBSYS_HOOK 12 64 + #define NFNL_SUBSYS_COUNT 13 64 65 65 66 /* Reserved control nfnetlink messages */ 66 67 #define NFNL_MSG_BATCH_BEGIN NLMSG_MIN_TYPE
+10
net/netfilter/Kconfig
··· 19 19 config NETFILTER_FAMILY_ARP 20 20 bool 21 21 22 + config NETFILTER_NETLINK_HOOK 23 + tristate "Netfilter base hook dump support" 24 + depends on NETFILTER_ADVANCED 25 + depends on NF_TABLES 26 + select NETFILTER_NETLINK 27 + help 28 + If this option is enabled, the kernel will include support 29 + to list the base netfilter hooks via NFNETLINK. 30 + This is helpful for debugging. 31 + 22 32 config NETFILTER_NETLINK_ACCT 23 33 tristate "Netfilter NFACCT over NFNETLINK interface" 24 34 depends on NETFILTER_ADVANCED
+1
net/netfilter/Makefile
··· 22 22 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 23 23 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 24 24 obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o 25 + obj-$(CONFIG_NETFILTER_NETLINK_HOOK) += nfnetlink_hook.o 25 26 26 27 # connection tracking 27 28 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
+9 -13
net/netfilter/nf_conntrack_core.c
··· 55 55 56 56 #include "nf_internals.h" 57 57 58 - extern unsigned int nf_conntrack_net_id; 59 - 60 58 __cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS]; 61 59 EXPORT_SYMBOL_GPL(nf_conntrack_locks); 62 60 ··· 84 86 #define GC_EVICT_RATIO 50u 85 87 86 88 static struct conntrack_gc_work conntrack_gc_work; 87 - 88 - extern unsigned int nf_conntrack_net_id; 89 89 90 90 void nf_conntrack_lock(spinlock_t *lock) __acquires(lock) 91 91 { ··· 1400 1404 continue; 1401 1405 1402 1406 net = nf_ct_net(tmp); 1403 - cnet = net_generic(net, nf_conntrack_net_id); 1407 + cnet = nf_ct_pernet(net); 1404 1408 if (atomic_read(&cnet->count) < nf_conntrack_max95) 1405 1409 continue; 1406 1410 ··· 1480 1484 const struct nf_conntrack_tuple *repl, 1481 1485 gfp_t gfp, u32 hash) 1482 1486 { 1483 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 1487 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 1484 1488 unsigned int ct_count; 1485 1489 struct nf_conn *ct; 1486 1490 ··· 1552 1556 1553 1557 nf_ct_ext_destroy(ct); 1554 1558 kmem_cache_free(nf_conntrack_cachep, ct); 1555 - cnet = net_generic(net, nf_conntrack_net_id); 1559 + cnet = nf_ct_pernet(net); 1556 1560 1557 1561 smp_mb__before_atomic(); 1558 1562 atomic_dec(&cnet->count); ··· 1610 1614 GFP_ATOMIC); 1611 1615 1612 1616 local_bh_disable(); 1613 - cnet = net_generic(net, nf_conntrack_net_id); 1617 + cnet = nf_ct_pernet(net); 1614 1618 if (cnet->expect_count) { 1615 1619 spin_lock(&nf_conntrack_expect_lock); 1616 1620 exp = nf_ct_find_expectation(net, zone, tuple); ··· 2313 2317 2314 2318 void nf_ct_unconfirmed_destroy(struct net *net) 2315 2319 { 2316 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 2320 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 2317 2321 2318 2322 might_sleep(); 2319 2323 ··· 2329 2333 int (*iter)(struct nf_conn *i, void *data), 2330 2334 void *data, u32 portid, int report) 2331 2335 { 2332 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 2336 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 2333 2337 struct iter_data d; 2334 2338 2335 2339 might_sleep(); ··· 2363 2367 2364 2368 down_read(&net_rwsem); 2365 2369 for_each_net(net) { 2366 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 2370 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 2367 2371 2368 2372 if (atomic_read(&cnet->count) == 0) 2369 2373 continue; ··· 2445 2449 i_see_dead_people: 2446 2450 busy = 0; 2447 2451 list_for_each_entry(net, net_exit_list, exit_list) { 2448 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 2452 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 2449 2453 2450 2454 nf_ct_iterate_cleanup(kill_all, net, 0, 0); 2451 2455 if (atomic_read(&cnet->count) != 0) ··· 2729 2733 2730 2734 int nf_conntrack_init_net(struct net *net) 2731 2735 { 2732 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 2736 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 2733 2737 int ret = -ENOMEM; 2734 2738 int cpu; 2735 2739
+3 -5
net/netfilter/nf_conntrack_ecache.c
··· 27 27 #include <net/netfilter/nf_conntrack_ecache.h> 28 28 #include <net/netfilter/nf_conntrack_extend.h> 29 29 30 - extern unsigned int nf_conntrack_net_id; 31 - 32 30 static DEFINE_MUTEX(nf_ct_ecache_mutex); 33 31 34 32 #define ECACHE_RETRY_WAIT (HZ/10) ··· 346 348 347 349 void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state) 348 350 { 349 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 351 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 350 352 351 353 if (state == NFCT_ECACHE_DESTROY_FAIL && 352 354 !delayed_work_pending(&cnet->ecache_dwork)) { ··· 369 371 370 372 void nf_conntrack_ecache_pernet_init(struct net *net) 371 373 { 372 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 374 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 373 375 374 376 net->ct.sysctl_events = nf_ct_events; 375 377 cnet->ct_net = &net->ct; ··· 378 380 379 381 void nf_conntrack_ecache_pernet_fini(struct net *net) 380 382 { 381 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 383 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 382 384 383 385 cancel_delayed_work_sync(&cnet->ecache_dwork); 384 386 }
+5 -7
net/netfilter/nf_conntrack_expect.c
··· 43 43 static struct kmem_cache *nf_ct_expect_cachep __read_mostly; 44 44 static unsigned int nf_ct_expect_hashrnd __read_mostly; 45 45 46 - extern unsigned int nf_conntrack_net_id; 47 - 48 46 /* nf_conntrack_expect helper functions */ 49 47 void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, 50 48 u32 portid, int report) ··· 56 58 57 59 hlist_del_rcu(&exp->hnode); 58 60 59 - cnet = net_generic(net, nf_conntrack_net_id); 61 + cnet = nf_ct_pernet(net); 60 62 cnet->expect_count--; 61 63 62 64 hlist_del_rcu(&exp->lnode); ··· 121 123 const struct nf_conntrack_zone *zone, 122 124 const struct nf_conntrack_tuple *tuple) 123 125 { 124 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 126 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 125 127 struct nf_conntrack_expect *i; 126 128 unsigned int h; 127 129 ··· 162 164 const struct nf_conntrack_zone *zone, 163 165 const struct nf_conntrack_tuple *tuple) 164 166 { 165 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 167 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 166 168 struct nf_conntrack_expect *i, *exp = NULL; 167 169 unsigned int h; 168 170 ··· 395 397 master_help->expecting[exp->class]++; 396 398 397 399 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); 398 - cnet = net_generic(net, nf_conntrack_net_id); 400 + cnet = nf_ct_pernet(net); 399 401 cnet->expect_count++; 400 402 401 403 NF_CT_STAT_INC(net, expect_create); ··· 466 468 } 467 469 } 468 470 469 - cnet = net_generic(net, nf_conntrack_net_id); 471 + cnet = nf_ct_pernet(net); 470 472 if (cnet->expect_count >= nf_ct_expect_max) { 471 473 net_warn_ratelimited("nf_conntrack: expectation table full\n"); 472 474 ret = -EMFILE;
+2 -4
net/netfilter/nf_conntrack_helper.c
··· 43 43 static DEFINE_MUTEX(nf_ct_nat_helpers_mutex); 44 44 static struct list_head nf_ct_nat_helpers __read_mostly; 45 45 46 - extern unsigned int nf_conntrack_net_id; 47 - 48 46 /* Stupid hash, but collision free for the default registrations of the 49 47 * helpers currently in the kernel. */ 50 48 static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple) ··· 212 214 static struct nf_conntrack_helper * 213 215 nf_ct_lookup_helper(struct nf_conn *ct, struct net *net) 214 216 { 215 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 217 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 216 218 217 219 if (!cnet->sysctl_auto_assign_helper) { 218 220 if (cnet->auto_assign_helper_warned) ··· 558 560 559 561 void nf_conntrack_helper_pernet_init(struct net *net) 560 562 { 561 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 563 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 562 564 563 565 cnet->sysctl_auto_assign_helper = nf_ct_auto_assign_helper; 564 566 }
+9 -14
net/netfilter/nf_conntrack_netlink.c
··· 1528 1528 const struct nfnl_info *info, 1529 1529 const struct nlattr * const cda[]) 1530 1530 { 1531 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1531 + u8 family = info->nfmsg->nfgen_family; 1532 1532 struct nf_conntrack_tuple_hash *h; 1533 1533 struct nf_conntrack_tuple tuple; 1534 1534 struct nf_conntrack_zone zone; ··· 1541 1541 1542 1542 if (cda[CTA_TUPLE_ORIG]) 1543 1543 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, 1544 - nfmsg->nfgen_family, &zone); 1544 + family, &zone); 1545 1545 else if (cda[CTA_TUPLE_REPLY]) 1546 1546 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, 1547 - nfmsg->nfgen_family, &zone); 1547 + family, &zone); 1548 1548 else { 1549 - u_int8_t u3 = nfmsg->version ? nfmsg->nfgen_family : AF_UNSPEC; 1549 + u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC; 1550 1550 1551 1551 return ctnetlink_flush_conntrack(info->net, cda, 1552 1552 NETLINK_CB(skb).portid, ··· 1586 1586 const struct nfnl_info *info, 1587 1587 const struct nlattr * const cda[]) 1588 1588 { 1589 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1590 - u_int8_t u3 = nfmsg->nfgen_family; 1589 + u_int8_t u3 = info->nfmsg->nfgen_family; 1591 1590 struct nf_conntrack_tuple_hash *h; 1592 1591 struct nf_conntrack_tuple tuple; 1593 1592 struct nf_conntrack_zone zone; ··· 2362 2363 const struct nfnl_info *info, 2363 2364 const struct nlattr * const cda[]) 2364 2365 { 2365 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 2366 2366 struct nf_conntrack_tuple otuple, rtuple; 2367 2367 struct nf_conntrack_tuple_hash *h = NULL; 2368 - u_int8_t u3 = nfmsg->nfgen_family; 2368 + u_int8_t u3 = info->nfmsg->nfgen_family; 2369 2369 struct nf_conntrack_zone zone; 2370 2370 struct nf_conn *ct; 2371 2371 int err; ··· 3257 3259 const struct nfnl_info *info, 3258 3260 const struct nlattr * const cda[]) 3259 3261 { 3260 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3261 - u_int8_t u3 = nfmsg->nfgen_family; 3262 + u_int8_t u3 = info->nfmsg->nfgen_family; 3262 3263 struct nf_conntrack_tuple tuple; 3263 3264 struct nf_conntrack_expect *exp; 3264 3265 struct nf_conntrack_zone zone; ··· 3346 3349 const struct nfnl_info *info, 3347 3350 const struct nlattr * const cda[]) 3348 3351 { 3349 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3350 - u_int8_t u3 = nfmsg->nfgen_family; 3352 + u_int8_t u3 = info->nfmsg->nfgen_family; 3351 3353 struct nf_conntrack_expect *exp; 3352 3354 struct nf_conntrack_tuple tuple; 3353 3355 struct nf_conntrack_zone zone; ··· 3597 3601 const struct nfnl_info *info, 3598 3602 const struct nlattr * const cda[]) 3599 3603 { 3600 - struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3601 - u_int8_t u3 = nfmsg->nfgen_family; 3604 + u_int8_t u3 = info->nfmsg->nfgen_family; 3602 3605 struct nf_conntrack_tuple tuple; 3603 3606 struct nf_conntrack_expect *exp; 3604 3607 struct nf_conntrack_zone zone;
+2 -4
net/netfilter/nf_conntrack_proto.c
··· 42 42 #include <net/ipv6.h> 43 43 #include <net/inet_frag.h> 44 44 45 - extern unsigned int nf_conntrack_net_id; 46 - 47 45 static DEFINE_MUTEX(nf_ct_proto_mutex); 48 46 49 47 #ifdef CONFIG_SYSCTL ··· 444 446 445 447 static int nf_ct_netns_do_get(struct net *net, u8 nfproto) 446 448 { 447 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 449 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 448 450 bool fixup_needed = false, retry = true; 449 451 int err = 0; 450 452 retry: ··· 529 531 530 532 static void nf_ct_netns_do_put(struct net *net, u8 nfproto) 531 533 { 532 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 534 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 533 535 534 536 mutex_lock(&nf_ct_proto_mutex); 535 537 switch (nfproto) {
+5
net/netfilter/nf_conntrack_proto_tcp.c
··· 1441 1441 * will be started. 1442 1442 */ 1443 1443 tn->tcp_max_retrans = 3; 1444 + 1445 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 1446 + tn->offload_timeout = 30 * HZ; 1447 + tn->offload_pickup = 120 * HZ; 1448 + #endif 1444 1449 } 1445 1450 1446 1451 const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp =
+5
net/netfilter/nf_conntrack_proto_udp.c
··· 270 270 271 271 for (i = 0; i < UDP_CT_MAX; i++) 272 272 un->timeouts[i] = udp_timeouts[i]; 273 + 274 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 275 + un->offload_timeout = 30 * HZ; 276 + un->offload_pickup = 30 * HZ; 277 + #endif 273 278 } 274 279 275 280 const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp =
+49 -5
net/netfilter/nf_conntrack_standalone.c
··· 512 512 513 513 u32 nf_conntrack_count(const struct net *net) 514 514 { 515 - const struct nf_conntrack_net *cnet; 516 - 517 - cnet = net_generic(net, nf_conntrack_net_id); 515 + const struct nf_conntrack_net *cnet = nf_ct_pernet(net); 518 516 519 517 return atomic_read(&cnet->count); 520 518 } ··· 573 575 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_CLOSE, 574 576 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_RETRANS, 575 577 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_UNACK, 578 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 579 + NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD, 580 + NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD_PICKUP, 581 + #endif 576 582 NF_SYSCTL_CT_PROTO_TCP_LOOSE, 577 583 NF_SYSCTL_CT_PROTO_TCP_LIBERAL, 578 584 NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, 579 585 NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, 580 586 NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM, 587 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 588 + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD, 589 + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD_PICKUP, 590 + #endif 581 591 NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP, 582 592 NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6, 583 593 #ifdef CONFIG_NF_CT_PROTO_SCTP ··· 768 762 .mode = 0644, 769 763 .proc_handler = proc_dointvec_jiffies, 770 764 }, 765 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 766 + [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD] = { 767 + .procname = "nf_flowtable_tcp_timeout", 768 + .maxlen = sizeof(unsigned int), 769 + .mode = 0644, 770 + .proc_handler = proc_dointvec_jiffies, 771 + }, 772 + [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD_PICKUP] = { 773 + .procname = "nf_flowtable_tcp_pickup", 774 + .maxlen = sizeof(unsigned int), 775 + .mode = 0644, 776 + .proc_handler = proc_dointvec_jiffies, 777 + }, 778 + #endif 771 779 [NF_SYSCTL_CT_PROTO_TCP_LOOSE] = { 772 780 .procname = "nf_conntrack_tcp_loose", 773 781 .maxlen = sizeof(u8), ··· 816 796 .mode = 0644, 817 797 .proc_handler = proc_dointvec_jiffies, 818 798 }, 799 + #if IS_ENABLED(CONFIG_NFT_FLOW_OFFLOAD) 800 + [NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD] = { 801 + .procname = "nf_flowtable_udp_timeout", 802 + .maxlen = sizeof(unsigned int), 803 + .mode = 0644, 804 + .proc_handler = proc_dointvec_jiffies, 805 + }, 806 + [NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD_PICKUP] = { 807 + .procname = "nf_flowtable_udp_pickup", 808 + .maxlen = sizeof(unsigned int), 809 + .mode = 0644, 810 + .proc_handler = proc_dointvec_jiffies, 811 + }, 812 + #endif 819 813 [NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP] = { 820 814 .procname = "nf_conntrack_icmp_timeout", 821 815 .maxlen = sizeof(unsigned int), ··· 1005 971 XASSIGN(LIBERAL, &tn->tcp_be_liberal); 1006 972 XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); 1007 973 #undef XASSIGN 974 + 975 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 976 + table[NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD].data = &tn->offload_timeout; 977 + table[NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD_PICKUP].data = &tn->offload_pickup; 978 + #endif 979 + 1008 980 } 1009 981 1010 982 static void nf_conntrack_standalone_init_sctp_sysctl(struct net *net, ··· 1072 1032 1073 1033 static int nf_conntrack_standalone_init_sysctl(struct net *net) 1074 1034 { 1075 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 1035 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 1076 1036 struct nf_udp_net *un = nf_udp_pernet(net); 1077 1037 struct ctl_table *table; 1078 1038 ··· 1099 1059 table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6].data = &nf_icmpv6_pernet(net)->timeout; 1100 1060 table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP].data = &un->timeouts[UDP_CT_UNREPLIED]; 1101 1061 table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM].data = &un->timeouts[UDP_CT_REPLIED]; 1062 + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 1063 + table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD].data = &un->offload_timeout; 1064 + table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD_PICKUP].data = &un->offload_pickup; 1065 + #endif 1102 1066 1103 1067 nf_conntrack_standalone_init_tcp_sysctl(net, table); 1104 1068 nf_conntrack_standalone_init_sctp_sysctl(net, table); ··· 1129 1085 1130 1086 static void nf_conntrack_standalone_fini_sysctl(struct net *net) 1131 1087 { 1132 - struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id); 1088 + struct nf_conntrack_net *cnet = nf_ct_pernet(net); 1133 1089 struct ctl_table *table; 1134 1090 1135 1091 table = cnet->sysctl_header->ctl_table_arg;
+37 -10
net/netfilter/nf_flow_table_core.c
··· 178 178 tcp->seen[1].td_maxwin = 0; 179 179 } 180 180 181 - #define NF_FLOWTABLE_TCP_PICKUP_TIMEOUT (120 * HZ) 182 - #define NF_FLOWTABLE_UDP_PICKUP_TIMEOUT (30 * HZ) 183 - 184 181 static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) 185 182 { 186 183 const struct nf_conntrack_l4proto *l4proto; 184 + struct net *net = nf_ct_net(ct); 187 185 int l4num = nf_ct_protonum(ct); 188 186 unsigned int timeout; 189 187 ··· 189 191 if (!l4proto) 190 192 return; 191 193 192 - if (l4num == IPPROTO_TCP) 193 - timeout = NF_FLOWTABLE_TCP_PICKUP_TIMEOUT; 194 - else if (l4num == IPPROTO_UDP) 195 - timeout = NF_FLOWTABLE_UDP_PICKUP_TIMEOUT; 196 - else 194 + if (l4num == IPPROTO_TCP) { 195 + struct nf_tcp_net *tn = nf_tcp_pernet(net); 196 + 197 + timeout = tn->offload_pickup; 198 + } else if (l4num == IPPROTO_UDP) { 199 + struct nf_udp_net *tn = nf_udp_pernet(net); 200 + 201 + timeout = tn->offload_pickup; 202 + } else { 197 203 return; 204 + } 198 205 199 206 if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout) 200 207 ct->timeout = nfct_time_stamp + timeout; ··· 271 268 .automatic_shrinking = true, 272 269 }; 273 270 271 + unsigned long flow_offload_get_timeout(struct flow_offload *flow) 272 + { 273 + const struct nf_conntrack_l4proto *l4proto; 274 + unsigned long timeout = NF_FLOW_TIMEOUT; 275 + struct net *net = nf_ct_net(flow->ct); 276 + int l4num = nf_ct_protonum(flow->ct); 277 + 278 + l4proto = nf_ct_l4proto_find(l4num); 279 + if (!l4proto) 280 + return timeout; 281 + 282 + if (l4num == IPPROTO_TCP) { 283 + struct nf_tcp_net *tn = nf_tcp_pernet(net); 284 + 285 + timeout = tn->offload_timeout; 286 + } else if (l4num == IPPROTO_UDP) { 287 + struct nf_udp_net *tn = nf_udp_pernet(net); 288 + 289 + timeout = tn->offload_timeout; 290 + } 291 + 292 + return timeout; 293 + } 294 + 274 295 int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) 275 296 { 276 297 int err; 277 298 278 - flow->timeout = nf_flowtable_time_stamp + NF_FLOW_TIMEOUT; 299 + flow->timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow); 279 300 280 301 err = rhashtable_insert_fast(&flow_table->rhashtable, 281 302 &flow->tuplehash[0].node, ··· 331 304 void flow_offload_refresh(struct nf_flowtable *flow_table, 332 305 struct flow_offload *flow) 333 306 { 334 - flow->timeout = nf_flowtable_time_stamp + NF_FLOW_TIMEOUT; 307 + flow->timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow); 335 308 336 309 if (likely(!nf_flowtable_hw_offload(flow_table))) 337 310 return;
+2 -2
net/netfilter/nf_flow_table_offload.c
··· 937 937 938 938 lastused = max_t(u64, stats[0].lastused, stats[1].lastused); 939 939 offload->flow->timeout = max_t(u64, offload->flow->timeout, 940 - lastused + NF_FLOW_TIMEOUT); 940 + lastused + flow_offload_get_timeout(offload->flow)); 941 941 942 942 if (offload->flowtable->flags & NF_FLOWTABLE_COUNTER) { 943 943 if (stats[0].pkts) ··· 1041 1041 __s32 delta; 1042 1042 1043 1043 delta = nf_flow_timeout_delta(flow->timeout); 1044 - if ((delta >= (9 * NF_FLOW_TIMEOUT) / 10)) 1044 + if ((delta >= (9 * flow_offload_get_timeout(flow)) / 10)) 1045 1045 return; 1046 1046 1047 1047 offload = nf_flow_offload_work_alloc(flowtable, flow, FLOW_CLS_STATS);
+84 -118
net/netfilter/nf_tables_api.c
··· 862 862 static int nf_tables_gettable(struct sk_buff *skb, const struct nfnl_info *info, 863 863 const struct nlattr * const nla[]) 864 864 { 865 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 866 865 struct netlink_ext_ack *extack = info->extack; 867 866 u8 genmask = nft_genmask_cur(info->net); 868 - int family = nfmsg->nfgen_family; 867 + u8 family = info->nfmsg->nfgen_family; 869 868 const struct nft_table *table; 870 869 struct net *net = info->net; 871 870 struct sk_buff *skb2; ··· 1067 1068 const struct nlattr * const nla[]) 1068 1069 { 1069 1070 struct nftables_pernet *nft_net = nft_pernet(info->net); 1070 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1071 1071 struct netlink_ext_ack *extack = info->extack; 1072 1072 u8 genmask = nft_genmask_next(info->net); 1073 - int family = nfmsg->nfgen_family; 1073 + u8 family = info->nfmsg->nfgen_family; 1074 1074 struct net *net = info->net; 1075 1075 const struct nlattr *attr; 1076 1076 struct nft_table *table; ··· 1261 1263 static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info, 1262 1264 const struct nlattr * const nla[]) 1263 1265 { 1264 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1265 1266 struct netlink_ext_ack *extack = info->extack; 1266 1267 u8 genmask = nft_genmask_next(info->net); 1267 - int family = nfmsg->nfgen_family; 1268 + u8 family = info->nfmsg->nfgen_family; 1268 1269 struct net *net = info->net; 1269 1270 const struct nlattr *attr; 1270 1271 struct nft_table *table; ··· 1633 1636 static int nf_tables_getchain(struct sk_buff *skb, const struct nfnl_info *info, 1634 1637 const struct nlattr * const nla[]) 1635 1638 { 1636 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1637 1639 struct netlink_ext_ack *extack = info->extack; 1638 1640 u8 genmask = nft_genmask_cur(info->net); 1639 - int family = nfmsg->nfgen_family; 1641 + u8 family = info->nfmsg->nfgen_family; 1640 1642 const struct nft_chain *chain; 1641 1643 struct net *net = info->net; 1642 1644 struct nft_table *table; ··· 2011 2015 const struct nft_chain_hook *hook, 2012 2016 struct nft_chain *chain) 2013 2017 { 2014 - ops->pf = family; 2015 - ops->hooknum = hook->num; 2016 - ops->priority = hook->priority; 2017 - ops->priv = chain; 2018 - ops->hook = hook->type->hooks[ops->hooknum]; 2018 + ops->pf = family; 2019 + ops->hooknum = hook->num; 2020 + ops->priority = hook->priority; 2021 + ops->priv = chain; 2022 + ops->hook = hook->type->hooks[ops->hooknum]; 2023 + ops->hook_ops_type = NF_HOOK_OP_NF_TABLES; 2019 2024 } 2020 2025 2021 2026 static int nft_basechain_init(struct nft_base_chain *basechain, u8 family, ··· 2368 2371 const struct nlattr * const nla[]) 2369 2372 { 2370 2373 struct nftables_pernet *nft_net = nft_pernet(info->net); 2371 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 2372 2374 struct netlink_ext_ack *extack = info->extack; 2373 2375 u8 genmask = nft_genmask_next(info->net); 2374 - int family = nfmsg->nfgen_family; 2376 + u8 family = info->nfmsg->nfgen_family; 2375 2377 struct nft_chain *chain = NULL; 2376 2378 struct net *net = info->net; 2377 2379 const struct nlattr *attr; ··· 2465 2469 static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info, 2466 2470 const struct nlattr * const nla[]) 2467 2471 { 2468 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 2469 2472 struct netlink_ext_ack *extack = info->extack; 2470 2473 u8 genmask = nft_genmask_next(info->net); 2471 - int family = nfmsg->nfgen_family; 2474 + u8 family = info->nfmsg->nfgen_family; 2472 2475 struct net *net = info->net; 2473 2476 const struct nlattr *attr; 2474 2477 struct nft_table *table; ··· 3091 3096 static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, 3092 3097 const struct nlattr * const nla[]) 3093 3098 { 3094 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3095 3099 struct netlink_ext_ack *extack = info->extack; 3096 3100 u8 genmask = nft_genmask_cur(info->net); 3097 - int family = nfmsg->nfgen_family; 3101 + u8 family = info->nfmsg->nfgen_family; 3098 3102 const struct nft_chain *chain; 3099 3103 const struct nft_rule *rule; 3100 3104 struct net *net = info->net; ··· 3231 3237 const struct nlattr * const nla[]) 3232 3238 { 3233 3239 struct nftables_pernet *nft_net = nft_pernet(info->net); 3234 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3235 3240 struct netlink_ext_ack *extack = info->extack; 3236 3241 unsigned int size, i, n, ulen = 0, usize = 0; 3237 3242 u8 genmask = nft_genmask_next(info->net); 3238 3243 struct nft_rule *rule, *old_rule = NULL; 3239 3244 struct nft_expr_info *expr_info = NULL; 3240 - int family = nfmsg->nfgen_family; 3245 + u8 family = info->nfmsg->nfgen_family; 3241 3246 struct net *net = info->net; 3242 3247 struct nft_flow_rule *flow; 3243 3248 struct nft_userdata *udata; ··· 3470 3477 static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, 3471 3478 const struct nlattr * const nla[]) 3472 3479 { 3473 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3474 3480 struct netlink_ext_ack *extack = info->extack; 3475 - int family = nfmsg->nfgen_family, err = 0; 3476 3481 u8 genmask = nft_genmask_next(info->net); 3482 + u8 family = info->nfmsg->nfgen_family; 3477 3483 struct nft_chain *chain = NULL; 3478 3484 struct net *net = info->net; 3479 3485 struct nft_table *table; 3480 3486 struct nft_rule *rule; 3481 3487 struct nft_ctx ctx; 3488 + int err = 0; 3482 3489 3483 3490 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask, 3484 3491 NETLINK_CB(skb).portid); ··· 3657 3664 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 }, 3658 3665 [NFTA_SET_DESC_CONCAT] = { .type = NLA_NESTED }, 3659 3666 }; 3660 - 3661 - static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net, 3662 - const struct sk_buff *skb, 3663 - const struct nlmsghdr *nlh, 3664 - const struct nlattr * const nla[], 3665 - struct netlink_ext_ack *extack, 3666 - u8 genmask, u32 nlpid) 3667 - { 3668 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3669 - int family = nfmsg->nfgen_family; 3670 - struct nft_table *table = NULL; 3671 - 3672 - if (nla[NFTA_SET_TABLE] != NULL) { 3673 - table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family, 3674 - genmask, nlpid); 3675 - if (IS_ERR(table)) { 3676 - NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]); 3677 - return PTR_ERR(table); 3678 - } 3679 - } 3680 - 3681 - nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); 3682 - return 0; 3683 - } 3684 3667 3685 3668 static struct nft_set *nft_set_lookup(const struct nft_table *table, 3686 3669 const struct nlattr *nla, u8 genmask) ··· 4037 4068 static int nf_tables_getset(struct sk_buff *skb, const struct nfnl_info *info, 4038 4069 const struct nlattr * const nla[]) 4039 4070 { 4040 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 4041 4071 struct netlink_ext_ack *extack = info->extack; 4042 4072 u8 genmask = nft_genmask_cur(info->net); 4073 + u8 family = info->nfmsg->nfgen_family; 4074 + struct nft_table *table = NULL; 4043 4075 struct net *net = info->net; 4044 4076 const struct nft_set *set; 4045 4077 struct sk_buff *skb2; 4046 4078 struct nft_ctx ctx; 4047 4079 int err; 4048 4080 4049 - /* Verify existence before starting dump */ 4050 - err = nft_ctx_init_from_setattr(&ctx, net, skb, info->nlh, nla, extack, 4051 - genmask, 0); 4052 - if (err < 0) 4053 - return err; 4081 + if (nla[NFTA_SET_TABLE]) { 4082 + table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family, 4083 + genmask, 0); 4084 + if (IS_ERR(table)) { 4085 + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]); 4086 + return PTR_ERR(table); 4087 + } 4088 + } 4089 + 4090 + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); 4054 4091 4055 4092 if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 4056 4093 struct netlink_dump_control c = { ··· 4071 4096 } 4072 4097 4073 4098 /* Only accept unspec with dump */ 4074 - if (nfmsg->nfgen_family == NFPROTO_UNSPEC) 4099 + if (info->nfmsg->nfgen_family == NFPROTO_UNSPEC) 4075 4100 return -EAFNOSUPPORT; 4076 4101 if (!nla[NFTA_SET_TABLE]) 4077 4102 return -EINVAL; 4078 4103 4079 - set = nft_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); 4104 + set = nft_set_lookup(table, nla[NFTA_SET_NAME], genmask); 4080 4105 if (IS_ERR(set)) 4081 4106 return PTR_ERR(set); 4082 4107 ··· 4164 4189 static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, 4165 4190 const struct nlattr * const nla[]) 4166 4191 { 4167 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 4168 4192 u32 ktype, dtype, flags, policy, gc_int, objtype; 4169 4193 struct netlink_ext_ack *extack = info->extack; 4170 4194 u8 genmask = nft_genmask_next(info->net); 4171 - int family = nfmsg->nfgen_family; 4195 + u8 family = info->nfmsg->nfgen_family; 4172 4196 const struct nft_set_ops *ops; 4173 4197 struct nft_expr *expr = NULL; 4174 4198 struct net *net = info->net; ··· 4467 4493 static int nf_tables_delset(struct sk_buff *skb, const struct nfnl_info *info, 4468 4494 const struct nlattr * const nla[]) 4469 4495 { 4470 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 4471 4496 struct netlink_ext_ack *extack = info->extack; 4472 4497 u8 genmask = nft_genmask_next(info->net); 4498 + u8 family = info->nfmsg->nfgen_family; 4473 4499 struct net *net = info->net; 4474 4500 const struct nlattr *attr; 4501 + struct nft_table *table; 4475 4502 struct nft_set *set; 4476 4503 struct nft_ctx ctx; 4477 - int err; 4478 4504 4479 - if (nfmsg->nfgen_family == NFPROTO_UNSPEC) 4505 + if (info->nfmsg->nfgen_family == NFPROTO_UNSPEC) 4480 4506 return -EAFNOSUPPORT; 4481 - if (nla[NFTA_SET_TABLE] == NULL) 4482 - return -EINVAL; 4483 4507 4484 - err = nft_ctx_init_from_setattr(&ctx, net, skb, info->nlh, nla, extack, 4485 - genmask, NETLINK_CB(skb).portid); 4486 - if (err < 0) 4487 - return err; 4508 + table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family, 4509 + genmask, NETLINK_CB(skb).portid); 4510 + if (IS_ERR(table)) { 4511 + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]); 4512 + return PTR_ERR(table); 4513 + } 4488 4514 4489 4515 if (nla[NFTA_SET_HANDLE]) { 4490 4516 attr = nla[NFTA_SET_HANDLE]; 4491 - set = nft_set_lookup_byhandle(ctx.table, attr, genmask); 4517 + set = nft_set_lookup_byhandle(table, attr, genmask); 4492 4518 } else { 4493 4519 attr = nla[NFTA_SET_NAME]; 4494 - set = nft_set_lookup(ctx.table, attr, genmask); 4520 + set = nft_set_lookup(table, attr, genmask); 4495 4521 } 4496 4522 4497 4523 if (IS_ERR(set)) { ··· 4504 4530 NL_SET_BAD_ATTR(extack, attr); 4505 4531 return -EBUSY; 4506 4532 } 4533 + 4534 + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); 4507 4535 4508 4536 return nft_delset(&ctx, set); 4509 4537 } ··· 4707 4731 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED }, 4708 4732 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 }, 4709 4733 }; 4710 - 4711 - static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, 4712 - const struct sk_buff *skb, 4713 - const struct nlmsghdr *nlh, 4714 - const struct nlattr * const nla[], 4715 - struct netlink_ext_ack *extack, 4716 - u8 genmask, u32 nlpid) 4717 - { 4718 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 4719 - int family = nfmsg->nfgen_family; 4720 - struct nft_table *table; 4721 - 4722 - table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family, 4723 - genmask, nlpid); 4724 - if (IS_ERR(table)) { 4725 - NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]); 4726 - return PTR_ERR(table); 4727 - } 4728 - 4729 - nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); 4730 - return 0; 4731 - } 4732 4734 4733 4735 static int nft_set_elem_expr_dump(struct sk_buff *skb, 4734 4736 const struct nft_set *set, ··· 5165 5211 { 5166 5212 struct netlink_ext_ack *extack = info->extack; 5167 5213 u8 genmask = nft_genmask_cur(info->net); 5214 + u8 family = info->nfmsg->nfgen_family; 5168 5215 struct net *net = info->net; 5216 + struct nft_table *table; 5169 5217 struct nft_set *set; 5170 5218 struct nlattr *attr; 5171 5219 struct nft_ctx ctx; 5172 5220 int rem, err = 0; 5173 5221 5174 - err = nft_ctx_init_from_elemattr(&ctx, net, skb, info->nlh, nla, extack, 5175 - genmask, NETLINK_CB(skb).portid); 5176 - if (err < 0) 5177 - return err; 5222 + table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family, 5223 + genmask, NETLINK_CB(skb).portid); 5224 + if (IS_ERR(table)) { 5225 + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]); 5226 + return PTR_ERR(table); 5227 + } 5178 5228 5179 - set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask); 5229 + set = nft_set_lookup(table, nla[NFTA_SET_ELEM_LIST_SET], genmask); 5180 5230 if (IS_ERR(set)) 5181 5231 return PTR_ERR(set); 5232 + 5233 + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); 5182 5234 5183 5235 if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 5184 5236 struct netlink_dump_control c = { ··· 5954 5994 struct nftables_pernet *nft_net = nft_pernet(info->net); 5955 5995 struct netlink_ext_ack *extack = info->extack; 5956 5996 u8 genmask = nft_genmask_next(info->net); 5997 + u8 family = info->nfmsg->nfgen_family; 5957 5998 struct net *net = info->net; 5958 5999 const struct nlattr *attr; 6000 + struct nft_table *table; 5959 6001 struct nft_set *set; 5960 6002 struct nft_ctx ctx; 5961 6003 int rem, err; ··· 5965 6003 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 5966 6004 return -EINVAL; 5967 6005 5968 - err = nft_ctx_init_from_elemattr(&ctx, net, skb, info->nlh, nla, extack, 5969 - genmask, NETLINK_CB(skb).portid); 5970 - if (err < 0) 5971 - return err; 6006 + table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family, 6007 + genmask, NETLINK_CB(skb).portid); 6008 + if (IS_ERR(table)) { 6009 + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]); 6010 + return PTR_ERR(table); 6011 + } 5972 6012 5973 - set = nft_set_lookup_global(net, ctx.table, nla[NFTA_SET_ELEM_LIST_SET], 6013 + set = nft_set_lookup_global(net, table, nla[NFTA_SET_ELEM_LIST_SET], 5974 6014 nla[NFTA_SET_ELEM_LIST_SET_ID], genmask); 5975 6015 if (IS_ERR(set)) 5976 6016 return PTR_ERR(set); 5977 6017 5978 6018 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT) 5979 6019 return -EBUSY; 6020 + 6021 + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); 5980 6022 5981 6023 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { 5982 6024 err = nft_add_set_elem(&ctx, set, attr, info->nlh->nlmsg_flags); ··· 5989 6023 } 5990 6024 5991 6025 if (nft_net->validate_state == NFT_VALIDATE_DO) 5992 - return nft_table_validate(net, ctx.table); 6026 + return nft_table_validate(net, table); 5993 6027 5994 6028 return 0; 5995 6029 } ··· 6227 6261 { 6228 6262 struct netlink_ext_ack *extack = info->extack; 6229 6263 u8 genmask = nft_genmask_next(info->net); 6264 + u8 family = info->nfmsg->nfgen_family; 6230 6265 struct net *net = info->net; 6231 6266 const struct nlattr *attr; 6267 + struct nft_table *table; 6232 6268 struct nft_set *set; 6233 6269 struct nft_ctx ctx; 6234 6270 int rem, err = 0; 6235 6271 6236 - err = nft_ctx_init_from_elemattr(&ctx, net, skb, info->nlh, nla, extack, 6237 - genmask, NETLINK_CB(skb).portid); 6238 - if (err < 0) 6239 - return err; 6272 + table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family, 6273 + genmask, NETLINK_CB(skb).portid); 6274 + if (IS_ERR(table)) { 6275 + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]); 6276 + return PTR_ERR(table); 6277 + } 6240 6278 6241 - set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask); 6279 + set = nft_set_lookup(table, nla[NFTA_SET_ELEM_LIST_SET], genmask); 6242 6280 if (IS_ERR(set)) 6243 6281 return PTR_ERR(set); 6244 6282 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT) 6245 6283 return -EBUSY; 6284 + 6285 + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); 6246 6286 6247 6287 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) 6248 6288 return nft_set_flush(&ctx, set, genmask); ··· 6517 6545 static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, 6518 6546 const struct nlattr * const nla[]) 6519 6547 { 6520 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 6521 6548 struct netlink_ext_ack *extack = info->extack; 6522 6549 u8 genmask = nft_genmask_next(info->net); 6550 + u8 family = info->nfmsg->nfgen_family; 6523 6551 const struct nft_object_type *type; 6524 - int family = nfmsg->nfgen_family; 6525 6552 struct net *net = info->net; 6526 6553 struct nft_table *table; 6527 6554 struct nft_object *obj; ··· 6772 6801 static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, 6773 6802 const struct nlattr * const nla[]) 6774 6803 { 6775 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 6776 6804 struct netlink_ext_ack *extack = info->extack; 6777 6805 u8 genmask = nft_genmask_cur(info->net); 6778 - int family = nfmsg->nfgen_family; 6806 + u8 family = info->nfmsg->nfgen_family; 6779 6807 const struct nft_table *table; 6780 6808 struct net *net = info->net; 6781 6809 struct nft_object *obj; ··· 6861 6891 static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, 6862 6892 const struct nlattr * const nla[]) 6863 6893 { 6864 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 6865 6894 struct netlink_ext_ack *extack = info->extack; 6866 6895 u8 genmask = nft_genmask_next(info->net); 6867 - int family = nfmsg->nfgen_family; 6896 + u8 family = info->nfmsg->nfgen_family; 6868 6897 struct net *net = info->net; 6869 6898 const struct nlattr *attr; 6870 6899 struct nft_table *table; ··· 7291 7322 const struct nfnl_info *info, 7292 7323 const struct nlattr * const nla[]) 7293 7324 { 7294 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 7295 7325 struct netlink_ext_ack *extack = info->extack; 7296 7326 struct nft_flowtable_hook flowtable_hook; 7297 7327 u8 genmask = nft_genmask_next(info->net); 7328 + u8 family = info->nfmsg->nfgen_family; 7298 7329 const struct nf_flowtable_type *type; 7299 - int family = nfmsg->nfgen_family; 7300 7330 struct nft_flowtable *flowtable; 7301 7331 struct nft_hook *hook, *next; 7302 7332 struct net *net = info->net; ··· 7479 7511 const struct nfnl_info *info, 7480 7512 const struct nlattr * const nla[]) 7481 7513 { 7482 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 7483 7514 struct netlink_ext_ack *extack = info->extack; 7484 7515 u8 genmask = nft_genmask_next(info->net); 7485 - int family = nfmsg->nfgen_family; 7516 + u8 family = info->nfmsg->nfgen_family; 7486 7517 struct nft_flowtable *flowtable; 7487 7518 struct net *net = info->net; 7488 7519 const struct nlattr *attr; ··· 7673 7706 const struct nfnl_info *info, 7674 7707 const struct nlattr * const nla[]) 7675 7708 { 7676 - const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 7677 7709 u8 genmask = nft_genmask_cur(info->net); 7678 - int family = nfmsg->nfgen_family; 7710 + u8 family = info->nfmsg->nfgen_family; 7679 7711 struct nft_flowtable *flowtable; 7680 7712 const struct nft_table *table; 7681 7713 struct net *net = info->net;
+3
net/netfilter/nfnetlink.c
··· 68 68 [NFNL_SUBSYS_CTHELPER] = "nfnl_subsys_cthelper", 69 69 [NFNL_SUBSYS_NFTABLES] = "nfnl_subsys_nftables", 70 70 [NFNL_SUBSYS_NFT_COMPAT] = "nfnl_subsys_nftcompat", 71 + [NFNL_SUBSYS_HOOK] = "nfnl_subsys_hook", 71 72 }; 72 73 73 74 static const int nfnl_group2type[NFNLGRP_MAX+1] = { ··· 257 256 .net = net, 258 257 .sk = nfnlnet->nfnl, 259 258 .nlh = nlh, 259 + .nfmsg = nlmsg_data(nlh), 260 260 .extack = extack, 261 261 }; 262 262 ··· 493 491 .net = net, 494 492 .sk = nfnlnet->nfnl, 495 493 .nlh = nlh, 494 + .nfmsg = nlmsg_data(nlh), 496 495 .extack = &extack, 497 496 }; 498 497
+6 -11
net/netfilter/nft_compat.c
··· 625 625 const struct nfnl_info *info, 626 626 const struct nlattr * const tb[]) 627 627 { 628 - struct nfgenmsg *nfmsg; 628 + u8 family = info->nfmsg->nfgen_family; 629 629 const char *name, *fmt; 630 630 struct sk_buff *skb2; 631 631 int ret = 0, target; ··· 640 640 rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV])); 641 641 target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE])); 642 642 643 - nfmsg = nlmsg_data(info->nlh); 644 - 645 - switch(nfmsg->nfgen_family) { 643 + switch(family) { 646 644 case AF_INET: 647 645 fmt = "ipt_%s"; 648 646 break; ··· 654 656 fmt = "arpt_%s"; 655 657 break; 656 658 default: 657 - pr_err("nft_compat: unsupported protocol %d\n", 658 - nfmsg->nfgen_family); 659 + pr_err("nft_compat: unsupported protocol %d\n", family); 659 660 return -EINVAL; 660 661 } 661 662 ··· 662 665 return -EINVAL; 663 666 664 667 rcu_read_unlock(); 665 - try_then_request_module(xt_find_revision(nfmsg->nfgen_family, name, 666 - rev, target, &ret), 667 - fmt, name); 668 + try_then_request_module(xt_find_revision(family, name, rev, target, &ret), 669 + fmt, name); 668 670 if (ret < 0) 669 671 goto out_put; 670 672 ··· 678 682 info->nlh->nlmsg_seq, 679 683 NFNL_MSG_TYPE(info->nlh->nlmsg_type), 680 684 NFNL_MSG_COMPAT_GET, 681 - nfmsg->nfgen_family, 682 - name, ret, target) <= 0) { 685 + family, name, ret, target) <= 0) { 683 686 kfree_skb(skb2); 684 687 goto out_put; 685 688 }
+3 -1
net/netfilter/nft_exthdr.c
··· 327 327 break; 328 328 329 329 dest[priv->len / NFT_REG32_SIZE] = 0; 330 - memcpy(dest, (char *)sch + priv->offset, priv->len); 330 + if (skb_copy_bits(pkt->skb, offset + priv->offset, 331 + dest, priv->len) < 0) 332 + break; 331 333 return; 332 334 } 333 335 offset += SCTP_PAD4(ntohs(sch->length));