1 /* $NetBSD: keysock.c,v 1.17 2009/03/14 14:46:10 dsl 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 $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.17 2009/03/14 14:46:10 dsl Exp $");
37 #include "opt_ipsec.h"
39 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
41 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/domain.h>
44 #include <sys/errno.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
48 #include <sys/protosw.h>
49 #include <sys/signalvar.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sysctl.h>
53 #include <sys/systm.h>
55 #include <net/raw_cb.h>
56 #include <net/route.h>
58 #include <net/pfkeyv2.h>
59 #include <netipsec/key.h>
60 #include <netipsec/keysock.h>
61 #include <netipsec/key_debug.h>
63 #include <netipsec/ipsec_osdep.h>
64 #include <netipsec/ipsec_private.h>
66 #include <machine/stdarg.h>
68 typedef int pr_output_t (struct mbuf
*, struct socket
*);
74 static struct key_cb key_cb
;
76 static struct sockaddr key_dst
= {
80 static struct sockaddr key_src
= {
86 static int key_sendup0(struct rawcb
*, struct mbuf
*, int, int);
88 int key_registered_sb_max
= (NMBCLUSTERS
* MHLEN
); /* XXX arbitrary */
92 SYSCTL_INT(_net_key
, OID_AUTO
, registered_sbmax
, CTLFLAG_RD
,
93 &key_registered_sb_max
, 0, "Maximum kernel-to-user PFKEY datagram size");
100 key_output(struct mbuf
*m
, ...)
102 struct sadb_msg
*msg
;
109 so
= va_arg(ap
, struct socket
*);
113 panic("key_output: NULL pointer was passed");
116 uint64_t *ps
= PFKEY_STAT_GETREF();
117 ps
[PFKEY_STAT_OUT_TOTAL
]++;
118 ps
[PFKEY_STAT_OUT_BYTES
] += m
->m_pkthdr
.len
;
122 len
= m
->m_pkthdr
.len
;
123 if (len
< sizeof(struct sadb_msg
)) {
124 PFKEY_STATINC(PFKEY_STAT_OUT_TOOSHORT
);
129 if (m
->m_len
< sizeof(struct sadb_msg
)) {
130 if ((m
= m_pullup(m
, sizeof(struct sadb_msg
))) == 0) {
131 PFKEY_STATINC(PFKEY_STAT_OUT_NOMEM
);
137 if ((m
->m_flags
& M_PKTHDR
) == 0)
138 panic("key_output: not M_PKTHDR ??");
140 KEYDEBUG(KEYDEBUG_KEY_DUMP
, kdebug_mbuf(m
));
142 msg
= mtod(m
, struct sadb_msg
*);
143 PFKEY_STATINC(PFKEY_STAT_OUT_MSGTYPE
+ msg
->sadb_msg_type
);
144 if (len
!= PFKEY_UNUNIT64(msg
->sadb_msg_len
)) {
145 PFKEY_STATINC(PFKEY_STAT_OUT_INVLEN
);
152 error
= key_parse(m
, so
);
162 * send message to the socket.
176 struct sadb_msg
*pmsg
;
178 M_PREPEND(m
, sizeof(struct sadb_msg
), M_DONTWAIT
);
179 if (m
&& m
->m_len
< sizeof(struct sadb_msg
))
180 m
= m_pullup(m
, sizeof(struct sadb_msg
));
182 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
186 m
->m_pkthdr
.len
+= sizeof(*pmsg
);
188 pmsg
= mtod(m
, struct sadb_msg
*);
189 memset(pmsg
, 0, sizeof(*pmsg
));
190 pmsg
->sadb_msg_version
= PF_KEY_V2
;
191 pmsg
->sadb_msg_type
= SADB_X_PROMISC
;
192 pmsg
->sadb_msg_len
= PFKEY_UNIT64(m
->m_pkthdr
.len
);
195 PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE
+ pmsg
->sadb_msg_type
);
199 ok
= sbappendaddr(&rp
->rcb_socket
->so_rcv
,
200 (struct sockaddr
*)&key_src
, m
, NULL
);
202 ok
= sbappendaddrchain(&rp
->rcb_socket
->so_rcv
,
203 (struct sockaddr
*)&key_src
, m
, sbprio
);
206 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
211 sorwakeup(rp
->rcb_socket
);
215 /* XXX this interface should be obsoleted. */
217 key_sendup(struct socket
*so
, struct sadb_msg
*msg
, u_int len
,
218 int target
) /*target of the resulting message*/
220 struct mbuf
*m
, *n
, *mprev
;
224 if (so
== 0 || msg
== 0)
225 panic("key_sendup: NULL pointer was passed");
227 KEYDEBUG(KEYDEBUG_KEY_DUMP
,
228 printf("key_sendup: \n");
232 * we increment statistics here, just in case we have ENOBUFS
236 uint64_t *ps
= PFKEY_STAT_GETREF();
237 ps
[PFKEY_STAT_IN_TOTAL
]++;
238 ps
[PFKEY_STAT_IN_BYTES
] += len
;
239 ps
[PFKEY_STAT_IN_MSGTYPE
+ msg
->sadb_msg_type
]++;
244 * Get mbuf chain whenever possible (not clusters),
245 * to save socket buffer. We'll be generating many SADB_ACQUIRE
246 * messages to listening key sockets. If we simply allocate clusters,
247 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
248 * sbspace() computes # of actual data bytes AND mbuf region.
250 * TODO: SADB_ACQUIRE filters should be implemented.
256 MGETHDR(n
, M_DONTWAIT
, MT_DATA
);
259 MGET(n
, M_DONTWAIT
, MT_DATA
);
263 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
266 if (tlen
>= MCLBYTES
) { /*XXX better threshold? */
267 MCLGET(n
, M_DONTWAIT
);
268 if ((n
->m_flags
& M_EXT
) == 0) {
271 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
289 m
->m_pkthdr
.len
= len
;
290 m
->m_pkthdr
.rcvif
= NULL
;
291 m_copyback(m
, 0, len
, msg
);
293 /* avoid duplicated statistics */
295 uint64_t *ps
= PFKEY_STAT_GETREF();
296 ps
[PFKEY_STAT_IN_TOTAL
]--;
297 ps
[PFKEY_STAT_IN_BYTES
] -= len
;
298 ps
[PFKEY_STAT_IN_MSGTYPE
+ msg
->sadb_msg_type
]--;
302 return key_sendup_mbuf(so
, m
, target
);
305 /* so can be NULL if target != KEY_SENDUP_ONE */
307 key_sendup_mbuf(struct socket
*so
, struct mbuf
*m
,
308 int target
/*, sbprio */)
315 int sbprio
= 0; /* XXX should be a parameter */
318 panic("key_sendup_mbuf: NULL pointer was passed");
319 if (so
== NULL
&& target
== KEY_SENDUP_ONE
)
320 panic("key_sendup_mbuf: NULL pointer was passed");
323 * RFC 2367 says ACQUIRE and other kernel-generated messages
324 * are special. We treat all KEY_SENDUP_REGISTERED messages
325 * as special, delivering them to all registered sockets
326 * even if the socket is at or above its so->so_rcv.sb_max limits.
327 * The only constraint is that the so_rcv data fall below
328 * key_registered_sb_max.
329 * Doing that check here avoids reworking every key_sendup_mbuf()
330 * in the short term. . The rework will be done after a technical
331 * conensus that this approach is appropriate.
333 if (target
== KEY_SENDUP_REGISTERED
) {
334 sbprio
= SB_PRIO_BESTEFFORT
;
338 uint64_t *ps
= PFKEY_STAT_GETREF();
339 ps
[PFKEY_STAT_IN_TOTAL
]++;
340 ps
[PFKEY_STAT_IN_BYTES
] += m
->m_pkthdr
.len
;
343 if (m
->m_len
< sizeof(struct sadb_msg
)) {
345 m
= m_pullup(m
, sizeof(struct sadb_msg
));
347 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
351 /* don't bother pulling it up just for stats */
354 if (m
->m_len
>= sizeof(struct sadb_msg
)) {
355 struct sadb_msg
*msg
;
356 msg
= mtod(m
, struct sadb_msg
*);
357 PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE
+ msg
->sadb_msg_type
);
360 LIST_FOREACH(rp
, &rawcb_list
, rcb_list
)
362 struct socket
* kso
= rp
->rcb_socket
;
363 if (rp
->rcb_proto
.sp_family
!= PF_KEY
)
365 if (rp
->rcb_proto
.sp_protocol
366 && rp
->rcb_proto
.sp_protocol
!= PF_KEY_V2
) {
370 kp
= (struct keycb
*)rp
;
373 * If you are in promiscuous mode, and when you get broadcasted
374 * reply, you'll get two PF_KEY messages.
375 * (based on pf_key@inner.net message on 14 Oct 1998)
377 if (((struct keycb
*)rp
)->kp_promisc
) {
378 if ((n
= m_copy(m
, 0, (int)M_COPYALL
)) != NULL
) {
379 (void)key_sendup0(rp
, n
, 1, 0);
384 /* the exact target will be processed later */
385 if (so
&& sotorawcb(so
) == rp
)
391 /* the statement has no effect */
392 if (so
&& sotorawcb(so
) == rp
)
398 case KEY_SENDUP_REGISTERED
:
399 if (kp
->kp_registered
) {
400 if (kso
->so_rcv
.sb_cc
<= key_registered_sb_max
)
404 "registered sendup dropped, "
405 "sb_cc %ld max %d\n",
407 key_registered_sb_max
);
411 PFKEY_STATINC(PFKEY_STAT_IN_MSGTARGET
+ target
);
416 if ((n
= m_copy(m
, 0, (int)M_COPYALL
)) == NULL
) {
418 PFKEY_STATINC(PFKEY_STAT_IN_NOMEM
);
422 if ((error
= key_sendup0(rp
, n
, 0, 0)) != 0) {
430 /* The 'later' time for processing the exact target has arrived */
432 error
= key_sendup0(sotorawcb(so
), m
, 0, sbprio
);
445 * derived from net/rtsock.c:rts_abort()
448 key_abort(struct socket
*so
)
451 s
= splnet(); /* FreeBSD */
452 error
= raw_usrreqs
.pru_abort(so
);
459 * derived from net/rtsock.c:rts_attach()
462 key_attach(struct socket
*so
, int proto
, struct proc
*td
)
467 if (sotorawcb(so
) != 0)
468 return EISCONN
; /* XXX panic? */
469 kp
= (struct keycb
*)malloc(sizeof *kp
, M_PCB
, M_WAITOK
|M_ZERO
); /* XXX */
474 * The spl[soft]net() is necessary to block protocols from sending
475 * error notifications (like RTM_REDIRECT or RTM_LOSING) while
476 * this PCB is extant but incompletely initialized.
477 * Probably we should try to do more of this work beforehand and
480 s
= splnet(); /* FreeBSD */
482 error
= raw_usrreqs
.pru_attach(so
, proto
, td
);
483 kp
= (struct keycb
*)sotorawcb(so
);
491 kp
->kp_promisc
= kp
->kp_registered
= 0;
493 if (kp
->kp_raw
.rcb_proto
.sp_protocol
== PF_KEY
) /* XXX: AF_KEY */
496 kp
->kp_raw
.rcb_laddr
= &key_src
;
497 kp
->kp_raw
.rcb_faddr
= &key_dst
;
499 so
->so_options
|= SO_USELOOPBACK
;
507 * derived from net/rtsock.c:rts_bind()
510 key_bind(struct socket
*so
, struct sockaddr
*nam
, struct proc
*td
)
513 s
= splnet(); /* FreeBSD */
514 error
= raw_usrreqs
.pru_bind(so
, nam
, td
); /* xxx just EINVAL */
521 * derived from net/rtsock.c:rts_connect()
524 key_connect(struct socket
*so
, struct sockaddr
*nam
, struct proc
*td
)
527 s
= splnet(); /* FreeBSD */
528 error
= raw_usrreqs
.pru_connect(so
, nam
, td
); /* XXX just EINVAL */
535 * derived from net/rtsock.c:rts_detach()
538 key_detach(struct socket
*so
)
540 struct keycb
*kp
= (struct keycb
*)sotorawcb(so
);
543 s
= splnet(); /* FreeBSD */
545 if (kp
->kp_raw
.rcb_proto
.sp_protocol
546 == PF_KEY
) /* XXX: AF_KEY */
552 error
= raw_usrreqs
.pru_detach(so
);
559 * derived from net/rtsock.c:key_disconnect()
562 key_disconnect(struct socket
*so
)
565 s
= splnet(); /* FreeBSD */
566 error
= raw_usrreqs
.pru_disconnect(so
);
573 * derived from net/rtsock.c:rts_peeraddr()
576 key_peeraddr(struct socket
*so
, struct sockaddr
**nam
)
579 s
= splnet(); /* FreeBSD */
580 error
= raw_usrreqs
.pru_peeraddr(so
, nam
);
587 * derived from net/rtsock.c:rts_send()
590 key_send(struct socket
*so
, int flags
, struct mbuf
*m
, struct sockaddr
*nam
,
591 struct mbuf
*control
, struct proc
*td
)
594 s
= splnet(); /* FreeBSD */
595 error
= raw_usrreqs
.pru_send(so
, flags
, m
, nam
, control
, td
);
602 * derived from net/rtsock.c:rts_shutdown()
605 key_shutdown(struct socket
*so
)
608 s
= splnet(); /* FreeBSD */
609 error
= raw_usrreqs
.pru_shutdown(so
);
616 * derived from net/rtsock.c:rts_sockaddr()
619 key_sockaddr(struct socket
*so
, struct sockaddr
**nam
)
622 s
= splnet(); /* FreeBSD */
623 error
= raw_usrreqs
.pru_sockaddr(so
, nam
);
627 #else /*!__FreeBSD__ -- traditional proto_usrreq() switch */
631 * derived from net/rtsock.c:route_usrreq()
634 key_usrreq(struct socket
*so
, int req
,struct mbuf
*m
, struct mbuf
*nam
,
635 struct mbuf
*control
, struct lwp
*l
)
638 struct keycb
*kp
= (struct keycb
*)sotorawcb(so
);
642 if (req
== PRU_ATTACH
) {
643 kp
= (struct keycb
*)malloc(sizeof(*kp
), M_PCB
, M_WAITOK
);
647 memset(so
->so_pcb
, 0, sizeof(*kp
));
649 if (req
== PRU_DETACH
&& kp
) {
650 int af
= kp
->kp_raw
.rcb_proto
.sp_protocol
;
651 if (af
== PF_KEY
) /* XXX: AF_KEY */
658 error
= raw_usrreq(so
, req
, m
, nam
, control
, l
);
659 m
= control
= NULL
; /* reclaimed in raw_usrreq */
660 kp
= (struct keycb
*)sotorawcb(so
);
661 if (req
== PRU_ATTACH
&& kp
) {
662 int af
= kp
->kp_raw
.rcb_proto
.sp_protocol
;
664 PFKEY_STATINC(PFKEY_STAT_SOCKERR
);
671 kp
->kp_promisc
= kp
->kp_registered
= 0;
673 if (af
== PF_KEY
) /* XXX: AF_KEY */
676 kp
->kp_raw
.rcb_laddr
= &key_src
;
677 kp
->kp_raw
.rcb_faddr
= &key_dst
;
679 so
->so_options
|= SO_USELOOPBACK
;
684 #endif /*!__FreeBSD__*/
688 SYSCTL_NODE(_net
, PF_KEY
, key
, CTLFLAG_RW
, 0, "Key Family");
689 #endif /* SYSCTL_NODE */
692 * Definitions of protocols supported in the KEY domain.
696 extern struct domain keydomain
;
698 struct pr_usrreqs key_usrreqs
= {
699 key_abort
, pru_accept_notsupp
, key_attach
, key_bind
,
701 pru_connect2_notsupp
, pru_control_notsupp
, key_detach
,
702 key_disconnect
, pru_listen_notsupp
, key_peeraddr
,
704 pru_rcvoob_notsupp
, key_send
, pru_sense_null
, key_shutdown
,
705 key_sockaddr
, sosend
, soreceive
, sopoll
708 struct protosw keysw
[] = {
709 { SOCK_RAW
, &keydomain
, PF_KEY_V2
, PR_ATOMIC
|PR_ADDR
,
710 0, (pr_output_t
*)key_output
, raw_ctlinput
, 0,
720 memset(&key_cb
, 0, sizeof(key_cb
));
724 struct domain keydomain
=
725 { PF_KEY
, "key", key_init0
, 0, 0,
726 keysw
, &keysw
[sizeof(keysw
)/sizeof(keysw
[0])] };
730 #else /* !__FreeBSD__ */
732 DOMAIN_DEFINE(keydomain
);
734 const struct protosw keysw
[] = {
737 .pr_domain
= &keydomain
,
738 .pr_protocol
= PF_KEY_V2
,
739 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
740 .pr_output
= key_output
,
741 .pr_ctlinput
= raw_ctlinput
,
742 .pr_usrreq
= key_usrreq
,
747 struct domain keydomain
= {
748 .dom_family
= PF_KEY
,
750 .dom_init
= key_init
,
751 .dom_protosw
= keysw
,
752 .dom_protoswNPROTOSW
= &keysw
[__arraycount(keysw
)],