shithub: riscv

Download patch

ref: 10d74fec160b6a97c1c434dc35c48f176974fb55
parent: 435a0f18d5a5f372b4d5a30953e8d6bfd9cf6d17
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 27 10:55:55 EDT 2023

ip/ipconfig: remove non-existant ip addresses from /net/ndb, check link-local adress in ra6 daemon

when updating /net/ndb, drop entries for
non-existant ip addreses. this prevents
accumulating alot of non-temporary dhcp
ip addresses that have been dropped when
the interface was unbound.

for the ra6 daemon, always check that the
interface still has our link-local address.

reuse Ipifc's for ipv6. we have now two
Ipifc pointers:

Ipifc *allifcs;
Ipifc *myifc;

the allifcs is updated by findmyifc() and
putndb() and contains all the interfaces
on the stack, while myifc is for our interface.
both pointers are distinct and must be
refreshed separately with readipifc().

--- a/sys/src/cmd/ip/ipconfig/dhcpv6.c
+++ b/sys/src/cmd/ip/ipconfig/dhcpv6.c
@@ -221,6 +221,9 @@
 {
 	int fd;
 
+	if(!dodhcp || conf.duidlen <= 0)
+		return;
+
 	fd = openlisten();
 	if(transaction(fd, SOLICIT, 5000) < 0)
 		goto out;
--- a/sys/src/cmd/ip/ipconfig/ipconfig.h
+++ b/sys/src/cmd/ip/ipconfig/ipconfig.h
@@ -98,8 +98,10 @@
 	char	*ctl;
 };
 
+/* my interface on conf.mpoint stack */
+extern Ipifc*	myifc;
+
 extern Conf	conf;
-extern int	myifc;
 extern int	noconfig;
 extern int	dodhcp;
 
@@ -122,6 +124,7 @@
 void	adddefroute(uchar*, uchar*, uchar*, uchar*);
 void	removedefroute(uchar*, uchar*, uchar*, uchar*);
 
+int	myip(Ipifc*, uchar*);
 int	isether(void);
 long	jitter(void);
 void	catch(void*, char*);
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -406,7 +406,7 @@
 static int
 recvra6on(Ipifc *ifc)
 {
-	if(ifc == nil)
+	if(!myip(ifc, conf.lladdr))
 		return 0;
 	else if(ifc->sendra6 > 0)
 		return IsRouter;
@@ -484,6 +484,9 @@
 {
 	char *cfg;
 
+	myifc->sendra6 = cf->sendra;
+	myifc->recvra6 = cf->recvra;
+
 	cfg = smprint("ra6 sendra %d recvra %d maxraint %d minraint %d",
 		cf->sendra, cf->recvra, cf->maxraint, cf->minraint);
 	ewrite(cf->cfd, cfg);
@@ -779,20 +782,12 @@
 {
 	int fd, n, sendrscnt, recvracnt, sleepfor;
 	uchar buf[4096];
-	Ipifc *ifc;
 
-	ifc = readipifc(conf.mpoint, nil, myifc);
-	if(ifc == nil)
-		sysfatal("can't read ipifc: %r");
-
-	if(!findllip(conf.lladdr, ifc))
-		sysfatal("no link local address");
-
 	fd = dialicmpv6(v6allnodesL, ICMP6_RA);
 	if(fd < 0)
 		sysfatal("can't open icmp_ra connection: %r");
 
-	switch(rfork(RFPROC|RFMEM|RFFDG|RFNOWAIT|RFNOTEG)){
+	switch(rfork(RFPROC|RFFDG|RFNOWAIT|RFNOTEG)){
 	case -1:
 		sysfatal("can't fork: %r");
 	default:
@@ -809,7 +804,7 @@
 
 	recvracnt = 0;
 	sendrscnt = 0;
-	if(recvra6on(ifc) == IsHostRecv){
+	if(recvra6on(myifc) == IsHostRecv){
 		sendrs(fd, v6allroutersL);
 		sendrscnt = Maxv6rss;
 	}
@@ -827,8 +822,8 @@
 
 		sleepfor = Maxv6radelay;
 
-		ifc = readipifc(conf.mpoint, ifc, myifc);
-		if(ifc == nil) {
+		myifc = readipifc(conf.mpoint, myifc, myifc->index);
+		if(myifc == nil) {
 			warning("recvra6: can't read router params on %s, quitting on %s",
 				conf.mpoint, conf.dev);
 			if(recvracnt == 0)
@@ -836,7 +831,7 @@
 			exits(nil);
 		}
 
-		switch(recvra6on(ifc)){
+		switch(recvra6on(myifc)){
 		case IsHostRecv:
 			break;
 		default:
@@ -1057,7 +1052,6 @@
 {
 	int fd, n, sleepfor, nquitmsgs;
 	uchar buf[4096], dst[IPaddrlen];
-	Ipifc *ifc;
 	Ndb *db;
 
 	db = opendatabase();
@@ -1064,18 +1058,11 @@
 	if(db == nil)
 		warning("couldn't open ndb: %r");
 
-	ifc = readipifc(conf.mpoint, nil, myifc);
-	if(ifc == nil)
-		sysfatal("can't read ipifc: %r");
-
-	if(!findllip(conf.lladdr, ifc))
-		sysfatal("no link local address");
-
 	fd = dialicmpv6(v6allroutersL, ICMP6_RS);
 	if(fd < 0)
 		sysfatal("can't open icmp_rs connection: %r");
 
-	switch(rfork(RFPROC|RFMEM|RFFDG|RFNOWAIT|RFNOTEG)){
+	switch(rfork(RFPROC|RFFDG|RFNOWAIT|RFNOTEG)){
 	case -1:
 		sysfatal("can't fork: %r");
 	default:
@@ -1096,8 +1083,8 @@
 		n = read(fd, buf, sizeof buf);
 		sleepfor = alarm(0);
 
-		if(ifc->sendra6 > 0 && n > 0 && recvrs(buf, n, dst) > 0)
-			sendra(fd, dst, 1, ifc, db);
+		if(myifc->sendra6 > 0 && n > 0 && recvrs(buf, n, dst) > 0)
+			sendra(fd, dst, 1, myifc, db);
 
 		/* wait for alarm to expire */
 		if(sleepfor > 100)
@@ -1104,16 +1091,16 @@
 			continue;
 		sleepfor = Minv6interradelay;
 
-		ifc = readipifc(conf.mpoint, ifc, myifc);
-		if(ifc == nil) {
+		myifc = readipifc(conf.mpoint, myifc, myifc->index);
+		if(myifc == nil || !myip(myifc, conf.lladdr)) {
 			warning("sendra6: can't read router params on %s, quitting on %s",
 				conf.mpoint, conf.dev);
 			exits(nil);
 		}
-		if(ifc->sendra6 <= 0){
+		if(myifc->sendra6 <= 0){
 			if(nquitmsgs > 0) {
 				nquitmsgs--;
-				sendra(fd, v6allnodesL, 0, ifc, nil);
+				sendra(fd, v6allnodesL, 0, myifc, nil);
 				continue;
 			}
 			warning("sendra6: sendra off on %s, quitting on %s",
@@ -1121,8 +1108,8 @@
 			exits(nil);
 		}
 		db = opendatabase();
-		sendra(fd, v6allnodesL, 1, ifc, db);
-		sleepfor = randint(ifc->rp.minraint, ifc->rp.maxraint);
+		sendra(fd, v6allnodesL, 1, myifc, db);
+		sleepfor = randint(myifc->rp.minraint, myifc->rp.maxraint);
 	}
 }
 
@@ -1129,6 +1116,9 @@
 static void
 startra6(void)
 {
+	if(!findllip(conf.lladdr, myifc))
+		sysfatal("no link local address");
+
 	if(conf.recvra > 0)
 		recvra6();
 
--- a/sys/src/cmd/ip/ipconfig/main.c
+++ b/sys/src/cmd/ip/ipconfig/main.c
@@ -12,10 +12,9 @@
 #include <libsec.h> /* genrandom() */
 
 Conf	conf;
-int	myifc = -1;
+Ipifc*	myifc;
 int	beprimary = -1;
 int	noconfig;
-Ipifc	*ifc;
 Ctl	*firstctl, **ctll = &firstctl;
 
 int	debug;
@@ -272,20 +271,40 @@
 	return action;
 }
 
-static int
-findifc(char *net, char *dev)
+/* all interfaces on conf.mpoint stack */
+static Ipifc *allifcs;
+
+static Ipifc*
+findmyifc(void)
 {
 	Ipifc *nifc;
 
-	ifc = readipifc(net, ifc, -1);
-	for(nifc = ifc; nifc != nil; nifc = nifc->next){
-		if(strcmp(nifc->dev, dev) == 0)
-			return nifc->index;
+	allifcs = readipifc(conf.mpoint, allifcs, -1);
+	for(nifc = allifcs; nifc != nil; nifc = nifc->next){
+		if(strcmp(nifc->dev, conf.dev) == 0){
+			myifc = readipifc(conf.mpoint, myifc, nifc->index);
+			return myifc;
+		}
 	}
-	return -1;
+	return nil;
 }
 
 int
+myip(Ipifc *ifc, uchar *ip)
+{
+	Iplifc *lifc;
+
+	for(; ifc != nil; ifc = ifc->next) {
+		for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+			if(ipcmp(ip, lifc->ip) == 0)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+int
 isether(void)
 {
 	switch(parseverb(conf.type)){
@@ -429,8 +448,7 @@
 		beprimary = 0;
 
 	openiproute();
-	myifc = findifc(conf.mpoint, conf.dev);
-	if(myifc < 0) {
+	if(findmyifc() == nil) {
 		switch(action){
 		default:
 			if(noconfig)
@@ -438,7 +456,7 @@
 			/* bind new interface */
 			controldevice();
 			binddevice();
-			myifc = findifc(conf.mpoint, conf.dev);
+			findmyifc();
 		case Vunbind:
 			break;
 		case Vremove:
@@ -449,7 +467,7 @@
 			doremove();
 			exits(nil);
 		}
-		if(myifc < 0)
+		if(myifc == nil)
 			sysfatal("interface not found for: %s", conf.dev);
 	} else if(!noconfig) {
 		/* open old interface */
@@ -597,9 +615,9 @@
 {
 	char buf[256];
 
-	if(myifc >= 0){
+	if(myifc != nil){
 		/* open the old interface */
-		snprint(buf, sizeof buf, "%s/ipifc/%d/ctl", conf.mpoint, myifc);
+		snprint(buf, sizeof buf, "%s/ipifc/%d/ctl", conf.mpoint, myifc->index);
 		conf.cfd = open(buf, ORDWR);
 		if(conf.cfd < 0)
 			sysfatal("open %s: %r", buf);
@@ -753,7 +771,10 @@
 			p = seprint(p, e, "%s\n", ndboptions);
 	}
 
-	/* write preexisting entries not matching our ip */
+	/* for myip() */
+	allifcs = readipifc(conf.mpoint, allifcs, -1);
+
+	/* write valid pre-existing entries not matching our ip */
 	snprint(file, sizeof file, "%s/ndb", conf.mpoint);
 	db = ndbopen(file);
 	if(db != nil ){
@@ -762,8 +783,9 @@
 
 			if((nt = ndbfindattr(t, t, "ip")) == nil
 			|| parseip(ip, nt->val) == -1
-			|| ipcmp(ip, conf.laddr) != 0){
-				p = seprint(p, e, "\n");
+			|| ipcmp(ip, conf.laddr) != 0 && myip(allifcs, ip)){
+				if(p > buf)
+					p = seprint(p, e, "\n");
 				for(nt = t; nt != nil; nt = nt->entry)
 					p = seprint(p, e, "%s=%s%s", nt->attr, nt->val,
 						nt->entry==nil? "\n": nt->line!=nt->entry? "\n\t": " ");
@@ -1193,7 +1215,7 @@
 		sysfatal("no ip addresses found in ndb");
 
 	/* add link local address first, if not already done */
-	if(!findllip(conf.lladdr, ifc)){
+	if(!findllip(conf.lladdr, myifc)){
 		for(i = 0; i < n; i++){
 			ipmove(conf.laddr, dbips+i*IPaddrlen);
 			if(ISIPV6LINKLOCAL(conf.laddr)){