netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing
@ 2018-02-12 20:17 Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 1/4] utils: Introduce and use inet_prefix_reset() Serhey Popovych
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Serhey Popovych @ 2018-02-12 20:17 UTC (permalink / raw)
  To: netdev

Use get_addr_rta() helper to unify address retriveal from netlink
message when configuring tunnel and get_addr() to parse endpoint
address into @inet_prefix.

This is next step towards ip and ipv6 tunnel module merge: endpoint
address parsing code will differ only in @family constant being
passed to get_addr_rta() and get_addr().

Reviews, comments and suggestions are welcome.

v3
  Rename inet_prefix_reset_flags() to inet_prefix_reset() looks more
  convenient to hide reset implementation.

v2
  Introduce and use inet_prefix_reset_flags() inline helper to
  initialize @inet_prefix data structure and make code self exmplaining.

  Set bitlen to zero in link_iptnl.c when kernel does not send
  corresponding prefixlen and we configure existing tunnel.

Thanks,
Serhey

Serhey Popovych (4):
  utils: Introduce and use inet_prefix_reset()
  vti/vti6: Unify local/remote endpoint address parsing
  gre/gre6: Unify local/remote endpoint address parsing
  iptnl/ip6tnl: Unify local/remote endpoint and 6rd address parsing

 include/utils.h    |    5 +++
 ip/iplink_geneve.c |    2 +-
 ip/iplink_vxlan.c  |    7 ++--
 ip/link_gre.c      |   57 +++++++++++++++++------------
 ip/link_gre6.c     |   38 ++++++++++---------
 ip/link_ip6tnl.c   |   40 +++++++++++---------
 ip/link_iptnl.c    |  103 ++++++++++++++++++++++++++--------------------------
 ip/link_vti.c      |   32 ++++++++++------
 ip/link_vti6.c     |   38 ++++++++++---------
 9 files changed, 177 insertions(+), 145 deletions(-)

-- 
1.7.10.4

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

* [PATCH iproute2-next v3 1/4] utils: Introduce and use inet_prefix_reset()
  2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
@ 2018-02-12 20:17 ` Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 2/4] vti/vti6: Unify local/remote endpoint address parsing Serhey Popovych
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Serhey Popovych @ 2018-02-12 20:17 UTC (permalink / raw)
  To: netdev

Initializing @inet_prefix using C initializers or memset() seems
inefficient and unnecessary: only small part of ->data[] field will be
used to store address corresponding to ->family.

Instead initialize ->flags with zero and assume no other fields accessed
before checking corresponding bits in ->flags. For example special
helpers (e.g. is_addrtype_*()) can be used to ensure that @inet_prefix
contains valid ip or ipv6 address.

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 include/utils.h    |    5 +++++
 ip/iplink_geneve.c |    2 +-
 ip/iplink_vxlan.c  |    7 ++++---
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/utils.h b/include/utils.h
index 4dc514d..867e540 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -65,6 +65,11 @@ enum {
 	ADDRTYPE_INET_MULTI	= ADDRTYPE_INET | ADDRTYPE_MULTI
 };
 
+static inline void inet_prefix_reset(inet_prefix *p)
+{
+	p->flags = 0;
+}
+
 static inline bool is_addrtype_inet(const inet_prefix *p)
 {
 	return p->flags & ADDRTYPE_INET;
diff --git a/ip/iplink_geneve.c b/ip/iplink_geneve.c
index c666072..1fcdd83 100644
--- a/ip/iplink_geneve.c
+++ b/ip/iplink_geneve.c
@@ -71,7 +71,7 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
 	bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
 		       !(n->nlmsg_flags & NLM_F_CREATE));
 
-	daddr.flags = 0;
+	inet_prefix_reset(&daddr);
 
 	while (argc > 0) {
 		if (!matches(*argv, "id") ||
diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 00875ba..d768c07 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -74,8 +74,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
 static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 			  struct nlmsghdr *n)
 {
-	inet_prefix saddr;
-	inet_prefix daddr;
+	inet_prefix saddr, daddr;
 	__u32 vni = 0;
 	__u8 learning = 1;
 	__u16 dstport = 0;
@@ -85,7 +84,9 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 		       !(n->nlmsg_flags & NLM_F_CREATE));
 
 	saddr.family = daddr.family = AF_UNSPEC;
-	saddr.flags = daddr.flags = 0;
+
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
 
 	while (argc > 0) {
 		if (!matches(*argv, "id") ||
-- 
1.7.10.4

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

* [PATCH iproute2-next v3 2/4] vti/vti6: Unify local/remote endpoint address parsing
  2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 1/4] utils: Introduce and use inet_prefix_reset() Serhey Popovych
@ 2018-02-12 20:17 ` Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 3/4] gre/gre6: " Serhey Popovych
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Serhey Popovych @ 2018-02-12 20:17 UTC (permalink / raw)
  To: netdev

We are going to merge link_vti.c and link_vti6.c and this is final step
to make their diffs clear and show what needs to be changed during merge.

Note that it is safe to omit endpoint address(es) from netlink create
request as kernel is aware of such case and will use zero for that
endpoint(s).

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 ip/link_vti.c  |   32 ++++++++++++++++++++------------
 ip/link_vti6.c |   38 ++++++++++++++++++++------------------
 2 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/ip/link_vti.c b/ip/link_vti.c
index edd17fe..99e10e8 100644
--- a/ip/link_vti.c
+++ b/ip/link_vti.c
@@ -64,13 +64,17 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
 	struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
 	__be32 ikey = 0;
 	__be32 okey = 0;
-	unsigned int saddr = 0;
-	unsigned int daddr = 0;
+	inet_prefix saddr, daddr;
 	unsigned int link = 0;
 	__u32 fwmark = 0;
 	int len;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -96,18 +100,20 @@ get_failed:
 		parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
+		rta = vtiinfo[IFLA_VTI_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET))
+			goto get_failed;
+
+		rta = vtiinfo[IFLA_VTI_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET))
+			goto get_failed;
+
 		if (vtiinfo[IFLA_VTI_IKEY])
 			ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]);
 
 		if (vtiinfo[IFLA_VTI_OKEY])
 			okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]);
 
-		if (vtiinfo[IFLA_VTI_LOCAL])
-			saddr = rta_getattr_u32(vtiinfo[IFLA_VTI_LOCAL]);
-
-		if (vtiinfo[IFLA_VTI_REMOTE])
-			daddr = rta_getattr_u32(vtiinfo[IFLA_VTI_REMOTE]);
-
 		if (vtiinfo[IFLA_VTI_LINK])
 			link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
 
@@ -129,10 +135,10 @@ get_failed:
 			okey = tnl_parse_key("okey", *argv);
 		} else if (!matches(*argv, "remote")) {
 			NEXT_ARG();
-			daddr = get_addr32(*argv);
+			get_addr(&daddr, *argv, AF_INET);
 		} else if (!matches(*argv, "local")) {
 			NEXT_ARG();
-			saddr = get_addr32(*argv);
+			get_addr(&saddr, *argv, AF_INET);
 		} else if (!matches(*argv, "dev")) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -154,8 +160,10 @@ get_failed:
 
 	addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
 	addattr32(n, 1024, IFLA_VTI_OKEY, okey);
-	addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, 4);
-	addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, 4);
+	if (is_addrtype_inet(&saddr))
+		addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
+	if (is_addrtype_inet(&daddr))
+		addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
 	addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
 	if (link)
 		addattr32(n, 1024, IFLA_VTI_LINK, link);
diff --git a/ip/link_vti6.c b/ip/link_vti6.c
index 1276ebd..1df6579 100644
--- a/ip/link_vti6.c
+++ b/ip/link_vti6.c
@@ -64,15 +64,19 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
 	struct rtattr *tb[IFLA_MAX + 1];
 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
 	struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
-	struct in6_addr saddr = IN6ADDR_ANY_INIT;
-	struct in6_addr daddr = IN6ADDR_ANY_INIT;
 	__be32 ikey = 0;
 	__be32 okey = 0;
+	inet_prefix saddr, daddr;
 	unsigned int link = 0;
 	__u32 fwmark = 0;
 	int len;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -98,18 +102,20 @@ get_failed:
 		parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
+		rta = vtiinfo[IFLA_VTI_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET6))
+			goto get_failed;
+
+		rta = vtiinfo[IFLA_VTI_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET6))
+			goto get_failed;
+
 		if (vtiinfo[IFLA_VTI_IKEY])
 			ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]);
 
 		if (vtiinfo[IFLA_VTI_OKEY])
 			okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]);
 
-		if (vtiinfo[IFLA_VTI_LOCAL])
-			memcpy(&saddr, RTA_DATA(vtiinfo[IFLA_VTI_LOCAL]), sizeof(saddr));
-
-		if (vtiinfo[IFLA_VTI_REMOTE])
-			memcpy(&daddr, RTA_DATA(vtiinfo[IFLA_VTI_REMOTE]), sizeof(daddr));
-
 		if (vtiinfo[IFLA_VTI_LINK])
 			link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
 
@@ -130,17 +136,11 @@ get_failed:
 			NEXT_ARG();
 			okey = tnl_parse_key("okey", *argv);
 		} else if (!matches(*argv, "remote")) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&daddr, addr.data, sizeof(daddr));
+			get_addr(&daddr, *argv, AF_INET6);
 		} else if (!matches(*argv, "local")) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&saddr, addr.data, sizeof(saddr));
+			get_addr(&saddr, *argv, AF_INET6);
 		} else if (!matches(*argv, "dev")) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -162,8 +162,10 @@ get_failed:
 
 	addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
 	addattr32(n, 1024, IFLA_VTI_OKEY, okey);
-	addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
-	addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
+	if (is_addrtype_inet(&saddr))
+		addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
+	if (is_addrtype_inet(&daddr))
+		addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
 	addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
 	if (link)
 		addattr32(n, 1024, IFLA_VTI_LINK, link);
-- 
1.7.10.4

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

* [PATCH iproute2-next v3 3/4] gre/gre6: Unify local/remote endpoint address parsing
  2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 1/4] utils: Introduce and use inet_prefix_reset() Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 2/4] vti/vti6: Unify local/remote endpoint address parsing Serhey Popovych
@ 2018-02-12 20:17 ` Serhey Popovych
  2018-02-12 20:17 ` [PATCH iproute2-next v3 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd " Serhey Popovych
  2018-02-14 17:03 ` [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint " David Ahern
  4 siblings, 0 replies; 6+ messages in thread
From: Serhey Popovych @ 2018-02-12 20:17 UTC (permalink / raw)
  To: netdev

We are going to merge link_gre.c and link_gre6.c and this is final step
to make their diffs clear and show what needs to be changed during merge.

Note that it is safe to omit endpoint address(es) from netlink create
request as kernel is aware of such case and will use zero for that
endpoint(s).

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 ip/link_gre.c  |   57 +++++++++++++++++++++++++++++++++-----------------------
 ip/link_gre6.c |   38 +++++++++++++++++++------------------
 2 files changed, 54 insertions(+), 41 deletions(-)

diff --git a/ip/link_gre.c b/ip/link_gre.c
index e3e5323..64588d7 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -86,8 +86,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u16 oflags = 0;
 	__be32 ikey = 0;
 	__be32 okey = 0;
-	unsigned int saddr = 0;
-	unsigned int daddr = 0;
+	inet_prefix saddr, daddr;
 	__u8 pmtudisc = 1;
 	__u8 ignore_df = 0;
 	__u8 tos = 0;
@@ -104,7 +103,12 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 erspan_dir = 0;
 	__u16 erspan_hwid = 0;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -130,6 +134,14 @@ get_failed:
 		parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
+		rta = greinfo[IFLA_GRE_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET))
+			goto get_failed;
+
+		rta = greinfo[IFLA_GRE_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET))
+			goto get_failed;
+
 		if (greinfo[IFLA_GRE_IKEY])
 			ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);
 
@@ -142,12 +154,6 @@ get_failed:
 		if (greinfo[IFLA_GRE_OFLAGS])
 			oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);
 
-		if (greinfo[IFLA_GRE_LOCAL])
-			saddr = rta_getattr_u32(greinfo[IFLA_GRE_LOCAL]);
-
-		if (greinfo[IFLA_GRE_REMOTE])
-			daddr = rta_getattr_u32(greinfo[IFLA_GRE_REMOTE]);
-
 		if (greinfo[IFLA_GRE_PMTUDISC])
 			pmtudisc = rta_getattr_u8(
 				greinfo[IFLA_GRE_PMTUDISC]);
@@ -232,10 +238,10 @@ get_failed:
 			pmtudisc = 1;
 		} else if (!matches(*argv, "remote")) {
 			NEXT_ARG();
-			daddr = get_addr32(*argv);
+			get_addr(&daddr, *argv, AF_INET);
 		} else if (!matches(*argv, "local")) {
 			NEXT_ARG();
-			saddr = get_addr32(*argv);
+			get_addr(&saddr, *argv, AF_INET);
 		} else if (!matches(*argv, "dev")) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -343,17 +349,20 @@ get_failed:
 		argc--; argv++;
 	}
 
-	if (!ikey && IN_MULTICAST(ntohl(daddr))) {
-		ikey = daddr;
-		iflags |= GRE_KEY;
-	}
-	if (!okey && IN_MULTICAST(ntohl(daddr))) {
-		okey = daddr;
-		oflags |= GRE_KEY;
-	}
-	if (IN_MULTICAST(ntohl(daddr)) && !saddr) {
-		fprintf(stderr, "A broadcast tunnel requires a source address.\n");
-		return -1;
+	if (is_addrtype_inet_multi(&daddr)) {
+		if (!ikey) {
+			ikey = daddr.data[0];
+			iflags |= GRE_KEY;
+		}
+		if (!okey) {
+			okey = daddr.data[0];
+			oflags |= GRE_KEY;
+		}
+		if (!is_addrtype_inet_not_unspec(&saddr)) {
+			fprintf(stderr,
+				"A broadcast tunnel requires a source address.\n");
+			return -1;
+		}
 	}
 
 	if (metadata) {
@@ -365,8 +374,10 @@ get_failed:
 	addattr32(n, 1024, IFLA_GRE_OKEY, okey);
 	addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
 	addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
-	addattr_l(n, 1024, IFLA_GRE_LOCAL, &saddr, 4);
-	addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4);
+	if (is_addrtype_inet(&saddr))
+		addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
+	if (is_addrtype_inet(&daddr))
+		addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
 	addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
 	if (ignore_df)
 		addattr8(n, 1024, IFLA_GRE_IGNORE_DF, ignore_df & 1);
diff --git a/ip/link_gre6.c b/ip/link_gre6.c
index 251ae0e..6c77038 100644
--- a/ip/link_gre6.c
+++ b/ip/link_gre6.c
@@ -97,8 +97,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u16 oflags = 0;
 	__be32 ikey = 0;
 	__be32 okey = 0;
-	struct in6_addr raddr = IN6ADDR_ANY_INIT;
-	struct in6_addr laddr = IN6ADDR_ANY_INIT;
+	inet_prefix saddr, daddr;
 	__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
 	__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
 	__u32 flowinfo = 0;
@@ -115,7 +114,12 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 erspan_dir = 0;
 	__u16 erspan_hwid = 0;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -141,6 +145,14 @@ get_failed:
 		parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
+		rta = greinfo[IFLA_GRE_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET6))
+			goto get_failed;
+
+		rta = greinfo[IFLA_GRE_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET6))
+			goto get_failed;
+
 		if (greinfo[IFLA_GRE_IKEY])
 			ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);
 
@@ -153,12 +165,6 @@ get_failed:
 		if (greinfo[IFLA_GRE_OFLAGS])
 			oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);
 
-		if (greinfo[IFLA_GRE_LOCAL])
-			memcpy(&laddr, RTA_DATA(greinfo[IFLA_GRE_LOCAL]), sizeof(laddr));
-
-		if (greinfo[IFLA_GRE_REMOTE])
-			memcpy(&raddr, RTA_DATA(greinfo[IFLA_GRE_REMOTE]), sizeof(raddr));
-
 		if (greinfo[IFLA_GRE_TTL])
 			hop_limit = rta_getattr_u8(greinfo[IFLA_GRE_TTL]);
 
@@ -236,17 +242,11 @@ get_failed:
 		} else if (!matches(*argv, "ocsum")) {
 			oflags |= GRE_CSUM;
 		} else if (!matches(*argv, "remote")) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&raddr, &addr.data, sizeof(raddr));
+			get_addr(&daddr, *argv, AF_INET6);
 		} else if (!matches(*argv, "local")) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&laddr, &addr.data, sizeof(laddr));
+			get_addr(&saddr, *argv, AF_INET6);
 		} else if (!matches(*argv, "dev")) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -398,8 +398,10 @@ get_failed:
 	addattr32(n, 1024, IFLA_GRE_OKEY, okey);
 	addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
 	addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
-	addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr));
-	addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr));
+	if (is_addrtype_inet(&saddr))
+		addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
+	if (is_addrtype_inet(&daddr))
+		addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
 	if (link)
 		addattr32(n, 1024, IFLA_GRE_LINK, link);
 	addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1);
-- 
1.7.10.4

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

* [PATCH iproute2-next v3 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd address parsing
  2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
                   ` (2 preceding siblings ...)
  2018-02-12 20:17 ` [PATCH iproute2-next v3 3/4] gre/gre6: " Serhey Popovych
@ 2018-02-12 20:17 ` Serhey Popovych
  2018-02-14 17:03 ` [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint " David Ahern
  4 siblings, 0 replies; 6+ messages in thread
From: Serhey Popovych @ 2018-02-12 20:17 UTC (permalink / raw)
  To: netdev

We are going to merge link_iptnl.c and link_ip6tnl.c and this is final
step to make their diffs clear and show what needs to be changed during
merge.

Note that it is safe to omit endpoint address(es) from netlink create
request as kernel is aware of such case and will use zero for that
endpoint(s).

Make sure we initialize ip6rdprefix and ip6rdrelayprefix bitlen in
link_iptnl.c only when configuring existing tunnel: if kernel does not
submit prefixlen in corresponding attributes preceeding get_addr_rta()
will set bitlen to -1 which is incorrect value.

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 ip/link_ip6tnl.c |   40 +++++++++++----------
 ip/link_iptnl.c  |  103 +++++++++++++++++++++++++++---------------------------
 2 files changed, 73 insertions(+), 70 deletions(-)

diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c
index 8a45d42..77a9090 100644
--- a/ip/link_ip6tnl.c
+++ b/ip/link_ip6tnl.c
@@ -93,8 +93,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
 	struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
 	int len;
-	struct in6_addr laddr = IN6ADDR_ANY_INIT;
-	struct in6_addr raddr = IN6ADDR_ANY_INIT;
+	inet_prefix saddr, daddr;
 	__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
 	__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
 	__u32 flowinfo = 0;
@@ -108,7 +107,12 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 metadata = 0;
 	__u32 fwmark = 0;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -134,13 +138,13 @@ get_failed:
 		parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
-		if (iptuninfo[IFLA_IPTUN_LOCAL])
-			memcpy(&laddr, RTA_DATA(iptuninfo[IFLA_IPTUN_LOCAL]),
-			       sizeof(laddr));
+		rta = iptuninfo[IFLA_IPTUN_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET6))
+			goto get_failed;
 
-		if (iptuninfo[IFLA_IPTUN_REMOTE])
-			memcpy(&raddr, RTA_DATA(iptuninfo[IFLA_IPTUN_REMOTE]),
-			       sizeof(raddr));
+		rta = iptuninfo[IFLA_IPTUN_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET6))
+			goto get_failed;
 
 		if (iptuninfo[IFLA_IPTUN_TTL])
 			hop_limit = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);
@@ -185,17 +189,11 @@ get_failed:
 			else
 				invarg("Cannot guess tunnel mode.", *argv);
 		} else if (strcmp(*argv, "remote") == 0) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&raddr, addr.data, sizeof(raddr));
+			get_addr(&daddr, *argv, AF_INET6);
 		} else if (strcmp(*argv, "local") == 0) {
-			inet_prefix addr;
-
 			NEXT_ARG();
-			get_addr(&addr, *argv, AF_INET6);
-			memcpy(&laddr, addr.data, sizeof(laddr));
+			get_addr(&saddr, *argv, AF_INET6);
 		} else if (matches(*argv, "dev") == 0) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -322,8 +320,14 @@ get_failed:
 		return 0;
 	}
 
-	addattr_l(n, 1024, IFLA_IPTUN_LOCAL, &laddr, sizeof(laddr));
-	addattr_l(n, 1024, IFLA_IPTUN_REMOTE, &raddr, sizeof(raddr));
+	if (is_addrtype_inet(&saddr)) {
+		addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
+			  saddr.data, saddr.bytelen);
+	}
+	if (is_addrtype_inet(&daddr)) {
+		addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
+			  daddr.data, daddr.bytelen);
+	}
 	addattr8(n, 1024, IFLA_IPTUN_TTL, hop_limit);
 	addattr8(n, 1024, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
 	addattr32(n, 1024, IFLA_IPTUN_FLOWINFO, flowinfo);
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index bc1074e..acd9f45 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -90,16 +90,11 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
 	struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
 	int len;
-	__u32 laddr = 0;
-	__u32 raddr = 0;
+	inet_prefix saddr, daddr, ip6rdprefix, ip6rdrelayprefix;
 	__u8 pmtudisc = 1;
 	__u8 tos = 0;
 	__u16 iflags = 0;
 	__u8 ttl = 0;
-	struct in6_addr ip6rdprefix = {};
-	__u16 ip6rdprefixlen = 0;
-	__u32 ip6rdrelayprefix = 0;
-	__u16 ip6rdrelayprefixlen = 0;
 	__u8 proto = 0;
 	__u32 link = 0;
 	__u16 encaptype = 0;
@@ -109,7 +104,15 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 metadata = 0;
 	__u32 fwmark = 0;
 
+	inet_prefix_reset(&saddr);
+	inet_prefix_reset(&daddr);
+
+	inet_prefix_reset(&ip6rdprefix);
+	inet_prefix_reset(&ip6rdrelayprefix);
+
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		const struct rtattr *rta;
+
 		if (rtnl_talk(&rth, &req.n, &answer) < 0) {
 get_failed:
 			fprintf(stderr,
@@ -135,11 +138,27 @@ get_failed:
 		parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
 				    linkinfo[IFLA_INFO_DATA]);
 
-		if (iptuninfo[IFLA_IPTUN_LOCAL])
-			laddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_LOCAL]);
+		rta = iptuninfo[IFLA_IPTUN_LOCAL];
+		if (rta && get_addr_rta(&saddr, rta, AF_INET))
+			goto get_failed;
+
+		rta = iptuninfo[IFLA_IPTUN_REMOTE];
+		if (rta && get_addr_rta(&daddr, rta, AF_INET))
+			goto get_failed;
+
+		rta = iptuninfo[IFLA_IPTUN_6RD_PREFIX];
+		if (rta && get_addr_rta(&ip6rdprefix, rta, AF_INET6))
+			goto get_failed;
+
+		rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX];
+		if (rta && get_addr_rta(&ip6rdrelayprefix, rta, AF_INET))
+			goto get_failed;
+
+		rta = iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN];
+		ip6rdprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
 
-		if (iptuninfo[IFLA_IPTUN_REMOTE])
-			raddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_REMOTE]);
+		rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN];
+		ip6rdrelayprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
 
 		if (iptuninfo[IFLA_IPTUN_TTL])
 			ttl = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);
@@ -168,22 +187,7 @@ get_failed:
 			encapsport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_SPORT]);
 		if (iptuninfo[IFLA_IPTUN_ENCAP_DPORT])
 			encapdport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_DPORT]);
-		if (iptuninfo[IFLA_IPTUN_6RD_PREFIX])
-			memcpy(&ip6rdprefix,
-			       RTA_DATA(iptuninfo[IFLA_IPTUN_6RD_PREFIX]),
-			       sizeof(laddr));
-
-		if (iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN])
-			ip6rdprefixlen =
-				rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN]);
-
-		if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX])
-			ip6rdrelayprefix =
-				rta_getattr_u32(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX]);
-
-		if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN])
-			ip6rdrelayprefixlen =
-				rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
+
 		if (iptuninfo[IFLA_IPTUN_COLLECT_METADATA])
 			metadata = 1;
 
@@ -214,10 +218,10 @@ get_failed:
 				invarg("Cannot guess tunnel mode.", *argv);
 		} else if (strcmp(*argv, "remote") == 0) {
 			NEXT_ARG();
-			raddr = get_addr32(*argv);
+			get_addr(&daddr, *argv, AF_INET);
 		} else if (strcmp(*argv, "local") == 0) {
 			NEXT_ARG();
-			laddr = get_addr32(*argv);
+			get_addr(&saddr, *argv, AF_INET);
 		} else if (matches(*argv, "dev") == 0) {
 			NEXT_ARG();
 			link = ll_name_to_index(*argv);
@@ -289,29 +293,16 @@ get_failed:
 		} else if (strcmp(*argv, "external") == 0) {
 			metadata = 1;
 		} else if (strcmp(*argv, "6rd-prefix") == 0) {
-			inet_prefix prefix;
-
 			NEXT_ARG();
-			if (get_prefix(&prefix, *argv, AF_INET6))
+			if (get_prefix(&ip6rdprefix, *argv, AF_INET6))
 				invarg("invalid 6rd_prefix\n", *argv);
-			memcpy(&ip6rdprefix, prefix.data, 16);
-			ip6rdprefixlen = prefix.bitlen;
 		} else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
-			inet_prefix prefix;
-
 			NEXT_ARG();
-			if (get_prefix(&prefix, *argv, AF_INET))
+			if (get_prefix(&ip6rdrelayprefix, *argv, AF_INET))
 				invarg("invalid 6rd-relay_prefix\n", *argv);
-			memcpy(&ip6rdrelayprefix, prefix.data, 4);
-			ip6rdrelayprefixlen = prefix.bitlen;
 		} else if (strcmp(*argv, "6rd-reset") == 0) {
-			inet_prefix prefix;
-
-			get_prefix(&prefix, "2002::", AF_INET6);
-			memcpy(&ip6rdprefix, prefix.data, 16);
-			ip6rdprefixlen = 16;
-			ip6rdrelayprefix = 0;
-			ip6rdrelayprefixlen = 0;
+			get_prefix(&ip6rdprefix, "2002::/16", AF_INET6);
+			inet_prefix_reset(&ip6rdrelayprefix);
 		} else if (strcmp(*argv, "fwmark") == 0) {
 			NEXT_ARG();
 			if (get_u32(&fwmark, *argv, 0))
@@ -334,8 +325,14 @@ get_failed:
 		return 0;
 	}
 
-	addattr32(n, 1024, IFLA_IPTUN_LOCAL, laddr);
-	addattr32(n, 1024, IFLA_IPTUN_REMOTE, raddr);
+	if (is_addrtype_inet(&saddr)) {
+		addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
+			  saddr.data, saddr.bytelen);
+	}
+	if (is_addrtype_inet(&daddr)) {
+		addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
+			  daddr.data, daddr.bytelen);
+	}
 	addattr8(n, 1024, IFLA_IPTUN_PMTUDISC, pmtudisc);
 	addattr8(n, 1024, IFLA_IPTUN_TOS, tos);
 	addattr8(n, 1024, IFLA_IPTUN_TTL, ttl);
@@ -349,15 +346,17 @@ get_failed:
 
 	if (strcmp(lu->id, "sit") == 0) {
 		addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
-		if (ip6rdprefixlen) {
+		if (is_addrtype_inet(&ip6rdprefix)) {
 			addattr_l(n, 1024, IFLA_IPTUN_6RD_PREFIX,
-				  &ip6rdprefix, sizeof(ip6rdprefix));
+				  ip6rdprefix.data, ip6rdprefix.bytelen);
 			addattr16(n, 1024, IFLA_IPTUN_6RD_PREFIXLEN,
-				  ip6rdprefixlen);
+				  ip6rdprefix.bitlen);
+		}
+		if (is_addrtype_inet(&ip6rdrelayprefix)) {
 			addattr32(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIX,
-				  ip6rdrelayprefix);
+				  ip6rdrelayprefix.data[0]);
 			addattr16(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
-				  ip6rdrelayprefixlen);
+				  ip6rdrelayprefix.bitlen);
 		}
 	}
 
-- 
1.7.10.4

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

* Re: [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing
  2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
                   ` (3 preceding siblings ...)
  2018-02-12 20:17 ` [PATCH iproute2-next v3 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd " Serhey Popovych
@ 2018-02-14 17:03 ` David Ahern
  4 siblings, 0 replies; 6+ messages in thread
From: David Ahern @ 2018-02-14 17:03 UTC (permalink / raw)
  To: Serhey Popovych, netdev

On 2/12/18 1:17 PM, Serhey Popovych wrote:
> Use get_addr_rta() helper to unify address retriveal from netlink
> message when configuring tunnel and get_addr() to parse endpoint
> address into @inet_prefix.
> 
> This is next step towards ip and ipv6 tunnel module merge: endpoint
> address parsing code will differ only in @family constant being
> passed to get_addr_rta() and get_addr().

series applied to iproute2-next

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

end of thread, other threads:[~2018-02-14 17:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-12 20:17 [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
2018-02-12 20:17 ` [PATCH iproute2-next v3 1/4] utils: Introduce and use inet_prefix_reset() Serhey Popovych
2018-02-12 20:17 ` [PATCH iproute2-next v3 2/4] vti/vti6: Unify local/remote endpoint address parsing Serhey Popovych
2018-02-12 20:17 ` [PATCH iproute2-next v3 3/4] gre/gre6: " Serhey Popovych
2018-02-12 20:17 ` [PATCH iproute2-next v3 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd " Serhey Popovych
2018-02-14 17:03 ` [PATCH iproute2-next v3 0/4] ip/tunnel: Unify local/remote endpoint " David Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).