shithub: riscv

Download patch

ref: c8507f428fc7f99da40fc59024742291e42136a7
parent: 6e4a1fda8c6105bc18aa7c26ff1fd28e18fec986
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Mar 13 13:29:16 EDT 2022

ipconfig(8): add -t flag to enable source address translation

--- a/sys/man/8/ipconfig
+++ b/sys/man/8/ipconfig
@@ -5,7 +5,7 @@
 .in +0.25i
 .ti -0.25i
 .B ip/ipconfig
-.RB [ -6DGNOPdnpruX ]
+.RB [ -6DGNOPdnprtuX ]
 .RB [ -b
 .IR baud ]
 .RB [ -c
@@ -222,6 +222,10 @@
 This option directs
 .I ipconfig
 instead to fork a background process that keeps trying forever.
+.TP
+.B t
+enable source address translation on the interface and default route.
+(only usefull for IPv4).
 .TP
 .B u
 disable IPv6 duplicate discovery detection,
--- a/sys/src/cmd/ip/ipconfig/ipconfig.h
+++ b/sys/src/cmd/ip/ipconfig/ipconfig.h
@@ -116,6 +116,7 @@
 int	ip4cfg(void);
 void	ipunconfig(void);
 
+void	setroutetag(char*);
 void	adddefroute(uchar*, uchar*, uchar*, uchar*);
 void	removedefroute(uchar*, uchar*, uchar*, uchar*);
 
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -354,8 +354,8 @@
 int
 ip6cfg(void)
 {
-	int tentative, n;
 	char buf[256];
+	int tentative, n;
 
 	if(!validip(conf.laddr) || isv4(conf.laddr))
 		return -1;
@@ -372,12 +372,12 @@
 	if(!validip(conf.mask))
 		ipmove(conf.mask, defmask(conf.laddr));
 	n += snprint(buf+n, sizeof buf-n, " %M", conf.mask);
-	if(validip(conf.raddr)){
-		n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
-		if(conf.mtu != 0)
-			n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
-	}
+	if(!validip(conf.raddr) || isv4(conf.raddr))
+		maskip(conf.laddr, conf.mask, conf.raddr);
+	n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
+	n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
 
+	DEBUG("ip6cfg: %.*s", n, buf);
 	if(write(conf.cfd, buf, n) < 0){
 		warning("write(%s): %r", buf);
 		return -1;
@@ -1134,8 +1134,7 @@
 void
 doipv6(int what)
 {
-	fprint(conf.rfd, "tag ra6");
-
+	setroutetag("ra6");
 	switch (what) {
 	default:
 		sysfatal("unknown IPv6 verb");
--- a/sys/src/cmd/ip/ipconfig/main.c
+++ b/sys/src/cmd/ip/ipconfig/main.c
@@ -24,6 +24,7 @@
 int	plan9 = 1;
 int	Oflag;
 int	rflag;
+int	tflag;
 
 int	dodhcp;
 int	nodhcpwatch;
@@ -53,7 +54,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-6dDGnNOpPruX][-b baud][-c ctl]* [-g gw]"
+	fprint(2, "usage: %s [-6dDGnNOpPrtuX][-b baud][-c ctl]* [-g gw]"
 		"[-h host][-m mtu]\n"
 		"\t[-f dbfile][-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask "
 		"[raddr [fs [auth]]]]]\n", argv0);
@@ -383,6 +384,9 @@
 	case 'r':
 		rflag = 1;
 		break;
+	case 't':
+		tflag = 1;
+		break;
 	case 'u':		/* IPv6: duplicate neighbour disc. off */
 		dupl_disc = 0;
 		break;
@@ -462,7 +466,7 @@
 
 	/* run dhcp if we need something */
 	if(dodhcp){
-		fprint(conf.rfd, "tag dhcp");
+		setroutetag("dhcp");
 		dhcpquery(!noconfig, Sselecting);
 	}
 
@@ -587,12 +591,14 @@
 		ipmove(conf.mask, defmask(conf.laddr));
 	n += snprint(buf+n, sizeof buf-n, " %M", conf.mask);
 
-	if(validip(conf.raddr)){
-		n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
-		if(conf.mtu != 0)
-			n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
-	}
+	if(!validip(conf.raddr) || !isv4(conf.raddr))
+		maskip(conf.laddr, conf.mask, conf.raddr);
+	n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
+	n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
+	if(tflag)
+		n += snprint(buf+n, sizeof buf-n, " trans");
 
+	DEBUG("ip4cfg: %.*s", n, buf);
 	if(write(conf.cfd, buf, n) < 0){
 		warning("write(%s): %r", buf);
 		return -1;
@@ -602,6 +608,9 @@
 	&& ipcmp(conf.gaddr, conf.laddr) != 0)
 		adddefroute(conf.gaddr, conf.laddr, conf.laddr, conf.mask);
 
+	if(tflag)
+		fprint(conf.cfd, "iprouting 1");
+
 	return 0;
 }
 
@@ -726,6 +735,15 @@
 	close(fd);
 }
 
+static char *routetag = "none";
+
+void
+setroutetag(char *tag)
+{
+	routetag = tag;
+	fprint(conf.rfd, "tag %s", routetag);
+}
+
 static int
 issrcspec(uchar *src, uchar *smask)
 {
@@ -733,18 +751,22 @@
 }
 
 static void
-routectl(char *cmd, uchar *dst, uchar *mask, uchar *gate, uchar *ia, uchar *src, uchar *smask)
+routectl(char *cmd, uchar *dst, uchar *mask, uchar *gate, char *flags, uchar *ia, uchar *src, uchar *smask)
 {
 	char *ctl;
 
-	if(issrcspec(src, smask))
-		ctl = "%s %I %M %I %I %I %M";
-	else
-		ctl = "%s %I %M %I %I";
-	DEBUG(ctl, cmd, dst, mask, gate, ia, src, smask);
-	if(conf.rfd < 0)
+	if(*flags == '\0'){
+		if(!issrcspec(src, smask))
+			ctl = "%s %I %M %I %I";
+		else
+			ctl = "%s %I %M %I %I %I %M";
+		DEBUG(ctl, cmd, dst, mask, gate, ia, src, smask);
+		fprint(conf.rfd, ctl, cmd, dst, mask, gate, ia, src, smask);
 		return;
-	fprint(conf.rfd, ctl, cmd, dst, mask, gate, ia, src, smask);
+	}
+	ctl = "%s %I %M %I %s %s %I %I %M";
+	DEBUG(ctl, cmd, dst, mask, gate, flags, routetag, ia, src, smask);
+	fprint(conf.rfd, ctl, cmd, dst, mask, gate, flags, routetag, ia, src, smask);
 }
 
 static void
@@ -765,11 +787,18 @@
 		if(smask == nil)
 			smask = IPnoaddr;
 	}
-	routectl(cmd, dst, mask, gaddr, ia, src, smask);
 
-	/* also add a source specific route */
-	if(ipcmp(src, IPnoaddr) != 0 && ipcmp(src, v4prefix) != 0)
-		routectl(cmd, dst, mask, gaddr, ia, src, IPallbits);
+	if(tflag && isv4(gaddr)){
+		/* add route for everyone with source translation */
+		routectl(cmd, dst, mask, gaddr, "4t", ia, dst, mask);
+	} else {
+		/* add route for subnet */
+		routectl(cmd, dst, mask, gaddr, "", ia, src, smask);
+	}
+
+	/* add source specific route for us */
+	if(validip(src))
+		routectl(cmd, dst, mask, gaddr, "", ia, src, IPallbits);
 }
 
 void
@@ -1016,6 +1045,7 @@
 
 	ipmove(conf.mask, defmask(conf.laddr));
 
+	memset(conf.raddr, 0, sizeof(conf.raddr));
 	memset(conf.gaddr, 0, sizeof(conf.gaddr));
 	memset(conf.dns, 0, sizeof(conf.dns));
 	memset(conf.ntp, 0, sizeof(conf.ntp));