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);
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*);

View file

@ -587,7 +587,7 @@ static int
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 @@ recvrahost(uchar buf[], int pktlen, ulong now)
/* 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 @@ recvrahost(uchar buf[], int pktlen, ulong now)
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;
}

View file

@ -556,8 +556,8 @@ doadd(void)
}
/* leave everything we've learned somewhere other procs can find it */
putndb(1);
refresh();
if(putndb(1))
refresh();
}
static void
@ -578,8 +578,8 @@ dodel(void)
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 @@ putnames(char *p, char *e, char *attr, char *s)
}
/* 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 @@ putndb(int doadd)
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 @@ putndb(int doadd)
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 @@ putndb(int doadd)
}
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