xref: /netbsd-src/sys/net/rtsock.c (revision f89f6560d453f5e37386cc7938c072d2f528b9fa)
1 /*	$NetBSD: rtsock.c,v 1.168 2015/04/06 06:26:21 ozaki-r Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 1988, 1991, 1993
34  *	The Regents of the University of California.  All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. Neither the name of the University nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  *
60  *	@(#)rtsock.c	8.7 (Berkeley) 10/12/95
61  */
62 
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.168 2015/04/06 06:26:21 ozaki-r Exp $");
65 
66 #ifdef _KERNEL_OPT
67 #include "opt_inet.h"
68 #include "opt_mpls.h"
69 #include "opt_compat_netbsd.h"
70 #endif
71 
72 #include <sys/param.h>
73 #include <sys/systm.h>
74 #include <sys/proc.h>
75 #include <sys/socket.h>
76 #include <sys/socketvar.h>
77 #include <sys/domain.h>
78 #include <sys/protosw.h>
79 #include <sys/sysctl.h>
80 #include <sys/kauth.h>
81 #include <sys/kmem.h>
82 #include <sys/intr.h>
83 #ifdef RTSOCK_DEBUG
84 #include <netinet/in.h>
85 #endif /* RTSOCK_DEBUG */
86 
87 #include <net/if.h>
88 #include <net/route.h>
89 #include <net/raw_cb.h>
90 
91 #include <netmpls/mpls.h>
92 
93 #if defined(COMPAT_14) || defined(COMPAT_50)
94 #include <compat/net/if.h>
95 #include <compat/net/route.h>
96 #endif
97 #ifdef COMPAT_RTSOCK
98 #define	RTM_XVERSION	RTM_OVERSION
99 #define	RT_XADVANCE(a,b) RT_OADVANCE(a,b)
100 #define	RT_XROUNDUP(n)	RT_OROUNDUP(n)
101 #define	PF_XROUTE	PF_OROUTE
102 #define	rt_xmsghdr	rt_msghdr50
103 #define	if_xmsghdr	if_msghdr	/* if_msghdr50 is for RTM_OIFINFO */
104 #define	ifa_xmsghdr	ifa_msghdr50
105 #define	if_xannouncemsghdr	if_announcemsghdr50
106 #define	COMPATNAME(x)	compat_50_ ## x
107 #define	DOMAINNAME	"oroute"
108 CTASSERT(sizeof(struct ifa_xmsghdr) == 20);
109 DOMAIN_DEFINE(compat_50_routedomain); /* forward declare and add to link set */
110 #else /* COMPAT_RTSOCK */
111 #define	RTM_XVERSION	RTM_VERSION
112 #define	RT_XADVANCE(a,b) RT_ADVANCE(a,b)
113 #define	RT_XROUNDUP(n)	RT_ROUNDUP(n)
114 #define	PF_XROUTE	PF_ROUTE
115 #define	rt_xmsghdr	rt_msghdr
116 #define	if_xmsghdr	if_msghdr
117 #define	ifa_xmsghdr	ifa_msghdr
118 #define	if_xannouncemsghdr	if_announcemsghdr
119 #define	COMPATNAME(x)	x
120 #define	DOMAINNAME	"route"
121 CTASSERT(sizeof(struct ifa_xmsghdr) == 24);
122 #ifdef COMPAT_50
123 #define	COMPATCALL(name, args)	compat_50_ ## name args
124 #endif
125 DOMAIN_DEFINE(routedomain); /* forward declare and add to link set */
126 #undef COMPAT_50
127 #undef COMPAT_14
128 #endif /* COMPAT_RTSOCK */
129 
130 #ifndef COMPATCALL
131 #define	COMPATCALL(name, args)	do { } while (/*CONSTCOND*/ 0)
132 #endif
133 
134 #ifdef RTSOCK_DEBUG
135 #define RT_IN_PRINT(b, a) (in_print((b), sizeof(b), \
136     &((const struct sockaddr_in *)info.rti_info[(a)])->sin_addr), (b))
137 #endif /* RTSOCK_DEBUG */
138 
139 struct route_info COMPATNAME(route_info) = {
140 	.ri_dst = { .sa_len = 2, .sa_family = PF_XROUTE, },
141 	.ri_src = { .sa_len = 2, .sa_family = PF_XROUTE, },
142 	.ri_maxqlen = IFQ_MAXLEN,
143 };
144 
145 #define	PRESERVED_RTF	(RTF_UP | RTF_GATEWAY | RTF_HOST | RTF_DONE | RTF_MASK)
146 
147 static void COMPATNAME(route_init)(void);
148 static int COMPATNAME(route_output)(struct mbuf *, ...);
149 
150 static int rt_msg2(int, struct rt_addrinfo *, void *, struct rt_walkarg *, int *);
151 static int rt_xaddrs(u_char, const char *, const char *, struct rt_addrinfo *);
152 static struct mbuf *rt_makeifannouncemsg(struct ifnet *, int, int,
153     struct rt_addrinfo *);
154 static void rt_setmetrics(int, const struct rt_xmsghdr *, struct rtentry *);
155 static void rtm_setmetrics(const struct rtentry *, struct rt_xmsghdr *);
156 static void sysctl_net_route_setup(struct sysctllog **);
157 static int sysctl_dumpentry(struct rtentry *, void *);
158 static int sysctl_iflist(int, struct rt_walkarg *, int);
159 static int sysctl_rtable(SYSCTLFN_PROTO);
160 static void rt_adjustcount(int, int);
161 
162 static void
163 rt_adjustcount(int af, int cnt)
164 {
165 	struct route_cb * const cb = &COMPATNAME(route_info).ri_cb;
166 
167 	cb->any_count += cnt;
168 
169 	switch (af) {
170 	case AF_INET:
171 		cb->ip_count += cnt;
172 		return;
173 #ifdef INET6
174 	case AF_INET6:
175 		cb->ip6_count += cnt;
176 		return;
177 #endif
178 	case AF_MPLS:
179 		cb->mpls_count += cnt;
180 		return;
181 	}
182 }
183 
184 static int
185 COMPATNAME(route_attach)(struct socket *so, int proto)
186 {
187 	struct rawcb *rp;
188 	int s, error;
189 
190 	KASSERT(sotorawcb(so) == NULL);
191 	rp = kmem_zalloc(sizeof(*rp), KM_SLEEP);
192 	rp->rcb_len = sizeof(*rp);
193 	so->so_pcb = rp;
194 
195 	s = splsoftnet();
196 	if ((error = raw_attach(so, proto)) == 0) {
197 		rt_adjustcount(rp->rcb_proto.sp_protocol, 1);
198 		rp->rcb_laddr = &COMPATNAME(route_info).ri_src;
199 		rp->rcb_faddr = &COMPATNAME(route_info).ri_dst;
200 	}
201 	splx(s);
202 
203 	if (error) {
204 		kmem_free(rp, sizeof(*rp));
205 		so->so_pcb = NULL;
206 		return error;
207 	}
208 
209 	soisconnected(so);
210 	so->so_options |= SO_USELOOPBACK;
211 	KASSERT(solocked(so));
212 
213 	return error;
214 }
215 
216 static void
217 COMPATNAME(route_detach)(struct socket *so)
218 {
219 	struct rawcb *rp = sotorawcb(so);
220 	int s;
221 
222 	KASSERT(rp != NULL);
223 	KASSERT(solocked(so));
224 
225 	s = splsoftnet();
226 	rt_adjustcount(rp->rcb_proto.sp_protocol, -1);
227 	raw_detach(so);
228 	splx(s);
229 }
230 
231 static int
232 COMPATNAME(route_accept)(struct socket *so, struct mbuf *nam)
233 {
234 	KASSERT(solocked(so));
235 
236 	panic("route_accept");
237 
238 	return EOPNOTSUPP;
239 }
240 
241 static int
242 COMPATNAME(route_bind)(struct socket *so, struct sockaddr *nam, struct lwp *l)
243 {
244 	KASSERT(solocked(so));
245 
246 	return EOPNOTSUPP;
247 }
248 
249 static int
250 COMPATNAME(route_listen)(struct socket *so, struct lwp *l)
251 {
252 	KASSERT(solocked(so));
253 
254 	return EOPNOTSUPP;
255 }
256 
257 static int
258 COMPATNAME(route_connect)(struct socket *so, struct mbuf *nam, struct lwp *l)
259 {
260 	KASSERT(solocked(so));
261 
262 	return EOPNOTSUPP;
263 }
264 
265 static int
266 COMPATNAME(route_connect2)(struct socket *so, struct socket *so2)
267 {
268 	KASSERT(solocked(so));
269 
270 	return EOPNOTSUPP;
271 }
272 
273 static int
274 COMPATNAME(route_disconnect)(struct socket *so)
275 {
276 	struct rawcb *rp = sotorawcb(so);
277 	int s;
278 
279 	KASSERT(solocked(so));
280 	KASSERT(rp != NULL);
281 
282 	s = splsoftnet();
283 	soisdisconnected(so);
284 	raw_disconnect(rp);
285 	splx(s);
286 
287 	return 0;
288 }
289 
290 static int
291 COMPATNAME(route_shutdown)(struct socket *so)
292 {
293 	int s;
294 
295 	KASSERT(solocked(so));
296 
297 	/*
298 	 * Mark the connection as being incapable of further input.
299 	 */
300 	s = splsoftnet();
301 	socantsendmore(so);
302 	splx(s);
303 	return 0;
304 }
305 
306 static int
307 COMPATNAME(route_abort)(struct socket *so)
308 {
309 	KASSERT(solocked(so));
310 
311 	panic("route_abort");
312 
313 	return EOPNOTSUPP;
314 }
315 
316 static int
317 COMPATNAME(route_ioctl)(struct socket *so, u_long cmd, void *nam,
318     struct ifnet * ifp)
319 {
320 	return EOPNOTSUPP;
321 }
322 
323 static int
324 COMPATNAME(route_stat)(struct socket *so, struct stat *ub)
325 {
326 	KASSERT(solocked(so));
327 
328 	return 0;
329 }
330 
331 static int
332 COMPATNAME(route_peeraddr)(struct socket *so, struct mbuf *nam)
333 {
334 	struct rawcb *rp = sotorawcb(so);
335 
336 	KASSERT(solocked(so));
337 	KASSERT(rp != NULL);
338 	KASSERT(nam != NULL);
339 
340 	if (rp->rcb_faddr == NULL)
341 		return ENOTCONN;
342 
343 	raw_setpeeraddr(rp, nam);
344 	return 0;
345 }
346 
347 static int
348 COMPATNAME(route_sockaddr)(struct socket *so, struct mbuf *nam)
349 {
350 	struct rawcb *rp = sotorawcb(so);
351 
352 	KASSERT(solocked(so));
353 	KASSERT(rp != NULL);
354 	KASSERT(nam != NULL);
355 
356 	if (rp->rcb_faddr == NULL)
357 		return ENOTCONN;
358 
359 	raw_setsockaddr(rp, nam);
360 	return 0;
361 }
362 
363 static int
364 COMPATNAME(route_rcvd)(struct socket *so, int flags, struct lwp *l)
365 {
366 	KASSERT(solocked(so));
367 
368 	return EOPNOTSUPP;
369 }
370 
371 static int
372 COMPATNAME(route_recvoob)(struct socket *so, struct mbuf *m, int flags)
373 {
374 	KASSERT(solocked(so));
375 
376 	return EOPNOTSUPP;
377 }
378 
379 static int
380 COMPATNAME(route_send)(struct socket *so, struct mbuf *m,
381     struct mbuf *nam, struct mbuf *control, struct lwp *l)
382 {
383 	int error = 0;
384 	int s;
385 
386 	KASSERT(solocked(so));
387 
388 	s = splsoftnet();
389 	error = raw_send(so, m, nam, control, l);
390 	splx(s);
391 
392 	return error;
393 }
394 
395 static int
396 COMPATNAME(route_sendoob)(struct socket *so, struct mbuf *m,
397     struct mbuf *control)
398 {
399 	KASSERT(solocked(so));
400 
401 	m_freem(m);
402 	m_freem(control);
403 
404 	return EOPNOTSUPP;
405 }
406 static int
407 COMPATNAME(route_purgeif)(struct socket *so, struct ifnet *ifp)
408 {
409 
410 	panic("route_purgeif");
411 
412 	return EOPNOTSUPP;
413 }
414 
415 static int
416 COMPATNAME(route_usrreq)(struct socket *so, int req, struct mbuf *m,
417     struct mbuf *nam, struct mbuf *control, struct lwp *l)
418 {
419 	int s, error = 0;
420 
421 	KASSERT(req != PRU_ATTACH);
422 	KASSERT(req != PRU_DETACH);
423 	KASSERT(req != PRU_ACCEPT);
424 	KASSERT(req != PRU_BIND);
425 	KASSERT(req != PRU_LISTEN);
426 	KASSERT(req != PRU_CONNECT);
427 	KASSERT(req != PRU_CONNECT2);
428 	KASSERT(req != PRU_DISCONNECT);
429 	KASSERT(req != PRU_SHUTDOWN);
430 	KASSERT(req != PRU_ABORT);
431 	KASSERT(req != PRU_CONTROL);
432 	KASSERT(req != PRU_SENSE);
433 	KASSERT(req != PRU_PEERADDR);
434 	KASSERT(req != PRU_SOCKADDR);
435 	KASSERT(req != PRU_RCVD);
436 	KASSERT(req != PRU_RCVOOB);
437 	KASSERT(req != PRU_SEND);
438 	KASSERT(req != PRU_SENDOOB);
439 	KASSERT(req != PRU_PURGEIF);
440 
441 	s = splsoftnet();
442 	error = raw_usrreq(so, req, m, nam, control, l);
443 	splx(s);
444 
445 	return error;
446 }
447 
448 /*ARGSUSED*/
449 int
450 COMPATNAME(route_output)(struct mbuf *m, ...)
451 {
452 	struct sockproto proto = { .sp_family = PF_XROUTE, };
453 	struct rt_xmsghdr *rtm = NULL;
454 	struct rt_xmsghdr *old_rtm = NULL;
455 	struct rtentry *rt = NULL;
456 	struct rtentry *saved_nrt = NULL;
457 	struct rt_addrinfo info;
458 	int len, error = 0;
459 	struct ifnet *ifp = NULL;
460 	struct ifaddr *ifa = NULL;
461 	struct socket *so;
462 	va_list ap;
463 	sa_family_t family;
464 
465 	va_start(ap, m);
466 	so = va_arg(ap, struct socket *);
467 	va_end(ap);
468 
469 #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0)
470 	if (m == NULL || ((m->m_len < sizeof(int32_t)) &&
471 	   (m = m_pullup(m, sizeof(int32_t))) == NULL))
472 		return ENOBUFS;
473 	if ((m->m_flags & M_PKTHDR) == 0)
474 		panic("%s", __func__);
475 	len = m->m_pkthdr.len;
476 	if (len < sizeof(*rtm) ||
477 	    len != mtod(m, struct rt_xmsghdr *)->rtm_msglen) {
478 		info.rti_info[RTAX_DST] = NULL;
479 		senderr(EINVAL);
480 	}
481 	R_Malloc(rtm, struct rt_xmsghdr *, len);
482 	if (rtm == NULL) {
483 		info.rti_info[RTAX_DST] = NULL;
484 		senderr(ENOBUFS);
485 	}
486 	m_copydata(m, 0, len, rtm);
487 	if (rtm->rtm_version != RTM_XVERSION) {
488 		info.rti_info[RTAX_DST] = NULL;
489 		senderr(EPROTONOSUPPORT);
490 	}
491 	rtm->rtm_pid = curproc->p_pid;
492 	memset(&info, 0, sizeof(info));
493 	info.rti_addrs = rtm->rtm_addrs;
494 	if (rt_xaddrs(rtm->rtm_type, (const char *)(rtm + 1), len + (char *)rtm,
495 	    &info)) {
496 		senderr(EINVAL);
497 	}
498 	info.rti_flags = rtm->rtm_flags;
499 #ifdef RTSOCK_DEBUG
500 	if (info.rti_info[RTAX_DST]->sa_family == AF_INET) {
501 		char abuf[INET_ADDRSTRLEN];
502 		printf("%s: extracted info.rti_info[RTAX_DST] %s\n", __func__,
503 		    RT_IN_PRINT(abuf, RTAX_DST));
504 	}
505 #endif /* RTSOCK_DEBUG */
506 	if (info.rti_info[RTAX_DST] == NULL ||
507 	    (info.rti_info[RTAX_DST]->sa_family >= AF_MAX)) {
508 		senderr(EINVAL);
509 	}
510 	if (info.rti_info[RTAX_GATEWAY] != NULL &&
511 	    (info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) {
512 		senderr(EINVAL);
513 	}
514 
515 	/*
516 	 * Verify that the caller has the appropriate privilege; RTM_GET
517 	 * is the only operation the non-superuser is allowed.
518 	 */
519 	if (kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_ROUTE,
520 	    0, rtm, NULL, NULL) != 0)
521 		senderr(EACCES);
522 
523 	switch (rtm->rtm_type) {
524 
525 	case RTM_ADD:
526 		if (info.rti_info[RTAX_GATEWAY] == NULL) {
527 			senderr(EINVAL);
528 		}
529 		error = rtrequest1(rtm->rtm_type, &info, &saved_nrt);
530 		if (error == 0 && saved_nrt) {
531 			rt_setmetrics(rtm->rtm_inits, rtm, saved_nrt);
532 			saved_nrt->rt_refcnt--;
533 		}
534 		break;
535 
536 	case RTM_DELETE:
537 		error = rtrequest1(rtm->rtm_type, &info, &saved_nrt);
538 		if (error == 0) {
539 			(rt = saved_nrt)->rt_refcnt++;
540 			goto report;
541 		}
542 		break;
543 
544 	case RTM_GET:
545 	case RTM_CHANGE:
546 	case RTM_LOCK:
547                 /* XXX This will mask info.rti_info[RTAX_DST] with
548 		 * info.rti_info[RTAX_NETMASK] before
549                  * searching.  It did not used to do that.  --dyoung
550 		 */
551 		error = rtrequest1(RTM_GET, &info, &rt);
552 		if (error != 0)
553 			senderr(error);
554 		if (rtm->rtm_type != RTM_GET) {/* XXX: too grotty */
555 			if (memcmp(info.rti_info[RTAX_DST], rt_getkey(rt),
556 			    info.rti_info[RTAX_DST]->sa_len) != 0)
557 				senderr(ESRCH);
558 			if (info.rti_info[RTAX_NETMASK] == NULL &&
559 			    rt_mask(rt) != NULL)
560 				senderr(ETOOMANYREFS);
561 		}
562 
563 		switch (rtm->rtm_type) {
564 		case RTM_GET:
565 		report:
566 			info.rti_info[RTAX_DST] = rt_getkey(rt);
567 			info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
568 			info.rti_info[RTAX_NETMASK] = rt_mask(rt);
569 			info.rti_info[RTAX_TAG] = rt_gettag(rt);
570 			if ((rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) == 0)
571 				;
572 			else if ((ifp = rt->rt_ifp) != NULL) {
573 				const struct ifaddr *rtifa;
574 				info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr;
575                                 /* rtifa used to be simply rt->rt_ifa.
576                                  * If rt->rt_ifa != NULL, then
577                                  * rt_get_ifa() != NULL.  So this
578                                  * ought to still be safe. --dyoung
579 				 */
580 				rtifa = rt_get_ifa(rt);
581 				info.rti_info[RTAX_IFA] = rtifa->ifa_addr;
582 #ifdef RTSOCK_DEBUG
583 				if (info.rti_info[RTAX_IFA]->sa_family ==
584 				    AF_INET) {
585 					char ibuf[INET_ADDRSTRLEN];
586 					char abuf[INET_ADDRSTRLEN];
587 					printf("%s: copying out RTAX_IFA %s "
588 					    "for info.rti_info[RTAX_DST] %s "
589 					    "ifa_getifa %p ifa_seqno %p\n",
590 					    __func__,
591 					    RT_IN_PRINT(ibuf, RTAX_IFA),
592 					    RT_IN_PRINT(abuf, RTAX_DST),
593 					    (void *)rtifa->ifa_getifa,
594 					    rtifa->ifa_seqno);
595 				}
596 #endif /* RTSOCK_DEBUG */
597 				if (ifp->if_flags & IFF_POINTOPOINT) {
598 					info.rti_info[RTAX_BRD] =
599 					    rtifa->ifa_dstaddr;
600 				} else
601 					info.rti_info[RTAX_BRD] = NULL;
602 				rtm->rtm_index = ifp->if_index;
603 			} else {
604 				info.rti_info[RTAX_IFP] = NULL;
605 				info.rti_info[RTAX_IFA] = NULL;
606 			}
607 			(void)rt_msg2(rtm->rtm_type, &info, NULL, NULL, &len);
608 			if (len > rtm->rtm_msglen) {
609 				old_rtm = rtm;
610 				R_Malloc(rtm, struct rt_xmsghdr *, len);
611 				if (rtm == NULL)
612 					senderr(ENOBUFS);
613 				(void)memcpy(rtm, old_rtm, old_rtm->rtm_msglen);
614 			}
615 			(void)rt_msg2(rtm->rtm_type, &info, rtm, NULL, 0);
616 			rtm->rtm_flags = rt->rt_flags;
617 			rtm_setmetrics(rt, rtm);
618 			rtm->rtm_addrs = info.rti_addrs;
619 			break;
620 
621 		case RTM_CHANGE:
622 			/*
623 			 * new gateway could require new ifaddr, ifp;
624 			 * flags may also be different; ifp may be specified
625 			 * by ll sockaddr when protocol address is ambiguous
626 			 */
627 			if ((error = rt_getifa(&info)) != 0)
628 				senderr(error);
629 			if (info.rti_info[RTAX_GATEWAY] &&
630 			    rt_setgate(rt, info.rti_info[RTAX_GATEWAY]))
631 				senderr(EDQUOT);
632 			if (info.rti_info[RTAX_TAG])
633 				rt_settag(rt, info.rti_info[RTAX_TAG]);
634 			/* new gateway could require new ifaddr, ifp;
635 			   flags may also be different; ifp may be specified
636 			   by ll sockaddr when protocol address is ambiguous */
637 			if (info.rti_info[RTAX_IFP] &&
638 			    (ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP])) &&
639 			    (ifp = ifa->ifa_ifp) && (info.rti_info[RTAX_IFA] ||
640 			    info.rti_info[RTAX_GATEWAY])) {
641 				if (info.rti_info[RTAX_IFA] == NULL ||
642 				    (ifa = ifa_ifwithaddr(
643 				    info.rti_info[RTAX_IFA])) == NULL)
644 					ifa = ifaof_ifpforaddr(
645 					    info.rti_info[RTAX_IFA] ?
646 					    info.rti_info[RTAX_IFA] :
647 					    info.rti_info[RTAX_GATEWAY], ifp);
648 			} else if ((info.rti_info[RTAX_IFA] &&
649 			    (ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]))) ||
650 			    (info.rti_info[RTAX_GATEWAY] &&
651 			    (ifa = ifa_ifwithroute(rt->rt_flags,
652 			    rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) {
653 				ifp = ifa->ifa_ifp;
654 			}
655 			if (ifa) {
656 				struct ifaddr *oifa = rt->rt_ifa;
657 				if (oifa != ifa) {
658 					if (oifa && oifa->ifa_rtrequest) {
659 						oifa->ifa_rtrequest(RTM_DELETE,
660 						    rt, &info);
661 					}
662 					rt_replace_ifa(rt, ifa);
663 					rt->rt_ifp = ifp;
664 				}
665 			}
666 			if (ifp && rt->rt_ifp != ifp)
667 				rt->rt_ifp = ifp;
668 			rt_setmetrics(rtm->rtm_inits, rtm, rt);
669 			if (rt->rt_flags != info.rti_flags)
670 				rt->rt_flags = (info.rti_flags & ~PRESERVED_RTF)
671 				    | (rt->rt_flags & PRESERVED_RTF);
672 			if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
673 				rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info);
674 			/*FALLTHROUGH*/
675 		case RTM_LOCK:
676 			rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
677 			rt->rt_rmx.rmx_locks |=
678 			    (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
679 			break;
680 		}
681 		break;
682 
683 	default:
684 		senderr(EOPNOTSUPP);
685 	}
686 
687 flush:
688 	if (rtm) {
689 		if (error)
690 			rtm->rtm_errno = error;
691 		else
692 			rtm->rtm_flags |= RTF_DONE;
693 	}
694 	family = info.rti_info[RTAX_DST] ? info.rti_info[RTAX_DST]->sa_family :
695 	    0;
696 	/* We cannot free old_rtm until we have stopped using the
697 	 * pointers in info, some of which may point to sockaddrs
698 	 * in old_rtm.
699 	 */
700 	if (old_rtm != NULL)
701 		Free(old_rtm);
702 	if (rt)
703 		rtfree(rt);
704     {
705 	struct rawcb *rp = NULL;
706 	/*
707 	 * Check to see if we don't want our own messages.
708 	 */
709 	if ((so->so_options & SO_USELOOPBACK) == 0) {
710 		if (COMPATNAME(route_info).ri_cb.any_count <= 1) {
711 			if (rtm)
712 				Free(rtm);
713 			m_freem(m);
714 			return error;
715 		}
716 		/* There is another listener, so construct message */
717 		rp = sotorawcb(so);
718 	}
719 	if (rtm) {
720 		m_copyback(m, 0, rtm->rtm_msglen, rtm);
721 		if (m->m_pkthdr.len < rtm->rtm_msglen) {
722 			m_freem(m);
723 			m = NULL;
724 		} else if (m->m_pkthdr.len > rtm->rtm_msglen)
725 			m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
726 		Free(rtm);
727 	}
728 	if (rp)
729 		rp->rcb_proto.sp_family = 0; /* Avoid us */
730 	if (family)
731 		proto.sp_protocol = family;
732 	if (m)
733 		raw_input(m, &proto, &COMPATNAME(route_info).ri_src,
734 		    &COMPATNAME(route_info).ri_dst);
735 	if (rp)
736 		rp->rcb_proto.sp_family = PF_XROUTE;
737     }
738 	return error;
739 }
740 
741 static void
742 rt_setmetrics(int which, const struct rt_xmsghdr *in, struct rtentry *out)
743 {
744 #define metric(f, e) if (which & (f)) out->rt_rmx.e = in->rtm_rmx.e;
745 	metric(RTV_RPIPE, rmx_recvpipe);
746 	metric(RTV_SPIPE, rmx_sendpipe);
747 	metric(RTV_SSTHRESH, rmx_ssthresh);
748 	metric(RTV_RTT, rmx_rtt);
749 	metric(RTV_RTTVAR, rmx_rttvar);
750 	metric(RTV_HOPCOUNT, rmx_hopcount);
751 	metric(RTV_MTU, rmx_mtu);
752 	metric(RTV_EXPIRE, rmx_expire);
753 #undef metric
754 }
755 
756 static void
757 rtm_setmetrics(const struct rtentry *in, struct rt_xmsghdr *out)
758 {
759 #define metric(e) out->rtm_rmx.e = in->rt_rmx.e;
760 	metric(rmx_recvpipe);
761 	metric(rmx_sendpipe);
762 	metric(rmx_ssthresh);
763 	metric(rmx_rtt);
764 	metric(rmx_rttvar);
765 	metric(rmx_hopcount);
766 	metric(rmx_mtu);
767 	metric(rmx_expire);
768 #undef metric
769 }
770 
771 static int
772 rt_xaddrs(u_char rtmtype, const char *cp, const char *cplim,
773     struct rt_addrinfo *rtinfo)
774 {
775 	const struct sockaddr *sa = NULL;	/* Quell compiler warning */
776 	int i;
777 
778 	for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
779 		if ((rtinfo->rti_addrs & (1 << i)) == 0)
780 			continue;
781 		rtinfo->rti_info[i] = sa = (const struct sockaddr *)cp;
782 		RT_XADVANCE(cp, sa);
783 	}
784 
785 	/*
786 	 * Check for extra addresses specified, except RTM_GET asking
787 	 * for interface info.
788 	 */
789 	if (rtmtype == RTM_GET) {
790 		if (((rtinfo->rti_addrs &
791 		    (~((1 << RTAX_IFP) | (1 << RTAX_IFA)))) & (~0 << i)) != 0)
792 			return 1;
793 	} else if ((rtinfo->rti_addrs & (~0 << i)) != 0)
794 		return 1;
795 	/* Check for bad data length.  */
796 	if (cp != cplim) {
797 		if (i == RTAX_NETMASK + 1 && sa != NULL &&
798 		    cp - RT_XROUNDUP(sa->sa_len) + sa->sa_len == cplim)
799 			/*
800 			 * The last sockaddr was info.rti_info[RTAX_NETMASK].
801 			 * We accept this for now for the sake of old
802 			 * binaries or third party softwares.
803 			 */
804 			;
805 		else
806 			return 1;
807 	}
808 	return 0;
809 }
810 
811 static int
812 rt_getlen(int type)
813 {
814 #ifndef COMPAT_RTSOCK
815 	CTASSERT(__alignof(struct ifa_msghdr) >= sizeof(uint64_t));
816 	CTASSERT(__alignof(struct if_msghdr) >= sizeof(uint64_t));
817 	CTASSERT(__alignof(struct if_announcemsghdr) >= sizeof(uint64_t));
818 	CTASSERT(__alignof(struct rt_msghdr) >= sizeof(uint64_t));
819 #endif
820 
821 	switch (type) {
822 	case RTM_DELADDR:
823 	case RTM_NEWADDR:
824 	case RTM_CHGADDR:
825 		return sizeof(struct ifa_xmsghdr);
826 
827 	case RTM_OOIFINFO:
828 #ifdef COMPAT_14
829 		return sizeof(struct if_msghdr14);
830 #else
831 #ifdef DIAGNOSTIC
832 		printf("RTM_OOIFINFO\n");
833 #endif
834 		return -1;
835 #endif
836 	case RTM_OIFINFO:
837 #ifdef COMPAT_50
838 		return sizeof(struct if_msghdr50);
839 #else
840 #ifdef DIAGNOSTIC
841 		printf("RTM_OIFINFO\n");
842 #endif
843 		return -1;
844 #endif
845 
846 	case RTM_IFINFO:
847 		return sizeof(struct if_xmsghdr);
848 
849 	case RTM_IFANNOUNCE:
850 	case RTM_IEEE80211:
851 		return sizeof(struct if_xannouncemsghdr);
852 
853 	default:
854 		return sizeof(struct rt_xmsghdr);
855 	}
856 }
857 
858 
859 struct mbuf *
860 COMPATNAME(rt_msg1)(int type, struct rt_addrinfo *rtinfo, void *data, int datalen)
861 {
862 	struct rt_xmsghdr *rtm;
863 	struct mbuf *m;
864 	int i;
865 	const struct sockaddr *sa;
866 	int len, dlen;
867 
868 	m = m_gethdr(M_DONTWAIT, MT_DATA);
869 	if (m == NULL)
870 		return m;
871 	MCLAIM(m, &COMPATNAME(routedomain).dom_mowner);
872 
873 	if ((len = rt_getlen(type)) == -1)
874 		goto out;
875 	if (len > MHLEN + MLEN)
876 		panic("%s: message too long", __func__);
877 	else if (len > MHLEN) {
878 		m->m_next = m_get(M_DONTWAIT, MT_DATA);
879 		if (m->m_next == NULL)
880 			goto out;
881 		MCLAIM(m->m_next, m->m_owner);
882 		m->m_pkthdr.len = len;
883 		m->m_len = MHLEN;
884 		m->m_next->m_len = len - MHLEN;
885 	} else {
886 		m->m_pkthdr.len = m->m_len = len;
887 	}
888 	m->m_pkthdr.rcvif = NULL;
889 	m_copyback(m, 0, datalen, data);
890 	if (len > datalen)
891 		(void)memset(mtod(m, char *) + datalen, 0, len - datalen);
892 	rtm = mtod(m, struct rt_xmsghdr *);
893 	for (i = 0; i < RTAX_MAX; i++) {
894 		if ((sa = rtinfo->rti_info[i]) == NULL)
895 			continue;
896 		rtinfo->rti_addrs |= (1 << i);
897 		dlen = RT_XROUNDUP(sa->sa_len);
898 		m_copyback(m, len, sa->sa_len, sa);
899 		if (dlen != sa->sa_len) {
900 			/*
901 			 * Up to 6 + 1 nul's since roundup is to
902 			 * sizeof(uint64_t) (8 bytes)
903 			 */
904 			m_copyback(m, len + sa->sa_len,
905 			    dlen - sa->sa_len, "\0\0\0\0\0\0");
906 		}
907 		len += dlen;
908 	}
909 	if (m->m_pkthdr.len != len)
910 		goto out;
911 	rtm->rtm_msglen = len;
912 	rtm->rtm_version = RTM_XVERSION;
913 	rtm->rtm_type = type;
914 	return m;
915 out:
916 	m_freem(m);
917 	return NULL;
918 }
919 
920 /*
921  * rt_msg2
922  *
923  *	 fills 'cp' or 'w'.w_tmem with the routing socket message and
924  *		returns the length of the message in 'lenp'.
925  *
926  * if walkarg is 0, cp is expected to be 0 or a buffer large enough to hold
927  *	the message
928  * otherwise walkarg's w_needed is updated and if the user buffer is
929  *	specified and w_needed indicates space exists the information is copied
930  *	into the temp space (w_tmem). w_tmem is [re]allocated if necessary,
931  *	if the allocation fails ENOBUFS is returned.
932  */
933 static int
934 rt_msg2(int type, struct rt_addrinfo *rtinfo, void *cpv, struct rt_walkarg *w,
935 	int *lenp)
936 {
937 	int i;
938 	int len, dlen, second_time = 0;
939 	char *cp0, *cp = cpv;
940 
941 	rtinfo->rti_addrs = 0;
942 again:
943 	if ((len = rt_getlen(type)) == -1)
944 		return EINVAL;
945 
946 	if ((cp0 = cp) != NULL)
947 		cp += len;
948 	for (i = 0; i < RTAX_MAX; i++) {
949 		const struct sockaddr *sa;
950 
951 		if ((sa = rtinfo->rti_info[i]) == NULL)
952 			continue;
953 		rtinfo->rti_addrs |= (1 << i);
954 		dlen = RT_XROUNDUP(sa->sa_len);
955 		if (cp) {
956 			int diff = dlen - sa->sa_len;
957 			(void)memcpy(cp, sa, (size_t)sa->sa_len);
958 			cp += sa->sa_len;
959 			if (diff > 0) {
960 				(void)memset(cp, 0, (size_t)diff);
961 				cp += diff;
962 			}
963 		}
964 		len += dlen;
965 	}
966 	if (cp == NULL && w != NULL && !second_time) {
967 		struct rt_walkarg *rw = w;
968 
969 		rw->w_needed += len;
970 		if (rw->w_needed <= 0 && rw->w_where) {
971 			if (rw->w_tmemsize < len) {
972 				if (rw->w_tmem)
973 					free(rw->w_tmem, M_RTABLE);
974 				rw->w_tmem = malloc(len, M_RTABLE, M_NOWAIT);
975 				if (rw->w_tmem)
976 					rw->w_tmemsize = len;
977 				else
978 					rw->w_tmemsize = 0;
979 			}
980 			if (rw->w_tmem) {
981 				cp = rw->w_tmem;
982 				second_time = 1;
983 				goto again;
984 			} else {
985 				rw->w_tmemneeded = len;
986 				return ENOBUFS;
987 			}
988 		}
989 	}
990 	if (cp) {
991 		struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)cp0;
992 
993 		rtm->rtm_version = RTM_XVERSION;
994 		rtm->rtm_type = type;
995 		rtm->rtm_msglen = len;
996 	}
997 	if (lenp)
998 		*lenp = len;
999 	return 0;
1000 }
1001 
1002 /*
1003  * This routine is called to generate a message from the routing
1004  * socket indicating that a redirect has occurred, a routing lookup
1005  * has failed, or that a protocol has detected timeouts to a particular
1006  * destination.
1007  */
1008 void
1009 COMPATNAME(rt_missmsg)(int type, const struct rt_addrinfo *rtinfo, int flags,
1010     int error)
1011 {
1012 	struct rt_xmsghdr rtm;
1013 	struct mbuf *m;
1014 	const struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
1015 	struct rt_addrinfo info = *rtinfo;
1016 
1017 	COMPATCALL(rt_missmsg, (type, rtinfo, flags, error));
1018 	if (COMPATNAME(route_info).ri_cb.any_count == 0)
1019 		return;
1020 	memset(&rtm, 0, sizeof(rtm));
1021 	rtm.rtm_flags = RTF_DONE | flags;
1022 	rtm.rtm_errno = error;
1023 	m = COMPATNAME(rt_msg1)(type, &info, &rtm, sizeof(rtm));
1024 	if (m == NULL)
1025 		return;
1026 	mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs;
1027 	COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0);
1028 }
1029 
1030 /*
1031  * This routine is called to generate a message from the routing
1032  * socket indicating that the status of a network interface has changed.
1033  */
1034 void
1035 COMPATNAME(rt_ifmsg)(struct ifnet *ifp)
1036 {
1037 	struct if_xmsghdr ifm;
1038 	struct mbuf *m;
1039 	struct rt_addrinfo info;
1040 
1041 	COMPATCALL(rt_ifmsg, (ifp));
1042 	if (COMPATNAME(route_info).ri_cb.any_count == 0)
1043 		return;
1044 	(void)memset(&info, 0, sizeof(info));
1045 	(void)memset(&ifm, 0, sizeof(ifm));
1046 	ifm.ifm_index = ifp->if_index;
1047 	ifm.ifm_flags = ifp->if_flags;
1048 	ifm.ifm_data = ifp->if_data;
1049 	ifm.ifm_addrs = 0;
1050 	m = COMPATNAME(rt_msg1)(RTM_IFINFO, &info, &ifm, sizeof(ifm));
1051 	if (m == NULL)
1052 		return;
1053 	COMPATNAME(route_enqueue)(m, 0);
1054 #ifdef COMPAT_14
1055 	compat_14_rt_oifmsg(ifp);
1056 #endif
1057 #ifdef COMPAT_50
1058 	compat_50_rt_oifmsg(ifp);
1059 #endif
1060 }
1061 
1062 
1063 /*
1064  * This is called to generate messages from the routing socket
1065  * indicating a network interface has had addresses associated with it.
1066  * if we ever reverse the logic and replace messages TO the routing
1067  * socket indicate a request to configure interfaces, then it will
1068  * be unnecessary as the routing socket will automatically generate
1069  * copies of it.
1070  */
1071 void
1072 COMPATNAME(rt_newaddrmsg)(int cmd, struct ifaddr *ifa, int error,
1073     struct rtentry *rt)
1074 {
1075 #define	cmdpass(__cmd, __pass)	(((__cmd) << 2) | (__pass))
1076 	struct rt_addrinfo info;
1077 	const struct sockaddr *sa;
1078 	int pass;
1079 	struct mbuf *m;
1080 	struct ifnet *ifp;
1081 	struct rt_xmsghdr rtm;
1082 	struct ifa_xmsghdr ifam;
1083 	int ncmd;
1084 
1085 	KASSERT(ifa != NULL);
1086 	ifp = ifa->ifa_ifp;
1087 	COMPATCALL(rt_newaddrmsg, (cmd, ifa, error, rt));
1088 	if (COMPATNAME(route_info).ri_cb.any_count == 0)
1089 		return;
1090 	for (pass = 1; pass < 3; pass++) {
1091 		memset(&info, 0, sizeof(info));
1092 		switch (cmdpass(cmd, pass)) {
1093 		case cmdpass(RTM_ADD, 1):
1094 		case cmdpass(RTM_CHANGE, 1):
1095 		case cmdpass(RTM_DELETE, 2):
1096 		case cmdpass(RTM_NEWADDR, 1):
1097 		case cmdpass(RTM_DELADDR, 1):
1098 		case cmdpass(RTM_CHGADDR, 1):
1099 			switch (cmd) {
1100 			case RTM_ADD:
1101 				ncmd = RTM_NEWADDR;
1102 				break;
1103 			case RTM_DELETE:
1104 				ncmd = RTM_DELADDR;
1105 				break;
1106 			case RTM_CHANGE:
1107 				ncmd = RTM_CHGADDR;
1108 				break;
1109 			default:
1110 				ncmd = cmd;
1111 			}
1112 			info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
1113 			KASSERT(ifp->if_dl != NULL);
1114 			info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr;
1115 			info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1116 			info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1117 			memset(&ifam, 0, sizeof(ifam));
1118 			ifam.ifam_index = ifp->if_index;
1119 			ifam.ifam_metric = ifa->ifa_metric;
1120 			ifam.ifam_flags = ifa->ifa_flags;
1121 			m = COMPATNAME(rt_msg1)(ncmd, &info, &ifam, sizeof(ifam));
1122 			if (m == NULL)
1123 				continue;
1124 			mtod(m, struct ifa_xmsghdr *)->ifam_addrs =
1125 			    info.rti_addrs;
1126 			break;
1127 		case cmdpass(RTM_ADD, 2):
1128 		case cmdpass(RTM_CHANGE, 2):
1129 		case cmdpass(RTM_DELETE, 1):
1130 			if (rt == NULL)
1131 				continue;
1132 			info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1133 			info.rti_info[RTAX_DST] = sa = rt_getkey(rt);
1134 			info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1135 			memset(&rtm, 0, sizeof(rtm));
1136 			rtm.rtm_index = ifp->if_index;
1137 			rtm.rtm_flags |= rt->rt_flags;
1138 			rtm.rtm_errno = error;
1139 			m = COMPATNAME(rt_msg1)(cmd, &info, &rtm, sizeof(rtm));
1140 			if (m == NULL)
1141 				continue;
1142 			mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs;
1143 			break;
1144 		default:
1145 			continue;
1146 		}
1147 #ifdef DIAGNOSTIC
1148 		if (m == NULL)
1149 			panic("%s: called with wrong command", __func__);
1150 #endif
1151 		COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0);
1152 	}
1153 #undef cmdpass
1154 }
1155 
1156 static struct mbuf *
1157 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what,
1158     struct rt_addrinfo *info)
1159 {
1160 	struct if_xannouncemsghdr ifan;
1161 
1162 	memset(info, 0, sizeof(*info));
1163 	memset(&ifan, 0, sizeof(ifan));
1164 	ifan.ifan_index = ifp->if_index;
1165 	strlcpy(ifan.ifan_name, ifp->if_xname, sizeof(ifan.ifan_name));
1166 	ifan.ifan_what = what;
1167 	return COMPATNAME(rt_msg1)(type, info, &ifan, sizeof(ifan));
1168 }
1169 
1170 /*
1171  * This is called to generate routing socket messages indicating
1172  * network interface arrival and departure.
1173  */
1174 void
1175 COMPATNAME(rt_ifannouncemsg)(struct ifnet *ifp, int what)
1176 {
1177 	struct mbuf *m;
1178 	struct rt_addrinfo info;
1179 
1180 	COMPATCALL(rt_ifannouncemsg, (ifp, what));
1181 	if (COMPATNAME(route_info).ri_cb.any_count == 0)
1182 		return;
1183 	m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
1184 	if (m == NULL)
1185 		return;
1186 	COMPATNAME(route_enqueue)(m, 0);
1187 }
1188 
1189 /*
1190  * This is called to generate routing socket messages indicating
1191  * IEEE80211 wireless events.
1192  * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way.
1193  */
1194 void
1195 COMPATNAME(rt_ieee80211msg)(struct ifnet *ifp, int what, void *data,
1196 	size_t data_len)
1197 {
1198 	struct mbuf *m;
1199 	struct rt_addrinfo info;
1200 
1201 	COMPATCALL(rt_ieee80211msg, (ifp, what, data, data_len));
1202 	if (COMPATNAME(route_info).ri_cb.any_count == 0)
1203 		return;
1204 	m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info);
1205 	if (m == NULL)
1206 		return;
1207 	/*
1208 	 * Append the ieee80211 data.  Try to stick it in the
1209 	 * mbuf containing the ifannounce msg; otherwise allocate
1210 	 * a new mbuf and append.
1211 	 *
1212 	 * NB: we assume m is a single mbuf.
1213 	 */
1214 	if (data_len > M_TRAILINGSPACE(m)) {
1215 		struct mbuf *n = m_get(M_NOWAIT, MT_DATA);
1216 		if (n == NULL) {
1217 			m_freem(m);
1218 			return;
1219 		}
1220 		(void)memcpy(mtod(n, void *), data, data_len);
1221 		n->m_len = data_len;
1222 		m->m_next = n;
1223 	} else if (data_len > 0) {
1224 		(void)memcpy(mtod(m, uint8_t *) + m->m_len, data, data_len);
1225 		m->m_len += data_len;
1226 	}
1227 	if (m->m_flags & M_PKTHDR)
1228 		m->m_pkthdr.len += data_len;
1229 	mtod(m, struct if_xannouncemsghdr *)->ifan_msglen += data_len;
1230 	COMPATNAME(route_enqueue)(m, 0);
1231 }
1232 
1233 /*
1234  * This is used in dumping the kernel table via sysctl().
1235  */
1236 static int
1237 sysctl_dumpentry(struct rtentry *rt, void *v)
1238 {
1239 	struct rt_walkarg *w = v;
1240 	int error = 0, size;
1241 	struct rt_addrinfo info;
1242 
1243 	if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
1244 		return 0;
1245 	memset(&info, 0, sizeof(info));
1246 	info.rti_info[RTAX_DST] = rt_getkey(rt);
1247 	info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1248 	info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1249 	info.rti_info[RTAX_TAG] = rt_gettag(rt);
1250 	if (rt->rt_ifp) {
1251 		const struct ifaddr *rtifa;
1252 		info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr;
1253 		/* rtifa used to be simply rt->rt_ifa.  If rt->rt_ifa != NULL,
1254 		 * then rt_get_ifa() != NULL.  So this ought to still be safe.
1255 		 * --dyoung
1256 		 */
1257 		rtifa = rt_get_ifa(rt);
1258 		info.rti_info[RTAX_IFA] = rtifa->ifa_addr;
1259 		if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
1260 			info.rti_info[RTAX_BRD] = rtifa->ifa_dstaddr;
1261 	}
1262 	if ((error = rt_msg2(RTM_GET, &info, 0, w, &size)))
1263 		return error;
1264 	if (w->w_where && w->w_tmem && w->w_needed <= 0) {
1265 		struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)w->w_tmem;
1266 
1267 		rtm->rtm_flags = rt->rt_flags;
1268 		rtm->rtm_use = rt->rt_use;
1269 		rtm_setmetrics(rt, rtm);
1270 		KASSERT(rt->rt_ifp != NULL);
1271 		rtm->rtm_index = rt->rt_ifp->if_index;
1272 		rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;
1273 		rtm->rtm_addrs = info.rti_addrs;
1274 		if ((error = copyout(rtm, w->w_where, size)) != 0)
1275 			w->w_where = NULL;
1276 		else
1277 			w->w_where = (char *)w->w_where + size;
1278 	}
1279 	return error;
1280 }
1281 
1282 static int
1283 sysctl_iflist(int af, struct rt_walkarg *w, int type)
1284 {
1285 	struct ifnet *ifp;
1286 	struct ifaddr *ifa;
1287 	struct	rt_addrinfo info;
1288 	int	len, error = 0;
1289 
1290 	memset(&info, 0, sizeof(info));
1291 	IFNET_FOREACH(ifp) {
1292 		if (w->w_arg && w->w_arg != ifp->if_index)
1293 			continue;
1294 		if (IFADDR_EMPTY(ifp))
1295 			continue;
1296 		info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr;
1297 		switch (type) {
1298 		case NET_RT_IFLIST:
1299 			error = rt_msg2(RTM_IFINFO, &info, NULL, w, &len);
1300 			break;
1301 #ifdef COMPAT_14
1302 		case NET_RT_OOIFLIST:
1303 			error = rt_msg2(RTM_OOIFINFO, &info, NULL, w, &len);
1304 			break;
1305 #endif
1306 #ifdef COMPAT_50
1307 		case NET_RT_OIFLIST:
1308 			error = rt_msg2(RTM_OIFINFO, &info, NULL, w, &len);
1309 			break;
1310 #endif
1311 		default:
1312 			panic("sysctl_iflist(1)");
1313 		}
1314 		if (error)
1315 			return error;
1316 		info.rti_info[RTAX_IFP] = NULL;
1317 		if (w->w_where && w->w_tmem && w->w_needed <= 0) {
1318 			switch (type) {
1319 			case NET_RT_IFLIST: {
1320 				struct if_xmsghdr *ifm;
1321 
1322 				ifm = (struct if_xmsghdr *)w->w_tmem;
1323 				ifm->ifm_index = ifp->if_index;
1324 				ifm->ifm_flags = ifp->if_flags;
1325 				ifm->ifm_data = ifp->if_data;
1326 				ifm->ifm_addrs = info.rti_addrs;
1327 				error = copyout(ifm, w->w_where, len);
1328 				if (error)
1329 					return error;
1330 				w->w_where = (char *)w->w_where + len;
1331 				break;
1332 			}
1333 
1334 #ifdef COMPAT_14
1335 			case NET_RT_OOIFLIST:
1336 				error = compat_14_iflist(ifp, w, &info, len);
1337 				if (error)
1338 					return error;
1339 				break;
1340 #endif
1341 #ifdef COMPAT_50
1342 			case NET_RT_OIFLIST:
1343 				error = compat_50_iflist(ifp, w, &info, len);
1344 				if (error)
1345 					return error;
1346 				break;
1347 #endif
1348 			default:
1349 				panic("sysctl_iflist(2)");
1350 			}
1351 		}
1352 		IFADDR_FOREACH(ifa, ifp) {
1353 			if (af && af != ifa->ifa_addr->sa_family)
1354 				continue;
1355 			info.rti_info[RTAX_IFA] = ifa->ifa_addr;
1356 			info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1357 			info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1358 			if ((error = rt_msg2(RTM_NEWADDR, &info, 0, w, &len)))
1359 				return error;
1360 			if (w->w_where && w->w_tmem && w->w_needed <= 0) {
1361 				struct ifa_xmsghdr *ifam;
1362 
1363 				ifam = (struct ifa_xmsghdr *)w->w_tmem;
1364 				ifam->ifam_index = ifa->ifa_ifp->if_index;
1365 				ifam->ifam_flags = ifa->ifa_flags;
1366 				ifam->ifam_metric = ifa->ifa_metric;
1367 				ifam->ifam_addrs = info.rti_addrs;
1368 				error = copyout(w->w_tmem, w->w_where, len);
1369 				if (error)
1370 					return error;
1371 				w->w_where = (char *)w->w_where + len;
1372 			}
1373 		}
1374 		info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] =
1375 		    info.rti_info[RTAX_BRD] = NULL;
1376 	}
1377 	return 0;
1378 }
1379 
1380 static int
1381 sysctl_rtable(SYSCTLFN_ARGS)
1382 {
1383 	void 	*where = oldp;
1384 	size_t	*given = oldlenp;
1385 	int	i, s, error = EINVAL;
1386 	u_char  af;
1387 	struct	rt_walkarg w;
1388 
1389 	if (namelen == 1 && name[0] == CTL_QUERY)
1390 		return sysctl_query(SYSCTLFN_CALL(rnode));
1391 
1392 	if (newp)
1393 		return EPERM;
1394 	if (namelen != 3)
1395 		return EINVAL;
1396 	af = name[0];
1397 	w.w_tmemneeded = 0;
1398 	w.w_tmemsize = 0;
1399 	w.w_tmem = NULL;
1400 again:
1401 	/* we may return here if a later [re]alloc of the t_mem buffer fails */
1402 	if (w.w_tmemneeded) {
1403 		w.w_tmem = malloc(w.w_tmemneeded, M_RTABLE, M_WAITOK);
1404 		w.w_tmemsize = w.w_tmemneeded;
1405 		w.w_tmemneeded = 0;
1406 	}
1407 	w.w_op = name[1];
1408 	w.w_arg = name[2];
1409 	w.w_given = *given;
1410 	w.w_needed = 0 - w.w_given;
1411 	w.w_where = where;
1412 
1413 	s = splsoftnet();
1414 	switch (w.w_op) {
1415 
1416 	case NET_RT_DUMP:
1417 	case NET_RT_FLAGS:
1418 		for (i = 1; i <= AF_MAX; i++)
1419 			if ((af == 0 || af == i) &&
1420 			    (error = rt_walktree(i, sysctl_dumpentry, &w)))
1421 				break;
1422 		break;
1423 
1424 #ifdef COMPAT_14
1425 	case NET_RT_OOIFLIST:
1426 		error = sysctl_iflist(af, &w, w.w_op);
1427 		break;
1428 #endif
1429 #ifdef COMPAT_50
1430 	case NET_RT_OIFLIST:
1431 		error = sysctl_iflist(af, &w, w.w_op);
1432 		break;
1433 #endif
1434 	case NET_RT_IFLIST:
1435 		error = sysctl_iflist(af, &w, w.w_op);
1436 		break;
1437 	}
1438 	splx(s);
1439 
1440 	/* check to see if we couldn't allocate memory with NOWAIT */
1441 	if (error == ENOBUFS && w.w_tmem == 0 && w.w_tmemneeded)
1442 		goto again;
1443 
1444 	if (w.w_tmem)
1445 		free(w.w_tmem, M_RTABLE);
1446 	w.w_needed += w.w_given;
1447 	if (where) {
1448 		*given = (char *)w.w_where - (char *)where;
1449 		if (*given < w.w_needed)
1450 			return ENOMEM;
1451 	} else {
1452 		*given = (11 * w.w_needed) / 10;
1453 	}
1454 	return error;
1455 }
1456 
1457 /*
1458  * Routing message software interrupt routine
1459  */
1460 static void
1461 COMPATNAME(route_intr)(void *cookie)
1462 {
1463 	struct sockproto proto = { .sp_family = PF_XROUTE, };
1464 	struct route_info * const ri = &COMPATNAME(route_info);
1465 	struct mbuf *m;
1466 	int s;
1467 
1468 	mutex_enter(softnet_lock);
1469 	KERNEL_LOCK(1, NULL);
1470 	while (!IF_IS_EMPTY(&ri->ri_intrq)) {
1471 		s = splnet();
1472 		IF_DEQUEUE(&ri->ri_intrq, m);
1473 		splx(s);
1474 		if (m == NULL)
1475 			break;
1476 		proto.sp_protocol = M_GETCTX(m, uintptr_t);
1477 		raw_input(m, &proto, &ri->ri_src, &ri->ri_dst);
1478 	}
1479 	KERNEL_UNLOCK_ONE(NULL);
1480 	mutex_exit(softnet_lock);
1481 }
1482 
1483 /*
1484  * Enqueue a message to the software interrupt routine.
1485  */
1486 void
1487 COMPATNAME(route_enqueue)(struct mbuf *m, int family)
1488 {
1489 	struct route_info * const ri = &COMPATNAME(route_info);
1490 	int s, wasempty;
1491 
1492 	s = splnet();
1493 	if (IF_QFULL(&ri->ri_intrq)) {
1494 		IF_DROP(&ri->ri_intrq);
1495 		m_freem(m);
1496 	} else {
1497 		wasempty = IF_IS_EMPTY(&ri->ri_intrq);
1498 		M_SETCTX(m, (uintptr_t)family);
1499 		IF_ENQUEUE(&ri->ri_intrq, m);
1500 		if (wasempty)
1501 			softint_schedule(ri->ri_sih);
1502 	}
1503 	splx(s);
1504 }
1505 
1506 static void
1507 COMPATNAME(route_init)(void)
1508 {
1509 	struct route_info * const ri = &COMPATNAME(route_info);
1510 
1511 #ifndef COMPAT_RTSOCK
1512 	rt_init();
1513 #endif
1514 
1515 	sysctl_net_route_setup(NULL);
1516 	ri->ri_intrq.ifq_maxlen = ri->ri_maxqlen;
1517 	ri->ri_sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
1518 	    COMPATNAME(route_intr), NULL);
1519 }
1520 
1521 /*
1522  * Definitions of protocols supported in the ROUTE domain.
1523  */
1524 #ifndef COMPAT_RTSOCK
1525 PR_WRAP_USRREQS(route);
1526 #else
1527 PR_WRAP_USRREQS(compat_50_route);
1528 #endif
1529 
1530 static const struct pr_usrreqs route_usrreqs = {
1531 	.pr_attach	= COMPATNAME(route_attach_wrapper),
1532 	.pr_detach	= COMPATNAME(route_detach_wrapper),
1533 	.pr_accept	= COMPATNAME(route_accept_wrapper),
1534 	.pr_bind	= COMPATNAME(route_bind_wrapper),
1535 	.pr_listen	= COMPATNAME(route_listen_wrapper),
1536 	.pr_connect	= COMPATNAME(route_connect_wrapper),
1537 	.pr_connect2	= COMPATNAME(route_connect2_wrapper),
1538 	.pr_disconnect	= COMPATNAME(route_disconnect_wrapper),
1539 	.pr_shutdown	= COMPATNAME(route_shutdown_wrapper),
1540 	.pr_abort	= COMPATNAME(route_abort_wrapper),
1541 	.pr_ioctl	= COMPATNAME(route_ioctl_wrapper),
1542 	.pr_stat	= COMPATNAME(route_stat_wrapper),
1543 	.pr_peeraddr	= COMPATNAME(route_peeraddr_wrapper),
1544 	.pr_sockaddr	= COMPATNAME(route_sockaddr_wrapper),
1545 	.pr_rcvd	= COMPATNAME(route_rcvd_wrapper),
1546 	.pr_recvoob	= COMPATNAME(route_recvoob_wrapper),
1547 	.pr_send	= COMPATNAME(route_send_wrapper),
1548 	.pr_sendoob	= COMPATNAME(route_sendoob_wrapper),
1549 	.pr_purgeif	= COMPATNAME(route_purgeif_wrapper),
1550 	.pr_generic	= COMPATNAME(route_usrreq_wrapper),
1551 };
1552 
1553 static const struct protosw COMPATNAME(route_protosw)[] = {
1554 	{
1555 		.pr_type = SOCK_RAW,
1556 		.pr_domain = &COMPATNAME(routedomain),
1557 		.pr_flags = PR_ATOMIC|PR_ADDR,
1558 		.pr_input = raw_input,
1559 		.pr_output = COMPATNAME(route_output),
1560 		.pr_ctlinput = raw_ctlinput,
1561 		.pr_usrreqs = &route_usrreqs,
1562 		.pr_init = raw_init,
1563 	},
1564 };
1565 
1566 struct domain COMPATNAME(routedomain) = {
1567 	.dom_family = PF_XROUTE,
1568 	.dom_name = DOMAINNAME,
1569 	.dom_init = COMPATNAME(route_init),
1570 	.dom_protosw = COMPATNAME(route_protosw),
1571 	.dom_protoswNPROTOSW =
1572 	    &COMPATNAME(route_protosw)[__arraycount(COMPATNAME(route_protosw))],
1573 };
1574 
1575 static void
1576 sysctl_net_route_setup(struct sysctllog **clog)
1577 {
1578 	const struct sysctlnode *rnode = NULL;
1579 
1580 	sysctl_createv(clog, 0, NULL, &rnode,
1581 		       CTLFLAG_PERMANENT,
1582 		       CTLTYPE_NODE, DOMAINNAME,
1583 		       SYSCTL_DESCR("PF_ROUTE information"),
1584 		       NULL, 0, NULL, 0,
1585 		       CTL_NET, PF_XROUTE, CTL_EOL);
1586 
1587 	sysctl_createv(clog, 0, NULL, NULL,
1588 		       CTLFLAG_PERMANENT,
1589 		       CTLTYPE_NODE, "rtable",
1590 		       SYSCTL_DESCR("Routing table information"),
1591 		       sysctl_rtable, 0, NULL, 0,
1592 		       CTL_NET, PF_XROUTE, 0 /* any protocol */, CTL_EOL);
1593 
1594 	sysctl_createv(clog, 0, &rnode, NULL,
1595 		       CTLFLAG_PERMANENT,
1596 		       CTLTYPE_STRUCT, "stats",
1597 		       SYSCTL_DESCR("Routing statistics"),
1598 		       NULL, 0, &rtstat, sizeof(rtstat),
1599 		       CTL_CREATE, CTL_EOL);
1600 }
1601