mirror of https://gitee.com/openkylin/linux.git
Merge branch 'mlxsw-GRE-mtu-changes'
Ido Schimmel says:
====================
mlxsw: Handle changes to MTU in GRE tunnels
Petr says:
When offloading GRE tunnels, the MTU setting is kept fixed after the
initial offload even as the slow-path configuration changed. Worse: the
offloaded MTU setting is actually just a transient value set at the time
of NETDEV_REGISTER of the tunnel. As of commit ffc2b6ee41
("ip_gre:
fix IFLA_MTU ignored on NEWLINK"), that transient value is zero, and
unless there's e.g. a VRF migration that prompts re-offload, it stays at
zero, and all GRE packets end up trapping.
Thus, in patch #1, change the way the MTU is changed post-registration,
so that the full event protocol is observed. That way the drivers get to
see the change and have a chance to react.
In the remaining two patches, implement support for MTU change in mlxsw
driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
69ebaed0c6
|
@ -1380,6 +1380,55 @@ mlxsw_sp_ipip_entry_ol_up_event(struct mlxsw_sp *mlxsw_sp,
|
|||
decap_fib_entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
|
||||
struct mlxsw_sp_vr *ul_vr, bool enable)
|
||||
{
|
||||
struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
|
||||
struct mlxsw_sp_rif *rif = &lb_rif->common;
|
||||
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
|
||||
char ritr_pl[MLXSW_REG_RITR_LEN];
|
||||
u32 saddr4;
|
||||
|
||||
switch (lb_cf.ul_protocol) {
|
||||
case MLXSW_SP_L3_PROTO_IPV4:
|
||||
saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
|
||||
mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
|
||||
rif->rif_index, rif->vr_id, rif->dev->mtu);
|
||||
mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
|
||||
MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
|
||||
ul_vr->id, saddr4, lb_cf.okey);
|
||||
break;
|
||||
|
||||
case MLXSW_SP_L3_PROTO_IPV6:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_netdevice_ipip_ol_update_mtu(struct mlxsw_sp *mlxsw_sp,
|
||||
struct net_device *ol_dev)
|
||||
{
|
||||
struct mlxsw_sp_ipip_entry *ipip_entry;
|
||||
struct mlxsw_sp_rif_ipip_lb *lb_rif;
|
||||
struct mlxsw_sp_vr *ul_vr;
|
||||
int err = 0;
|
||||
|
||||
ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
|
||||
if (ipip_entry) {
|
||||
lb_rif = ipip_entry->ol_lb;
|
||||
ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id];
|
||||
err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, true);
|
||||
if (err)
|
||||
goto out;
|
||||
lb_rif->common.mtu = ol_dev->mtu;
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_netdevice_ipip_ol_up_event(struct mlxsw_sp *mlxsw_sp,
|
||||
struct net_device *ol_dev)
|
||||
{
|
||||
|
@ -1660,6 +1709,8 @@ int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp,
|
|||
extack = info->extack;
|
||||
return mlxsw_sp_netdevice_ipip_ol_change_event(mlxsw_sp,
|
||||
ol_dev, extack);
|
||||
case NETDEV_CHANGEMTU:
|
||||
return mlxsw_sp_netdevice_ipip_ol_update_mtu(mlxsw_sp, ol_dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -6843,33 +6894,6 @@ mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif,
|
|||
rif_lb->lb_config = params_lb->lb_config;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
|
||||
struct mlxsw_sp_vr *ul_vr, bool enable)
|
||||
{
|
||||
struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
|
||||
struct mlxsw_sp_rif *rif = &lb_rif->common;
|
||||
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
|
||||
char ritr_pl[MLXSW_REG_RITR_LEN];
|
||||
u32 saddr4;
|
||||
|
||||
switch (lb_cf.ul_protocol) {
|
||||
case MLXSW_SP_L3_PROTO_IPV4:
|
||||
saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
|
||||
mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
|
||||
rif->rif_index, rif->vr_id, rif->dev->mtu);
|
||||
mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
|
||||
MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
|
||||
ul_vr->id, saddr4, lb_cf.okey);
|
||||
break;
|
||||
|
||||
case MLXSW_SP_L3_PROTO_IPV6:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
|
||||
{
|
||||
|
|
|
@ -362,13 +362,18 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
|
|||
struct ip_tunnel *nt;
|
||||
struct net_device *dev;
|
||||
int t_hlen;
|
||||
int mtu;
|
||||
int err;
|
||||
|
||||
BUG_ON(!itn->fb_tunnel_dev);
|
||||
dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
|
||||
if (IS_ERR(dev))
|
||||
return ERR_CAST(dev);
|
||||
|
||||
dev->mtu = ip_tunnel_bind_dev(dev);
|
||||
mtu = ip_tunnel_bind_dev(dev);
|
||||
err = dev_set_mtu(dev, mtu);
|
||||
if (err)
|
||||
goto err_dev_set_mtu;
|
||||
|
||||
nt = netdev_priv(dev);
|
||||
t_hlen = nt->hlen + sizeof(struct iphdr);
|
||||
|
@ -376,6 +381,10 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
|
|||
dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
|
||||
ip_tunnel_add(itn, nt);
|
||||
return nt;
|
||||
|
||||
err_dev_set_mtu:
|
||||
unregister_netdevice(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
|
||||
|
@ -1102,17 +1111,24 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
|
|||
nt->fwmark = fwmark;
|
||||
err = register_netdevice(dev);
|
||||
if (err)
|
||||
goto out;
|
||||
goto err_register_netdevice;
|
||||
|
||||
if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
|
||||
eth_hw_addr_random(dev);
|
||||
|
||||
mtu = ip_tunnel_bind_dev(dev);
|
||||
if (!tb[IFLA_MTU])
|
||||
dev->mtu = mtu;
|
||||
if (!tb[IFLA_MTU]) {
|
||||
err = dev_set_mtu(dev, mtu);
|
||||
if (err)
|
||||
goto err_dev_set_mtu;
|
||||
}
|
||||
|
||||
ip_tunnel_add(itn, nt);
|
||||
out:
|
||||
return 0;
|
||||
|
||||
err_dev_set_mtu:
|
||||
unregister_netdevice(dev);
|
||||
err_register_netdevice:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
|
||||
|
|
Loading…
Reference in New Issue