keysock.c revision 253088
185587Sobrien/* $FreeBSD: head/sys/netipsec/keysock.c 253088 2013-07-09 10:08:13Z ae $ */ 285587Sobrien/* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ 385587Sobrien 485587Sobrien/*- 585587Sobrien * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 685587Sobrien * All rights reserved. 785587Sobrien * 885587Sobrien * Redistribution and use in source and binary forms, with or without 985587Sobrien * modification, are permitted provided that the following conditions 1085587Sobrien * are met: 1185587Sobrien * 1. Redistributions of source code must retain the above copyright 1285587Sobrien * notice, this list of conditions and the following disclaimer. 1385587Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1485587Sobrien * notice, this list of conditions and the following disclaimer in the 1585587Sobrien * documentation and/or other materials provided with the distribution. 1685587Sobrien * 3. Neither the name of the project nor the names of its contributors 1785587Sobrien * may be used to endorse or promote products derived from this software 1885587Sobrien * without specific prior written permission. 1985587Sobrien * 2085587Sobrien * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2185587Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2285587Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2385587Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2485587Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25170331Srafan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2685587Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27201989Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28201989Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29201989Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3085587Sobrien * SUCH DAMAGE. 3185587Sobrien */ 3285587Sobrien 3385587Sobrien#include "opt_ipsec.h" 3485587Sobrien 3585587Sobrien/* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ 3685587Sobrien 3785587Sobrien#include <sys/types.h> 3885587Sobrien#include <sys/param.h> 39118194Sru#include <sys/domain.h> 4085587Sobrien#include <sys/errno.h> 4185587Sobrien#include <sys/kernel.h> 4285587Sobrien#include <sys/lock.h> 4385587Sobrien#include <sys/malloc.h> 4485587Sobrien#include <sys/mbuf.h> 4585587Sobrien#include <sys/mutex.h> 4685587Sobrien#include <sys/priv.h> 4785587Sobrien#include <sys/protosw.h> 4885587Sobrien#include <sys/signalvar.h> 4985587Sobrien#include <sys/socket.h> 50170331Srafan#include <sys/socketvar.h> 5185587Sobrien#include <sys/sysctl.h> 5285587Sobrien#include <sys/systm.h> 5385587Sobrien 54170331Srafan#include <net/if.h> 5585587Sobrien#include <net/raw_cb.h> 5685587Sobrien#include <net/route.h> 5785587Sobrien#include <net/vnet.h> 5885587Sobrien 5985587Sobrien#include <netinet/in.h> 6085587Sobrien 6185587Sobrien#include <net/pfkeyv2.h> 6285587Sobrien#include <netipsec/key.h> 6385587Sobrien#include <netipsec/keysock.h> 6485587Sobrien#include <netipsec/key_debug.h> 6585587Sobrien#include <netipsec/ipsec.h> 6685587Sobrien 6785587Sobrien#include <machine/stdarg.h> 6885587Sobrien 6985587Sobrienstruct key_cb { 7085587Sobrien int key_count; 7185587Sobrien int any_count; 7285587Sobrien}; 7385587Sobrienstatic VNET_DEFINE(struct key_cb, key_cb); 7485587Sobrien#define V_key_cb VNET(key_cb) 7585587Sobrien 7685587Sobrienstatic struct sockaddr key_src = { 2, PF_KEY, }; 7785587Sobrien 7885587Sobrienstatic int key_sendup0 __P((struct rawcb *, struct mbuf *, int)); 7985587Sobrien 8085587SobrienVNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat); 8185587SobrienVNET_PCPUSTAT_SYSINIT(pfkeystat); 82107806Sobrien 8385587Sobrien#ifdef VIMAGE 8485587SobrienVNET_PCPUSTAT_SYSUNINIT(pfkeystat); 8585587Sobrien#endif /* VIMAGE */ 8685587Sobrien 8785587Sobrien/* 8885587Sobrien * key_output() 8985587Sobrien */ 9085587Sobrienint 9185587Sobrienkey_output(struct mbuf *m, struct socket *so) 9285587Sobrien{ 9385587Sobrien struct sadb_msg *msg; 9485587Sobrien int len, error = 0; 9585587Sobrien 9685587Sobrien if (m == 0) 9785587Sobrien panic("%s: NULL pointer was passed.\n", __func__); 9885587Sobrien 9985587Sobrien PFKEYSTAT_INC(out_total); 10090902Sdes PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len); 10185587Sobrien 10285587Sobrien len = m->m_pkthdr.len; 10385587Sobrien if (len < sizeof(struct sadb_msg)) { 10485587Sobrien PFKEYSTAT_INC(out_tooshort); 10585587Sobrien error = EINVAL; 10685587Sobrien goto end; 10785587Sobrien } 10885587Sobrien 10985587Sobrien if (m->m_len < sizeof(struct sadb_msg)) { 11085587Sobrien if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) { 11185587Sobrien PFKEYSTAT_INC(out_nomem); 11285587Sobrien error = ENOBUFS; 11385587Sobrien goto end; 11485587Sobrien } 11585587Sobrien } 11685587Sobrien 11785587Sobrien M_ASSERTPKTHDR(m); 11885587Sobrien 11985587Sobrien KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m)); 12085587Sobrien 12185587Sobrien msg = mtod(m, struct sadb_msg *); 12285587Sobrien PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]); 12385587Sobrien if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { 124107806Sobrien PFKEYSTAT_INC(out_invlen); 12585587Sobrien error = EINVAL; 12685587Sobrien goto end; 12785587Sobrien } 12885587Sobrien 12985587Sobrien error = key_parse(m, so); 13085587Sobrien m = NULL; 13185587Sobrienend: 13285587Sobrien if (m) 13385587Sobrien m_freem(m); 13485587Sobrien return error; 13585587Sobrien} 13685587Sobrien 13785587Sobrien/* 13885587Sobrien * send message to the socket. 13985587Sobrien */ 14085587Sobrienstatic int 14185587Sobrienkey_sendup0(rp, m, promisc) 14285587Sobrien struct rawcb *rp; 143315582Spfg struct mbuf *m; 14485587Sobrien int promisc; 14585587Sobrien{ 14685587Sobrien int error; 14785587Sobrien 14885587Sobrien if (promisc) { 14985587Sobrien struct sadb_msg *pmsg; 15085587Sobrien 15185587Sobrien M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT); 15285587Sobrien if (m && m->m_len < sizeof(struct sadb_msg)) 15385587Sobrien m = m_pullup(m, sizeof(struct sadb_msg)); 15485587Sobrien if (!m) { 15585587Sobrien PFKEYSTAT_INC(in_nomem); 15685587Sobrien m_freem(m); 15785587Sobrien return ENOBUFS; 15885587Sobrien } 15985587Sobrien m->m_pkthdr.len += sizeof(*pmsg); 16085587Sobrien 16185587Sobrien pmsg = mtod(m, struct sadb_msg *); 16285587Sobrien bzero(pmsg, sizeof(*pmsg)); 163315582Spfg pmsg->sadb_msg_version = PF_KEY_V2; 16485587Sobrien pmsg->sadb_msg_type = SADB_X_PROMISC; 16585587Sobrien pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); 16685587Sobrien /* pid and seq? */ 16785587Sobrien 16885587Sobrien PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]); 16985587Sobrien } 17085587Sobrien 17185587Sobrien if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, 17285587Sobrien m, NULL)) { 17385587Sobrien PFKEYSTAT_INC(in_nomem); 17485587Sobrien m_freem(m); 17585587Sobrien error = ENOBUFS; 17685587Sobrien } else 17785587Sobrien error = 0; 17885587Sobrien sorwakeup(rp->rcb_socket); 17985587Sobrien return error; 18085587Sobrien} 18185587Sobrien 18285587Sobrien/* XXX this interface should be obsoleted. */ 18385587Sobrienint 18485587Sobrienkey_sendup(so, msg, len, target) 18585587Sobrien struct socket *so; 18685587Sobrien struct sadb_msg *msg; 18785587Sobrien u_int len; 18885587Sobrien int target; /*target of the resulting message*/ 189170331Srafan{ 19085587Sobrien struct mbuf *m, *n, *mprev; 19185587Sobrien int tlen; 19285587Sobrien 19385587Sobrien /* sanity check */ 19485587Sobrien if (so == 0 || msg == 0) 19585587Sobrien panic("%s: NULL pointer was passed.\n", __func__); 19685587Sobrien 19785587Sobrien KEYDEBUG(KEYDEBUG_KEY_DUMP, 19885587Sobrien printf("%s: \n", __func__); 19985587Sobrien kdebug_sadb(msg)); 20085587Sobrien 20185587Sobrien /* 20285587Sobrien * we increment statistics here, just in case we have ENOBUFS 20385587Sobrien * in this function. 20485587Sobrien */ 20585587Sobrien PFKEYSTAT_INC(in_total); 20685587Sobrien PFKEYSTAT_ADD(in_bytes, len); 20785587Sobrien PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 20885587Sobrien 20985587Sobrien /* 21085587Sobrien * Get mbuf chain whenever possible (not clusters), 21185587Sobrien * to save socket buffer. We'll be generating many SADB_ACQUIRE 21285587Sobrien * messages to listening key sockets. If we simply allocate clusters, 21385587Sobrien * sbappendaddr() will raise ENOBUFS due to too little sbspace(). 214170331Srafan * sbspace() computes # of actual data bytes AND mbuf region. 21585587Sobrien * 21685587Sobrien * TODO: SADB_ACQUIRE filters should be implemented. 21785587Sobrien */ 21885587Sobrien tlen = len; 21985587Sobrien m = mprev = NULL; 22085587Sobrien while (tlen > 0) { 22185587Sobrien if (tlen == len) { 22285587Sobrien MGETHDR(n, M_NOWAIT, MT_DATA); 22385587Sobrien if (n == NULL) { 22485587Sobrien PFKEYSTAT_INC(in_nomem); 22585587Sobrien return ENOBUFS; 22685587Sobrien } 22785587Sobrien n->m_len = MHLEN; 22885587Sobrien } else { 22985587Sobrien MGET(n, M_NOWAIT, MT_DATA); 23085587Sobrien if (n == NULL) { 23185587Sobrien PFKEYSTAT_INC(in_nomem); 23285587Sobrien return ENOBUFS; 23385587Sobrien } 23485587Sobrien n->m_len = MLEN; 23585587Sobrien } 23685587Sobrien if (tlen >= MCLBYTES) { /*XXX better threshold? */ 237224731Sru MCLGET(n, M_NOWAIT); 23885587Sobrien if ((n->m_flags & M_EXT) == 0) { 23985587Sobrien m_free(n); 24085587Sobrien m_freem(m); 24185587Sobrien PFKEYSTAT_INC(in_nomem); 24285587Sobrien return ENOBUFS; 24385587Sobrien } 24485587Sobrien n->m_len = MCLBYTES; 24585587Sobrien } 24685587Sobrien 24785587Sobrien if (tlen < n->m_len) 24885587Sobrien n->m_len = tlen; 24985587Sobrien n->m_next = NULL; 25085587Sobrien if (m == NULL) 251224731Sru m = mprev = n; 25285587Sobrien else { 25385587Sobrien mprev->m_next = n; 25485587Sobrien mprev = n; 25585587Sobrien } 25685587Sobrien tlen -= n->m_len; 257224731Sru n = NULL; 25885587Sobrien } 25985587Sobrien m->m_pkthdr.len = len; 260224731Sru m->m_pkthdr.rcvif = NULL; 26185587Sobrien m_copyback(m, 0, len, (caddr_t)msg); 26285587Sobrien 26385587Sobrien /* avoid duplicated statistics */ 26485587Sobrien PFKEYSTAT_ADD(in_total, -1); 26585587Sobrien PFKEYSTAT_ADD(in_bytes, -len); 26685587Sobrien PFKEYSTAT_ADD(in_msgtype[msg->sadb_msg_type], -1); 26785587Sobrien 26885587Sobrien return key_sendup_mbuf(so, m, target); 26985587Sobrien} 27085587Sobrien 27185587Sobrien/* so can be NULL if target != KEY_SENDUP_ONE */ 27285587Sobrienint 27385587Sobrienkey_sendup_mbuf(so, m, target) 27485587Sobrien struct socket *so; 27585587Sobrien struct mbuf *m; 27685587Sobrien int target; 27785587Sobrien{ 27885587Sobrien struct mbuf *n; 27985587Sobrien struct keycb *kp; 28085587Sobrien int sendup; 28185587Sobrien struct rawcb *rp; 28285587Sobrien int error = 0; 28385587Sobrien 28485587Sobrien if (m == NULL) 28585587Sobrien panic("key_sendup_mbuf: NULL pointer was passed.\n"); 28685587Sobrien if (so == NULL && target == KEY_SENDUP_ONE) 28785587Sobrien panic("%s: NULL pointer was passed.\n", __func__); 28885587Sobrien 28985587Sobrien PFKEYSTAT_INC(in_total); 29085587Sobrien PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len); 291201989Sru if (m->m_len < sizeof(struct sadb_msg)) { 292201989Sru m = m_pullup(m, sizeof(struct sadb_msg)); 293201989Sru if (m == NULL) { 294201989Sru PFKEYSTAT_INC(in_nomem); 295201989Sru return ENOBUFS; 296201989Sru } 297201989Sru } 298201989Sru if (m->m_len >= sizeof(struct sadb_msg)) { 299201989Sru struct sadb_msg *msg; 300201989Sru msg = mtod(m, struct sadb_msg *); 301201989Sru PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 302107806Sobrien } 303107806Sobrien mtx_lock(&rawcb_mtx); 30485587Sobrien LIST_FOREACH(rp, &V_rawcb_list, list) 305201989Sru { 30685587Sobrien if (rp->rcb_proto.sp_family != PF_KEY) 30785587Sobrien continue; 30885587Sobrien if (rp->rcb_proto.sp_protocol 30985587Sobrien && rp->rcb_proto.sp_protocol != PF_KEY_V2) { 31085587Sobrien continue; 31185587Sobrien } 31285587Sobrien 31385587Sobrien kp = (struct keycb *)rp; 31485587Sobrien 31585587Sobrien /* 31685587Sobrien * If you are in promiscuous mode, and when you get broadcasted 317224731Sru * reply, you'll get two PF_KEY messages. 31885587Sobrien * (based on pf_key@inner.net message on 14 Oct 1998) 31985587Sobrien */ 32085587Sobrien if (((struct keycb *)rp)->kp_promisc) { 32185587Sobrien if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { 32285587Sobrien (void)key_sendup0(rp, n, 1); 323224731Sru n = NULL; 324201989Sru } 32585587Sobrien } 32685587Sobrien 32785587Sobrien /* the exact target will be processed later */ 32885587Sobrien if (so && sotorawcb(so) == rp) 329201989Sru continue; 330201989Sru 331201989Sru sendup = 0; 332201989Sru switch (target) { 333170331Srafan case KEY_SENDUP_ONE: 33485587Sobrien /* the statement has no effect */ 335201989Sru if (so && sotorawcb(so) == rp) 33685587Sobrien sendup++; 33785587Sobrien break; 33885587Sobrien case KEY_SENDUP_ALL: 33985587Sobrien sendup++; 34085587Sobrien break; 341170331Srafan case KEY_SENDUP_REGISTERED: 34285587Sobrien if (kp->kp_registered) 34385587Sobrien sendup++; 34485587Sobrien break; 34585587Sobrien } 34685587Sobrien PFKEYSTAT_INC(in_msgtarget[target]); 34785587Sobrien 34885587Sobrien if (!sendup) 34985587Sobrien continue; 35085587Sobrien 35185587Sobrien if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) { 352107806Sobrien m_freem(m); 35385587Sobrien PFKEYSTAT_INC(in_nomem); 35485587Sobrien mtx_unlock(&rawcb_mtx); 35585587Sobrien return ENOBUFS; 35685587Sobrien } 35785587Sobrien 35885587Sobrien if ((error = key_sendup0(rp, n, 0)) != 0) { 35985587Sobrien m_freem(m); 36085587Sobrien mtx_unlock(&rawcb_mtx); 36185587Sobrien return error; 36285587Sobrien } 363170331Srafan 36485587Sobrien n = NULL; 36585587Sobrien } 36685587Sobrien 36785587Sobrien if (so) { 36885587Sobrien error = key_sendup0(sotorawcb(so), m, 0); 36985587Sobrien m = NULL; 37085587Sobrien } else { 37185587Sobrien error = 0; 37285587Sobrien m_freem(m); 37385587Sobrien } 37485587Sobrien mtx_unlock(&rawcb_mtx); 37585587Sobrien return error; 37685587Sobrien} 37785587Sobrien 378315582Spfg/* 37985587Sobrien * key_abort() 38085587Sobrien * derived from net/rtsock.c:rts_abort() 38185587Sobrien */ 38285587Sobrienstatic void 38385587Sobrienkey_abort(struct socket *so) 38485587Sobrien{ 38585587Sobrien raw_usrreqs.pru_abort(so); 38685587Sobrien} 38785587Sobrien 38885587Sobrien/* 38985587Sobrien * key_attach() 39085587Sobrien * derived from net/rtsock.c:rts_attach() 39185587Sobrien */ 39285587Sobrienstatic int 39385587Sobrienkey_attach(struct socket *so, int proto, struct thread *td) 39485587Sobrien{ 39585587Sobrien struct keycb *kp; 39685587Sobrien int error; 39785587Sobrien 39885587Sobrien KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL")); 39985587Sobrien 400170331Srafan if (td != NULL) { 40185587Sobrien error = priv_check(td, PRIV_NET_RAW); 40285587Sobrien if (error) 40385587Sobrien return error; 40485587Sobrien } 405170331Srafan 40685587Sobrien /* XXX */ 40785587Sobrien kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 40885587Sobrien if (kp == 0) 40985587Sobrien return ENOBUFS; 41085587Sobrien 41185587Sobrien so->so_pcb = (caddr_t)kp; 41285587Sobrien error = raw_attach(so, proto); 41385587Sobrien kp = (struct keycb *)sotorawcb(so); 41485587Sobrien if (error) { 415170331Srafan free(kp, M_PCB); 416170331Srafan so->so_pcb = (caddr_t) 0; 417170331Srafan return error; 418170331Srafan } 41985587Sobrien 42085587Sobrien kp->kp_promisc = kp->kp_registered = 0; 42185587Sobrien 42285587Sobrien if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ 42385587Sobrien V_key_cb.key_count++; 42485587Sobrien V_key_cb.any_count++; 42585587Sobrien soisconnected(so); 42685587Sobrien so->so_options |= SO_USELOOPBACK; 42785587Sobrien 42885587Sobrien return 0; 42985587Sobrien} 43085587Sobrien 43185587Sobrien/* 43285587Sobrien * key_bind() 43385587Sobrien * derived from net/rtsock.c:rts_bind() 43485587Sobrien */ 43585587Sobrienstatic int 43685587Sobrienkey_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 43785587Sobrien{ 43885587Sobrien return EINVAL; 43985587Sobrien} 44085587Sobrien 44185587Sobrien/* 44285587Sobrien * key_close() 44385587Sobrien * derived from net/rtsock.c:rts_close(). 44485587Sobrien */ 44585587Sobrienstatic void 44685587Sobrienkey_close(struct socket *so) 44785587Sobrien{ 44885587Sobrien 44985587Sobrien raw_usrreqs.pru_close(so); 45085587Sobrien} 45185587Sobrien 45285587Sobrien/* 45385587Sobrien * key_connect() 45485587Sobrien * derived from net/rtsock.c:rts_connect() 45585587Sobrien */ 45685587Sobrienstatic int 45785587Sobrienkey_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 45885587Sobrien{ 45985587Sobrien return EINVAL; 46085587Sobrien} 46185587Sobrien 46285587Sobrien/* 46385587Sobrien * key_detach() 46485587Sobrien * derived from net/rtsock.c:rts_detach() 46585587Sobrien */ 46685587Sobrienstatic void 46785587Sobrienkey_detach(struct socket *so) 46885587Sobrien{ 46985587Sobrien struct keycb *kp = (struct keycb *)sotorawcb(so); 47085587Sobrien 47185587Sobrien KASSERT(kp != NULL, ("key_detach: kp == NULL")); 47285587Sobrien if (kp->kp_raw.rcb_proto.sp_protocol 47385587Sobrien == PF_KEY) /* XXX: AF_KEY */ 47485587Sobrien V_key_cb.key_count--; 47585587Sobrien V_key_cb.any_count--; 476107806Sobrien 47785587Sobrien key_freereg(so); 47885587Sobrien raw_usrreqs.pru_detach(so); 47985587Sobrien} 48085587Sobrien 48185587Sobrien/* 48285587Sobrien * key_disconnect() 48385587Sobrien * derived from net/rtsock.c:key_disconnect() 48485587Sobrien */ 48585587Sobrienstatic int 486107806Sobrienkey_disconnect(struct socket *so) 48785587Sobrien{ 48885587Sobrien return(raw_usrreqs.pru_disconnect(so)); 48985587Sobrien} 49085587Sobrien 49185587Sobrien/* 49285587Sobrien * key_peeraddr() 49385587Sobrien * derived from net/rtsock.c:rts_peeraddr() 49485587Sobrien */ 495170331Srafanstatic int 49685587Sobrienkey_peeraddr(struct socket *so, struct sockaddr **nam) 49785587Sobrien{ 49885587Sobrien return(raw_usrreqs.pru_peeraddr(so, nam)); 49985587Sobrien} 50085587Sobrien 50185587Sobrien/* 50285587Sobrien * key_send() 50385587Sobrien * derived from net/rtsock.c:rts_send() 50485587Sobrien */ 50585587Sobrienstatic int 506107806Sobrienkey_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 50785587Sobrien struct mbuf *control, struct thread *td) 50885587Sobrien{ 50985587Sobrien return(raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 51085587Sobrien} 51185587Sobrien 51285587Sobrien/* 513125601Sru * key_shutdown() 514125601Sru * derived from net/rtsock.c:rts_shutdown() 515125601Sru */ 516125601Srustatic int 517125601Srukey_shutdown(struct socket *so) 518125601Sru{ 51985587Sobrien return(raw_usrreqs.pru_shutdown(so)); 52085587Sobrien} 52185587Sobrien 52285587Sobrien/* 52385587Sobrien * key_sockaddr() 52485587Sobrien * derived from net/rtsock.c:rts_sockaddr() 52585587Sobrien */ 526170331Srafanstatic int 52785587Sobrienkey_sockaddr(struct socket *so, struct sockaddr **nam) 52885587Sobrien{ 52985587Sobrien return(raw_usrreqs.pru_sockaddr(so, nam)); 53085587Sobrien} 53185587Sobrien 53285587Sobrienstruct pr_usrreqs key_usrreqs = { 53385587Sobrien .pru_abort = key_abort, 53485587Sobrien .pru_attach = key_attach, 53585587Sobrien .pru_bind = key_bind, 53685587Sobrien .pru_connect = key_connect, 53785587Sobrien .pru_detach = key_detach, 53885587Sobrien .pru_disconnect = key_disconnect, 53985587Sobrien .pru_peeraddr = key_peeraddr, 54085587Sobrien .pru_send = key_send, 54185587Sobrien .pru_shutdown = key_shutdown, 54285587Sobrien .pru_sockaddr = key_sockaddr, 54385587Sobrien .pru_close = key_close, 54485587Sobrien}; 54585587Sobrien 54685587Sobrien/* sysctl */ 54785587SobrienSYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family"); 54885587Sobrien 54985587Sobrien/* 55085587Sobrien * Definitions of protocols supported in the KEY domain. 55185587Sobrien */ 552315582Spfg 55385587Sobrienextern struct domain keydomain; 55485587Sobrien 55585587Sobrienstruct protosw keysw[] = { 55685587Sobrien{ 55785587Sobrien .pr_type = SOCK_RAW, 55885587Sobrien .pr_domain = &keydomain, 55985587Sobrien .pr_protocol = PF_KEY_V2, 56085587Sobrien .pr_flags = PR_ATOMIC|PR_ADDR, 56185587Sobrien .pr_output = key_output, 56285587Sobrien .pr_ctlinput = raw_ctlinput, 56385587Sobrien .pr_init = raw_init, 56485587Sobrien .pr_usrreqs = &key_usrreqs 565107806Sobrien} 56685587Sobrien}; 56785587Sobrien 56885587Sobrienstatic void 56985587Sobrienkey_init0(void) 57085587Sobrien{ 57185587Sobrien 572125601Sru bzero((caddr_t)&V_key_cb, sizeof(V_key_cb)); 573125601Sru key_init(); 574125601Sru} 575125601Sru 576125601Srustruct domain keydomain = { 577125601Sru .dom_family = PF_KEY, 57885587Sobrien .dom_name = "key", 57985587Sobrien .dom_init = key_init0, 58085587Sobrien#ifdef VIMAGE 58185587Sobrien .dom_destroy = key_destroy, 58285587Sobrien#endif 58385587Sobrien .dom_protosw = keysw, 584170331Srafan .dom_protoswNPROTOSW = &keysw[sizeof(keysw)/sizeof(keysw[0])] 58585587Sobrien}; 58685587Sobrien 58785587SobrienVNET_DOMAIN_SET(key); 58885587Sobrien