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
--
⑨