lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1518199563-16182-3-git-send-email-serhe.popovych@gmail.com>
Date:   Fri,  9 Feb 2018 20:06:02 +0200
From:   Serhey Popovych <serhe.popovych@...il.com>
To:     netdev@...r.kernel.org
Subject: [PATCH iproute2-next 2/3] gre/gre6: Unify local/remote endpoint address parsing

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@...il.com>
---
 ip/link_gre.c  |   56 +++++++++++++++++++++++++++++++++-----------------------
 ip/link_gre6.c |   37 +++++++++++++++++++------------------
 2 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/ip/link_gre.c b/ip/link_gre.c
index e3e5323..4f81696 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,11 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 erspan_dir = 0;
 	__u16 erspan_hwid = 0;
 
+	saddr.flags = daddr.flags = 0;
+
 	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 +133,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 +153,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 +237,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 +348,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 +373,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..5e68fff 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,11 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 erspan_dir = 0;
 	__u16 erspan_hwid = 0;
 
+	saddr.flags = daddr.flags = 0;
+
 	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 +144,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 +164,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 +241,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 +397,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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ