/* * attach a device (or pkt driver) to the interface. * called with c locked */ static char* ipifcbind(Conv *c, char **argv, int argc) { Ipifc *ifc; Medium *m; if(argc < 2) return Ebadarg; ifc = (Ipifc*)c->ptcl; /* bind the device to the interface */ m = ipfindmedium(argv[1]); if(m == nil) return "unknown interface type"; wlock(ifc); if(ifc->m != nil) { wunlock(ifc); return "interface already bound"; } if(waserror()) { wunlock(ifc); nexterror(); } /* do medium specific binding */ (*m->bind)(ifc, argc, argv); /* set the bound device name */ if(argc > 2) strncpy(ifc->dev, argv[2], sizeof(ifc->dev)); else snprint(ifc->dev, sizeof ifc->dev, "%s%d", m->name, c->x); ifc->dev[sizeof(ifc->dev)-1] = 0; /* set up parameters */ ifc->m = m; ifc->mintu = ifc->m->mintu; ifc->maxtu = ifc->m->maxtu; if(ifc->m->unbindonclose == 0) ifc->conv->inuse++; ifc->rp.mflag = 0; /* default not managed */ ifc->rp.oflag = 0; ifc->rp.maxraint = 600000; /* millisecs */ ifc->rp.minraint = 200000; ifc->rp.linkmtu = 0; /* no mtu sent */ ifc->rp.reachtime = 0; ifc->rp.rxmitra = 0; ifc->rp.ttl = MAXTTL; ifc->rp.routerlt = 3 * ifc->rp.maxraint; /* any ancillary structures (like routes) no longer pertain */ ifc->ifcid++; /* reopen all the queues closed by a previous unbind */ qreopen(c->rq); qreopen(c->eq); qreopen(c->sq); wunlock(ifc); poperror(); return nil; }
/* * called with protocol locked */ Conv* Fsprotoclone(Proto *p, char *user) { Conv *c, **pp, **ep; retry: c = nil; ep = &p->conv[p->nc]; for(pp = p->conv; pp < ep; pp++) { c = *pp; if(c == nil){ c = malloc(sizeof(Conv)); if(c == nil) error(Enomem); qlock(c); c->p = p; c->x = pp - p->conv; if(p->ptclsize != 0){ c->ptcl = malloc(p->ptclsize); if(c->ptcl == nil) { free(c); error(Enomem); } } *pp = c; p->ac++; c->eq = qopen(1024, Qmsg, 0, 0); (*p->create)(c); break; } if(canqlock(c)){ /* * make sure both processes and protocol * are done with this Conv */ if(c->inuse == 0 && (p->inuse == nil || (*p->inuse)(c) == 0)) break; qunlock(c); } } if(pp >= ep) { if(p->gc) print("Fsprotoclone: garbage collecting Convs\n"); if(p->gc != nil && (*p->gc)(p)) goto retry; /* debugging: do we ever get here? */ if (cpuserver) panic("Fsprotoclone: all conversations in use"); return nil; } c->inuse = 1; kstrdup(&c->owner, user); c->perm = 0660; c->state = Idle; ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); c->r = nil; c->rgen = 0; c->lport = 0; c->rport = 0; c->restricted = 0; c->maxfragsize = 0; c->ttl = MAXTTL; qreopen(c->rq); qreopen(c->wq); qreopen(c->eq); qunlock(c); return c; }