[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200205145725.19449-1-w.dauchy@criteo.com>
Date: Wed, 5 Feb 2020 15:57:25 +0100
From: William Dauchy <w.dauchy@...teo.com>
To: netdev@...r.kernel.org
Cc: Nicolas Dichtel <nicolas.dichtel@...nd.com>,
William Dauchy <w.dauchy@...teo.com>
Subject: [PATCH] net, ip6_tunnel: enhance tunnel locate with link/type check
With ipip, it is possible to create an extra interface explicitly
attached to a given physical interface:
# ip link show tunl0
4: tunl0@...E: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
# ip link add tunl1 type ipip dev eth0
# ip link show tunl1
6: tunl1@...0: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
But it is not possible with ip6tnl:
# ip link show ip6tnl0
5: ip6tnl0@...E: <NOARP> mtu 1452 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/tunnel6 :: brd ::
# ip link add ip6tnl1 type ip6tnl dev eth0
RTNETLINK answers: File exists
This patch aims to make it possible by adding the comparaison of the
link device while trying to locate an existing tunnel.
This later permits to make use of x-netns communication by moving the
newly created tunnel in a given netns.
Take this opportunity to also compare dev->type value as it is done in
ip_tunnel. This is therefore adding a new type parameter to
`ip6_tnl_locate`.
Signed-off-by: William Dauchy <w.dauchy@...teo.com>
---
net/ipv6/ip6_tunnel.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index b5dd20c4599b..0df3b3ca7608 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -339,7 +339,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
**/
static struct ip6_tnl *ip6_tnl_locate(struct net *net,
- struct __ip6_tnl_parm *p, int create)
+ struct __ip6_tnl_parm *p, int create, int type)
{
const struct in6_addr *remote = &p->raddr;
const struct in6_addr *local = &p->laddr;
@@ -351,7 +351,9 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net,
(t = rtnl_dereference(*tp)) != NULL;
tp = &t->next) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
- ipv6_addr_equal(remote, &t->parms.raddr)) {
+ ipv6_addr_equal(remote, &t->parms.raddr) &&
+ p->link == t->parms.link &&
+ type == t->dev->type) {
if (create)
return ERR_PTR(-EEXIST);
@@ -1600,7 +1602,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
}
ip6_tnl_parm_from_user(&p1, &p);
- t = ip6_tnl_locate(net, &p1, 0);
+ t = ip6_tnl_locate(net, &p1, 0, dev->type);
if (IS_ERR(t))
t = netdev_priv(dev);
} else {
@@ -1624,7 +1626,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
p.proto != 0)
break;
ip6_tnl_parm_from_user(&p1, &p);
- t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL);
+ t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL, dev->type);
if (cmd == SIOCCHGTUNNEL) {
if (!IS_ERR(t)) {
if (t->dev != dev) {
@@ -1659,7 +1661,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
err = -ENOENT;
ip6_tnl_parm_from_user(&p1, &p);
- t = ip6_tnl_locate(net, &p1, 0);
+ t = ip6_tnl_locate(net, &p1, 0, dev->type);
if (IS_ERR(t))
break;
err = -EPERM;
@@ -2015,7 +2017,7 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
if (rtnl_dereference(ip6n->collect_md_tun))
return -EEXIST;
} else {
- t = ip6_tnl_locate(net, &nt->parms, 0);
+ t = ip6_tnl_locate(net, &nt->parms, 0, dev->type);
if (!IS_ERR(t))
return -EEXIST;
}
@@ -2050,7 +2052,7 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
if (p.collect_md)
return -EINVAL;
- t = ip6_tnl_locate(net, &p, 0);
+ t = ip6_tnl_locate(net, &p, 0, dev->type);
if (!IS_ERR(t)) {
if (t->dev != dev)
return -EEXIST;
--
2.24.1
Powered by blists - more mailing lists