aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--net/8021q/vlan_dev.c10
-rw-r--r--net/8021q/vlan_netlink.c7
3 files changed, 18 insertions, 6 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f45929ce8157..da4b33bea982 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4145,6 +4145,13 @@ static inline void netif_keep_dst(struct net_device *dev)
4145 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM); 4145 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM);
4146} 4146}
4147 4147
4148/* return true if dev can't cope with mtu frames that need vlan tag insertion */
4149static inline bool netif_reduces_vlan_mtu(struct net_device *dev)
4150{
4151 /* TODO: reserve and use an additional IFF bit, if we get more users */
4152 return dev->priv_flags & IFF_MACSEC;
4153}
4154
4148extern struct pernet_operations __net_initdata loopback_net_ops; 4155extern struct pernet_operations __net_initdata loopback_net_ops;
4149 4156
4150/* Logging, debugging and troubleshooting/diagnostic helpers. */ 4157/* Logging, debugging and troubleshooting/diagnostic helpers. */
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);