aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
commit0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch)
tree454d1842b1833d976da62abcbd5c47521ebe9bd7 /net/bridge
parent54a696bd07c14d3b1192d03ce7269bc59b45209a (diff)
parenteb56092fc168bf5af199d47af50c0d84a96db898 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1429 commits) net: Allow dependancies of FDDI & Tokenring to be modular. igb: Fix build warning when DCA is disabled. net: Fix warning fallout from recent NAPI interface changes. gro: Fix potential use after free sfc: If AN is enabled, always read speed/duplex from the AN advertising bits sfc: When disabling the NIC, close the device rather than unregistering it sfc: SFT9001: Add cable diagnostics sfc: Add support for multiple PHY self-tests sfc: Merge top-level functions for self-tests sfc: Clean up PHY mode management in loopback self-test sfc: Fix unreliable link detection in some loopback modes sfc: Generate unique names for per-NIC workqueues 802.3ad: use standard ethhdr instead of ad_header 802.3ad: generalize out mac address initializer 802.3ad: initialize ports LACPDU from const initializer 802.3ad: remove typedef around ad_system 802.3ad: turn ports is_individual into a bool 802.3ad: turn ports is_enabled into a bool 802.3ad: make ntt bool ixgbe: Fix set_ringparam in ixgbe to use the same memory pools. ... Fixed trivial IPv4/6 address printing conflicts in fs/cifs/connect.c due to the conversion to %pI (in this networking merge) and the addition of doing IPv6 addresses (from the earlier merge of CIFS).
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c20
-rw-r--r--net/bridge/br_if.c4
-rw-r--r--net/bridge/br_netfilter.c13
-rw-r--r--net/bridge/br_sysfs_br.c2
-rw-r--r--net/bridge/netfilter/ebt_log.c18
-rw-r--r--net/bridge/netfilter/ebtable_broute.c26
-rw-r--r--net/bridge/netfilter/ebtable_filter.c41
-rw-r--r--net/bridge/netfilter/ebtable_nat.c38
-rw-r--r--net/bridge/netfilter/ebtables.c52
9 files changed, 144 insertions, 70 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 6c023f0f8252..18538d7460d7 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -147,7 +147,7 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
147 return 0; 147 return 0;
148} 148}
149 149
150static struct ethtool_ops br_ethtool_ops = { 150static const struct ethtool_ops br_ethtool_ops = {
151 .get_drvinfo = br_getinfo, 151 .get_drvinfo = br_getinfo,
152 .get_link = ethtool_op_get_link, 152 .get_link = ethtool_op_get_link,
153 .get_tx_csum = ethtool_op_get_tx_csum, 153 .get_tx_csum = ethtool_op_get_tx_csum,
@@ -160,21 +160,25 @@ static struct ethtool_ops br_ethtool_ops = {
160 .get_flags = ethtool_op_get_flags, 160 .get_flags = ethtool_op_get_flags,
161}; 161};
162 162
163static const struct net_device_ops br_netdev_ops = {
164 .ndo_open = br_dev_open,
165 .ndo_stop = br_dev_stop,
166 .ndo_start_xmit = br_dev_xmit,
167 .ndo_set_mac_address = br_set_mac_address,
168 .ndo_set_multicast_list = br_dev_set_multicast_list,
169 .ndo_change_mtu = br_change_mtu,
170 .ndo_do_ioctl = br_dev_ioctl,
171};
172
163void br_dev_setup(struct net_device *dev) 173void br_dev_setup(struct net_device *dev)
164{ 174{
165 random_ether_addr(dev->dev_addr); 175 random_ether_addr(dev->dev_addr);
166 ether_setup(dev); 176 ether_setup(dev);
167 177
168 dev->do_ioctl = br_dev_ioctl; 178 dev->netdev_ops = &br_netdev_ops;
169 dev->hard_start_xmit = br_dev_xmit;
170 dev->open = br_dev_open;
171 dev->set_multicast_list = br_dev_set_multicast_list;
172 dev->change_mtu = br_change_mtu;
173 dev->destructor = free_netdev; 179 dev->destructor = free_netdev;
174 SET_ETHTOOL_OPS(dev, &br_ethtool_ops); 180 SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
175 dev->stop = br_dev_stop;
176 dev->tx_queue_len = 0; 181 dev->tx_queue_len = 0;
177 dev->set_mac_address = br_set_mac_address;
178 dev->priv_flags = IFF_EBRIDGE; 182 dev->priv_flags = IFF_EBRIDGE;
179 183
180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 184 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 0a09ccf68c1c..727c5c510a60 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -373,7 +373,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
373 if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) 373 if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
374 return -EINVAL; 374 return -EINVAL;
375 375
376 if (dev->hard_start_xmit == br_dev_xmit) 376 if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit)
377 return -ELOOP; 377 return -ELOOP;
378 378
379 if (dev->br_port != NULL) 379 if (dev->br_port != NULL)
@@ -460,7 +460,7 @@ void br_net_exit(struct net *net)
460restart: 460restart:
461 for_each_netdev(net, dev) { 461 for_each_netdev(net, dev) {
462 if (dev->priv_flags & IFF_EBRIDGE) { 462 if (dev->priv_flags & IFF_EBRIDGE) {
463 del_br(dev->priv); 463 del_br(netdev_priv(dev));
464 goto restart; 464 goto restart;
465 } 465 }
466 } 466 }
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 45f61c348e36..a65e43a17fbb 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -109,7 +109,6 @@ static struct dst_ops fake_dst_ops = {
109 .family = AF_INET, 109 .family = AF_INET,
110 .protocol = __constant_htons(ETH_P_IP), 110 .protocol = __constant_htons(ETH_P_IP),
111 .update_pmtu = fake_update_pmtu, 111 .update_pmtu = fake_update_pmtu,
112 .entry_size = sizeof(struct rtable),
113 .entries = ATOMIC_INIT(0), 112 .entries = ATOMIC_INIT(0),
114}; 113};
115 114
@@ -370,7 +369,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
370 if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev)) 369 if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
371 goto free_skb; 370 goto free_skb;
372 371
373 if (!ip_route_output_key(&init_net, &rt, &fl)) { 372 if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
374 /* - Bridged-and-DNAT'ed traffic doesn't 373 /* - Bridged-and-DNAT'ed traffic doesn't
375 * require ip_forwarding. */ 374 * require ip_forwarding. */
376 if (((struct dst_entry *)rt)->dev == dev) { 375 if (((struct dst_entry *)rt)->dev == dev) {
@@ -951,35 +950,35 @@ static ctl_table brnf_table[] = {
951 .data = &brnf_call_arptables, 950 .data = &brnf_call_arptables,
952 .maxlen = sizeof(int), 951 .maxlen = sizeof(int),
953 .mode = 0644, 952 .mode = 0644,
954 .proc_handler = &brnf_sysctl_call_tables, 953 .proc_handler = brnf_sysctl_call_tables,
955 }, 954 },
956 { 955 {
957 .procname = "bridge-nf-call-iptables", 956 .procname = "bridge-nf-call-iptables",
958 .data = &brnf_call_iptables, 957 .data = &brnf_call_iptables,
959 .maxlen = sizeof(int), 958 .maxlen = sizeof(int),
960 .mode = 0644, 959 .mode = 0644,
961 .proc_handler = &brnf_sysctl_call_tables, 960 .proc_handler = brnf_sysctl_call_tables,
962 }, 961 },
963 { 962 {
964 .procname = "bridge-nf-call-ip6tables", 963 .procname = "bridge-nf-call-ip6tables",
965 .data = &brnf_call_ip6tables, 964 .data = &brnf_call_ip6tables,
966 .maxlen = sizeof(int), 965 .maxlen = sizeof(int),
967 .mode = 0644, 966 .mode = 0644,
968 .proc_handler = &brnf_sysctl_call_tables, 967 .proc_handler = brnf_sysctl_call_tables,
969 }, 968 },
970 { 969 {
971 .procname = "bridge-nf-filter-vlan-tagged", 970 .procname = "bridge-nf-filter-vlan-tagged",
972 .data = &brnf_filter_vlan_tagged, 971 .data = &brnf_filter_vlan_tagged,
973 .maxlen = sizeof(int), 972 .maxlen = sizeof(int),
974 .mode = 0644, 973 .mode = 0644,
975 .proc_handler = &brnf_sysctl_call_tables, 974 .proc_handler = brnf_sysctl_call_tables,
976 }, 975 },
977 { 976 {
978 .procname = "bridge-nf-filter-pppoe-tagged", 977 .procname = "bridge-nf-filter-pppoe-tagged",
979 .data = &brnf_filter_pppoe_tagged, 978 .data = &brnf_filter_pppoe_tagged,
980 .maxlen = sizeof(int), 979 .maxlen = sizeof(int),
981 .mode = 0644, 980 .mode = 0644,
982 .proc_handler = &brnf_sysctl_call_tables, 981 .proc_handler = brnf_sysctl_call_tables,
983 }, 982 },
984 { .ctl_name = 0 } 983 { .ctl_name = 0 }
985}; 984};
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 158dee8b4965..603d89248e71 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -22,7 +22,7 @@
22#include "br_private.h" 22#include "br_private.h"
23 23
24#define to_dev(obj) container_of(obj, struct device, kobj) 24#define to_dev(obj) container_of(obj, struct device, kobj)
25#define to_bridge(cd) ((struct net_bridge *)(to_net_dev(cd)->priv)) 25#define to_bridge(cd) ((struct net_bridge *)netdev_priv(to_net_dev(cd)))
26 26
27/* 27/*
28 * Common code for storing bridge parameters. 28 * Common code for storing bridge parameters.
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 3d33c608906a..d44cbf8c374a 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -79,7 +79,6 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
79 } 79 }
80} 80}
81 81
82#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
83static void 82static void
84ebt_log_packet(u_int8_t pf, unsigned int hooknum, 83ebt_log_packet(u_int8_t pf, unsigned int hooknum,
85 const struct sk_buff *skb, const struct net_device *in, 84 const struct sk_buff *skb, const struct net_device *in,
@@ -113,9 +112,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
113 printk(" INCOMPLETE IP header"); 112 printk(" INCOMPLETE IP header");
114 goto out; 113 goto out;
115 } 114 }
116 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP " 115 printk(" IP SRC=%pI4 IP DST=%pI4, IP tos=0x%02X, IP proto=%d",
117 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr), 116 &ih->saddr, &ih->daddr, ih->tos, ih->protocol);
118 NIPQUAD(ih->daddr), ih->tos, ih->protocol);
119 print_ports(skb, ih->protocol, ih->ihl*4); 117 print_ports(skb, ih->protocol, ih->ihl*4);
120 goto out; 118 goto out;
121 } 119 }
@@ -133,10 +131,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
133 printk(" INCOMPLETE IPv6 header"); 131 printk(" INCOMPLETE IPv6 header");
134 goto out; 132 goto out;
135 } 133 }
136 printk(" IPv6 SRC=%x:%x:%x:%x:%x:%x:%x:%x " 134 printk(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d",
137 "IPv6 DST=%x:%x:%x:%x:%x:%x:%x:%x, IPv6 " 135 &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr);
138 "priority=0x%01X, Next Header=%d", NIP6(ih->saddr),
139 NIP6(ih->daddr), ih->priority, ih->nexthdr);
140 nexthdr = ih->nexthdr; 136 nexthdr = ih->nexthdr;
141 offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr); 137 offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr);
142 if (offset_ph == -1) 138 if (offset_ph == -1)
@@ -177,12 +173,10 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
177 } 173 }
178 printk(" ARP MAC SRC="); 174 printk(" ARP MAC SRC=");
179 print_MAC(ap->mac_src); 175 print_MAC(ap->mac_src);
180 printk(" ARP IP SRC=%u.%u.%u.%u", 176 printk(" ARP IP SRC=%pI4", ap->ip_src);
181 myNIPQUAD(ap->ip_src));
182 printk(" ARP MAC DST="); 177 printk(" ARP MAC DST=");
183 print_MAC(ap->mac_dst); 178 print_MAC(ap->mac_dst);
184 printk(" ARP IP DST=%u.%u.%u.%u", 179 printk(" ARP IP DST=%pI4", ap->ip_dst);
185 myNIPQUAD(ap->ip_dst));
186 } 180 }
187 } 181 }
188out: 182out:
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index 246626bb0c87..8604dfc1fc3b 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -56,29 +56,47 @@ static int ebt_broute(struct sk_buff *skb)
56 int ret; 56 int ret;
57 57
58 ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL, 58 ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL,
59 &broute_table); 59 dev_net(skb->dev)->xt.broute_table);
60 if (ret == NF_DROP) 60 if (ret == NF_DROP)
61 return 1; /* route it */ 61 return 1; /* route it */
62 return 0; /* bridge it */ 62 return 0; /* bridge it */
63} 63}
64 64
65static int __net_init broute_net_init(struct net *net)
66{
67 net->xt.broute_table = ebt_register_table(net, &broute_table);
68 if (IS_ERR(net->xt.broute_table))
69 return PTR_ERR(net->xt.broute_table);
70 return 0;
71}
72
73static void __net_exit broute_net_exit(struct net *net)
74{
75 ebt_unregister_table(net->xt.broute_table);
76}
77
78static struct pernet_operations broute_net_ops = {
79 .init = broute_net_init,
80 .exit = broute_net_exit,
81};
82
65static int __init ebtable_broute_init(void) 83static int __init ebtable_broute_init(void)
66{ 84{
67 int ret; 85 int ret;
68 86
69 ret = ebt_register_table(&broute_table); 87 ret = register_pernet_subsys(&broute_net_ops);
70 if (ret < 0) 88 if (ret < 0)
71 return ret; 89 return ret;
72 /* see br_input.c */ 90 /* see br_input.c */
73 rcu_assign_pointer(br_should_route_hook, ebt_broute); 91 rcu_assign_pointer(br_should_route_hook, ebt_broute);
74 return ret; 92 return 0;
75} 93}
76 94
77static void __exit ebtable_broute_fini(void) 95static void __exit ebtable_broute_fini(void)
78{ 96{
79 rcu_assign_pointer(br_should_route_hook, NULL); 97 rcu_assign_pointer(br_should_route_hook, NULL);
80 synchronize_net(); 98 synchronize_net();
81 ebt_unregister_table(&broute_table); 99 unregister_pernet_subsys(&broute_net_ops);
82} 100}
83 101
84module_init(ebtable_broute_init); 102module_init(ebtable_broute_init);
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index 1a58af51a2e2..2b2e8040a9c6 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -61,29 +61,36 @@ static struct ebt_table frame_filter =
61}; 61};
62 62
63static unsigned int 63static unsigned int
64ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, 64ebt_in_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
65 const struct net_device *out, int (*okfn)(struct sk_buff *)) 65 const struct net_device *out, int (*okfn)(struct sk_buff *))
66{ 66{
67 return ebt_do_table(hook, skb, in, out, &frame_filter); 67 return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_filter);
68}
69
70static unsigned int
71ebt_out_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
72 const struct net_device *out, int (*okfn)(struct sk_buff *))
73{
74 return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_filter);
68} 75}
69 76
70static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { 77static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
71 { 78 {
72 .hook = ebt_hook, 79 .hook = ebt_in_hook,
73 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
74 .pf = PF_BRIDGE, 81 .pf = PF_BRIDGE,
75 .hooknum = NF_BR_LOCAL_IN, 82 .hooknum = NF_BR_LOCAL_IN,
76 .priority = NF_BR_PRI_FILTER_BRIDGED, 83 .priority = NF_BR_PRI_FILTER_BRIDGED,
77 }, 84 },
78 { 85 {
79 .hook = ebt_hook, 86 .hook = ebt_in_hook,
80 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
81 .pf = PF_BRIDGE, 88 .pf = PF_BRIDGE,
82 .hooknum = NF_BR_FORWARD, 89 .hooknum = NF_BR_FORWARD,
83 .priority = NF_BR_PRI_FILTER_BRIDGED, 90 .priority = NF_BR_PRI_FILTER_BRIDGED,
84 }, 91 },
85 { 92 {
86 .hook = ebt_hook, 93 .hook = ebt_out_hook,
87 .owner = THIS_MODULE, 94 .owner = THIS_MODULE,
88 .pf = PF_BRIDGE, 95 .pf = PF_BRIDGE,
89 .hooknum = NF_BR_LOCAL_OUT, 96 .hooknum = NF_BR_LOCAL_OUT,
@@ -91,23 +98,41 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
91 }, 98 },
92}; 99};
93 100
101static int __net_init frame_filter_net_init(struct net *net)
102{
103 net->xt.frame_filter = ebt_register_table(net, &frame_filter);
104 if (IS_ERR(net->xt.frame_filter))
105 return PTR_ERR(net->xt.frame_filter);
106 return 0;
107}
108
109static void __net_exit frame_filter_net_exit(struct net *net)
110{
111 ebt_unregister_table(net->xt.frame_filter);
112}
113
114static struct pernet_operations frame_filter_net_ops = {
115 .init = frame_filter_net_init,
116 .exit = frame_filter_net_exit,
117};
118
94static int __init ebtable_filter_init(void) 119static int __init ebtable_filter_init(void)
95{ 120{
96 int ret; 121 int ret;
97 122
98 ret = ebt_register_table(&frame_filter); 123 ret = register_pernet_subsys(&frame_filter_net_ops);
99 if (ret < 0) 124 if (ret < 0)
100 return ret; 125 return ret;
101 ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 126 ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
102 if (ret < 0) 127 if (ret < 0)
103 ebt_unregister_table(&frame_filter); 128 unregister_pernet_subsys(&frame_filter_net_ops);
104 return ret; 129 return ret;
105} 130}
106 131
107static void __exit ebtable_filter_fini(void) 132static void __exit ebtable_filter_fini(void)
108{ 133{
109 nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 134 nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
110 ebt_unregister_table(&frame_filter); 135 unregister_pernet_subsys(&frame_filter_net_ops);
111} 136}
112 137
113module_init(ebtable_filter_init); 138module_init(ebtable_filter_init);
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index f60c1e78e575..3fe1ae87e35f 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -61,36 +61,36 @@ static struct ebt_table frame_nat =
61}; 61};
62 62
63static unsigned int 63static unsigned int
64ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in 64ebt_nat_in(unsigned int hook, struct sk_buff *skb, const struct net_device *in
65 , const struct net_device *out, int (*okfn)(struct sk_buff *)) 65 , const struct net_device *out, int (*okfn)(struct sk_buff *))
66{ 66{
67 return ebt_do_table(hook, skb, in, out, &frame_nat); 67 return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_nat);
68} 68}
69 69
70static unsigned int 70static unsigned int
71ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in 71ebt_nat_out(unsigned int hook, struct sk_buff *skb, const struct net_device *in
72 , const struct net_device *out, int (*okfn)(struct sk_buff *)) 72 , const struct net_device *out, int (*okfn)(struct sk_buff *))
73{ 73{
74 return ebt_do_table(hook, skb, in, out, &frame_nat); 74 return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_nat);
75} 75}
76 76
77static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { 77static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
78 { 78 {
79 .hook = ebt_nat_dst, 79 .hook = ebt_nat_out,
80 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
81 .pf = PF_BRIDGE, 81 .pf = PF_BRIDGE,
82 .hooknum = NF_BR_LOCAL_OUT, 82 .hooknum = NF_BR_LOCAL_OUT,
83 .priority = NF_BR_PRI_NAT_DST_OTHER, 83 .priority = NF_BR_PRI_NAT_DST_OTHER,
84 }, 84 },
85 { 85 {
86 .hook = ebt_nat_src, 86 .hook = ebt_nat_out,
87 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
88 .pf = PF_BRIDGE, 88 .pf = PF_BRIDGE,
89 .hooknum = NF_BR_POST_ROUTING, 89 .hooknum = NF_BR_POST_ROUTING,
90 .priority = NF_BR_PRI_NAT_SRC, 90 .priority = NF_BR_PRI_NAT_SRC,
91 }, 91 },
92 { 92 {
93 .hook = ebt_nat_dst, 93 .hook = ebt_nat_in,
94 .owner = THIS_MODULE, 94 .owner = THIS_MODULE,
95 .pf = PF_BRIDGE, 95 .pf = PF_BRIDGE,
96 .hooknum = NF_BR_PRE_ROUTING, 96 .hooknum = NF_BR_PRE_ROUTING,
@@ -98,23 +98,41 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
98 }, 98 },
99}; 99};
100 100
101static int __net_init frame_nat_net_init(struct net *net)
102{
103 net->xt.frame_nat = ebt_register_table(net, &frame_nat);
104 if (IS_ERR(net->xt.frame_nat))
105 return PTR_ERR(net->xt.frame_nat);
106 return 0;
107}
108
109static void __net_exit frame_nat_net_exit(struct net *net)
110{
111 ebt_unregister_table(net->xt.frame_nat);
112}
113
114static struct pernet_operations frame_nat_net_ops = {
115 .init = frame_nat_net_init,
116 .exit = frame_nat_net_exit,
117};
118
101static int __init ebtable_nat_init(void) 119static int __init ebtable_nat_init(void)
102{ 120{
103 int ret; 121 int ret;
104 122
105 ret = ebt_register_table(&frame_nat); 123 ret = register_pernet_subsys(&frame_nat_net_ops);
106 if (ret < 0) 124 if (ret < 0)
107 return ret; 125 return ret;
108 ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); 126 ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
109 if (ret < 0) 127 if (ret < 0)
110 ebt_unregister_table(&frame_nat); 128 unregister_pernet_subsys(&frame_nat_net_ops);
111 return ret; 129 return ret;
112} 130}
113 131
114static void __exit ebtable_nat_fini(void) 132static void __exit ebtable_nat_fini(void)
115{ 133{
116 nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); 134 nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
117 ebt_unregister_table(&frame_nat); 135 unregister_pernet_subsys(&frame_nat_net_ops);
118} 136}
119 137
120module_init(ebtable_nat_init); 138module_init(ebtable_nat_init);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 0fa208e86405..fa108c46e851 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -55,7 +55,6 @@
55 55
56 56
57static DEFINE_MUTEX(ebt_mutex); 57static DEFINE_MUTEX(ebt_mutex);
58static LIST_HEAD(ebt_tables);
59 58
60static struct xt_target ebt_standard_target = { 59static struct xt_target ebt_standard_target = {
61 .name = "standard", 60 .name = "standard",
@@ -315,9 +314,11 @@ find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
315} 314}
316 315
317static inline struct ebt_table * 316static inline struct ebt_table *
318find_table_lock(const char *name, int *error, struct mutex *mutex) 317find_table_lock(struct net *net, const char *name, int *error,
318 struct mutex *mutex)
319{ 319{
320 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); 320 return find_inlist_lock(&net->xt.tables[NFPROTO_BRIDGE], name,
321 "ebtable_", error, mutex);
321} 322}
322 323
323static inline int 324static inline int
@@ -944,7 +945,7 @@ static void get_counters(struct ebt_counter *oldcounters,
944} 945}
945 946
946/* replace the table */ 947/* replace the table */
947static int do_replace(void __user *user, unsigned int len) 948static int do_replace(struct net *net, void __user *user, unsigned int len)
948{ 949{
949 int ret, i, countersize; 950 int ret, i, countersize;
950 struct ebt_table_info *newinfo; 951 struct ebt_table_info *newinfo;
@@ -1016,7 +1017,7 @@ static int do_replace(void __user *user, unsigned int len)
1016 if (ret != 0) 1017 if (ret != 0)
1017 goto free_counterstmp; 1018 goto free_counterstmp;
1018 1019
1019 t = find_table_lock(tmp.name, &ret, &ebt_mutex); 1020 t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
1020 if (!t) { 1021 if (!t) {
1021 ret = -ENOENT; 1022 ret = -ENOENT;
1022 goto free_iterate; 1023 goto free_iterate;
@@ -1097,7 +1098,7 @@ free_newinfo:
1097 return ret; 1098 return ret;
1098} 1099}
1099 1100
1100int ebt_register_table(struct ebt_table *table) 1101struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table)
1101{ 1102{
1102 struct ebt_table_info *newinfo; 1103 struct ebt_table_info *newinfo;
1103 struct ebt_table *t; 1104 struct ebt_table *t;
@@ -1109,14 +1110,21 @@ int ebt_register_table(struct ebt_table *table)
1109 repl->entries_size == 0 || 1110 repl->entries_size == 0 ||
1110 repl->counters || table->private) { 1111 repl->counters || table->private) {
1111 BUGPRINT("Bad table data for ebt_register_table!!!\n"); 1112 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1112 return -EINVAL; 1113 return ERR_PTR(-EINVAL);
1114 }
1115
1116 /* Don't add one table to multiple lists. */
1117 table = kmemdup(table, sizeof(struct ebt_table), GFP_KERNEL);
1118 if (!table) {
1119 ret = -ENOMEM;
1120 goto out;
1113 } 1121 }
1114 1122
1115 countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids; 1123 countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids;
1116 newinfo = vmalloc(sizeof(*newinfo) + countersize); 1124 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1117 ret = -ENOMEM; 1125 ret = -ENOMEM;
1118 if (!newinfo) 1126 if (!newinfo)
1119 return -ENOMEM; 1127 goto free_table;
1120 1128
1121 p = vmalloc(repl->entries_size); 1129 p = vmalloc(repl->entries_size);
1122 if (!p) 1130 if (!p)
@@ -1148,7 +1156,7 @@ int ebt_register_table(struct ebt_table *table)
1148 1156
1149 if (table->check && table->check(newinfo, table->valid_hooks)) { 1157 if (table->check && table->check(newinfo, table->valid_hooks)) {
1150 BUGPRINT("The table doesn't like its own initial data, lol\n"); 1158 BUGPRINT("The table doesn't like its own initial data, lol\n");
1151 return -EINVAL; 1159 return ERR_PTR(-EINVAL);
1152 } 1160 }
1153 1161
1154 table->private = newinfo; 1162 table->private = newinfo;
@@ -1157,7 +1165,7 @@ int ebt_register_table(struct ebt_table *table)
1157 if (ret != 0) 1165 if (ret != 0)
1158 goto free_chainstack; 1166 goto free_chainstack;
1159 1167
1160 list_for_each_entry(t, &ebt_tables, list) { 1168 list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
1161 if (strcmp(t->name, table->name) == 0) { 1169 if (strcmp(t->name, table->name) == 0) {
1162 ret = -EEXIST; 1170 ret = -EEXIST;
1163 BUGPRINT("Table name already exists\n"); 1171 BUGPRINT("Table name already exists\n");
@@ -1170,9 +1178,9 @@ int ebt_register_table(struct ebt_table *table)
1170 ret = -ENOENT; 1178 ret = -ENOENT;
1171 goto free_unlock; 1179 goto free_unlock;
1172 } 1180 }
1173 list_add(&table->list, &ebt_tables); 1181 list_add(&table->list, &net->xt.tables[NFPROTO_BRIDGE]);
1174 mutex_unlock(&ebt_mutex); 1182 mutex_unlock(&ebt_mutex);
1175 return 0; 1183 return table;
1176free_unlock: 1184free_unlock:
1177 mutex_unlock(&ebt_mutex); 1185 mutex_unlock(&ebt_mutex);
1178free_chainstack: 1186free_chainstack:
@@ -1184,7 +1192,10 @@ free_chainstack:
1184 vfree(newinfo->entries); 1192 vfree(newinfo->entries);
1185free_newinfo: 1193free_newinfo:
1186 vfree(newinfo); 1194 vfree(newinfo);
1187 return ret; 1195free_table:
1196 kfree(table);
1197out:
1198 return ERR_PTR(ret);
1188} 1199}
1189 1200
1190void ebt_unregister_table(struct ebt_table *table) 1201void ebt_unregister_table(struct ebt_table *table)
@@ -1198,6 +1209,10 @@ void ebt_unregister_table(struct ebt_table *table)
1198 mutex_lock(&ebt_mutex); 1209 mutex_lock(&ebt_mutex);
1199 list_del(&table->list); 1210 list_del(&table->list);
1200 mutex_unlock(&ebt_mutex); 1211 mutex_unlock(&ebt_mutex);
1212 EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
1213 ebt_cleanup_entry, NULL);
1214 if (table->private->nentries)
1215 module_put(table->me);
1201 vfree(table->private->entries); 1216 vfree(table->private->entries);
1202 if (table->private->chainstack) { 1217 if (table->private->chainstack) {
1203 for_each_possible_cpu(i) 1218 for_each_possible_cpu(i)
@@ -1205,10 +1220,11 @@ void ebt_unregister_table(struct ebt_table *table)
1205 vfree(table->private->chainstack); 1220 vfree(table->private->chainstack);
1206 } 1221 }
1207 vfree(table->private); 1222 vfree(table->private);
1223 kfree(table);
1208} 1224}
1209 1225
1210/* userspace just supplied us with counters */ 1226/* userspace just supplied us with counters */
1211static int update_counters(void __user *user, unsigned int len) 1227static int update_counters(struct net *net, void __user *user, unsigned int len)
1212{ 1228{
1213 int i, ret; 1229 int i, ret;
1214 struct ebt_counter *tmp; 1230 struct ebt_counter *tmp;
@@ -1228,7 +1244,7 @@ static int update_counters(void __user *user, unsigned int len)
1228 return -ENOMEM; 1244 return -ENOMEM;
1229 } 1245 }
1230 1246
1231 t = find_table_lock(hlp.name, &ret, &ebt_mutex); 1247 t = find_table_lock(net, hlp.name, &ret, &ebt_mutex);
1232 if (!t) 1248 if (!t)
1233 goto free_tmp; 1249 goto free_tmp;
1234 1250
@@ -1386,10 +1402,10 @@ static int do_ebt_set_ctl(struct sock *sk,
1386 1402
1387 switch(cmd) { 1403 switch(cmd) {
1388 case EBT_SO_SET_ENTRIES: 1404 case EBT_SO_SET_ENTRIES:
1389 ret = do_replace(user, len); 1405 ret = do_replace(sock_net(sk), user, len);
1390 break; 1406 break;
1391 case EBT_SO_SET_COUNTERS: 1407 case EBT_SO_SET_COUNTERS:
1392 ret = update_counters(user, len); 1408 ret = update_counters(sock_net(sk), user, len);
1393 break; 1409 break;
1394 default: 1410 default:
1395 ret = -EINVAL; 1411 ret = -EINVAL;
@@ -1406,7 +1422,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1406 if (copy_from_user(&tmp, user, sizeof(tmp))) 1422 if (copy_from_user(&tmp, user, sizeof(tmp)))
1407 return -EFAULT; 1423 return -EFAULT;
1408 1424
1409 t = find_table_lock(tmp.name, &ret, &ebt_mutex); 1425 t = find_table_lock(sock_net(sk), tmp.name, &ret, &ebt_mutex);
1410 if (!t) 1426 if (!t)
1411 return ret; 1427 return ret;
1412 1428