summaryrefslogtreecommitdiff
path: root/sys/src/9/ip/ipifc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2023-05-16 22:16:12 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2023-05-16 22:16:12 +0000
commitc45766fb054e3c82fe7be6cd5da2e6ff58e534e3 (patch)
tree6100eecedb57d1b1dedaa0a899f974bbca49ecb9 /sys/src/9/ip/ipifc.c
parentd4ce962fe33f3eca8da0b4ab2b5a81cc5359b71f (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.c138
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;