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

netfilter: move nf_ct_netns_get out of nf_conncount_init

This patch is to move nf_ct_netns_get() out of nf_conncount_init()
and let the consumers of nf_conncount decide if they want to turn
on netfilter conntrack.

It makes nf_conncount more flexible to be used in other places and
avoids netfilter conntrack turned on when using it in openvswitch
conntrack.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Xin Long and committed by
Pablo Neira Ayuso
d5283b47 c9526aeb

+20 -21
+2 -4
include/net/netfilter/nf_conntrack_count.h
··· 15 15 unsigned int count; /* length of list */ 16 16 }; 17 17 18 - struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, 19 - unsigned int keylen); 20 - void nf_conncount_destroy(struct net *net, unsigned int family, 21 - struct nf_conncount_data *data); 18 + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen); 19 + void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data); 22 20 23 21 unsigned int nf_conncount_count(struct net *net, 24 22 struct nf_conncount_data *data,
+3 -12
net/netfilter/nf_conncount.c
··· 522 522 } 523 523 EXPORT_SYMBOL_GPL(nf_conncount_count); 524 524 525 - struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, 526 - unsigned int keylen) 525 + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen) 527 526 { 528 527 struct nf_conncount_data *data; 529 - int ret, i; 528 + int i; 530 529 531 530 if (keylen % sizeof(u32) || 532 531 keylen / sizeof(u32) > MAX_KEYLEN || ··· 537 538 data = kmalloc(sizeof(*data), GFP_KERNEL); 538 539 if (!data) 539 540 return ERR_PTR(-ENOMEM); 540 - 541 - ret = nf_ct_netns_get(net, family); 542 - if (ret < 0) { 543 - kfree(data); 544 - return ERR_PTR(ret); 545 - } 546 541 547 542 for (i = 0; i < ARRAY_SIZE(data->root); ++i) 548 543 data->root[i] = RB_ROOT; ··· 574 581 } 575 582 } 576 583 577 - void nf_conncount_destroy(struct net *net, unsigned int family, 578 - struct nf_conncount_data *data) 584 + void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data) 579 585 { 580 586 unsigned int i; 581 587 582 588 cancel_work_sync(&data->gc_work); 583 - nf_ct_netns_put(net, family); 584 589 585 590 for (i = 0; i < ARRAY_SIZE(data->root); ++i) 586 591 destroy_tree(&data->root[i]);
+13 -2
net/netfilter/xt_connlimit.c
··· 86 86 { 87 87 struct xt_connlimit_info *info = par->matchinfo; 88 88 unsigned int keylen; 89 + int ret; 89 90 90 91 keylen = sizeof(u32); 91 92 if (par->family == NFPROTO_IPV6) ··· 94 93 else 95 94 keylen += sizeof(struct in_addr); 96 95 96 + ret = nf_ct_netns_get(par->net, par->family); 97 + if (ret < 0) { 98 + pr_info_ratelimited("cannot load conntrack support for proto=%u\n", 99 + par->family); 100 + return ret; 101 + } 102 + 97 103 /* init private data */ 98 - info->data = nf_conncount_init(par->net, par->family, keylen); 104 + info->data = nf_conncount_init(par->net, keylen); 105 + if (IS_ERR(info->data)) 106 + nf_ct_netns_put(par->net, par->family); 99 107 100 108 return PTR_ERR_OR_ZERO(info->data); 101 109 } ··· 113 103 { 114 104 const struct xt_connlimit_info *info = par->matchinfo; 115 105 116 - nf_conncount_destroy(par->net, par->family, info->data); 106 + nf_conncount_destroy(par->net, info->data); 107 + nf_ct_netns_put(par->net, par->family); 117 108 } 118 109 119 110 static struct xt_match connlimit_mt_reg __read_mostly = {
+2 -3
net/openvswitch/conntrack.c
··· 1608 1608 for (i = 0; i < CT_LIMIT_HASH_BUCKETS; i++) 1609 1609 INIT_HLIST_HEAD(&ovs_net->ct_limit_info->limits[i]); 1610 1610 1611 - ovs_net->ct_limit_info->data = 1612 - nf_conncount_init(net, NFPROTO_INET, sizeof(u32)); 1611 + ovs_net->ct_limit_info->data = nf_conncount_init(net, sizeof(u32)); 1613 1612 1614 1613 if (IS_ERR(ovs_net->ct_limit_info->data)) { 1615 1614 err = PTR_ERR(ovs_net->ct_limit_info->data); ··· 1625 1626 const struct ovs_ct_limit_info *info = ovs_net->ct_limit_info; 1626 1627 int i; 1627 1628 1628 - nf_conncount_destroy(net, NFPROTO_INET, info->data); 1629 + nf_conncount_destroy(net, info->data); 1629 1630 for (i = 0; i < CT_LIMIT_HASH_BUCKETS; ++i) { 1630 1631 struct hlist_head *head = &info->limits[i]; 1631 1632 struct ovs_ct_limit *ct_limit;