summaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2016-07-14 12:00:10 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-16 23:15:02 -0400
commit18d3df3eab23796d7f852f9c6bb60962b8372ced (patch)
tree4871d69274a682be6379696208efafc622d3234d /net/8021q
parente86663c475d384ab5f46cb5637e9b7ad08c5c505 (diff)
vlan: use a valid default mtu value for vlan over macsec
macsec can't cope with mtu frames which need vlan tag insertion, and vlan device set the default mtu equal to the underlying dev's one. By default vlan over macsec devices use invalid mtu, dropping all the large packets. This patch adds a netif helper to check if an upper vlan device needs mtu reduction. The helper is used during vlan devices initialization to set a valid default and during mtu updating to forbid invalid, too bit, mtu values. The helper currently only check if the lower dev is a macsec device, if we get more users, we need to update only the helper (possibly reserving an additional IFF bit). Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan_dev.c10
-rw-r--r--net/8021q/vlan_netlink.c7
2 files changed, 11 insertions, 6 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 86ae75b77390..516b0e73263c 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -146,10 +146,12 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
146 146
147static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) 147static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
148{ 148{
149 /* TODO: gotta make sure the underlying layer can handle it, 149 struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
150 * maybe an IFF_VLAN_CAPABLE flag for devices? 150 unsigned int max_mtu = real_dev->mtu;
151 */ 151
152 if (vlan_dev_priv(dev)->real_dev->mtu < new_mtu) 152 if (netif_reduces_vlan_mtu(real_dev))
153 max_mtu -= VLAN_HLEN;
154 if (max_mtu < new_mtu)
153 return -ERANGE; 155 return -ERANGE;
154 156
155 dev->mtu = new_mtu; 157 dev->mtu = new_mtu;
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index c92b52f37d38..1270207f3d7c 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -118,6 +118,7 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
118{ 118{
119 struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 119 struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
120 struct net_device *real_dev; 120 struct net_device *real_dev;
121 unsigned int max_mtu;
121 __be16 proto; 122 __be16 proto;
122 int err; 123 int err;
123 124
@@ -144,9 +145,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
144 if (err < 0) 145 if (err < 0)
145 return err; 146 return err;
146 147
148 max_mtu = netif_reduces_vlan_mtu(real_dev) ? real_dev->mtu - VLAN_HLEN :
149 real_dev->mtu;
147 if (!tb[IFLA_MTU]) 150 if (!tb[IFLA_MTU])
148 dev->mtu = real_dev->mtu; 151 dev->mtu = max_mtu;
149 else if (dev->mtu > real_dev->mtu) 152 else if (dev->mtu > max_mtu)
150 return -EINVAL; 153 return -EINVAL;
151 154
152 err = vlan_changelink(dev, tb, data); 155 err = vlan_changelink(dev, tb, data);