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