x0 = afinfo->state_lookup(&tmpl->id.daddr, tmpl->id.spi, tmpl->id.proto); if (x0 != NULL) { 
if (tmpl->id.spi && (x0 = afinfo->state_lookup(daddr, tmpl->id.spi, tmpl->id.proto)) != NULL) { 
xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 		struct flowi *fl, struct xfrm_tmpl *tmpl,		struct xfrm_policy *pol, int *err,		unsigned short family){	unsigned h = xfrm_dst_hash(daddr, family);	struct xfrm_state *x, *x0;	int acquire_in_progress = 0;	int error = 0;	struct xfrm_state *best = NULL;	struct xfrm_state_afinfo *afinfo;		afinfo = xfrm_state_get_afinfo(family);	if (afinfo == NULL) {		*err = -EAFNOSUPPORT;		return NULL;	}	spin_lock_bh(&xfrm_state_lock);	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {		if (x->props.family == family &&		    x->props.reqid == tmpl->reqid &&		    xfrm_state_addr_check(x, daddr, saddr, family) &&		    tmpl->mode == x->props.mode &&		    tmpl->id.proto == x->id.proto &&		    (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) {			/* Resolution logic:			   1. There is a valid state with matching selector.			      Done.			   2. Valid state with inappropriate selector. Skip.			   Entering area of "sysdeps".			   3. If state is not valid, selector is temporary,			      it selects only session which triggered			      previous resolution. Key manager will do			      something to install a state with proper			      selector.			 */			if (x->km.state == XFRM_STATE_VALID) {				if (!xfrm_selector_match(&x->sel, fl, family))					continue;				if (!best ||				    best->km.dying > x->km.dying ||				    (best->km.dying == x->km.dying &&				     best->curlft.add_time < x->curlft.add_time))					best = x;			} else if (x->km.state == XFRM_STATE_ACQ) {				acquire_in_progress = 1;			} else if (x->km.state == XFRM_STATE_ERROR ||				   x->km.state == XFRM_STATE_EXPIRED) {				if (xfrm_selector_match(&x->sel, fl, family))					error = -ESRCH;			}		}	}	x = best;	if (!x && !error && !acquire_in_progress) {		x0 = afinfo->state_lookup(&tmpl->id.daddr, tmpl->id.spi, tmpl->id.proto);		if (x0 != NULL) {			xfrm_state_put(x0);			error = -EEXIST;			goto out;		}		x = xfrm_state_alloc();		if (x == NULL) {			error = -ENOMEM;			goto out;		}		/* Initialize temporary selector matching only		 * to current session. */		xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);		if (km_query(x, tmpl, pol) == 0) {			x->km.state = XFRM_STATE_ACQ;			list_add_tail(&x->bydst, xfrm_state_bydst+h);			xfrm_state_hold(x);			if (x->id.spi) {				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);				list_add(&x->byspi, xfrm_state_byspi+h);				xfrm_state_hold(x);			}			x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;			xfrm_state_hold(x);			x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;			add_timer(&x->timer);		} else {			x->km.state = XFRM_STATE_DEAD;			xfrm_state_put(x);			x = NULL;			error = -ESRCH;		}	}out:	if (x)		xfrm_state_hold(x);	else		*err = acquire_in_progress ? -EAGAIN : error;	spin_unlock_bh(&xfrm_state_lock);	xfrm_state_put_afinfo(afinfo);	return x;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/5c5d281a93e9816966b6131ccec19519dab0e103/xfrm_state.c/buggy/net/xfrm/xfrm_state.c