aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r--net/bridge/br_device.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 1a99c4e04e85..eb7062d2e9e5 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -25,6 +25,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
25 struct net_bridge *br = netdev_priv(dev); 25 struct net_bridge *br = netdev_priv(dev);
26 const unsigned char *dest = skb->data; 26 const unsigned char *dest = skb->data;
27 struct net_bridge_fdb_entry *dst; 27 struct net_bridge_fdb_entry *dst;
28 struct net_bridge_mdb_entry *mdst;
29
30 BR_INPUT_SKB_CB(skb)->brdev = dev;
28 31
29 dev->stats.tx_packets++; 32 dev->stats.tx_packets++;
30 dev->stats.tx_bytes += skb->len; 33 dev->stats.tx_bytes += skb->len;
@@ -32,13 +35,21 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
32 skb_reset_mac_header(skb); 35 skb_reset_mac_header(skb);
33 skb_pull(skb, ETH_HLEN); 36 skb_pull(skb, ETH_HLEN);
34 37
35 if (dest[0] & 1) 38 if (dest[0] & 1) {
36 br_flood_deliver(br, skb); 39 if (br_multicast_rcv(br, NULL, skb))
37 else if ((dst = __br_fdb_get(br, dest)) != NULL) 40 goto out;
41
42 mdst = br_mdb_get(br, skb);
43 if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only)
44 br_multicast_deliver(mdst, skb);
45 else
46 br_flood_deliver(br, skb);
47 } else if ((dst = __br_fdb_get(br, dest)) != NULL)
38 br_deliver(dst->dst, skb); 48 br_deliver(dst->dst, skb);
39 else 49 else
40 br_flood_deliver(br, skb); 50 br_flood_deliver(br, skb);
41 51
52out:
42 return NETDEV_TX_OK; 53 return NETDEV_TX_OK;
43} 54}
44 55
@@ -49,6 +60,7 @@ static int br_dev_open(struct net_device *dev)
49 br_features_recompute(br); 60 br_features_recompute(br);
50 netif_start_queue(dev); 61 netif_start_queue(dev);
51 br_stp_enable_bridge(br); 62 br_stp_enable_bridge(br);
63 br_multicast_open(br);
52 64
53 return 0; 65 return 0;
54} 66}
@@ -59,7 +71,10 @@ static void br_dev_set_multicast_list(struct net_device *dev)
59 71
60static int br_dev_stop(struct net_device *dev) 72static int br_dev_stop(struct net_device *dev)
61{ 73{
62 br_stp_disable_bridge(netdev_priv(dev)); 74 struct net_bridge *br = netdev_priv(dev);
75
76 br_stp_disable_bridge(br);
77 br_multicast_stop(br);
63 78
64 netif_stop_queue(dev); 79 netif_stop_queue(dev);
65 80