aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-11-05 20:19:25 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-05 20:19:25 -0500
commita422757e8c323ae12163fa74bc21c41606a233df (patch)
tree02f0f9cd6f85d35991430d383a5d1c1dfdda0b27 /net
parent7131193157414ac3167d7b2f2feb4c42b415d6c5 (diff)
parentf393808dc64149ccd0e5a8427505ba2974a59854 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains the first batch of Netfilter fixes for your net tree: 1) Fix splat with IPv6 defragmenting locally generated fragments, from Florian Westphal. 2) Fix Incorrect check for missing attribute in nft_osf. 3) Missing INT_MIN & INT_MAX definition for netfilter bridge uapi header, from Jiri Slaby. 4) Revert map lookup in nft_numgen, this is already possible with the existing infrastructure without this extension. 5) Fix wrong listing of set reference counter, make counter synchronous again, from Stefano Brivio. 6) Fix CIDR 0 in hash:net,port,net, from Eric Westbrook. 7) Fix allocation failure with large set, use kvcalloc(). From Andrey Ryabinin. 8) No need to disable BH when fetch ip set comment, patch from Jozsef Kadlecsik. 9) Sanity check for valid sysfs entry in xt_IDLETIMER, from Taehee Yoo. 10) Fix suspicious rcu usage via ip_set() macro at netlink dump, from Jozsef Kadlecsik. 11) Fix setting default timeout via nfnetlink_cttimeout, this comes with preparation patch to add nf_{tcp,udp,...}_pernet() helper. 12) Allow ebtables table nat to be of filter type via nft_compat. From Florian Westphal. 13) Incorrect calculation of next bucket in early_drop, do no bump hash value, update bucket counter instead. From Vasily Khoruzhick. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c13
-rw-r--r--net/netfilter/ipset/ip_set_core.c43
-rw-r--r--net/netfilter/ipset/ip_set_hash_netportnet.c8
-rw-r--r--net/netfilter/ipset/ip_set_list_set.c17
-rw-r--r--net/netfilter/nf_conntrack_core.c13
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c13
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c11
-rw-r--r--net/netfilter/nf_conntrack_proto_icmp.c11
-rw-r--r--net/netfilter/nf_conntrack_proto_icmpv6.c11
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c11
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c15
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c11
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c47
-rw-r--r--net/netfilter/nft_compat.c21
-rw-r--r--net/netfilter/nft_numgen.c127
-rw-r--r--net/netfilter/nft_osf.c2
-rw-r--r--net/netfilter/xt_IDLETIMER.c20
17 files changed, 152 insertions, 242 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index b8ac369f98ad..d219979c3e52 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -587,11 +587,16 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
587 */ 587 */
588 ret = -EINPROGRESS; 588 ret = -EINPROGRESS;
589 if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && 589 if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
590 fq->q.meat == fq->q.len && 590 fq->q.meat == fq->q.len) {
591 nf_ct_frag6_reasm(fq, skb, dev)) 591 unsigned long orefdst = skb->_skb_refdst;
592 ret = 0; 592
593 else 593 skb->_skb_refdst = 0UL;
594 if (nf_ct_frag6_reasm(fq, skb, dev))
595 ret = 0;
596 skb->_skb_refdst = orefdst;
597 } else {
594 skb_dst_drop(skb); 598 skb_dst_drop(skb);
599 }
595 600
596out_unlock: 601out_unlock:
597 spin_unlock_bh(&fq->q.lock); 602 spin_unlock_bh(&fq->q.lock);
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index bc4bd247bb7d..1577f2f76060 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -55,11 +55,15 @@ MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
55MODULE_DESCRIPTION("core IP set support"); 55MODULE_DESCRIPTION("core IP set support");
56MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); 56MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET);
57 57
58/* When the nfnl mutex is held: */ 58/* When the nfnl mutex or ip_set_ref_lock is held: */
59#define ip_set_dereference(p) \ 59#define ip_set_dereference(p) \
60 rcu_dereference_protected(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) 60 rcu_dereference_protected(p, \
61 lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \
62 lockdep_is_held(&ip_set_ref_lock))
61#define ip_set(inst, id) \ 63#define ip_set(inst, id) \
62 ip_set_dereference((inst)->ip_set_list)[id] 64 ip_set_dereference((inst)->ip_set_list)[id]
65#define ip_set_ref_netlink(inst,id) \
66 rcu_dereference_raw((inst)->ip_set_list)[id]
63 67
64/* The set types are implemented in modules and registered set types 68/* The set types are implemented in modules and registered set types
65 * can be found in ip_set_type_list. Adding/deleting types is 69 * can be found in ip_set_type_list. Adding/deleting types is
@@ -693,21 +697,20 @@ ip_set_put_byindex(struct net *net, ip_set_id_t index)
693EXPORT_SYMBOL_GPL(ip_set_put_byindex); 697EXPORT_SYMBOL_GPL(ip_set_put_byindex);
694 698
695/* Get the name of a set behind a set index. 699/* Get the name of a set behind a set index.
696 * We assume the set is referenced, so it does exist and 700 * Set itself is protected by RCU, but its name isn't: to protect against
697 * can't be destroyed. The set cannot be renamed due to 701 * renaming, grab ip_set_ref_lock as reader (see ip_set_rename()) and copy the
698 * the referencing either. 702 * name.
699 *
700 */ 703 */
701const char * 704void
702ip_set_name_byindex(struct net *net, ip_set_id_t index) 705ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name)
703{ 706{
704 const struct ip_set *set = ip_set_rcu_get(net, index); 707 struct ip_set *set = ip_set_rcu_get(net, index);
705 708
706 BUG_ON(!set); 709 BUG_ON(!set);
707 BUG_ON(set->ref == 0);
708 710
709 /* Referenced, so it's safe */ 711 read_lock_bh(&ip_set_ref_lock);
710 return set->name; 712 strncpy(name, set->name, IPSET_MAXNAMELEN);
713 read_unlock_bh(&ip_set_ref_lock);
711} 714}
712EXPORT_SYMBOL_GPL(ip_set_name_byindex); 715EXPORT_SYMBOL_GPL(ip_set_name_byindex);
713 716
@@ -961,7 +964,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
961 /* Wraparound */ 964 /* Wraparound */
962 goto cleanup; 965 goto cleanup;
963 966
964 list = kcalloc(i, sizeof(struct ip_set *), GFP_KERNEL); 967 list = kvcalloc(i, sizeof(struct ip_set *), GFP_KERNEL);
965 if (!list) 968 if (!list)
966 goto cleanup; 969 goto cleanup;
967 /* nfnl mutex is held, both lists are valid */ 970 /* nfnl mutex is held, both lists are valid */
@@ -973,7 +976,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
973 /* Use new list */ 976 /* Use new list */
974 index = inst->ip_set_max; 977 index = inst->ip_set_max;
975 inst->ip_set_max = i; 978 inst->ip_set_max = i;
976 kfree(tmp); 979 kvfree(tmp);
977 ret = 0; 980 ret = 0;
978 } else if (ret) { 981 } else if (ret) {
979 goto cleanup; 982 goto cleanup;
@@ -1153,7 +1156,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
1153 if (!set) 1156 if (!set)
1154 return -ENOENT; 1157 return -ENOENT;
1155 1158
1156 read_lock_bh(&ip_set_ref_lock); 1159 write_lock_bh(&ip_set_ref_lock);
1157 if (set->ref != 0) { 1160 if (set->ref != 0) {
1158 ret = -IPSET_ERR_REFERENCED; 1161 ret = -IPSET_ERR_REFERENCED;
1159 goto out; 1162 goto out;
@@ -1170,7 +1173,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
1170 strncpy(set->name, name2, IPSET_MAXNAMELEN); 1173 strncpy(set->name, name2, IPSET_MAXNAMELEN);
1171 1174
1172out: 1175out:
1173 read_unlock_bh(&ip_set_ref_lock); 1176 write_unlock_bh(&ip_set_ref_lock);
1174 return ret; 1177 return ret;
1175} 1178}
1176 1179
@@ -1252,7 +1255,7 @@ ip_set_dump_done(struct netlink_callback *cb)
1252 struct ip_set_net *inst = 1255 struct ip_set_net *inst =
1253 (struct ip_set_net *)cb->args[IPSET_CB_NET]; 1256 (struct ip_set_net *)cb->args[IPSET_CB_NET];
1254 ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX]; 1257 ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX];
1255 struct ip_set *set = ip_set(inst, index); 1258 struct ip_set *set = ip_set_ref_netlink(inst, index);
1256 1259
1257 if (set->variant->uref) 1260 if (set->variant->uref)
1258 set->variant->uref(set, cb, false); 1261 set->variant->uref(set, cb, false);
@@ -1441,7 +1444,7 @@ next_set:
1441release_refcount: 1444release_refcount:
1442 /* If there was an error or set is done, release set */ 1445 /* If there was an error or set is done, release set */
1443 if (ret || !cb->args[IPSET_CB_ARG0]) { 1446 if (ret || !cb->args[IPSET_CB_ARG0]) {
1444 set = ip_set(inst, index); 1447 set = ip_set_ref_netlink(inst, index);
1445 if (set->variant->uref) 1448 if (set->variant->uref)
1446 set->variant->uref(set, cb, false); 1449 set->variant->uref(set, cb, false);
1447 pr_debug("release set %s\n", set->name); 1450 pr_debug("release set %s\n", set->name);
@@ -2059,7 +2062,7 @@ ip_set_net_init(struct net *net)
2059 if (inst->ip_set_max >= IPSET_INVALID_ID) 2062 if (inst->ip_set_max >= IPSET_INVALID_ID)
2060 inst->ip_set_max = IPSET_INVALID_ID - 1; 2063 inst->ip_set_max = IPSET_INVALID_ID - 1;
2061 2064
2062 list = kcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL); 2065 list = kvcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL);
2063 if (!list) 2066 if (!list)
2064 return -ENOMEM; 2067 return -ENOMEM;
2065 inst->is_deleted = false; 2068 inst->is_deleted = false;
@@ -2087,7 +2090,7 @@ ip_set_net_exit(struct net *net)
2087 } 2090 }
2088 } 2091 }
2089 nfnl_unlock(NFNL_SUBSYS_IPSET); 2092 nfnl_unlock(NFNL_SUBSYS_IPSET);
2090 kfree(rcu_dereference_protected(inst->ip_set_list, 1)); 2093 kvfree(rcu_dereference_protected(inst->ip_set_list, 1));
2091} 2094}
2092 2095
2093static struct pernet_operations ip_set_net_ops = { 2096static struct pernet_operations ip_set_net_ops = {
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
index d391485a6acd..613e18e720a4 100644
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -213,13 +213,13 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
213 213
214 if (tb[IPSET_ATTR_CIDR]) { 214 if (tb[IPSET_ATTR_CIDR]) {
215 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); 215 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
216 if (!e.cidr[0] || e.cidr[0] > HOST_MASK) 216 if (e.cidr[0] > HOST_MASK)
217 return -IPSET_ERR_INVALID_CIDR; 217 return -IPSET_ERR_INVALID_CIDR;
218 } 218 }
219 219
220 if (tb[IPSET_ATTR_CIDR2]) { 220 if (tb[IPSET_ATTR_CIDR2]) {
221 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); 221 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
222 if (!e.cidr[1] || e.cidr[1] > HOST_MASK) 222 if (e.cidr[1] > HOST_MASK)
223 return -IPSET_ERR_INVALID_CIDR; 223 return -IPSET_ERR_INVALID_CIDR;
224 } 224 }
225 225
@@ -493,13 +493,13 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
493 493
494 if (tb[IPSET_ATTR_CIDR]) { 494 if (tb[IPSET_ATTR_CIDR]) {
495 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); 495 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
496 if (!e.cidr[0] || e.cidr[0] > HOST_MASK) 496 if (e.cidr[0] > HOST_MASK)
497 return -IPSET_ERR_INVALID_CIDR; 497 return -IPSET_ERR_INVALID_CIDR;
498 } 498 }
499 499
500 if (tb[IPSET_ATTR_CIDR2]) { 500 if (tb[IPSET_ATTR_CIDR2]) {
501 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); 501 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
502 if (!e.cidr[1] || e.cidr[1] > HOST_MASK) 502 if (e.cidr[1] > HOST_MASK)
503 return -IPSET_ERR_INVALID_CIDR; 503 return -IPSET_ERR_INVALID_CIDR;
504 } 504 }
505 505
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 072a658fde04..4eef55da0878 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -148,9 +148,7 @@ __list_set_del_rcu(struct rcu_head * rcu)
148{ 148{
149 struct set_elem *e = container_of(rcu, struct set_elem, rcu); 149 struct set_elem *e = container_of(rcu, struct set_elem, rcu);
150 struct ip_set *set = e->set; 150 struct ip_set *set = e->set;
151 struct list_set *map = set->data;
152 151
153 ip_set_put_byindex(map->net, e->id);
154 ip_set_ext_destroy(set, e); 152 ip_set_ext_destroy(set, e);
155 kfree(e); 153 kfree(e);
156} 154}
@@ -158,15 +156,21 @@ __list_set_del_rcu(struct rcu_head * rcu)
158static inline void 156static inline void
159list_set_del(struct ip_set *set, struct set_elem *e) 157list_set_del(struct ip_set *set, struct set_elem *e)
160{ 158{
159 struct list_set *map = set->data;
160
161 set->elements--; 161 set->elements--;
162 list_del_rcu(&e->list); 162 list_del_rcu(&e->list);
163 ip_set_put_byindex(map->net, e->id);
163 call_rcu(&e->rcu, __list_set_del_rcu); 164 call_rcu(&e->rcu, __list_set_del_rcu);
164} 165}
165 166
166static inline void 167static inline void
167list_set_replace(struct set_elem *e, struct set_elem *old) 168list_set_replace(struct ip_set *set, struct set_elem *e, struct set_elem *old)
168{ 169{
170 struct list_set *map = set->data;
171
169 list_replace_rcu(&old->list, &e->list); 172 list_replace_rcu(&old->list, &e->list);
173 ip_set_put_byindex(map->net, old->id);
170 call_rcu(&old->rcu, __list_set_del_rcu); 174 call_rcu(&old->rcu, __list_set_del_rcu);
171} 175}
172 176
@@ -298,7 +302,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
298 INIT_LIST_HEAD(&e->list); 302 INIT_LIST_HEAD(&e->list);
299 list_set_init_extensions(set, ext, e); 303 list_set_init_extensions(set, ext, e);
300 if (n) 304 if (n)
301 list_set_replace(e, n); 305 list_set_replace(set, e, n);
302 else if (next) 306 else if (next)
303 list_add_tail_rcu(&e->list, &next->list); 307 list_add_tail_rcu(&e->list, &next->list);
304 else if (prev) 308 else if (prev)
@@ -486,6 +490,7 @@ list_set_list(const struct ip_set *set,
486 const struct list_set *map = set->data; 490 const struct list_set *map = set->data;
487 struct nlattr *atd, *nested; 491 struct nlattr *atd, *nested;
488 u32 i = 0, first = cb->args[IPSET_CB_ARG0]; 492 u32 i = 0, first = cb->args[IPSET_CB_ARG0];
493 char name[IPSET_MAXNAMELEN];
489 struct set_elem *e; 494 struct set_elem *e;
490 int ret = 0; 495 int ret = 0;
491 496
@@ -504,8 +509,8 @@ list_set_list(const struct ip_set *set,
504 nested = ipset_nest_start(skb, IPSET_ATTR_DATA); 509 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
505 if (!nested) 510 if (!nested)
506 goto nla_put_failure; 511 goto nla_put_failure;
507 if (nla_put_string(skb, IPSET_ATTR_NAME, 512 ip_set_name_byindex(map->net, e->id, name);
508 ip_set_name_byindex(map->net, e->id))) 513 if (nla_put_string(skb, IPSET_ATTR_NAME, name))
509 goto nla_put_failure; 514 goto nla_put_failure;
510 if (ip_set_put_extensions(skb, set, e, true)) 515 if (ip_set_put_extensions(skb, set, e, true))
511 goto nla_put_failure; 516 goto nla_put_failure;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ca1168d67fac..e92e749aff53 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1073,19 +1073,22 @@ static unsigned int early_drop_list(struct net *net,
1073 return drops; 1073 return drops;
1074} 1074}
1075 1075
1076static noinline int early_drop(struct net *net, unsigned int _hash) 1076static noinline int early_drop(struct net *net, unsigned int hash)
1077{ 1077{
1078 unsigned int i; 1078 unsigned int i, bucket;
1079 1079
1080 for (i = 0; i < NF_CT_EVICTION_RANGE; i++) { 1080 for (i = 0; i < NF_CT_EVICTION_RANGE; i++) {
1081 struct hlist_nulls_head *ct_hash; 1081 struct hlist_nulls_head *ct_hash;
1082 unsigned int hash, hsize, drops; 1082 unsigned int hsize, drops;
1083 1083
1084 rcu_read_lock(); 1084 rcu_read_lock();
1085 nf_conntrack_get_ht(&ct_hash, &hsize); 1085 nf_conntrack_get_ht(&ct_hash, &hsize);
1086 hash = reciprocal_scale(_hash++, hsize); 1086 if (!i)
1087 bucket = reciprocal_scale(hash, hsize);
1088 else
1089 bucket = (bucket + 1) % hsize;
1087 1090
1088 drops = early_drop_list(net, &ct_hash[hash]); 1091 drops = early_drop_list(net, &ct_hash[bucket]);
1089 rcu_read_unlock(); 1092 rcu_read_unlock();
1090 1093
1091 if (drops) { 1094 if (drops) {
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 171e9e122e5f..023c1445bc39 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -384,11 +384,6 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
384 }, 384 },
385}; 385};
386 386
387static inline struct nf_dccp_net *dccp_pernet(struct net *net)
388{
389 return &net->ct.nf_ct_proto.dccp;
390}
391
392static noinline bool 387static noinline bool
393dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 388dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
394 const struct dccp_hdr *dh) 389 const struct dccp_hdr *dh)
@@ -401,7 +396,7 @@ dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
401 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE]; 396 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
402 switch (state) { 397 switch (state) {
403 default: 398 default:
404 dn = dccp_pernet(net); 399 dn = nf_dccp_pernet(net);
405 if (dn->dccp_loose == 0) { 400 if (dn->dccp_loose == 0) {
406 msg = "not picking up existing connection "; 401 msg = "not picking up existing connection ";
407 goto out_invalid; 402 goto out_invalid;
@@ -568,7 +563,7 @@ static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
568 563
569 timeouts = nf_ct_timeout_lookup(ct); 564 timeouts = nf_ct_timeout_lookup(ct);
570 if (!timeouts) 565 if (!timeouts)
571 timeouts = dccp_pernet(nf_ct_net(ct))->dccp_timeout; 566 timeouts = nf_dccp_pernet(nf_ct_net(ct))->dccp_timeout;
572 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]); 567 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
573 568
574 return NF_ACCEPT; 569 return NF_ACCEPT;
@@ -681,7 +676,7 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
681static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], 676static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
682 struct net *net, void *data) 677 struct net *net, void *data)
683{ 678{
684 struct nf_dccp_net *dn = dccp_pernet(net); 679 struct nf_dccp_net *dn = nf_dccp_pernet(net);
685 unsigned int *timeouts = data; 680 unsigned int *timeouts = data;
686 int i; 681 int i;
687 682
@@ -814,7 +809,7 @@ static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
814 809
815static int dccp_init_net(struct net *net) 810static int dccp_init_net(struct net *net)
816{ 811{
817 struct nf_dccp_net *dn = dccp_pernet(net); 812 struct nf_dccp_net *dn = nf_dccp_pernet(net);
818 struct nf_proto_net *pn = &dn->pn; 813 struct nf_proto_net *pn = &dn->pn;
819 814
820 if (!pn->users) { 815 if (!pn->users) {
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index e10e867e0b55..5da19d5fbc76 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -27,11 +27,6 @@ static bool nf_generic_should_process(u8 proto)
27 } 27 }
28} 28}
29 29
30static inline struct nf_generic_net *generic_pernet(struct net *net)
31{
32 return &net->ct.nf_ct_proto.generic;
33}
34
35static bool generic_pkt_to_tuple(const struct sk_buff *skb, 30static bool generic_pkt_to_tuple(const struct sk_buff *skb,
36 unsigned int dataoff, 31 unsigned int dataoff,
37 struct net *net, struct nf_conntrack_tuple *tuple) 32 struct net *net, struct nf_conntrack_tuple *tuple)
@@ -58,7 +53,7 @@ static int generic_packet(struct nf_conn *ct,
58 } 53 }
59 54
60 if (!timeout) 55 if (!timeout)
61 timeout = &generic_pernet(nf_ct_net(ct))->timeout; 56 timeout = &nf_generic_pernet(nf_ct_net(ct))->timeout;
62 57
63 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout); 58 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
64 return NF_ACCEPT; 59 return NF_ACCEPT;
@@ -72,7 +67,7 @@ static int generic_packet(struct nf_conn *ct,
72static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], 67static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
73 struct net *net, void *data) 68 struct net *net, void *data)
74{ 69{
75 struct nf_generic_net *gn = generic_pernet(net); 70 struct nf_generic_net *gn = nf_generic_pernet(net);
76 unsigned int *timeout = data; 71 unsigned int *timeout = data;
77 72
78 if (!timeout) 73 if (!timeout)
@@ -138,7 +133,7 @@ static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
138 133
139static int generic_init_net(struct net *net) 134static int generic_init_net(struct net *net)
140{ 135{
141 struct nf_generic_net *gn = generic_pernet(net); 136 struct nf_generic_net *gn = nf_generic_pernet(net);
142 struct nf_proto_net *pn = &gn->pn; 137 struct nf_proto_net *pn = &gn->pn;
143 138
144 gn->timeout = nf_ct_generic_timeout; 139 gn->timeout = nf_ct_generic_timeout;
diff --git a/net/netfilter/nf_conntrack_proto_icmp.c b/net/netfilter/nf_conntrack_proto_icmp.c
index 3598520bd19b..de64d8a5fdfd 100644
--- a/net/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/netfilter/nf_conntrack_proto_icmp.c
@@ -25,11 +25,6 @@
25 25
26static const unsigned int nf_ct_icmp_timeout = 30*HZ; 26static const unsigned int nf_ct_icmp_timeout = 30*HZ;
27 27
28static inline struct nf_icmp_net *icmp_pernet(struct net *net)
29{
30 return &net->ct.nf_ct_proto.icmp;
31}
32
33static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 28static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
34 struct net *net, struct nf_conntrack_tuple *tuple) 29 struct net *net, struct nf_conntrack_tuple *tuple)
35{ 30{
@@ -103,7 +98,7 @@ static int icmp_packet(struct nf_conn *ct,
103 } 98 }
104 99
105 if (!timeout) 100 if (!timeout)
106 timeout = &icmp_pernet(nf_ct_net(ct))->timeout; 101 timeout = &nf_icmp_pernet(nf_ct_net(ct))->timeout;
107 102
108 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout); 103 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
109 return NF_ACCEPT; 104 return NF_ACCEPT;
@@ -275,7 +270,7 @@ static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[],
275 struct net *net, void *data) 270 struct net *net, void *data)
276{ 271{
277 unsigned int *timeout = data; 272 unsigned int *timeout = data;
278 struct nf_icmp_net *in = icmp_pernet(net); 273 struct nf_icmp_net *in = nf_icmp_pernet(net);
279 274
280 if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) { 275 if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) {
281 if (!timeout) 276 if (!timeout)
@@ -337,7 +332,7 @@ static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn,
337 332
338static int icmp_init_net(struct net *net) 333static int icmp_init_net(struct net *net)
339{ 334{
340 struct nf_icmp_net *in = icmp_pernet(net); 335 struct nf_icmp_net *in = nf_icmp_pernet(net);
341 struct nf_proto_net *pn = &in->pn; 336 struct nf_proto_net *pn = &in->pn;
342 337
343 in->timeout = nf_ct_icmp_timeout; 338 in->timeout = nf_ct_icmp_timeout;
diff --git a/net/netfilter/nf_conntrack_proto_icmpv6.c b/net/netfilter/nf_conntrack_proto_icmpv6.c
index 378618feed5d..a15eefb8e317 100644
--- a/net/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/netfilter/nf_conntrack_proto_icmpv6.c
@@ -30,11 +30,6 @@
30 30
31static const unsigned int nf_ct_icmpv6_timeout = 30*HZ; 31static const unsigned int nf_ct_icmpv6_timeout = 30*HZ;
32 32
33static inline struct nf_icmp_net *icmpv6_pernet(struct net *net)
34{
35 return &net->ct.nf_ct_proto.icmpv6;
36}
37
38static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, 33static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
39 unsigned int dataoff, 34 unsigned int dataoff,
40 struct net *net, 35 struct net *net,
@@ -87,7 +82,7 @@ static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
87 82
88static unsigned int *icmpv6_get_timeouts(struct net *net) 83static unsigned int *icmpv6_get_timeouts(struct net *net)
89{ 84{
90 return &icmpv6_pernet(net)->timeout; 85 return &nf_icmpv6_pernet(net)->timeout;
91} 86}
92 87
93/* Returns verdict for packet, or -1 for invalid. */ 88/* Returns verdict for packet, or -1 for invalid. */
@@ -286,7 +281,7 @@ static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[],
286 struct net *net, void *data) 281 struct net *net, void *data)
287{ 282{
288 unsigned int *timeout = data; 283 unsigned int *timeout = data;
289 struct nf_icmp_net *in = icmpv6_pernet(net); 284 struct nf_icmp_net *in = nf_icmpv6_pernet(net);
290 285
291 if (!timeout) 286 if (!timeout)
292 timeout = icmpv6_get_timeouts(net); 287 timeout = icmpv6_get_timeouts(net);
@@ -348,7 +343,7 @@ static int icmpv6_kmemdup_sysctl_table(struct nf_proto_net *pn,
348 343
349static int icmpv6_init_net(struct net *net) 344static int icmpv6_init_net(struct net *net)
350{ 345{
351 struct nf_icmp_net *in = icmpv6_pernet(net); 346 struct nf_icmp_net *in = nf_icmpv6_pernet(net);
352 struct nf_proto_net *pn = &in->pn; 347 struct nf_proto_net *pn = &in->pn;
353 348
354 in->timeout = nf_ct_icmpv6_timeout; 349 in->timeout = nf_ct_icmpv6_timeout;
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 3d719d3eb9a3..d53e3e78f605 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -146,11 +146,6 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
146 } 146 }
147}; 147};
148 148
149static inline struct nf_sctp_net *sctp_pernet(struct net *net)
150{
151 return &net->ct.nf_ct_proto.sctp;
152}
153
154#ifdef CONFIG_NF_CONNTRACK_PROCFS 149#ifdef CONFIG_NF_CONNTRACK_PROCFS
155/* Print out the private part of the conntrack. */ 150/* Print out the private part of the conntrack. */
156static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) 151static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
@@ -480,7 +475,7 @@ static int sctp_packet(struct nf_conn *ct,
480 475
481 timeouts = nf_ct_timeout_lookup(ct); 476 timeouts = nf_ct_timeout_lookup(ct);
482 if (!timeouts) 477 if (!timeouts)
483 timeouts = sctp_pernet(nf_ct_net(ct))->timeouts; 478 timeouts = nf_sctp_pernet(nf_ct_net(ct))->timeouts;
484 479
485 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]); 480 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
486 481
@@ -599,7 +594,7 @@ static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
599 struct net *net, void *data) 594 struct net *net, void *data)
600{ 595{
601 unsigned int *timeouts = data; 596 unsigned int *timeouts = data;
602 struct nf_sctp_net *sn = sctp_pernet(net); 597 struct nf_sctp_net *sn = nf_sctp_pernet(net);
603 int i; 598 int i;
604 599
605 /* set default SCTP timeouts. */ 600 /* set default SCTP timeouts. */
@@ -736,7 +731,7 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
736 731
737static int sctp_init_net(struct net *net) 732static int sctp_init_net(struct net *net)
738{ 733{
739 struct nf_sctp_net *sn = sctp_pernet(net); 734 struct nf_sctp_net *sn = nf_sctp_pernet(net);
740 struct nf_proto_net *pn = &sn->pn; 735 struct nf_proto_net *pn = &sn->pn;
741 736
742 if (!pn->users) { 737 if (!pn->users) {
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 1bcf9984d45e..4dcbd51a8e97 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -272,11 +272,6 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
272 } 272 }
273}; 273};
274 274
275static inline struct nf_tcp_net *tcp_pernet(struct net *net)
276{
277 return &net->ct.nf_ct_proto.tcp;
278}
279
280#ifdef CONFIG_NF_CONNTRACK_PROCFS 275#ifdef CONFIG_NF_CONNTRACK_PROCFS
281/* Print out the private part of the conntrack. */ 276/* Print out the private part of the conntrack. */
282static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) 277static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
@@ -475,7 +470,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
475 const struct tcphdr *tcph) 470 const struct tcphdr *tcph)
476{ 471{
477 struct net *net = nf_ct_net(ct); 472 struct net *net = nf_ct_net(ct);
478 struct nf_tcp_net *tn = tcp_pernet(net); 473 struct nf_tcp_net *tn = nf_tcp_pernet(net);
479 struct ip_ct_tcp_state *sender = &state->seen[dir]; 474 struct ip_ct_tcp_state *sender = &state->seen[dir];
480 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 475 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
481 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; 476 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -767,7 +762,7 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
767{ 762{
768 enum tcp_conntrack new_state; 763 enum tcp_conntrack new_state;
769 struct net *net = nf_ct_net(ct); 764 struct net *net = nf_ct_net(ct);
770 const struct nf_tcp_net *tn = tcp_pernet(net); 765 const struct nf_tcp_net *tn = nf_tcp_pernet(net);
771 const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0]; 766 const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
772 const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1]; 767 const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
773 768
@@ -841,7 +836,7 @@ static int tcp_packet(struct nf_conn *ct,
841 const struct nf_hook_state *state) 836 const struct nf_hook_state *state)
842{ 837{
843 struct net *net = nf_ct_net(ct); 838 struct net *net = nf_ct_net(ct);
844 struct nf_tcp_net *tn = tcp_pernet(net); 839 struct nf_tcp_net *tn = nf_tcp_pernet(net);
845 struct nf_conntrack_tuple *tuple; 840 struct nf_conntrack_tuple *tuple;
846 enum tcp_conntrack new_state, old_state; 841 enum tcp_conntrack new_state, old_state;
847 unsigned int index, *timeouts; 842 unsigned int index, *timeouts;
@@ -1283,7 +1278,7 @@ static unsigned int tcp_nlattr_tuple_size(void)
1283static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], 1278static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
1284 struct net *net, void *data) 1279 struct net *net, void *data)
1285{ 1280{
1286 struct nf_tcp_net *tn = tcp_pernet(net); 1281 struct nf_tcp_net *tn = nf_tcp_pernet(net);
1287 unsigned int *timeouts = data; 1282 unsigned int *timeouts = data;
1288 int i; 1283 int i;
1289 1284
@@ -1508,7 +1503,7 @@ static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn,
1508 1503
1509static int tcp_init_net(struct net *net) 1504static int tcp_init_net(struct net *net)
1510{ 1505{
1511 struct nf_tcp_net *tn = tcp_pernet(net); 1506 struct nf_tcp_net *tn = nf_tcp_pernet(net);
1512 struct nf_proto_net *pn = &tn->pn; 1507 struct nf_proto_net *pn = &tn->pn;
1513 1508
1514 if (!pn->users) { 1509 if (!pn->users) {
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index a7aa70370913..c879d8d78cfd 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -32,14 +32,9 @@ static const unsigned int udp_timeouts[UDP_CT_MAX] = {
32 [UDP_CT_REPLIED] = 180*HZ, 32 [UDP_CT_REPLIED] = 180*HZ,
33}; 33};
34 34
35static inline struct nf_udp_net *udp_pernet(struct net *net)
36{
37 return &net->ct.nf_ct_proto.udp;
38}
39
40static unsigned int *udp_get_timeouts(struct net *net) 35static unsigned int *udp_get_timeouts(struct net *net)
41{ 36{
42 return udp_pernet(net)->timeouts; 37 return nf_udp_pernet(net)->timeouts;
43} 38}
44 39
45static void udp_error_log(const struct sk_buff *skb, 40static void udp_error_log(const struct sk_buff *skb,
@@ -212,7 +207,7 @@ static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
212 struct net *net, void *data) 207 struct net *net, void *data)
213{ 208{
214 unsigned int *timeouts = data; 209 unsigned int *timeouts = data;
215 struct nf_udp_net *un = udp_pernet(net); 210 struct nf_udp_net *un = nf_udp_pernet(net);
216 211
217 if (!timeouts) 212 if (!timeouts)
218 timeouts = un->timeouts; 213 timeouts = un->timeouts;
@@ -292,7 +287,7 @@ static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn,
292 287
293static int udp_init_net(struct net *net) 288static int udp_init_net(struct net *net)
294{ 289{
295 struct nf_udp_net *un = udp_pernet(net); 290 struct nf_udp_net *un = nf_udp_pernet(net);
296 struct nf_proto_net *pn = &un->pn; 291 struct nf_proto_net *pn = &un->pn;
297 292
298 if (!pn->users) { 293 if (!pn->users) {
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index e7a50af1b3d6..a518eb162344 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -382,7 +382,8 @@ err:
382static int 382static int
383cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid, 383cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
384 u32 seq, u32 type, int event, u16 l3num, 384 u32 seq, u32 type, int event, u16 l3num,
385 const struct nf_conntrack_l4proto *l4proto) 385 const struct nf_conntrack_l4proto *l4proto,
386 const unsigned int *timeouts)
386{ 387{
387 struct nlmsghdr *nlh; 388 struct nlmsghdr *nlh;
388 struct nfgenmsg *nfmsg; 389 struct nfgenmsg *nfmsg;
@@ -408,7 +409,7 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
408 if (!nest_parms) 409 if (!nest_parms)
409 goto nla_put_failure; 410 goto nla_put_failure;
410 411
411 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL); 412 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
412 if (ret < 0) 413 if (ret < 0)
413 goto nla_put_failure; 414 goto nla_put_failure;
414 415
@@ -430,6 +431,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
430 struct netlink_ext_ack *extack) 431 struct netlink_ext_ack *extack)
431{ 432{
432 const struct nf_conntrack_l4proto *l4proto; 433 const struct nf_conntrack_l4proto *l4proto;
434 unsigned int *timeouts = NULL;
433 struct sk_buff *skb2; 435 struct sk_buff *skb2;
434 int ret, err; 436 int ret, err;
435 __u16 l3num; 437 __u16 l3num;
@@ -442,12 +444,44 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
442 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]); 444 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
443 l4proto = nf_ct_l4proto_find_get(l4num); 445 l4proto = nf_ct_l4proto_find_get(l4num);
444 446
445 /* This protocol is not supported, skip. */ 447 err = -EOPNOTSUPP;
446 if (l4proto->l4proto != l4num) { 448 if (l4proto->l4proto != l4num)
447 err = -EOPNOTSUPP;
448 goto err; 449 goto err;
450
451 switch (l4proto->l4proto) {
452 case IPPROTO_ICMP:
453 timeouts = &nf_icmp_pernet(net)->timeout;
454 break;
455 case IPPROTO_TCP:
456 timeouts = nf_tcp_pernet(net)->timeouts;
457 break;
458 case IPPROTO_UDP:
459 timeouts = nf_udp_pernet(net)->timeouts;
460 break;
461 case IPPROTO_DCCP:
462#ifdef CONFIG_NF_CT_PROTO_DCCP
463 timeouts = nf_dccp_pernet(net)->dccp_timeout;
464#endif
465 break;
466 case IPPROTO_ICMPV6:
467 timeouts = &nf_icmpv6_pernet(net)->timeout;
468 break;
469 case IPPROTO_SCTP:
470#ifdef CONFIG_NF_CT_PROTO_SCTP
471 timeouts = nf_sctp_pernet(net)->timeouts;
472#endif
473 break;
474 case 255:
475 timeouts = &nf_generic_pernet(net)->timeout;
476 break;
477 default:
478 WARN_ON_ONCE(1);
479 break;
449 } 480 }
450 481
482 if (!timeouts)
483 goto err;
484
451 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 485 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
452 if (skb2 == NULL) { 486 if (skb2 == NULL) {
453 err = -ENOMEM; 487 err = -ENOMEM;
@@ -458,8 +492,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
458 nlh->nlmsg_seq, 492 nlh->nlmsg_seq,
459 NFNL_MSG_TYPE(nlh->nlmsg_type), 493 NFNL_MSG_TYPE(nlh->nlmsg_type),
460 IPCTNL_MSG_TIMEOUT_DEFAULT_SET, 494 IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
461 l3num, 495 l3num, l4proto, timeouts);
462 l4proto);
463 if (ret <= 0) { 496 if (ret <= 0) {
464 kfree_skb(skb2); 497 kfree_skb(skb2);
465 err = -ENOMEM; 498 err = -ENOMEM;
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 768292eac2a4..9d0ede474224 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -54,9 +54,11 @@ static bool nft_xt_put(struct nft_xt *xt)
54 return false; 54 return false;
55} 55}
56 56
57static int nft_compat_chain_validate_dependency(const char *tablename, 57static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
58 const struct nft_chain *chain) 58 const char *tablename)
59{ 59{
60 enum nft_chain_types type = NFT_CHAIN_T_DEFAULT;
61 const struct nft_chain *chain = ctx->chain;
60 const struct nft_base_chain *basechain; 62 const struct nft_base_chain *basechain;
61 63
62 if (!tablename || 64 if (!tablename ||
@@ -64,9 +66,12 @@ static int nft_compat_chain_validate_dependency(const char *tablename,
64 return 0; 66 return 0;
65 67
66 basechain = nft_base_chain(chain); 68 basechain = nft_base_chain(chain);
67 if (strcmp(tablename, "nat") == 0 && 69 if (strcmp(tablename, "nat") == 0) {
68 basechain->type->type != NFT_CHAIN_T_NAT) 70 if (ctx->family != NFPROTO_BRIDGE)
69 return -EINVAL; 71 type = NFT_CHAIN_T_NAT;
72 if (basechain->type->type != type)
73 return -EINVAL;
74 }
70 75
71 return 0; 76 return 0;
72} 77}
@@ -342,8 +347,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
342 if (target->hooks && !(hook_mask & target->hooks)) 347 if (target->hooks && !(hook_mask & target->hooks))
343 return -EINVAL; 348 return -EINVAL;
344 349
345 ret = nft_compat_chain_validate_dependency(target->table, 350 ret = nft_compat_chain_validate_dependency(ctx, target->table);
346 ctx->chain);
347 if (ret < 0) 351 if (ret < 0)
348 return ret; 352 return ret;
349 } 353 }
@@ -590,8 +594,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
590 if (match->hooks && !(hook_mask & match->hooks)) 594 if (match->hooks && !(hook_mask & match->hooks))
591 return -EINVAL; 595 return -EINVAL;
592 596
593 ret = nft_compat_chain_validate_dependency(match->table, 597 ret = nft_compat_chain_validate_dependency(ctx, match->table);
594 ctx->chain);
595 if (ret < 0) 598 if (ret < 0)
596 return ret; 599 return ret;
597 } 600 }
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index 649d1700ec5b..3cc1b3dc3c3c 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -24,7 +24,6 @@ struct nft_ng_inc {
24 u32 modulus; 24 u32 modulus;
25 atomic_t counter; 25 atomic_t counter;
26 u32 offset; 26 u32 offset;
27 struct nft_set *map;
28}; 27};
29 28
30static u32 nft_ng_inc_gen(struct nft_ng_inc *priv) 29static u32 nft_ng_inc_gen(struct nft_ng_inc *priv)
@@ -48,34 +47,11 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
48 regs->data[priv->dreg] = nft_ng_inc_gen(priv); 47 regs->data[priv->dreg] = nft_ng_inc_gen(priv);
49} 48}
50 49
51static void nft_ng_inc_map_eval(const struct nft_expr *expr,
52 struct nft_regs *regs,
53 const struct nft_pktinfo *pkt)
54{
55 struct nft_ng_inc *priv = nft_expr_priv(expr);
56 const struct nft_set *map = priv->map;
57 const struct nft_set_ext *ext;
58 u32 result;
59 bool found;
60
61 result = nft_ng_inc_gen(priv);
62 found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
63
64 if (!found)
65 return;
66
67 nft_data_copy(&regs->data[priv->dreg],
68 nft_set_ext_data(ext), map->dlen);
69}
70
71static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = { 50static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
72 [NFTA_NG_DREG] = { .type = NLA_U32 }, 51 [NFTA_NG_DREG] = { .type = NLA_U32 },
73 [NFTA_NG_MODULUS] = { .type = NLA_U32 }, 52 [NFTA_NG_MODULUS] = { .type = NLA_U32 },
74 [NFTA_NG_TYPE] = { .type = NLA_U32 }, 53 [NFTA_NG_TYPE] = { .type = NLA_U32 },
75 [NFTA_NG_OFFSET] = { .type = NLA_U32 }, 54 [NFTA_NG_OFFSET] = { .type = NLA_U32 },
76 [NFTA_NG_SET_NAME] = { .type = NLA_STRING,
77 .len = NFT_SET_MAXNAMELEN - 1 },
78 [NFTA_NG_SET_ID] = { .type = NLA_U32 },
79}; 55};
80 56
81static int nft_ng_inc_init(const struct nft_ctx *ctx, 57static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -101,22 +77,6 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
101 NFT_DATA_VALUE, sizeof(u32)); 77 NFT_DATA_VALUE, sizeof(u32));
102} 78}
103 79
104static int nft_ng_inc_map_init(const struct nft_ctx *ctx,
105 const struct nft_expr *expr,
106 const struct nlattr * const tb[])
107{
108 struct nft_ng_inc *priv = nft_expr_priv(expr);
109 u8 genmask = nft_genmask_next(ctx->net);
110
111 nft_ng_inc_init(ctx, expr, tb);
112
113 priv->map = nft_set_lookup_global(ctx->net, ctx->table,
114 tb[NFTA_NG_SET_NAME],
115 tb[NFTA_NG_SET_ID], genmask);
116
117 return PTR_ERR_OR_ZERO(priv->map);
118}
119
120static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg, 80static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
121 u32 modulus, enum nft_ng_types type, u32 offset) 81 u32 modulus, enum nft_ng_types type, u32 offset)
122{ 82{
@@ -143,27 +103,10 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr)
143 priv->offset); 103 priv->offset);
144} 104}
145 105
146static int nft_ng_inc_map_dump(struct sk_buff *skb,
147 const struct nft_expr *expr)
148{
149 const struct nft_ng_inc *priv = nft_expr_priv(expr);
150
151 if (nft_ng_dump(skb, priv->dreg, priv->modulus,
152 NFT_NG_INCREMENTAL, priv->offset) ||
153 nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
154 goto nla_put_failure;
155
156 return 0;
157
158nla_put_failure:
159 return -1;
160}
161
162struct nft_ng_random { 106struct nft_ng_random {
163 enum nft_registers dreg:8; 107 enum nft_registers dreg:8;
164 u32 modulus; 108 u32 modulus;
165 u32 offset; 109 u32 offset;
166 struct nft_set *map;
167}; 110};
168 111
169static u32 nft_ng_random_gen(struct nft_ng_random *priv) 112static u32 nft_ng_random_gen(struct nft_ng_random *priv)
@@ -183,25 +126,6 @@ static void nft_ng_random_eval(const struct nft_expr *expr,
183 regs->data[priv->dreg] = nft_ng_random_gen(priv); 126 regs->data[priv->dreg] = nft_ng_random_gen(priv);
184} 127}
185 128
186static void nft_ng_random_map_eval(const struct nft_expr *expr,
187 struct nft_regs *regs,
188 const struct nft_pktinfo *pkt)
189{
190 struct nft_ng_random *priv = nft_expr_priv(expr);
191 const struct nft_set *map = priv->map;
192 const struct nft_set_ext *ext;
193 u32 result;
194 bool found;
195
196 result = nft_ng_random_gen(priv);
197 found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
198 if (!found)
199 return;
200
201 nft_data_copy(&regs->data[priv->dreg],
202 nft_set_ext_data(ext), map->dlen);
203}
204
205static int nft_ng_random_init(const struct nft_ctx *ctx, 129static int nft_ng_random_init(const struct nft_ctx *ctx,
206 const struct nft_expr *expr, 130 const struct nft_expr *expr,
207 const struct nlattr * const tb[]) 131 const struct nlattr * const tb[])
@@ -226,21 +150,6 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
226 NFT_DATA_VALUE, sizeof(u32)); 150 NFT_DATA_VALUE, sizeof(u32));
227} 151}
228 152
229static int nft_ng_random_map_init(const struct nft_ctx *ctx,
230 const struct nft_expr *expr,
231 const struct nlattr * const tb[])
232{
233 struct nft_ng_random *priv = nft_expr_priv(expr);
234 u8 genmask = nft_genmask_next(ctx->net);
235
236 nft_ng_random_init(ctx, expr, tb);
237 priv->map = nft_set_lookup_global(ctx->net, ctx->table,
238 tb[NFTA_NG_SET_NAME],
239 tb[NFTA_NG_SET_ID], genmask);
240
241 return PTR_ERR_OR_ZERO(priv->map);
242}
243
244static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr) 153static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
245{ 154{
246 const struct nft_ng_random *priv = nft_expr_priv(expr); 155 const struct nft_ng_random *priv = nft_expr_priv(expr);
@@ -249,22 +158,6 @@ static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
249 priv->offset); 158 priv->offset);
250} 159}
251 160
252static int nft_ng_random_map_dump(struct sk_buff *skb,
253 const struct nft_expr *expr)
254{
255 const struct nft_ng_random *priv = nft_expr_priv(expr);
256
257 if (nft_ng_dump(skb, priv->dreg, priv->modulus,
258 NFT_NG_RANDOM, priv->offset) ||
259 nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
260 goto nla_put_failure;
261
262 return 0;
263
264nla_put_failure:
265 return -1;
266}
267
268static struct nft_expr_type nft_ng_type; 161static struct nft_expr_type nft_ng_type;
269static const struct nft_expr_ops nft_ng_inc_ops = { 162static const struct nft_expr_ops nft_ng_inc_ops = {
270 .type = &nft_ng_type, 163 .type = &nft_ng_type,
@@ -274,14 +167,6 @@ static const struct nft_expr_ops nft_ng_inc_ops = {
274 .dump = nft_ng_inc_dump, 167 .dump = nft_ng_inc_dump,
275}; 168};
276 169
277static const struct nft_expr_ops nft_ng_inc_map_ops = {
278 .type = &nft_ng_type,
279 .size = NFT_EXPR_SIZE(sizeof(struct nft_ng_inc)),
280 .eval = nft_ng_inc_map_eval,
281 .init = nft_ng_inc_map_init,
282 .dump = nft_ng_inc_map_dump,
283};
284
285static const struct nft_expr_ops nft_ng_random_ops = { 170static const struct nft_expr_ops nft_ng_random_ops = {
286 .type = &nft_ng_type, 171 .type = &nft_ng_type,
287 .size = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)), 172 .size = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
@@ -290,14 +175,6 @@ static const struct nft_expr_ops nft_ng_random_ops = {
290 .dump = nft_ng_random_dump, 175 .dump = nft_ng_random_dump,
291}; 176};
292 177
293static const struct nft_expr_ops nft_ng_random_map_ops = {
294 .type = &nft_ng_type,
295 .size = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
296 .eval = nft_ng_random_map_eval,
297 .init = nft_ng_random_map_init,
298 .dump = nft_ng_random_map_dump,
299};
300
301static const struct nft_expr_ops * 178static const struct nft_expr_ops *
302nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) 179nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
303{ 180{
@@ -312,12 +189,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
312 189
313 switch (type) { 190 switch (type) {
314 case NFT_NG_INCREMENTAL: 191 case NFT_NG_INCREMENTAL:
315 if (tb[NFTA_NG_SET_NAME])
316 return &nft_ng_inc_map_ops;
317 return &nft_ng_inc_ops; 192 return &nft_ng_inc_ops;
318 case NFT_NG_RANDOM: 193 case NFT_NG_RANDOM:
319 if (tb[NFTA_NG_SET_NAME])
320 return &nft_ng_random_map_ops;
321 return &nft_ng_random_ops; 194 return &nft_ng_random_ops;
322 } 195 }
323 196
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index ca5e5d8c5ef8..b13618c764ec 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -50,7 +50,7 @@ static int nft_osf_init(const struct nft_ctx *ctx,
50 int err; 50 int err;
51 u8 ttl; 51 u8 ttl;
52 52
53 if (nla_get_u8(tb[NFTA_OSF_TTL])) { 53 if (tb[NFTA_OSF_TTL]) {
54 ttl = nla_get_u8(tb[NFTA_OSF_TTL]); 54 ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
55 if (ttl > 2) 55 if (ttl > 2)
56 return -EINVAL; 56 return -EINVAL;
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index c6acfc2d9c84..eb4cbd244c3d 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -114,6 +114,22 @@ static void idletimer_tg_expired(struct timer_list *t)
114 schedule_work(&timer->work); 114 schedule_work(&timer->work);
115} 115}
116 116
117static int idletimer_check_sysfs_name(const char *name, unsigned int size)
118{
119 int ret;
120
121 ret = xt_check_proc_name(name, size);
122 if (ret < 0)
123 return ret;
124
125 if (!strcmp(name, "power") ||
126 !strcmp(name, "subsystem") ||
127 !strcmp(name, "uevent"))
128 return -EINVAL;
129
130 return 0;
131}
132
117static int idletimer_tg_create(struct idletimer_tg_info *info) 133static int idletimer_tg_create(struct idletimer_tg_info *info)
118{ 134{
119 int ret; 135 int ret;
@@ -124,6 +140,10 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
124 goto out; 140 goto out;
125 } 141 }
126 142
143 ret = idletimer_check_sysfs_name(info->label, sizeof(info->label));
144 if (ret < 0)
145 goto out_free_timer;
146
127 sysfs_attr_init(&info->timer->attr.attr); 147 sysfs_attr_init(&info->timer->attr.attr);
128 info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); 148 info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
129 if (!info->timer->attr.attr.name) { 149 if (!info->timer->attr.attr.name) {