shithub: front

Download patch

ref: 4730816fa4e220833c4481aeb1bd3d7443c5191b
parent: 511cd4dc31b14ba392858a523bb3a4cbf37044e8
author: Arne <cgnarne@netcologne.de>
date: Sat Jan 11 10:03:56 EST 2025

ip/ipconfig: only write out /net/ndb when something changed

keep track of changes by calculating a hash in putndb() and only
update /net/ndb when something changed. use this to also only call refresh()
after changes and to garbage collect stale ipv6 networks after we receive
router advertisements.

--- a/sys/src/cmd/ip/ipconfig/ipconfig.h
+++ b/sys/src/cmd/ip/ipconfig/ipconfig.h
@@ -141,7 +141,7 @@
 int	gnames(char*, int, uchar*, int);
 Ndb*	opendatabase(void);
 void	ndb2conf(Ndb *db, uchar *ip);
-void	putndb(int);
+int	putndb(int);
 void	refresh(void);
 ulong	randint(ulong low, ulong hi);
 int	validip(uchar*);
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -587,7 +587,7 @@
 recvrahost(uchar buf[], int pktlen, ulong now)
 {
 	char dnsdomain[sizeof(conf.dnsdomain)];
-	int m, n, optype, seen;
+	int m, n, optype, seen, needrefresh;
 	Lladdropt *llao;
 	Mtuopt *mtuo;
 	Prefixopt *prfo;
@@ -705,12 +705,14 @@
 
 	/* remove expired prefixes */
 	issuedel6(&conf);
+	ipmove(conf.laddr, IPnoaddr);
 
-	/* managed netork: prefixes are acquired with dhcpv6 */
+	/* managed network: prefixes are acquired with dhcpv6 */
 	if(dodhcp && conf.mflag)
 		return 0;
 
 	/* process new prefixes */
+	needrefresh = 0;
 	m = sizeof *ra;
 	while(pktlen - m >= 8) {
 		n = m;
@@ -819,10 +821,10 @@
 		if(validip(conf.gaddr))
 			adddefroute(conf.gaddr, conf.lladdr, conf.laddr, conf.raddr, conf.mask);
 
-		putndb(1);
-		refresh();
+		needrefresh |= 1<<(putndb(1) != 0);
 	}
-
+	if(needrefresh > 1 || (needrefresh == 0 && putndb(0)))
+		refresh();
 	return 0;
 }
 
--- a/sys/src/cmd/ip/ipconfig/main.c
+++ b/sys/src/cmd/ip/ipconfig/main.c
@@ -556,8 +556,8 @@
 	}
 
 	/* leave everything we've learned somewhere other procs can find it */
-	putndb(1);
-	refresh();
+	if(putndb(1))
+		refresh();
 }
 
 static void
@@ -578,8 +578,8 @@
 		warning("can't delete %I %M: %r", conf.laddr, conf.mask);
 
 	/* remove ndb entries matching our ip address */
-	putndb(0);
-	refresh();
+	if(putndb(0))
+		refresh();
 }
 
 static void
@@ -749,7 +749,7 @@
 }
 
 /* make an ndb entry and put it into /net/ndb for the servers to see */
-void
+int
 putndb(int doadd)
 {
 	static char buf[16*1024];
@@ -757,9 +757,11 @@
 	Ndbtuple *t, *nt;
 	Ndb *db;
 	int fd;
+	static uchar csum[SHA1dlen];
+	uchar newcsum[SHA1dlen];
 
 	if(beprimary == 0 || noconfig)
-		return;
+		return 0;
 
 	p = buf;
 	e = buf + sizeof buf;
@@ -811,7 +813,8 @@
 			if(nt != nil && (ipnet == nil || strcmp(nt->val, ipnet) != 0)
 			|| nt == nil && ((nt = ndbfindattr(t, t, "ip")) == nil
 				|| parseip(ip, nt->val) == -1
-				|| ipcmp(ip, conf.laddr) != 0 && myip(allifcs, ip))){
+				|| (!doadd || !validip(conf.laddr) || ipcmp(ip, conf.laddr) != 0) 
+					 && myip(allifcs, ip))){
 				if(p > buf)
 					p = seprint(p, e, "\n");
 				for(nt = t; nt != nil; nt = nt->entry)
@@ -822,10 +825,18 @@
 		}
 		ndbclose(db);
 	}
+
+	/* only write if something has changed since last time */
+	sha1((uchar *)buf, p-buf, newcsum, nil);
+	if(memcmp(csum, newcsum, SHA1dlen) == 0)
+		return 0;
+	memcpy(csum, newcsum, SHA1dlen);
+
 	if((fd = open(file, OWRITE|OTRUNC)) < 0)
-		return;
+		return 0;
 	write(fd, buf, p-buf);
 	close(fd);
+	return 1;
 }
 
 static int
--