Example #1
0
/*
 *  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;
}
Example #2
0
/*
 *  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;
}