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.
This commit is contained in:
Arne 2025-01-11 15:03:56 +00:00
parent 511cd4dc31
commit 4730816fa4
3 changed files with 27 additions and 14 deletions

View file

@ -141,7 +141,7 @@ int pnames(uchar*, int, char*);
int gnames(char*, int, uchar*, int); int gnames(char*, int, uchar*, int);
Ndb* opendatabase(void); Ndb* opendatabase(void);
void ndb2conf(Ndb *db, uchar *ip); void ndb2conf(Ndb *db, uchar *ip);
void putndb(int); int putndb(int);
void refresh(void); void refresh(void);
ulong randint(ulong low, ulong hi); ulong randint(ulong low, ulong hi);
int validip(uchar*); int validip(uchar*);

View file

@ -587,7 +587,7 @@ static int
recvrahost(uchar buf[], int pktlen, ulong now) recvrahost(uchar buf[], int pktlen, ulong now)
{ {
char dnsdomain[sizeof(conf.dnsdomain)]; char dnsdomain[sizeof(conf.dnsdomain)];
int m, n, optype, seen; int m, n, optype, seen, needrefresh;
Lladdropt *llao; Lladdropt *llao;
Mtuopt *mtuo; Mtuopt *mtuo;
Prefixopt *prfo; Prefixopt *prfo;
@ -705,12 +705,14 @@ recvrahost(uchar buf[], int pktlen, ulong now)
/* remove expired prefixes */ /* remove expired prefixes */
issuedel6(&conf); issuedel6(&conf);
ipmove(conf.laddr, IPnoaddr);
/* managed netork: prefixes are acquired with dhcpv6 */ /* managed network: prefixes are acquired with dhcpv6 */
if(dodhcp && conf.mflag) if(dodhcp && conf.mflag)
return 0; return 0;
/* process new prefixes */ /* process new prefixes */
needrefresh = 0;
m = sizeof *ra; m = sizeof *ra;
while(pktlen - m >= 8) { while(pktlen - m >= 8) {
n = m; n = m;
@ -819,10 +821,10 @@ recvrahost(uchar buf[], int pktlen, ulong now)
if(validip(conf.gaddr)) if(validip(conf.gaddr))
adddefroute(conf.gaddr, conf.lladdr, conf.laddr, conf.raddr, conf.mask); adddefroute(conf.gaddr, conf.lladdr, conf.laddr, conf.raddr, conf.mask);
putndb(1); needrefresh |= 1<<(putndb(1) != 0);
refresh();
} }
if(needrefresh > 1 || (needrefresh == 0 && putndb(0)))
refresh();
return 0; return 0;
} }

View file

@ -556,8 +556,8 @@ doadd(void)
} }
/* leave everything we've learned somewhere other procs can find it */ /* leave everything we've learned somewhere other procs can find it */
putndb(1); if(putndb(1))
refresh(); refresh();
} }
static void static void
@ -578,8 +578,8 @@ dodel(void)
warning("can't delete %I %M: %r", conf.laddr, conf.mask); warning("can't delete %I %M: %r", conf.laddr, conf.mask);
/* remove ndb entries matching our ip address */ /* remove ndb entries matching our ip address */
putndb(0); if(putndb(0))
refresh(); refresh();
} }
static void static void
@ -749,7 +749,7 @@ putnames(char *p, char *e, char *attr, char *s)
} }
/* make an ndb entry and put it into /net/ndb for the servers to see */ /* make an ndb entry and put it into /net/ndb for the servers to see */
void int
putndb(int doadd) putndb(int doadd)
{ {
static char buf[16*1024]; static char buf[16*1024];
@ -757,9 +757,11 @@ putndb(int doadd)
Ndbtuple *t, *nt; Ndbtuple *t, *nt;
Ndb *db; Ndb *db;
int fd; int fd;
static uchar csum[SHA1dlen];
uchar newcsum[SHA1dlen];
if(beprimary == 0 || noconfig) if(beprimary == 0 || noconfig)
return; return 0;
p = buf; p = buf;
e = buf + sizeof buf; e = buf + sizeof buf;
@ -811,7 +813,8 @@ putndb(int doadd)
if(nt != nil && (ipnet == nil || strcmp(nt->val, ipnet) != 0) if(nt != nil && (ipnet == nil || strcmp(nt->val, ipnet) != 0)
|| nt == nil && ((nt = ndbfindattr(t, t, "ip")) == nil || nt == nil && ((nt = ndbfindattr(t, t, "ip")) == nil
|| parseip(ip, nt->val) == -1 || 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) if(p > buf)
p = seprint(p, e, "\n"); p = seprint(p, e, "\n");
for(nt = t; nt != nil; nt = nt->entry) for(nt = t; nt != nil; nt = nt->entry)
@ -822,10 +825,18 @@ putndb(int doadd)
} }
ndbclose(db); 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) if((fd = open(file, OWRITE|OTRUNC)) < 0)
return; return 0;
write(fd, buf, p-buf); write(fd, buf, p-buf);
close(fd); close(fd);
return 1;
} }
static int static int