All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/10] Add support of tunnel management via rtnetlink
@ 2012-11-14 15:13 Nicolas Dichtel
  2012-11-14 15:13 ` [PATCH net-next 01/10] ip6tnl/rtnl: add IFLA_IPTUN_PROTO on dump Nicolas Dichtel
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:13 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet

The goal of this serie is to add the support of ipip, sit and ip6tnl tunnels
via rtnetlink.

The patch against iproute2 will be sent once the patches are included and
net-next merged. I can send it on demand.

 include/uapi/linux/if_tunnel.h |   2 +
 net/ipv4/ipip.c                | 175 ++++++++++++++++++++++++++++++------
 net/ipv6/ip6_tunnel.c          | 177 +++++++++++++++++++++++++++++++-----
 net/ipv6/sit.c                 | 199 +++++++++++++++++++++++++++++++++--------
 4 files changed, 469 insertions(+), 84 deletions(-)

Comments are welcome.

Regards,
Nicolas

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH net-next 01/10] ip6tnl/rtnl: add IFLA_IPTUN_PROTO on dump
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
@ 2012-11-14 15:13 ` Nicolas Dichtel
  2012-11-14 15:13 ` [PATCH net-next 02/10] ip6tnl: rename rtnl functions for consistency Nicolas Dichtel
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:13 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

IPv6 tunnels can have three mode: 4in6, 6in6 and xin6.
This information was missing in the netlink message.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/uapi/linux/if_tunnel.h | 1 +
 net/ipv6/ip6_tunnel.c          | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index c1bf0b5..f5ea6b7 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -47,6 +47,7 @@ enum {
 	IFLA_IPTUN_ENCAP_LIMIT,
 	IFLA_IPTUN_FLOWINFO,
 	IFLA_IPTUN_FLAGS,
+	IFLA_IPTUN_PROTO,
 	__IFLA_IPTUN_MAX,
 };
 #define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 424ed45..9a7d8c7 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1523,6 +1523,8 @@ static size_t ip6_get_size(const struct net_device *dev)
 		nla_total_size(4) +
 		/* IFLA_IPTUN_FLAGS */
 		nla_total_size(4) +
+		/* IFLA_IPTUN_PROTO */
+		nla_total_size(1) +
 		0;
 }
 
@@ -1539,7 +1541,8 @@ static int ip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) ||
 	    nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) ||
 	    nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
-	    nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags))
+	    nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
+	    nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto))
 		goto nla_put_failure;
 	return 0;
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 02/10] ip6tnl: rename rtnl functions for consistency
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
  2012-11-14 15:13 ` [PATCH net-next 01/10] ip6tnl/rtnl: add IFLA_IPTUN_PROTO on dump Nicolas Dichtel
@ 2012-11-14 15:13 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 03/10] ip6tnl: add support of link creation via rtnl Nicolas Dichtel
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:13 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

Functions in this file start with ip6_tnl_.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/ip6_tunnel.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9a7d8c7..6d35426 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1506,7 +1506,7 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
 	return 0;
 }
 
-static size_t ip6_get_size(const struct net_device *dev)
+static size_t ip6_tnl_get_size(const struct net_device *dev)
 {
 	return
 		/* IFLA_IPTUN_LINK */
@@ -1528,7 +1528,7 @@ static size_t ip6_get_size(const struct net_device *dev)
 		0;
 }
 
-static int ip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
+static int ip6_tnl_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
 	struct ip6_tnl *tunnel = netdev_priv(dev);
 	struct __ip6_tnl_parm *parm = &tunnel->parms;
@@ -1554,8 +1554,8 @@ static struct rtnl_link_ops ip6_link_ops __read_mostly = {
 	.kind		= "ip6tnl",
 	.maxtype	= IFLA_IPTUN_MAX,
 	.priv_size	= sizeof(struct ip6_tnl),
-	.get_size	= ip6_get_size,
-	.fill_info	= ip6_fill_info,
+	.get_size	= ip6_tnl_get_size,
+	.fill_info	= ip6_tnl_fill_info,
 };
 
 static struct xfrm6_tunnel ip4ip6_handler __read_mostly = {
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 03/10] ip6tnl: add support of link creation via rtnl
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
  2012-11-14 15:13 ` [PATCH net-next 01/10] ip6tnl/rtnl: add IFLA_IPTUN_PROTO on dump Nicolas Dichtel
  2012-11-14 15:13 ` [PATCH net-next 02/10] ip6tnl: rename rtnl functions for consistency Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 04/10] ipip: always notify change when params are updated Nicolas Dichtel
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

This patch add the support of 'ip link .. type ip6tnl'.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/ip6_tunnel.c | 164 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 149 insertions(+), 15 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6d35426..c583a87 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -259,6 +259,33 @@ static void ip6_dev_free(struct net_device *dev)
 	free_netdev(dev);
 }
 
+static int ip6_tnl_create2(struct net_device *dev)
+{
+	struct ip6_tnl *t = netdev_priv(dev);
+	struct net *net = dev_net(dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+	int err;
+
+	t = netdev_priv(dev);
+	err = ip6_tnl_dev_init(dev);
+	if (err < 0)
+		goto out;
+
+	err = register_netdevice(dev);
+	if (err < 0)
+		goto out;
+
+	strcpy(t->parms.name, dev->name);
+	dev->rtnl_link_ops = &ip6_link_ops;
+
+	dev_hold(dev);
+	ip6_tnl_link(ip6n, t);
+	return 0;
+
+out:
+	return err;
+}
+
 /**
  * ip6_tnl_create - create a new tunnel
  *   @p: tunnel parameters
@@ -277,7 +304,6 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
 	struct ip6_tnl *t;
 	char name[IFNAMSIZ];
 	int err;
-	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	if (p->name[0])
 		strlcpy(name, p->name, IFNAMSIZ);
@@ -292,18 +318,10 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
 
 	t = netdev_priv(dev);
 	t->parms = *p;
-	err = ip6_tnl_dev_init(dev);
+	err = ip6_tnl_create2(dev);
 	if (err < 0)
 		goto failed_free;
 
-	if ((err = register_netdevice(dev)) < 0)
-		goto failed_free;
-
-	strcpy(t->parms.name, dev->name);
-	dev->rtnl_link_ops = &ip6_link_ops;
-
-	dev_hold(dev);
-	ip6_tnl_link(ip6n, t);
 	return t;
 
 failed_free:
@@ -1238,6 +1256,20 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
 	return 0;
 }
 
+static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+{
+	struct net *net = dev_net(t->dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+	int err;
+
+	ip6_tnl_unlink(ip6n, t);
+	synchronize_net();
+	err = ip6_tnl_change(t, p);
+	ip6_tnl_link(ip6n, t);
+	netdev_state_change(t->dev);
+	return err;
+}
+
 static void
 ip6_tnl_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm *u)
 {
@@ -1346,11 +1378,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			} else
 				t = netdev_priv(dev);
 
-			ip6_tnl_unlink(ip6n, t);
-			synchronize_net();
-			err = ip6_tnl_change(t, &p1);
-			ip6_tnl_link(ip6n, t);
-			netdev_state_change(dev);
+			err = ip6_tnl_update(t, &p1);
 		}
 		if (t) {
 			err = 0;
@@ -1506,6 +1534,96 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
 	return 0;
 }
 
+static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	u8 proto;
+
+	if (!data)
+		return 0;
+
+	proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
+	if (proto != IPPROTO_IPV6 &&
+	    proto != IPPROTO_IPIP &&
+	    proto != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void ip6_tnl_netlink_parms(struct nlattr *data[],
+				  struct __ip6_tnl_parm *parms)
+{
+	memset(parms, 0, sizeof(*parms));
+
+	if (!data)
+		return;
+
+	if (data[IFLA_IPTUN_LINK])
+		parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]);
+
+	if (data[IFLA_IPTUN_LOCAL])
+		nla_memcpy(&parms->laddr, data[IFLA_IPTUN_LOCAL],
+			   sizeof(struct in6_addr));
+
+	if (data[IFLA_IPTUN_REMOTE])
+		nla_memcpy(&parms->raddr, data[IFLA_IPTUN_REMOTE],
+			   sizeof(struct in6_addr));
+
+	if (data[IFLA_IPTUN_TTL])
+		parms->hop_limit = nla_get_u8(data[IFLA_IPTUN_TTL]);
+
+	if (data[IFLA_IPTUN_ENCAP_LIMIT])
+		parms->encap_limit = nla_get_u8(data[IFLA_IPTUN_ENCAP_LIMIT]);
+
+	if (data[IFLA_IPTUN_FLOWINFO])
+		parms->flowinfo = nla_get_u32(data[IFLA_IPTUN_FLOWINFO]);
+
+	if (data[IFLA_IPTUN_FLAGS])
+		parms->flags = nla_get_u32(data[IFLA_IPTUN_FLAGS]);
+
+	if (data[IFLA_IPTUN_PROTO])
+		parms->proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
+}
+
+static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
+			   struct nlattr *tb[], struct nlattr *data[])
+{
+	struct net *net = dev_net(dev);
+	struct ip6_tnl *nt;
+
+	nt = netdev_priv(dev);
+	ip6_tnl_netlink_parms(data, &nt->parms);
+
+	if (ip6_tnl_locate(net, &nt->parms, 0))
+		return -EEXIST;
+
+	return ip6_tnl_create2(dev);
+}
+
+static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
+			      struct nlattr *data[])
+{
+	struct ip6_tnl *t;
+	struct __ip6_tnl_parm p;
+	struct net *net = dev_net(dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+
+	if (dev == ip6n->fb_tnl_dev)
+		return -EINVAL;
+
+	ip6_tnl_netlink_parms(data, &p);
+
+	t = ip6_tnl_locate(net, &p, 0);
+
+	if (t) {
+		if (t->dev != dev)
+			return -EEXIST;
+	} else
+		t = netdev_priv(dev);
+
+	return ip6_tnl_update(t, &p);
+}
+
 static size_t ip6_tnl_get_size(const struct net_device *dev)
 {
 	return
@@ -1550,10 +1668,26 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = {
+	[IFLA_IPTUN_LINK]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_LOCAL]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_IPTUN_REMOTE]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_IPTUN_TTL]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_ENCAP_LIMIT]	= { .type = NLA_U8 },
+	[IFLA_IPTUN_FLOWINFO]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_FLAGS]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_PROTO]		= { .type = NLA_U8 },
+};
+
 static struct rtnl_link_ops ip6_link_ops __read_mostly = {
 	.kind		= "ip6tnl",
 	.maxtype	= IFLA_IPTUN_MAX,
+	.policy		= ip6_tnl_policy,
 	.priv_size	= sizeof(struct ip6_tnl),
+	.setup		= ip6_tnl_dev_setup,
+	.validate	= ip6_tnl_validate,
+	.newlink	= ip6_tnl_newlink,
+	.changelink	= ip6_tnl_changelink,
 	.get_size	= ip6_tnl_get_size,
 	.fill_info	= ip6_tnl_fill_info,
 };
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 04/10] ipip: always notify change when params are updated
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (2 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 03/10] ip6tnl: add support of link creation via rtnl Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 05/10] ipip/rtnl: add IFLA_IPTUN_PMTUDISC on dump Nicolas Dichtel
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

netdev_state_change() was called only when end points or link was updated. Now
that all parameters are advertised via netlink, we must advertise any change.

This patch also prepares the support of ipip tunnels management via rtnl. The
code which update tunnels will be put in a new function.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv4/ipip.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 720855e..40984fa 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -699,29 +699,27 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 					break;
 				}
 				t = netdev_priv(dev);
-				ipip_tunnel_unlink(ipn, t);
-				synchronize_net();
-				t->parms.iph.saddr = p.iph.saddr;
-				t->parms.iph.daddr = p.iph.daddr;
-				memcpy(dev->dev_addr, &p.iph.saddr, 4);
-				memcpy(dev->broadcast, &p.iph.daddr, 4);
-				ipip_tunnel_link(ipn, t);
-				netdev_state_change(dev);
 			}
+
+			ipip_tunnel_unlink(ipn, t);
+			synchronize_net();
+			t->parms.iph.saddr = p.iph.saddr;
+			t->parms.iph.daddr = p.iph.daddr;
+			memcpy(dev->dev_addr, &p.iph.saddr, 4);
+			memcpy(dev->broadcast, &p.iph.daddr, 4);
+			ipip_tunnel_link(ipn, t);
+			t->parms.iph.ttl = p.iph.ttl;
+			t->parms.iph.tos = p.iph.tos;
+			t->parms.iph.frag_off = p.iph.frag_off;
+			if (t->parms.link != p.link) {
+				t->parms.link = p.link;
+				ipip_tunnel_bind_dev(dev);
+			}
+			netdev_state_change(dev);
 		}
 
 		if (t) {
 			err = 0;
-			if (cmd == SIOCCHGTUNNEL) {
-				t->parms.iph.ttl = p.iph.ttl;
-				t->parms.iph.tos = p.iph.tos;
-				t->parms.iph.frag_off = p.iph.frag_off;
-				if (t->parms.link != p.link) {
-					t->parms.link = p.link;
-					ipip_tunnel_bind_dev(dev);
-					netdev_state_change(dev);
-				}
-			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;
 		} else
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 05/10] ipip/rtnl: add IFLA_IPTUN_PMTUDISC on dump
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (3 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 04/10] ipip: always notify change when params are updated Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 06/10] ipip: add support of link creation via rtnl Nicolas Dichtel
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

This parameter was missing in the dump.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/uapi/linux/if_tunnel.h | 1 +
 net/ipv4/ipip.c                | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index f5ea6b7..5ab0c8d 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -48,6 +48,7 @@ enum {
 	IFLA_IPTUN_FLOWINFO,
 	IFLA_IPTUN_FLAGS,
 	IFLA_IPTUN_PROTO,
+	IFLA_IPTUN_PMTUDISC,
 	__IFLA_IPTUN_MAX,
 };
 #define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 40984fa..1204da3 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -854,6 +854,8 @@ static size_t ipip_get_size(const struct net_device *dev)
 		nla_total_size(1) +
 		/* IFLA_IPTUN_TOS */
 		nla_total_size(1) +
+		/* IFLA_IPTUN_PMTUDISC */
+		nla_total_size(1) +
 		0;
 }
 
@@ -866,7 +868,9 @@ static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) ||
 	    nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
 	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
-	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos))
+	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
+	    nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
+		       !!(parm->iph.frag_off & htons(IP_DF))))
 		goto nla_put_failure;
 	return 0;
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 06/10] ipip: add support of link creation via rtnl
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (4 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 05/10] ipip/rtnl: add IFLA_IPTUN_PMTUDISC on dump Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 07/10] sit: always notify change when params are updated Nicolas Dichtel
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

This patch add the support of 'ip link .. type ipip'.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv4/ipip.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 141 insertions(+), 24 deletions(-)

diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 1204da3..889735a 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -265,6 +265,32 @@ static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t)
 	rcu_assign_pointer(*tp, t);
 }
 
+static int ipip_tunnel_create(struct net_device *dev)
+{
+	struct ip_tunnel *t = netdev_priv(dev);
+	struct net *net = dev_net(dev);
+	struct ipip_net *ipn = net_generic(net, ipip_net_id);
+	int err;
+
+	err = ipip_tunnel_init(dev);
+	if (err < 0)
+		goto out;
+
+	err = register_netdevice(dev);
+	if (err < 0)
+		goto out;
+
+	strcpy(t->parms.name, dev->name);
+	dev->rtnl_link_ops = &ipip_link_ops;
+
+	dev_hold(dev);
+	ipip_tunnel_link(ipn, t);
+	return 0;
+
+out:
+	return err;
+}
+
 static struct ip_tunnel *ipip_tunnel_locate(struct net *net,
 		struct ip_tunnel_parm *parms, int create)
 {
@@ -299,17 +325,9 @@ static struct ip_tunnel *ipip_tunnel_locate(struct net *net,
 	nt = netdev_priv(dev);
 	nt->parms = *parms;
 
-	if (ipip_tunnel_init(dev) < 0)
+	if (ipip_tunnel_create(dev) < 0)
 		goto failed_free;
 
-	if (register_netdevice(dev) < 0)
-		goto failed_free;
-
-	strcpy(nt->parms.name, dev->name);
-	dev->rtnl_link_ops = &ipip_link_ops;
-
-	dev_hold(dev);
-	ipip_tunnel_link(ipn, nt);
 	return nt;
 
 failed_free:
@@ -641,6 +659,28 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
 	dev->iflink = tunnel->parms.link;
 }
 
+static void ipip_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
+{
+	struct net *net = dev_net(t->dev);
+	struct ipip_net *ipn = net_generic(net, ipip_net_id);
+
+	ipip_tunnel_unlink(ipn, t);
+	synchronize_net();
+	t->parms.iph.saddr = p->iph.saddr;
+	t->parms.iph.daddr = p->iph.daddr;
+	memcpy(t->dev->dev_addr, &p->iph.saddr, 4);
+	memcpy(t->dev->broadcast, &p->iph.daddr, 4);
+	ipip_tunnel_link(ipn, t);
+	t->parms.iph.ttl = p->iph.ttl;
+	t->parms.iph.tos = p->iph.tos;
+	t->parms.iph.frag_off = p->iph.frag_off;
+	if (t->parms.link != p->link) {
+		t->parms.link = p->link;
+		ipip_tunnel_bind_dev(t->dev);
+	}
+	netdev_state_change(t->dev);
+}
+
 static int
 ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -701,21 +741,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 				t = netdev_priv(dev);
 			}
 
-			ipip_tunnel_unlink(ipn, t);
-			synchronize_net();
-			t->parms.iph.saddr = p.iph.saddr;
-			t->parms.iph.daddr = p.iph.daddr;
-			memcpy(dev->dev_addr, &p.iph.saddr, 4);
-			memcpy(dev->broadcast, &p.iph.daddr, 4);
-			ipip_tunnel_link(ipn, t);
-			t->parms.iph.ttl = p.iph.ttl;
-			t->parms.iph.tos = p.iph.tos;
-			t->parms.iph.frag_off = p.iph.frag_off;
-			if (t->parms.link != p.link) {
-				t->parms.link = p.link;
-				ipip_tunnel_bind_dev(dev);
-			}
-			netdev_state_change(dev);
+			ipip_tunnel_update(t, &p);
 		}
 
 		if (t) {
@@ -841,6 +867,84 @@ static int __net_init ipip_fb_tunnel_init(struct net_device *dev)
 	return 0;
 }
 
+static void ipip_netlink_parms(struct nlattr *data[],
+			       struct ip_tunnel_parm *parms)
+{
+	memset(parms, 0, sizeof(*parms));
+
+	parms->iph.version = 4;
+	parms->iph.protocol = IPPROTO_IPIP;
+	parms->iph.ihl = 5;
+
+	if (!data)
+		return;
+
+	if (data[IFLA_IPTUN_LINK])
+		parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]);
+
+	if (data[IFLA_IPTUN_LOCAL])
+		parms->iph.saddr = nla_get_u32(data[IFLA_IPTUN_LOCAL]);
+
+	if (data[IFLA_IPTUN_REMOTE])
+		parms->iph.daddr = nla_get_u32(data[IFLA_IPTUN_REMOTE]);
+
+	if (data[IFLA_IPTUN_TTL]) {
+		parms->iph.ttl = nla_get_u8(data[IFLA_IPTUN_TTL]);
+		if (parms->iph.ttl)
+			parms->iph.frag_off = htons(IP_DF);
+	}
+
+	if (data[IFLA_IPTUN_TOS])
+		parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]);
+
+	if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC]))
+		parms->iph.frag_off = htons(IP_DF);
+}
+
+static int ipip_newlink(struct net *src_net, struct net_device *dev,
+			struct nlattr *tb[], struct nlattr *data[])
+{
+	struct net *net = dev_net(dev);
+	struct ip_tunnel *nt;
+
+	nt = netdev_priv(dev);
+	ipip_netlink_parms(data, &nt->parms);
+
+	if (ipip_tunnel_locate(net, &nt->parms, 0))
+		return -EEXIST;
+
+	return ipip_tunnel_create(dev);
+}
+
+static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
+			   struct nlattr *data[])
+{
+	struct ip_tunnel *t;
+	struct ip_tunnel_parm p;
+	struct net *net = dev_net(dev);
+	struct ipip_net *ipn = net_generic(net, ipip_net_id);
+
+	if (dev == ipn->fb_tunnel_dev)
+		return -EINVAL;
+
+	ipip_netlink_parms(data, &p);
+
+	if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
+	    (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr))
+		return -EINVAL;
+
+	t = ipip_tunnel_locate(net, &p, 0);
+
+	if (t) {
+		if (t->dev != dev)
+			return -EEXIST;
+	} else
+		t = netdev_priv(dev);
+
+	ipip_tunnel_update(t, &p);
+	return 0;
+}
+
 static size_t ipip_get_size(const struct net_device *dev)
 {
 	return
@@ -878,10 +982,23 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
+	[IFLA_IPTUN_LINK]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_LOCAL]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_REMOTE]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_TTL]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_TOS]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_PMTUDISC]		= { .type = NLA_U8 },
+};
+
 static struct rtnl_link_ops ipip_link_ops __read_mostly = {
 	.kind		= "ipip",
 	.maxtype	= IFLA_IPTUN_MAX,
+	.policy		= ipip_policy,
 	.priv_size	= sizeof(struct ip_tunnel),
+	.setup		= ipip_tunnel_setup,
+	.newlink	= ipip_newlink,
+	.changelink	= ipip_changelink,
 	.get_size	= ipip_get_size,
 	.fill_info	= ipip_fill_info,
 };
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 07/10] sit: always notify change when params are updated
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (5 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 06/10] ipip: add support of link creation via rtnl Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 08/10] sit/rtnl: add missing parameters on dump Nicolas Dichtel
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

netdev_state_change() was called only when end points or link was updated. Now
that all parameters are advertised via netlink, we must advertise any change.

This patch also prepares the support of sit tunnels management via rtnl. The
code which update tunnels will be put in a new function.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/sit.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b543c56..b2cfdda 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -997,28 +997,26 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 					break;
 				}
 				t = netdev_priv(dev);
-				ipip6_tunnel_unlink(sitn, t);
-				synchronize_net();
-				t->parms.iph.saddr = p.iph.saddr;
-				t->parms.iph.daddr = p.iph.daddr;
-				memcpy(dev->dev_addr, &p.iph.saddr, 4);
-				memcpy(dev->broadcast, &p.iph.daddr, 4);
-				ipip6_tunnel_link(sitn, t);
-				netdev_state_change(dev);
 			}
+
+			ipip6_tunnel_unlink(sitn, t);
+			synchronize_net();
+			t->parms.iph.saddr = p.iph.saddr;
+			t->parms.iph.daddr = p.iph.daddr;
+			memcpy(dev->dev_addr, &p.iph.saddr, 4);
+			memcpy(dev->broadcast, &p.iph.daddr, 4);
+			ipip6_tunnel_link(sitn, t);
+			t->parms.iph.ttl = p.iph.ttl;
+			t->parms.iph.tos = p.iph.tos;
+			if (t->parms.link != p.link) {
+				t->parms.link = p.link;
+				ipip6_tunnel_bind_dev(dev);
+			}
+			netdev_state_change(dev);
 		}
 
 		if (t) {
 			err = 0;
-			if (cmd == SIOCCHGTUNNEL) {
-				t->parms.iph.ttl = p.iph.ttl;
-				t->parms.iph.tos = p.iph.tos;
-				if (t->parms.link != p.link) {
-					t->parms.link = p.link;
-					ipip6_tunnel_bind_dev(dev);
-					netdev_state_change(dev);
-				}
-			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;
 		} else
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 08/10] sit/rtnl: add missing parameters on dump
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (6 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 07/10] sit: always notify change when params are updated Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 09/10] sit: rename rtnl functions for consistency Nicolas Dichtel
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

IFLA_IPTUN_FLAGS and IFLA_IPTUN_PMTUDISC were missing.
There is only one possible flag in i_flag: SIT_ISATAP.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/sit.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b2cfdda..28f56ee 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1229,6 +1229,10 @@ static size_t sit_get_size(const struct net_device *dev)
 		nla_total_size(1) +
 		/* IFLA_IPTUN_TOS */
 		nla_total_size(1) +
+		/* IFLA_IPTUN_PMTUDISC */
+		nla_total_size(1) +
+		/* IFLA_IPTUN_FLAGS */
+		nla_total_size(2) +
 		0;
 }
 
@@ -1241,7 +1245,10 @@ static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) ||
 	    nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
 	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
-	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos))
+	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
+	    nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
+		       !!(parm->iph.frag_off & htons(IP_DF))) ||
+	    nla_put_u16(skb, IFLA_IPTUN_FLAGS, parm->i_flags))
 		goto nla_put_failure;
 	return 0;
 
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 09/10] sit: rename rtnl functions for consistency
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (7 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 08/10] sit/rtnl: add missing parameters on dump Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-14 15:14 ` [PATCH net-next 10/10] sit: add support of link creation via rtnl Nicolas Dichtel
  2012-11-15  3:03 ` [PATCH net-next 0/10] Add support of tunnel management via rtnetlink David Miller
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

Functions in this file start with ipip6_.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/sit.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 28f56ee..28c1b82 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1216,7 +1216,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
 	return 0;
 }
 
-static size_t sit_get_size(const struct net_device *dev)
+static size_t ipip6_get_size(const struct net_device *dev)
 {
 	return
 		/* IFLA_IPTUN_LINK */
@@ -1236,7 +1236,7 @@ static size_t sit_get_size(const struct net_device *dev)
 		0;
 }
 
-static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev)
+static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct ip_tunnel_parm *parm = &tunnel->parms;
@@ -1260,8 +1260,8 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = {
 	.kind		= "sit",
 	.maxtype	= IFLA_IPTUN_MAX,
 	.priv_size	= sizeof(struct ip_tunnel),
-	.get_size	= sit_get_size,
-	.fill_info	= sit_fill_info,
+	.get_size	= ipip6_get_size,
+	.fill_info	= ipip6_fill_info,
 };
 
 static struct xfrm_tunnel sit_handler __read_mostly = {
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 10/10] sit: add support of link creation via rtnl
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (8 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 09/10] sit: rename rtnl functions for consistency Nicolas Dichtel
@ 2012-11-14 15:14 ` Nicolas Dichtel
  2012-11-15  3:03 ` [PATCH net-next 0/10] Add support of tunnel management via rtnetlink David Miller
  10 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2012-11-14 15:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, Nicolas Dichtel

This patch add the support of 'ip link .. type sit'.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/sit.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 150 insertions(+), 28 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 28c1b82..7db6c54 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -232,6 +232,37 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
 #endif
 }
 
+static int ipip6_tunnel_create(struct net_device *dev)
+{
+	struct ip_tunnel *t = netdev_priv(dev);
+	struct net *net = dev_net(dev);
+	struct sit_net *sitn = net_generic(net, sit_net_id);
+	int err;
+
+	err = ipip6_tunnel_init(dev);
+	if (err < 0)
+		goto out;
+	ipip6_tunnel_clone_6rd(dev, sitn);
+
+	if (t->parms.i_flags & SIT_ISATAP)
+		dev->priv_flags |= IFF_ISATAP;
+
+	err = register_netdevice(dev);
+	if (err < 0)
+		goto out;
+
+	strcpy(t->parms.name, dev->name);
+	dev->rtnl_link_ops = &sit_link_ops;
+
+	dev_hold(dev);
+
+	ipip6_tunnel_link(sitn, t);
+	return 0;
+
+out:
+	return err;
+}
+
 static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
 		struct ip_tunnel_parm *parms, int create)
 {
@@ -272,22 +303,9 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
 	nt = netdev_priv(dev);
 
 	nt->parms = *parms;
-	if (ipip6_tunnel_init(dev) < 0)
-		goto failed_free;
-	ipip6_tunnel_clone_6rd(dev, sitn);
-
-	if (parms->i_flags & SIT_ISATAP)
-		dev->priv_flags |= IFF_ISATAP;
-
-	if (register_netdevice(dev) < 0)
+	if (ipip6_tunnel_create(dev) < 0)
 		goto failed_free;
 
-	strcpy(nt->parms.name, dev->name);
-	dev->rtnl_link_ops = &sit_link_ops;
-
-	dev_hold(dev);
-
-	ipip6_tunnel_link(sitn, nt);
 	return nt;
 
 failed_free:
@@ -916,6 +934,27 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
 	dev->iflink = tunnel->parms.link;
 }
 
+static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
+{
+	struct net *net = dev_net(t->dev);
+	struct sit_net *sitn = net_generic(net, sit_net_id);
+
+	ipip6_tunnel_unlink(sitn, t);
+	synchronize_net();
+	t->parms.iph.saddr = p->iph.saddr;
+	t->parms.iph.daddr = p->iph.daddr;
+	memcpy(t->dev->dev_addr, &p->iph.saddr, 4);
+	memcpy(t->dev->broadcast, &p->iph.daddr, 4);
+	ipip6_tunnel_link(sitn, t);
+	t->parms.iph.ttl = p->iph.ttl;
+	t->parms.iph.tos = p->iph.tos;
+	if (t->parms.link != p->link) {
+		t->parms.link = p->link;
+		ipip6_tunnel_bind_dev(t->dev);
+	}
+	netdev_state_change(t->dev);
+}
+
 static int
 ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -999,20 +1038,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 				t = netdev_priv(dev);
 			}
 
-			ipip6_tunnel_unlink(sitn, t);
-			synchronize_net();
-			t->parms.iph.saddr = p.iph.saddr;
-			t->parms.iph.daddr = p.iph.daddr;
-			memcpy(dev->dev_addr, &p.iph.saddr, 4);
-			memcpy(dev->broadcast, &p.iph.daddr, 4);
-			ipip6_tunnel_link(sitn, t);
-			t->parms.iph.ttl = p.iph.ttl;
-			t->parms.iph.tos = p.iph.tos;
-			if (t->parms.link != p.link) {
-				t->parms.link = p.link;
-				ipip6_tunnel_bind_dev(dev);
-			}
-			netdev_state_change(dev);
+			ipip6_tunnel_update(t, &p);
 		}
 
 		if (t) {
@@ -1216,6 +1242,88 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
 	return 0;
 }
 
+static void ipip6_netlink_parms(struct nlattr *data[],
+				struct ip_tunnel_parm *parms)
+{
+	memset(parms, 0, sizeof(*parms));
+
+	parms->iph.version = 4;
+	parms->iph.protocol = IPPROTO_IPV6;
+	parms->iph.ihl = 5;
+	parms->iph.ttl = 64;
+
+	if (!data)
+		return;
+
+	if (data[IFLA_IPTUN_LINK])
+		parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]);
+
+	if (data[IFLA_IPTUN_LOCAL])
+		parms->iph.saddr = nla_get_u32(data[IFLA_IPTUN_LOCAL]);
+
+	if (data[IFLA_IPTUN_REMOTE])
+		parms->iph.daddr = nla_get_u32(data[IFLA_IPTUN_REMOTE]);
+
+	if (data[IFLA_IPTUN_TTL]) {
+		parms->iph.ttl = nla_get_u8(data[IFLA_IPTUN_TTL]);
+		if (parms->iph.ttl)
+			parms->iph.frag_off = htons(IP_DF);
+	}
+
+	if (data[IFLA_IPTUN_TOS])
+		parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]);
+
+	if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC]))
+		parms->iph.frag_off = htons(IP_DF);
+
+	if (data[IFLA_IPTUN_FLAGS])
+		parms->i_flags = nla_get_u16(data[IFLA_IPTUN_FLAGS]);
+}
+
+static int ipip6_newlink(struct net *src_net, struct net_device *dev,
+			 struct nlattr *tb[], struct nlattr *data[])
+{
+	struct net *net = dev_net(dev);
+	struct ip_tunnel *nt;
+
+	nt = netdev_priv(dev);
+	ipip6_netlink_parms(data, &nt->parms);
+
+	if (ipip6_tunnel_locate(net, &nt->parms, 0))
+		return -EEXIST;
+
+	return ipip6_tunnel_create(dev);
+}
+
+static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[],
+			  struct nlattr *data[])
+{
+	struct ip_tunnel *t;
+	struct ip_tunnel_parm p;
+	struct net *net = dev_net(dev);
+	struct sit_net *sitn = net_generic(net, sit_net_id);
+
+	if (dev == sitn->fb_tunnel_dev)
+		return -EINVAL;
+
+	ipip6_netlink_parms(data, &p);
+
+	if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
+	    (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr))
+		return -EINVAL;
+
+	t = ipip6_tunnel_locate(net, &p, 0);
+
+	if (t) {
+		if (t->dev != dev)
+			return -EEXIST;
+	} else
+		t = netdev_priv(dev);
+
+	ipip6_tunnel_update(t, &p);
+	return 0;
+}
+
 static size_t ipip6_get_size(const struct net_device *dev)
 {
 	return
@@ -1256,10 +1364,24 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
+	[IFLA_IPTUN_LINK]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_LOCAL]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_REMOTE]		= { .type = NLA_U32 },
+	[IFLA_IPTUN_TTL]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_TOS]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_PMTUDISC]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_FLAGS]		= { .type = NLA_U16 },
+};
+
 static struct rtnl_link_ops sit_link_ops __read_mostly = {
 	.kind		= "sit",
 	.maxtype	= IFLA_IPTUN_MAX,
+	.policy		= ipip6_policy,
 	.priv_size	= sizeof(struct ip_tunnel),
+	.setup		= ipip6_tunnel_setup,
+	.newlink	= ipip6_newlink,
+	.changelink	= ipip6_changelink,
 	.get_size	= ipip6_get_size,
 	.fill_info	= ipip6_fill_info,
 };
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/10] Add support of tunnel management via rtnetlink
  2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
                   ` (9 preceding siblings ...)
  2012-11-14 15:14 ` [PATCH net-next 10/10] sit: add support of link creation via rtnl Nicolas Dichtel
@ 2012-11-15  3:03 ` David Miller
  10 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2012-11-15  3:03 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: netdev, eric.dumazet

From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Date: Wed, 14 Nov 2012 16:13:57 +0100

> The goal of this serie is to add the support of ipip, sit and ip6tnl tunnels
> via rtnetlink.
> 
> The patch against iproute2 will be sent once the patches are included and
> net-next merged. I can send it on demand.

Great work, all applied to net-next.

Thanks Nicolas!

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-11-15  3:03 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-14 15:13 [PATCH net-next 0/10] Add support of tunnel management via rtnetlink Nicolas Dichtel
2012-11-14 15:13 ` [PATCH net-next 01/10] ip6tnl/rtnl: add IFLA_IPTUN_PROTO on dump Nicolas Dichtel
2012-11-14 15:13 ` [PATCH net-next 02/10] ip6tnl: rename rtnl functions for consistency Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 03/10] ip6tnl: add support of link creation via rtnl Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 04/10] ipip: always notify change when params are updated Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 05/10] ipip/rtnl: add IFLA_IPTUN_PMTUDISC on dump Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 06/10] ipip: add support of link creation via rtnl Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 07/10] sit: always notify change when params are updated Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 08/10] sit/rtnl: add missing parameters on dump Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 09/10] sit: rename rtnl functions for consistency Nicolas Dichtel
2012-11-14 15:14 ` [PATCH net-next 10/10] sit: add support of link creation via rtnl Nicolas Dichtel
2012-11-15  3:03 ` [PATCH net-next 0/10] Add support of tunnel management via rtnetlink David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.