1105197Ssam/* $FreeBSD$ */ 2105197Ssam/* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ 3105197Ssam 4139823Simp/*- 5105197Ssam * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6105197Ssam * All rights reserved. 7105197Ssam * 8105197Ssam * Redistribution and use in source and binary forms, with or without 9105197Ssam * modification, are permitted provided that the following conditions 10105197Ssam * are met: 11105197Ssam * 1. Redistributions of source code must retain the above copyright 12105197Ssam * notice, this list of conditions and the following disclaimer. 13105197Ssam * 2. Redistributions in binary form must reproduce the above copyright 14105197Ssam * notice, this list of conditions and the following disclaimer in the 15105197Ssam * documentation and/or other materials provided with the distribution. 16105197Ssam * 3. Neither the name of the project nor the names of its contributors 17105197Ssam * may be used to endorse or promote products derived from this software 18105197Ssam * without specific prior written permission. 19105197Ssam * 20105197Ssam * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21105197Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22105197Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23105197Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24105197Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25105197Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26105197Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27105197Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28105197Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29105197Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30105197Ssam * SUCH DAMAGE. 31105197Ssam */ 32105197Ssam 33105197Ssam#include "opt_ipsec.h" 34105197Ssam 35105197Ssam/* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ 36105197Ssam 37105197Ssam#include <sys/types.h> 38105197Ssam#include <sys/param.h> 39105197Ssam#include <sys/domain.h> 40105197Ssam#include <sys/errno.h> 41105197Ssam#include <sys/kernel.h> 42130955Sbms#include <sys/lock.h> 43105197Ssam#include <sys/malloc.h> 44105197Ssam#include <sys/mbuf.h> 45130955Sbms#include <sys/mutex.h> 46173574Sbz#include <sys/priv.h> 47105197Ssam#include <sys/protosw.h> 48105197Ssam#include <sys/signalvar.h> 49105197Ssam#include <sys/socket.h> 50105197Ssam#include <sys/socketvar.h> 51105197Ssam#include <sys/sysctl.h> 52105197Ssam#include <sys/systm.h> 53105197Ssam 54183550Szec#include <net/if.h> 55105197Ssam#include <net/raw_cb.h> 56185571Sbz#include <net/vnet.h> 57105197Ssam 58183550Szec#include <netinet/in.h> 59183550Szec 60105197Ssam#include <net/pfkeyv2.h> 61105197Ssam#include <netipsec/key.h> 62105197Ssam#include <netipsec/keysock.h> 63105197Ssam#include <netipsec/key_debug.h> 64183550Szec#include <netipsec/ipsec.h> 65105197Ssam 66105197Ssam#include <machine/stdarg.h> 67105197Ssam 68195699Srwatsonstruct key_cb { 69195699Srwatson int key_count; 70195699Srwatson int any_count; 71195699Srwatson}; 72215701Sdimstatic VNET_DEFINE(struct key_cb, key_cb); 73195727Srwatson#define V_key_cb VNET(key_cb) 74105197Ssam 75195699Srwatsonstatic struct sockaddr key_src = { 2, PF_KEY, }; 76105197Ssam 77283902Saestatic int key_sendup0(struct rawcb *, struct mbuf *, int); 78105197Ssam 79253088SaeVNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat); 80253088SaeVNET_PCPUSTAT_SYSINIT(pfkeystat); 81195699Srwatson 82253088Sae#ifdef VIMAGE 83253088SaeVNET_PCPUSTAT_SYSUNINIT(pfkeystat); 84253088Sae#endif /* VIMAGE */ 85253088Sae 86105197Ssam/* 87105197Ssam * key_output() 88105197Ssam */ 89105197Ssamint 90154625Sbzkey_output(struct mbuf *m, struct socket *so) 91105197Ssam{ 92105197Ssam struct sadb_msg *msg; 93105197Ssam int len, error = 0; 94105197Ssam 95105197Ssam if (m == 0) 96120585Ssam panic("%s: NULL pointer was passed.\n", __func__); 97105197Ssam 98252028Sae PFKEYSTAT_INC(out_total); 99252028Sae PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len); 100105197Ssam 101105197Ssam len = m->m_pkthdr.len; 102105197Ssam if (len < sizeof(struct sadb_msg)) { 103252028Sae PFKEYSTAT_INC(out_tooshort); 104105197Ssam error = EINVAL; 105105197Ssam goto end; 106105197Ssam } 107105197Ssam 108105197Ssam if (m->m_len < sizeof(struct sadb_msg)) { 109105197Ssam if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) { 110252028Sae PFKEYSTAT_INC(out_nomem); 111105197Ssam error = ENOBUFS; 112105197Ssam goto end; 113105197Ssam } 114105197Ssam } 115105197Ssam 116113255Sdes M_ASSERTPKTHDR(m); 117105197Ssam 118105197Ssam KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m)); 119105197Ssam 120105197Ssam msg = mtod(m, struct sadb_msg *); 121252028Sae PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]); 122105197Ssam if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { 123252028Sae PFKEYSTAT_INC(out_invlen); 124105197Ssam error = EINVAL; 125105197Ssam goto end; 126105197Ssam } 127105197Ssam 128105197Ssam error = key_parse(m, so); 129105197Ssam m = NULL; 130105197Ssamend: 131105197Ssam if (m) 132105197Ssam m_freem(m); 133105197Ssam return error; 134105197Ssam} 135105197Ssam 136105197Ssam/* 137105197Ssam * send message to the socket. 138105197Ssam */ 139105197Ssamstatic int 140283902Saekey_sendup0(struct rawcb *rp, struct mbuf *m, int promisc) 141105197Ssam{ 142105197Ssam int error; 143105197Ssam 144105197Ssam if (promisc) { 145105197Ssam struct sadb_msg *pmsg; 146105197Ssam 147243882Sglebius M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT); 148275825Sae if (m == NULL) { 149252028Sae PFKEYSTAT_INC(in_nomem); 150275825Sae return (ENOBUFS); 151105197Ssam } 152105197Ssam pmsg = mtod(m, struct sadb_msg *); 153105197Ssam bzero(pmsg, sizeof(*pmsg)); 154105197Ssam pmsg->sadb_msg_version = PF_KEY_V2; 155105197Ssam pmsg->sadb_msg_type = SADB_X_PROMISC; 156105197Ssam pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); 157105197Ssam /* pid and seq? */ 158105197Ssam 159252028Sae PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]); 160105197Ssam } 161105197Ssam 162185348Szec if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, 163105197Ssam m, NULL)) { 164252028Sae PFKEYSTAT_INC(in_nomem); 165105197Ssam m_freem(m); 166105197Ssam error = ENOBUFS; 167105197Ssam } else 168105197Ssam error = 0; 169105197Ssam sorwakeup(rp->rcb_socket); 170105197Ssam return error; 171105197Ssam} 172105197Ssam 173105197Ssam/* XXX this interface should be obsoleted. */ 174105197Ssamint 175283902Saekey_sendup(struct socket *so, struct sadb_msg *msg, u_int len, int target) 176105197Ssam{ 177105197Ssam struct mbuf *m, *n, *mprev; 178105197Ssam int tlen; 179105197Ssam 180105197Ssam /* sanity check */ 181105197Ssam if (so == 0 || msg == 0) 182120585Ssam panic("%s: NULL pointer was passed.\n", __func__); 183105197Ssam 184105197Ssam KEYDEBUG(KEYDEBUG_KEY_DUMP, 185120585Ssam printf("%s: \n", __func__); 186105197Ssam kdebug_sadb(msg)); 187105197Ssam 188105197Ssam /* 189105197Ssam * we increment statistics here, just in case we have ENOBUFS 190105197Ssam * in this function. 191105197Ssam */ 192252028Sae PFKEYSTAT_INC(in_total); 193252028Sae PFKEYSTAT_ADD(in_bytes, len); 194252028Sae PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 195105197Ssam 196105197Ssam /* 197105197Ssam * Get mbuf chain whenever possible (not clusters), 198105197Ssam * to save socket buffer. We'll be generating many SADB_ACQUIRE 199105197Ssam * messages to listening key sockets. If we simply allocate clusters, 200105197Ssam * sbappendaddr() will raise ENOBUFS due to too little sbspace(). 201105197Ssam * sbspace() computes # of actual data bytes AND mbuf region. 202105197Ssam * 203105197Ssam * TODO: SADB_ACQUIRE filters should be implemented. 204105197Ssam */ 205105197Ssam tlen = len; 206105197Ssam m = mprev = NULL; 207105197Ssam while (tlen > 0) { 208105197Ssam if (tlen == len) { 209243882Sglebius MGETHDR(n, M_NOWAIT, MT_DATA); 210171133Sgnn if (n == NULL) { 211252028Sae PFKEYSTAT_INC(in_nomem); 212171133Sgnn return ENOBUFS; 213171133Sgnn } 214105197Ssam n->m_len = MHLEN; 215105197Ssam } else { 216243882Sglebius MGET(n, M_NOWAIT, MT_DATA); 217171133Sgnn if (n == NULL) { 218252028Sae PFKEYSTAT_INC(in_nomem); 219171133Sgnn return ENOBUFS; 220171133Sgnn } 221105197Ssam n->m_len = MLEN; 222105197Ssam } 223105197Ssam if (tlen >= MCLBYTES) { /*XXX better threshold? */ 224243882Sglebius MCLGET(n, M_NOWAIT); 225105197Ssam if ((n->m_flags & M_EXT) == 0) { 226105197Ssam m_free(n); 227105197Ssam m_freem(m); 228252028Sae PFKEYSTAT_INC(in_nomem); 229105197Ssam return ENOBUFS; 230105197Ssam } 231105197Ssam n->m_len = MCLBYTES; 232105197Ssam } 233105197Ssam 234105197Ssam if (tlen < n->m_len) 235105197Ssam n->m_len = tlen; 236105197Ssam n->m_next = NULL; 237105197Ssam if (m == NULL) 238105197Ssam m = mprev = n; 239105197Ssam else { 240105197Ssam mprev->m_next = n; 241105197Ssam mprev = n; 242105197Ssam } 243105197Ssam tlen -= n->m_len; 244105197Ssam n = NULL; 245105197Ssam } 246105197Ssam m->m_pkthdr.len = len; 247105197Ssam m->m_pkthdr.rcvif = NULL; 248105197Ssam m_copyback(m, 0, len, (caddr_t)msg); 249105197Ssam 250105197Ssam /* avoid duplicated statistics */ 251252028Sae PFKEYSTAT_ADD(in_total, -1); 252252028Sae PFKEYSTAT_ADD(in_bytes, -len); 253252028Sae PFKEYSTAT_ADD(in_msgtype[msg->sadb_msg_type], -1); 254105197Ssam 255105197Ssam return key_sendup_mbuf(so, m, target); 256105197Ssam} 257105197Ssam 258105197Ssam/* so can be NULL if target != KEY_SENDUP_ONE */ 259105197Ssamint 260283902Saekey_sendup_mbuf(struct socket *so, struct mbuf *m, int target) 261105197Ssam{ 262105197Ssam struct mbuf *n; 263105197Ssam struct keycb *kp; 264105197Ssam int sendup; 265105197Ssam struct rawcb *rp; 266105197Ssam int error = 0; 267105197Ssam 268105197Ssam if (m == NULL) 269105197Ssam panic("key_sendup_mbuf: NULL pointer was passed.\n"); 270105197Ssam if (so == NULL && target == KEY_SENDUP_ONE) 271120585Ssam panic("%s: NULL pointer was passed.\n", __func__); 272105197Ssam 273252028Sae PFKEYSTAT_INC(in_total); 274252028Sae PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len); 275105197Ssam if (m->m_len < sizeof(struct sadb_msg)) { 276105197Ssam m = m_pullup(m, sizeof(struct sadb_msg)); 277105197Ssam if (m == NULL) { 278252028Sae PFKEYSTAT_INC(in_nomem); 279105197Ssam return ENOBUFS; 280105197Ssam } 281105197Ssam } 282105197Ssam if (m->m_len >= sizeof(struct sadb_msg)) { 283105197Ssam struct sadb_msg *msg; 284105197Ssam msg = mtod(m, struct sadb_msg *); 285252028Sae PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 286105197Ssam } 287171133Sgnn mtx_lock(&rawcb_mtx); 288181803Sbz LIST_FOREACH(rp, &V_rawcb_list, list) 289105197Ssam { 290105197Ssam if (rp->rcb_proto.sp_family != PF_KEY) 291105197Ssam continue; 292105197Ssam if (rp->rcb_proto.sp_protocol 293105197Ssam && rp->rcb_proto.sp_protocol != PF_KEY_V2) { 294105197Ssam continue; 295105197Ssam } 296105197Ssam 297105197Ssam kp = (struct keycb *)rp; 298105197Ssam 299105197Ssam /* 300105197Ssam * If you are in promiscuous mode, and when you get broadcasted 301105197Ssam * reply, you'll get two PF_KEY messages. 302105197Ssam * (based on pf_key@inner.net message on 14 Oct 1998) 303105197Ssam */ 304105197Ssam if (((struct keycb *)rp)->kp_promisc) { 305105197Ssam if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { 306105197Ssam (void)key_sendup0(rp, n, 1); 307105197Ssam n = NULL; 308105197Ssam } 309105197Ssam } 310105197Ssam 311105197Ssam /* the exact target will be processed later */ 312105197Ssam if (so && sotorawcb(so) == rp) 313105197Ssam continue; 314105197Ssam 315105197Ssam sendup = 0; 316105197Ssam switch (target) { 317105197Ssam case KEY_SENDUP_ONE: 318105197Ssam /* the statement has no effect */ 319105197Ssam if (so && sotorawcb(so) == rp) 320105197Ssam sendup++; 321105197Ssam break; 322105197Ssam case KEY_SENDUP_ALL: 323105197Ssam sendup++; 324105197Ssam break; 325105197Ssam case KEY_SENDUP_REGISTERED: 326105197Ssam if (kp->kp_registered) 327105197Ssam sendup++; 328105197Ssam break; 329105197Ssam } 330252028Sae PFKEYSTAT_INC(in_msgtarget[target]); 331105197Ssam 332105197Ssam if (!sendup) 333105197Ssam continue; 334105197Ssam 335105197Ssam if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) { 336105197Ssam m_freem(m); 337252028Sae PFKEYSTAT_INC(in_nomem); 338171133Sgnn mtx_unlock(&rawcb_mtx); 339105197Ssam return ENOBUFS; 340105197Ssam } 341105197Ssam 342105197Ssam if ((error = key_sendup0(rp, n, 0)) != 0) { 343105197Ssam m_freem(m); 344171133Sgnn mtx_unlock(&rawcb_mtx); 345105197Ssam return error; 346105197Ssam } 347105197Ssam 348105197Ssam n = NULL; 349105197Ssam } 350105197Ssam 351105197Ssam if (so) { 352105197Ssam error = key_sendup0(sotorawcb(so), m, 0); 353105197Ssam m = NULL; 354105197Ssam } else { 355105197Ssam error = 0; 356105197Ssam m_freem(m); 357105197Ssam } 358171133Sgnn mtx_unlock(&rawcb_mtx); 359105197Ssam return error; 360105197Ssam} 361105197Ssam 362105197Ssam/* 363105197Ssam * key_abort() 364105197Ssam * derived from net/rtsock.c:rts_abort() 365105197Ssam */ 366157366Srwatsonstatic void 367105197Ssamkey_abort(struct socket *so) 368105197Ssam{ 369157366Srwatson raw_usrreqs.pru_abort(so); 370105197Ssam} 371105197Ssam 372105197Ssam/* 373105197Ssam * key_attach() 374105197Ssam * derived from net/rtsock.c:rts_attach() 375105197Ssam */ 376105197Ssamstatic int 377105197Ssamkey_attach(struct socket *so, int proto, struct thread *td) 378105197Ssam{ 379105197Ssam struct keycb *kp; 380171133Sgnn int error; 381105197Ssam 382171133Sgnn KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL")); 383171133Sgnn 384173689Sbz if (td != NULL) { 385173689Sbz error = priv_check(td, PRIV_NET_RAW); 386173689Sbz if (error) 387173689Sbz return error; 388173689Sbz } 389173689Sbz 390171133Sgnn /* XXX */ 391184205Sdes kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 392105197Ssam if (kp == 0) 393105197Ssam return ENOBUFS; 394105197Ssam 395105197Ssam so->so_pcb = (caddr_t)kp; 396171133Sgnn error = raw_attach(so, proto); 397105197Ssam kp = (struct keycb *)sotorawcb(so); 398105197Ssam if (error) { 399105197Ssam free(kp, M_PCB); 400105197Ssam so->so_pcb = (caddr_t) 0; 401105197Ssam return error; 402105197Ssam } 403105197Ssam 404105197Ssam kp->kp_promisc = kp->kp_registered = 0; 405105197Ssam 406105197Ssam if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ 407181803Sbz V_key_cb.key_count++; 408181803Sbz V_key_cb.any_count++; 409105197Ssam soisconnected(so); 410105197Ssam so->so_options |= SO_USELOOPBACK; 411105197Ssam 412105197Ssam return 0; 413105197Ssam} 414105197Ssam 415105197Ssam/* 416105197Ssam * key_bind() 417105197Ssam * derived from net/rtsock.c:rts_bind() 418105197Ssam */ 419105197Ssamstatic int 420105197Ssamkey_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 421105197Ssam{ 422171133Sgnn return EINVAL; 423105197Ssam} 424105197Ssam 425105197Ssam/* 426160549Srwatson * key_close() 427160549Srwatson * derived from net/rtsock.c:rts_close(). 428160549Srwatson */ 429160549Srwatsonstatic void 430160566Sgnnkey_close(struct socket *so) 431160549Srwatson{ 432160549Srwatson 433160549Srwatson raw_usrreqs.pru_close(so); 434160549Srwatson} 435160549Srwatson 436160549Srwatson/* 437105197Ssam * key_connect() 438105197Ssam * derived from net/rtsock.c:rts_connect() 439105197Ssam */ 440105197Ssamstatic int 441105197Ssamkey_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 442105197Ssam{ 443171133Sgnn return EINVAL; 444105197Ssam} 445105197Ssam 446105197Ssam/* 447105197Ssam * key_detach() 448105197Ssam * derived from net/rtsock.c:rts_detach() 449105197Ssam */ 450157370Srwatsonstatic void 451105197Ssamkey_detach(struct socket *so) 452105197Ssam{ 453105197Ssam struct keycb *kp = (struct keycb *)sotorawcb(so); 454105197Ssam 455157370Srwatson KASSERT(kp != NULL, ("key_detach: kp == NULL")); 456157370Srwatson if (kp->kp_raw.rcb_proto.sp_protocol 457157370Srwatson == PF_KEY) /* XXX: AF_KEY */ 458181803Sbz V_key_cb.key_count--; 459181803Sbz V_key_cb.any_count--; 460105197Ssam 461157370Srwatson key_freereg(so); 462157370Srwatson raw_usrreqs.pru_detach(so); 463105197Ssam} 464105197Ssam 465105197Ssam/* 466105197Ssam * key_disconnect() 467105197Ssam * derived from net/rtsock.c:key_disconnect() 468105197Ssam */ 469105197Ssamstatic int 470105197Ssamkey_disconnect(struct socket *so) 471105197Ssam{ 472171133Sgnn return(raw_usrreqs.pru_disconnect(so)); 473105197Ssam} 474105197Ssam 475105197Ssam/* 476105197Ssam * key_peeraddr() 477105197Ssam * derived from net/rtsock.c:rts_peeraddr() 478105197Ssam */ 479105197Ssamstatic int 480105197Ssamkey_peeraddr(struct socket *so, struct sockaddr **nam) 481105197Ssam{ 482171133Sgnn return(raw_usrreqs.pru_peeraddr(so, nam)); 483105197Ssam} 484105197Ssam 485105197Ssam/* 486105197Ssam * key_send() 487105197Ssam * derived from net/rtsock.c:rts_send() 488105197Ssam */ 489105197Ssamstatic int 490105197Ssamkey_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 491105197Ssam struct mbuf *control, struct thread *td) 492105197Ssam{ 493171133Sgnn return(raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 494105197Ssam} 495105197Ssam 496105197Ssam/* 497105197Ssam * key_shutdown() 498105197Ssam * derived from net/rtsock.c:rts_shutdown() 499105197Ssam */ 500105197Ssamstatic int 501105197Ssamkey_shutdown(struct socket *so) 502105197Ssam{ 503171133Sgnn return(raw_usrreqs.pru_shutdown(so)); 504105197Ssam} 505105197Ssam 506105197Ssam/* 507105197Ssam * key_sockaddr() 508105197Ssam * derived from net/rtsock.c:rts_sockaddr() 509105197Ssam */ 510105197Ssamstatic int 511105197Ssamkey_sockaddr(struct socket *so, struct sockaddr **nam) 512105197Ssam{ 513171133Sgnn return(raw_usrreqs.pru_sockaddr(so, nam)); 514105197Ssam} 515105197Ssam 516105197Ssamstruct pr_usrreqs key_usrreqs = { 517137386Sphk .pru_abort = key_abort, 518137386Sphk .pru_attach = key_attach, 519137386Sphk .pru_bind = key_bind, 520137386Sphk .pru_connect = key_connect, 521137386Sphk .pru_detach = key_detach, 522137386Sphk .pru_disconnect = key_disconnect, 523137386Sphk .pru_peeraddr = key_peeraddr, 524137386Sphk .pru_send = key_send, 525137386Sphk .pru_shutdown = key_shutdown, 526137386Sphk .pru_sockaddr = key_sockaddr, 527160549Srwatson .pru_close = key_close, 528105197Ssam}; 529105197Ssam 530105197Ssam/* sysctl */ 531105197SsamSYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family"); 532105197Ssam 533105197Ssam/* 534105197Ssam * Definitions of protocols supported in the KEY domain. 535105197Ssam */ 536105197Ssam 537105197Ssamextern struct domain keydomain; 538105197Ssam 539105197Ssamstruct protosw keysw[] = { 540152242Sru{ 541152242Sru .pr_type = SOCK_RAW, 542152242Sru .pr_domain = &keydomain, 543152242Sru .pr_protocol = PF_KEY_V2, 544152242Sru .pr_flags = PR_ATOMIC|PR_ADDR, 545154625Sbz .pr_output = key_output, 546152242Sru .pr_ctlinput = raw_ctlinput, 547152242Sru .pr_init = raw_init, 548152242Sru .pr_usrreqs = &key_usrreqs 549105197Ssam} 550105197Ssam}; 551105197Ssam 552105197Ssamstatic void 553105197Ssamkey_init0(void) 554105197Ssam{ 555185088Szec 556181803Sbz bzero((caddr_t)&V_key_cb, sizeof(V_key_cb)); 557105197Ssam key_init(); 558105197Ssam} 559105197Ssam 560152242Srustruct domain keydomain = { 561152242Sru .dom_family = PF_KEY, 562152242Sru .dom_name = "key", 563152242Sru .dom_init = key_init0, 564193731Szec#ifdef VIMAGE 565193731Szec .dom_destroy = key_destroy, 566193731Szec#endif 567152242Sru .dom_protosw = keysw, 568152242Sru .dom_protoswNPROTOSW = &keysw[sizeof(keysw)/sizeof(keysw[0])] 569152242Sru}; 570105197Ssam 571195837SrwatsonVNET_DOMAIN_SET(key); 572