188768458SSam Leffler /* $FreeBSD$ */ 288768458SSam Leffler /* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ 388768458SSam Leffler 4c398230bSWarner Losh /*- 551369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 651369649SPedro F. Giffuni * 788768458SSam Leffler * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 888768458SSam Leffler * All rights reserved. 988768458SSam Leffler * 1088768458SSam Leffler * Redistribution and use in source and binary forms, with or without 1188768458SSam Leffler * modification, are permitted provided that the following conditions 1288768458SSam Leffler * are met: 1388768458SSam Leffler * 1. Redistributions of source code must retain the above copyright 1488768458SSam Leffler * notice, this list of conditions and the following disclaimer. 1588768458SSam Leffler * 2. Redistributions in binary form must reproduce the above copyright 1688768458SSam Leffler * notice, this list of conditions and the following disclaimer in the 1788768458SSam Leffler * documentation and/or other materials provided with the distribution. 1888768458SSam Leffler * 3. Neither the name of the project nor the names of its contributors 1988768458SSam Leffler * may be used to endorse or promote products derived from this software 2088768458SSam Leffler * without specific prior written permission. 2188768458SSam Leffler * 2288768458SSam Leffler * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2388768458SSam Leffler * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2488768458SSam Leffler * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2588768458SSam Leffler * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2688768458SSam Leffler * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2788768458SSam Leffler * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2888768458SSam Leffler * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2988768458SSam Leffler * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3088768458SSam Leffler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3188768458SSam Leffler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3288768458SSam Leffler * SUCH DAMAGE. 3388768458SSam Leffler */ 3488768458SSam Leffler 3588768458SSam Leffler #include "opt_ipsec.h" 3688768458SSam Leffler 3788768458SSam Leffler /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ 3888768458SSam Leffler 3988768458SSam Leffler #include <sys/types.h> 4088768458SSam Leffler #include <sys/param.h> 4188768458SSam Leffler #include <sys/domain.h> 4288768458SSam Leffler #include <sys/errno.h> 4388768458SSam Leffler #include <sys/kernel.h> 448eafa045SBruce M Simpson #include <sys/lock.h> 4588768458SSam Leffler #include <sys/malloc.h> 4688768458SSam Leffler #include <sys/mbuf.h> 478eafa045SBruce M Simpson #include <sys/mutex.h> 48190320e2SBjoern A. Zeeb #include <sys/priv.h> 4988768458SSam Leffler #include <sys/protosw.h> 5088768458SSam Leffler #include <sys/signalvar.h> 5188768458SSam Leffler #include <sys/socket.h> 5288768458SSam Leffler #include <sys/socketvar.h> 5388768458SSam Leffler #include <sys/sysctl.h> 5488768458SSam Leffler #include <sys/systm.h> 5588768458SSam Leffler 568b615593SMarko Zec #include <net/if.h> 57eedc7fd9SGleb Smirnoff #include <net/vnet.h> 5888768458SSam Leffler #include <net/raw_cb.h> 5988768458SSam Leffler 608b615593SMarko Zec #include <netinet/in.h> 618b615593SMarko Zec 6288768458SSam Leffler #include <net/pfkeyv2.h> 6388768458SSam Leffler #include <netipsec/key.h> 6488768458SSam Leffler #include <netipsec/keysock.h> 6588768458SSam Leffler #include <netipsec/key_debug.h> 668b615593SMarko Zec #include <netipsec/ipsec.h> 6788768458SSam Leffler 6888768458SSam Leffler #include <machine/stdarg.h> 6988768458SSam Leffler 70eddfbb76SRobert Watson struct key_cb { 71eddfbb76SRobert Watson int key_count; 72eddfbb76SRobert Watson int any_count; 73eddfbb76SRobert Watson }; 745f901c92SAndrew Turner VNET_DEFINE_STATIC(struct key_cb, key_cb); 751e77c105SRobert Watson #define V_key_cb VNET(key_cb) 7688768458SSam Leffler 77eddfbb76SRobert Watson static struct sockaddr key_src = { 2, PF_KEY, }; 7888768458SSam Leffler 7918961126SAndrey V. Elsukov static int key_sendup0(struct rawcb *, struct mbuf *, int); 8088768458SSam Leffler 81db8c0879SAndrey V. Elsukov VNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat); 82db8c0879SAndrey V. Elsukov VNET_PCPUSTAT_SYSINIT(pfkeystat); 83db8c0879SAndrey V. Elsukov 84db8c0879SAndrey V. Elsukov #ifdef VIMAGE 85db8c0879SAndrey V. Elsukov VNET_PCPUSTAT_SYSUNINIT(pfkeystat); 86db8c0879SAndrey V. Elsukov #endif /* VIMAGE */ 87eddfbb76SRobert Watson 8888768458SSam Leffler /* 8988768458SSam Leffler * key_output() 9088768458SSam Leffler */ 9188768458SSam Leffler int 9273d76e77SKevin Lo key_output(struct mbuf *m, struct socket *so, ...) 9388768458SSam Leffler { 9488768458SSam Leffler struct sadb_msg *msg; 9588768458SSam Leffler int len, error = 0; 9688768458SSam Leffler 97155d72c4SPedro F. Giffuni if (m == NULL) 989ffa9677SSam Leffler panic("%s: NULL pointer was passed.\n", __func__); 9988768458SSam Leffler 100a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(out_total); 101a04d64d8SAndrey V. Elsukov PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len); 10288768458SSam Leffler 10388768458SSam Leffler len = m->m_pkthdr.len; 10488768458SSam Leffler if (len < sizeof(struct sadb_msg)) { 105a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(out_tooshort); 10688768458SSam Leffler error = EINVAL; 10788768458SSam Leffler goto end; 10888768458SSam Leffler } 10988768458SSam Leffler 11088768458SSam Leffler if (m->m_len < sizeof(struct sadb_msg)) { 111155d72c4SPedro F. Giffuni if ((m = m_pullup(m, sizeof(struct sadb_msg))) == NULL) { 112a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(out_nomem); 11388768458SSam Leffler error = ENOBUFS; 11488768458SSam Leffler goto end; 11588768458SSam Leffler } 11688768458SSam Leffler } 11788768458SSam Leffler 118fe584538SDag-Erling Smørgrav M_ASSERTPKTHDR(m); 11988768458SSam Leffler 120fcf59617SAndrey V. Elsukov KEYDBG(KEY_DUMP, kdebug_mbuf(m)); 12188768458SSam Leffler 12288768458SSam Leffler msg = mtod(m, struct sadb_msg *); 123a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]); 12488768458SSam Leffler if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { 125a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(out_invlen); 12688768458SSam Leffler error = EINVAL; 12788768458SSam Leffler goto end; 12888768458SSam Leffler } 12988768458SSam Leffler 13088768458SSam Leffler error = key_parse(m, so); 13188768458SSam Leffler m = NULL; 13288768458SSam Leffler end: 13388768458SSam Leffler if (m) 13488768458SSam Leffler m_freem(m); 13588768458SSam Leffler return error; 13688768458SSam Leffler } 13788768458SSam Leffler 13888768458SSam Leffler /* 13988768458SSam Leffler * send message to the socket. 14088768458SSam Leffler */ 14188768458SSam Leffler static int 1422e84e6eaSAndrey V. Elsukov key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc) 14388768458SSam Leffler { 14488768458SSam Leffler int error; 14588768458SSam Leffler 14688768458SSam Leffler if (promisc) { 14788768458SSam Leffler struct sadb_msg *pmsg; 14888768458SSam Leffler 149eb1b1807SGleb Smirnoff M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT); 1503d6aff56SAndrey V. Elsukov if (m == NULL) { 151a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_nomem); 1523d6aff56SAndrey V. Elsukov return (ENOBUFS); 15388768458SSam Leffler } 15488768458SSam Leffler pmsg = mtod(m, struct sadb_msg *); 15588768458SSam Leffler bzero(pmsg, sizeof(*pmsg)); 15688768458SSam Leffler pmsg->sadb_msg_version = PF_KEY_V2; 15788768458SSam Leffler pmsg->sadb_msg_type = SADB_X_PROMISC; 15888768458SSam Leffler pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); 15988768458SSam Leffler /* pid and seq? */ 16088768458SSam Leffler 161a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]); 16288768458SSam Leffler } 16388768458SSam Leffler 16497021c24SMarko Zec if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, 16588768458SSam Leffler m, NULL)) { 166a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_nomem); 16788768458SSam Leffler m_freem(m); 16888768458SSam Leffler error = ENOBUFS; 16988768458SSam Leffler } else 17088768458SSam Leffler error = 0; 17188768458SSam Leffler sorwakeup(rp->rcb_socket); 17288768458SSam Leffler return error; 17388768458SSam Leffler } 17488768458SSam Leffler 17588768458SSam Leffler /* so can be NULL if target != KEY_SENDUP_ONE */ 17688768458SSam Leffler int 1772e84e6eaSAndrey V. Elsukov key_sendup_mbuf(struct socket *so, struct mbuf *m, int target) 17888768458SSam Leffler { 17988768458SSam Leffler struct mbuf *n; 18088768458SSam Leffler struct keycb *kp; 18188768458SSam Leffler struct rawcb *rp; 18288768458SSam Leffler int error = 0; 18388768458SSam Leffler 184e3004d24SAndrey V. Elsukov KASSERT(m != NULL, ("NULL mbuf pointer was passed.")); 185e3004d24SAndrey V. Elsukov KASSERT(so != NULL || target != KEY_SENDUP_ONE, 186e3004d24SAndrey V. Elsukov ("NULL socket pointer was passed.")); 187d158b221SAndrey V. Elsukov KASSERT(target == KEY_SENDUP_ONE || target == KEY_SENDUP_ALL || 188d158b221SAndrey V. Elsukov target == KEY_SENDUP_REGISTERED, ("Wrong target %d", target)); 18988768458SSam Leffler 190a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_total); 191a04d64d8SAndrey V. Elsukov PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len); 19288768458SSam Leffler if (m->m_len < sizeof(struct sadb_msg)) { 19388768458SSam Leffler m = m_pullup(m, sizeof(struct sadb_msg)); 19488768458SSam Leffler if (m == NULL) { 195a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_nomem); 19688768458SSam Leffler return ENOBUFS; 19788768458SSam Leffler } 19888768458SSam Leffler } 19988768458SSam Leffler if (m->m_len >= sizeof(struct sadb_msg)) { 20088768458SSam Leffler struct sadb_msg *msg; 20188768458SSam Leffler msg = mtod(m, struct sadb_msg *); 202a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 20388768458SSam Leffler } 2042cb64cb2SGeorge V. Neville-Neil mtx_lock(&rawcb_mtx); 205dccd41cbSAndrey V. Elsukov if (V_key_cb.any_count == 0) { 206dccd41cbSAndrey V. Elsukov mtx_unlock(&rawcb_mtx); 207dccd41cbSAndrey V. Elsukov m_freem(m); 208dccd41cbSAndrey V. Elsukov return (0); 209dccd41cbSAndrey V. Elsukov } 210603724d3SBjoern A. Zeeb LIST_FOREACH(rp, &V_rawcb_list, list) 21188768458SSam Leffler { 21288768458SSam Leffler if (rp->rcb_proto.sp_family != PF_KEY) 21388768458SSam Leffler continue; 21488768458SSam Leffler if (rp->rcb_proto.sp_protocol 21588768458SSam Leffler && rp->rcb_proto.sp_protocol != PF_KEY_V2) { 21688768458SSam Leffler continue; 21788768458SSam Leffler } 21888768458SSam Leffler 21988768458SSam Leffler /* 22088768458SSam Leffler * If you are in promiscuous mode, and when you get broadcasted 22188768458SSam Leffler * reply, you'll get two PF_KEY messages. 22288768458SSam Leffler * (based on pf_key@inner.net message on 14 Oct 1998) 22388768458SSam Leffler */ 224017a5e58SAndrey V. Elsukov kp = (struct keycb *)rp; 225017a5e58SAndrey V. Elsukov if (kp->kp_promisc) { 226017a5e58SAndrey V. Elsukov n = m_copym(m, 0, M_COPYALL, M_NOWAIT); 227017a5e58SAndrey V. Elsukov if (n != NULL) 228017a5e58SAndrey V. Elsukov key_sendup0(rp, n, 1); 229017a5e58SAndrey V. Elsukov else 230017a5e58SAndrey V. Elsukov PFKEYSTAT_INC(in_nomem); 23188768458SSam Leffler } 23288768458SSam Leffler 23388768458SSam Leffler /* the exact target will be processed later */ 23488768458SSam Leffler if (so && sotorawcb(so) == rp) 23588768458SSam Leffler continue; 23688768458SSam Leffler 237017a5e58SAndrey V. Elsukov if (target == KEY_SENDUP_ONE || ( 238017a5e58SAndrey V. Elsukov target == KEY_SENDUP_REGISTERED && kp->kp_registered == 0)) 23988768458SSam Leffler continue; 24088768458SSam Leffler 241017a5e58SAndrey V. Elsukov /* KEY_SENDUP_ALL + KEY_SENDUP_REGISTERED */ 242017a5e58SAndrey V. Elsukov n = m_copym(m, 0, M_COPYALL, M_NOWAIT); 243017a5e58SAndrey V. Elsukov if (n == NULL) { 244a04d64d8SAndrey V. Elsukov PFKEYSTAT_INC(in_nomem); 245017a5e58SAndrey V. Elsukov /* Try send to another socket */ 246017a5e58SAndrey V. Elsukov continue; 24788768458SSam Leffler } 24888768458SSam Leffler 249017a5e58SAndrey V. Elsukov if (key_sendup0(rp, n, 0) == 0) 250017a5e58SAndrey V. Elsukov PFKEYSTAT_INC(in_msgtarget[target]); 25188768458SSam Leffler } 25288768458SSam Leffler 253017a5e58SAndrey V. Elsukov if (so) { /* KEY_SENDUP_ONE */ 25488768458SSam Leffler error = key_sendup0(sotorawcb(so), m, 0); 255017a5e58SAndrey V. Elsukov if (error == 0) 256017a5e58SAndrey V. Elsukov PFKEYSTAT_INC(in_msgtarget[KEY_SENDUP_ONE]); 25788768458SSam Leffler } else { 25888768458SSam Leffler error = 0; 25988768458SSam Leffler m_freem(m); 26088768458SSam Leffler } 2612cb64cb2SGeorge V. Neville-Neil mtx_unlock(&rawcb_mtx); 262017a5e58SAndrey V. Elsukov return (error); 26388768458SSam Leffler } 26488768458SSam Leffler 26588768458SSam Leffler /* 26688768458SSam Leffler * key_abort() 26788768458SSam Leffler * derived from net/rtsock.c:rts_abort() 26888768458SSam Leffler */ 269ac45e92fSRobert Watson static void 27088768458SSam Leffler key_abort(struct socket *so) 27188768458SSam Leffler { 272ac45e92fSRobert Watson raw_usrreqs.pru_abort(so); 27388768458SSam Leffler } 27488768458SSam Leffler 27588768458SSam Leffler /* 27688768458SSam Leffler * key_attach() 27788768458SSam Leffler * derived from net/rtsock.c:rts_attach() 27888768458SSam Leffler */ 27988768458SSam Leffler static int 28088768458SSam Leffler key_attach(struct socket *so, int proto, struct thread *td) 28188768458SSam Leffler { 28288768458SSam Leffler struct keycb *kp; 2832cb64cb2SGeorge V. Neville-Neil int error; 28488768458SSam Leffler 2852cb64cb2SGeorge V. Neville-Neil KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL")); 2862cb64cb2SGeorge V. Neville-Neil 287cf94a6a9SBjoern A. Zeeb if (td != NULL) { 288cf94a6a9SBjoern A. Zeeb error = priv_check(td, PRIV_NET_RAW); 289cf94a6a9SBjoern A. Zeeb if (error) 290cf94a6a9SBjoern A. Zeeb return error; 291cf94a6a9SBjoern A. Zeeb } 292cf94a6a9SBjoern A. Zeeb 2932cb64cb2SGeorge V. Neville-Neil /* XXX */ 2941ede983cSDag-Erling Smørgrav kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 295155d72c4SPedro F. Giffuni if (kp == NULL) 29688768458SSam Leffler return ENOBUFS; 29788768458SSam Leffler 29888768458SSam Leffler so->so_pcb = (caddr_t)kp; 2992cb64cb2SGeorge V. Neville-Neil error = raw_attach(so, proto); 30088768458SSam Leffler kp = (struct keycb *)sotorawcb(so); 30188768458SSam Leffler if (error) { 30288768458SSam Leffler free(kp, M_PCB); 30388768458SSam Leffler so->so_pcb = (caddr_t) 0; 30488768458SSam Leffler return error; 30588768458SSam Leffler } 30688768458SSam Leffler 30788768458SSam Leffler kp->kp_promisc = kp->kp_registered = 0; 30888768458SSam Leffler 30988768458SSam Leffler if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ 310603724d3SBjoern A. Zeeb V_key_cb.key_count++; 311603724d3SBjoern A. Zeeb V_key_cb.any_count++; 31288768458SSam Leffler soisconnected(so); 31388768458SSam Leffler so->so_options |= SO_USELOOPBACK; 31488768458SSam Leffler 31588768458SSam Leffler return 0; 31688768458SSam Leffler } 31788768458SSam Leffler 31888768458SSam Leffler /* 31988768458SSam Leffler * key_bind() 32088768458SSam Leffler * derived from net/rtsock.c:rts_bind() 32188768458SSam Leffler */ 32288768458SSam Leffler static int 32388768458SSam Leffler key_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 32488768458SSam Leffler { 3252cb64cb2SGeorge V. Neville-Neil return EINVAL; 32688768458SSam Leffler } 32788768458SSam Leffler 32888768458SSam Leffler /* 329a152f8a3SRobert Watson * key_close() 330a152f8a3SRobert Watson * derived from net/rtsock.c:rts_close(). 331a152f8a3SRobert Watson */ 332a152f8a3SRobert Watson static void 33387b4dfd5SGeorge V. Neville-Neil key_close(struct socket *so) 334a152f8a3SRobert Watson { 335a152f8a3SRobert Watson 336a152f8a3SRobert Watson raw_usrreqs.pru_close(so); 337a152f8a3SRobert Watson } 338a152f8a3SRobert Watson 339a152f8a3SRobert Watson /* 34088768458SSam Leffler * key_connect() 34188768458SSam Leffler * derived from net/rtsock.c:rts_connect() 34288768458SSam Leffler */ 34388768458SSam Leffler static int 34488768458SSam Leffler key_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 34588768458SSam Leffler { 3462cb64cb2SGeorge V. Neville-Neil return EINVAL; 34788768458SSam Leffler } 34888768458SSam Leffler 34988768458SSam Leffler /* 35088768458SSam Leffler * key_detach() 35188768458SSam Leffler * derived from net/rtsock.c:rts_detach() 35288768458SSam Leffler */ 353bc725eafSRobert Watson static void 35488768458SSam Leffler key_detach(struct socket *so) 35588768458SSam Leffler { 35688768458SSam Leffler struct keycb *kp = (struct keycb *)sotorawcb(so); 35788768458SSam Leffler 358bc725eafSRobert Watson KASSERT(kp != NULL, ("key_detach: kp == NULL")); 35988768458SSam Leffler if (kp->kp_raw.rcb_proto.sp_protocol 36088768458SSam Leffler == PF_KEY) /* XXX: AF_KEY */ 361603724d3SBjoern A. Zeeb V_key_cb.key_count--; 362603724d3SBjoern A. Zeeb V_key_cb.any_count--; 36388768458SSam Leffler 36488768458SSam Leffler key_freereg(so); 365bc725eafSRobert Watson raw_usrreqs.pru_detach(so); 36688768458SSam Leffler } 36788768458SSam Leffler 36888768458SSam Leffler /* 36988768458SSam Leffler * key_disconnect() 37088768458SSam Leffler * derived from net/rtsock.c:key_disconnect() 37188768458SSam Leffler */ 37288768458SSam Leffler static int 37388768458SSam Leffler key_disconnect(struct socket *so) 37488768458SSam Leffler { 3752cb64cb2SGeorge V. Neville-Neil return(raw_usrreqs.pru_disconnect(so)); 37688768458SSam Leffler } 37788768458SSam Leffler 37888768458SSam Leffler /* 37988768458SSam Leffler * key_peeraddr() 38088768458SSam Leffler * derived from net/rtsock.c:rts_peeraddr() 38188768458SSam Leffler */ 38288768458SSam Leffler static int 38388768458SSam Leffler key_peeraddr(struct socket *so, struct sockaddr **nam) 38488768458SSam Leffler { 3852cb64cb2SGeorge V. Neville-Neil return(raw_usrreqs.pru_peeraddr(so, nam)); 38688768458SSam Leffler } 38788768458SSam Leffler 38888768458SSam Leffler /* 38988768458SSam Leffler * key_send() 39088768458SSam Leffler * derived from net/rtsock.c:rts_send() 39188768458SSam Leffler */ 39288768458SSam Leffler static int 39388768458SSam Leffler key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 39488768458SSam Leffler struct mbuf *control, struct thread *td) 39588768458SSam Leffler { 3962cb64cb2SGeorge V. Neville-Neil return(raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 39788768458SSam Leffler } 39888768458SSam Leffler 39988768458SSam Leffler /* 40088768458SSam Leffler * key_shutdown() 40188768458SSam Leffler * derived from net/rtsock.c:rts_shutdown() 40288768458SSam Leffler */ 40388768458SSam Leffler static int 40488768458SSam Leffler key_shutdown(struct socket *so) 40588768458SSam Leffler { 4062cb64cb2SGeorge V. Neville-Neil return(raw_usrreqs.pru_shutdown(so)); 40788768458SSam Leffler } 40888768458SSam Leffler 40988768458SSam Leffler /* 41088768458SSam Leffler * key_sockaddr() 41188768458SSam Leffler * derived from net/rtsock.c:rts_sockaddr() 41288768458SSam Leffler */ 41388768458SSam Leffler static int 41488768458SSam Leffler key_sockaddr(struct socket *so, struct sockaddr **nam) 41588768458SSam Leffler { 4162cb64cb2SGeorge V. Neville-Neil return(raw_usrreqs.pru_sockaddr(so, nam)); 41788768458SSam Leffler } 41888768458SSam Leffler 41988768458SSam Leffler struct pr_usrreqs key_usrreqs = { 420756d52a1SPoul-Henning Kamp .pru_abort = key_abort, 421756d52a1SPoul-Henning Kamp .pru_attach = key_attach, 422756d52a1SPoul-Henning Kamp .pru_bind = key_bind, 423756d52a1SPoul-Henning Kamp .pru_connect = key_connect, 424756d52a1SPoul-Henning Kamp .pru_detach = key_detach, 425756d52a1SPoul-Henning Kamp .pru_disconnect = key_disconnect, 426756d52a1SPoul-Henning Kamp .pru_peeraddr = key_peeraddr, 427756d52a1SPoul-Henning Kamp .pru_send = key_send, 428756d52a1SPoul-Henning Kamp .pru_shutdown = key_shutdown, 429756d52a1SPoul-Henning Kamp .pru_sockaddr = key_sockaddr, 430a152f8a3SRobert Watson .pru_close = key_close, 43188768458SSam Leffler }; 43288768458SSam Leffler 43388768458SSam Leffler /* sysctl */ 434*7029da5cSPawel Biernacki SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 435*7029da5cSPawel Biernacki "Key Family"); 43688768458SSam Leffler 43788768458SSam Leffler /* 43888768458SSam Leffler * Definitions of protocols supported in the KEY domain. 43988768458SSam Leffler */ 44088768458SSam Leffler 44188768458SSam Leffler extern struct domain keydomain; 44288768458SSam Leffler 44388768458SSam Leffler struct protosw keysw[] = { 444303989a2SRuslan Ermilov { 445303989a2SRuslan Ermilov .pr_type = SOCK_RAW, 446303989a2SRuslan Ermilov .pr_domain = &keydomain, 447303989a2SRuslan Ermilov .pr_protocol = PF_KEY_V2, 448303989a2SRuslan Ermilov .pr_flags = PR_ATOMIC|PR_ADDR, 4493f2e28feSBjoern A. Zeeb .pr_output = key_output, 450303989a2SRuslan Ermilov .pr_ctlinput = raw_ctlinput, 451303989a2SRuslan Ermilov .pr_init = raw_init, 452303989a2SRuslan Ermilov .pr_usrreqs = &key_usrreqs 45388768458SSam Leffler } 45488768458SSam Leffler }; 45588768458SSam Leffler 45688768458SSam Leffler static void 45788768458SSam Leffler key_init0(void) 45888768458SSam Leffler { 45944e33a07SMarko Zec 460603724d3SBjoern A. Zeeb bzero((caddr_t)&V_key_cb, sizeof(V_key_cb)); 46188768458SSam Leffler key_init(); 46288768458SSam Leffler } 46388768458SSam Leffler 464303989a2SRuslan Ermilov struct domain keydomain = { 465303989a2SRuslan Ermilov .dom_family = PF_KEY, 466303989a2SRuslan Ermilov .dom_name = "key", 467303989a2SRuslan Ermilov .dom_init = key_init0, 468bc29160dSMarko Zec #ifdef VIMAGE 469bc29160dSMarko Zec .dom_destroy = key_destroy, 470bc29160dSMarko Zec #endif 471303989a2SRuslan Ermilov .dom_protosw = keysw, 47202abd400SPedro F. Giffuni .dom_protoswNPROTOSW = &keysw[nitems(keysw)] 473303989a2SRuslan Ermilov }; 47488768458SSam Leffler 475d0728d71SRobert Watson VNET_DOMAIN_SET(key); 476