diff options
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r-- | net/bridge/br_device.c | 23 |
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 | ||
52 | out: | ||
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 | ||
60 | static int br_dev_stop(struct net_device *dev) | 72 | static 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 | ||