devether: mux bridges, portable netconsole

This commit is contained in:
cinap_lenrek 2018-02-18 19:56:01 +01:00
parent a2e8246ffc
commit 729c9c39d9
39 changed files with 192 additions and 173 deletions

View file

@ -643,7 +643,7 @@ receive(Ether *ether)
* in memory (mv-s104860-u0 §8.3.4.1)
*/
b->rp += 2;
etheriq(ether, b, 1);
etheriq(ether, b);
etheractive(ether);
if (i % (Nrx / 2) == 0) {
rxreplenish(ctlr);

View file

@ -468,7 +468,7 @@ interrupt(Ureg*, void* arg)
else if(bp = iallocb(Rbsz)){
len = ((des->status & Fl)>>16)-4;
des->bp->wp = des->bp->rp+len;
etheriq(ether, des->bp, 1);
etheriq(ether, des->bp);
des->bp = bp;
des->addr = PCIWADDR(bp->rp);
}

View file

@ -642,7 +642,7 @@ smcreceive(Ether *edev)
/* and push the Block upstream */
if (ctlr->inited)
etheriq(edev, bp, 1);
etheriq(edev, bp);
else
freeb(bp);

View file

@ -477,7 +477,7 @@ interrupt(Ureg*, void* arg)
else if(bp = iallocb(Rbsz)){
len = ((des->status & Fl)>>16)-4;
des->bp->wp = des->bp->rp+len;
etheriq(ether, des->bp, 1);
etheriq(ether, des->bp);
des->bp = bp;
des->addr = PCIWADDR(bp->rp);
}

View file

@ -424,7 +424,7 @@ intrloop:
if(bb != nil){
len = (dre->md2 & 0x0FFF)-4;
bb->wp = bb->rp+len;
etheriq(ether, bb, 1);
etheriq(ether, bb);
}
dre->addr = PADDR(bp->rp);
}

View file

@ -583,7 +583,7 @@ rtl8139receive(Ether* edev)
bp->wp += length;
}
bp->wp -= 4;
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
capr = ROUNDUP(capr, 4);

View file

@ -970,7 +970,7 @@ rtl8169receive(Ether* edev)
bp->flag |= Bipck;
break;
}
etheriq(edev, bp, 1);
etheriq(edev, bp);
}else{
if(!(control & Res))
ctlr->frag++;

View file

@ -851,7 +851,7 @@ gc82543recv(Ether* edev, int icr)
ctlr->rb[rdh] = nil;
bp->wp += rdesc->length;
bp->next = nil;
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
if(ctlr->rb[rdh] != nil){

View file

@ -655,7 +655,7 @@ receive(Ether* ether)
bp = xbp;
}
if(pbp != nil)
etheriq(ether, pbp, 1);
etheriq(ether, pbp);
}
else{
rfd->count = 0;

View file

@ -1062,7 +1062,7 @@ i82563rproc(void *arg)
bp->checksum = rd->checksum;
bp->flag |= Bpktck;
}
etheriq(edev, bp, 1);
etheriq(edev, bp);
} else
freeb(bp);
ctlr->rb[rdh] = nil;

View file

@ -584,7 +584,7 @@ loop1:
b->checksum = r->cksum;
}
// r->status = 0;
etheriq(e, b, 1);
etheriq(e, b);
c->rdfree--;
rdh = Next(rdh, m);
goto loop1; /* UGH */

View file

@ -545,7 +545,7 @@ interrupt(Ureg*, void* arg)
freeb(des->bp);
}else{
des->bp->wp = des->bp->rp+len;
etheriq(ether, des->bp, 1);
etheriq(ether, des->bp);
}
des->bp = bp;
des->addr = PADDR(bp->rp);

View file

@ -439,7 +439,7 @@ receive(Ether* ether)
/*
* Copy the packet to whoever wants it.
*/
etheriq(ether, bp, 1);
etheriq(ether, bp);
}
/*

View file

@ -414,7 +414,7 @@ bcmreceive(Ether *edev)
if(pkt[3] & FrameError) {
freeb(bp); /* dump erroneous packets */
} else {
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
}
}

View file

@ -839,7 +839,7 @@ dp83820interrupt(Ureg*, void* arg)
bp = desc->bp;
desc->bp = nil;
bp->wp += cmdsts & SizeMASK;
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
else if(0 && !(cmdsts & Ok)){
iprint("dp83820: rx %8.8uX:", cmdsts);

View file

@ -834,7 +834,7 @@ receive905(Ether* ether)
else if(bp = iallocb(sizeof(Etherpkt)+4)){
len = pd->control & rxBytes;
pd->bp->wp = pd->bp->rp+len;
etheriq(ether, pd->bp, 1);
etheriq(ether, pd->bp);
pd->bp = bp;
pd->addr = PADDR(bp->rp);
coherence();
@ -944,7 +944,7 @@ receive(Ether* ether)
if(ctlr->busmaster == 1)
ctlr->rbp->wp = startdma(ether, PADDR(bp->rp));
etheriq(ether, ctlr->rbp, 1);
etheriq(ether, ctlr->rbp);
ctlr->rbp = bp;
}
}

View file

@ -626,7 +626,7 @@ ga620receive(Ether* edev)
if(!(rbd->flags & Ferror) && len != 0){
bp = rbd->opaque;
bp->wp = bp->rp+len;
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
else
freeb(rbd->opaque);

View file

@ -1142,7 +1142,7 @@ igberproc(void* arg)
bp->checksum = rd->checksum;
bp->flag |= Bpktck;
}
etheriq(edev, bp, 1);
etheriq(edev, bp);
}
else if(ctlr->rb[rdh] != nil){
freeb(ctlr->rb[rdh]);

View file

@ -1087,7 +1087,7 @@ m10rx(void *v)
replenish(&c->bg);
sleep(&c->rxrendez, rxcansleep, c);
while(b = nextblock(c))
etheriq(e, b, 1);
etheriq(e, b);
}
}

View file

@ -405,7 +405,7 @@ receive(Ether* ether)
bp->wp++;
}
etheriq(ether, bp, 1);
etheriq(ether, bp);
ether->inpackets++;
outs(port + MmuCmd, McRelease);
}

View file

@ -531,7 +531,7 @@ vgberxeof(Ether* edev)
/* plant new block, might fail if out of memory */
if(vgbenewrx(ctlr, i) == 0){
block->wp = block->rp + length;
etheriq(edev, block, 1);
etheriq(edev, block);
continue;
}
}

View file

@ -325,7 +325,7 @@ rxproc(void *v)
blocks[i] = nil;
b->wp = b->rp + u->len - VheaderSize;
etheriq(edev, b, 1);
etheriq(edev, b);
q->lastused++;
}
}

View file

@ -720,7 +720,7 @@ vt6102receive(Ether* edev)
else if(bp = iallocb(Rdbsz+3)){
len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
ds->bp->wp = ds->bp->rp+len;
etheriq(edev, ds->bp, 1);
etheriq(edev, ds->bp);
bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
ds->addr = PCIWADDR(bp->rp);
ds->bp = bp;

View file

@ -865,7 +865,7 @@ vt6105Mreceive(Ether* edev)
}
len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
ds->bp->wp = ds->bp->rp+len;
etheriq(edev, ds->bp, 1);
etheriq(edev, ds->bp);
bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
ds->addr = PCIWADDR(bp->rp);
ds->bp = bp;

View file

@ -1430,7 +1430,7 @@ rx(Ether *e, uint l, uint x, uint flag)
}else{
b->wp += l;
b->flag |= flag;
etheriq(e, b, 1);
etheriq(e, b);
}
unstarve(&c->rxmit);
}

View file

@ -113,7 +113,6 @@ char* mtrr(uvlong, uvlong, char *);
void mtrrclock(void);
int mtrrprint(char *, long);
void mtrrsync(void);
void netconsole(void);
uchar nvramread(int);
void nvramwrite(int, uchar);
void outb(int, int);

View file

@ -60,7 +60,6 @@ main(void)
}else
links();
chandevreset();
netconsole();
pageinit();
userinit();
schedinit();

View file

@ -452,7 +452,7 @@ w_rxdone(Ether* ether)
}
ctlr->nrx++;
etheriq(ether,bp,1);
etheriq(ether, bp);
ctlr->signal = ((ctlr->signal*15)+((f.qinfo>>8) & 0xFF))/16;
ctlr->noise = ((ctlr->noise*15)+(f.qinfo & 0xFF))/16;
return;

View file

@ -111,7 +111,6 @@ char* mtrr(uvlong, uvlong, char *);
void mtrrclock(void);
int mtrrprint(char *, long);
void mtrrsync(void);
void netconsole(void);
void noteret(void);
uchar nvramread(int);
void nvramwrite(int, uchar);

View file

@ -329,7 +329,6 @@ main()
}else
links();
chandevreset();
netconsole();
preallocpages();
pageinit();
userinit();

View file

@ -11,6 +11,7 @@
#include "../port/etherif.h"
extern int eipfmt(Fmt*);
extern ushort ipcsum(uchar *);
static Ether *etherxx[MaxEther];
@ -70,7 +71,12 @@ ethercreate(Chan*, char*, int, ulong)
static void
etherclose(Chan* chan)
{
netifclose(etherxx[chan->dev], chan);
Ether *ether = etherxx[chan->dev];
if(NETTYPE(chan->qid.path) == Ndataqid && ether->f[NETID(chan->qid.path)]->bridge)
memset(ether->mactab, 0, sizeof(ether->mactab));
netifclose(ether, chan);
}
static long
@ -109,152 +115,154 @@ etherwstat(Chan* chan, uchar* dp, int n)
static void
etherrtrace(Netfile* f, Etherpkt* pkt, int len)
{
int i, n;
Block *bp;
if(qwindow(f->in) <= 0)
return;
if(len > 58)
n = 58;
else
n = len;
bp = iallocb(64);
if(bp == nil)
return;
memmove(bp->wp, pkt->d, n);
i = TK2MS(MACHP(0)->ticks);
bp->wp[58] = len>>8;
bp->wp[59] = len;
bp->wp[60] = i>>24;
bp->wp[61] = i>>16;
bp->wp[62] = i>>8;
bp->wp[63] = i;
memmove(bp->wp, pkt, len < 64 ? len : 64);
if(f->type != -2){
u32int ms = TK2MS(MACHP(0)->ticks);
bp->wp[58] = len>>8;
bp->wp[59] = len;
bp->wp[60] = ms>>24;
bp->wp[61] = ms>>16;
bp->wp[62] = ms>>8;
bp->wp[63] = ms;
}
bp->wp += 64;
qpass(f->in, bp);
}
Block*
etheriq(Ether* ether, Block* bp, int fromwire)
static Macent*
macent(Ether *ether, uchar *ea)
{
u32int h = (ea[0] | ea[1]<<8 | ea[2]<<16 | ea[3]<<24) ^ (ea[4] | ea[5]<<8);
return &ether->mactab[h % nelem(ether->mactab)];
}
/*
* Multiplex the packet to all the connections which want it.
* If the packet is not to be used subsequently (tome || from == nil),
* attempt to simply pass it into one of the connections, thereby
* saving a copy of the data (usual case hopefully).
*/
static Block*
ethermux(Ether *ether, Block *bp, Netfile **from)
{
Etherpkt *pkt;
ushort type;
int len, multi, tome, fromme;
Netfile **ep, *f, **fp, *fx;
Block *xbp;
Etherpkt *pkt;
Netfile *f, *x, **fp;
int len, multi, tome, port, type, dispose;
ether->inpackets++;
pkt = (Etherpkt*)bp->rp;
len = BLEN(bp);
type = (pkt->type[0]<<8)|pkt->type[1];
fx = 0;
ep = &ether->f[Ntypes];
multi = pkt->d[0] & 1;
/* check for valid multicast addresses */
if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
if(fromwire){
freeb(bp);
bp = 0;
}
if(len < ETHERHDRSIZE)
goto Drop;
pkt = (Etherpkt*)bp->rp;
if(!(multi = pkt->d[0] & 1)){
tome = memcmp(pkt->d, ether->ea, Eaddrlen) == 0;
if(!tome && from != nil && ether->prom == 0)
return bp;
} else {
tome = 0;
if(from == nil && ether->prom == 0
&& memcmp(pkt->d, ether->bcast, Eaddrlen) != 0
&& !activemulti(ether, pkt->d, Eaddrlen))
goto Drop;
}
port = -1;
if(ether->prom){
if((from == nil || (*from)->bridge) && (pkt->s[0] & 1) == 0){
Macent *t = macent(ether, pkt->s);
t->port = from == nil ? 0 : 1+(from - ether->f);
memmove(t->ea, pkt->s, Eaddrlen);
}
if(!tome && !multi){
Macent *t = macent(ether, pkt->d);
if(memcmp(t->ea, pkt->d, Eaddrlen) == 0)
port = t->port;
}
}
/* is it for me? */
tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
x = nil;
type = (pkt->type[0]<<8)|pkt->type[1];
dispose = tome || from == nil || port > 0;
/*
* Multiplex the packet to all the connections which want it.
* If the packet is not to be used subsequently (fromwire != 0),
* attempt to simply pass it into one of the connections, thereby
* saving a copy of the data (usual case hopefully).
*/
for(fp = ether->f; fp < ep; fp++){
if(f = *fp)
if(f->type == type || f->type < 0)
if(tome || multi || f->prom){
/* Don't want to hear loopback or bridged packets */
if(f->bridge && (tome || !fromwire && !fromme))
for(fp = ether->f; fp < &ether->f[Ntypes]; fp++){
if((f = *fp) == nil)
continue;
if(f->type != type && f->type >= 0)
continue;
if(!tome && !multi && !f->prom)
continue;
if(f->bridge){
if(tome || fp == from)
continue;
if(port >= 0 && port != 1+(fp - ether->f))
continue;
if(!f->headersonly){
if(fromwire && fx == 0)
fx = f;
else if(xbp = iallocb(len)){
memmove(xbp->wp, pkt, len);
xbp->wp += len;
xbp->flag = bp->flag;
if(qpass(f->in, xbp) < 0) {
// print("soverflow for f->in\n");
ether->soverflows++;
}
}
else {
// print("soverflow iallocb\n");
ether->soverflows++;
}
}
else
etherrtrace(f, pkt, len);
}
}
if(fx){
if(qpass(fx->in, bp) < 0) {
// print("soverflow for fx->in\n");
if(f->headersonly || f->type == -2){
etherrtrace(f, pkt, len);
continue;
}
if(dispose && x == nil)
x = f;
else if((xbp = iallocb(len)) != nil){
memmove(xbp->wp, pkt, len);
xbp->wp += len;
xbp->flag = bp->flag;
if(qpass(f->in, xbp) < 0)
ether->soverflows++;
} else
ether->soverflows++;
}
return 0;
}
if(fromwire){
freeb(bp);
return 0;
if(x != nil){
if(qpass(x->in, bp) < 0)
ether->soverflows++;
return nil;
}
if(dispose){
Drop: freeb(bp);
return nil;
}
return bp;
}
static int
etheroq(Ether* ether, Block* bp)
void
etheriq(Ether* ether, Block* bp)
{
int len, loopback;
Etherpkt *pkt;
ether->inpackets++;
ethermux(ether, bp, nil);
}
static void
etheroq(Ether* ether, Block* bp, Netfile **from)
{
if((*from)->bridge == 0)
memmove(((Etherpkt*)bp->rp)->s, ether->ea, Eaddrlen);
bp = ethermux(ether, bp, from);
if(bp == nil)
return;
ether->outpackets++;
/*
* Check if the packet has to be placed back onto the input queue,
* i.e. if it's a loopback or broadcast packet or the interface is
* in promiscuous mode.
* If it's a loopback packet indicate to etheriq that the data isn't
* needed and return, etheriq will pass-on or free the block.
* To enable bridging to work, only packets that were originated
* by this interface are fed back.
*/
pkt = (Etherpkt*)bp->rp;
len = BLEN(bp);
loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom)
if(etheriq(ether, bp, loopback) == 0)
return len;
qbwrite(ether->oq, bp);
if(ether->transmit != nil)
ether->transmit(ether);
return len;
}
static long
etherwrite(Chan* chan, void* buf, long n, vlong)
{
Ether *ether;
Ether *ether = etherxx[chan->dev];
Block *bp;
int nn, onoff;
Cmdbuf *cb;
ether = etherxx[chan->dev];
if(NETTYPE(chan->qid.path) != Ndataqid) {
nn = netifwrite(ether, chan, buf, n);
if(nn >= 0)
@ -287,21 +295,19 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
nexterror();
}
memmove(bp->rp, buf, n);
if(!ether->f[NETID(chan->qid.path)]->bridge)
memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
poperror();
bp->wp += n;
return etheroq(ether, bp);
etheroq(ether, bp, &ether->f[NETID(chan->qid.path)]);
return n;
}
static long
etherbwrite(Chan* chan, Block* bp, ulong)
{
Ether *ether;
long n;
long n = BLEN(bp);
n = BLEN(bp);
if(NETTYPE(chan->qid.path) != Ndataqid){
if(waserror()) {
freeb(bp);
@ -312,8 +318,8 @@ etherbwrite(Chan* chan, Block* bp, ulong)
freeb(bp);
return n;
}
ether = etherxx[chan->dev];
ether = etherxx[chan->dev];
if(n > ether->maxmtu){
freeb(bp);
error(Etoobig);
@ -322,8 +328,8 @@ etherbwrite(Chan* chan, Block* bp, ulong)
freeb(bp);
error(Etoosmall);
}
return etheroq(ether, bp);
etheroq(ether, bp, &ether->f[NETID(chan->qid.path)]);
return n;
}
static struct {
@ -422,6 +428,8 @@ etherprobe(int cardno, int ctlrno)
return ether;
}
static void netconsole(int);
static void
etherreset(void)
{
@ -436,22 +444,23 @@ etherreset(void)
etherxx[ctlrno] = ether;
}
if(getconf("*noetherprobe"))
return;
cardno = ctlrno = 0;
while(cards[cardno].type != nil && ctlrno < MaxEther){
if(etherxx[ctlrno] != nil){
if(getconf("*noetherprobe") == nil){
cardno = ctlrno = 0;
while(cards[cardno].type != nil && ctlrno < MaxEther){
if(etherxx[ctlrno] != nil){
ctlrno++;
continue;
}
if((ether = etherprobe(cardno, ctlrno)) == nil){
cardno++;
continue;
}
etherxx[ctlrno] = ether;
ctlrno++;
continue;
}
if((ether = etherprobe(cardno, ctlrno)) == nil){
cardno++;
continue;
}
etherxx[ctlrno] = ether;
ctlrno++;
}
netconsole(1);
}
static void
@ -460,6 +469,8 @@ ethershutdown(void)
Ether *ether;
int i;
netconsole(0);
for(i = 0; i < MaxEther; i++){
ether = etherxx[i];
if(ether == nil)
@ -524,9 +535,7 @@ struct Netconsole {
};
static Netconsole *netcons;
extern ushort ipcsum(uchar *);
void
static void
netconsputc(Uart *, int c)
{
char *p;
@ -556,13 +565,11 @@ netconsputc(Uart *, int c)
netcons->ether->transmit(netcons->ether);
}
PhysUart netconsphys = {
.putc = netconsputc,
};
Uart netconsuart = { .phys = &netconsphys };
static PhysUart netconsphys = { .putc = netconsputc };
static Uart netconsuart = { .phys = &netconsphys };
void
netconsole(void)
static void
netconsole(int on)
{
char *p;
char *r;
@ -572,8 +579,15 @@ netconsole(void)
u64int dstmac;
Netconsole *nc;
if(!on){
if(consuart == &netconsuart)
consuart = nil;
return;
}
if((p = getconf("console")) == nil || strncmp(p, "net ", 4) != 0)
return;
p += 4;
for(i = 0; i < 4; i++){
srcip[i] = strtol(p, &r, 0);

View file

@ -3,6 +3,13 @@ enum {
Ntypes = 8,
};
typedef struct Macent Macent;
struct Macent
{
uchar ea[Eaddrlen];
ushort port;
};
typedef struct Ether Ether;
struct Ether {
ISAConf; /* hardware info */
@ -11,7 +18,6 @@ struct Ether {
int ctlrno;
int minmtu;
int maxmtu;
uchar ea[Eaddrlen];
void (*attach)(Ether*); /* filled in by reset routine */
void (*detach)(Ether*);
@ -25,9 +31,12 @@ struct Ether {
Queue* oq;
Netif;
uchar ea[Eaddrlen];
Macent mactab[127]; /* for bridge */
};
extern Block* etheriq(Ether*, Block*, int);
extern void etheriq(Ether*, Block*);
extern void addethercard(char*, int(*)(Ether*));
extern ulong ethercrc(uchar*, int);
extern int parseether(uchar*, char*);

View file

@ -139,7 +139,7 @@ wifiiq(Wifi *wifi, Block *b)
dmatproxy(b, 0, wifi->ether->ea, &wifi->dmat);
etheriq(wifi->ether, b, 1);
etheriq(wifi->ether, b);
return;
}
drop:

View file

@ -367,7 +367,7 @@ interrupt(Ureg*, void *arg)
dczap(b->rp, len);
if(nb = iallocb(Bufsize)){
b->wp += len;
etheriq(ether, b, 1);
etheriq(ether, b);
b = nb;
b->rp = (uchar*)(((ulong)b->rp + CACHELINESZ-1) & ~(CACHELINESZ-1));
b->wp = b->rp;

View file

@ -176,7 +176,7 @@ interrupt(Ureg*, void*arg)
memmove(b->wp, pkt, len+sizeof(ushort));
b->rp += sizeof(ushort);
b->wp = b->rp + len;
etheriq(ether, b, 1);
etheriq(ether, b);
}else
ether->soverflows++;
rx=*ersr&Ersr_rxfpmask;

View file

@ -250,7 +250,7 @@ rxproc(void *arg)
b = allocb(n);
b->wp += n;
memmove(b->rp, p->base+2, n);
etheriq(edev, b, 1);
etheriq(edev, b);
}
p->addr = PADDR(p->base);
p->count = Ioc|Empty|Rbsize;

View file

@ -828,7 +828,7 @@ qpkt(Ether *edev, int rdh, ulong control)
allcache->invse(bp->rp, len); /* clear any stale cached packet */
ckrderrs(ctlr, bp, control);
etheriq(edev, bp, 1);
etheriq(edev, bp);
if(Debug > 1)
iprint("R%d ", len);

View file

@ -248,7 +248,7 @@ vifrecvdone(Ether *ether, netif_rx_response_t *rr)
bp->list = 0;
if (rr->flags & NETRXF_data_validated)
bp->flag |= Btcpck|Budpck;
etheriq(ether, bp, 1);
etheriq(ether, bp);
return 0;
}

View file

@ -235,7 +235,7 @@ ethrx(Ether *edev)
bp->wp = bp->rp + (r[1] & 0x1fff);
invaldse(bp->rp, bp->wp);
inval2pa(PADDR(bp->rp), PADDR(bp->wp));
etheriq(edev, bp, 1);
etheriq(edev, bp);
c->rxconsi = (c->rxconsi + 1) & (RXRING - 1);
replenish(c);
}