Skip to content

Commit

Permalink
bridge: Add multicast data-path hooks
Browse files Browse the repository at this point in the history
This patch finally hooks up the multicast snooping module to the
data path.  In particular, all multicast packets passing through
the bridge are fed into the module and switched by it.

Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
herbertx authored and davem330 committed Feb 28, 2010
1 parent 3fe2d7c commit c4fcb78
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
15 changes: 12 additions & 3 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
struct net_bridge *br = netdev_priv(dev);
const unsigned char *dest = skb->data;
struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst;

BR_INPUT_SKB_CB(skb)->brdev = dev;

Expand All @@ -34,13 +35,21 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
skb_reset_mac_header(skb);
skb_pull(skb, ETH_HLEN);

if (dest[0] & 1)
br_flood_deliver(br, skb);
else if ((dst = __br_fdb_get(br, dest)) != NULL)
if (dest[0] & 1) {
if (br_multicast_rcv(br, NULL, skb))
goto out;

mdst = br_mdb_get(br, skb);
if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only)
br_multicast_deliver(mdst, skb);
else
br_flood_deliver(br, skb);
} else if ((dst = __br_fdb_get(br, dest)) != NULL)
br_deliver(dst->dst, skb);
else
br_flood_deliver(br, skb);

out:
return NETDEV_TX_OK;
}

Expand Down
18 changes: 17 additions & 1 deletion net/bridge/br_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
struct net_bridge *br;
struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst;
struct sk_buff *skb2;

if (!p || p->state == BR_STATE_DISABLED)
Expand All @@ -50,6 +51,10 @@ int br_handle_frame_finish(struct sk_buff *skb)
br = p->br;
br_fdb_update(br, p, eth_hdr(skb)->h_source);

if (is_multicast_ether_addr(dest) &&
br_multicast_rcv(br, p, skb))
goto drop;

if (p->state == BR_STATE_LEARNING)
goto drop;

Expand All @@ -64,8 +69,19 @@ int br_handle_frame_finish(struct sk_buff *skb)
dst = NULL;

if (is_multicast_ether_addr(dest)) {
mdst = br_mdb_get(br, skb);
if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) {
if ((mdst && !hlist_unhashed(&mdst->mglist)) ||
br_multicast_is_router(br))
skb2 = skb;
br_multicast_forward(mdst, skb, skb2);
skb = NULL;
if (!skb2)
goto out;
} else
skb2 = skb;

br->dev->stats.multicast++;
skb2 = skb;
} else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
skb2 = skb;
/* Do not forward the packet since it's local. */
Expand Down

0 comments on commit c4fcb78

Please sign in to comment.