diff --git a/rc/bin/cpurc b/rc/bin/cpurc index a410d3dcb..404f494ff 100755 --- a/rc/bin/cpurc +++ b/rc/bin/cpurc @@ -5,7 +5,7 @@ NPROC=`{wc -l /dev/null >[2=1] rm -f /env/i @@ -56,12 +56,19 @@ if(test -e /cfg/$sysname/cpurc) # automatic ip address setup if(test -r /net/ipselftab){ if(! grep u /net/ipselftab | grep -sv 127.0.0.1){ - ether=`{ndb/query sys $sysname ether} - if(~ $#ether 1){ - # try /lib/ndb first, then do dhcp - ip/ipconfig -N >[2]/dev/null || ip/ipconfig -h $sysname + addrs=`{ndb/query -a sys $sysname ether} + if(! ~ $#addrs 0){ + for(ether in /net/ether*){ + addr=`{cat $ether/addr} + switch($addr){ + case $addrs + # try /lib/ndb first, then do dhcp + ip/ipconfig -N ether $ether >[2]/dev/null \ + || ip/ipconfig -h $sysname ether $ether + } + } } - rm -f /env/ether + rm -f /env/ether /env/addrs /env/addr } } @@ -77,16 +84,16 @@ if(! ps|grep -s timesync){ sleep 2 } -if(~ $#auth 0){ - auth=`{ndb/query sys $sysname auth} - . <{ndb/ipquery sys $sysname auth | sed 's, +,\n,g'} -} if(test -d /cfg/$sysname/service) serviced=/cfg/$sysname/service if not if(test -d /cfg/default/service) serviced=/cfg/default/service if not serviced=/rc/bin/service +if(~ $#auth 0){ + auth=`{ndb/query sys $sysname auth} + . <{ndb/ipquery sys $sysname auth | sed 's, +,\n,g'} +} switch($auth){ case `{ echo $sysname; ndb/query sys $sysname dom if(test -r /net/ipselftab){ diff --git a/rc/bin/ipv6on b/rc/bin/ipv6on deleted file mode 100755 index 703feed76..000000000 --- a/rc/bin/ipv6on +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/rc -# ipv6on [netdir ndbfile [gwv4]] - configure an interface for ipv6, -# once ipv4 is configured. -if (! ~ $#* 0 2 3) { - echo usage: $0 '[netdir ndbfile [gw-v4-name]]' >[1=2] - exit usage -} -rfork e -if (~ $#* 0) { - netdir=/net - ndbf=/lib/ndb/local - gw=`{ndb/ipquery sys $sysname ipgw | sed 's/ipgw=//'} -} -if not { - netdir=$1 - ndbf=$2 - if (~ $#* 2) - # gw=() - gw=`{ndb/ipquery sys $sysname ipgw | sed 's/ipgw=//'} - if not - gw=$3 -} -if (~ $netdir /net) { - xsfx=() - xdir=() -} -if not { - xsfx=(-x `{echo $netdir | sed 's;^/net;;'}) - xdir=(-x $netdir) -} -fn nonnil { # variable - if (~ $#$1 0) { - echo no ip for $1 - exit no-ip - } - if (! ~ $#$1 1) { - echo multiple ips for $1 - exit multiple-ips - } -} -devdir=`{awk '/^device/{print $2}' $netdir/ipifc/*/status | grep -v /dev/null} -nonnil devdir -devtype=pkt -if(~ $devdir *ether*) - devtype=ether - -# -# configure v6 for link-local addresses (fe80::) & multicast (ff02::) -# -if (! ip/ipconfig -6 $xdir $devtype $devdir) - exit 'ipconfig -6 failed' -ip/ipconfig $xdir $devtype $devdir ra6 recvra 1 - -mev6=`{ndb/query -f $ndbf sys $sysname ipv6 | grep :} -if (~ $#mev6 0) - mev6=`{ndb/query -mf $ndbf sys $sysname ip | grep :} -# mev4=`{ndb/query -f $ndbf sys $sysname ip | grep -v :} - -# for testing -if(~ $devtype ether){ - mylnk=`{ip/linklocal `{cat $devdir/addr}} - nonnil mylnk -} - -if (~ $#gw 1) { - if (~ $gw [0-9]*.[0-9]*.[0-9]*.[0-9]*) - gwv4=$gw - if (~ $#gwv4 0) - gwv4=`{ndb/query -f $ndbf sys $gw ip | grep -v :} - if (~ $gw *:*) - gwv6=$gw - if (~ $#gwv6 0) - gwv6=`{ndb/query -f $ndbf sys $gw ipv6 | grep :} - if (~ $#gwv6 0) - gwv6=`{ndb/query -f $ndbf sys $gw ip | grep :} - if (~ $#gwv6 0) { - if (~ $#gwv4 1) { - # echo ping gw $gwv4... - # load arp cache with gw mac - ip/ping -qn 3 $netdir/icmp!$gwv4 >/dev/null >[2=1] & - sleep 1 # wait for ping - - gweth=`{grep '* '^$gwv4^' ' $netdir/arp | awk '{print $4}' } - nonnil gweth - gwlnk=`{ip/linklocal $gweth} - nonnil gwlnk - gwv6=$gwlnk - } - } -} -nonnil mev6 -# -# configure my global v6 addresses -# -ip/ipconfig $xdir $devtype $devdir add $mev6 /64 -ip/ipconfig $xdir loopback /dev/null add $mev6 /128 - -if (~ $#gwv6 1) { - # - # add default v6 route to v6 addr of v4 gw - # - echo add :: /0 $gwv6 >$netdir/iproute # need not be link-local -} -exit '' diff --git a/rc/bin/termrc b/rc/bin/termrc index dfc99968b..f160915e6 100755 --- a/rc/bin/termrc +++ b/rc/bin/termrc @@ -6,7 +6,7 @@ TIMESYNCARGS=(-rLa1000000) NPROC=`{wc -l /dev/null >[2=1] rm -f /env/i @@ -57,12 +57,19 @@ if(test -e /cfg/$sysname/termrc) # automatic ip address setup if(test -r /net/ipselftab){ if(! grep u /net/ipselftab | grep -sv 127.0.0.1){ - ether=`{ndb/query sys $sysname ether} - if(~ $#ether 1){ - # try /lib/ndb first, then do dhcp - ip/ipconfig -N >[2]/dev/null || ip/ipconfig -h $sysname + addrs=`{ndb/query -a sys $sysname ether} + if(! ~ $#addrs 0){ + for(ether in /net/ether*){ + addr=`{cat $ether/addr} + switch($addr){ + case $addrs + # try /lib/ndb first, then do dhcp + ip/ipconfig -N ether $ether >[2]/dev/null \ + || ip/ipconfig -h $sysname ether $ether + } + } } - rm -f /env/ether + rm -f /env/ether /env/addrs /env/addr } } diff --git a/sys/man/3/ip b/sys/man/3/ip index 76430cd01..38ae273bc 100644 --- a/sys/man/3/ip +++ b/sys/man/3/ip @@ -194,6 +194,17 @@ Set the maximum transfer unit for this device to The mtu is the maximum size of the packet including any medium-specific headers. .TP +.BI speed\ n +Set the maximum transmit speed in bits per second. +TP +.BI delay\ n +Set the maximum burst delay in milliseconds. (Default is 40ms) +When +.B speed +has been set and packets in flight exceed the maximum burst +delay then packets send on the interface are discarded until +the load drops below the maximum. +.TP .BI iprouting\ n Allow .RI ( n diff --git a/sys/man/8/ipconfig b/sys/man/8/ipconfig index 6cbaa3ef6..1e14eeaf9 100644 --- a/sys/man/8/ipconfig +++ b/sys/man/8/ipconfig @@ -1,6 +1,6 @@ .TH IPCONFIG 8 .SH NAME -ipconfig, rip, linklocal, ipv6on \- Internet configuration and routing +ipconfig, rip, linklocal \- Internet configuration and routing .SH SYNOPSIS .in +0.25i .ti -0.25i @@ -52,14 +52,6 @@ ipconfig, rip, linklocal, ipv6on \- Internet configuration and routing ] .I mac \&... -.PP -.B ipv6on -[ -.I netmtpt -.I ndbfile -[ -.I gwv4 -]\|] .SH DESCRIPTION .I Ipconfig binds a device interface to a mounted IP stack (default @@ -73,12 +65,13 @@ The addresses can be specified in the command line or obtained via DHCP. If DHCP is requested, it will also obtain the addresses of DNS servers, NTP servers, gateways, a Plan 9 file server, and a Plan 9 authentication server. -If this is the first non-loopback -interface on the IP stack, the information will be written to +Information from DHCP and IPv6 router advertisements is written to .B /net/ndb in the form of an .IR ndb (8) -entry. +entry unless the +.B P +flag has been specified. .PP .I Type may be @@ -175,7 +168,7 @@ turn on debugging. the default gateway. .TP .B G -use only generic DHCP options. Without this option, +use only generic DHCP and RA options. Without this option, .I ipconfig adds to requests a Vendor Class option with value .BI plan9_$ cputype @@ -197,10 +190,18 @@ determine parameters but don't configure the interface. .TP .B N look in -.B /lib/ndb -for the IP parameters. This only works if the -interface is an ethernet. It uses the ethernet address to find -a matching entry. +.I dbfile +(default +.BR /lib/ndb/local ) +for the IP parameters for the specified +.I local +IP address or if +.I local +is omited and the device is an ethernet then all IP parameters +associated with the MAC address. IPv6 addresses are added only +if a IPv6 link-local address exists on the interface or the +.B 6 +flag has been given to automatically configure one. .TP .B O addresses specified on the command line override those obtained via DHCP. @@ -208,13 +209,11 @@ A command line address of 0 implies no override. .TP .B p write configuration information to -.BR /net/ndb , -even if other network interfaces are already configured +.BR /net/ndb . .TP .B P do not write configuration information to -.BR /net/ndb , -even if this is the first network interface to be configured +.BR /net/ndb . .TP .B r by default, @@ -231,7 +230,7 @@ before adding new ones. .TP .B f use the ndb database file -.I dbfile . +.IR dbfile . .TP .B x use the IP stack mounted at @@ -322,18 +321,6 @@ and .I 6to4 gateway .IR gwipv4 . -.PP -.I Ipv6on -uses the network database at -.I ndbfile -to configure the network mounted on -.I netmtpt -with a link-local address (derived from its MAC address) -and attempts to add a default IPv6 route to the local -IPv4 gateway's IPv6 address. -If -.I gwv4 -is supplied, it will be used as the gateway IPv4 address. .SH EXAMPLES Configure Ethernet 0 as the primary IP interface. Get all addresses via DHCP. Start up a connection server @@ -386,8 +373,6 @@ ip/ipconfig ra6 recvra 1 .B /sys/src/cmd/ip/rip.c .br .B /sys/src/cmd/ip/linklocal.c -.br -.B /rc/bin/ipv6on .SH "SEE ALSO" .IR ether (3), .IR ip (3), diff --git a/sys/man/8/ppp b/sys/man/8/ppp index be60bfda3..66ebb7bfd 100644 --- a/sys/man/8/ppp +++ b/sys/man/8/ppp @@ -53,6 +53,10 @@ ppp, pppoe, pptp, pptpd \- point-to-point protocol .I mtu ] [ +.B -b +.I baud +] +[ .B -x .I pppnetmntpt ] diff --git a/sys/src/9/ip/arp.c b/sys/src/9/ip/arp.c index 12cb42fd1..03897c705 100644 --- a/sys/src/9/ip/arp.c +++ b/sys/src/9/ip/arp.c @@ -303,7 +303,7 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *if freeblistchain(next); break; } - ifc->m->bwrite(ifc, concatblock(bp), version, ip); + ipifcoput(ifc, bp, version, ip); poperror(); } return 1; diff --git a/sys/src/9/ip/ip.c b/sys/src/9/ip/ip.c index 7166619dd..f1cd74c10 100644 --- a/sys/src/9/ip/ip.c +++ b/sys/src/9/ip/ip.c @@ -180,6 +180,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) runlock(ifc); nexterror(); } + if(ifc->m == nil) goto raise; @@ -196,7 +197,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) eh->cksum[0] = 0; eh->cksum[1] = 0; hnputs(eh->cksum, ipcsum(&eh->vihl)); - ifc->m->bwrite(ifc, concatblock(bp), V4, gate); + ipifcoput(ifc, bp, V4, gate); runlock(ifc); poperror(); return 0; @@ -280,7 +281,7 @@ if((eh->frag[0] & (IP_DF>>8)) && !gating) print("%V: DF set\n", eh->dst); feh->cksum[0] = 0; feh->cksum[1] = 0; hnputs(feh->cksum, ipcsum(&feh->vihl)); - ifc->m->bwrite(ifc, nb, V4, gate); + ipifcoput(ifc, nb, V4, gate); ip->stats[FragCreates]++; } ip->stats[FragOKs]++; diff --git a/sys/src/9/ip/ip.h b/sys/src/9/ip/ip.h index 84edd761e..de1908dcd 100644 --- a/sys/src/9/ip/ip.h +++ b/sys/src/9/ip/ip.h @@ -327,6 +327,12 @@ struct Ipifc uchar recvra6; /* flag: recv router advs on this ifc */ Routerparams rp; /* router parameters as in RFC 2461, pp.40—43. used only if node is router */ + + int speed; /* link speed in bits per second */ + int delay; /* burst delay in ms */ + int burst; /* burst delay in bytes */ + int load; /* bytes in flight */ + ulong ticks; }; /* @@ -652,6 +658,7 @@ extern Medium pktmedium; */ extern Medium* ipfindmedium(char *name); extern void addipmedium(Medium *med); +extern void ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip); extern int ipforme(Fs*, uchar *addr); extern int ipismulticast(uchar *ip); extern Ipifc* findipifc(Fs*, uchar *local, uchar *remote, int type); diff --git a/sys/src/9/ip/ipifc.c b/sys/src/9/ip/ipifc.c index 037f2abd9..d0d0557a9 100644 --- a/sys/src/9/ip/ipifc.c +++ b/sys/src/9/ip/ipifc.c @@ -250,7 +250,7 @@ ipifcunbind(Ipifc *ifc) char sfixedformat[] = "device %s maxtu %d sendra %d recvra %d mflag %d oflag" " %d maxraint %d minraint %d linkmtu %d reachtime %d rxmitra %d ttl %d routerlt" -" %d pktin %lud pktout %lud errin %lud errout %lud\n"; +" %d pktin %lud pktout %lud errin %lud errout %lud speed %d delay %d\n"; char slineformat[] = " %-40I %-10M %-40I %-12lud %-12lud\n"; @@ -267,7 +267,8 @@ ipifcstate(Conv *c, char *state, int n) ifc->rp.mflag, ifc->rp.oflag, ifc->rp.maxraint, ifc->rp.minraint, ifc->rp.linkmtu, ifc->rp.reachtime, ifc->rp.rxmitra, ifc->rp.ttl, ifc->rp.routerlt, - ifc->in, ifc->out, ifc->inerr, ifc->outerr); + ifc->in, ifc->out, ifc->inerr, ifc->outerr, + ifc->speed, ifc->delay); rlock(ifc); for(lifc = ifc->lifc; lifc != nil && n > m; lifc = lifc->next) @@ -309,6 +310,50 @@ ipifcinuse(Conv *c) return ifc->m != nil; } +static void +ipifcsetdelay(Ipifc *ifc, int delay) +{ + if(delay < 0) + delay = 0; + 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; +} + +static void +ipifcsetspeed(Ipifc *ifc, int speed) +{ + if(speed < 0) + speed = 0; + ifc->speed = speed; + ifc->load = 0; + ipifcsetdelay(ifc, ifc->delay); +} + +void +ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip) +{ + if(ifc->speed){ + ulong now = MACHP(0)->ticks; + int dt = TK2MS(now - ifc->ticks); + ifc->ticks = now; + ifc->load -= ((vlong)dt * ifc->speed) / 8000; + if(ifc->load < 0 || dt < 0 || dt > 1000) + ifc->load = 0; + else if(ifc->load > ifc->burst){ + freeblist(bp); + return; + } + } + bp = concatblock(bp); + ifc->load += BLEN(bp); + ifc->m->bwrite(ifc, bp, version, ip); +} + + /* * called when a process writes to an interface's 'data' */ @@ -358,6 +403,8 @@ ipifccreate(Conv *c) ifc->m = nil; ifc->reflect = 0; ifc->reassemble = 0; + ipifcsetspeed(ifc, 0); + ipifcsetdelay(ifc, 40); } /* @@ -772,6 +819,14 @@ ipifcctl(Conv* c, char **argv, int argc) return ipifcunbind(ifc); else if(strcmp(argv[0], "mtu") == 0) return ipifcsetmtu(ifc, argv, argc); + 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; diff --git a/sys/src/9/ip/ipv6.c b/sys/src/9/ip/ipv6.c index aab473c87..6b6d4eeca 100644 --- a/sys/src/9/ip/ipv6.c +++ b/sys/src/9/ip/ipv6.c @@ -103,7 +103,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) medialen = ifc->maxtu - ifc->m->hsize; if(len <= medialen) { hnputs(eh->ploadlen, len - IP6HDR); - ifc->m->bwrite(ifc, concatblock(bp), V6, gate); + ipifcoput(ifc, bp, V6, gate); runlock(ifc); poperror(); return 0; @@ -193,8 +193,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) if(xp->rp == xp->wp) xp = xp->next; } - - ifc->m->bwrite(ifc, nb, V6, gate); + ipifcoput(ifc, nb, V6, gate); ip->stats[FragCreates]++; } ip->stats[FragOKs]++; diff --git a/sys/src/cmd/ip/ipconfig/main.c b/sys/src/cmd/ip/ipconfig/main.c index e051821d9..b8899d06d 100644 --- a/sys/src/cmd/ip/ipconfig/main.c +++ b/sys/src/cmd/ip/ipconfig/main.c @@ -318,8 +318,7 @@ main(int argc, char **argv) plan9 = 0; break; case 'h': - snprint(conf.hostname, sizeof conf.hostname, "%s", - EARGF(usage())); + snprint(conf.hostname, sizeof conf.hostname, "%s", EARGF(usage())); sendhostname = 1; break; case 'm': @@ -389,7 +388,7 @@ main(int argc, char **argv) if(dondbconfig){ dodhcp = 0; ndbconfig(); - return; + break; } doadd(); break; diff --git a/sys/src/cmd/ip/linklocal.c b/sys/src/cmd/ip/linklocal.c index afe86435b..9c5066d64 100644 --- a/sys/src/cmd/ip/linklocal.c +++ b/sys/src/cmd/ip/linklocal.c @@ -25,7 +25,7 @@ usage(void) void ea2eui64(uchar *lla, uchar *ea) { - *lla++ = *ea++ | V60globaladm; /* oui (company id) */ + *lla++ = *ea++ ^ V60globaladm; /* oui (company id) */ *lla++ = *ea++; /* " */ *lla++ = *ea++; /* " */ *lla++ = 0xFF; /* mac-48 in eui-64 (sic) */ diff --git a/sys/src/cmd/ip/ppp/ppp.c b/sys/src/cmd/ip/ppp/ppp.c index 650b75c3d..1225e8373 100644 --- a/sys/src/cmd/ip/ppp/ppp.c +++ b/sys/src/cmd/ip/ppp/ppp.c @@ -1497,7 +1497,7 @@ ppptimer(PPP *ppp) } static void -setdefroute(char *net, Ipaddr gate) +defroute(char *net, char *verb, Ipaddr gate, Ipaddr local) { int fd; char path[128]; @@ -1506,7 +1506,10 @@ setdefroute(char *net, Ipaddr gate) fd = open(path, ORDWR); if(fd < 0) return; - fprint(fd, "add 0 0 %I", gate); + fprint(fd, "tag ppp"); + if(primary) + fprint(fd, "%s 0.0.0.0 0.0.0.0 %I", verb, gate); + fprint(fd, "%s 0.0.0.0 0.0.0.0 %I %I 255.255.255.255", verb, gate, local); close(fd); } @@ -1550,8 +1553,9 @@ ipopen(PPP *ppp) close(cfd); return "can't set addresses"; } - if(primary) - setdefroute(ppp->net, ppp->remote); + if(baud) + fprint(cfd, "speed %d", baud); + defroute(ppp->net, "add", ppp->remote, ppp->local); ppp->ipfd = fd; ppp->ipcfd = cfd; @@ -1570,6 +1574,7 @@ ipopen(PPP *ppp) /* we may have changed addresses */ if(ipcmp(ppp->local, ppp->curlocal) != 0 || ipcmp(ppp->remote, ppp->curremote) != 0){ + defroute(ppp->net, "remove", ppp->curremote, ppp->curlocal); snprint(buf, sizeof buf, "remove %I 255.255.255.255 %I", ppp->curlocal, ppp->curremote); if(fprint(ppp->ipcfd, "%s", buf) < 0) @@ -1578,6 +1583,7 @@ ipopen(PPP *ppp) ppp->local, ppp->remote, ppp->mtu-10); if(fprint(ppp->ipcfd, "%s", buf) < 0) syslog(0, "ppp", "can't %s: %r", buf); + defroute(ppp->net, "add", ppp->remote, ppp->local); } syslog(0, "ppp", "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote, ppp->local, ppp->remote); @@ -2634,7 +2640,7 @@ usage(void) void main(int argc, char **argv) { - int mtu, baud, framing, user, mediain, mediaout, cfd; + int mtu, framing, user, mediain, mediaout, cfd; Ipaddr ipaddr, remip; char *dev, *modemcmd; char net[128]; @@ -2654,7 +2660,6 @@ main(int argc, char **argv) invalidate(remip); mtu = Defmtu; - baud = 0; framing = 0; setnetmtpt(net, sizeof(net), nil); user = 0; diff --git a/sys/src/cmd/ip/pppoe.c b/sys/src/cmd/ip/pppoe.c index 34bfb00f9..8dd0f3638 100644 --- a/sys/src/cmd/ip/pppoe.c +++ b/sys/src/cmd/ip/pppoe.c @@ -29,11 +29,12 @@ int cookielen; uchar etherdst[6]; int mtu = 1492; int pktcompress, hdrcompress; +char *baud; void usage(void) { - fprint(2, "usage: pppoe [-PdcC] [-A acname] [-S srvname] [-k keyspec] [-m mtu] [-x pppnet] [ether0]\n"); + fprint(2, "usage: pppoe [-PdcC] [-A acname] [-S srvname] [-k keyspec] [-m mtu] [-b baud] [-x pppnet] [ether0]\n"); exits("usage"); } @@ -76,6 +77,9 @@ main(int argc, char **argv) case 'k': keyspec = EARGF(usage()); break; + case 'b': + baud = EARGF(usage()); + break; case 'c': pktcompress = 1; break; @@ -533,6 +537,10 @@ execppp(int fd) argv[argc++] = "-d"; if(primary) argv[argc++] = "-P"; + if(baud){ + argv[argc++] = "-b"; + argv[argc++] = baud; + } if(hdrcompress) argv[argc++] = "-C"; if(pktcompress)