Skip to content

Commit 0341e34

Browse files
NicolasDichtelkuba-moo
authored andcommitted
ip6_tunnel: enable to change proto of fb tunnels
This is possible via the ioctl API: > ip -6 tunnel change ip6tnl0 mode any Let's align the netlink API: > ip link set ip6tnl0 type ip6tnl mode any Signed-off-by: Nicolas Dichtel <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 131e0a1 commit 0341e34

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

net/ipv6/ip6_tunnel.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,11 +1562,22 @@ static void ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
15621562
netdev_state_change(t->dev);
15631563
}
15641564

1565-
static void ip6_tnl0_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
1565+
static int ip6_tnl0_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
1566+
bool strict)
15661567
{
1567-
/* for default tnl0 device allow to change only the proto */
1568+
/* For the default ip6tnl0 device, allow changing only the protocol
1569+
* (the IP6_TNL_F_CAP_PER_PACKET flag is set on ip6tnl0, and all other
1570+
* parameters are 0).
1571+
*/
1572+
if (strict &&
1573+
(!ipv6_addr_any(&p->laddr) || !ipv6_addr_any(&p->raddr) ||
1574+
p->flags != t->parms.flags || p->hop_limit || p->encap_limit ||
1575+
p->flowinfo || p->link || p->fwmark || p->collect_md))
1576+
return -EINVAL;
1577+
15681578
t->parms.proto = p->proto;
15691579
netdev_state_change(t->dev);
1580+
return 0;
15701581
}
15711582

15721583
static void
@@ -1680,7 +1691,7 @@ ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
16801691
} else
16811692
t = netdev_priv(dev);
16821693
if (dev == ip6n->fb_tnl_dev)
1683-
ip6_tnl0_update(t, &p1);
1694+
ip6_tnl0_update(t, &p1, false);
16841695
else
16851696
ip6_tnl_update(t, &p1);
16861697
}
@@ -2053,8 +2064,28 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
20532064
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
20542065
struct ip_tunnel_encap ipencap;
20552066

2056-
if (dev == ip6n->fb_tnl_dev)
2057-
return -EINVAL;
2067+
if (dev == ip6n->fb_tnl_dev) {
2068+
if (ip_tunnel_netlink_encap_parms(data, &ipencap)) {
2069+
/* iproute2 always sets TUNNEL_ENCAP_FLAG_CSUM6, so
2070+
* let's ignore this flag.
2071+
*/
2072+
ipencap.flags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
2073+
if (memchr_inv(&ipencap, 0, sizeof(ipencap))) {
2074+
NL_SET_ERR_MSG(extack,
2075+
"Only protocol can be changed for fallback tunnel, not encap params");
2076+
return -EINVAL;
2077+
}
2078+
}
2079+
2080+
ip6_tnl_netlink_parms(data, &p);
2081+
if (ip6_tnl0_update(t, &p, true) < 0) {
2082+
NL_SET_ERR_MSG(extack,
2083+
"Only protocol can be changed for fallback tunnel");
2084+
return -EINVAL;
2085+
}
2086+
2087+
return 0;
2088+
}
20582089

20592090
if (ip_tunnel_netlink_encap_parms(data, &ipencap)) {
20602091
int err = ip6_tnl_encap_setup(t, &ipencap);

0 commit comments

Comments
 (0)