keysock.c revision 259065
11590Srgrimes/* $FreeBSD: releng/10.0/sys/netipsec/keysock.c 253088 2013-07-09 10:08:13Z ae $ */ 21590Srgrimes/* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ 31590Srgrimes 41590Srgrimes/*- 51590Srgrimes * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 61590Srgrimes * All rights reserved. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 1. Redistributions of source code must retain the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer. 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 3. Neither the name of the project nor the names of its contributors 171590Srgrimes * may be used to endorse or promote products derived from this software 181590Srgrimes * without specific prior written permission. 191590Srgrimes * 201590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 211590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 241590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301590Srgrimes * SUCH DAMAGE. 311590Srgrimes */ 321590Srgrimes 331590Srgrimes#include "opt_ipsec.h" 341590Srgrimes 351590Srgrimes/* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ 361590Srgrimes 371590Srgrimes#include <sys/types.h> 381590Srgrimes#include <sys/param.h> 391590Srgrimes#include <sys/domain.h> 401590Srgrimes#include <sys/errno.h> 411590Srgrimes#include <sys/kernel.h> 421590Srgrimes#include <sys/lock.h> 431590Srgrimes#include <sys/malloc.h> 441590Srgrimes#include <sys/mbuf.h> 451590Srgrimes#include <sys/mutex.h> 461590Srgrimes#include <sys/priv.h> 471590Srgrimes#include <sys/protosw.h> 481590Srgrimes#include <sys/signalvar.h> 491590Srgrimes#include <sys/socket.h> 501590Srgrimes#include <sys/socketvar.h> 511590Srgrimes#include <sys/sysctl.h> 521590Srgrimes#include <sys/systm.h> 531590Srgrimes 541590Srgrimes#include <net/if.h> 551590Srgrimes#include <net/raw_cb.h> 561590Srgrimes#include <net/route.h> 571590Srgrimes#include <net/vnet.h> 581590Srgrimes 591590Srgrimes#include <netinet/in.h> 601590Srgrimes 611590Srgrimes#include <net/pfkeyv2.h> 621590Srgrimes#include <netipsec/key.h> 631590Srgrimes#include <netipsec/keysock.h> 641590Srgrimes#include <netipsec/key_debug.h> 651590Srgrimes#include <netipsec/ipsec.h> 661590Srgrimes 671590Srgrimes#include <machine/stdarg.h> 681590Srgrimes 691590Srgrimesstruct key_cb { 701590Srgrimes int key_count; 711590Srgrimes int any_count; 721590Srgrimes}; 731590Srgrimesstatic VNET_DEFINE(struct key_cb, key_cb); 741590Srgrimes#define V_key_cb VNET(key_cb) 751590Srgrimes 761590Srgrimesstatic struct sockaddr key_src = { 2, PF_KEY, }; 771590Srgrimes 781590Srgrimesstatic int key_sendup0 __P((struct rawcb *, struct mbuf *, int)); 791590Srgrimes 801590SrgrimesVNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat); 811590SrgrimesVNET_PCPUSTAT_SYSINIT(pfkeystat); 821590Srgrimes 831590Srgrimes#ifdef VIMAGE 841590SrgrimesVNET_PCPUSTAT_SYSUNINIT(pfkeystat); 851590Srgrimes#endif /* VIMAGE */ 861590Srgrimes 871590Srgrimes/* 881590Srgrimes * key_output() 891590Srgrimes */ 901590Srgrimesint 911590Srgrimeskey_output(struct mbuf *m, struct socket *so) 921590Srgrimes{ 931590Srgrimes struct sadb_msg *msg; 948874Srgrimes int len, error = 0; 951590Srgrimes 961590Srgrimes if (m == 0) 971590Srgrimes panic("%s: NULL pointer was passed.\n", __func__); 981590Srgrimes 991590Srgrimes PFKEYSTAT_INC(out_total); 1001590Srgrimes PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len); 1011590Srgrimes 1021590Srgrimes len = m->m_pkthdr.len; 1031590Srgrimes if (len < sizeof(struct sadb_msg)) { 1041590Srgrimes PFKEYSTAT_INC(out_tooshort); 1051590Srgrimes error = EINVAL; 1061590Srgrimes goto end; 1071590Srgrimes } 1081590Srgrimes 1091590Srgrimes if (m->m_len < sizeof(struct sadb_msg)) { 1101590Srgrimes if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) { 1111590Srgrimes PFKEYSTAT_INC(out_nomem); 1121590Srgrimes error = ENOBUFS; 1131590Srgrimes goto end; 1141590Srgrimes } 1151590Srgrimes } 1161590Srgrimes 1171590Srgrimes M_ASSERTPKTHDR(m); 1181590Srgrimes 1191590Srgrimes KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m)); 1201590Srgrimes 1211590Srgrimes msg = mtod(m, struct sadb_msg *); 1221590Srgrimes PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]); 1231590Srgrimes if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { 1241590Srgrimes PFKEYSTAT_INC(out_invlen); 1251590Srgrimes error = EINVAL; 1261590Srgrimes goto end; 1271590Srgrimes } 1281590Srgrimes 1291590Srgrimes error = key_parse(m, so); 1301590Srgrimes m = NULL; 1311590Srgrimesend: 1321590Srgrimes if (m) 1331590Srgrimes m_freem(m); 1341590Srgrimes return error; 1351590Srgrimes} 1361590Srgrimes 1371590Srgrimes/* 1381590Srgrimes * send message to the socket. 1391590Srgrimes */ 1401590Srgrimesstatic int 1411590Srgrimeskey_sendup0(rp, m, promisc) 1421590Srgrimes struct rawcb *rp; 1431590Srgrimes struct mbuf *m; 1441590Srgrimes int promisc; 1451590Srgrimes{ 1461590Srgrimes int error; 1471590Srgrimes 1481590Srgrimes if (promisc) { 1491590Srgrimes struct sadb_msg *pmsg; 1501590Srgrimes 1511590Srgrimes M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT); 1521590Srgrimes if (m && m->m_len < sizeof(struct sadb_msg)) 1531590Srgrimes m = m_pullup(m, sizeof(struct sadb_msg)); 1541590Srgrimes if (!m) { 1551590Srgrimes PFKEYSTAT_INC(in_nomem); 1561590Srgrimes m_freem(m); 1571590Srgrimes return ENOBUFS; 1581590Srgrimes } 1591590Srgrimes m->m_pkthdr.len += sizeof(*pmsg); 1601590Srgrimes 1611590Srgrimes pmsg = mtod(m, struct sadb_msg *); 1621590Srgrimes bzero(pmsg, sizeof(*pmsg)); 1631590Srgrimes pmsg->sadb_msg_version = PF_KEY_V2; 1641590Srgrimes pmsg->sadb_msg_type = SADB_X_PROMISC; 1651590Srgrimes pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); 1661590Srgrimes /* pid and seq? */ 1671590Srgrimes 1681590Srgrimes PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]); 1691590Srgrimes } 1701590Srgrimes 1711590Srgrimes if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, 1721590Srgrimes m, NULL)) { 1731590Srgrimes PFKEYSTAT_INC(in_nomem); 1741590Srgrimes m_freem(m); 1751590Srgrimes error = ENOBUFS; 1761590Srgrimes } else 1771590Srgrimes error = 0; 1781590Srgrimes sorwakeup(rp->rcb_socket); 1791590Srgrimes return error; 1801590Srgrimes} 1811590Srgrimes 1821590Srgrimes/* XXX this interface should be obsoleted. */ 1831590Srgrimesint 1841590Srgrimeskey_sendup(so, msg, len, target) 1851590Srgrimes struct socket *so; 1861590Srgrimes struct sadb_msg *msg; 1871590Srgrimes u_int len; 1881590Srgrimes int target; /*target of the resulting message*/ 1891590Srgrimes{ 1901590Srgrimes struct mbuf *m, *n, *mprev; 1911590Srgrimes int tlen; 1921590Srgrimes 1931590Srgrimes /* sanity check */ 1941590Srgrimes if (so == 0 || msg == 0) 1951590Srgrimes panic("%s: NULL pointer was passed.\n", __func__); 1961590Srgrimes 1971590Srgrimes KEYDEBUG(KEYDEBUG_KEY_DUMP, 1981590Srgrimes printf("%s: \n", __func__); 1991590Srgrimes kdebug_sadb(msg)); 2001590Srgrimes 2011590Srgrimes /* 2021590Srgrimes * we increment statistics here, just in case we have ENOBUFS 2031590Srgrimes * in this function. 2041590Srgrimes */ 2051590Srgrimes PFKEYSTAT_INC(in_total); 2061590Srgrimes PFKEYSTAT_ADD(in_bytes, len); 2071590Srgrimes PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 2081590Srgrimes 2091590Srgrimes /* 2101590Srgrimes * Get mbuf chain whenever possible (not clusters), 2111590Srgrimes * to save socket buffer. We'll be generating many SADB_ACQUIRE 2121590Srgrimes * messages to listening key sockets. If we simply allocate clusters, 2131590Srgrimes * sbappendaddr() will raise ENOBUFS due to too little sbspace(). 2141590Srgrimes * sbspace() computes # of actual data bytes AND mbuf region. 2151590Srgrimes * 2161590Srgrimes * TODO: SADB_ACQUIRE filters should be implemented. 2171590Srgrimes */ 2181590Srgrimes tlen = len; 2191590Srgrimes m = mprev = NULL; 2201590Srgrimes while (tlen > 0) { 2211590Srgrimes if (tlen == len) { 2221590Srgrimes MGETHDR(n, M_NOWAIT, MT_DATA); 2231590Srgrimes if (n == NULL) { 2241590Srgrimes PFKEYSTAT_INC(in_nomem); 2251590Srgrimes return ENOBUFS; 2261590Srgrimes } 2271590Srgrimes n->m_len = MHLEN; 2281590Srgrimes } else { 2291590Srgrimes MGET(n, M_NOWAIT, MT_DATA); 2301590Srgrimes if (n == NULL) { 2311590Srgrimes PFKEYSTAT_INC(in_nomem); 2321590Srgrimes return ENOBUFS; 2331590Srgrimes } 2341590Srgrimes n->m_len = MLEN; 2351590Srgrimes } 2361590Srgrimes if (tlen >= MCLBYTES) { /*XXX better threshold? */ 2371590Srgrimes MCLGET(n, M_NOWAIT); 2381590Srgrimes if ((n->m_flags & M_EXT) == 0) { 2391590Srgrimes m_free(n); 2401590Srgrimes m_freem(m); 2411590Srgrimes PFKEYSTAT_INC(in_nomem); 2421590Srgrimes return ENOBUFS; 2431590Srgrimes } 2441590Srgrimes n->m_len = MCLBYTES; 2451590Srgrimes } 2461590Srgrimes 2471590Srgrimes if (tlen < n->m_len) 2481590Srgrimes n->m_len = tlen; 2491590Srgrimes n->m_next = NULL; 2501590Srgrimes if (m == NULL) 2511590Srgrimes m = mprev = n; 2521590Srgrimes else { 2531590Srgrimes mprev->m_next = n; 2541590Srgrimes mprev = n; 2551590Srgrimes } 2561590Srgrimes tlen -= n->m_len; 2571590Srgrimes n = NULL; 2581590Srgrimes } 2591590Srgrimes m->m_pkthdr.len = len; 2601590Srgrimes m->m_pkthdr.rcvif = NULL; 2611590Srgrimes m_copyback(m, 0, len, (caddr_t)msg); 2621590Srgrimes 2631590Srgrimes /* avoid duplicated statistics */ 2641590Srgrimes PFKEYSTAT_ADD(in_total, -1); 2651590Srgrimes PFKEYSTAT_ADD(in_bytes, -len); 2661590Srgrimes PFKEYSTAT_ADD(in_msgtype[msg->sadb_msg_type], -1); 2671590Srgrimes 2681590Srgrimes return key_sendup_mbuf(so, m, target); 2691590Srgrimes} 2701590Srgrimes 2711590Srgrimes/* so can be NULL if target != KEY_SENDUP_ONE */ 2721590Srgrimesint 2731590Srgrimeskey_sendup_mbuf(so, m, target) 2741590Srgrimes struct socket *so; 2751590Srgrimes struct mbuf *m; 2761590Srgrimes int target; 2771590Srgrimes{ 2781590Srgrimes struct mbuf *n; 2791590Srgrimes struct keycb *kp; 2801590Srgrimes int sendup; 2811590Srgrimes struct rawcb *rp; 2821590Srgrimes int error = 0; 2831590Srgrimes 2841590Srgrimes if (m == NULL) 2851590Srgrimes panic("key_sendup_mbuf: NULL pointer was passed.\n"); 2861590Srgrimes if (so == NULL && target == KEY_SENDUP_ONE) 2871590Srgrimes panic("%s: NULL pointer was passed.\n", __func__); 2881590Srgrimes 2891590Srgrimes PFKEYSTAT_INC(in_total); 2901590Srgrimes PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len); 2911590Srgrimes if (m->m_len < sizeof(struct sadb_msg)) { 2921590Srgrimes m = m_pullup(m, sizeof(struct sadb_msg)); 2931590Srgrimes if (m == NULL) { 2941590Srgrimes PFKEYSTAT_INC(in_nomem); 2951590Srgrimes return ENOBUFS; 2961590Srgrimes } 2971590Srgrimes } 2981590Srgrimes if (m->m_len >= sizeof(struct sadb_msg)) { 2991590Srgrimes struct sadb_msg *msg; 3001590Srgrimes msg = mtod(m, struct sadb_msg *); 3011590Srgrimes PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 3021590Srgrimes } 3031590Srgrimes mtx_lock(&rawcb_mtx); 3041590Srgrimes LIST_FOREACH(rp, &V_rawcb_list, list) 3051590Srgrimes { 3061590Srgrimes if (rp->rcb_proto.sp_family != PF_KEY) 3071590Srgrimes continue; 3081590Srgrimes if (rp->rcb_proto.sp_protocol 3091590Srgrimes && rp->rcb_proto.sp_protocol != PF_KEY_V2) { 3101590Srgrimes continue; 3111590Srgrimes } 3121590Srgrimes 3131590Srgrimes kp = (struct keycb *)rp; 3141590Srgrimes 3151590Srgrimes /* 3161590Srgrimes * If you are in promiscuous mode, and when you get broadcasted 3171590Srgrimes * reply, you'll get two PF_KEY messages. 3181590Srgrimes * (based on pf_key@inner.net message on 14 Oct 1998) 3191590Srgrimes */ 3201590Srgrimes if (((struct keycb *)rp)->kp_promisc) { 3211590Srgrimes if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { 3221590Srgrimes (void)key_sendup0(rp, n, 1); 3231590Srgrimes n = NULL; 3241590Srgrimes } 3251590Srgrimes } 3261590Srgrimes 3271590Srgrimes /* the exact target will be processed later */ 3281590Srgrimes if (so && sotorawcb(so) == rp) 3291590Srgrimes continue; 3301590Srgrimes 3311590Srgrimes sendup = 0; 3321590Srgrimes switch (target) { 3331590Srgrimes case KEY_SENDUP_ONE: 3341590Srgrimes /* the statement has no effect */ 3351590Srgrimes if (so && sotorawcb(so) == rp) 3361590Srgrimes sendup++; 3371590Srgrimes break; 3381590Srgrimes case KEY_SENDUP_ALL: 3391590Srgrimes sendup++; 3401590Srgrimes break; 3411590Srgrimes case KEY_SENDUP_REGISTERED: 3421590Srgrimes if (kp->kp_registered) 3431590Srgrimes sendup++; 3441590Srgrimes break; 3451590Srgrimes } 3461590Srgrimes PFKEYSTAT_INC(in_msgtarget[target]); 3471590Srgrimes 3481590Srgrimes if (!sendup) 3491590Srgrimes continue; 3501590Srgrimes 3511590Srgrimes if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) { 3521590Srgrimes m_freem(m); 3531590Srgrimes PFKEYSTAT_INC(in_nomem); 3541590Srgrimes mtx_unlock(&rawcb_mtx); 3551590Srgrimes return ENOBUFS; 3561590Srgrimes } 3571590Srgrimes 3581590Srgrimes if ((error = key_sendup0(rp, n, 0)) != 0) { 3591590Srgrimes m_freem(m); 3601590Srgrimes mtx_unlock(&rawcb_mtx); 3611590Srgrimes return error; 3621590Srgrimes } 3631590Srgrimes 3641590Srgrimes n = NULL; 3651590Srgrimes } 3661590Srgrimes 3671590Srgrimes if (so) { 3681590Srgrimes error = key_sendup0(sotorawcb(so), m, 0); 3691590Srgrimes m = NULL; 3701590Srgrimes } else { 3711590Srgrimes error = 0; 3721590Srgrimes m_freem(m); 3731590Srgrimes } 3741590Srgrimes mtx_unlock(&rawcb_mtx); 3751590Srgrimes return error; 3761590Srgrimes} 3771590Srgrimes 3781590Srgrimes/* 3791590Srgrimes * key_abort() 3801590Srgrimes * derived from net/rtsock.c:rts_abort() 3811590Srgrimes */ 3821590Srgrimesstatic void 3831590Srgrimeskey_abort(struct socket *so) 3841590Srgrimes{ 3851590Srgrimes raw_usrreqs.pru_abort(so); 3861590Srgrimes} 3871590Srgrimes 3881590Srgrimes/* 3891590Srgrimes * key_attach() 3901590Srgrimes * derived from net/rtsock.c:rts_attach() 3911590Srgrimes */ 3921590Srgrimesstatic int 3931590Srgrimeskey_attach(struct socket *so, int proto, struct thread *td) 3941590Srgrimes{ 3951590Srgrimes struct keycb *kp; 3961590Srgrimes int error; 3971590Srgrimes 3981590Srgrimes KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL")); 3991590Srgrimes 4001590Srgrimes if (td != NULL) { 4011590Srgrimes error = priv_check(td, PRIV_NET_RAW); 4021590Srgrimes if (error) 4031590Srgrimes return error; 4041590Srgrimes } 4051590Srgrimes 4061590Srgrimes /* XXX */ 4071590Srgrimes kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 4081590Srgrimes if (kp == 0) 4091590Srgrimes return ENOBUFS; 4101590Srgrimes 4111590Srgrimes so->so_pcb = (caddr_t)kp; 4121590Srgrimes error = raw_attach(so, proto); 4131590Srgrimes kp = (struct keycb *)sotorawcb(so); 4141590Srgrimes if (error) { 4151590Srgrimes free(kp, M_PCB); 4161590Srgrimes so->so_pcb = (caddr_t) 0; 4171590Srgrimes return error; 4181590Srgrimes } 4191590Srgrimes 4201590Srgrimes kp->kp_promisc = kp->kp_registered = 0; 4211590Srgrimes 4221590Srgrimes if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ 4231590Srgrimes V_key_cb.key_count++; 4241590Srgrimes V_key_cb.any_count++; 4251590Srgrimes soisconnected(so); 4261590Srgrimes so->so_options |= SO_USELOOPBACK; 4271590Srgrimes 4281590Srgrimes return 0; 4291590Srgrimes} 4301590Srgrimes 4311590Srgrimes/* 4321590Srgrimes * key_bind() 4331590Srgrimes * derived from net/rtsock.c:rts_bind() 4341590Srgrimes */ 4351590Srgrimesstatic int 4361590Srgrimeskey_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 4371590Srgrimes{ 4381590Srgrimes return EINVAL; 4391590Srgrimes} 4401590Srgrimes 4411590Srgrimes/* 4421590Srgrimes * key_close() 4431590Srgrimes * derived from net/rtsock.c:rts_close(). 4441590Srgrimes */ 4451590Srgrimesstatic void 4461590Srgrimeskey_close(struct socket *so) 4471590Srgrimes{ 4481590Srgrimes 4491590Srgrimes raw_usrreqs.pru_close(so); 4501590Srgrimes} 4511590Srgrimes 4521590Srgrimes/* 4531590Srgrimes * key_connect() 4541590Srgrimes * derived from net/rtsock.c:rts_connect() 4551590Srgrimes */ 4561590Srgrimesstatic int 4571590Srgrimeskey_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 4581590Srgrimes{ 4591590Srgrimes return EINVAL; 4601590Srgrimes} 4611590Srgrimes 4621590Srgrimes/* 4631590Srgrimes * key_detach() 4641590Srgrimes * derived from net/rtsock.c:rts_detach() 4651590Srgrimes */ 4661590Srgrimesstatic void 4671590Srgrimeskey_detach(struct socket *so) 4681590Srgrimes{ 4691590Srgrimes struct keycb *kp = (struct keycb *)sotorawcb(so); 4701590Srgrimes 4711590Srgrimes KASSERT(kp != NULL, ("key_detach: kp == NULL")); 4721590Srgrimes if (kp->kp_raw.rcb_proto.sp_protocol 4731590Srgrimes == PF_KEY) /* XXX: AF_KEY */ 4741590Srgrimes V_key_cb.key_count--; 4751590Srgrimes V_key_cb.any_count--; 4761590Srgrimes 4771590Srgrimes key_freereg(so); 4781590Srgrimes raw_usrreqs.pru_detach(so); 4791590Srgrimes} 4801590Srgrimes 4811590Srgrimes/* 4821590Srgrimes * key_disconnect() 4831590Srgrimes * derived from net/rtsock.c:key_disconnect() 4841590Srgrimes */ 4851590Srgrimesstatic int 4861590Srgrimeskey_disconnect(struct socket *so) 4871590Srgrimes{ 4881590Srgrimes return(raw_usrreqs.pru_disconnect(so)); 4891590Srgrimes} 4901590Srgrimes 4911590Srgrimes/* 4921590Srgrimes * key_peeraddr() 4931590Srgrimes * derived from net/rtsock.c:rts_peeraddr() 4941590Srgrimes */ 4951590Srgrimesstatic int 4961590Srgrimeskey_peeraddr(struct socket *so, struct sockaddr **nam) 4971590Srgrimes{ 4981590Srgrimes return(raw_usrreqs.pru_peeraddr(so, nam)); 4991590Srgrimes} 5001590Srgrimes 5011590Srgrimes/* 5021590Srgrimes * key_send() 5031590Srgrimes * derived from net/rtsock.c:rts_send() 5041590Srgrimes */ 5051590Srgrimesstatic int 5061590Srgrimeskey_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 5071590Srgrimes struct mbuf *control, struct thread *td) 5081590Srgrimes{ 5091590Srgrimes return(raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 5101590Srgrimes} 5111590Srgrimes 5121590Srgrimes/* 5131590Srgrimes * key_shutdown() 5141590Srgrimes * derived from net/rtsock.c:rts_shutdown() 5151590Srgrimes */ 5161590Srgrimesstatic int 5171590Srgrimeskey_shutdown(struct socket *so) 5181590Srgrimes{ 5191590Srgrimes return(raw_usrreqs.pru_shutdown(so)); 5201590Srgrimes} 5211590Srgrimes 5221590Srgrimes/* 5231590Srgrimes * key_sockaddr() 5241590Srgrimes * derived from net/rtsock.c:rts_sockaddr() 5251590Srgrimes */ 5261590Srgrimesstatic int 5271590Srgrimeskey_sockaddr(struct socket *so, struct sockaddr **nam) 5281590Srgrimes{ 5291590Srgrimes return(raw_usrreqs.pru_sockaddr(so, nam)); 5301590Srgrimes} 5311590Srgrimes 5321590Srgrimesstruct pr_usrreqs key_usrreqs = { 5331590Srgrimes .pru_abort = key_abort, 5341590Srgrimes .pru_attach = key_attach, 5351590Srgrimes .pru_bind = key_bind, 5361590Srgrimes .pru_connect = key_connect, 5371590Srgrimes .pru_detach = key_detach, 5381590Srgrimes .pru_disconnect = key_disconnect, 5391590Srgrimes .pru_peeraddr = key_peeraddr, 5401590Srgrimes .pru_send = key_send, 5411590Srgrimes .pru_shutdown = key_shutdown, 5421590Srgrimes .pru_sockaddr = key_sockaddr, 5431590Srgrimes .pru_close = key_close, 5441590Srgrimes}; 5451590Srgrimes 5461590Srgrimes/* sysctl */ 5471590SrgrimesSYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family"); 5481590Srgrimes 5491590Srgrimes/* 5501590Srgrimes * Definitions of protocols supported in the KEY domain. 5511590Srgrimes */ 5521590Srgrimes 5531590Srgrimesextern struct domain keydomain; 5541590Srgrimes 5551590Srgrimesstruct protosw keysw[] = { 5561590Srgrimes{ 557 .pr_type = SOCK_RAW, 558 .pr_domain = &keydomain, 559 .pr_protocol = PF_KEY_V2, 560 .pr_flags = PR_ATOMIC|PR_ADDR, 561 .pr_output = key_output, 562 .pr_ctlinput = raw_ctlinput, 563 .pr_init = raw_init, 564 .pr_usrreqs = &key_usrreqs 565} 566}; 567 568static void 569key_init0(void) 570{ 571 572 bzero((caddr_t)&V_key_cb, sizeof(V_key_cb)); 573 key_init(); 574} 575 576struct domain keydomain = { 577 .dom_family = PF_KEY, 578 .dom_name = "key", 579 .dom_init = key_init0, 580#ifdef VIMAGE 581 .dom_destroy = key_destroy, 582#endif 583 .dom_protosw = keysw, 584 .dom_protoswNPROTOSW = &keysw[sizeof(keysw)/sizeof(keysw[0])] 585}; 586 587VNET_DOMAIN_SET(key); 588