ref: 10d74fec160b6a97c1c434dc35c48f176974fb55
parent: 435a0f18d5a5f372b4d5a30953e8d6bfd9cf6d17
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 27 10:55:55 EDT 2023
ip/ipconfig: remove non-existant ip addresses from /net/ndb, check link-local adress in ra6 daemon when updating /net/ndb, drop entries for non-existant ip addreses. this prevents accumulating alot of non-temporary dhcp ip addresses that have been dropped when the interface was unbound. for the ra6 daemon, always check that the interface still has our link-local address. reuse Ipifc's for ipv6. we have now two Ipifc pointers: Ipifc *allifcs; Ipifc *myifc; the allifcs is updated by findmyifc() and putndb() and contains all the interfaces on the stack, while myifc is for our interface. both pointers are distinct and must be refreshed separately with readipifc().
--- a/sys/src/cmd/ip/ipconfig/dhcpv6.c
+++ b/sys/src/cmd/ip/ipconfig/dhcpv6.c
@@ -221,6 +221,9 @@
{
int fd;
+ if(!dodhcp || conf.duidlen <= 0)
+ return;
+
fd = openlisten();
if(transaction(fd, SOLICIT, 5000) < 0)
goto out;
--- a/sys/src/cmd/ip/ipconfig/ipconfig.h
+++ b/sys/src/cmd/ip/ipconfig/ipconfig.h
@@ -98,8 +98,10 @@
char *ctl;
};
+/* my interface on conf.mpoint stack */
+extern Ipifc* myifc;
+
extern Conf conf;
-extern int myifc;
extern int noconfig;
extern int dodhcp;
@@ -122,6 +124,7 @@
void adddefroute(uchar*, uchar*, uchar*, uchar*);
void removedefroute(uchar*, uchar*, uchar*, uchar*);
+int myip(Ipifc*, uchar*);
int isether(void);
long jitter(void);
void catch(void*, char*);
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -406,7 +406,7 @@
static int
recvra6on(Ipifc *ifc)
{
- if(ifc == nil)
+ if(!myip(ifc, conf.lladdr))
return 0;
else if(ifc->sendra6 > 0)
return IsRouter;
@@ -484,6 +484,9 @@
{
char *cfg;
+ myifc->sendra6 = cf->sendra;
+ myifc->recvra6 = cf->recvra;
+
cfg = smprint("ra6 sendra %d recvra %d maxraint %d minraint %d",
cf->sendra, cf->recvra, cf->maxraint, cf->minraint);
ewrite(cf->cfd, cfg);
@@ -779,20 +782,12 @@
{
int fd, n, sendrscnt, recvracnt, sleepfor;
uchar buf[4096];
- Ipifc *ifc;
- ifc = readipifc(conf.mpoint, nil, myifc);
- if(ifc == nil)
- sysfatal("can't read ipifc: %r");
-
- if(!findllip(conf.lladdr, ifc))
- sysfatal("no link local address");
-
fd = dialicmpv6(v6allnodesL, ICMP6_RA);
if(fd < 0)
sysfatal("can't open icmp_ra connection: %r");
- switch(rfork(RFPROC|RFMEM|RFFDG|RFNOWAIT|RFNOTEG)){
+ switch(rfork(RFPROC|RFFDG|RFNOWAIT|RFNOTEG)){
case -1:
sysfatal("can't fork: %r");
default:
@@ -809,7 +804,7 @@
recvracnt = 0;
sendrscnt = 0;
- if(recvra6on(ifc) == IsHostRecv){
+ if(recvra6on(myifc) == IsHostRecv){
sendrs(fd, v6allroutersL);
sendrscnt = Maxv6rss;
}
@@ -827,8 +822,8 @@
sleepfor = Maxv6radelay;
- ifc = readipifc(conf.mpoint, ifc, myifc);
- if(ifc == nil) {
+ myifc = readipifc(conf.mpoint, myifc, myifc->index);
+ if(myifc == nil) {
warning("recvra6: can't read router params on %s, quitting on %s",
conf.mpoint, conf.dev);
if(recvracnt == 0)
@@ -836,7 +831,7 @@
exits(nil);
}
- switch(recvra6on(ifc)){
+ switch(recvra6on(myifc)){
case IsHostRecv:
break;
default:
@@ -1057,7 +1052,6 @@
{
int fd, n, sleepfor, nquitmsgs;
uchar buf[4096], dst[IPaddrlen];
- Ipifc *ifc;
Ndb *db;
db = opendatabase();
@@ -1064,18 +1058,11 @@
if(db == nil)
warning("couldn't open ndb: %r");
- ifc = readipifc(conf.mpoint, nil, myifc);
- if(ifc == nil)
- sysfatal("can't read ipifc: %r");
-
- if(!findllip(conf.lladdr, ifc))
- sysfatal("no link local address");
-
fd = dialicmpv6(v6allroutersL, ICMP6_RS);
if(fd < 0)
sysfatal("can't open icmp_rs connection: %r");
- switch(rfork(RFPROC|RFMEM|RFFDG|RFNOWAIT|RFNOTEG)){
+ switch(rfork(RFPROC|RFFDG|RFNOWAIT|RFNOTEG)){
case -1:
sysfatal("can't fork: %r");
default:
@@ -1096,8 +1083,8 @@
n = read(fd, buf, sizeof buf);
sleepfor = alarm(0);
- if(ifc->sendra6 > 0 && n > 0 && recvrs(buf, n, dst) > 0)
- sendra(fd, dst, 1, ifc, db);
+ if(myifc->sendra6 > 0 && n > 0 && recvrs(buf, n, dst) > 0)
+ sendra(fd, dst, 1, myifc, db);
/* wait for alarm to expire */
if(sleepfor > 100)
@@ -1104,16 +1091,16 @@
continue;
sleepfor = Minv6interradelay;
- ifc = readipifc(conf.mpoint, ifc, myifc);
- if(ifc == nil) {
+ myifc = readipifc(conf.mpoint, myifc, myifc->index);
+ if(myifc == nil || !myip(myifc, conf.lladdr)) {
warning("sendra6: can't read router params on %s, quitting on %s",
conf.mpoint, conf.dev);
exits(nil);
}
- if(ifc->sendra6 <= 0){
+ if(myifc->sendra6 <= 0){
if(nquitmsgs > 0) {
nquitmsgs--;
- sendra(fd, v6allnodesL, 0, ifc, nil);
+ sendra(fd, v6allnodesL, 0, myifc, nil);
continue;
}
warning("sendra6: sendra off on %s, quitting on %s",
@@ -1121,8 +1108,8 @@
exits(nil);
}
db = opendatabase();
- sendra(fd, v6allnodesL, 1, ifc, db);
- sleepfor = randint(ifc->rp.minraint, ifc->rp.maxraint);
+ sendra(fd, v6allnodesL, 1, myifc, db);
+ sleepfor = randint(myifc->rp.minraint, myifc->rp.maxraint);
}
}
@@ -1129,6 +1116,9 @@
static void
startra6(void)
{
+ if(!findllip(conf.lladdr, myifc))
+ sysfatal("no link local address");
+
if(conf.recvra > 0)
recvra6();
--- a/sys/src/cmd/ip/ipconfig/main.c
+++ b/sys/src/cmd/ip/ipconfig/main.c
@@ -12,10 +12,9 @@
#include <libsec.h> /* genrandom() */
Conf conf;
-int myifc = -1;
+Ipifc* myifc;
int beprimary = -1;
int noconfig;
-Ipifc *ifc;
Ctl *firstctl, **ctll = &firstctl;
int debug;
@@ -272,20 +271,40 @@
return action;
}
-static int
-findifc(char *net, char *dev)
+/* all interfaces on conf.mpoint stack */
+static Ipifc *allifcs;
+
+static Ipifc*
+findmyifc(void)
{
Ipifc *nifc;
- ifc = readipifc(net, ifc, -1);
- for(nifc = ifc; nifc != nil; nifc = nifc->next){
- if(strcmp(nifc->dev, dev) == 0)
- return nifc->index;
+ allifcs = readipifc(conf.mpoint, allifcs, -1);
+ for(nifc = allifcs; nifc != nil; nifc = nifc->next){
+ if(strcmp(nifc->dev, conf.dev) == 0){
+ myifc = readipifc(conf.mpoint, myifc, nifc->index);
+ return myifc;
+ }
}
- return -1;
+ return nil;
}
int
+myip(Ipifc *ifc, uchar *ip)
+{
+ Iplifc *lifc;
+
+ for(; ifc != nil; ifc = ifc->next) {
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+ if(ipcmp(ip, lifc->ip) == 0)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
isether(void)
{
switch(parseverb(conf.type)){
@@ -429,8 +448,7 @@
beprimary = 0;
openiproute();
- myifc = findifc(conf.mpoint, conf.dev);
- if(myifc < 0) {
+ if(findmyifc() == nil) {
switch(action){
default:
if(noconfig)
@@ -438,7 +456,7 @@
/* bind new interface */
controldevice();
binddevice();
- myifc = findifc(conf.mpoint, conf.dev);
+ findmyifc();
case Vunbind:
break;
case Vremove:
@@ -449,7 +467,7 @@
doremove();
exits(nil);
}
- if(myifc < 0)
+ if(myifc == nil)
sysfatal("interface not found for: %s", conf.dev);
} else if(!noconfig) {
/* open old interface */
@@ -597,9 +615,9 @@
{
char buf[256];
- if(myifc >= 0){
+ if(myifc != nil){
/* open the old interface */
- snprint(buf, sizeof buf, "%s/ipifc/%d/ctl", conf.mpoint, myifc);
+ snprint(buf, sizeof buf, "%s/ipifc/%d/ctl", conf.mpoint, myifc->index);
conf.cfd = open(buf, ORDWR);
if(conf.cfd < 0)
sysfatal("open %s: %r", buf);
@@ -753,7 +771,10 @@
p = seprint(p, e, "%s\n", ndboptions);
}
- /* write preexisting entries not matching our ip */
+ /* for myip() */
+ allifcs = readipifc(conf.mpoint, allifcs, -1);
+
+ /* write valid pre-existing entries not matching our ip */
snprint(file, sizeof file, "%s/ndb", conf.mpoint);
db = ndbopen(file);
if(db != nil ){
@@ -762,8 +783,9 @@
if((nt = ndbfindattr(t, t, "ip")) == nil
|| parseip(ip, nt->val) == -1
- || ipcmp(ip, conf.laddr) != 0){
- p = seprint(p, e, "\n");
+ || ipcmp(ip, conf.laddr) != 0 && myip(allifcs, ip)){
+ if(p > buf)
+ p = seprint(p, e, "\n");
for(nt = t; nt != nil; nt = nt->entry)
p = seprint(p, e, "%s=%s%s", nt->attr, nt->val,
nt->entry==nil? "\n": nt->line!=nt->entry? "\n\t": " ");
@@ -1193,7 +1215,7 @@
sysfatal("no ip addresses found in ndb");
/* add link local address first, if not already done */
- if(!findllip(conf.lladdr, ifc)){
+ if(!findllip(conf.lladdr, myifc)){
for(i = 0; i < n; i++){
ipmove(conf.laddr, dbips+i*IPaddrlen);
if(ISIPV6LINKLOCAL(conf.laddr)){