FreeBSD/sys/netipsec/key.c
/*
 * return a policy that matches this particular inbound packet.
 * XXX slow
 */
return a policy that matches this particular inbound packet.
XXX slow
return a policy that matches this particular inbound packet . XXX slow
struct secpolicy *
key_gettunnel(const struct sockaddr *osrc,
	      const struct sockaddr *odst,
	      const struct sockaddr *isrc,
	      const struct sockaddr *idst,
	      const char* where, int tag)
{
	struct secpolicy *sp;
	const int dir = IPSEC_DIR_INBOUND;
	struct ipsecrequest *r1, *r2, *p;
	struct secpolicyindex spidx;
	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
		printf("DP %s from %s:%u\n", __func__, where, tag));
	if (isrc->sa_family != idst->sa_family) {
		ipseclog((LOG_ERR, "%s: protocol family mismatched %d != %d\n.",
			__func__, isrc->sa_family, idst->sa_family));
		sp = NULL;
		goto done;
	}
	SPTREE_LOCK();
	LIST_FOREACH(sp, &V_sptree[dir], chain) {
		if (sp->state == IPSEC_SPSTATE_DEAD)
			continue;
		r1 = r2 = NULL;
		for (p = sp->req; p; p = p->next) {
			if (p->saidx.mode != IPSEC_MODE_TUNNEL)
				continue;
			r1 = r2;
			r2 = p;
			if (!r1) {
				spidx = sp->spidx;
				if (isrc->sa_len > sizeof(spidx.src) ||
				    idst->sa_len > sizeof(spidx.dst))
					continue;
				bcopy(isrc, &spidx.src, isrc->sa_len);
				bcopy(idst, &spidx.dst, idst->sa_len);
				if (!key_cmpspidx_withmask(&sp->spidx, &spidx))
					continue;
			} else {
				if (key_sockaddrcmp(&r1->saidx.src.sa, isrc, 0) ||
				    key_sockaddrcmp(&r1->saidx.dst.sa, idst, 0))
					continue;
			}
			if (key_sockaddrcmp(&r2->saidx.src.sa, osrc, 0) ||
			    key_sockaddrcmp(&r2->saidx.dst.sa, odst, 0))
				continue;
			goto found;
		}
	}
	sp = NULL;
found:
	if (sp) {
		sp->lastused = time_second;
		SP_ADDREF(sp);
	}
	SPTREE_UNLOCK();
done:
	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
		printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
			sp, sp ? sp->id : 0, sp ? sp->refcnt : 0));
	return sp;
}
struct secpolicy * key_gettunnel ( const struct sockaddr * osrc , const struct sockaddr * odst , const struct sockaddr * isrc , const struct sockaddr * idst , const char * where , int tag ) { struct secpolicy * sp ; const int dir = IPSEC_DIR_INBOUND ; struct ipsecrequest * r1 , * r2 , * p ; struct secpolicyindex spidx ; KEYDEBUG ( KEYDEBUG_IPSEC_STAMP , printf ( " \n " , __func__ , where , tag ) ) ; if ( isrc -> sa_family != idst -> sa_family ) { ipseclog ( ( LOG_ERR , " \n " , __func__ , isrc -> sa_family , idst -> sa_family ) ) ; sp = NULL ; goto done ; } SPTREE_LOCK ( ) ; LIST_FOREACH ( sp , & V_sptree [ dir ] , chain ) { if ( sp -> state == IPSEC_SPSTATE_DEAD ) continue ; r1 = r2 = NULL ; for ( p = sp -> req ; p ; p = p -> next ) { if ( p -> saidx . mode != IPSEC_MODE_TUNNEL ) continue ; r1 = r2 ; r2 = p ; if ( ! r1 ) { spidx = sp -> spidx ; if ( isrc -> sa_len > sizeof ( spidx . src ) || idst -> sa_len > sizeof ( spidx . dst ) ) continue ; bcopy ( isrc , & spidx . src , isrc -> sa_len ) ; bcopy ( idst , & spidx . dst , idst -> sa_len ) ; if ( ! key_cmpspidx_withmask ( & sp -> spidx , & spidx ) ) continue ; } else { if ( key_sockaddrcmp ( & r1 -> saidx . src . sa , isrc , 0 ) || key_sockaddrcmp ( & r1 -> saidx . dst . sa , idst , 0 ) ) continue ; } if ( key_sockaddrcmp ( & r2 -> saidx . src . sa , osrc , 0 ) || key_sockaddrcmp ( & r2 -> saidx . dst . sa , odst , 0 ) ) continue ; goto found ; } } sp = NULL ; found : if ( sp ) { sp -> lastused = time_second ; SP_ADDREF ( sp ) ; } SPTREE_UNLOCK ( ) ; done : KEYDEBUG ( KEYDEBUG_IPSEC_STAMP , printf ( " \n " , __func__ , sp , sp ? sp -> id : 0 , sp ? sp -> refcnt : 0 ) ) ; return sp ; }
return a policy that matches this particular inbound packet.
return a policy that matches this particular inbound packet .
/* here we look at address matches only */