add code to dhcpd to allow the dhcp server to be multihomed on the same interface and still properly match served ip addresses. Reference: /n/atom/patch/applied2013/dhcpmultihome Date: Thu Jun 20 01:01:25 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/ip/dhcpd/ndb.c Thu Jun 20 01:00:09 2013 +++ /sys/src/cmd/ip/dhcpd/ndb.c Thu Jun 20 01:00:09 2013 @@ -20,8 +20,8 @@ for(ifc = ipifcs; ifc; ifc = ifc->next){ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ - if(lifc->net[0] == 0) - continue; +// if(lifc->net[0] == 0) +// continue; maskip(ip, lifc->mask, x); if(memcmp(x, lifc->net, IPaddrlen) == 0) return lifc; @@ -60,6 +60,28 @@ parseipmask(mask, ip); } +static int +checkdb(void) +{ + long t; + static long ndbtime; + + t = time(0); + if(db == nil){ + db = ndbopen(ndbfile); + ndbtime = t; + } + else if(t - ndbtime > 30){ + db = ndbreopendb(db); + ndbtime = t; + } + if(db == nil){ + warning(1, "can't open db"); + return -1; + } + return 0; +} + /* * do an ipinfo with defaults */ @@ -70,12 +92,8 @@ Ndbtuple *t, *nt; char *attrs[32], **p; - if(db == 0) - db = ndbopen(ndbfile); - if(db == 0){ - warning(1, "can't open db"); + if(checkdb() == -1) return -1; - } p = attrs; *p++ = "ip"; @@ -170,6 +188,45 @@ return 0; } +static int +mksamenet(Info *ii, Info *gii) +{ + uchar x[IPaddrlen]; + Ipifc *ifc; + Iplifc *lifc, *nexus; + + maskip(ii->ipaddr, gii->ipmask, x); + if(ipcmp(x, gii->ipnet) == 0) + return 0; + + /* find ii's interface */ + for(ifc = ipifcs;; ifc = ifc->next){ + if(ifc == nil) + return -1; + for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ + maskip(ii->ipaddr, lifc->mask, x); + if(ipcmp(x, lifc->net) == 0) + goto found; + } + } +found: + nexus = lifc; + /* check to see that gii appears on same interface */ + for(lifc = ifc->lifc;; lifc = lifc->next){ + if(lifc == nil) + return -1; + if(ipcmp(lifc->net, gii->ipnet) == 0) + break; + } + + /* fixup incorrect gii information */ + if(lookupip(nexus->ip, gii, 1) < 0) + return -1; + syslog(0, blog, "nexus %I %I is %s:%I", + ii->ipaddr, gii->ipaddr, ifc->dev, nexus->net); + return 0; +} + static uchar zeroes[6]; /* @@ -185,12 +242,8 @@ char *hwval, hwbuf[33]; uchar ciaddr[IPaddrlen]; - if(db == 0) - db = ndbopen(ndbfile); - if(db == 0){ - warning(1, "can't open db"); + if(checkdb() == -1) return -1; - } memset(iip, 0, sizeof(*iip)); @@ -245,7 +298,7 @@ parseip(ciaddr, nt->val); if(lookupip(ciaddr, iip, 0) < 0) continue; - if(samenet(riip->ipaddr, iip)){ + if(mksamenet(iip, riip) == 0){ ndbfree(t); return 0; }