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>] [day] [month] [year] [list]
Message-ID: <1451933211-17330-1-git-send-email-saurabh@cplanenetworks.com>
Date:	Mon, 4 Jan 2016 10:46:51 -0800
From:	Saurabh Mohan <saurabh@...anenetworks.com>
To:	<netdev@...r.kernel.org>, <stephen@...workplumber.org>,
	<davem@...emloft.net>, <pshelar@...ira.com>, <tgraf@...g.ch>
CC:	Saurabh Mohan <saurabh@...anenetworks.com>
Subject: [PATCH iproute2] Support outside netns for tunnels.


This patch enchances a tunnel interface, like gre, to have the tunnel
encap/decap be in the context of a network namespace that is different from 
the namespace of the tunnel interface.

>From userspace this feature may be configured using the new 'onetns' keyword:
ip netns exec custa ip link add dev tun1 type gre local 10.0.0.1 \
 remote 10.0.0.2 onetns outside 

In the above example the tunnel would be in the 'custa' namespace and the 
tunnel endpoints would be in the 'outside' namespace.

Also, proposing the use of netns name 'global' to specify the global namespace.

If this patch set is accepted then I will add support for other tunnels as 
well.

Signed-off-by: Saurabh Mohan <saurabh@...anenetworks.com>
---
 ip/iptunnel.c | 27 +++++++++++++++++++++++++++
 ip/link_gre.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 ip/link_vti.c | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)

diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index 65a4e6e..8165a38 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -27,6 +27,7 @@
 #include "utils.h"
 #include "ip_common.h"
 #include "tunnel.h"
+#include "namespace.h"
 
 static void usage(void) __attribute__((noreturn));
 
@@ -38,6 +39,7 @@ static void usage(void)
 	fprintf(stderr, "          [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n");
 	fprintf(stderr, "          [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
 	fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
+	fprintf(stderr, "          [ onetns NAME ]\n");
 	fprintf(stderr, "\n");
 	fprintf(stderr, "Where: NAME := STRING\n");
 	fprintf(stderr, "       ADDR := { IP_ADDRESS | any }\n");
@@ -172,6 +174,22 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
 					invarg("bad TOS value", *argv);
 				p->iph.tos |= uval;
 			}
+		} else if (strcmp(*argv, "onetns") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "global") == 0)
+				p->o_net.o_netns_flag |=
+					TUNNEL_ONETNS_FLAG_GLOBAL;
+			else {
+				p->o_net.o_netns_fd = netns_get_fd(*argv);
+				if (p->o_net.o_netns_fd < 0)
+					invarg("bad netns name %s\n", *argv);
+				else {
+					p->o_net.o_netns_flag |=
+						TUNNEL_ONETNS_FLAG_NETNS;
+					strncpy(p->o_net.netns, *argv,
+						sizeof(p->o_net.netns));
+				}
+			}
 		} else {
 			if (strcmp(*argv, "name") == 0)
 				NEXT_ARG();
@@ -374,6 +392,11 @@ static void print_tunnel(struct ip_tunnel_parm *p)
 			printf(" okey %u", ntohl(p->o_key));
 	}
 
+	if (p->o_net.o_netns_flag & TUNNEL_ONETNS_FLAG_GLOBAL)
+		printf(" onetns global ");
+	if (p->o_net.o_netns_flag & TUNNEL_ONETNS_FLAG_NETNS)
+		printf(" onetns %s ", p->o_net.netns);
+
 	if (p->i_flags & GRE_SEQ)
 		printf("%s  Drop packets out of sequence.", _SL_);
 	if (p->i_flags & GRE_CSUM)
@@ -401,6 +424,10 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
 		fprintf(stderr, "/proc/net/dev read error\n");
 		goto end;
 	}
+	if (p->o_net.o_netns_flag & TUNNEL_ONETNS_FLAG_GLOBAL)
+		printf(" onetns global ");
+	if (p->o_net.o_netns_flag & TUNNEL_ONETNS_FLAG_NETNS)
+		printf(" onetns %s ", p->o_net.netns);
 
 	while (fgets(buf, sizeof(buf), fp) != NULL) {
 		char name[IFNAMSIZ];
diff --git a/ip/link_gre.c b/ip/link_gre.c
index c85741f..4f51aa4 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -22,6 +22,7 @@
 #include "utils.h"
 #include "ip_common.h"
 #include "tunnel.h"
+#include "namespace.h"
 
 static void print_usage(FILE *f)
 {
@@ -32,6 +33,7 @@ static void print_usage(FILE *f)
 	fprintf(f, "          [ noencap ] [ encap { fou | gue | none } ]\n");
 	fprintf(f, "          [ encap-sport PORT ] [ encap-dport PORT ]\n");
 	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n");
+	fprintf(f, "          [ onetns NAME ]\n");
 	fprintf(f, "\n");
 	fprintf(f, "Where: NAME := STRING\n");
 	fprintf(f, "       ADDR := { IP_ADDRESS | any }\n");
@@ -75,6 +77,9 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u16 encapsport = 0;
 	__u16 encapdport = 0;
 	__u8 metadata = 0;
+	__u32 o_netns = 0;
+	__u8 o_netns_flag = 0;
+	char netns_name[NAME_MAX];
 
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
 		memset(&req, 0, sizeof(req));
@@ -152,6 +157,14 @@ get_failed:
 
 		if (greinfo[IFLA_GRE_COLLECT_METADATA])
 			metadata = 1;
+		if (greinfo[IFLA_GRE_ONETNS_FLAGS])
+			o_netns_flag = rta_getattr_u8(
+						greinfo[IFLA_GRE_ONETNS_FLAGS]);
+		if (greinfo[IFLA_GRE_ONETNS_FD])
+			o_netns = rta_getattr_u32(greinfo[IFLA_GRE_ONETNS_FD]);
+		if (greinfo[IFLA_GRE_ONETNS_NAME])
+			netns_name[0] = '\0';
+
 	}
 
 	while (argc > 0) {
@@ -297,6 +310,21 @@ get_failed:
 			encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM;
 		} else if (strcmp(*argv, "external") == 0) {
 			metadata = 1;
+		} else if (strcmp(*argv, "onetns") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "global") == 0)
+				o_netns_flag |= TUNNEL_ONETNS_FLAG_GLOBAL;
+			else {
+				o_netns = netns_get_fd(*argv);
+				if (o_netns < 0)
+					invarg("invalid onetns %s\n", *argv);
+				else {
+					o_netns_flag |=
+						TUNNEL_ONETNS_FLAG_NETNS;
+					strncpy(netns_name, *argv,
+						sizeof(netns_name));
+				}
+			}
 		} else
 			usage();
 		argc--; argv++;
@@ -333,6 +361,9 @@ get_failed:
 	addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport));
 	if (metadata)
 		addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0);
+	addattr8(n, 1024, IFLA_IPTUN_ONETNS_FLAGS, o_netns_flag);
+	addattr_l(n, 1024, IFLA_GRE_ONETNS_FD, &o_netns, 1);
+	addattrstrz(n, 1024, IFLA_GRE_ONETNS_NAME, netns_name);
 
 	return 0;
 }
@@ -345,6 +376,7 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 	const char *remote = "any";
 	unsigned iflags = 0;
 	unsigned oflags = 0;
+	__u8 o_netns_flag = 0;
 
 	if (!tb)
 		return;
@@ -466,6 +498,17 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 		else
 			fputs("noencap-remcsum ", f);
 	}
+	if (tb[IFLA_GRE_ONETNS_FLAGS]) {
+		o_netns_flag = rta_getattr_u8(tb[IFLA_GRE_ONETNS_FLAGS]);
+		if (o_netns_flag & TUNNEL_ONETNS_FLAG_GLOBAL)
+			fprintf(f, "onetns global ");
+	}
+	if ((o_netns_flag & TUNNEL_ONETNS_FLAG_NETNS) &&
+	    tb[IFLA_GRE_ONETNS_NAME]) {
+		const char *name = rta_getattr_str(tb[IFLA_GRE_ONETNS_NAME]);
+
+		fprintf(f, "onetns %s ", name);
+	}
 }
 
 static void gre_print_help(struct link_util *lu, int argc, char **argv,
diff --git a/ip/link_vti.c b/ip/link_vti.c
index f3fea33..7f6d4ae 100644
--- a/ip/link_vti.c
+++ b/ip/link_vti.c
@@ -30,6 +30,7 @@ static void print_usage(FILE *f)
 	fprintf(f, "          type { vti } [ remote ADDR ] [ local ADDR ]\n");
 	fprintf(f, "          [ [i|o]key KEY ]\n");
 	fprintf(f, "          [ dev PHYS_DEV ]\n");
+	fprintf(f, "          [ onetns NAME ]\n");
 	fprintf(f, "\n");
 	fprintf(f, "Where: NAME := STRING\n");
 	fprintf(f, "       ADDR := { IP_ADDRESS }\n");
@@ -61,6 +62,9 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
 	unsigned daddr = 0;
 	unsigned link = 0;
 	int len;
+	__u32 o_netns = 0;
+	__u8  o_netns_flag = 0;
+	char netns_name[NAME_MAX];
 
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
 		memset(&req, 0, sizeof(req));
@@ -110,6 +114,13 @@ get_failed:
 
 		if (vtiinfo[IFLA_VTI_LINK])
 			link = *(__u8 *)RTA_DATA(vtiinfo[IFLA_VTI_LINK]);
+		if (vtiinfo[IFLA_VTI_ONETNS_FLAGS])
+			o_netns_flag = rta_getattr_u8(
+					    vtiinfo[IFLA_VTI_ONETNS_FLAGS]);
+		if (vtiinfo[IFLA_VTI_ONETNS_FD])
+			o_netns = rta_getattr_u32(vtiinfo[IFLA_VTI_ONETNS_FD]);
+		if (vtiinfo[IFLA_VTI_ONETNS_NAME])
+			netns_name[0] = '\0';
 	}
 
 	while (argc > 0) {
@@ -181,6 +192,21 @@ get_failed:
 					*argv);
 				exit(-1);
 			}
+		} else if (strcmp(*argv, "onetns") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "global") == 0)
+				o_netns_flag |= TUNNEL_ONETNS_FLAG_GLOBAL;
+			else {
+				o_netns = netns_get_fd(*argv);
+				if (o_netns < 0)
+					invarg("invalid onetns %s\n", *argv);
+				else {
+					o_netns_flag |=
+						TUNNEL_ONETNS_FLAG_NETNS;
+					strncpy(netns_name, *argv,
+						sizeof(netns_name));
+				}
+			}
 		} else
 			usage();
 		argc--; argv++;
@@ -192,6 +218,9 @@ get_failed:
 	addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, 4);
 	if (link)
 		addattr32(n, 1024, IFLA_VTI_LINK, link);
+	addattr8(n, 1024, IFLA_IPTUN_ONETNS_FLAGS, o_netns_flag);
+	addattr_l(n, 1024, IFLA_VTI_ONETNS_FD, &o_netns, 1);
+	addattrstrz(n, 1024, IFLA_VTI_ONETNS_NAME, netns_name);
 
 	return 0;
 }
@@ -202,6 +231,7 @@ static void vti_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 	char s2[64];
 	const char *local = "any";
 	const char *remote = "any";
+	__u8 o_netns_flag = 0;
 
 	if (!tb)
 		return;
@@ -243,6 +273,17 @@ static void vti_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_VTI_OKEY]), s2, sizeof(s2));
 		fprintf(f, "okey %s ", s2);
 	}
+	if (tb[IFLA_VTI_ONETNS_FLAGS]) {
+		o_netns_flag = rta_getattr_u8(tb[IFLA_VTI_ONETNS_FLAGS]);
+		if (o_netns_flag & TUNNEL_ONETNS_FLAG_GLOBAL)
+			fprintf(f, "onetns global ");
+	}
+	if ((o_netns_flag & TUNNEL_ONETNS_FLAG_NETNS) &&
+	    tb[IFLA_VTI_ONETNS_NAME]) {
+		const char *name = rta_getattr_str(tb[IFLA_VTI_ONETNS_NAME]);
+
+		fprintf(f, "onetns %s ", name);
+	}
 }
 
 static void vti_print_help(struct link_util *lu, int argc, char **argv,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ