struct tdb *tdb = NULL;
check_ipsec_policy(struct inpcb *inp, u_int32_t daddr){    union sockaddr_union sunion;    struct socket *so;    struct route_enc re0, *re = &re0;    struct sockaddr_encap *dst;     u_int8_t sa_require, sa_have;    int error, i, s;    struct tdb *tdb = NULL;    if (inp == NULL || ((so = inp->inp_socket) == 0))      return (EINVAL);    /* If IPSEC is not required just use what we got */    if (!(sa_require = inp->inp_secrequire))      return 0;    s = spltdb();    if (!inp->inp_tdb)    {	bzero((caddr_t) re, sizeof(*re));	dst = (struct sockaddr_encap *) &re->re_dst;	dst->sen_family = PF_KEY;	dst->sen_len = SENT_IP4_LEN;	dst->sen_type = SENT_IP4;	dst->sen_ip_src = inp->inp_laddr;	dst->sen_ip_dst.s_addr = inp->inp_faddr.s_addr ? 	  inp->inp_faddr.s_addr : daddr;	dst->sen_proto = so->so_proto->pr_protocol;	switch (dst->sen_proto)	{	  case IPPROTO_UDP:	  case IPPROTO_TCP:	    dst->sen_sport = htons(inp->inp_lport);	    dst->sen_dport = htons(inp->inp_fport);	    break;	  default:	    dst->sen_sport = 0;	    dst->sen_dport = 0;	}    	/* Try to find a flow */	rtalloc((struct route *) re);    	if (re->re_rt != NULL)	{	    struct sockaddr_encap *gw;	    	    gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway);	    	    if (gw->sen_type == SENT_IPSP)	    {		bzero(&sunion, sizeof(sunion));	        sunion.sin.sin_family = AF_INET;		sunion.sin.sin_len = sizeof(struct sockaddr_in);		sunion.sin.sin_addr = gw->sen_ipsp_dst;	      		tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,					    gw->sen_ipsp_sproto);	    }	    RTFREE(re->re_rt);	}    } else      tdb = inp->inp_tdb;    if (tdb)      SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb);    else      sa_have = 0;    splx(s);    /* Check if our requirements are met */    if (!(sa_require & ~sa_have))      return 0;    error = i = 0;    inp->inp_secresult = SR_WAIT;    /* If necessary try to notify keymanagement three times */    while (i < 3)    {	switch (dst->sen_type)	{	    case SENT_IPSP:		DPRINTF(("ipsec: send SA request (%d), remote IPv4 address: %s, SA type: %d\n", i + 1, inet_ntoa4(dst->sen_ip_dst), sa_require));		break;#ifdef INET6	    case SENT_IPSP6:		DPRINTF(("ipsec: send SA request (%d), remote IPv6 address: %s, SA type: %d\n", i + 1, inet6_ntoa4(dst->sen_ip6_dst), sa_require));		break;#endif /* INET6 */	    default:		DPRINTF(("ipsec: unsupported protocol family %d, cannot notify kkey management\n", dst->sen_type));		return EPFNOSUPPORT;	}	/* Send notify */	/* XXX PF_KEYv2 Notify */	 	/* 	 * Wait for the keymanagement daemon to establich a new SA,	 * even on error check again, perhaps some other process	 * already established the necessary SA.	 */	error = tsleep((caddr_t)inp, PSOCK|PCATCH, "ipsecnotify", 30*hz);	DPRINTF(("check_ipsec: sleep %d\n", error));	if (error && error != EWOULDBLOCK)	  break;	/* 	 * A Key Management daemon returned an apropriate SA back	 * to the kernel, the kernel noted that state in the waiting	 * socket.	 */	if (inp->inp_secresult == SR_SUCCESS)	  return (0);	/*	 * Key Management returned a permanent failure, we do not	 * need to retry again. XXX - when more than one key	 * management daemon is available we can not do that.	 */	if (inp->inp_secresult == SR_FAILED)	  break;	i++;    }    return (error ? error : EWOULDBLOCK);}