@@ -26,11 +26,29 @@ static int deliver_clone(const struct net_bridge_port *prev,
void (*__packet_hook)(const struct net_bridge_port *p,
struct sk_buff *skb));
+static inline bool br_allowed_egress(const struct net_bridge_port *p,
+ const struct sk_buff *skb)
+{
+ struct net_port_vlan *pve;
+ u16 vid;
+
+ if (list_empty(&p->vlan_list))
+ return true;
+
+ vid = br_get_vlan(skb);
+ pve = nbp_vlan_find(p, vid);
+ if (pve)
+ return true;
+
+ return false;
+}
+
/* Don't forward packets to originating port or forwarding diasabled */
static inline int should_deliver(const struct net_bridge_port *p,
const struct sk_buff *skb)
{
return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
+ br_allowed_egress(p, skb) &&
p->state == BR_STATE_FORWARDING);
}
@@ -202,6 +202,7 @@ static inline u16 br_get_vlan(const struct sk_buff *skb)
if (vlan_tx_tag_present(skb))
return vlan_tx_tag_get(skb) & VLAN_VID_MASK;
+ /* Untagged and VLAN 0 traffic is handled the same way */
if (vlan_get_tag(skb, &tag))
return 0;
When bridge forwards a frame, make sure that a frame is allowed to egress on that port. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> --- net/bridge/br_forward.c | 18 ++++++++++++++++++ net/bridge/br_private.h | 1 + 2 files changed, 19 insertions(+), 0 deletions(-)