FreeBSD/sys/netnatm/natm_pcb.c
/*
 * npcb_add: add or remove npcb from main list
 *   returns npcb if ok
 */
add or remove npcb from main list
returns npcb if ok
add or remove npcb from main list returns npcb if ok
struct natmpcb *
npcb_add(struct natmpcb *npcb, struct ifnet *ifp, u_int16_t vci, u_int8_t vpi)
{
	struct natmpcb *cpcb = NULL;		
	NATM_LOCK_ASSERT();
	LIST_FOREACH(cpcb, &natm_pcbs, pcblist)
		if (ifp == cpcb->npcb_ifp && vci == cpcb->npcb_vci &&
		    vpi == cpcb->npcb_vpi)
			break;
	if (cpcb) {
		cpcb = NULL;
		goto done;			
	}
	if (npcb == NULL) {
		cpcb = npcb_alloc(M_NOWAIT);
		if (cpcb == NULL) 
			goto done;			
	} else {
		cpcb = npcb;
	}
	cpcb->npcb_ifp = ifp;
	cpcb->ipaddr.s_addr = 0;
	cpcb->npcb_vci = vci;
	cpcb->npcb_vpi = vpi;
	cpcb->npcb_flags = NPCB_CONNECTED;
	LIST_INSERT_HEAD(&natm_pcbs, cpcb, pcblist);
done:
	return (cpcb);
}
struct natmpcb * npcb_add ( struct natmpcb * npcb , struct ifnet * ifp , u_int16_t vci , u_int8_t vpi ) { struct natmpcb * cpcb = NULL ; NATM_LOCK_ASSERT ( ) ; LIST_FOREACH ( cpcb , & natm_pcbs , pcblist ) if ( ifp == cpcb -> npcb_ifp && vci == cpcb -> npcb_vci && vpi == cpcb -> npcb_vpi ) break ; if ( cpcb ) { cpcb = NULL ; goto done ; } if ( npcb == NULL ) { cpcb = npcb_alloc ( M_NOWAIT ) ; if ( cpcb == NULL ) goto done ; } else { cpcb = npcb ; } cpcb -> npcb_ifp = ifp ; cpcb -> ipaddr . s_addr = 0 ; cpcb -> npcb_vci = vci ; cpcb -> npcb_vpi = vpi ; cpcb -> npcb_flags = NPCB_CONNECTED ; LIST_INSERT_HEAD ( & natm_pcbs , cpcb , pcblist ) ; done : return ( cpcb ) ; }
npcb_add: add or remove npcb from main list
   returns npcb if ok
npcb_add : add or remove npcb from main list returns npcb if ok
/* current pcb */ /*
	 * lookup required
	 */ /*
	 * add & something already there?
	 */ /* fail */ /*
	 * need to allocate a pcb?
	 */ /* could be called from lower half */ /* fail */