diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
commit | 0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch) | |
tree | 454d1842b1833d976da62abcbd5c47521ebe9bd7 /net/bridge | |
parent | 54a696bd07c14d3b1192d03ce7269bc59b45209a (diff) | |
parent | eb56092fc168bf5af199d47af50c0d84a96db898 (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.c | 20 | ||||
-rw-r--r-- | net/bridge/br_if.c | 4 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 13 | ||||
-rw-r--r-- | net/bridge/br_sysfs_br.c | 2 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_log.c | 18 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_broute.c | 26 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_filter.c | 41 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_nat.c | 38 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 52 |
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 | ||
150 | static struct ethtool_ops br_ethtool_ops = { | 150 | static 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 | ||
163 | static 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 | |||
163 | void br_dev_setup(struct net_device *dev) | 173 | void 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) | |||
460 | restart: | 460 | restart: |
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] | ||
83 | static void | 82 | static void |
84 | ebt_log_packet(u_int8_t pf, unsigned int hooknum, | 83 | ebt_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 | } |
188 | out: | 182 | out: |
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 | ||
65 | static 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 | |||
73 | static void __net_exit broute_net_exit(struct net *net) | ||
74 | { | ||
75 | ebt_unregister_table(net->xt.broute_table); | ||
76 | } | ||
77 | |||
78 | static struct pernet_operations broute_net_ops = { | ||
79 | .init = broute_net_init, | ||
80 | .exit = broute_net_exit, | ||
81 | }; | ||
82 | |||
65 | static int __init ebtable_broute_init(void) | 83 | static 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 | ||
77 | static void __exit ebtable_broute_fini(void) | 95 | static 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 | ||
84 | module_init(ebtable_broute_init); | 102 | module_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 | ||
63 | static unsigned int | 63 | static unsigned int |
64 | ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, | 64 | ebt_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 | |||
70 | static unsigned int | ||
71 | ebt_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 | ||
70 | static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { | 77 | static 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 | ||
101 | static 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 | |||
109 | static void __net_exit frame_filter_net_exit(struct net *net) | ||
110 | { | ||
111 | ebt_unregister_table(net->xt.frame_filter); | ||
112 | } | ||
113 | |||
114 | static struct pernet_operations frame_filter_net_ops = { | ||
115 | .init = frame_filter_net_init, | ||
116 | .exit = frame_filter_net_exit, | ||
117 | }; | ||
118 | |||
94 | static int __init ebtable_filter_init(void) | 119 | static 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 | ||
107 | static void __exit ebtable_filter_fini(void) | 132 | static 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 | ||
113 | module_init(ebtable_filter_init); | 138 | module_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 | ||
63 | static unsigned int | 63 | static unsigned int |
64 | ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in | 64 | ebt_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 | ||
70 | static unsigned int | 70 | static unsigned int |
71 | ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in | 71 | ebt_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 | ||
77 | static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { | 77 | static 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 | ||
101 | static 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 | |||
109 | static void __net_exit frame_nat_net_exit(struct net *net) | ||
110 | { | ||
111 | ebt_unregister_table(net->xt.frame_nat); | ||
112 | } | ||
113 | |||
114 | static struct pernet_operations frame_nat_net_ops = { | ||
115 | .init = frame_nat_net_init, | ||
116 | .exit = frame_nat_net_exit, | ||
117 | }; | ||
118 | |||
101 | static int __init ebtable_nat_init(void) | 119 | static 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 | ||
114 | static void __exit ebtable_nat_fini(void) | 132 | static 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 | ||
120 | module_init(ebtable_nat_init); | 138 | module_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 | ||
57 | static DEFINE_MUTEX(ebt_mutex); | 57 | static DEFINE_MUTEX(ebt_mutex); |
58 | static LIST_HEAD(ebt_tables); | ||
59 | 58 | ||
60 | static struct xt_target ebt_standard_target = { | 59 | static 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 | ||
317 | static inline struct ebt_table * | 316 | static inline struct ebt_table * |
318 | find_table_lock(const char *name, int *error, struct mutex *mutex) | 317 | find_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 | ||
323 | static inline int | 324 | static 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 */ |
947 | static int do_replace(void __user *user, unsigned int len) | 948 | static 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 | ||
1100 | int ebt_register_table(struct ebt_table *table) | 1101 | struct 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; |
1176 | free_unlock: | 1184 | free_unlock: |
1177 | mutex_unlock(&ebt_mutex); | 1185 | mutex_unlock(&ebt_mutex); |
1178 | free_chainstack: | 1186 | free_chainstack: |
@@ -1184,7 +1192,10 @@ free_chainstack: | |||
1184 | vfree(newinfo->entries); | 1192 | vfree(newinfo->entries); |
1185 | free_newinfo: | 1193 | free_newinfo: |
1186 | vfree(newinfo); | 1194 | vfree(newinfo); |
1187 | return ret; | 1195 | free_table: |
1196 | kfree(table); | ||
1197 | out: | ||
1198 | return ERR_PTR(ret); | ||
1188 | } | 1199 | } |
1189 | 1200 | ||
1190 | void ebt_unregister_table(struct ebt_table *table) | 1201 | void 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 */ |
1211 | static int update_counters(void __user *user, unsigned int len) | 1227 | static 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 | ||