All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next v2 0/4] ip/tunnel: Unify local/remote endpoint address parsing
@ 2018-02-11 20:02 Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags() Serhey Popovych
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Serhey Popovych @ 2018-02-11 20:02 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.

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_flags()
  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] 8+ messages in thread

* [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags()
  2018-02-11 20:02 [PATCH iproute2-next v2 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
@ 2018-02-11 20:02 ` Serhey Popovych
  2018-02-11 23:48   ` Stephen Hemminger
  2018-02-12 20:08   ` David Ahern
  2018-02-11 20:02 ` [PATCH iproute2-next v2 2/4] vti/vti6: Unify local/remote endpoint address parsing Serhey Popovych
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 8+ messages in thread
From: Serhey Popovych @ 2018-02-11 20:02 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..ccbf353 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_flags(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..f90bca6 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_flags(&daddr);
 
 	while (argc > 0) {
 		if (!matches(*argv, "id") ||
diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 00875ba..02fdc66 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_flags(&saddr);
+	inet_prefix_reset_flags(&daddr);
 
 	while (argc > 0) {
 		if (!matches(*argv, "id") ||
-- 
1.7.10.4

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

* [PATCH iproute2-next v2 2/4] vti/vti6: Unify local/remote endpoint address parsing
  2018-02-11 20:02 [PATCH iproute2-next v2 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags() Serhey Popovych
@ 2018-02-11 20:02 ` Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 3/4] gre/gre6: " Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd " Serhey Popovych
  3 siblings, 0 replies; 8+ messages in thread
From: Serhey Popovych @ 2018-02-11 20:02 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..125fc20 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_flags(&saddr);
+	inet_prefix_reset_flags(&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..9f2c6ac 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_flags(&saddr);
+	inet_prefix_reset_flags(&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] 8+ messages in thread

* [PATCH iproute2-next v2 3/4] gre/gre6: Unify local/remote endpoint address parsing
  2018-02-11 20:02 [PATCH iproute2-next v2 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags() Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 2/4] vti/vti6: Unify local/remote endpoint address parsing Serhey Popovych
@ 2018-02-11 20:02 ` Serhey Popovych
  2018-02-11 20:02 ` [PATCH iproute2-next v2 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd " Serhey Popovych
  3 siblings, 0 replies; 8+ messages in thread
From: Serhey Popovych @ 2018-02-11 20:02 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..df7c12d 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_flags(&saddr);
+	inet_prefix_reset_flags(&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..46f396f 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_flags(&saddr);
+	inet_prefix_reset_flags(&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] 8+ messages in thread

* [PATCH iproute2-next v2 4/4] iptnl/ip6tnl: Unify local/remote endpoint and 6rd address parsing
  2018-02-11 20:02 [PATCH iproute2-next v2 0/4] ip/tunnel: Unify local/remote endpoint address parsing Serhey Popovych
                   ` (2 preceding siblings ...)
  2018-02-11 20:02 ` [PATCH iproute2-next v2 3/4] gre/gre6: " Serhey Popovych
@ 2018-02-11 20:02 ` Serhey Popovych
  3 siblings, 0 replies; 8+ messages in thread
From: Serhey Popovych @ 2018-02-11 20:02 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..1891947 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_flags(&saddr);
+	inet_prefix_reset_flags(&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..368d6cc 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_flags(&saddr);
+	inet_prefix_reset_flags(&daddr);
+
+	inet_prefix_reset_flags(&ip6rdprefix);
+	inet_prefix_reset_flags(&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_flags(&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] 8+ messages in thread

* Re: [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags()
  2018-02-11 20:02 ` [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags() Serhey Popovych
@ 2018-02-11 23:48   ` Stephen Hemminger
  2018-02-12  1:15     ` David Ahern
  2018-02-12 20:08   ` David Ahern
  1 sibling, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2018-02-11 23:48 UTC (permalink / raw)
  To: Serhey Popovych; +Cc: netdev

On Sun, 11 Feb 2018 22:02:30 +0200
Serhey Popovych <serhe.popovych@gmail.com> wrote:

> +static inline void inet_prefix_reset_flags(inet_prefix *p)
> +{
> +	p->flags = 0;
> +}

Just do it.

Wrapper adds nothing here.

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

* Re: [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags()
  2018-02-11 23:48   ` Stephen Hemminger
@ 2018-02-12  1:15     ` David Ahern
  0 siblings, 0 replies; 8+ messages in thread
From: David Ahern @ 2018-02-12  1:15 UTC (permalink / raw)
  To: Stephen Hemminger, Serhey Popovych; +Cc: netdev

On 2/11/18 4:48 PM, Stephen Hemminger wrote:
> On Sun, 11 Feb 2018 22:02:30 +0200
> Serhey Popovych <serhe.popovych@gmail.com> wrote:
> 
>> +static inline void inet_prefix_reset_flags(inet_prefix *p)
>> +{
>> +	p->flags = 0;
>> +}
> 
> Just do it.
> 
> Wrapper adds nothing here.
> 

I asked for a wrapper to flags b/c embedding 'p->flags = 0' into code
hides what it is doing - which is resetting the address type in
inet_prefix. If inet_prefix is hiding address family and address type
details from the main ip code, details of how it works should be opaque
to that code.

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

* Re: [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags()
  2018-02-11 20:02 ` [PATCH iproute2-next v2 1/4] utils: Introduce and use inet_prefix_reset_flags() Serhey Popovych
  2018-02-11 23:48   ` Stephen Hemminger
@ 2018-02-12 20:08   ` David Ahern
  1 sibling, 0 replies; 8+ messages in thread
From: David Ahern @ 2018-02-12 20:08 UTC (permalink / raw)
  To: Serhey Popovych, netdev

On 2/11/18 1:02 PM, Serhey Popovych wrote:
> 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..ccbf353 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_flags(inet_prefix *p)
> +{
> +	p->flags = 0;
> +}
> +

I think inet_prefix_reset is sufficient; flags is an implementation detail.

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

end of thread, other threads:[~2018-02-12 20:08 UTC | newest]

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

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.