Home | History | Annotate | Line # | Download | only in netipsec
keysock.c revision 1.51
      1 /*	$NetBSD: keysock.c,v 1.51 2017/04/19 03:39:14 ozaki-r Exp $	*/
      2 /*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
      3 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
      4 
      5 /*
      6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. Neither the name of the project nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 __KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.51 2017/04/19 03:39:14 ozaki-r Exp $");
     36 
     37 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
     38 
     39 #include <sys/types.h>
     40 #include <sys/param.h>
     41 #include <sys/domain.h>
     42 #include <sys/errno.h>
     43 #include <sys/kernel.h>
     44 #include <sys/kmem.h>
     45 #include <sys/mbuf.h>
     46 #include <sys/protosw.h>
     47 #include <sys/signalvar.h>
     48 #include <sys/socket.h>
     49 #include <sys/socketvar.h>
     50 #include <sys/sysctl.h>
     51 #include <sys/systm.h>
     52 
     53 #include <net/raw_cb.h>
     54 #include <net/route.h>
     55 
     56 #include <net/pfkeyv2.h>
     57 #include <netipsec/key.h>
     58 #include <netipsec/keysock.h>
     59 #include <netipsec/key_debug.h>
     60 
     61 #include <netipsec/ipsec_private.h>
     62 
     63 struct key_cb {
     64 	int key_count;
     65 	int any_count;
     66 };
     67 static struct key_cb key_cb;
     68 
     69 static struct sockaddr key_dst = {
     70     .sa_len = 2,
     71     .sa_family = PF_KEY,
     72 };
     73 static struct sockaddr key_src = {
     74     .sa_len = 2,
     75     .sa_family = PF_KEY,
     76 };
     77 
     78 static const struct protosw keysw[];
     79 
     80 static int key_sendup0(struct rawcb *, struct mbuf *, int, int);
     81 
     82 int key_registered_sb_max = (2048 * MHLEN); /* XXX arbitrary */
     83 
     84 /*
     85  * key_output()
     86  */
     87 static int
     88 key_output(struct mbuf *m, struct socket *so)
     89 {
     90 	struct sadb_msg *msg;
     91 	int len, error = 0;
     92 	int s;
     93 
     94 	if (m == 0)
     95 		panic("key_output: NULL pointer was passed");
     96 
     97 	{
     98 		uint64_t *ps = PFKEY_STAT_GETREF();
     99 		ps[PFKEY_STAT_OUT_TOTAL]++;
    100 		ps[PFKEY_STAT_OUT_BYTES] += m->m_pkthdr.len;
    101 		PFKEY_STAT_PUTREF();
    102 	}
    103 
    104 	len = m->m_pkthdr.len;
    105 	if (len < sizeof(struct sadb_msg)) {
    106 		PFKEY_STATINC(PFKEY_STAT_OUT_TOOSHORT);
    107 		error = EINVAL;
    108 		goto end;
    109 	}
    110 
    111 	if (m->m_len < sizeof(struct sadb_msg)) {
    112 		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) {
    113 			PFKEY_STATINC(PFKEY_STAT_OUT_NOMEM);
    114 			error = ENOBUFS;
    115 			goto end;
    116 		}
    117 	}
    118 
    119 	if ((m->m_flags & M_PKTHDR) == 0)
    120 		panic("key_output: not M_PKTHDR ??");
    121 
    122 	KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));
    123 
    124 	msg = mtod(m, struct sadb_msg *);
    125 	PFKEY_STATINC(PFKEY_STAT_OUT_MSGTYPE + msg->sadb_msg_type);
    126 	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
    127 		PFKEY_STATINC(PFKEY_STAT_OUT_INVLEN);
    128 		error = EINVAL;
    129 		goto end;
    130 	}
    131 
    132 	/*XXX giant lock*/
    133 	s = splsoftnet();
    134 	error = key_parse(m, so);
    135 	m = NULL;
    136 	splx(s);
    137 end:
    138 	if (m)
    139 		m_freem(m);
    140 	return error;
    141 }
    142 
    143 /*
    144  * send message to the socket.
    145  */
    146 static int
    147 key_sendup0(
    148     struct rawcb *rp,
    149     struct mbuf *m,
    150     int promisc,
    151     int sbprio
    152 )
    153 {
    154 	int error;
    155 	int ok;
    156 
    157 	if (promisc) {
    158 		struct sadb_msg *pmsg;
    159 
    160 		M_PREPEND(m, sizeof(struct sadb_msg), M_DONTWAIT);
    161 		if (m && m->m_len < sizeof(struct sadb_msg))
    162 			m = m_pullup(m, sizeof(struct sadb_msg));
    163 		if (!m) {
    164 			PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    165 			return ENOBUFS;
    166 		}
    167 		m->m_pkthdr.len += sizeof(*pmsg);
    168 
    169 		pmsg = mtod(m, struct sadb_msg *);
    170 		memset(pmsg, 0, sizeof(*pmsg));
    171 		pmsg->sadb_msg_version = PF_KEY_V2;
    172 		pmsg->sadb_msg_type = SADB_X_PROMISC;
    173 		pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
    174 		/* pid and seq? */
    175 
    176 		PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE + pmsg->sadb_msg_type);
    177 	}
    178 
    179 	if (sbprio == 0)
    180 		ok = sbappendaddr(&rp->rcb_socket->so_rcv,
    181 			       (struct sockaddr *)&key_src, m, NULL);
    182 	else
    183 		ok = sbappendaddrchain(&rp->rcb_socket->so_rcv,
    184 			       (struct sockaddr *)&key_src, m, sbprio);
    185 
    186 	  if (!ok) {
    187 		PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    188 		m_freem(m);
    189 		error = ENOBUFS;
    190 	} else
    191 		error = 0;
    192 	sorwakeup(rp->rcb_socket);
    193 	return error;
    194 }
    195 
    196 /* XXX this interface should be obsoleted. */
    197 int
    198 key_sendup(struct socket *so, struct sadb_msg *msg, u_int len,
    199 	   int target)	/*target of the resulting message*/
    200 {
    201 	struct mbuf *m, *n, *mprev;
    202 	int tlen;
    203 
    204 	/* sanity check */
    205 	if (so == 0 || msg == 0)
    206 		panic("key_sendup: NULL pointer was passed");
    207 
    208 	KEYDEBUG(KEYDEBUG_KEY_DUMP,
    209 		printf("key_sendup: \n");
    210 		kdebug_sadb(msg));
    211 
    212 	/*
    213 	 * we increment statistics here, just in case we have ENOBUFS
    214 	 * in this function.
    215 	 */
    216 	{
    217 		uint64_t *ps = PFKEY_STAT_GETREF();
    218 		ps[PFKEY_STAT_IN_TOTAL]++;
    219 		ps[PFKEY_STAT_IN_BYTES] += len;
    220 		ps[PFKEY_STAT_IN_MSGTYPE + msg->sadb_msg_type]++;
    221 		PFKEY_STAT_PUTREF();
    222 	}
    223 
    224 	/*
    225 	 * Get mbuf chain whenever possible (not clusters),
    226 	 * to save socket buffer.  We'll be generating many SADB_ACQUIRE
    227 	 * messages to listening key sockets.  If we simply allocate clusters,
    228 	 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
    229 	 * sbspace() computes # of actual data bytes AND mbuf region.
    230 	 *
    231 	 * TODO: SADB_ACQUIRE filters should be implemented.
    232 	 */
    233 	tlen = len;
    234 	m = mprev = NULL;
    235 	while (tlen > 0) {
    236 		int mlen;
    237 		if (tlen == len) {
    238 			MGETHDR(n, M_DONTWAIT, MT_DATA);
    239 			mlen = MHLEN;
    240 		} else {
    241 			MGET(n, M_DONTWAIT, MT_DATA);
    242 			mlen = MLEN;
    243 		}
    244 		if (!n) {
    245 			PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    246 			return ENOBUFS;
    247 		}
    248 		n->m_len = mlen;
    249 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
    250 			MCLGET(n, M_DONTWAIT);
    251 			if ((n->m_flags & M_EXT) == 0) {
    252 				m_free(n);
    253 				m_freem(m);
    254 				PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    255 				return ENOBUFS;
    256 			}
    257 			n->m_len = MCLBYTES;
    258 		}
    259 
    260 		if (tlen < n->m_len)
    261 			n->m_len = tlen;
    262 		n->m_next = NULL;
    263 		if (m == NULL)
    264 			m = mprev = n;
    265 		else {
    266 			mprev->m_next = n;
    267 			mprev = n;
    268 		}
    269 		tlen -= n->m_len;
    270 		n = NULL;
    271 	}
    272 	m->m_pkthdr.len = len;
    273 	m_reset_rcvif(m);
    274 	m_copyback(m, 0, len, msg);
    275 
    276 	/* avoid duplicated statistics */
    277 	{
    278 		uint64_t *ps = PFKEY_STAT_GETREF();
    279 		ps[PFKEY_STAT_IN_TOTAL]--;
    280 		ps[PFKEY_STAT_IN_BYTES] -= len;
    281 		ps[PFKEY_STAT_IN_MSGTYPE + msg->sadb_msg_type]--;
    282 		PFKEY_STAT_PUTREF();
    283 	}
    284 
    285 	return key_sendup_mbuf(so, m, target);
    286 }
    287 
    288 /* so can be NULL if target != KEY_SENDUP_ONE */
    289 int
    290 key_sendup_mbuf(struct socket *so, struct mbuf *m,
    291 		int target/*, sbprio */)
    292 {
    293 	struct mbuf *n;
    294 	struct keycb *kp;
    295 	int sendup;
    296 	struct rawcb *rp;
    297 	int error = 0;
    298 	int sbprio = 0; /* XXX should be a parameter */
    299 
    300 	if (m == NULL)
    301 		panic("key_sendup_mbuf: NULL pointer was passed");
    302 	if (so == NULL && target == KEY_SENDUP_ONE)
    303 		panic("key_sendup_mbuf: NULL pointer was passed");
    304 
    305 	/*
    306 	 * RFC 2367 says ACQUIRE and other kernel-generated messages
    307 	 * are special. We treat all KEY_SENDUP_REGISTERED messages
    308 	 * as special, delivering them to all registered sockets
    309 	 * even if the socket is at or above its so->so_rcv.sb_max limits.
    310 	 * The only constraint is that the  so_rcv data fall below
    311 	 * key_registered_sb_max.
    312 	 * Doing that check here avoids reworking every key_sendup_mbuf()
    313 	 * in the short term. . The rework will be done after a technical
    314 	 * conensus that this approach is appropriate.
    315  	 */
    316 	if (target == KEY_SENDUP_REGISTERED) {
    317 		sbprio = SB_PRIO_BESTEFFORT;
    318 	}
    319 
    320 	{
    321 		uint64_t *ps = PFKEY_STAT_GETREF();
    322 		ps[PFKEY_STAT_IN_TOTAL]++;
    323 		ps[PFKEY_STAT_IN_BYTES] += m->m_pkthdr.len;
    324 		PFKEY_STAT_PUTREF();
    325 	}
    326 	if (m->m_len < sizeof(struct sadb_msg)) {
    327 #if 1
    328 		m = m_pullup(m, sizeof(struct sadb_msg));
    329 		if (m == NULL) {
    330 			PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    331 			return ENOBUFS;
    332 		}
    333 #else
    334 		/* don't bother pulling it up just for stats */
    335 #endif
    336 	}
    337 	if (m->m_len >= sizeof(struct sadb_msg)) {
    338 		struct sadb_msg *msg;
    339 		msg = mtod(m, struct sadb_msg *);
    340 		PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE + msg->sadb_msg_type);
    341 	}
    342 
    343 	LIST_FOREACH(rp, &rawcb, rcb_list)
    344 	{
    345 		struct socket * kso = rp->rcb_socket;
    346 		if (rp->rcb_proto.sp_family != PF_KEY)
    347 			continue;
    348 		if (rp->rcb_proto.sp_protocol
    349 		 && rp->rcb_proto.sp_protocol != PF_KEY_V2) {
    350 			continue;
    351 		}
    352 
    353 		kp = (struct keycb *)rp;
    354 
    355 		/*
    356 		 * If you are in promiscuous mode, and when you get broadcasted
    357 		 * reply, you'll get two PF_KEY messages.
    358 		 * (based on pf_key (at) inner.net message on 14 Oct 1998)
    359 		 */
    360 		if (((struct keycb *)rp)->kp_promisc) {
    361 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
    362 				(void)key_sendup0(rp, n, 1, 0);
    363 				n = NULL;
    364 			}
    365 		}
    366 
    367 		/* the exact target will be processed later */
    368 		if (so && sotorawcb(so) == rp)
    369 			continue;
    370 
    371 		sendup = 0;
    372 		switch (target) {
    373 		case KEY_SENDUP_ONE:
    374 			/* the statement has no effect */
    375 			if (so && sotorawcb(so) == rp)
    376 				sendup++;
    377 			break;
    378 		case KEY_SENDUP_ALL:
    379 			sendup++;
    380 			break;
    381 		case KEY_SENDUP_REGISTERED:
    382 			if (kp->kp_registered) {
    383 				if (kso->so_rcv.sb_cc <= key_registered_sb_max)
    384 					sendup++;
    385 			  	else
    386 			  		printf("keysock: "
    387 					       "registered sendup dropped, "
    388 					       "sb_cc %ld max %d\n",
    389 					       kso->so_rcv.sb_cc,
    390 					       key_registered_sb_max);
    391 			}
    392 			break;
    393 		}
    394 		PFKEY_STATINC(PFKEY_STAT_IN_MSGTARGET + target);
    395 
    396 		if (!sendup)
    397 			continue;
    398 
    399 		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
    400 			m_freem(m);
    401 			PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
    402 			return ENOBUFS;
    403 		}
    404 
    405 		if ((error = key_sendup0(rp, n, 0, 0)) != 0) {
    406 			m_freem(m);
    407 			return error;
    408 		}
    409 
    410 		n = NULL;
    411 	}
    412 
    413 	/* The 'later' time for processing the exact target has arrived */
    414 	if (so) {
    415 		error = key_sendup0(sotorawcb(so), m, 0, sbprio);
    416 		m = NULL;
    417 	} else {
    418 		error = 0;
    419 		m_freem(m);
    420 	}
    421 	return error;
    422 }
    423 
    424 static int
    425 key_attach(struct socket *so, int proto)
    426 {
    427 	struct keycb *kp;
    428 	int s, error;
    429 
    430 	KASSERT(sotorawcb(so) == NULL);
    431 	kp = kmem_zalloc(sizeof(*kp), KM_SLEEP);
    432 	kp->kp_raw.rcb_len = sizeof(*kp);
    433 	so->so_pcb = kp;
    434 
    435 	s = splsoftnet();
    436 	error = raw_attach(so, proto);
    437 	if (error) {
    438 		PFKEY_STATINC(PFKEY_STAT_SOCKERR);
    439 		kmem_free(kp, sizeof(*kp));
    440 		so->so_pcb = NULL;
    441 		goto out;
    442 	}
    443 
    444 	kp->kp_promisc = kp->kp_registered = 0;
    445 
    446 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
    447 		key_cb.key_count++;
    448 	key_cb.any_count++;
    449 	kp->kp_raw.rcb_laddr = &key_src;
    450 	kp->kp_raw.rcb_faddr = &key_dst;
    451 	soisconnected(so);
    452 	so->so_options |= SO_USELOOPBACK;
    453 out:
    454 	KASSERT(solocked(so));
    455 	splx(s);
    456 	return error;
    457 }
    458 
    459 static void
    460 key_detach(struct socket *so)
    461 {
    462 	struct keycb *kp = (struct keycb *)sotorawcb(so);
    463 	int s;
    464 
    465 	KASSERT(solocked(so));
    466 	KASSERT(kp != NULL);
    467 
    468 	s = splsoftnet();
    469 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
    470 		key_cb.key_count--;
    471 	key_cb.any_count--;
    472 	key_freereg(so);
    473 	raw_detach(so);
    474 	splx(s);
    475 }
    476 
    477 static int
    478 key_accept(struct socket *so, struct sockaddr *nam)
    479 {
    480 	KASSERT(solocked(so));
    481 
    482 	panic("key_accept");
    483 
    484 	return EOPNOTSUPP;
    485 }
    486 
    487 static int
    488 key_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
    489 {
    490 	KASSERT(solocked(so));
    491 
    492 	return EOPNOTSUPP;
    493 }
    494 
    495 static int
    496 key_listen(struct socket *so, struct lwp *l)
    497 {
    498 	KASSERT(solocked(so));
    499 
    500 	return EOPNOTSUPP;
    501 }
    502 
    503 static int
    504 key_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
    505 {
    506 	KASSERT(solocked(so));
    507 
    508 	return EOPNOTSUPP;
    509 }
    510 
    511 static int
    512 key_connect2(struct socket *so, struct socket *so2)
    513 {
    514 	KASSERT(solocked(so));
    515 
    516 	return EOPNOTSUPP;
    517 }
    518 
    519 static int
    520 key_disconnect(struct socket *so)
    521 {
    522 	struct rawcb *rp = sotorawcb(so);
    523 	int s;
    524 
    525 	KASSERT(solocked(so));
    526 	KASSERT(rp != NULL);
    527 
    528 	s = splsoftnet();
    529 	soisdisconnected(so);
    530 	raw_disconnect(rp);
    531 	splx(s);
    532 
    533 	return 0;
    534 }
    535 
    536 static int
    537 key_shutdown(struct socket *so)
    538 {
    539 	int s;
    540 
    541 	KASSERT(solocked(so));
    542 
    543 	/*
    544 	 * Mark the connection as being incapable of further input.
    545 	 */
    546 	s = splsoftnet();
    547 	socantsendmore(so);
    548 	splx(s);
    549 
    550 	return 0;
    551 }
    552 
    553 static int
    554 key_abort(struct socket *so)
    555 {
    556 	KASSERT(solocked(so));
    557 
    558 	panic("key_abort");
    559 
    560 	return EOPNOTSUPP;
    561 }
    562 
    563 static int
    564 key_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
    565 {
    566 	return EOPNOTSUPP;
    567 }
    568 
    569 static int
    570 key_stat(struct socket *so, struct stat *ub)
    571 {
    572 	KASSERT(solocked(so));
    573 
    574 	return 0;
    575 }
    576 
    577 static int
    578 key_peeraddr(struct socket *so, struct sockaddr *nam)
    579 {
    580 	struct rawcb *rp = sotorawcb(so);
    581 
    582 	KASSERT(solocked(so));
    583 	KASSERT(rp != NULL);
    584 	KASSERT(nam != NULL);
    585 
    586 	if (rp->rcb_faddr == NULL)
    587 		return ENOTCONN;
    588 
    589 	raw_setpeeraddr(rp, nam);
    590 	return 0;
    591 }
    592 
    593 static int
    594 key_sockaddr(struct socket *so, struct sockaddr *nam)
    595 {
    596 	struct rawcb *rp = sotorawcb(so);
    597 
    598 	KASSERT(solocked(so));
    599 	KASSERT(rp != NULL);
    600 	KASSERT(nam != NULL);
    601 
    602 	if (rp->rcb_faddr == NULL)
    603 		return ENOTCONN;
    604 
    605 	raw_setsockaddr(rp, nam);
    606 	return 0;
    607 }
    608 
    609 static int
    610 key_rcvd(struct socket *so, int flags, struct lwp *l)
    611 {
    612 	KASSERT(solocked(so));
    613 
    614 	return EOPNOTSUPP;
    615 }
    616 
    617 static int
    618 key_recvoob(struct socket *so, struct mbuf *m, int flags)
    619 {
    620 	KASSERT(solocked(so));
    621 
    622 	return EOPNOTSUPP;
    623 }
    624 
    625 static int
    626 key_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
    627     struct mbuf *control, struct lwp *l)
    628 {
    629 	int error = 0;
    630 	int s;
    631 
    632 	KASSERT(solocked(so));
    633 	KASSERT(so->so_proto == &keysw[0]);
    634 
    635 	s = splsoftnet();
    636 	error = raw_send(so, m, nam, control, l, &key_output);
    637 	splx(s);
    638 
    639 	return error;
    640 }
    641 
    642 static int
    643 key_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
    644 {
    645 	KASSERT(solocked(so));
    646 
    647 	m_freem(m);
    648 	m_freem(control);
    649 
    650 	return EOPNOTSUPP;
    651 }
    652 
    653 static int
    654 key_purgeif(struct socket *so, struct ifnet *ifa)
    655 {
    656 
    657 	panic("key_purgeif");
    658 
    659 	return EOPNOTSUPP;
    660 }
    661 
    662 /*
    663  * Definitions of protocols supported in the KEY domain.
    664  */
    665 
    666 DOMAIN_DEFINE(keydomain);
    667 
    668 PR_WRAP_USRREQS(key)
    669 #define	key_attach	key_attach_wrapper
    670 #define	key_detach	key_detach_wrapper
    671 #define	key_accept	key_accept_wrapper
    672 #define	key_bind	key_bind_wrapper
    673 #define	key_listen	key_listen_wrapper
    674 #define	key_connect	key_connect_wrapper
    675 #define	key_connect2	key_connect2_wrapper
    676 #define	key_disconnect	key_disconnect_wrapper
    677 #define	key_shutdown	key_shutdown_wrapper
    678 #define	key_abort	key_abort_wrapper
    679 #define	key_ioctl	key_ioctl_wrapper
    680 #define	key_stat	key_stat_wrapper
    681 #define	key_peeraddr	key_peeraddr_wrapper
    682 #define	key_sockaddr	key_sockaddr_wrapper
    683 #define	key_rcvd	key_rcvd_wrapper
    684 #define	key_recvoob	key_recvoob_wrapper
    685 #define	key_send	key_send_wrapper
    686 #define	key_sendoob	key_sendoob_wrapper
    687 #define	key_purgeif	key_purgeif_wrapper
    688 
    689 static const struct pr_usrreqs key_usrreqs = {
    690 	.pr_attach	= key_attach,
    691 	.pr_detach	= key_detach,
    692 	.pr_accept	= key_accept,
    693 	.pr_bind	= key_bind,
    694 	.pr_listen	= key_listen,
    695 	.pr_connect	= key_connect,
    696 	.pr_connect2	= key_connect2,
    697 	.pr_disconnect	= key_disconnect,
    698 	.pr_shutdown	= key_shutdown,
    699 	.pr_abort	= key_abort,
    700 	.pr_ioctl	= key_ioctl,
    701 	.pr_stat	= key_stat,
    702 	.pr_peeraddr	= key_peeraddr,
    703 	.pr_sockaddr	= key_sockaddr,
    704 	.pr_rcvd	= key_rcvd,
    705 	.pr_recvoob	= key_recvoob,
    706 	.pr_send	= key_send,
    707 	.pr_sendoob	= key_sendoob,
    708 	.pr_purgeif	= key_purgeif,
    709 };
    710 
    711 static const struct protosw keysw[] = {
    712     {
    713 	.pr_type = SOCK_RAW,
    714 	.pr_domain = &keydomain,
    715 	.pr_protocol = PF_KEY_V2,
    716 	.pr_flags = PR_ATOMIC|PR_ADDR,
    717 	.pr_ctlinput = raw_ctlinput,
    718 	.pr_usrreqs = &key_usrreqs,
    719 	.pr_init = raw_init,
    720     }
    721 };
    722 
    723 struct domain keydomain = {
    724     .dom_family = PF_KEY,
    725     .dom_name = "key",
    726     .dom_init = key_init,
    727     .dom_protosw = keysw,
    728     .dom_protoswNPROTOSW = &keysw[__arraycount(keysw)],
    729 };
    730