diff options
author | David S. Miller <davem@davemloft.net> | 2013-06-11 02:04:43 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-11 02:04:43 -0700 |
commit | 2e42206948c98fdd32b64094264419a47ee2718c (patch) | |
tree | 8b5aafe092cf6212894fc2f0176833be9b9e22ed /net/bridge/br_input.c | |
parent | 30f3a40f9a2a2869a560a9cb9ef488d10c803e14 (diff) | |
parent | 867a59436fc35593ae0e0efcd56cc6d2f8506586 (diff) |
Merge branch 'bridge_flags'
Vlad Yasevich says:
====================
The following series adds 2 new flags to bridge. One flag allows
the user to control whether mac learning is performed on the interface
or not. By default mac learning is on.
The other flag allows the user to control whether unicast traffic
is flooded (send without an fdb) to a given unicast port. Default is
on.
Changes since v4:
- Implemented Stephen's suggestions.
Changes since v2:
- removed unused "unlock" tag.
Changes since v1:
- Integrated suggestion from MST to not impact RTM_NEWNEIGH and to
skip lookups when learning is disabled.
Vlad Yasevich (2):
bridge: Add flag to control mac learning.
bridge: Add a flag to control unicast packet flood.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 828e2bcc1f5..1b8b8b824cd 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -65,6 +65,7 @@ int br_handle_frame_finish(struct sk_buff *skb) struct net_bridge_fdb_entry *dst; struct net_bridge_mdb_entry *mdst; struct sk_buff *skb2; + bool unicast = true; u16 vid = 0; if (!p || p->state == BR_STATE_DISABLED) @@ -75,7 +76,8 @@ int br_handle_frame_finish(struct sk_buff *skb) /* insert into forwarding database after filtering to avoid spoofing */ br = p->br; - br_fdb_update(br, p, eth_hdr(skb)->h_source, vid); + if (p->flags & BR_LEARNING) + br_fdb_update(br, p, eth_hdr(skb)->h_source, vid); if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && br_multicast_rcv(br, p, skb)) @@ -94,9 +96,10 @@ int br_handle_frame_finish(struct sk_buff *skb) dst = NULL; - if (is_broadcast_ether_addr(dest)) + if (is_broadcast_ether_addr(dest)) { skb2 = skb; - else if (is_multicast_ether_addr(dest)) { + unicast = false; + } else if (is_multicast_ether_addr(dest)) { mdst = br_mdb_get(br, skb, vid); if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { if ((mdst && mdst->mglist) || @@ -109,6 +112,7 @@ int br_handle_frame_finish(struct sk_buff *skb) } else skb2 = skb; + unicast = false; br->dev->stats.multicast++; } else if ((dst = __br_fdb_get(br, dest, vid)) && dst->is_local) { @@ -122,7 +126,7 @@ int br_handle_frame_finish(struct sk_buff *skb) dst->used = jiffies; br_forward(dst->dst, skb, skb2); } else - br_flood_forward(br, skb, skb2); + br_flood_forward(br, skb, skb2, unicast); } if (skb2) @@ -142,7 +146,8 @@ static int br_handle_local_finish(struct sk_buff *skb) u16 vid = 0; br_vlan_get_tag(skb, &vid); - br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); + if (p->flags & BR_LEARNING) + br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); return 0; /* process further */ } |