aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-04 19:46:58 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-04 19:46:58 -0500
commit72c39a0ade6229a938736fe1aa1d5e471fc7face (patch)
tree33e5e634d553750eba4bf876a23c4c051e0d9c26 /net/ipv4
parent6fcf018ae4491dc11b080892fa9f3dbd928fdbb9 (diff)
parent4542fa4727f5f83faf9e1f28f35be0b9a2317aec (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== This is another batch containing Netfilter/IPVS updates for your net-next tree, they are: * Six patches to make the ipt_CLUSTERIP target support netnamespace, from Gao feng. * Two cleanups for the nf_conntrack_acct infrastructure, introducing a new structure to encapsulate conntrack counters, from Holger Eitzenberger. * Fix missing verdict in SCTP support for IPVS, from Daniel Borkmann. * Skip checksum recalculation in SCTP support for IPVS, also from Daniel Borkmann. * Fix behavioural change in xt_socket after IP early demux, from Florian Westphal. * Fix bogus large memory allocation in the bitmap port set type in ipset, from Jozsef Kadlecsik. * Fix possible compilation issues in the hash netnet set type in ipset, also from Jozsef Kadlecsik. * Define constants to identify netlink callback data in ipset dumps, again from Jozsef Kadlecsik. * Use sock_gen_put() in xt_socket to replace xt_socket_put_sk, from Eric Dumazet. * Improvements for the SH scheduler in IPVS, from Alexander Frolkin. * Remove extra delay due to unneeded rcu barrier in IPVS net namespace cleanup path, from Julian Anastasov. * Save some cycles in ip6t_REJECT by skipping checksum validation in packets leaving from our stack, from Stanislav Fomichev. * Fix IPVS_CMD_ATTR_MAX definition in IPVS, larger that required, from Julian Anastasov. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index a2e2b61cd7da..2510c02c2d21 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -28,6 +28,7 @@
28#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> 28#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
29#include <net/netfilter/nf_conntrack.h> 29#include <net/netfilter/nf_conntrack.h>
30#include <net/net_namespace.h> 30#include <net/net_namespace.h>
31#include <net/netns/generic.h>
31#include <net/checksum.h> 32#include <net/checksum.h>
32#include <net/ip.h> 33#include <net/ip.h>
33 34
@@ -57,15 +58,21 @@ struct clusterip_config {
57 struct rcu_head rcu; 58 struct rcu_head rcu;
58}; 59};
59 60
60static LIST_HEAD(clusterip_configs); 61#ifdef CONFIG_PROC_FS
62static const struct file_operations clusterip_proc_fops;
63#endif
61 64
62/* clusterip_lock protects the clusterip_configs list */ 65static int clusterip_net_id __read_mostly;
63static DEFINE_SPINLOCK(clusterip_lock); 66
67struct clusterip_net {
68 struct list_head configs;
69 /* lock protects the configs list */
70 spinlock_t lock;
64 71
65#ifdef CONFIG_PROC_FS 72#ifdef CONFIG_PROC_FS
66static const struct file_operations clusterip_proc_fops; 73 struct proc_dir_entry *procdir;
67static struct proc_dir_entry *clusterip_procdir;
68#endif 74#endif
75};
69 76
70static inline void 77static inline void
71clusterip_config_get(struct clusterip_config *c) 78clusterip_config_get(struct clusterip_config *c)
@@ -92,10 +99,13 @@ clusterip_config_put(struct clusterip_config *c)
92static inline void 99static inline void
93clusterip_config_entry_put(struct clusterip_config *c) 100clusterip_config_entry_put(struct clusterip_config *c)
94{ 101{
102 struct net *net = dev_net(c->dev);
103 struct clusterip_net *cn = net_generic(net, clusterip_net_id);
104
95 local_bh_disable(); 105 local_bh_disable();
96 if (atomic_dec_and_lock(&c->entries, &clusterip_lock)) { 106 if (atomic_dec_and_lock(&c->entries, &cn->lock)) {
97 list_del_rcu(&c->list); 107 list_del_rcu(&c->list);
98 spin_unlock(&clusterip_lock); 108 spin_unlock(&cn->lock);
99 local_bh_enable(); 109 local_bh_enable();
100 110
101 dev_mc_del(c->dev, c->clustermac); 111 dev_mc_del(c->dev, c->clustermac);
@@ -113,11 +123,12 @@ clusterip_config_entry_put(struct clusterip_config *c)
113} 123}
114 124
115static struct clusterip_config * 125static struct clusterip_config *
116__clusterip_config_find(__be32 clusterip) 126__clusterip_config_find(struct net *net, __be32 clusterip)
117{ 127{
118 struct clusterip_config *c; 128 struct clusterip_config *c;
129 struct clusterip_net *cn = net_generic(net, clusterip_net_id);
119 130
120 list_for_each_entry_rcu(c, &clusterip_configs, list) { 131 list_for_each_entry_rcu(c, &cn->configs, list) {
121 if (c->clusterip == clusterip) 132 if (c->clusterip == clusterip)
122 return c; 133 return c;
123 } 134 }
@@ -126,12 +137,12 @@ __clusterip_config_find(__be32 clusterip)
126} 137}
127 138
128static inline struct clusterip_config * 139static inline struct clusterip_config *
129clusterip_config_find_get(__be32 clusterip, int entry) 140clusterip_config_find_get(struct net *net, __be32 clusterip, int entry)
130{ 141{
131 struct clusterip_config *c; 142 struct clusterip_config *c;
132 143
133 rcu_read_lock_bh(); 144 rcu_read_lock_bh();
134 c = __clusterip_config_find(clusterip); 145 c = __clusterip_config_find(net, clusterip);
135 if (c) { 146 if (c) {
136 if (unlikely(!atomic_inc_not_zero(&c->refcount))) 147 if (unlikely(!atomic_inc_not_zero(&c->refcount)))
137 c = NULL; 148 c = NULL;
@@ -158,6 +169,7 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
158 struct net_device *dev) 169 struct net_device *dev)
159{ 170{
160 struct clusterip_config *c; 171 struct clusterip_config *c;
172 struct clusterip_net *cn = net_generic(dev_net(dev), clusterip_net_id);
161 173
162 c = kzalloc(sizeof(*c), GFP_ATOMIC); 174 c = kzalloc(sizeof(*c), GFP_ATOMIC);
163 if (!c) 175 if (!c)
@@ -180,7 +192,7 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
180 /* create proc dir entry */ 192 /* create proc dir entry */
181 sprintf(buffer, "%pI4", &ip); 193 sprintf(buffer, "%pI4", &ip);
182 c->pde = proc_create_data(buffer, S_IWUSR|S_IRUSR, 194 c->pde = proc_create_data(buffer, S_IWUSR|S_IRUSR,
183 clusterip_procdir, 195 cn->procdir,
184 &clusterip_proc_fops, c); 196 &clusterip_proc_fops, c);
185 if (!c->pde) { 197 if (!c->pde) {
186 kfree(c); 198 kfree(c);
@@ -189,9 +201,9 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
189 } 201 }
190#endif 202#endif
191 203
192 spin_lock_bh(&clusterip_lock); 204 spin_lock_bh(&cn->lock);
193 list_add_rcu(&c->list, &clusterip_configs); 205 list_add_rcu(&c->list, &cn->configs);
194 spin_unlock_bh(&clusterip_lock); 206 spin_unlock_bh(&cn->lock);
195 207
196 return c; 208 return c;
197} 209}
@@ -370,7 +382,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
370 382
371 /* FIXME: further sanity checks */ 383 /* FIXME: further sanity checks */
372 384
373 config = clusterip_config_find_get(e->ip.dst.s_addr, 1); 385 config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1);
374 if (!config) { 386 if (!config) {
375 if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) { 387 if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
376 pr_info("no config found for %pI4, need 'new'\n", 388 pr_info("no config found for %pI4, need 'new'\n",
@@ -384,7 +396,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
384 return -EINVAL; 396 return -EINVAL;
385 } 397 }
386 398
387 dev = dev_get_by_name(&init_net, e->ip.iniface); 399 dev = dev_get_by_name(par->net, e->ip.iniface);
388 if (!dev) { 400 if (!dev) {
389 pr_info("no such interface %s\n", 401 pr_info("no such interface %s\n",
390 e->ip.iniface); 402 e->ip.iniface);
@@ -492,6 +504,7 @@ arp_mangle(const struct nf_hook_ops *ops,
492 struct arphdr *arp = arp_hdr(skb); 504 struct arphdr *arp = arp_hdr(skb);
493 struct arp_payload *payload; 505 struct arp_payload *payload;
494 struct clusterip_config *c; 506 struct clusterip_config *c;
507 struct net *net = dev_net(in ? in : out);
495 508
496 /* we don't care about non-ethernet and non-ipv4 ARP */ 509 /* we don't care about non-ethernet and non-ipv4 ARP */
497 if (arp->ar_hrd != htons(ARPHRD_ETHER) || 510 if (arp->ar_hrd != htons(ARPHRD_ETHER) ||
@@ -508,7 +521,7 @@ arp_mangle(const struct nf_hook_ops *ops,
508 521
509 /* if there is no clusterip configuration for the arp reply's 522 /* if there is no clusterip configuration for the arp reply's
510 * source ip, we don't want to mangle it */ 523 * source ip, we don't want to mangle it */
511 c = clusterip_config_find_get(payload->src_ip, 0); 524 c = clusterip_config_find_get(net, payload->src_ip, 0);
512 if (!c) 525 if (!c)
513 return NF_ACCEPT; 526 return NF_ACCEPT;
514 527
@@ -698,48 +711,75 @@ static const struct file_operations clusterip_proc_fops = {
698 711
699#endif /* CONFIG_PROC_FS */ 712#endif /* CONFIG_PROC_FS */
700 713
714static int clusterip_net_init(struct net *net)
715{
716 struct clusterip_net *cn = net_generic(net, clusterip_net_id);
717
718 INIT_LIST_HEAD(&cn->configs);
719
720 spin_lock_init(&cn->lock);
721
722#ifdef CONFIG_PROC_FS
723 cn->procdir = proc_mkdir("ipt_CLUSTERIP", net->proc_net);
724 if (!cn->procdir) {
725 pr_err("Unable to proc dir entry\n");
726 return -ENOMEM;
727 }
728#endif /* CONFIG_PROC_FS */
729
730 return 0;
731}
732
733static void clusterip_net_exit(struct net *net)
734{
735#ifdef CONFIG_PROC_FS
736 struct clusterip_net *cn = net_generic(net, clusterip_net_id);
737 proc_remove(cn->procdir);
738#endif
739}
740
741static struct pernet_operations clusterip_net_ops = {
742 .init = clusterip_net_init,
743 .exit = clusterip_net_exit,
744 .id = &clusterip_net_id,
745 .size = sizeof(struct clusterip_net),
746};
747
701static int __init clusterip_tg_init(void) 748static int __init clusterip_tg_init(void)
702{ 749{
703 int ret; 750 int ret;
704 751
705 ret = xt_register_target(&clusterip_tg_reg); 752 ret = register_pernet_subsys(&clusterip_net_ops);
706 if (ret < 0) 753 if (ret < 0)
707 return ret; 754 return ret;
708 755
756 ret = xt_register_target(&clusterip_tg_reg);
757 if (ret < 0)
758 goto cleanup_subsys;
759
709 ret = nf_register_hook(&cip_arp_ops); 760 ret = nf_register_hook(&cip_arp_ops);
710 if (ret < 0) 761 if (ret < 0)
711 goto cleanup_target; 762 goto cleanup_target;
712 763
713#ifdef CONFIG_PROC_FS
714 clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net);
715 if (!clusterip_procdir) {
716 pr_err("Unable to proc dir entry\n");
717 ret = -ENOMEM;
718 goto cleanup_hook;
719 }
720#endif /* CONFIG_PROC_FS */
721
722 pr_info("ClusterIP Version %s loaded successfully\n", 764 pr_info("ClusterIP Version %s loaded successfully\n",
723 CLUSTERIP_VERSION); 765 CLUSTERIP_VERSION);
766
724 return 0; 767 return 0;
725 768
726#ifdef CONFIG_PROC_FS
727cleanup_hook:
728 nf_unregister_hook(&cip_arp_ops);
729#endif /* CONFIG_PROC_FS */
730cleanup_target: 769cleanup_target:
731 xt_unregister_target(&clusterip_tg_reg); 770 xt_unregister_target(&clusterip_tg_reg);
771cleanup_subsys:
772 unregister_pernet_subsys(&clusterip_net_ops);
732 return ret; 773 return ret;
733} 774}
734 775
735static void __exit clusterip_tg_exit(void) 776static void __exit clusterip_tg_exit(void)
736{ 777{
737 pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION); 778 pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION);
738#ifdef CONFIG_PROC_FS 779
739 proc_remove(clusterip_procdir);
740#endif
741 nf_unregister_hook(&cip_arp_ops); 780 nf_unregister_hook(&cip_arp_ops);
742 xt_unregister_target(&clusterip_tg_reg); 781 xt_unregister_target(&clusterip_tg_reg);
782 unregister_pernet_subsys(&clusterip_net_ops);
743 783
744 /* Wait for completion of call_rcu_bh()'s (clusterip_config_rcu_free) */ 784 /* Wait for completion of call_rcu_bh()'s (clusterip_config_rcu_free) */
745 rcu_barrier_bh(); 785 rcu_barrier_bh();