xref: /freebsd/sys/netipsec/keysock.c (revision a812392203d7c4c3f0db9d8a0f3391374c49c71f)
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 == 0)
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))) == 0) {
110 			PFKEYSTAT_INC(out_nomem);
111 			error = ENOBUFS;
112 			goto end;
113 		}
114 	}
115 
116 	M_ASSERTPKTHDR(m);
117 
118 	KEYDEBUG(KEYDEBUG_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 		m->m_pkthdr.len += sizeof(*pmsg); /* XXX: is this correct? */
153 
154 		pmsg = mtod(m, struct sadb_msg *);
155 		bzero(pmsg, sizeof(*pmsg));
156 		pmsg->sadb_msg_version = PF_KEY_V2;
157 		pmsg->sadb_msg_type = SADB_X_PROMISC;
158 		pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
159 		/* pid and seq? */
160 
161 		PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]);
162 	}
163 
164 	if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src,
165 	    m, NULL)) {
166 		PFKEYSTAT_INC(in_nomem);
167 		m_freem(m);
168 		error = ENOBUFS;
169 	} else
170 		error = 0;
171 	sorwakeup(rp->rcb_socket);
172 	return error;
173 }
174 
175 /* XXX this interface should be obsoleted. */
176 int
177 key_sendup(struct socket *so, struct sadb_msg *msg, u_int len, int target)
178 {
179 	struct mbuf *m, *n, *mprev;
180 	int tlen;
181 
182 	/* sanity check */
183 	if (so == 0 || msg == 0)
184 		panic("%s: NULL pointer was passed.\n", __func__);
185 
186 	KEYDEBUG(KEYDEBUG_KEY_DUMP,
187 		printf("%s: \n", __func__);
188 		kdebug_sadb(msg));
189 
190 	/*
191 	 * we increment statistics here, just in case we have ENOBUFS
192 	 * in this function.
193 	 */
194 	PFKEYSTAT_INC(in_total);
195 	PFKEYSTAT_ADD(in_bytes, len);
196 	PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]);
197 
198 	/*
199 	 * Get mbuf chain whenever possible (not clusters),
200 	 * to save socket buffer.  We'll be generating many SADB_ACQUIRE
201 	 * messages to listening key sockets.  If we simply allocate clusters,
202 	 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
203 	 * sbspace() computes # of actual data bytes AND mbuf region.
204 	 *
205 	 * TODO: SADB_ACQUIRE filters should be implemented.
206 	 */
207 	tlen = len;
208 	m = mprev = NULL;
209 	while (tlen > 0) {
210 		if (tlen == len) {
211 			MGETHDR(n, M_NOWAIT, MT_DATA);
212 			if (n == NULL) {
213 				PFKEYSTAT_INC(in_nomem);
214 				return ENOBUFS;
215 			}
216 			n->m_len = MHLEN;
217 		} else {
218 			MGET(n, M_NOWAIT, MT_DATA);
219 			if (n == NULL) {
220 				PFKEYSTAT_INC(in_nomem);
221 				return ENOBUFS;
222 			}
223 			n->m_len = MLEN;
224 		}
225 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
226 			MCLGET(n, M_NOWAIT);
227 			if ((n->m_flags & M_EXT) == 0) {
228 				m_free(n);
229 				m_freem(m);
230 				PFKEYSTAT_INC(in_nomem);
231 				return ENOBUFS;
232 			}
233 			n->m_len = MCLBYTES;
234 		}
235 
236 		if (tlen < n->m_len)
237 			n->m_len = tlen;
238 		n->m_next = NULL;
239 		if (m == NULL)
240 			m = mprev = n;
241 		else {
242 			mprev->m_next = n;
243 			mprev = n;
244 		}
245 		tlen -= n->m_len;
246 		n = NULL;
247 	}
248 	m->m_pkthdr.len = len;
249 	m->m_pkthdr.rcvif = NULL;
250 	m_copyback(m, 0, len, (caddr_t)msg);
251 
252 	/* avoid duplicated statistics */
253 	PFKEYSTAT_ADD(in_total, -1);
254 	PFKEYSTAT_ADD(in_bytes, -len);
255 	PFKEYSTAT_ADD(in_msgtype[msg->sadb_msg_type], -1);
256 
257 	return key_sendup_mbuf(so, m, target);
258 }
259 
260 /* so can be NULL if target != KEY_SENDUP_ONE */
261 int
262 key_sendup_mbuf(struct socket *so, struct mbuf *m, int target)
263 {
264 	struct mbuf *n;
265 	struct keycb *kp;
266 	int sendup;
267 	struct rawcb *rp;
268 	int error = 0;
269 
270 	if (m == NULL)
271 		panic("key_sendup_mbuf: NULL pointer was passed.\n");
272 	if (so == NULL && target == KEY_SENDUP_ONE)
273 		panic("%s: NULL pointer was passed.\n", __func__);
274 
275 	PFKEYSTAT_INC(in_total);
276 	PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len);
277 	if (m->m_len < sizeof(struct sadb_msg)) {
278 		m = m_pullup(m, sizeof(struct sadb_msg));
279 		if (m == NULL) {
280 			PFKEYSTAT_INC(in_nomem);
281 			return ENOBUFS;
282 		}
283 	}
284 	if (m->m_len >= sizeof(struct sadb_msg)) {
285 		struct sadb_msg *msg;
286 		msg = mtod(m, struct sadb_msg *);
287 		PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]);
288 	}
289 	mtx_lock(&rawcb_mtx);
290 	LIST_FOREACH(rp, &V_rawcb_list, list)
291 	{
292 		if (rp->rcb_proto.sp_family != PF_KEY)
293 			continue;
294 		if (rp->rcb_proto.sp_protocol
295 		 && rp->rcb_proto.sp_protocol != PF_KEY_V2) {
296 			continue;
297 		}
298 
299 		kp = (struct keycb *)rp;
300 
301 		/*
302 		 * If you are in promiscuous mode, and when you get broadcasted
303 		 * reply, you'll get two PF_KEY messages.
304 		 * (based on pf_key@inner.net message on 14 Oct 1998)
305 		 */
306 		if (((struct keycb *)rp)->kp_promisc) {
307 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
308 				(void)key_sendup0(rp, n, 1);
309 				n = NULL;
310 			}
311 		}
312 
313 		/* the exact target will be processed later */
314 		if (so && sotorawcb(so) == rp)
315 			continue;
316 
317 		sendup = 0;
318 		switch (target) {
319 		case KEY_SENDUP_ONE:
320 			/* the statement has no effect */
321 			if (so && sotorawcb(so) == rp)
322 				sendup++;
323 			break;
324 		case KEY_SENDUP_ALL:
325 			sendup++;
326 			break;
327 		case KEY_SENDUP_REGISTERED:
328 			if (kp->kp_registered)
329 				sendup++;
330 			break;
331 		}
332 		PFKEYSTAT_INC(in_msgtarget[target]);
333 
334 		if (!sendup)
335 			continue;
336 
337 		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
338 			m_freem(m);
339 			PFKEYSTAT_INC(in_nomem);
340 			mtx_unlock(&rawcb_mtx);
341 			return ENOBUFS;
342 		}
343 
344 		if ((error = key_sendup0(rp, n, 0)) != 0) {
345 			m_freem(m);
346 			mtx_unlock(&rawcb_mtx);
347 			return error;
348 		}
349 
350 		n = NULL;
351 	}
352 
353 	if (so) {
354 		error = key_sendup0(sotorawcb(so), m, 0);
355 		m = NULL;
356 	} else {
357 		error = 0;
358 		m_freem(m);
359 	}
360 	mtx_unlock(&rawcb_mtx);
361 	return error;
362 }
363 
364 /*
365  * key_abort()
366  * derived from net/rtsock.c:rts_abort()
367  */
368 static void
369 key_abort(struct socket *so)
370 {
371 	raw_usrreqs.pru_abort(so);
372 }
373 
374 /*
375  * key_attach()
376  * derived from net/rtsock.c:rts_attach()
377  */
378 static int
379 key_attach(struct socket *so, int proto, struct thread *td)
380 {
381 	struct keycb *kp;
382 	int error;
383 
384 	KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL"));
385 
386 	if (td != NULL) {
387 		error = priv_check(td, PRIV_NET_RAW);
388 		if (error)
389 			return error;
390 	}
391 
392 	/* XXX */
393 	kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO);
394 	if (kp == 0)
395 		return ENOBUFS;
396 
397 	so->so_pcb = (caddr_t)kp;
398 	error = raw_attach(so, proto);
399 	kp = (struct keycb *)sotorawcb(so);
400 	if (error) {
401 		free(kp, M_PCB);
402 		so->so_pcb = (caddr_t) 0;
403 		return error;
404 	}
405 
406 	kp->kp_promisc = kp->kp_registered = 0;
407 
408 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
409 		V_key_cb.key_count++;
410 	V_key_cb.any_count++;
411 	soisconnected(so);
412 	so->so_options |= SO_USELOOPBACK;
413 
414 	return 0;
415 }
416 
417 /*
418  * key_bind()
419  * derived from net/rtsock.c:rts_bind()
420  */
421 static int
422 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
423 {
424   return EINVAL;
425 }
426 
427 /*
428  * key_close()
429  * derived from net/rtsock.c:rts_close().
430  */
431 static void
432 key_close(struct socket *so)
433 {
434 
435 	raw_usrreqs.pru_close(so);
436 }
437 
438 /*
439  * key_connect()
440  * derived from net/rtsock.c:rts_connect()
441  */
442 static int
443 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
444 {
445 	return EINVAL;
446 }
447 
448 /*
449  * key_detach()
450  * derived from net/rtsock.c:rts_detach()
451  */
452 static void
453 key_detach(struct socket *so)
454 {
455 	struct keycb *kp = (struct keycb *)sotorawcb(so);
456 
457 	KASSERT(kp != NULL, ("key_detach: kp == NULL"));
458 	if (kp->kp_raw.rcb_proto.sp_protocol
459 	    == PF_KEY) /* XXX: AF_KEY */
460 		V_key_cb.key_count--;
461 	V_key_cb.any_count--;
462 
463 	key_freereg(so);
464 	raw_usrreqs.pru_detach(so);
465 }
466 
467 /*
468  * key_disconnect()
469  * derived from net/rtsock.c:key_disconnect()
470  */
471 static int
472 key_disconnect(struct socket *so)
473 {
474 	return(raw_usrreqs.pru_disconnect(so));
475 }
476 
477 /*
478  * key_peeraddr()
479  * derived from net/rtsock.c:rts_peeraddr()
480  */
481 static int
482 key_peeraddr(struct socket *so, struct sockaddr **nam)
483 {
484 	return(raw_usrreqs.pru_peeraddr(so, nam));
485 }
486 
487 /*
488  * key_send()
489  * derived from net/rtsock.c:rts_send()
490  */
491 static int
492 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
493 	 struct mbuf *control, struct thread *td)
494 {
495 	return(raw_usrreqs.pru_send(so, flags, m, nam, control, td));
496 }
497 
498 /*
499  * key_shutdown()
500  * derived from net/rtsock.c:rts_shutdown()
501  */
502 static int
503 key_shutdown(struct socket *so)
504 {
505 	return(raw_usrreqs.pru_shutdown(so));
506 }
507 
508 /*
509  * key_sockaddr()
510  * derived from net/rtsock.c:rts_sockaddr()
511  */
512 static int
513 key_sockaddr(struct socket *so, struct sockaddr **nam)
514 {
515 	return(raw_usrreqs.pru_sockaddr(so, nam));
516 }
517 
518 struct pr_usrreqs key_usrreqs = {
519 	.pru_abort =		key_abort,
520 	.pru_attach =		key_attach,
521 	.pru_bind =		key_bind,
522 	.pru_connect =		key_connect,
523 	.pru_detach =		key_detach,
524 	.pru_disconnect =	key_disconnect,
525 	.pru_peeraddr =		key_peeraddr,
526 	.pru_send =		key_send,
527 	.pru_shutdown =		key_shutdown,
528 	.pru_sockaddr =		key_sockaddr,
529 	.pru_close =		key_close,
530 };
531 
532 /* sysctl */
533 SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
534 
535 /*
536  * Definitions of protocols supported in the KEY domain.
537  */
538 
539 extern struct domain keydomain;
540 
541 struct protosw keysw[] = {
542 {
543 	.pr_type =		SOCK_RAW,
544 	.pr_domain =		&keydomain,
545 	.pr_protocol =		PF_KEY_V2,
546 	.pr_flags =		PR_ATOMIC|PR_ADDR,
547 	.pr_output =		key_output,
548 	.pr_ctlinput =		raw_ctlinput,
549 	.pr_init =		raw_init,
550 	.pr_usrreqs =		&key_usrreqs
551 }
552 };
553 
554 static void
555 key_init0(void)
556 {
557 
558 	bzero((caddr_t)&V_key_cb, sizeof(V_key_cb));
559 	key_init();
560 }
561 
562 struct domain keydomain = {
563 	.dom_family =		PF_KEY,
564 	.dom_name =		"key",
565 	.dom_init =		key_init0,
566 #ifdef VIMAGE
567 	.dom_destroy =		key_destroy,
568 #endif
569 	.dom_protosw =		keysw,
570 	.dom_protoswNPROTOSW =	&keysw[sizeof(keysw)/sizeof(keysw[0])]
571 };
572 
573 VNET_DOMAIN_SET(key);
574