shithub: riscv

Download patch

ref: 333c3202043d25c8a975b94cdd374712314189c7
parent: 7186be0424ba65942a13b7706017c6ef4338f219
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 11 13:22:33 EDT 2019

devip: reset speed and delay on bind, adjust burst on mtu change, ifc->m nil check, consistent error strings

initialize the rate limits when the device gets
bound, not when it is created. so that the
rate limtis get reset to default when the ifc
is reused.

adjust the burst delay when the mtu is changed.
this is to make sure that we allow at least one
full sized packet burst.

make a local copy of ifc->m before doing nil
check as it can change under us when we do
not have the ifc locked.

specify Ebound[] and Eunbound[] error strings
and use them consistently.

--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -65,6 +65,9 @@
 static void	ipifcregisterproxy(Fs*, Ipifc*, uchar*, int);
 static char*	ipifcremlifc(Ipifc*, Iplifc**);
 
+static char Ebound[] = "interface already bound";
+static char Eunbound[] = "interface not bound";
+
 enum {
 	unknownv6,		/* UGH */
 	unspecifiedv6,
@@ -151,7 +154,7 @@
 	wlock(ifc);
 	if(ifc->m != nil){
 		wunlock(ifc);
-		return "interface already bound";
+		return Ebound;
 	}
 	if(waserror()){
 		wunlock(ifc);
@@ -172,6 +175,8 @@
 	ifc->m = m;
 	ifc->mintu = ifc->m->mintu;
 	ifc->maxtu = ifc->m->maxtu;
+	ifc->delay = 40;
+	ifc->speed = 0;
 	if(ifc->m->unbindonclose == 0)
 		ifc->conv->inuse++;
 
@@ -201,7 +206,7 @@
 	wlock(ifc);
 	if(ifc->m == nil){
 		wunlock(ifc);
-		return "interface not bound";
+		return Eunbound;
 	}
 
 	/* disassociate logical interfaces (before zeroing ifc->arg) */
@@ -300,6 +305,17 @@
 }
 
 static void
+ipifcadjustburst(Ipifc *ifc)
+{
+	int burst;
+
+	burst = ((vlong)ifc->delay * ifc->speed) / 8000;
+	if(burst < ifc->maxtu)
+		burst = ifc->maxtu;
+	ifc->burst = burst;
+}
+
+static void
 ipifcsetdelay(Ipifc *ifc, int delay)
 {
 	if(delay < 0)
@@ -307,9 +323,7 @@
 	else if(delay > 1000)
 		delay = 1000;
 	ifc->delay = delay;
-	ifc->burst = ((vlong)delay * ifc->speed) / 8000;
-	if(ifc->burst < ifc->maxtu)
-		ifc->burst = ifc->maxtu;
+	ipifcadjustburst(ifc);
 }
 
 static void
@@ -319,7 +333,7 @@
 		speed = 0;
 	ifc->speed = speed;
 	ifc->load = 0;
-	ipifcsetdelay(ifc, ifc->delay);
+	ipifcadjustburst(ifc);
 }
 
 void
@@ -392,8 +406,6 @@
 	ifc->m = nil;
 	ifc->reflect = 0;
 	ifc->reassemble = 0;
-	ipifcsetspeed(ifc, 0);
-	ipifcsetdelay(ifc, 40);
 }
 
 /*
@@ -402,11 +414,9 @@
 static void
 ipifcclose(Conv *c)
 {
-	Ipifc *ifc;
-	Medium *m;
+	Ipifc *ifc = (Ipifc*)c->ptcl;
+	Medium *m = ifc->m;
 
-	ifc = (Ipifc*)c->ptcl;
-	m = ifc->m;
 	if(m != nil && m->unbindonclose)
 		ipifcunbind(ifc);
 }
@@ -414,17 +424,17 @@
 /*
  *  change an interface's mtu
  */
-char*
-ipifcsetmtu(Ipifc *ifc, char **argv, int argc)
+static char*
+ipifcsetmtu(Ipifc *ifc, int mtu)
 {
-	int mtu;
+	Medium *m = ifc->m;
 
-	if(argc < 2 || ifc->m == nil)
+	if(m == nil)
+		return Eunbound;
+	if(mtu < m->mintu || mtu > m->maxtu)
 		return Ebadarg;
-	mtu = strtoul(argv[1], 0, 0);
-	if(mtu < ifc->m->mintu || mtu > ifc->m->maxtu)
-		return Ebadarg;
 	ifc->maxtu = mtu;
+	ipifcadjustburst(ifc);
 	return nil;
 }
 
@@ -488,7 +498,7 @@
 	wlock(ifc);
 	if(ifc->m == nil){
 		wunlock(ifc);
-		return "interface not yet bound to device";
+		return Eunbound;
 	}
 	f = ifc->conv->p->f;
 	if(waserror()){
@@ -496,8 +506,8 @@
 		return up->errstr;
 	}
 
-	if(mtu > 0 && mtu >= ifc->m->mintu && mtu <= ifc->m->maxtu)
-		ifc->maxtu = mtu;
+	if(mtu > 0)
+		ipifcsetmtu(ifc, mtu);
 
 	/* ignore if this is already a local address for this ifc */
 	if((lifc = iplocalonifc(ifc, ip)) != nil){
@@ -680,9 +690,9 @@
 char*
 ipifcrem(Ipifc *ifc, char **argv, int argc)
 {
-	char *rv;
 	uchar ip[IPaddrlen], mask[IPaddrlen], rem[IPaddrlen];
 	Iplifc *lifc, **l;
+	char *err;
 
 	if(argc < 3)
 		return Ebadarg;
@@ -707,9 +717,9 @@
 			break;
 		l = &lifc->next;
 	}
-	rv = ipifcremlifc(ifc, l);
+	err = ipifcremlifc(ifc, l);
 	wunlock(ifc);
-	return rv;
+	return err;
 }
 
 /*
@@ -720,10 +730,9 @@
 static char*
 ipifcconnect(Conv* c, char **argv, int argc)
 {
+	Ipifc *ifc = (Ipifc*)c->ptcl;
 	char *err;
-	Ipifc *ifc;
 
-	ifc = (Ipifc*)c->ptcl;
 	wlock(ifc);
 	while(ifc->lifc != nil)
 		ipifcremlifc(ifc, &ifc->lifc);
@@ -800,9 +809,8 @@
 static char*
 ipifcctl(Conv* c, char **argv, int argc)
 {
-	Ipifc *ifc;
+	Ipifc *ifc = (Ipifc*)c->ptcl;
 
-	ifc = (Ipifc*)c->ptcl;
 	if(strcmp(argv[0], "add") == 0)
 		return ipifcadd(ifc, argv, argc, 0, nil);
 	else if(strcmp(argv[0], "try") == 0)
@@ -812,7 +820,7 @@
 	else if(strcmp(argv[0], "unbind") == 0)
 		return ipifcunbind(ifc);
 	else if(strcmp(argv[0], "mtu") == 0)
-		return ipifcsetmtu(ifc, argv, argc);
+		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;
@@ -1619,7 +1627,7 @@
 	/* issue "add" ctl msg for v6 link-local addr and prefix len */
 	m = ifc->m;
 	if(m == nil || m->pref2addr == nil)
-		return Ebadarg;
+		return Eunbound;
 	(*m->pref2addr)(prefix, ifc->mac);	/* mac → v6 link-local addr */
 
 	sprint(addr, "%I", prefix);