aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2006-01-07 03:50:18 -0500
committerLen Brown <len.brown@intel.com>2006-01-07 03:50:18 -0500
commited03f430cdc8c802652467e9097606fedc2c7abc (patch)
tree30941ec1e6f93e99358fefe18175e5dd800a4379 /net/bridge
parented349a8a0a780ed27e2a765f16cee54d9b63bfee (diff)
parent6f957eaf79356a32e838f5f262ee9a60544b1d5b (diff)
Pull pnpacpi into acpica branch
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br.c1
-rw-r--r--net/bridge/br_device.c91
-rw-r--r--net/bridge/br_if.c60
-rw-r--r--net/bridge/br_input.c13
-rw-r--r--net/bridge/br_netfilter.c36
-rw-r--r--net/bridge/br_notify.c14
-rw-r--r--net/bridge/br_private.h7
-rw-r--r--net/bridge/br_stp_if.c5
-rw-r--r--net/bridge/br_sysfs_if.c4
-rw-r--r--net/bridge/netfilter/Kconfig6
-rw-r--r--net/bridge/netfilter/ebt_log.c73
-rw-r--r--net/bridge/netfilter/ebt_ulog.c53
12 files changed, 289 insertions, 74 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index f8f184942aaf..188cc1ac49eb 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -67,3 +67,4 @@ EXPORT_SYMBOL(br_should_route_hook);
67module_init(br_init) 67module_init(br_init)
68module_exit(br_deinit) 68module_exit(br_deinit)
69MODULE_LICENSE("GPL"); 69MODULE_LICENSE("GPL");
70MODULE_VERSION(BR_VERSION);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f564ee99782d..0b33a7b3a00c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -15,7 +15,9 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/module.h> 18#include <linux/etherdevice.h>
19#include <linux/ethtool.h>
20
19#include <asm/uaccess.h> 21#include <asm/uaccess.h>
20#include "br_private.h" 22#include "br_private.h"
21 23
@@ -82,6 +84,87 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
82 return 0; 84 return 0;
83} 85}
84 86
87/* Allow setting mac address of pseudo-bridge to be same as
88 * any of the bound interfaces
89 */
90static int br_set_mac_address(struct net_device *dev, void *p)
91{
92 struct net_bridge *br = netdev_priv(dev);
93 struct sockaddr *addr = p;
94 struct net_bridge_port *port;
95 int err = -EADDRNOTAVAIL;
96
97 spin_lock_bh(&br->lock);
98 list_for_each_entry(port, &br->port_list, list) {
99 if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
100 br_stp_change_bridge_id(br, addr->sa_data);
101 err = 0;
102 break;
103 }
104 }
105 spin_unlock_bh(&br->lock);
106
107 return err;
108}
109
110static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
111{
112 strcpy(info->driver, "bridge");
113 strcpy(info->version, BR_VERSION);
114 strcpy(info->fw_version, "N/A");
115 strcpy(info->bus_info, "N/A");
116}
117
118static int br_set_sg(struct net_device *dev, u32 data)
119{
120 struct net_bridge *br = netdev_priv(dev);
121
122 if (data)
123 br->feature_mask |= NETIF_F_SG;
124 else
125 br->feature_mask &= ~NETIF_F_SG;
126
127 br_features_recompute(br);
128 return 0;
129}
130
131static int br_set_tso(struct net_device *dev, u32 data)
132{
133 struct net_bridge *br = netdev_priv(dev);
134
135 if (data)
136 br->feature_mask |= NETIF_F_TSO;
137 else
138 br->feature_mask &= ~NETIF_F_TSO;
139
140 br_features_recompute(br);
141 return 0;
142}
143
144static int br_set_tx_csum(struct net_device *dev, u32 data)
145{
146 struct net_bridge *br = netdev_priv(dev);
147
148 if (data)
149 br->feature_mask |= NETIF_F_IP_CSUM;
150 else
151 br->feature_mask &= ~NETIF_F_IP_CSUM;
152
153 br_features_recompute(br);
154 return 0;
155}
156
157static struct ethtool_ops br_ethtool_ops = {
158 .get_drvinfo = br_getinfo,
159 .get_link = ethtool_op_get_link,
160 .get_sg = ethtool_op_get_sg,
161 .set_sg = br_set_sg,
162 .get_tx_csum = ethtool_op_get_tx_csum,
163 .set_tx_csum = br_set_tx_csum,
164 .get_tso = ethtool_op_get_tso,
165 .set_tso = br_set_tso,
166};
167
85void br_dev_setup(struct net_device *dev) 168void br_dev_setup(struct net_device *dev)
86{ 169{
87 memset(dev->dev_addr, 0, ETH_ALEN); 170 memset(dev->dev_addr, 0, ETH_ALEN);
@@ -96,8 +179,12 @@ void br_dev_setup(struct net_device *dev)
96 dev->change_mtu = br_change_mtu; 179 dev->change_mtu = br_change_mtu;
97 dev->destructor = free_netdev; 180 dev->destructor = free_netdev;
98 SET_MODULE_OWNER(dev); 181 SET_MODULE_OWNER(dev);
182 SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
99 dev->stop = br_dev_stop; 183 dev->stop = br_dev_stop;
100 dev->tx_queue_len = 0; 184 dev->tx_queue_len = 0;
101 dev->set_mac_address = NULL; 185 dev->set_mac_address = br_set_mac_address;
102 dev->priv_flags = IFF_EBRIDGE; 186 dev->priv_flags = IFF_EBRIDGE;
187
188 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
189 | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
103} 190}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 975abe254b7a..ba442883e877 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -20,6 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/if_ether.h>
23#include <net/sock.h> 24#include <net/sock.h>
24 25
25#include "br_private.h" 26#include "br_private.h"
@@ -32,9 +33,8 @@
32 * ethtool, use ethtool_ops. Also, since driver might sleep need to 33 * ethtool, use ethtool_ops. Also, since driver might sleep need to
33 * not be holding any locks. 34 * not be holding any locks.
34 */ 35 */
35static int br_initial_port_cost(struct net_device *dev) 36static int port_cost(struct net_device *dev)
36{ 37{
37
38 struct ethtool_cmd ecmd = { ETHTOOL_GSET }; 38 struct ethtool_cmd ecmd = { ETHTOOL_GSET };
39 struct ifreq ifr; 39 struct ifreq ifr;
40 mm_segment_t old_fs; 40 mm_segment_t old_fs;
@@ -58,10 +58,6 @@ static int br_initial_port_cost(struct net_device *dev)
58 return 2; 58 return 2;
59 case SPEED_10: 59 case SPEED_10:
60 return 100; 60 return 100;
61 default:
62 pr_info("bridge: can't decode speed from %s: %d\n",
63 dev->name, ecmd.speed);
64 return 100;
65 } 61 }
66 } 62 }
67 63
@@ -75,6 +71,35 @@ static int br_initial_port_cost(struct net_device *dev)
75 return 100; /* assume old 10Mbps */ 71 return 100; /* assume old 10Mbps */
76} 72}
77 73
74
75/*
76 * Check for port carrier transistions.
77 * Called from work queue to allow for calling functions that
78 * might sleep (such as speed check), and to debounce.
79 */
80static void port_carrier_check(void *arg)
81{
82 struct net_bridge_port *p = arg;
83
84 rtnl_lock();
85 if (netif_carrier_ok(p->dev)) {
86 u32 cost = port_cost(p->dev);
87
88 spin_lock_bh(&p->br->lock);
89 if (p->state == BR_STATE_DISABLED) {
90 p->path_cost = cost;
91 br_stp_enable_port(p);
92 }
93 spin_unlock_bh(&p->br->lock);
94 } else {
95 spin_lock_bh(&p->br->lock);
96 if (p->state != BR_STATE_DISABLED)
97 br_stp_disable_port(p);
98 spin_unlock_bh(&p->br->lock);
99 }
100 rtnl_unlock();
101}
102
78static void destroy_nbp(struct net_bridge_port *p) 103static void destroy_nbp(struct net_bridge_port *p)
79{ 104{
80 struct net_device *dev = p->dev; 105 struct net_device *dev = p->dev;
@@ -102,6 +127,9 @@ static void del_nbp(struct net_bridge_port *p)
102 dev->br_port = NULL; 127 dev->br_port = NULL;
103 dev_set_promiscuity(dev, -1); 128 dev_set_promiscuity(dev, -1);
104 129
130 cancel_delayed_work(&p->carrier_check);
131 flush_scheduled_work();
132
105 spin_lock_bh(&br->lock); 133 spin_lock_bh(&br->lock);
106 br_stp_disable_port(p); 134 br_stp_disable_port(p);
107 spin_unlock_bh(&br->lock); 135 spin_unlock_bh(&br->lock);
@@ -155,6 +183,7 @@ static struct net_device *new_bridge_dev(const char *name)
155 br->bridge_id.prio[1] = 0x00; 183 br->bridge_id.prio[1] = 0x00;
156 memset(br->bridge_id.addr, 0, ETH_ALEN); 184 memset(br->bridge_id.addr, 0, ETH_ALEN);
157 185
186 br->feature_mask = dev->features;
158 br->stp_enabled = 0; 187 br->stp_enabled = 0;
159 br->designated_root = br->bridge_id; 188 br->designated_root = br->bridge_id;
160 br->root_path_cost = 0; 189 br->root_path_cost = 0;
@@ -195,10 +224,9 @@ static int find_portno(struct net_bridge *br)
195 return (index >= BR_MAX_PORTS) ? -EXFULL : index; 224 return (index >= BR_MAX_PORTS) ? -EXFULL : index;
196} 225}
197 226
198/* called with RTNL */ 227/* called with RTNL but without bridge lock */
199static struct net_bridge_port *new_nbp(struct net_bridge *br, 228static struct net_bridge_port *new_nbp(struct net_bridge *br,
200 struct net_device *dev, 229 struct net_device *dev)
201 unsigned long cost)
202{ 230{
203 int index; 231 int index;
204 struct net_bridge_port *p; 232 struct net_bridge_port *p;
@@ -215,12 +243,13 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
215 p->br = br; 243 p->br = br;
216 dev_hold(dev); 244 dev_hold(dev);
217 p->dev = dev; 245 p->dev = dev;
218 p->path_cost = cost; 246 p->path_cost = port_cost(dev);
219 p->priority = 0x8000 >> BR_PORT_BITS; 247 p->priority = 0x8000 >> BR_PORT_BITS;
220 dev->br_port = p; 248 dev->br_port = p;
221 p->port_no = index; 249 p->port_no = index;
222 br_init_port(p); 250 br_init_port(p);
223 p->state = BR_STATE_DISABLED; 251 p->state = BR_STATE_DISABLED;
252 INIT_WORK(&p->carrier_check, port_carrier_check, p);
224 kobject_init(&p->kobj); 253 kobject_init(&p->kobj);
225 254
226 return p; 255 return p;
@@ -295,7 +324,7 @@ int br_del_bridge(const char *name)
295 return ret; 324 return ret;
296} 325}
297 326
298/* Mtu of the bridge pseudo-device 1500 or the minimum of the ports */ 327/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
299int br_min_mtu(const struct net_bridge *br) 328int br_min_mtu(const struct net_bridge *br)
300{ 329{
301 const struct net_bridge_port *p; 330 const struct net_bridge_port *p;
@@ -304,7 +333,7 @@ int br_min_mtu(const struct net_bridge *br)
304 ASSERT_RTNL(); 333 ASSERT_RTNL();
305 334
306 if (list_empty(&br->port_list)) 335 if (list_empty(&br->port_list))
307 mtu = 1500; 336 mtu = ETH_DATA_LEN;
308 else { 337 else {
309 list_for_each_entry(p, &br->port_list, list) { 338 list_for_each_entry(p, &br->port_list, list) {
310 if (!mtu || p->dev->mtu < mtu) 339 if (!mtu || p->dev->mtu < mtu)
@@ -322,9 +351,8 @@ void br_features_recompute(struct net_bridge *br)
322 struct net_bridge_port *p; 351 struct net_bridge_port *p;
323 unsigned long features, checksum; 352 unsigned long features, checksum;
324 353
325 features = NETIF_F_SG | NETIF_F_FRAGLIST 354 features = br->feature_mask &~ NETIF_F_IP_CSUM;
326 | NETIF_F_HIGHDMA | NETIF_F_TSO; 355 checksum = br->feature_mask & NETIF_F_IP_CSUM;
327 checksum = NETIF_F_IP_CSUM; /* least commmon subset */
328 356
329 list_for_each_entry(p, &br->port_list, list) { 357 list_for_each_entry(p, &br->port_list, list) {
330 if (!(p->dev->features 358 if (!(p->dev->features
@@ -351,7 +379,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
351 if (dev->br_port != NULL) 379 if (dev->br_port != NULL)
352 return -EBUSY; 380 return -EBUSY;
353 381
354 if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev)))) 382 if (IS_ERR(p = new_nbp(br, dev)))
355 return PTR_ERR(p); 383 return PTR_ERR(p);
356 384
357 if ((err = br_fdb_insert(br, p, dev->dev_addr))) 385 if ((err = br_fdb_insert(br, p, dev->dev_addr)))
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index b88220a64cd8..e3a73cead6b6 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -53,6 +53,11 @@ int br_handle_frame_finish(struct sk_buff *skb)
53 /* insert into forwarding database after filtering to avoid spoofing */ 53 /* insert into forwarding database after filtering to avoid spoofing */
54 br_fdb_update(p->br, p, eth_hdr(skb)->h_source); 54 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
55 55
56 if (p->state == BR_STATE_LEARNING) {
57 kfree_skb(skb);
58 goto out;
59 }
60
56 if (br->dev->flags & IFF_PROMISC) { 61 if (br->dev->flags & IFF_PROMISC) {
57 struct sk_buff *skb2; 62 struct sk_buff *skb2;
58 63
@@ -63,7 +68,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
63 } 68 }
64 } 69 }
65 70
66 if (dest[0] & 1) { 71 if (is_multicast_ether_addr(dest)) {
67 br_flood_forward(br, skb, !passedup); 72 br_flood_forward(br, skb, !passedup);
68 if (!passedup) 73 if (!passedup)
69 br_pass_frame_up(br, skb); 74 br_pass_frame_up(br, skb);
@@ -107,9 +112,6 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
107 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 112 if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
108 goto err; 113 goto err;
109 114
110 if (p->state == BR_STATE_LEARNING)
111 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
112
113 if (p->br->stp_enabled && 115 if (p->br->stp_enabled &&
114 !memcmp(dest, bridge_ula, 5) && 116 !memcmp(dest, bridge_ula, 5) &&
115 !(dest[5] & 0xF0)) { 117 !(dest[5] & 0xF0)) {
@@ -118,9 +120,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
118 NULL, br_stp_handle_bpdu); 120 NULL, br_stp_handle_bpdu);
119 return 1; 121 return 1;
120 } 122 }
123 goto err;
121 } 124 }
122 125
123 else if (p->state == BR_STATE_FORWARDING) { 126 if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
124 if (br_should_route_hook) { 127 if (br_should_route_hook) {
125 if (br_should_route_hook(pskb)) 128 if (br_should_route_hook(pskb))
126 return 0; 129 return 0;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index d8e36b775125..7cac3fb9f809 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -26,6 +26,7 @@
26#include <linux/ip.h> 26#include <linux/ip.h>
27#include <linux/netdevice.h> 27#include <linux/netdevice.h>
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <linux/if_arp.h>
29#include <linux/if_ether.h> 30#include <linux/if_ether.h>
30#include <linux/if_vlan.h> 31#include <linux/if_vlan.h>
31#include <linux/netfilter_bridge.h> 32#include <linux/netfilter_bridge.h>
@@ -33,8 +34,11 @@
33#include <linux/netfilter_ipv6.h> 34#include <linux/netfilter_ipv6.h>
34#include <linux/netfilter_arp.h> 35#include <linux/netfilter_arp.h>
35#include <linux/in_route.h> 36#include <linux/in_route.h>
37
36#include <net/ip.h> 38#include <net/ip.h>
37#include <net/ipv6.h> 39#include <net/ipv6.h>
40#include <net/route.h>
41
38#include <asm/uaccess.h> 42#include <asm/uaccess.h>
39#include <asm/checksum.h> 43#include <asm/checksum.h>
40#include "br_private.h" 44#include "br_private.h"
@@ -295,7 +299,7 @@ static int check_hbh_len(struct sk_buff *skb)
295 len -= 2; 299 len -= 2;
296 300
297 while (len > 0) { 301 while (len > 0) {
298 int optlen = raw[off+1]+2; 302 int optlen = skb->nh.raw[off+1]+2;
299 303
300 switch (skb->nh.raw[off]) { 304 switch (skb->nh.raw[off]) {
301 case IPV6_TLV_PAD0: 305 case IPV6_TLV_PAD0:
@@ -308,18 +312,15 @@ static int check_hbh_len(struct sk_buff *skb)
308 case IPV6_TLV_JUMBO: 312 case IPV6_TLV_JUMBO:
309 if (skb->nh.raw[off+1] != 4 || (off&3) != 2) 313 if (skb->nh.raw[off+1] != 4 || (off&3) != 2)
310 goto bad; 314 goto bad;
311
312 pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2)); 315 pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2));
313 316 if (pkt_len <= IPV6_MAXPLEN ||
317 skb->nh.ipv6h->payload_len)
318 goto bad;
314 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) 319 if (pkt_len > skb->len - sizeof(struct ipv6hdr))
315 goto bad; 320 goto bad;
316 if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { 321 if (pskb_trim_rcsum(skb,
317 if (__pskb_trim(skb, 322 pkt_len+sizeof(struct ipv6hdr)))
318 pkt_len + sizeof(struct ipv6hdr))) 323 goto bad;
319 goto bad;
320 if (skb->ip_summed == CHECKSUM_HW)
321 skb->ip_summed = CHECKSUM_NONE;
322 }
323 break; 324 break;
324 default: 325 default:
325 if (optlen > len) 326 if (optlen > len)
@@ -372,6 +373,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
372 if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) 373 if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
373 goto inhdr_error; 374 goto inhdr_error;
374 375
376 nf_bridge_put(skb->nf_bridge);
375 if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) 377 if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
376 return NF_DROP; 378 return NF_DROP;
377 setup_pre_routing(skb); 379 setup_pre_routing(skb);
@@ -392,8 +394,9 @@ inhdr_error:
392 * target in particular. Save the original destination IP 394 * target in particular. Save the original destination IP
393 * address to be able to detect DNAT afterwards. */ 395 * address to be able to detect DNAT afterwards. */
394static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, 396static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
395 const struct net_device *in, const struct net_device *out, 397 const struct net_device *in,
396 int (*okfn)(struct sk_buff *)) 398 const struct net_device *out,
399 int (*okfn)(struct sk_buff *))
397{ 400{
398 struct iphdr *iph; 401 struct iphdr *iph;
399 __u32 len; 402 __u32 len;
@@ -410,8 +413,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
410 goto out; 413 goto out;
411 414
412 if (skb->protocol == __constant_htons(ETH_P_8021Q)) { 415 if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
416 u8 *vhdr = skb->data;
413 skb_pull(skb, VLAN_HLEN); 417 skb_pull(skb, VLAN_HLEN);
414 (skb)->nh.raw += VLAN_HLEN; 418 skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
419 skb->nh.raw += VLAN_HLEN;
415 } 420 }
416 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); 421 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
417 } 422 }
@@ -427,8 +432,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
427 goto out; 432 goto out;
428 433
429 if (skb->protocol == __constant_htons(ETH_P_8021Q)) { 434 if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
435 u8 *vhdr = skb->data;
430 skb_pull(skb, VLAN_HLEN); 436 skb_pull(skb, VLAN_HLEN);
431 (skb)->nh.raw += VLAN_HLEN; 437 skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
438 skb->nh.raw += VLAN_HLEN;
432 } 439 }
433 440
434 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 441 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
@@ -455,6 +462,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
455 skb->ip_summed = CHECKSUM_NONE; 462 skb->ip_summed = CHECKSUM_NONE;
456 } 463 }
457 464
465 nf_bridge_put(skb->nf_bridge);
458 if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) 466 if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
459 return NF_DROP; 467 return NF_DROP;
460 setup_pre_routing(skb); 468 setup_pre_routing(skb);
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 917311c6828b..a43a9c1d50d7 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -52,17 +52,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
52 br_stp_recalculate_bridge_id(br); 52 br_stp_recalculate_bridge_id(br);
53 break; 53 break;
54 54
55 case NETDEV_CHANGE: /* device is up but carrier changed */ 55 case NETDEV_CHANGE:
56 if (!(br->dev->flags & IFF_UP)) 56 if (br->dev->flags & IFF_UP)
57 break; 57 schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
58
59 if (netif_carrier_ok(dev)) {
60 if (p->state == BR_STATE_DISABLED)
61 br_stp_enable_port(p);
62 } else {
63 if (p->state != BR_STATE_DISABLED)
64 br_stp_disable_port(p);
65 }
66 break; 58 break;
67 59
68 case NETDEV_FEAT_CHANGE: 60 case NETDEV_FEAT_CHANGE:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index bdf95a74d8cd..c5bd631ffcd5 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -27,6 +27,10 @@
27#define BR_PORT_BITS 10 27#define BR_PORT_BITS 10
28#define BR_MAX_PORTS (1<<BR_PORT_BITS) 28#define BR_MAX_PORTS (1<<BR_PORT_BITS)
29 29
30#define BR_PORT_DEBOUNCE (HZ/10)
31
32#define BR_VERSION "2.1"
33
30typedef struct bridge_id bridge_id; 34typedef struct bridge_id bridge_id;
31typedef struct mac_addr mac_addr; 35typedef struct mac_addr mac_addr;
32typedef __u16 port_id; 36typedef __u16 port_id;
@@ -78,6 +82,7 @@ struct net_bridge_port
78 struct timer_list hold_timer; 82 struct timer_list hold_timer;
79 struct timer_list message_age_timer; 83 struct timer_list message_age_timer;
80 struct kobject kobj; 84 struct kobject kobj;
85 struct work_struct carrier_check;
81 struct rcu_head rcu; 86 struct rcu_head rcu;
82}; 87};
83 88
@@ -90,6 +95,7 @@ struct net_bridge
90 spinlock_t hash_lock; 95 spinlock_t hash_lock;
91 struct hlist_head hash[BR_HASH_SIZE]; 96 struct hlist_head hash[BR_HASH_SIZE];
92 struct list_head age_list; 97 struct list_head age_list;
98 unsigned long feature_mask;
93 99
94 /* STP */ 100 /* STP */
95 bridge_id designated_root; 101 bridge_id designated_root;
@@ -201,6 +207,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br);
201extern void br_stp_enable_port(struct net_bridge_port *p); 207extern void br_stp_enable_port(struct net_bridge_port *p);
202extern void br_stp_disable_port(struct net_bridge_port *p); 208extern void br_stp_disable_port(struct net_bridge_port *p);
203extern void br_stp_recalculate_bridge_id(struct net_bridge *br); 209extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
210extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
204extern void br_stp_set_bridge_priority(struct net_bridge *br, 211extern void br_stp_set_bridge_priority(struct net_bridge *br,
205 u16 newprio); 212 u16 newprio);
206extern void br_stp_set_port_priority(struct net_bridge_port *p, 213extern void br_stp_set_port_priority(struct net_bridge_port *p,
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index ac09b6a23523..cc047f7fb6ef 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -120,8 +120,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
120} 120}
121 121
122/* called under bridge lock */ 122/* called under bridge lock */
123static void br_stp_change_bridge_id(struct net_bridge *br, 123void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
124 const unsigned char *addr)
125{ 124{
126 unsigned char oldaddr[6]; 125 unsigned char oldaddr[6];
127 struct net_bridge_port *p; 126 struct net_bridge_port *p;
@@ -158,7 +157,7 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
158 157
159 list_for_each_entry(p, &br->port_list, list) { 158 list_for_each_entry(p, &br->port_list, list) {
160 if (addr == br_mac_zero || 159 if (addr == br_mac_zero ||
161 compare_ether_addr(p->dev->dev_addr, addr) < 0) 160 memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
162 addr = p->dev->dev_addr; 161 addr = p->dev->dev_addr;
163 162
164 } 163 }
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index f6a19d53eaeb..2ebdc23bbe26 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -248,7 +248,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
248 if (err) 248 if (err)
249 goto out2; 249 goto out2;
250 250
251 kobject_hotplug(&p->kobj, KOBJ_ADD); 251 kobject_uevent(&p->kobj, KOBJ_ADD);
252 return 0; 252 return 0;
253 out2: 253 out2:
254 kobject_del(&p->kobj); 254 kobject_del(&p->kobj);
@@ -260,7 +260,7 @@ void br_sysfs_removeif(struct net_bridge_port *p)
260{ 260{
261 pr_debug("br_sysfs_removeif\n"); 261 pr_debug("br_sysfs_removeif\n");
262 sysfs_remove_link(&p->br->ifobj, p->dev->name); 262 sysfs_remove_link(&p->br->ifobj, p->dev->name);
263 kobject_hotplug(&p->kobj, KOBJ_REMOVE); 263 kobject_uevent(&p->kobj, KOBJ_REMOVE);
264 kobject_del(&p->kobj); 264 kobject_del(&p->kobj);
265} 265}
266 266
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index c70b3be23026..b84fc6075fe1 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG
196 To compile it as a module, choose M here. If unsure, say N. 196 To compile it as a module, choose M here. If unsure, say N.
197 197
198config BRIDGE_EBT_ULOG 198config BRIDGE_EBT_ULOG
199 tristate "ebt: ulog support" 199 tristate "ebt: ulog support (OBSOLETE)"
200 depends on BRIDGE_NF_EBTABLES 200 depends on BRIDGE_NF_EBTABLES
201 help 201 help
202 This option enables the old bridge-specific "ebt_ulog" implementation
203 which has been obsoleted by the new "nfnetlink_log" code (see
204 CONFIG_NETFILTER_NETLINK_LOG).
205
202 This option adds the ulog watcher, that you can use in any rule 206 This option adds the ulog watcher, that you can use in any rule
203 in any ebtables table. The packet is passed to a userspace 207 in any ebtables table. The packet is passed to a userspace
204 logging daemon using netlink multicast sockets. This differs 208 logging daemon using netlink multicast sockets. This differs
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 662975be3d1d..9f6e0193ae10 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -3,13 +3,16 @@
3 * 3 *
4 * Authors: 4 * Authors:
5 * Bart De Schuymer <bdschuym@pandora.be> 5 * Bart De Schuymer <bdschuym@pandora.be>
6 * Harald Welte <laforge@netfilter.org>
6 * 7 *
7 * April, 2002 8 * April, 2002
8 * 9 *
9 */ 10 */
10 11
12#include <linux/in.h>
11#include <linux/netfilter_bridge/ebtables.h> 13#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_log.h> 14#include <linux/netfilter_bridge/ebt_log.h>
15#include <linux/netfilter.h>
13#include <linux/module.h> 16#include <linux/module.h>
14#include <linux/ip.h> 17#include <linux/ip.h>
15#include <linux/if_arp.h> 18#include <linux/if_arp.h>
@@ -55,27 +58,30 @@ static void print_MAC(unsigned char *p)
55} 58}
56 59
57#define myNIPQUAD(a) a[0], a[1], a[2], a[3] 60#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
58static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, 61static void
59 const struct net_device *in, const struct net_device *out, 62ebt_log_packet(unsigned int pf, unsigned int hooknum,
60 const void *data, unsigned int datalen) 63 const struct sk_buff *skb, const struct net_device *in,
64 const struct net_device *out, const struct nf_loginfo *loginfo,
65 const char *prefix)
61{ 66{
62 struct ebt_log_info *info = (struct ebt_log_info *)data; 67 unsigned int bitmask;
63 char level_string[4] = "< >";
64 68
65 level_string[1] = '0' + info->loglevel;
66 spin_lock_bh(&ebt_log_lock); 69 spin_lock_bh(&ebt_log_lock);
67 printk(level_string); 70 printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
68 printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", 71 prefix, in ? in->name : "", out ? out->name : "");
69 out ? out->name : "");
70 72
71 printk("MAC source = ");
72 print_MAC(eth_hdr(skb)->h_source); 73 print_MAC(eth_hdr(skb)->h_source);
73 printk("MAC dest = "); 74 printk("MAC dest = ");
74 print_MAC(eth_hdr(skb)->h_dest); 75 print_MAC(eth_hdr(skb)->h_dest);
75 76
76 printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); 77 printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
77 78
78 if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == 79 if (loginfo->type == NF_LOG_TYPE_LOG)
80 bitmask = loginfo->u.log.logflags;
81 else
82 bitmask = NF_LOG_MASK;
83
84 if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
79 htons(ETH_P_IP)){ 85 htons(ETH_P_IP)){
80 struct iphdr _iph, *ih; 86 struct iphdr _iph, *ih;
81 87
@@ -84,10 +90,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
84 printk(" INCOMPLETE IP header"); 90 printk(" INCOMPLETE IP header");
85 goto out; 91 goto out;
86 } 92 }
87 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", 93 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
88 NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); 94 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
89 printk(" IP tos=0x%02X, IP proto=%d", ih->tos, 95 NIPQUAD(ih->daddr), ih->tos, ih->protocol);
90 ih->protocol);
91 if (ih->protocol == IPPROTO_TCP || 96 if (ih->protocol == IPPROTO_TCP ||
92 ih->protocol == IPPROTO_UDP) { 97 ih->protocol == IPPROTO_UDP) {
93 struct tcpudphdr _ports, *pptr; 98 struct tcpudphdr _ports, *pptr;
@@ -104,7 +109,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
104 goto out; 109 goto out;
105 } 110 }
106 111
107 if ((info->bitmask & EBT_LOG_ARP) && 112 if ((bitmask & EBT_LOG_ARP) &&
108 ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || 113 ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
109 (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { 114 (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
110 struct arphdr _arph, *ah; 115 struct arphdr _arph, *ah;
@@ -144,6 +149,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
144out: 149out:
145 printk("\n"); 150 printk("\n");
146 spin_unlock_bh(&ebt_log_lock); 151 spin_unlock_bh(&ebt_log_lock);
152
153}
154
155static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
156 const struct net_device *in, const struct net_device *out,
157 const void *data, unsigned int datalen)
158{
159 struct ebt_log_info *info = (struct ebt_log_info *)data;
160 struct nf_loginfo li;
161
162 li.type = NF_LOG_TYPE_LOG;
163 li.u.log.level = info->loglevel;
164 li.u.log.logflags = info->bitmask;
165
166 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
147} 167}
148 168
149static struct ebt_watcher log = 169static struct ebt_watcher log =
@@ -154,13 +174,32 @@ static struct ebt_watcher log =
154 .me = THIS_MODULE, 174 .me = THIS_MODULE,
155}; 175};
156 176
177static struct nf_logger ebt_log_logger = {
178 .name = "ebt_log",
179 .logfn = &ebt_log_packet,
180 .me = THIS_MODULE,
181};
182
157static int __init init(void) 183static int __init init(void)
158{ 184{
159 return ebt_register_watcher(&log); 185 int ret;
186
187 ret = ebt_register_watcher(&log);
188 if (ret < 0)
189 return ret;
190 if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
191 printk(KERN_WARNING "ebt_log: not logging via system console "
192 "since somebody else already registered for PF_INET\n");
193 /* we cannot make module load fail here, since otherwise
194 * ebtables userspace would abort */
195 }
196
197 return 0;
160} 198}
161 199
162static void __exit fini(void) 200static void __exit fini(void)
163{ 201{
202 nf_log_unregister_logger(&ebt_log_logger);
164 ebt_unregister_watcher(&log); 203 ebt_unregister_watcher(&log);
165} 204}
166 205
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index aae26ae2e61f..ce617b3dbbb8 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Authors: 4 * Authors:
5 * Bart De Schuymer <bdschuym@pandora.be> 5 * Bart De Schuymer <bdschuym@pandora.be>
6 * Harald Welte <laforge@netfilter.org>
6 * 7 *
7 * November, 2004 8 * November, 2004
8 * 9 *
@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
115 return skb; 116 return skb;
116} 117}
117 118
118static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, 119static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
119 const struct net_device *in, const struct net_device *out, 120 const struct net_device *in, const struct net_device *out,
120 const void *data, unsigned int datalen) 121 const struct ebt_ulog_info *uloginfo, const char *prefix)
121{ 122{
122 ebt_ulog_packet_msg_t *pm; 123 ebt_ulog_packet_msg_t *pm;
123 size_t size, copy_len; 124 size_t size, copy_len;
124 struct nlmsghdr *nlh; 125 struct nlmsghdr *nlh;
125 struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
126 unsigned int group = uloginfo->nlgroup; 126 unsigned int group = uloginfo->nlgroup;
127 ebt_ulog_buff_t *ub = &ulog_buffers[group]; 127 ebt_ulog_buff_t *ub = &ulog_buffers[group];
128 spinlock_t *lock = &ub->lock; 128 spinlock_t *lock = &ub->lock;
@@ -216,6 +216,39 @@ alloc_failure:
216 goto unlock; 216 goto unlock;
217} 217}
218 218
219/* this function is registered with the netfilter core */
220static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
221 const struct sk_buff *skb, const struct net_device *in,
222 const struct net_device *out, const struct nf_loginfo *li,
223 const char *prefix)
224{
225 struct ebt_ulog_info loginfo;
226
227 if (!li || li->type != NF_LOG_TYPE_ULOG) {
228 loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
229 loginfo.cprange = 0;
230 loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
231 loginfo.prefix[0] = '\0';
232 } else {
233 loginfo.nlgroup = li->u.ulog.group;
234 loginfo.cprange = li->u.ulog.copy_len;
235 loginfo.qthreshold = li->u.ulog.qthreshold;
236 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
237 }
238
239 ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
240}
241
242static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
243 const struct net_device *in, const struct net_device *out,
244 const void *data, unsigned int datalen)
245{
246 struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
247
248 ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
249}
250
251
219static int ebt_ulog_check(const char *tablename, unsigned int hookmask, 252static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
220 const struct ebt_entry *e, void *data, unsigned int datalen) 253 const struct ebt_entry *e, void *data, unsigned int datalen)
221{ 254{
@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = {
240 .me = THIS_MODULE, 273 .me = THIS_MODULE,
241}; 274};
242 275
276static struct nf_logger ebt_ulog_logger = {
277 .name = EBT_ULOG_WATCHER,
278 .logfn = &ebt_log_packet,
279 .me = THIS_MODULE,
280};
281
243static int __init init(void) 282static int __init init(void)
244{ 283{
245 int i, ret = 0; 284 int i, ret = 0;
@@ -265,6 +304,13 @@ static int __init init(void)
265 else if ((ret = ebt_register_watcher(&ulog))) 304 else if ((ret = ebt_register_watcher(&ulog)))
266 sock_release(ebtulognl->sk_socket); 305 sock_release(ebtulognl->sk_socket);
267 306
307 if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
308 printk(KERN_WARNING "ebt_ulog: not logging via ulog "
309 "since somebody else already registered for PF_BRIDGE\n");
310 /* we cannot make module load fail here, since otherwise
311 * ebtables userspace would abort */
312 }
313
268 return ret; 314 return ret;
269} 315}
270 316
@@ -273,6 +319,7 @@ static void __exit fini(void)
273 ebt_ulog_buff_t *ub; 319 ebt_ulog_buff_t *ub;
274 int i; 320 int i;
275 321
322 nf_log_unregister_logger(&ebt_ulog_logger);
276 ebt_unregister_watcher(&ulog); 323 ebt_unregister_watcher(&ulog);
277 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { 324 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
278 ub = &ulog_buffers[i]; 325 ub = &ulog_buffers[i];