summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vyasevich@gmail.com>2015-11-16 21:43:45 +0100
committerDavid S. Miller <davem@davemloft.net>2015-11-17 20:38:35 +0100
commit28f9ee22bcdd84726dbf6267d0b58f254166b900 (patch)
treed7eeee0f1222b51aa0803ab2c50fd0eabfaa2fa5
parentvlan: Fix untag operations of stacked vlans with REORDER_HEADER off (diff)
downloadlinux-28f9ee22bcdd84726dbf6267d0b58f254166b900.tar.xz
linux-28f9ee22bcdd84726dbf6267d0b58f254166b900.zip
vlan: Do not put vlan headers back on bridge and macvlan ports
When a vlan is configured with REORDER_HEADER set to 0, the vlan header is put back into the packet and makes it appear that the vlan header is still there even after it's been processed. This posses a problem for bridge and macvlan ports. The packets passed to those device may be forwarded and at the time of the forward, vlan headers end up being unexpectedly present. With the patch, we make sure that we do not put the vlan header back (when REORDER_HEADER is 0) if a bridge or macvlan has been configured on top of the vlan device. Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netdevice.h5
-rw-r--r--net/8021q/vlan_core.c4
2 files changed, 8 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cc221b967687..67bfac1abfc1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3857,6 +3857,11 @@ static inline bool netif_is_bridge_master(const struct net_device *dev)
return dev->priv_flags & IFF_EBRIDGE;
}
+static inline bool netif_is_bridge_port(const struct net_device *dev)
+{
+ return dev->priv_flags & IFF_BRIDGE_PORT;
+}
+
static inline bool netif_is_ovs_master(const struct net_device *dev)
{
return dev->priv_flags & IFF_OPENVSWITCH;
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 496b27588493..e2ed69850489 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -30,7 +30,9 @@ bool vlan_do_receive(struct sk_buff **skbp)
skb->pkt_type = PACKET_HOST;
}
- if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) {
+ if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR) &&
+ !netif_is_macvlan_port(vlan_dev) &&
+ !netif_is_bridge_port(vlan_dev)) {
unsigned int offset = skb->data - skb_mac_header(skb);
/*