xref: /freebsd/sys/netipsec/keysock.c (revision d6b92ffa)
1 /*	$FreeBSD$	*/
2 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
3 
4 /*-
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include "opt_ipsec.h"
34 
35 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
36 
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/domain.h>
40 #include <sys/errno.h>
41 #include <sys/kernel.h>
42 #include <sys/lock.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/mutex.h>
46 #include <sys/priv.h>
47 #include <sys/protosw.h>
48 #include <sys/signalvar.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/sysctl.h>
52 #include <sys/systm.h>
53 
54 #include <net/if.h>
55 #include <net/vnet.h>
56 #include <net/raw_cb.h>
57 
58 #include <netinet/in.h>
59 
60 #include <net/pfkeyv2.h>
61 #include <netipsec/key.h>
62 #include <netipsec/keysock.h>
63 #include <netipsec/key_debug.h>
64 #include <netipsec/ipsec.h>
65 
66 #include <machine/stdarg.h>
67 
68 struct key_cb {
69 	int key_count;
70 	int any_count;
71 };
72 static VNET_DEFINE(struct key_cb, key_cb);
73 #define	V_key_cb		VNET(key_cb)
74 
75 static struct sockaddr key_src = { 2, PF_KEY, };
76 
77 static int key_sendup0(struct rawcb *, struct mbuf *, int);
78 
79 VNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat);
80 VNET_PCPUSTAT_SYSINIT(pfkeystat);
81 
82 #ifdef VIMAGE
83 VNET_PCPUSTAT_SYSUNINIT(pfkeystat);
84 #endif /* VIMAGE */
85 
86 /*
87  * key_output()
88  */
89 int
90 key_output(struct mbuf *m, struct socket *so, ...)
91 {
92 	struct sadb_msg *msg;
93 	int len, error = 0;
94 
95 	if (m == NULL)
96 		panic("%s: NULL pointer was passed.\n", __func__);
97 
98 	PFKEYSTAT_INC(out_total);
99 	PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len);
100 
101 	len = m->m_pkthdr.len;
102 	if (len < sizeof(struct sadb_msg)) {
103 		PFKEYSTAT_INC(out_tooshort);
104 		error = EINVAL;
105 		goto end;
106 	}
107 
108 	if (m->m_len < sizeof(struct sadb_msg)) {
109 		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == NULL) {
110 			PFKEYSTAT_INC(out_nomem);
111 			error = ENOBUFS;
112 			goto end;
113 		}
114 	}
115 
116 	M_ASSERTPKTHDR(m);
117 
118 	KEYDBG(KEY_DUMP, kdebug_mbuf(m));
119 
120 	msg = mtod(m, struct sadb_msg *);
121 	PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]);
122 	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
123 		PFKEYSTAT_INC(out_invlen);
124 		error = EINVAL;
125 		goto end;
126 	}
127 
128 	error = key_parse(m, so);
129 	m = NULL;
130 end:
131 	if (m)
132 		m_freem(m);
133 	return error;
134 }
135 
136 /*
137  * send message to the socket.
138  */
139 static int
140 key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc)
141 {
142 	int error;
143 
144 	if (promisc) {
145 		struct sadb_msg *pmsg;
146 
147 		M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT);
148 		if (m == NULL) {
149 			PFKEYSTAT_INC(in_nomem);
150 			return (ENOBUFS);
151 		}
152 		pmsg = mtod(m, struct sadb_msg *);
153 		bzero(pmsg, sizeof(*pmsg));
154 		pmsg->sadb_msg_version = PF_KEY_V2;
155 		pmsg->sadb_msg_type = SADB_X_PROMISC;
156 		pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
157 		/* pid and seq? */
158 
159 		PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]);
160 	}
161 
162 	if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src,
163 	    m, NULL)) {
164 		PFKEYSTAT_INC(in_nomem);
165 		m_freem(m);
166 		error = ENOBUFS;
167 	} else
168 		error = 0;
169 	sorwakeup(rp->rcb_socket);
170 	return error;
171 }
172 
173 /* XXX this interface should be obsoleted. */
174 int
175 key_sendup(struct socket *so, struct sadb_msg *msg, u_int len, int target)
176 {
177 	struct mbuf *m, *n, *mprev;
178 	int tlen;
179 
180 	/* sanity check */
181 	if (so == NULL || msg == NULL)
182 		panic("%s: NULL pointer was passed.\n", __func__);
183 
184 	KEYDBG(KEY_DUMP,
185 	    printf("%s: \n", __func__);
186 	    kdebug_sadb(msg));
187 
188 	/*
189 	 * we increment statistics here, just in case we have ENOBUFS
190 	 * in this function.
191 	 */
192 	PFKEYSTAT_INC(in_total);
193 	PFKEYSTAT_ADD(in_bytes, len);
194 	PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]);
195 
196 	/*
197 	 * Get mbuf chain whenever possible (not clusters),
198 	 * to save socket buffer.  We'll be generating many SADB_ACQUIRE
199 	 * messages to listening key sockets.  If we simply allocate clusters,
200 	 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
201 	 * sbspace() computes # of actual data bytes AND mbuf region.
202 	 *
203 	 * TODO: SADB_ACQUIRE filters should be implemented.
204 	 */
205 	tlen = len;
206 	m = mprev = NULL;
207 	while (tlen > 0) {
208 		if (tlen == len) {
209 			MGETHDR(n, M_NOWAIT, MT_DATA);
210 			if (n == NULL) {
211 				PFKEYSTAT_INC(in_nomem);
212 				return ENOBUFS;
213 			}
214 			n->m_len = MHLEN;
215 		} else {
216 			MGET(n, M_NOWAIT, MT_DATA);
217 			if (n == NULL) {
218 				PFKEYSTAT_INC(in_nomem);
219 				return ENOBUFS;
220 			}
221 			n->m_len = MLEN;
222 		}
223 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
224 			if (!(MCLGET(n, M_NOWAIT))) {
225 				m_free(n);
226 				m_freem(m);
227 				PFKEYSTAT_INC(in_nomem);
228 				return ENOBUFS;
229 			}
230 			n->m_len = MCLBYTES;
231 		}
232 
233 		if (tlen < n->m_len)
234 			n->m_len = tlen;
235 		n->m_next = NULL;
236 		if (m == NULL)
237 			m = mprev = n;
238 		else {
239 			mprev->m_next = n;
240 			mprev = n;
241 		}
242 		tlen -= n->m_len;
243 		n = NULL;
244 	}
245 	m->m_pkthdr.len = len;
246 	m->m_pkthdr.rcvif = NULL;
247 	m_copyback(m, 0, len, (caddr_t)msg);
248 
249 	/* avoid duplicated statistics */
250 	PFKEYSTAT_ADD(in_total, -1);
251 	PFKEYSTAT_ADD(in_bytes, -len);
252 	PFKEYSTAT_ADD(in_msgtype[msg->sadb_msg_type], -1);
253 
254 	return key_sendup_mbuf(so, m, target);
255 }
256 
257 /* so can be NULL if target != KEY_SENDUP_ONE */
258 int
259 key_sendup_mbuf(struct socket *so, struct mbuf *m, int target)
260 {
261 	struct mbuf *n;
262 	struct keycb *kp;
263 	int sendup;
264 	struct rawcb *rp;
265 	int error = 0;
266 
267 	if (m == NULL)
268 		panic("key_sendup_mbuf: NULL pointer was passed.\n");
269 	if (so == NULL && target == KEY_SENDUP_ONE)
270 		panic("%s: NULL pointer was passed.\n", __func__);
271 
272 	PFKEYSTAT_INC(in_total);
273 	PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len);
274 	if (m->m_len < sizeof(struct sadb_msg)) {
275 		m = m_pullup(m, sizeof(struct sadb_msg));
276 		if (m == NULL) {
277 			PFKEYSTAT_INC(in_nomem);
278 			return ENOBUFS;
279 		}
280 	}
281 	if (m->m_len >= sizeof(struct sadb_msg)) {
282 		struct sadb_msg *msg;
283 		msg = mtod(m, struct sadb_msg *);
284 		PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]);
285 	}
286 	mtx_lock(&rawcb_mtx);
287 	LIST_FOREACH(rp, &V_rawcb_list, list)
288 	{
289 		if (rp->rcb_proto.sp_family != PF_KEY)
290 			continue;
291 		if (rp->rcb_proto.sp_protocol
292 		 && rp->rcb_proto.sp_protocol != PF_KEY_V2) {
293 			continue;
294 		}
295 
296 		kp = (struct keycb *)rp;
297 
298 		/*
299 		 * If you are in promiscuous mode, and when you get broadcasted
300 		 * reply, you'll get two PF_KEY messages.
301 		 * (based on pf_key@inner.net message on 14 Oct 1998)
302 		 */
303 		if (((struct keycb *)rp)->kp_promisc) {
304 			if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) {
305 				(void)key_sendup0(rp, n, 1);
306 				n = NULL;
307 			}
308 		}
309 
310 		/* the exact target will be processed later */
311 		if (so && sotorawcb(so) == rp)
312 			continue;
313 
314 		sendup = 0;
315 		switch (target) {
316 		case KEY_SENDUP_ONE:
317 			/* the statement has no effect */
318 			if (so && sotorawcb(so) == rp)
319 				sendup++;
320 			break;
321 		case KEY_SENDUP_ALL:
322 			sendup++;
323 			break;
324 		case KEY_SENDUP_REGISTERED:
325 			if (kp->kp_registered)
326 				sendup++;
327 			break;
328 		}
329 		PFKEYSTAT_INC(in_msgtarget[target]);
330 
331 		if (!sendup)
332 			continue;
333 
334 		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
335 			m_freem(m);
336 			PFKEYSTAT_INC(in_nomem);
337 			mtx_unlock(&rawcb_mtx);
338 			return ENOBUFS;
339 		}
340 
341 		if ((error = key_sendup0(rp, n, 0)) != 0) {
342 			m_freem(m);
343 			mtx_unlock(&rawcb_mtx);
344 			return error;
345 		}
346 
347 		n = NULL;
348 	}
349 
350 	if (so) {
351 		error = key_sendup0(sotorawcb(so), m, 0);
352 		m = NULL;
353 	} else {
354 		error = 0;
355 		m_freem(m);
356 	}
357 	mtx_unlock(&rawcb_mtx);
358 	return error;
359 }
360 
361 /*
362  * key_abort()
363  * derived from net/rtsock.c:rts_abort()
364  */
365 static void
366 key_abort(struct socket *so)
367 {
368 	raw_usrreqs.pru_abort(so);
369 }
370 
371 /*
372  * key_attach()
373  * derived from net/rtsock.c:rts_attach()
374  */
375 static int
376 key_attach(struct socket *so, int proto, struct thread *td)
377 {
378 	struct keycb *kp;
379 	int error;
380 
381 	KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL"));
382 
383 	if (td != NULL) {
384 		error = priv_check(td, PRIV_NET_RAW);
385 		if (error)
386 			return error;
387 	}
388 
389 	/* XXX */
390 	kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO);
391 	if (kp == NULL)
392 		return ENOBUFS;
393 
394 	so->so_pcb = (caddr_t)kp;
395 	error = raw_attach(so, proto);
396 	kp = (struct keycb *)sotorawcb(so);
397 	if (error) {
398 		free(kp, M_PCB);
399 		so->so_pcb = (caddr_t) 0;
400 		return error;
401 	}
402 
403 	kp->kp_promisc = kp->kp_registered = 0;
404 
405 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
406 		V_key_cb.key_count++;
407 	V_key_cb.any_count++;
408 	soisconnected(so);
409 	so->so_options |= SO_USELOOPBACK;
410 
411 	return 0;
412 }
413 
414 /*
415  * key_bind()
416  * derived from net/rtsock.c:rts_bind()
417  */
418 static int
419 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
420 {
421   return EINVAL;
422 }
423 
424 /*
425  * key_close()
426  * derived from net/rtsock.c:rts_close().
427  */
428 static void
429 key_close(struct socket *so)
430 {
431 
432 	raw_usrreqs.pru_close(so);
433 }
434 
435 /*
436  * key_connect()
437  * derived from net/rtsock.c:rts_connect()
438  */
439 static int
440 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
441 {
442 	return EINVAL;
443 }
444 
445 /*
446  * key_detach()
447  * derived from net/rtsock.c:rts_detach()
448  */
449 static void
450 key_detach(struct socket *so)
451 {
452 	struct keycb *kp = (struct keycb *)sotorawcb(so);
453 
454 	KASSERT(kp != NULL, ("key_detach: kp == NULL"));
455 	if (kp->kp_raw.rcb_proto.sp_protocol
456 	    == PF_KEY) /* XXX: AF_KEY */
457 		V_key_cb.key_count--;
458 	V_key_cb.any_count--;
459 
460 	key_freereg(so);
461 	raw_usrreqs.pru_detach(so);
462 }
463 
464 /*
465  * key_disconnect()
466  * derived from net/rtsock.c:key_disconnect()
467  */
468 static int
469 key_disconnect(struct socket *so)
470 {
471 	return(raw_usrreqs.pru_disconnect(so));
472 }
473 
474 /*
475  * key_peeraddr()
476  * derived from net/rtsock.c:rts_peeraddr()
477  */
478 static int
479 key_peeraddr(struct socket *so, struct sockaddr **nam)
480 {
481 	return(raw_usrreqs.pru_peeraddr(so, nam));
482 }
483 
484 /*
485  * key_send()
486  * derived from net/rtsock.c:rts_send()
487  */
488 static int
489 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
490 	 struct mbuf *control, struct thread *td)
491 {
492 	return(raw_usrreqs.pru_send(so, flags, m, nam, control, td));
493 }
494 
495 /*
496  * key_shutdown()
497  * derived from net/rtsock.c:rts_shutdown()
498  */
499 static int
500 key_shutdown(struct socket *so)
501 {
502 	return(raw_usrreqs.pru_shutdown(so));
503 }
504 
505 /*
506  * key_sockaddr()
507  * derived from net/rtsock.c:rts_sockaddr()
508  */
509 static int
510 key_sockaddr(struct socket *so, struct sockaddr **nam)
511 {
512 	return(raw_usrreqs.pru_sockaddr(so, nam));
513 }
514 
515 struct pr_usrreqs key_usrreqs = {
516 	.pru_abort =		key_abort,
517 	.pru_attach =		key_attach,
518 	.pru_bind =		key_bind,
519 	.pru_connect =		key_connect,
520 	.pru_detach =		key_detach,
521 	.pru_disconnect =	key_disconnect,
522 	.pru_peeraddr =		key_peeraddr,
523 	.pru_send =		key_send,
524 	.pru_shutdown =		key_shutdown,
525 	.pru_sockaddr =		key_sockaddr,
526 	.pru_close =		key_close,
527 };
528 
529 /* sysctl */
530 SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
531 
532 /*
533  * Definitions of protocols supported in the KEY domain.
534  */
535 
536 extern struct domain keydomain;
537 
538 struct protosw keysw[] = {
539 {
540 	.pr_type =		SOCK_RAW,
541 	.pr_domain =		&keydomain,
542 	.pr_protocol =		PF_KEY_V2,
543 	.pr_flags =		PR_ATOMIC|PR_ADDR,
544 	.pr_output =		key_output,
545 	.pr_ctlinput =		raw_ctlinput,
546 	.pr_init =		raw_init,
547 	.pr_usrreqs =		&key_usrreqs
548 }
549 };
550 
551 static void
552 key_init0(void)
553 {
554 
555 	bzero((caddr_t)&V_key_cb, sizeof(V_key_cb));
556 	key_init();
557 }
558 
559 struct domain keydomain = {
560 	.dom_family =		PF_KEY,
561 	.dom_name =		"key",
562 	.dom_init =		key_init0,
563 #ifdef VIMAGE
564 	.dom_destroy =		key_destroy,
565 #endif
566 	.dom_protosw =		keysw,
567 	.dom_protoswNPROTOSW =	&keysw[nitems(keysw)]
568 };
569 
570 VNET_DOMAIN_SET(key);
571