diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-16 22:16:12 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-16 22:16:12 +0000 |
commit | c45766fb054e3c82fe7be6cd5da2e6ff58e534e3 (patch) | |
tree | 6100eecedb57d1b1dedaa0a899f974bbca49ecb9 /sys/src/9/ip/ipifc.c | |
parent | d4ce962fe33f3eca8da0b4ab2b5a81cc5359b71f (diff) |
devip: address some ipv6 issues on pkt interface
relax the maclen check as v6 neighbour disicovery might
give bigger buffers as the medium uses for the mac
address size, as the packet does not contain exact byte
count but rounds all the options to multiples of 8.
drop neighbour discovery packets coming from interfaces
with zero-length maclen.
when dialing icmpv6 protocol with link-local address
for the local ip address, filter any packets to it that
come from a different interface. otherwise ipconfig
would see router advertisements from other interfaces.
fix the locking for ipifc ctl messages: properly
acquire the wlock and check that the interface is still
bound for every ctl messages touching the interface.
make add6 ipifc ctl message work for media with
zero-length maclen by using the interface identier
from pre-existing link-local address when available.
Diffstat (limited to 'sys/src/9/ip/ipifc.c')
-rw-r--r-- | sys/src/9/ip/ipifc.c | 138 |
1 files changed, 80 insertions, 58 deletions
diff --git a/sys/src/9/ip/ipifc.c b/sys/src/9/ip/ipifc.c index f1fa6486c..2c401bc98 100644 --- a/sys/src/9/ip/ipifc.c +++ b/sys/src/9/ip/ipifc.c @@ -317,6 +317,10 @@ ipifcadjustburst(Ipifc *ifc) ifc->burst = burst; } +/* + * change an interface's burst delay + * ifc must be bound and wlock'd + */ static void ipifcsetdelay(Ipifc *ifc, int delay) { @@ -328,6 +332,10 @@ ipifcsetdelay(Ipifc *ifc, int delay) ipifcadjustburst(ifc); } +/* + * change an interface's baud rate + * ifc must be bound and wlock'd + */ static void ipifcsetspeed(Ipifc *ifc, int speed) { @@ -338,6 +346,20 @@ ipifcsetspeed(Ipifc *ifc, int speed) ipifcadjustburst(ifc); } +/* + * change an interface's mtu + * ifc must be bound and wlock'd + */ +static char* +ipifcsetmtu(Ipifc *ifc, int mtu) +{ + if(mtu < ifc->m->mintu || mtu > ifc->m->maxtu) + return Ebadarg; + ifc->maxtu = mtu; + ipifcadjustburst(ifc); + return nil; +} + void ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh) { @@ -421,23 +443,6 @@ ipifcclose(Conv *c) } /* - * change an interface's mtu - */ -static char* -ipifcsetmtu(Ipifc *ifc, int mtu) -{ - Medium *m = ifc->m; - - if(m == nil) - return Eunbound; - if(mtu < m->mintu || mtu > m->maxtu) - return Ebadarg; - ifc->maxtu = mtu; - ipifcadjustburst(ifc); - return nil; -} - -/* * add an address to an interface. */ char* @@ -761,7 +766,11 @@ ipifcconnect(Conv* c, char **argv, int argc) return nil; } -char* +/* + * change ipv6 router parameters + * ifc must be bound and wlock'd + */ +static char* ipifcra6(Ipifc *ifc, char **argv, int argc) { int i, argsleft; @@ -802,7 +811,6 @@ ipifcra6(Ipifc *ifc, char **argv, int argc) rp.routerlt = atoi(argv[i+1]); else return Ebadarg; - argsleft -= 2; i += 2; } @@ -825,44 +833,45 @@ static char* ipifcctl(Conv* c, char **argv, int argc) { Ipifc *ifc = (Ipifc*)c->ptcl; + char *err = nil; - if(strcmp(argv[0], "add") == 0) - return ipifcadd(ifc, argv, argc, 0, nil); + if(strcmp(argv[0], "iprouting") == 0) + iprouting(c->p->f, argc>1? atoi(argv[1]): 1); + else if(strcmp(argv[0], "add") == 0) + err = ipifcadd(ifc, argv, argc, 0, nil); else if(strcmp(argv[0], "try") == 0) - return ipifcadd(ifc, argv, argc, 1, nil); + err = ipifcadd(ifc, argv, argc, 1, nil); else if(strcmp(argv[0], "remove") == 0) - return ipifcrem(ifc, argv, argc); + err = ipifcrem(ifc, argv, argc); else if(strcmp(argv[0], "unbind") == 0) - return ipifcunbind(ifc); - else if(strcmp(argv[0], "mtu") == 0) - return ipifcsetmtu(ifc, argc>1? strtoul(argv[1], 0, 0): 0); - else if(strcmp(argv[0], "speed") == 0){ - ipifcsetspeed(ifc, argc>1? atoi(argv[1]): 0); - return nil; - } - else if(strcmp(argv[0], "delay") == 0){ - ipifcsetdelay(ifc, argc>1? atoi(argv[1]): 0); - return nil; - } - else if(strcmp(argv[0], "iprouting") == 0){ - iprouting(c->p->f, argc>1? atoi(argv[1]): 1); - return nil; - } - else if(strcmp(argv[0], "reflect") == 0){ - ifc->reflect = argc>1? atoi(argv[1]): 1; - return nil; - } - else if(strcmp(argv[0], "reassemble") == 0){ - ifc->reassemble = argc>1? atoi(argv[1]): 1; - return nil; - } + err = ipifcunbind(ifc); else if(strcmp(argv[0], "add6") == 0) - return ipifcadd6(ifc, argv, argc); + err = ipifcadd6(ifc, argv, argc); else if(strcmp(argv[0], "remove6") == 0) - return ipifcremove6(ifc, argv, argc); - else if(strcmp(argv[0], "ra6") == 0) - return ipifcra6(ifc, argv, argc); - return "unsupported ctl"; + err = ipifcremove6(ifc, argv, argc); + else { + wlock(ifc); + if(ifc->m == nil){ + wunlock(ifc); + return Eunbound; + } + if(strcmp(argv[0], "mtu") == 0) + err = ipifcsetmtu(ifc, argc>1? strtoul(argv[1], 0, 0): 0); + else if(strcmp(argv[0], "speed") == 0) + ipifcsetspeed(ifc, argc>1? atoi(argv[1]): 0); + else if(strcmp(argv[0], "delay") == 0) + ipifcsetdelay(ifc, argc>1? atoi(argv[1]): 0); + else if(strcmp(argv[0], "reflect") == 0) + ifc->reflect = argc>1? atoi(argv[1]): 1; + else if(strcmp(argv[0], "reassemble") == 0) + ifc->reassemble = argc>1? atoi(argv[1]): 1; + else if(strcmp(argv[0], "ra6") == 0) + err = ipifcra6(ifc, argv, argc); + else + err = "unsupported ctl"; + wunlock(ifc); + } + return err; } int @@ -1661,7 +1670,6 @@ ipifcadd6(Ipifc *ifc, char **argv, int argc) char *params[3]; uchar prefix[IPaddrlen]; Iplifc lifc; - Medium *m; lifc.onlink = 1; lifc.autoflag = 1; @@ -1694,14 +1702,28 @@ ipifcadd6(Ipifc *ifc, char **argv, int argc) plen > 64 || islinklocal(prefix)) return Ebadarg; - /* issue "add" ctl msg for v6 link-local addr and prefix len */ - m = ifc->m; - if(m == nil || m->pref2addr == nil) + rlock(ifc); + if(ifc->m == nil){ + runlock(ifc); return Eunbound; - (*m->pref2addr)(prefix, ifc->mac); /* mac → v6 link-local addr */ + } + if(ifc->m->pref2addr != nil && ifc->m->maclen > 0) { + /* mac → v6 link-local addr */ + (*ifc->m->pref2addr)(prefix, ifc->mac); + } else { + /* copy from existing v6 link-local address */ + Iplifc *llifc = iplinklocalifc(ifc); + if(llifc == nil){ + runlock(ifc); + return Eunbound; + } + memmove(prefix+8, llifc->local+8, 8); + } + runlock(ifc); - sprint(addr, "%I", prefix); - sprint(preflen, "/%d", plen); + /* issue "add" ctl msg for v6 link-local addr and prefix len */ + snprint(addr, sizeof addr, "%I", prefix); + snprint(preflen, sizeof preflen, "/%d", plen); params[0] = "add"; params[1] = addr; params[2] = preflen; |