mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 21:52:04 +00:00
Merge branch 'geneve-mtu'
Alexey Kodanev says: ==================== geneve: verify user specified MTU or adjust with a lower device The first two patches don't introduce any functional changes and contain minor cleanups for code readability. The last one adds a new function geneve_link_config() similar to the other tunnels. The function will be used on a new link creation or when 'remote' parameter is changed. It adjusts a user specified MTU or, if it finds a lower device, tunes the tunnel MTU using it. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
2ed021255b
@ -36,6 +36,8 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
|
||||
|
||||
#define GENEVE_VER 0
|
||||
#define GENEVE_BASE_HLEN (sizeof(struct udphdr) + sizeof(struct genevehdr))
|
||||
#define GENEVE_IPV4_HLEN (ETH_HLEN + sizeof(struct iphdr) + GENEVE_BASE_HLEN)
|
||||
#define GENEVE_IPV6_HLEN (ETH_HLEN + sizeof(struct ipv6hdr) + GENEVE_BASE_HLEN)
|
||||
|
||||
/* per-network namespace private data for this module */
|
||||
struct geneve_net {
|
||||
@ -826,8 +828,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
return PTR_ERR(rt);
|
||||
|
||||
if (skb_dst(skb)) {
|
||||
int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) -
|
||||
GENEVE_BASE_HLEN - info->options_len - 14;
|
||||
int mtu = dst_mtu(&rt->dst) - GENEVE_IPV4_HLEN -
|
||||
info->options_len;
|
||||
|
||||
skb_dst_update_pmtu(skb, mtu);
|
||||
}
|
||||
@ -872,8 +874,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
return PTR_ERR(dst);
|
||||
|
||||
if (skb_dst(skb)) {
|
||||
int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) -
|
||||
GENEVE_BASE_HLEN - info->options_len - 14;
|
||||
int mtu = dst_mtu(dst) - GENEVE_IPV6_HLEN - info->options_len;
|
||||
|
||||
skb_dst_update_pmtu(skb, mtu);
|
||||
}
|
||||
@ -941,11 +942,10 @@ tx_error:
|
||||
|
||||
static int geneve_change_mtu(struct net_device *dev, int new_mtu)
|
||||
{
|
||||
/* Only possible if called internally, ndo_change_mtu path's new_mtu
|
||||
* is guaranteed to be between dev->min_mtu and dev->max_mtu.
|
||||
*/
|
||||
if (new_mtu > dev->max_mtu)
|
||||
new_mtu = dev->max_mtu;
|
||||
else if (new_mtu < dev->min_mtu)
|
||||
new_mtu = dev->min_mtu;
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
return 0;
|
||||
@ -1261,7 +1261,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
|
||||
}
|
||||
|
||||
if (data[IFLA_GENEVE_REMOTE6]) {
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (changelink && (ip_tunnel_info_af(info) == AF_INET)) {
|
||||
attrtype = IFLA_GENEVE_REMOTE6;
|
||||
goto change_notsup;
|
||||
@ -1387,6 +1387,48 @@ change_notsup:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void geneve_link_config(struct net_device *dev,
|
||||
struct ip_tunnel_info *info, struct nlattr *tb[])
|
||||
{
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
int ldev_mtu = 0;
|
||||
|
||||
if (tb[IFLA_MTU]) {
|
||||
geneve_change_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ip_tunnel_info_af(info)) {
|
||||
case AF_INET: {
|
||||
struct flowi4 fl4 = { .daddr = info->key.u.ipv4.dst };
|
||||
struct rtable *rt = ip_route_output_key(geneve->net, &fl4);
|
||||
|
||||
if (!IS_ERR(rt) && rt->dst.dev) {
|
||||
ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV4_HLEN;
|
||||
ip_rt_put(rt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case AF_INET6: {
|
||||
struct rt6_info *rt = rt6_lookup(geneve->net,
|
||||
&info->key.u.ipv6.dst, NULL, 0,
|
||||
NULL, 0);
|
||||
|
||||
if (rt && rt->dst.dev)
|
||||
ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
|
||||
ip6_rt_put(rt);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ldev_mtu <= 0)
|
||||
return;
|
||||
|
||||
geneve_change_mtu(dev, ldev_mtu - info->options_len);
|
||||
}
|
||||
|
||||
static int geneve_newlink(struct net *net, struct net_device *dev,
|
||||
struct nlattr *tb[], struct nlattr *data[],
|
||||
struct netlink_ext_ack *extack)
|
||||
@ -1402,8 +1444,14 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return geneve_configure(net, dev, extack, &info, metadata,
|
||||
use_udp6_rx_checksums);
|
||||
err = geneve_configure(net, dev, extack, &info, metadata,
|
||||
use_udp6_rx_checksums);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
geneve_link_config(dev, &info, tb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Quiesces the geneve device data path for both TX and RX.
|
||||
@ -1477,8 +1525,10 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!geneve_dst_addr_equal(&geneve->info, &info))
|
||||
if (!geneve_dst_addr_equal(&geneve->info, &info)) {
|
||||
dst_cache_reset(&info.dst_cache);
|
||||
geneve_link_config(dev, &info, tb);
|
||||
}
|
||||
|
||||
geneve_quiesce(geneve, &gs4, &gs6);
|
||||
geneve->info = info;
|
||||
|
Loading…
Reference in New Issue
Block a user