## diffname ip/iproute.c 1998/0306
## diff -e /dev/null /n/emeliedump/1998/0306/sys/src/brazil/ip/iproute.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "ip.h"
enum
{
Lroot = 10,
};
Route *v4root[1<<Lroot], *v6root[1<<Lroot], *queue;
static void walkadd(Route**, Route*);
static void addnode(Route**, Route*);
static void calcd(Route*);
Route* v4freelist;
Route* v6freelist;
RWlock routelock;
static void
freeroute(Route *r)
{
Route **l;
r->left = nil;
r->right = nil;
if(r->type & Rv4)
l = &v4freelist;
else
l = &v6freelist;
r->mid = *l;
*l = r;
}
static Route*
allocroute(int type)
{
Route *r;
int n;
Route **l;
if(type & Rv4){
n = sizeof(RouteTree) + sizeof(V4route);
l = &v4freelist;
} else {
n = sizeof(RouteTree) + sizeof(V6route);
l = &v6freelist;
}
r = *l;
if(r != nil){
*l = r->mid;
} else {
r = malloc(n);
if(r == nil)
panic("out of routing nodes");
}
memset(r, 0, n);
r->type = type;
r->ifc = nil;
return r;
}
static void
addqueue(Route **q, Route *r)
{
Route *l;
if(r == nil)
return;
l = allocroute(r->type);
l->mid = *q;
*q = l;
l->left = r;
}
/*
* compare 2 v6 addresses
*/
static int
lcmp(ulong *a, ulong *b)
{
int i;
for(i = 0; i < IPllen; i++){
if(a[i] > b[i])
return 1;
if(a[i] < b[i])
return -1;
}
return 0;
}
/*
* compare 2 v4 or v6 ranges
*/
enum
{
Rpreceeds,
Rfollows,
Requals,
Rcontains,
Rcontained,
};
static int
rangecompare(Route *a, Route *b)
{
if(a->type & Rv4){
if(a->v4.endaddress < b->v4.address)
return Rpreceeds;
if(a->v4.address > b->v4.endaddress)
return Rfollows;
if(a->v4.address <= b->v4.address
&& a->v4.endaddress >= b->v4.endaddress){
if(a->v4.address == b->v4.address
&& a->v4.endaddress == b->v4.endaddress)
return Requals;
return Rcontains;
}
return Rcontained;
}
if(lcmp(a->v6.endaddress, b->v6.address) < 0)
return Rpreceeds;
if(lcmp(a->v6.address, b->v6.endaddress) > 0)
return Rfollows;
if(lcmp(a->v6.address, b->v6.address) <= 0
&& lcmp(a->v6.endaddress, b->v6.endaddress) >= 0){
if(lcmp(a->v6.address, b->v6.address) == 0
&& lcmp(a->v6.endaddress, b->v6.endaddress) == 0)
return Requals;
return Rcontains;
}
return Rcontained;
}
static void
copygate(Route *old, Route *new)
{
if(new->type & Rv4)
memmove(old->v4.gate, new->v4.gate, IPv4addrlen);
else
memmove(old->v6.gate, new->v6.gate, IPaddrlen);
}
/*
* walk down a tree adding nodes back in
*/
static void
walkadd(Route **root, Route *p)
{
Route *l, *r;
l = p->left;
r = p->right;
p->left = 0;
p->right = 0;
addnode(root, p);
if(l)
walkadd(root, l);
if(r)
walkadd(root, r);
}
/*
* calculate depth
*/
static void
calcd(Route *p)
{
Route *q;
int d;
if(p) {
d = 0;
q = p->left;
if(q)
d = q->depth;
q = p->right;
if(q && q->depth > d)
d = q->depth;
q = p->mid;
if(q && q->depth > d)
d = q->depth;
p->depth = d+1;
}
}
/*
* balance the tree at the current node
*/
static void
balancetree(Route **cur)
{
Route *p, *l, *r;
int dl, dr;
/*
* if left and right are
* too out of balance,
* rotate tree node
*/
p = *cur;
dl = 0; if(l = p->left) dl = l->depth;
dr = 0; if(r = p->right) dr = r->depth;
if(dl > dr+1) {
p->left = l->right;
l->right = p;
*cur = l;
calcd(p);
calcd(l);
} else
if(dr > dl+1) {
p->right = r->left;
r->left = p;
*cur = r;
calcd(p);
calcd(r);
} else
calcd(p);
}
/*
* add a new node to the tree
*/
static void
addnode(Route **cur, Route *new)
{
Route *p;
p = *cur;
if(p == 0) {
*cur = new;
new->depth = 1;
return;
}
switch(rangecompare(new, p)){
case Rpreceeds:
addnode(&p->left, new);
break;
case Rfollows:
addnode(&p->right, new);
break;
case Rcontains:
/*
* if new node is superset
* of tree node,
* replace tree node and
* queue tree node to be
* merged into root.
*/
*cur = new;
new->depth = 1;
addqueue(&queue, p);
break;
case Requals:
copygate(p, new);
freeroute(new);
break;
case Rcontained:
addnode(&p->mid, new);
break;
}
balancetree(cur);
}
#define V4H(a) ((a&0x07ffffff)>>(32-Lroot-5))
void
v4addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
{
Route *p;
ulong sa;
ulong m;
ulong ea;
int h, eh;
m = nhgetl(mask);
sa = nhgetl(a) & m;
ea = sa | ~m;
eh = V4H(ea);
for(h=V4H(sa); h<=eh; h++) {
p = allocroute(Rv4 | type);
p->v4.address = sa;
p->v4.endaddress = ea;
memmove(p->v4.gate, gate, sizeof(p->v4.gate));
memmove(p->tag, tag, sizeof(p->tag));
wlock(&routelock);
addnode(&v4root[h], p);
while(p = queue) {
queue = p->mid;
walkadd(&v4root[h], p->left);
freeroute(p);
}
wunlock(&routelock);
}
ipifcaddroute(Rv4, a, mask, gate, type);
}
#define V6H(a) (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
void
v6addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
{
Route *p;
ulong sa[IPllen], ea[IPllen];
ulong x, y;
int h, eh;
for(h = 0; h < IPllen; h++){
x = nhgetl(a+4*h);
y = nhgetl(mask+4*h);
sa[h] = x & y;
ea[h] = x | ~y;
}
eh = V6H(ea);
for(h = V6H(sa); h <= eh; h++) {
p = allocroute(type);
memmove(p->v6.address, sa, IPaddrlen);
memmove(p->v6.endaddress, ea, IPaddrlen);
memmove(p->v6.gate, gate, IPaddrlen);
memmove(p->tag, tag, sizeof(p->tag));
wlock(&routelock);
addnode(&v6root[h], p);
while(p = queue) {
queue = p->mid;
walkadd(&v6root[h], p->left);
freeroute(p);
}
wunlock(&routelock);
}
ipifcaddroute(0, a, mask, gate, type);
}
Route**
looknode(Route **cur, Route *r)
{
Route *p;
for(;;){
p = *cur;
if(p == 0)
return 0;
switch(rangecompare(r, p)){
case Rcontains:
return 0;
case Rpreceeds:
cur = &p->left;
break;
case Rfollows:
cur = &p->right;
break;
case Rcontained:
cur = &p->mid;
break;
case Requals:
return cur;
}
}
}
void
v4delroute(uchar *a, uchar *mask)
{
Route **r, *p;
Route rt;
int h, eh;
ulong m;
m = nhgetl(mask);
rt.v4.address = nhgetl(a) & m;
rt.v4.endaddress = rt.v4.address | ~m;
rt.type = Rv4;
eh = V4H(rt.v4.endaddress);
for(h=V4H(rt.v4.address); h<=eh; h++) {
wlock(&routelock);
r = looknode(&v4root[h], &rt);
if(r) {
p = *r;
*r = 0;
addqueue(&queue, p->left);
addqueue(&queue, p->mid);
addqueue(&queue, p->right);
freeroute(p);
while(p = queue) {
queue = p->mid;
walkadd(&v4root[h], p->left);
freeroute(p);
}
}
wunlock(&routelock);
}
ipifcremroute(Rv4, a, mask);
}
void
v6delroute(uchar *a, uchar *mask)
{
Route **r, *p;
Route rt;
int h, eh;
ulong x, y;
for(h = 0; h < IPllen; h++){
x = nhgetl(a+4*h);
y = nhgetl(mask+4*h);
rt.v6.address[h] = x & y;
rt.v6.endaddress[h] = x | ~y;
}
rt.type = 0;
eh = V6H(rt.v6.endaddress);
for(h=V6H(rt.v6.address); h<=eh; h++) {
wlock(&routelock);
r = looknode(&v6root[h], &rt);
if(r) {
p = *r;
*r = 0;
addqueue(&queue, p->left);
addqueue(&queue, p->mid);
addqueue(&queue, p->right);
freeroute(p);
while(p = queue) {
queue = p->mid;
walkadd(&v6root[h], p->left);
freeroute(p);
}
}
wunlock(&routelock);
}
ipifcremroute(0, a, mask);
}
Route*
v4lookup(uchar *a)
{
Route *p, *q;
ulong la;
uchar gate[IPaddrlen];
la = nhgetl(a);
q = nil;
for(p=v4root[V4H(la)]; p;)
if(la >= p->v4.address) {
if(la <= p->v4.endaddress) {
q = p;
p = p->mid;
} else
p = p->right;
} else
p = p->left;
if(q && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
v4tov6(gate, q->v4.gate);
q->ifc = findipifc(gate, q->type);
if(q->ifc == nil)
return nil;
q->ifcid = q->ifc->ifcid;
}
return q;
}
Route*
v6lookup(uchar *a)
{
Route *p, *q;
ulong la[IPllen];
int h;
ulong x, y;
if(memcmp(a, v4prefix, 12) == 0){
q = v4lookup(a+12);
if(q != nil)
return q;
}
for(h = 0; h < IPllen; h++)
la[h] = nhgetl(a+4*h);
q = 0;
for(p=v6root[V6H(la)]; p;){
for(h = 0; h < IPllen; h++){
x = la[h];
y = p->v6.address[h];
if(x == y)
continue;
if(x < y){
p = p->left;
goto next;
}
break;
}
for(h = 0; h < IPllen; h++){
x = la[h];
y = p->v6.endaddress[h];
if(x == y)
continue;
if(x > y){
p = p->right;
goto next;
}
break;
}
q = p;
p = p->mid;
next: ;
}
if(q && q->ifc == nil){
q->ifc = findipifc(q->v6.gate, q->type);
if(q->ifc == nil)
return nil;
if(q->ifcid != q->ifc->ifcid)
return nil;
}
return q;
}
enum
{
Rlinelen= 89,
};
char *rformat = "%-24.24I %-24.24M %-24.24I %4.4s %4.4s %3s\n";
void
convroute(Route *r, uchar *addr, uchar *mask, uchar *gate, char *t, int *nifc)
{
int i;
char *p = t;
if(r->type & Rv4){
memmove(addr, v4prefix, IPv4off);
hnputl(addr+IPv4off, r->v4.address);
memset(mask, 0xff, IPv4off);
hnputl(mask+IPv4off, ~(r->v4.endaddress ^ r->v4.address));
memmove(gate, v4prefix, IPv4off);
memmove(gate+IPv4off, r->v4.gate, IPv4addrlen);
} else {
for(i = 0; i < IPllen; i++){
hnputl(addr + 4*i, r->v6.address[i]);
hnputl(mask + 4*i, ~(r->v6.endaddress[i] ^ r->v6.address[i]));
}
memmove(gate, r->v6.gate, IPaddrlen);
}
memset(t, ' ', 4);
t[4] = 0;
if(r->type & Rv4)
*p++ = '4';
else
*p++ = '6';
if(r->type & Rifc)
*p++ = 'i';
if(r->type & Runi)
*p++ = 'u';
else if(r->type & Rbcast)
*p++ = 'b';
else if(r->type & Rmulti)
*p++ = 'm';
if(r->type & Rptpt)
*p = 'p';
if(r->ifc)
*nifc = r->ifc->conv->x;
else
*nifc = -1;
}
/*
* this code is not in rr to reduce stack size
*/
static void
sprintroute(Route *r, Routewalk *rw)
{
int nifc;
char t[5], *iname, ifbuf[5];
uchar addr[IPaddrlen], mask[IPaddrlen], gate[IPaddrlen];
if(rw->o >= 0) {
convroute(r, addr, mask, gate, t, &nifc);
iname = "-";
if(nifc != -1) {
iname = ifbuf;
sprint(ifbuf, "%d", nifc);
}
sprint(rw->p, rformat, addr, mask, gate, t, r->tag, iname);
rw->p += Rlinelen;
}
rw->o++;
}
/*
* recurse descending tree, applying the function in Routewalk
*/
static int
rr(Route *r, Routewalk *rw)
{
int h;
if(rw->n <= rw->o)
return 0;
if(r == nil)
return 1;
if(rr(r->left, rw) == 0)
return 0;
if(r->type & Rv4)
h = V4H(r->v4.address);
else
h = V6H(r->v6.address);
if(h == rw->h)
rw->walk(r, rw);
if(rr(r->mid, rw) == 0)
return 0;
return rr(r->right, rw);
}
void
ipwalkroutes(Routewalk *rw)
{
rlock(&routelock);
if(rw->n > rw->o) {
for(rw->h = 0; rw->h < nelem(v4root); rw->h++)
if(rr(v4root[rw->h], rw) == 0)
break;
}
if(rw->n > rw->o) {
for(rw->h = 0; rw->h < nelem(v6root); rw->h++)
if(rr(v6root[rw->h], rw) == 0)
break;
}
runlock(&routelock);
}
long
routeread(char *p, ulong offset, int n)
{
Routewalk rw;
if(offset % Rlinelen)
return 0;
rw.p = p;
rw.n = n/Rlinelen;
rw.o = -(offset/Rlinelen);
rw.walk = sprintroute;
ipwalkroutes(&rw);
if(rw.o < 0)
rw.o = 0;
return rw.o*Rlinelen;
}
/*
* this code is not in routeflush to reduce stack size
*/
void
delroute(Route *r)
{
uchar addr[IPaddrlen];
uchar mask[IPaddrlen];
uchar gate[IPaddrlen];
char t[5];
int nifc;
convroute(r, addr, mask, gate, t, &nifc);
if(r->type & Rv4)
v4delroute(addr+IPv4off, mask+IPv4off);
else
v6delroute(addr, mask);
}
/*
* recurse until one route is deleted
* returns 0 if nothing is deleted, 1 otherwise
*/
int
routeflush(Route *r)
{
if(r == nil)
return 0;
if(routeflush(r->mid))
return 1;
if(routeflush(r->left))
return 1;
if(routeflush(r->right))
return 1;
if((r->type & Rifc) == 0){
delroute(r);
return 1;
}
return 0;
}
long
routewrite(Chan *c, char *p, int n)
{
int h;
char *tag;
Cmdbuf *cb;
uchar addr[IPaddrlen];
uchar mask[IPaddrlen];
uchar gate[IPaddrlen];
cb = parsecmd(p, n);
if(waserror()){
free(cb);
nexterror();
}
if(strcmp(cb->f[0], "flush") == 0){
wlock(&routelock);
for(h = 0; h < nelem(v4root); h++)
while(routeflush(v4root[h]) == 1)
;
for(h = 0; h < nelem(v6root); h++)
while(routeflush(v6root[h]) == 1)
;
wunlock(&routelock);
} else if(strcmp(cb->f[0], "remove") == 0){
if(cb->nf < 3)
error(Ebadarg);
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
if(memcmp(addr, v4prefix, IPv4off) == 0)
v4delroute(addr+IPv4off, mask+IPv4off);
else
v6delroute(addr, mask);
} else if(strcmp(cb->f[0], "add") == 0){
if(cb->nf < 4)
error(Ebadarg);
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
parseip(gate, cb->f[3]);
tag = "none";
if(c != nil)
tag = c->tag;
if(memcmp(addr, v4prefix, IPv4off) == 0)
v4addroute(tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
else
v6addroute(tag, addr, mask, gate, 0);
} else if(strcmp(cb->f[0], "tag") == 0) {
if(cb->nf < 2)
error(Ebadarg);
h = strlen(cb->f[1]);
if(h > sizeof(c->tag))
h = sizeof(c->tag);
strncpy(c->tag, cb->f[1], h);
if(h < 4)
memset(c->tag+h, ' ', sizeof(c->tag)-h);
}
poperror();
free(cb);
return n;
}
.
## diffname ip/iproute.c 1998/0310
## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/iproute.c /n/emeliedump/1998/0310/sys/src/brazil/ip/iproute.c
575,590c
routetype(r->type, t);
.
558d
546a
void
routetype(int type, char *p)
{
memset(p, ' ', 4);
p[4] = 0;
if(type & Rv4)
*p++ = '4';
else
*p++ = '6';
if(type & Rifc)
*p++ = 'i';
if(type & Runi)
*p++ = 'u';
else if(type & Rbcast)
*p++ = 'b';
else if(type & Rmulti)
*p++ = 'm';
if(type & Rptpt)
*p = 'p';
}
.
## diffname ip/iproute.c 1998/0313
## diff -e /n/emeliedump/1998/0310/sys/src/brazil/ip/iproute.c /n/emeliedump/1998/0313/sys/src/brazil/ip/iproute.c
781c
v6addroute(f, tag, addr, mask, gate, 0);
.
779c
v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
.
768c
v6delroute(f, addr, mask);
.
766c
v4delroute(f, addr+IPv4off, mask+IPv4off);
.
756,757c
for(h = 0; h < nelem(f->v6root); h++)
while(routeflush(f, f->v6root[h]) == 1)
.
753,754c
for(h = 0; h < nelem(f->v4root); h++)
while(routeflush(f, f->v4root[h]) == 1)
.
736c
routewrite(Fs *f, Chan *c, char *p, int n)
.
729c
delroute(f, r);
.
726c
if(routeflush(f, r->right))
.
724c
if(routeflush(f, r->left))
.
722c
if(routeflush(f, r->mid))
.
718c
routeflush(Fs *f, Route *r)
.
710c
v6delroute(f, addr, mask);
.
708c
v4delroute(f, addr+IPv4off, mask+IPv4off);
.
698c
delroute(Fs *f, Route *r)
.
686c
ipwalkroutes(f, &rw);
.
674c
routeread(Fs *f, char *p, ulong offset, int n)
.
666,667c
for(rw->h = 0; rw->h < nelem(f->v6root); rw->h++)
if(rr(f->v6root[rw->h], rw) == 0)
.
661,662c
for(rw->h = 0; rw->h < nelem(f->v4root); rw->h++)
if(rr(f->v4root[rw->h], rw) == 0)
.
657c
ipwalkroutes(Fs *f, Routewalk *rw)
.
537c
q->ifc = findipifc(f, q->v6.gate, q->type);
.
508c
for(p=f->v6root[V6H(la)]; p;){
.
499c
q = v4lookup(f, a+12);
.
491c
v6lookup(Fs *f, uchar *a)
.
481c
q->ifc = findipifc(f, gate, q->type);
.
469c
for(p=f->v4root[V4H(la)]; p;)
.
461c
v4lookup(Fs *f, uchar *a)
.
457c
ipifcremroute(f, 0, a, mask);
.
448,450c
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v6root[h], p->left);
.
444,446c
addqueue(&f->queue, p->left);
addqueue(&f->queue, p->mid);
addqueue(&f->queue, p->right);
.
440c
r = looknode(&f->v6root[h], &rt);
.
422c
v6delroute(Fs *f, uchar *a, uchar *mask)
.
418c
ipifcremroute(f, Rv4, a, mask);
.
409,411c
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v4root[h], p->left);
.
405,407c
addqueue(&f->queue, p->left);
addqueue(&f->queue, p->mid);
addqueue(&f->queue, p->right);
.
401c
r = looknode(&f->v4root[h], &rt);
.
386c
v4delroute(Fs *f, uchar *a, uchar *mask)
.
354c
ipifcaddroute(f, 0, a, mask, gate, type);
.
345,348c
addnode(f, &f->v6root[h], p);
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v6root[h], p->left);
.
322c
v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
.
316c
ipifcaddroute(f, Rv4, a, mask, gate, type);
.
307,310c
addnode(f, &f->v4root[h], p);
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v4root[h], p->left);
.
286c
v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
.
276c
addnode(f, &p->mid, new);
.
269c
addqueue(&f->queue, p);
.
257c
addnode(f, &p->right, new);
.
254c
addnode(f, &p->left, new);
.
241c
addnode(Fs *f, Route **cur, Route *new)
.
175c
walkadd(f, root, r);
.
173c
walkadd(f, root, l);
.
171c
addnode(f, root, p);
.
163c
walkadd(Fs *f, Route **root, Route *p)
.
20a
/* these are used for all instances of IP */
.
10,18c
static void walkadd(Fs*, Route**, Route*);
static void addnode(Fs*, Route**, Route*);
.
## diffname ip/iproute.c 1998/0316
## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/iproute.c /n/emeliedump/1998/0316/sys/src/brazil/ip/iproute.c
534,535c
q->ifcid = q->ifc->ifcid;
.
530,531c
if(q && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
if(q->type & Rifc) {
hnputl(gate, q->v6.gate[0]);
hnputl(gate+4, q->v6.gate[1]);
hnputl(gate+8, q->v6.gate[2]);
hnputl(gate+12, q->v6.gate[3]);
q->ifc = findipifc(f, gate, q->type);
} else
q->ifc = findipifc(f, q->v6.gate, q->type);
.
490a
uchar gate[IPaddrlen];
.
474c
if(q->type & Rifc) {
hnputl(gate+IPv4off, q->v4.address);
memmove(gate, v4prefix, IPv4off);
} else
v4tov6(gate, q->v4.gate);
.
266c
/*
* supercede the old entry if the old one isn't
* a local interface.
*/
if((p->type & Rifc) == 0){
p->type = new->type;
p->ifcid = -1;
copygate(p, new);
}
.
## diffname ip/iproute.c 1998/0630
## diff -e /n/emeliedump/1998/0316/sys/src/brazil/ip/iproute.c /n/emeliedump/1998/0630/sys/src/brazil/ip/iproute.c
781c
v6delroute(f, addr, mask, 1);
.
779c
v4delroute(f, addr+IPv4off, mask+IPv4off, 1);
.
770,772c
for(changed = 1; changed;){
wlock(&routelock);
changed = routeflush(f, f->v6root[h], tag);
wunlock(&routelock);
}
.
767,768c
for(changed = 1; changed;){
wlock(&routelock);
changed = routeflush(f, f->v4root[h], tag);
wunlock(&routelock);
}
.
765c
tag = cb->f[1];
.
751c
int h, changed;
.
742c
if(tag == nil || strncmp(tag, r->tag, sizeof(r->tag)) == 0)
delroute(f, r, 0);
.
739c
if(routeflush(f, r->right, tag))
.
737c
if(routeflush(f, r->left, tag))
.
735c
if(routeflush(f, r->mid, tag))
.
731c
routeflush(Fs *f, Route *r, char *tag)
.
723c
v6delroute(f, addr, mask, dolock);
.
721c
v4delroute(f, addr+IPv4off, mask+IPv4off, dolock);
.
711c
delroute(Fs *f, Route *r, int dolock)
.
456c
if(dolock)
wunlock(&routelock);
.
441c
if(dolock)
wlock(&routelock);
.
424c
v6delroute(Fs *f, uchar *a, uchar *mask, int dolock)
.
417c
if(dolock)
wunlock(&routelock);
.
402c
if(dolock)
wlock(&routelock);
.
388c
v4delroute(Fs *f, uchar *a, uchar *mask, int dolock)
.
## diffname ip/iproute.c 1998/0701
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/iproute.c /n/emeliedump/1998/0701/sys/src/brazil/ip/iproute.c
748c
return 1;
}
.
746c
if(tag == nil || strncmp(tag, r->tag, sizeof(r->tag)) == 0){
.
## diffname ip/iproute.c 2001/0405
## diff -e /n/emeliedump/1998/0701/sys/src/brazil/ip/iproute.c /n/emeliedump/2001/0405/sys/src/9/ip/iproute.c
810,815c
a = c->aux;
na = newipaux(a->owner, cb->f[1]);
c->aux = na;
free(a);
.
800,801c
if(c != nil){
a = c->aux;
tag = a->tag;
}
.
762a
IPaux *a, *na;
.
## diffname ip/iproute.c 2001/0710
## diff -e /n/emeliedump/2001/0405/sys/src/9/ip/iproute.c /n/emeliedump/2001/0710/sys/src/9/ip/iproute.c
456a
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v6root[h], p->left);
freeroute(p);
}
.
448,455c
if(--(p->ref) == 0){
*r = 0;
addqueue(&f->queue, p->left);
addqueue(&f->queue, p->mid);
addqueue(&f->queue, p->right);
.
415a
while(p = f->queue) {
f->queue = p->mid;
walkadd(f, &f->v4root[h], p->left);
freeroute(p);
}
.
407,414c
if(--(p->ref) == 0){
*r = 0;
addqueue(&f->queue, p->left);
addqueue(&f->queue, p->mid);
addqueue(&f->queue, p->right);
.
274c
} else if(new->type & Rifc)
p->ref++;
.
59a
r->ref = 1;
.
## diffname ip/iproute.c 2001/1120
## diff -e /n/emeliedump/2001/0710/sys/src/9/ip/iproute.c /n/emeliedump/2001/1120/sys/src/9/ip/iproute.c
818a
case RWtag:
.
800,817c
break;
.
791,793c
break;
case RWremove:
.
777c
ct = lookupcmd(cb, routecmd, nelem(routecmd));
switch(ct->index){
case RWadd:
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
parseip(gate, cb->f[3]);
tag = "none";
if(c != nil){
a = c->aux;
tag = a->tag;
}
if(memcmp(addr, v4prefix, IPv4off) == 0)
v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
else
v6addroute(f, tag, addr, mask, gate, 0);
break;
case RWflush:
.
765a
Cmdtab *ct;
.
18a
enum
{
RWadd,
RWflush,
RWremove,
RWtag,
};
static
Cmdtab routecmd[] = {
RWadd, "add", 4,
RWflush, "flush", 2,
RWremove, "remove", 3,
RWtag, "tag", 2,
};
.
## diffname ip/iproute.c 2002/0507
## diff -e /n/emeliedump/2001/1120/sys/src/9/ip/iproute.c /n/emeliedump/2002/0507/sys/src/9/ip/iproute.c
837d
835c
} else if(strcmp(cb->f[0], "add") == 0){
if(cb->nf < 4)
error(Ebadarg);
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
parseip(gate, cb->f[3]);
tag = "none";
if(c != nil){
a = c->aux;
tag = a->tag;
}
if(memcmp(addr, v4prefix, IPv4off) == 0)
v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
else
v6addroute(f, tag, addr, mask, gate, 0);
} else if(strcmp(cb->f[0], "tag") == 0) {
if(cb->nf < 2)
error(Ebadarg);
.
826,828c
} else if(strcmp(cb->f[0], "remove") == 0){
if(cb->nf < 3)
error(Ebadarg);
.
794,812c
if(strcmp(cb->f[0], "flush") == 0){
.
782d
612c
char *rformat = "%-40.40I %-40.40M %-40.40I %4.4s %4.4s %3s\n";
.
609c
Rlinelen= 137,
.
571,574c
for(h = 0; h < IPllen; h++)
hnputl(gate+4*h, q->v6.address[h]);
.
531,532c
if(memcmp(a, v4prefix, IPv4off) == 0){
q = v4lookup(f, a+IPv4off);
.
348a
/*
if(ISDFLT(a, mask, tag))
f->v6p->cdrouter = -1;
*/
.
339a
#define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0))
.
19,34d
## diffname ip/iproute.c 2003/0308
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/iproute.c /n/emeliedump/2003/0308/sys/src/9/ip/iproute.c
569a
}
if(c != nil){
c->r = q;
c->rgen = v6routegeneration;
.
527a
if(c != nil && c->r != nil && c->rgen == v6routegeneration)
return c->r;
.
523c
q = v4lookup(f, a+IPv4off, c);
.
514c
v6lookup(Fs *f, uchar *a, Conv *c)
.
508a
if(c != nil){
c->r = q;
c->rgen = v4routegeneration;
}
.
485a
if(c != nil && c->r != nil && c->rgen == v4routegeneration)
return c->r;
.
480c
v4lookup(Fs *f, uchar *a, Conv *c)
.
474a
v6routegeneration++;
.
431a
v4routegeneration++;
.
363a
v6routegeneration++;
.
318a
v4routegeneration++;
.
17a
ulong v4routegeneration, v6routegeneration;
.
## diffname ip/iproute.c 2003/0314
## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/iproute.c /n/emeliedump/2003/0314/sys/src/9/ip/iproute.c
584c
q->ifc = ifc;
q->ifcid = ifc->ifcid;
.
581,582c
ifc = findipifc(f, q->v6.gate, q->type);
if(ifc == nil)
.
579c
ifc = findipifc(f, gate, q->type);
.
540c
if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v6routegeneration)
.
532a
Ipifc *ifc;
.
516a
.
515c
q->ifc = ifc;
q->ifcid = ifc->ifcid;
.
512,513c
ifc = findipifc(f, gate, q->type);
if(ifc == nil)
.
491c
if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v4routegeneration)
.
489a
Ipifc *ifc;
.
## diffname ip/iproute.c 2003/0404
## diff -e /n/emeliedump/2003/0314/sys/src/9/ip/iproute.c /n/emeliedump/2003/0404/sys/src/9/ip/iproute.c
740,743c
return rw.p - p;
.
734,735c
rw.e = p+n;
rw.o = -offset;
.
730,732d
717c
if(rw->e > rw->p) {
.
712c
if(rw->e > rw->p) {
.
686c
if(rw->e <= rw->p)
.
675c
p = seprint(rw->p, rw->e, rformat, addr, mask, gate, t, r->tag, iname);
if(rw->o < 0){
n = p - rw->p;
if(n > -rw->o){
memmove(rw->p, rw->p-rw->o, n+rw->o);
rw->p = p + rw->o;
}
rw->o += n;
} else
rw->p = p;
.
665,673c
convroute(r, addr, mask, gate, t, &nifc);
iname = "-";
if(nifc != -1) {
iname = ifbuf;
sprint(ifbuf, "%d", nifc);
.
663a
char *p;
.
661c
int nifc, n;
.
625,626d
620,623c
char *rformat = "%-15I %-4M %-15I %4.4s %4.4s %3s\n";
.
|