aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorSteve French <sfrench@hera.kernel.org>2005-05-31 17:32:44 -0400
committerSteve French <sfrench@hera.kernel.org>2005-05-31 17:32:44 -0400
commitaf6f5e3247a68074e384ef93c0b4bce1b73c9d80 (patch)
tree87b0f1e48bd0ca67a78fab0fa42b37864863fdfd /net/bridge
parent7e2987503dda95a5f80290bb8c06279009c2419e (diff)
parent2e3e80c2b75e3815a0160cbd23d4fdb767d66b35 (diff)
Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c15
-rw-r--r--net/bridge/br_if.c23
-rw-r--r--net/bridge/br_input.c8
-rw-r--r--net/bridge/br_notify.c9
-rw-r--r--net/bridge/br_private.h1
-rw-r--r--net/bridge/br_stp_bpdu.c3
6 files changed, 48 insertions, 11 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index d9b72fde433c..f564ee99782d 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -21,10 +21,7 @@
21 21
22static struct net_device_stats *br_dev_get_stats(struct net_device *dev) 22static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
23{ 23{
24 struct net_bridge *br; 24 struct net_bridge *br = netdev_priv(dev);
25
26 br = dev->priv;
27
28 return &br->statistics; 25 return &br->statistics;
29} 26}
30 27
@@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
54 51
55static int br_dev_open(struct net_device *dev) 52static int br_dev_open(struct net_device *dev)
56{ 53{
57 netif_start_queue(dev); 54 struct net_bridge *br = netdev_priv(dev);
58 55
59 br_stp_enable_bridge(dev->priv); 56 br_features_recompute(br);
57 netif_start_queue(dev);
58 br_stp_enable_bridge(br);
60 59
61 return 0; 60 return 0;
62} 61}
@@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(struct net_device *dev)
67 66
68static int br_dev_stop(struct net_device *dev) 67static int br_dev_stop(struct net_device *dev)
69{ 68{
70 br_stp_disable_bridge(dev->priv); 69 br_stp_disable_bridge(netdev_priv(dev));
71 70
72 netif_stop_queue(dev); 71 netif_stop_queue(dev);
73 72
@@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device *dev)
76 75
77static int br_change_mtu(struct net_device *dev, int new_mtu) 76static int br_change_mtu(struct net_device *dev, int new_mtu)
78{ 77{
79 if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv)) 78 if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev)))
80 return -EINVAL; 79 return -EINVAL;
81 80
82 dev->mtu = new_mtu; 81 dev->mtu = new_mtu;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 69872bf3b87e..91bb895375f4 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br)
314 return mtu; 314 return mtu;
315} 315}
316 316
317/*
318 * Recomputes features using slave's features
319 */
320void br_features_recompute(struct net_bridge *br)
321{
322 struct net_bridge_port *p;
323 unsigned long features, checksum;
324
325 features = NETIF_F_SG | NETIF_F_FRAGLIST
326 | NETIF_F_HIGHDMA | NETIF_F_TSO;
327 checksum = NETIF_F_IP_CSUM; /* least commmon subset */
328
329 list_for_each_entry(p, &br->port_list, list) {
330 if (!(p->dev->features
331 & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
332 checksum = 0;
333 features &= p->dev->features;
334 }
335
336 br->dev->features = features | checksum | NETIF_F_LLTX;
337}
338
317/* called with RTNL */ 339/* called with RTNL */
318int br_add_if(struct net_bridge *br, struct net_device *dev) 340int br_add_if(struct net_bridge *br, struct net_device *dev)
319{ 341{
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
368 390
369 spin_lock_bh(&br->lock); 391 spin_lock_bh(&br->lock);
370 br_stp_recalculate_bridge_id(br); 392 br_stp_recalculate_bridge_id(br);
393 br_features_recompute(br);
371 spin_unlock_bh(&br->lock); 394 spin_unlock_bh(&br->lock);
372 395
373 return 0; 396 return 0;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 2b1cce46cab4..8f5f2e730992 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -26,7 +26,7 @@ static int br_pass_frame_up_finish(struct sk_buff *skb)
26#ifdef CONFIG_NETFILTER_DEBUG 26#ifdef CONFIG_NETFILTER_DEBUG
27 skb->nf_debug = 0; 27 skb->nf_debug = 0;
28#endif 28#endif
29 netif_rx(skb); 29 netif_receive_skb(skb);
30 30
31 return 0; 31 return 0;
32} 32}
@@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buff *skb)
54 struct net_bridge_fdb_entry *dst; 54 struct net_bridge_fdb_entry *dst;
55 int passedup = 0; 55 int passedup = 0;
56 56
57 /* insert into forwarding database after filtering to avoid spoofing */
58 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
59
57 if (br->dev->flags & IFF_PROMISC) { 60 if (br->dev->flags & IFF_PROMISC) {
58 struct sk_buff *skb2; 61 struct sk_buff *skb2;
59 62
@@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
108 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 111 if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
109 goto err; 112 goto err;
110 113
111 if (p->state == BR_STATE_LEARNING || 114 if (p->state == BR_STATE_LEARNING)
112 p->state == BR_STATE_FORWARDING)
113 br_fdb_update(p->br, p, eth_hdr(skb)->h_source); 115 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
114 116
115 if (p->br->stp_enabled && 117 if (p->br->stp_enabled &&
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index f8fb49e34764..917311c6828b 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -65,6 +65,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
65 } 65 }
66 break; 66 break;
67 67
68 case NETDEV_FEAT_CHANGE:
69 if (br->dev->flags & IFF_UP)
70 br_features_recompute(br);
71
72 /* could do recursive feature change notification
73 * but who would care??
74 */
75 break;
76
68 case NETDEV_DOWN: 77 case NETDEV_DOWN:
69 if (br->dev->flags & IFF_UP) 78 if (br->dev->flags & IFF_UP)
70 br_stp_disable_port(p); 79 br_stp_disable_port(p);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 54d63f1372a0..bdf95a74d8cd 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *br,
174extern int br_del_if(struct net_bridge *br, 174extern int br_del_if(struct net_bridge *br,
175 struct net_device *dev); 175 struct net_device *dev);
176extern int br_min_mtu(const struct net_bridge *br); 176extern int br_min_mtu(const struct net_bridge *br);
177extern void br_features_recompute(struct net_bridge *br);
177 178
178/* br_input.c */ 179/* br_input.c */
179extern int br_handle_frame_finish(struct sk_buff *skb); 180extern int br_handle_frame_finish(struct sk_buff *skb);
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index b91a875aca01..d071f1c9ad0b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *skb)
140 struct net_bridge *br = p->br; 140 struct net_bridge *br = p->br;
141 unsigned char *buf; 141 unsigned char *buf;
142 142
143 /* insert into forwarding database after filtering to avoid spoofing */
144 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
145
143 /* need at least the 802 and STP headers */ 146 /* need at least the 802 and STP headers */
144 if (!pskb_may_pull(skb, sizeof(header)+1) || 147 if (!pskb_may_pull(skb, sizeof(header)+1) ||
145 memcmp(skb->data, header, sizeof(header))) 148 memcmp(skb->data, header, sizeof(header)))