1 /* $NetBSD: rtsock.c,v 1.230 2017/11/17 07:37:12 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.230 2017/11/17 07:37:12 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 #include "opt_sctp.h" 71 #include "opt_net_mpsafe.h" 72 #endif 73 74 #include <sys/param.h> 75 #include <sys/systm.h> 76 #include <sys/proc.h> 77 #include <sys/socket.h> 78 #include <sys/socketvar.h> 79 #include <sys/domain.h> 80 #include <sys/protosw.h> 81 #include <sys/sysctl.h> 82 #include <sys/kauth.h> 83 #include <sys/kmem.h> 84 #include <sys/intr.h> 85 86 #include <net/if.h> 87 #include <net/if_llatbl.h> 88 #include <net/if_types.h> 89 #include <net/route.h> 90 #include <net/raw_cb.h> 91 92 #include <netinet/in_var.h> 93 #include <netinet/if_inarp.h> 94 95 #include <netmpls/mpls.h> 96 97 #ifdef SCTP 98 extern void sctp_add_ip_address(struct ifaddr *); 99 extern void sctp_delete_ip_address(struct ifaddr *); 100 #endif 101 102 #if defined(COMPAT_14) || defined(COMPAT_50) || defined(COMPAT_70) 103 #include <compat/net/if.h> 104 #include <compat/net/route.h> 105 #endif 106 #ifdef COMPAT_RTSOCK 107 #define RTM_XVERSION RTM_OVERSION 108 #define RTM_XNEWADDR RTM_ONEWADDR 109 #define RTM_XDELADDR RTM_ODELADDR 110 #define RTM_XCHGADDR RTM_OCHGADDR 111 #define RT_XADVANCE(a,b) RT_OADVANCE(a,b) 112 #define RT_XROUNDUP(n) RT_OROUNDUP(n) 113 #define PF_XROUTE PF_OROUTE 114 #define rt_xmsghdr rt_msghdr50 115 #define if_xmsghdr if_msghdr /* if_msghdr50 is for RTM_OIFINFO */ 116 #define ifa_xmsghdr ifa_msghdr50 117 #define if_xannouncemsghdr if_announcemsghdr50 118 #define COMPATNAME(x) compat_50_ ## x 119 #define DOMAINNAME "oroute" 120 CTASSERT(sizeof(struct ifa_xmsghdr) == 20); 121 DOMAIN_DEFINE(compat_50_routedomain); /* forward declare and add to link set */ 122 #undef COMPAT_70 123 #else /* COMPAT_RTSOCK */ 124 #define RTM_XVERSION RTM_VERSION 125 #define RTM_XNEWADDR RTM_NEWADDR 126 #define RTM_XDELADDR RTM_DELADDR 127 #define RTM_XCHGADDR RTM_CHGADDR 128 #define RT_XADVANCE(a,b) RT_ADVANCE(a,b) 129 #define RT_XROUNDUP(n) RT_ROUNDUP(n) 130 #define PF_XROUTE PF_ROUTE 131 #define rt_xmsghdr rt_msghdr 132 #define if_xmsghdr if_msghdr 133 #define ifa_xmsghdr ifa_msghdr 134 #define if_xannouncemsghdr if_announcemsghdr 135 #define COMPATNAME(x) x 136 #define DOMAINNAME "route" 137 CTASSERT(sizeof(struct ifa_xmsghdr) == 32); 138 #ifdef COMPAT_50 139 #define COMPATCALL(name, args) compat_50_ ## name args 140 #endif 141 DOMAIN_DEFINE(routedomain); /* forward declare and add to link set */ 142 #undef COMPAT_50 143 #undef COMPAT_14 144 #endif /* COMPAT_RTSOCK */ 145 146 #ifndef COMPATCALL 147 #define COMPATCALL(name, args) do { } while (/*CONSTCOND*/ 0) 148 #endif 149 150 #ifdef RTSOCK_DEBUG 151 #define RT_IN_PRINT(info, b, a) (in_print((b), sizeof(b), \ 152 &((const struct sockaddr_in *)(info)->rti_info[(a)])->sin_addr), (b)) 153 #endif /* RTSOCK_DEBUG */ 154 155 struct route_info COMPATNAME(route_info) = { 156 .ri_dst = { .sa_len = 2, .sa_family = PF_XROUTE, }, 157 .ri_src = { .sa_len = 2, .sa_family = PF_XROUTE, }, 158 .ri_maxqlen = IFQ_MAXLEN, 159 }; 160 161 #define PRESERVED_RTF (RTF_UP | RTF_GATEWAY | RTF_HOST | RTF_DONE | RTF_MASK) 162 163 static void COMPATNAME(route_init)(void); 164 static int COMPATNAME(route_output)(struct mbuf *, struct socket *); 165 166 static int rt_xaddrs(u_char, const char *, const char *, struct rt_addrinfo *); 167 static struct mbuf *rt_makeifannouncemsg(struct ifnet *, int, int, 168 struct rt_addrinfo *); 169 static int rt_msg2(int, struct rt_addrinfo *, void *, struct rt_walkarg *, int *); 170 static void rt_setmetrics(int, const struct rt_xmsghdr *, struct rtentry *); 171 static void rtm_setmetrics(const struct rtentry *, struct rt_xmsghdr *); 172 static void sysctl_net_route_setup(struct sysctllog **); 173 static int sysctl_dumpentry(struct rtentry *, void *); 174 static int sysctl_iflist(int, struct rt_walkarg *, int); 175 static int sysctl_rtable(SYSCTLFN_PROTO); 176 static void rt_adjustcount(int, int); 177 178 static const struct protosw COMPATNAME(route_protosw)[]; 179 180 struct routecb { 181 struct rawcb rocb_rcb; 182 unsigned int rocb_msgfilter; 183 #define RTMSGFILTER(m) (1U << (m)) 184 }; 185 #define sotoroutecb(so) ((struct routecb *)(so)->so_pcb) 186 187 static struct rawcbhead rt_rawcb; 188 #ifdef NET_MPSAFE 189 static kmutex_t *rt_so_mtx; 190 #endif 191 192 static void 193 rt_adjustcount(int af, int cnt) 194 { 195 struct route_cb * const cb = &COMPATNAME(route_info).ri_cb; 196 197 cb->any_count += cnt; 198 199 switch (af) { 200 case AF_INET: 201 cb->ip_count += cnt; 202 return; 203 #ifdef INET6 204 case AF_INET6: 205 cb->ip6_count += cnt; 206 return; 207 #endif 208 case AF_MPLS: 209 cb->mpls_count += cnt; 210 return; 211 } 212 } 213 214 static int 215 COMPATNAME(route_filter)(struct mbuf *m, struct sockproto *proto, 216 struct rawcb *rp) 217 { 218 struct routecb *rop = (struct routecb *)rp; 219 struct rt_xmsghdr *rtm; 220 221 KASSERT(m != NULL); 222 KASSERT(proto != NULL); 223 KASSERT(rp != NULL); 224 225 /* Wrong family for this socket. */ 226 if (proto->sp_family != PF_ROUTE) 227 return ENOPROTOOPT; 228 229 /* If no filter set, just return. */ 230 if (rop->rocb_msgfilter == 0) 231 return 0; 232 233 /* Ensure we can access rtm_type */ 234 if (m->m_len < 235 offsetof(struct rt_xmsghdr, rtm_type) + sizeof(rtm->rtm_type)) 236 return EINVAL; 237 238 rtm = mtod(m, struct rt_xmsghdr *); 239 /* If the rtm type is filtered out, return a positive. */ 240 if (!(rop->rocb_msgfilter & RTMSGFILTER(rtm->rtm_type))) 241 return EEXIST; 242 243 /* Passed the filter. */ 244 return 0; 245 } 246 247 static void 248 rt_pr_init(void) 249 { 250 251 LIST_INIT(&rt_rawcb); 252 } 253 254 static int 255 COMPATNAME(route_attach)(struct socket *so, int proto) 256 { 257 struct rawcb *rp; 258 struct routecb *rop; 259 int s, error; 260 261 KASSERT(sotorawcb(so) == NULL); 262 rop = kmem_zalloc(sizeof(*rop), KM_SLEEP); 263 rp = &rop->rocb_rcb; 264 rp->rcb_len = sizeof(*rop); 265 so->so_pcb = rp; 266 267 s = splsoftnet(); 268 269 #ifdef NET_MPSAFE 270 KASSERT(so->so_lock == NULL); 271 mutex_obj_hold(rt_so_mtx); 272 so->so_lock = rt_so_mtx; 273 solock(so); 274 #endif 275 276 if ((error = raw_attach(so, proto, &rt_rawcb)) == 0) { 277 rt_adjustcount(rp->rcb_proto.sp_protocol, 1); 278 rp->rcb_laddr = &COMPATNAME(route_info).ri_src; 279 rp->rcb_faddr = &COMPATNAME(route_info).ri_dst; 280 rp->rcb_filter = COMPATNAME(route_filter); 281 } 282 splx(s); 283 284 if (error) { 285 kmem_free(rop, sizeof(*rop)); 286 so->so_pcb = NULL; 287 return error; 288 } 289 290 soisconnected(so); 291 so->so_options |= SO_USELOOPBACK; 292 KASSERT(solocked(so)); 293 294 return error; 295 } 296 297 static void 298 COMPATNAME(route_detach)(struct socket *so) 299 { 300 struct rawcb *rp = sotorawcb(so); 301 int s; 302 303 KASSERT(rp != NULL); 304 KASSERT(solocked(so)); 305 306 s = splsoftnet(); 307 rt_adjustcount(rp->rcb_proto.sp_protocol, -1); 308 raw_detach(so); 309 splx(s); 310 } 311 312 static int 313 COMPATNAME(route_accept)(struct socket *so, struct sockaddr *nam) 314 { 315 KASSERT(solocked(so)); 316 317 panic("route_accept"); 318 319 return EOPNOTSUPP; 320 } 321 322 static int 323 COMPATNAME(route_bind)(struct socket *so, struct sockaddr *nam, struct lwp *l) 324 { 325 KASSERT(solocked(so)); 326 327 return EOPNOTSUPP; 328 } 329 330 static int 331 COMPATNAME(route_listen)(struct socket *so, struct lwp *l) 332 { 333 KASSERT(solocked(so)); 334 335 return EOPNOTSUPP; 336 } 337 338 static int 339 COMPATNAME(route_connect)(struct socket *so, struct sockaddr *nam, struct lwp *l) 340 { 341 KASSERT(solocked(so)); 342 343 return EOPNOTSUPP; 344 } 345 346 static int 347 COMPATNAME(route_connect2)(struct socket *so, struct socket *so2) 348 { 349 KASSERT(solocked(so)); 350 351 return EOPNOTSUPP; 352 } 353 354 static int 355 COMPATNAME(route_disconnect)(struct socket *so) 356 { 357 struct rawcb *rp = sotorawcb(so); 358 int s; 359 360 KASSERT(solocked(so)); 361 KASSERT(rp != NULL); 362 363 s = splsoftnet(); 364 soisdisconnected(so); 365 raw_disconnect(rp); 366 splx(s); 367 368 return 0; 369 } 370 371 static int 372 COMPATNAME(route_shutdown)(struct socket *so) 373 { 374 int s; 375 376 KASSERT(solocked(so)); 377 378 /* 379 * Mark the connection as being incapable of further input. 380 */ 381 s = splsoftnet(); 382 socantsendmore(so); 383 splx(s); 384 return 0; 385 } 386 387 static int 388 COMPATNAME(route_abort)(struct socket *so) 389 { 390 KASSERT(solocked(so)); 391 392 panic("route_abort"); 393 394 return EOPNOTSUPP; 395 } 396 397 static int 398 COMPATNAME(route_ioctl)(struct socket *so, u_long cmd, void *nam, 399 struct ifnet * ifp) 400 { 401 return EOPNOTSUPP; 402 } 403 404 static int 405 COMPATNAME(route_stat)(struct socket *so, struct stat *ub) 406 { 407 KASSERT(solocked(so)); 408 409 return 0; 410 } 411 412 static int 413 COMPATNAME(route_peeraddr)(struct socket *so, struct sockaddr *nam) 414 { 415 struct rawcb *rp = sotorawcb(so); 416 417 KASSERT(solocked(so)); 418 KASSERT(rp != NULL); 419 KASSERT(nam != NULL); 420 421 if (rp->rcb_faddr == NULL) 422 return ENOTCONN; 423 424 raw_setpeeraddr(rp, nam); 425 return 0; 426 } 427 428 static int 429 COMPATNAME(route_sockaddr)(struct socket *so, struct sockaddr *nam) 430 { 431 struct rawcb *rp = sotorawcb(so); 432 433 KASSERT(solocked(so)); 434 KASSERT(rp != NULL); 435 KASSERT(nam != NULL); 436 437 if (rp->rcb_faddr == NULL) 438 return ENOTCONN; 439 440 raw_setsockaddr(rp, nam); 441 return 0; 442 } 443 444 static int 445 COMPATNAME(route_rcvd)(struct socket *so, int flags, struct lwp *l) 446 { 447 KASSERT(solocked(so)); 448 449 return EOPNOTSUPP; 450 } 451 452 static int 453 COMPATNAME(route_recvoob)(struct socket *so, struct mbuf *m, int flags) 454 { 455 KASSERT(solocked(so)); 456 457 return EOPNOTSUPP; 458 } 459 460 static int 461 COMPATNAME(route_send)(struct socket *so, struct mbuf *m, 462 struct sockaddr *nam, struct mbuf *control, struct lwp *l) 463 { 464 int error = 0; 465 int s; 466 467 KASSERT(solocked(so)); 468 KASSERT(so->so_proto == &COMPATNAME(route_protosw)[0]); 469 470 s = splsoftnet(); 471 error = raw_send(so, m, nam, control, l, &COMPATNAME(route_output)); 472 splx(s); 473 474 return error; 475 } 476 477 static int 478 COMPATNAME(route_sendoob)(struct socket *so, struct mbuf *m, 479 struct mbuf *control) 480 { 481 KASSERT(solocked(so)); 482 483 m_freem(m); 484 m_freem(control); 485 486 return EOPNOTSUPP; 487 } 488 static int 489 COMPATNAME(route_purgeif)(struct socket *so, struct ifnet *ifp) 490 { 491 492 panic("route_purgeif"); 493 494 return EOPNOTSUPP; 495 } 496 497 #if defined(INET) || defined(INET6) 498 static int 499 route_get_sdl_index(struct rt_addrinfo *info, int *sdl_index) 500 { 501 struct rtentry *nrt; 502 int error; 503 504 error = rtrequest1(RTM_GET, info, &nrt); 505 if (error != 0) 506 return error; 507 /* 508 * nrt->rt_ifp->if_index may not be correct 509 * due to changing to ifplo0. 510 */ 511 *sdl_index = satosdl(nrt->rt_gateway)->sdl_index; 512 rt_unref(nrt); 513 514 return 0; 515 } 516 #endif 517 518 static void 519 route_get_sdl(const struct ifnet *ifp, const struct sockaddr *dst, 520 struct sockaddr_dl *sdl, int *flags) 521 { 522 struct llentry *la; 523 524 KASSERT(ifp != NULL); 525 526 IF_AFDATA_RLOCK(ifp); 527 switch (dst->sa_family) { 528 case AF_INET: 529 la = lla_lookup(LLTABLE(ifp), 0, dst); 530 break; 531 case AF_INET6: 532 la = lla_lookup(LLTABLE6(ifp), 0, dst); 533 break; 534 default: 535 la = NULL; 536 KASSERTMSG(0, "Invalid AF=%d\n", dst->sa_family); 537 break; 538 } 539 IF_AFDATA_RUNLOCK(ifp); 540 541 void *a = (LLE_IS_VALID(la) && (la->la_flags & LLE_VALID) == LLE_VALID) 542 ? &la->ll_addr : NULL; 543 544 a = sockaddr_dl_init(sdl, sizeof(*sdl), ifp->if_index, ifp->if_type, 545 NULL, 0, a, ifp->if_addrlen); 546 KASSERT(a != NULL); 547 548 if (la != NULL) { 549 *flags = la->la_flags; 550 LLE_RUNLOCK(la); 551 } 552 } 553 554 static int 555 route_output_report(struct rtentry *rt, struct rt_addrinfo *info, 556 struct rt_xmsghdr *rtm, struct rt_xmsghdr **new_rtm) 557 { 558 int len; 559 560 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 561 const struct ifaddr *rtifa; 562 const struct ifnet *ifp = rt->rt_ifp; 563 564 info->rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; 565 /* rtifa used to be simply rt->rt_ifa. 566 * If rt->rt_ifa != NULL, then 567 * rt_get_ifa() != NULL. So this 568 * ought to still be safe. --dyoung 569 */ 570 rtifa = rt_get_ifa(rt); 571 info->rti_info[RTAX_IFA] = rtifa->ifa_addr; 572 #ifdef RTSOCK_DEBUG 573 if (info->rti_info[RTAX_IFA]->sa_family == AF_INET) { 574 char ibuf[INET_ADDRSTRLEN]; 575 char abuf[INET_ADDRSTRLEN]; 576 printf("%s: copying out RTAX_IFA %s " 577 "for info->rti_info[RTAX_DST] %s " 578 "ifa_getifa %p ifa_seqno %p\n", 579 __func__, 580 RT_IN_PRINT(info, ibuf, RTAX_IFA), 581 RT_IN_PRINT(info, abuf, RTAX_DST), 582 (void *)rtifa->ifa_getifa, 583 rtifa->ifa_seqno); 584 } 585 #endif /* RTSOCK_DEBUG */ 586 if (ifp->if_flags & IFF_POINTOPOINT) 587 info->rti_info[RTAX_BRD] = rtifa->ifa_dstaddr; 588 else 589 info->rti_info[RTAX_BRD] = NULL; 590 rtm->rtm_index = ifp->if_index; 591 } 592 (void)rt_msg2(rtm->rtm_type, info, NULL, NULL, &len); 593 if (len > rtm->rtm_msglen) { 594 struct rt_xmsghdr *old_rtm = rtm; 595 R_Malloc(*new_rtm, struct rt_xmsghdr *, len); 596 if (*new_rtm == NULL) 597 return ENOBUFS; 598 (void)memcpy(*new_rtm, old_rtm, old_rtm->rtm_msglen); 599 rtm = *new_rtm; 600 } 601 (void)rt_msg2(rtm->rtm_type, info, rtm, NULL, 0); 602 rtm->rtm_flags = rt->rt_flags; 603 rtm_setmetrics(rt, rtm); 604 rtm->rtm_addrs = info->rti_addrs; 605 606 return 0; 607 } 608 609 static struct ifaddr * 610 route_output_get_ifa(const struct rt_addrinfo info, const struct rtentry *rt, 611 struct ifnet **ifp, struct psref *psref) 612 { 613 struct ifaddr *ifa = NULL; 614 615 *ifp = NULL; 616 if (info.rti_info[RTAX_IFP] != NULL) { 617 ifa = ifa_ifwithnet_psref(info.rti_info[RTAX_IFP], psref); 618 if (ifa == NULL) 619 goto next; 620 *ifp = ifa->ifa_ifp; 621 if (info.rti_info[RTAX_IFA] == NULL && 622 info.rti_info[RTAX_GATEWAY] == NULL) 623 goto next; 624 if (info.rti_info[RTAX_IFA] == NULL) { 625 /* route change <dst> <gw> -ifp <if> */ 626 ifa = ifaof_ifpforaddr_psref(info.rti_info[RTAX_GATEWAY], 627 *ifp, psref); 628 } else { 629 /* route change <dst> -ifp <if> -ifa <addr> */ 630 ifa = ifa_ifwithaddr_psref(info.rti_info[RTAX_IFA], psref); 631 if (ifa != NULL) 632 goto out; 633 ifa = ifaof_ifpforaddr_psref(info.rti_info[RTAX_IFA], 634 *ifp, psref); 635 } 636 goto out; 637 } 638 next: 639 if (info.rti_info[RTAX_IFA] != NULL) { 640 /* route change <dst> <gw> -ifa <addr> */ 641 ifa = ifa_ifwithaddr_psref(info.rti_info[RTAX_IFA], psref); 642 if (ifa != NULL) 643 goto out; 644 } 645 if (info.rti_info[RTAX_GATEWAY] != NULL) { 646 /* route change <dst> <gw> */ 647 ifa = ifa_ifwithroute_psref(rt->rt_flags, rt_getkey(rt), 648 info.rti_info[RTAX_GATEWAY], psref); 649 } 650 out: 651 if (ifa != NULL && *ifp == NULL) 652 *ifp = ifa->ifa_ifp; 653 return ifa; 654 } 655 656 static int 657 route_output_change(struct rtentry *rt, struct rt_addrinfo *info, 658 struct rt_xmsghdr *rtm) 659 { 660 int error = 0; 661 struct ifnet *ifp = NULL, *new_ifp; 662 struct ifaddr *ifa = NULL, *new_ifa; 663 struct psref psref_ifa, psref_new_ifa, psref_ifp; 664 bool newgw, ifp_changed = false; 665 666 /* 667 * New gateway could require new ifaddr, ifp; 668 * flags may also be different; ifp may be specified 669 * by ll sockaddr when protocol address is ambiguous 670 */ 671 newgw = info->rti_info[RTAX_GATEWAY] != NULL && 672 sockaddr_cmp(info->rti_info[RTAX_GATEWAY], rt->rt_gateway) != 0; 673 674 if (newgw || info->rti_info[RTAX_IFP] != NULL || 675 info->rti_info[RTAX_IFA] != NULL) { 676 ifp = rt_getifp(info, &psref_ifp); 677 ifa = rt_getifa(info, &psref_ifa); 678 if (ifa == NULL) { 679 error = ENETUNREACH; 680 goto out; 681 } 682 } 683 if (newgw) { 684 error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]); 685 if (error != 0) 686 goto out; 687 } 688 if (info->rti_info[RTAX_TAG]) { 689 const struct sockaddr *tag; 690 tag = rt_settag(rt, info->rti_info[RTAX_TAG]); 691 if (tag == NULL) { 692 error = ENOBUFS; 693 goto out; 694 } 695 } 696 /* 697 * New gateway could require new ifaddr, ifp; 698 * flags may also be different; ifp may be specified 699 * by ll sockaddr when protocol address is ambiguous 700 */ 701 new_ifa = route_output_get_ifa(*info, rt, &new_ifp, &psref_new_ifa); 702 if (new_ifa != NULL) { 703 ifa_release(ifa, &psref_ifa); 704 ifa = new_ifa; 705 } 706 if (ifa) { 707 struct ifaddr *oifa = rt->rt_ifa; 708 if (oifa != ifa && !ifa_is_destroying(ifa) && 709 new_ifp != NULL && !if_is_deactivated(new_ifp)) { 710 if (oifa && oifa->ifa_rtrequest) 711 oifa->ifa_rtrequest(RTM_DELETE, rt, info); 712 rt_replace_ifa(rt, ifa); 713 rt->rt_ifp = new_ifp; 714 ifp_changed = true; 715 } 716 if (new_ifa == NULL) 717 ifa_release(ifa, &psref_ifa); 718 } 719 ifa_release(new_ifa, &psref_new_ifa); 720 if (new_ifp && rt->rt_ifp != new_ifp && !if_is_deactivated(new_ifp)) { 721 rt->rt_ifp = new_ifp; 722 ifp_changed = true; 723 } 724 rt_setmetrics(rtm->rtm_inits, rtm, rt); 725 if (rt->rt_flags != info->rti_flags) { 726 rt->rt_flags = (info->rti_flags & ~PRESERVED_RTF) | 727 (rt->rt_flags & PRESERVED_RTF); 728 } 729 if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) 730 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info); 731 #if defined(INET) || defined(INET6) 732 if (ifp_changed && rt_mask(rt) != NULL) 733 lltable_prefix_free(rt_getkey(rt)->sa_family, rt_getkey(rt), 734 rt_mask(rt), 0); 735 #else 736 (void)ifp_changed; /* XXX gcc */ 737 #endif 738 out: 739 if_put(ifp, &psref_ifp); 740 741 return error; 742 } 743 744 /*ARGSUSED*/ 745 int 746 COMPATNAME(route_output)(struct mbuf *m, struct socket *so) 747 { 748 struct sockproto proto = { .sp_family = PF_XROUTE, }; 749 struct rt_xmsghdr *rtm = NULL; 750 struct rt_xmsghdr *old_rtm = NULL, *new_rtm = NULL; 751 struct rtentry *rt = NULL; 752 struct rtentry *saved_nrt = NULL; 753 struct rt_addrinfo info; 754 int len, error = 0; 755 sa_family_t family; 756 struct sockaddr_dl sdl; 757 int bound = curlwp_bind(); 758 bool do_rt_free = false; 759 struct sockaddr_storage netmask; 760 761 #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0) 762 if (m == NULL || ((m->m_len < sizeof(int32_t)) && 763 (m = m_pullup(m, sizeof(int32_t))) == NULL)) { 764 error = ENOBUFS; 765 goto out; 766 } 767 if ((m->m_flags & M_PKTHDR) == 0) 768 panic("%s", __func__); 769 len = m->m_pkthdr.len; 770 if (len < sizeof(*rtm) || 771 len != mtod(m, struct rt_xmsghdr *)->rtm_msglen) { 772 info.rti_info[RTAX_DST] = NULL; 773 senderr(EINVAL); 774 } 775 R_Malloc(rtm, struct rt_xmsghdr *, len); 776 if (rtm == NULL) { 777 info.rti_info[RTAX_DST] = NULL; 778 senderr(ENOBUFS); 779 } 780 m_copydata(m, 0, len, rtm); 781 if (rtm->rtm_version != RTM_XVERSION) { 782 info.rti_info[RTAX_DST] = NULL; 783 senderr(EPROTONOSUPPORT); 784 } 785 rtm->rtm_pid = curproc->p_pid; 786 memset(&info, 0, sizeof(info)); 787 info.rti_addrs = rtm->rtm_addrs; 788 if (rt_xaddrs(rtm->rtm_type, (const char *)(rtm + 1), len + (char *)rtm, 789 &info)) { 790 senderr(EINVAL); 791 } 792 info.rti_flags = rtm->rtm_flags; 793 #ifdef RTSOCK_DEBUG 794 if (info.rti_info[RTAX_DST]->sa_family == AF_INET) { 795 char abuf[INET_ADDRSTRLEN]; 796 printf("%s: extracted info.rti_info[RTAX_DST] %s\n", __func__, 797 RT_IN_PRINT(&info, abuf, RTAX_DST)); 798 } 799 #endif /* RTSOCK_DEBUG */ 800 if (info.rti_info[RTAX_DST] == NULL || 801 (info.rti_info[RTAX_DST]->sa_family >= AF_MAX)) { 802 senderr(EINVAL); 803 } 804 if (info.rti_info[RTAX_GATEWAY] != NULL && 805 (info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) { 806 senderr(EINVAL); 807 } 808 809 /* 810 * Verify that the caller has the appropriate privilege; RTM_GET 811 * is the only operation the non-superuser is allowed. 812 */ 813 if (kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_ROUTE, 814 0, rtm, NULL, NULL) != 0) 815 senderr(EACCES); 816 817 /* 818 * route(8) passes a sockaddr truncated with prefixlen. 819 * The kernel doesn't expect such sockaddr and need to 820 * use a buffer that is big enough for the sockaddr expected 821 * (padded with 0's). We keep the original length of the sockaddr. 822 */ 823 if (info.rti_info[RTAX_NETMASK]) { 824 socklen_t sa_len = sockaddr_getsize_by_family( 825 info.rti_info[RTAX_NETMASK]->sa_family); 826 socklen_t masklen = sockaddr_getlen( 827 info.rti_info[RTAX_NETMASK]); 828 if (sa_len != 0 && sa_len > masklen) { 829 KASSERT(sa_len <= sizeof(netmask)); 830 memcpy(&netmask, info.rti_info[RTAX_NETMASK], masklen); 831 memset((char *)&netmask + masklen, 0, sa_len - masklen); 832 info.rti_info[RTAX_NETMASK] = sstocsa(&netmask); 833 } 834 } 835 836 switch (rtm->rtm_type) { 837 838 case RTM_ADD: 839 if (info.rti_info[RTAX_GATEWAY] == NULL) { 840 senderr(EINVAL); 841 } 842 #if defined(INET) || defined(INET6) 843 /* support for new ARP/NDP code with keeping backcompat */ 844 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { 845 const struct sockaddr_dl *sdlp = 846 satocsdl(info.rti_info[RTAX_GATEWAY]); 847 848 /* Allow routing requests by interface index */ 849 if (sdlp->sdl_nlen == 0 && sdlp->sdl_alen == 0 850 && sdlp->sdl_slen == 0) 851 goto fallback; 852 /* 853 * Old arp binaries don't set the sdl_index 854 * so we have to complement it. 855 */ 856 int sdl_index = sdlp->sdl_index; 857 if (sdl_index == 0) { 858 error = route_get_sdl_index(&info, &sdl_index); 859 if (error != 0) 860 goto fallback; 861 } else if ( 862 info.rti_info[RTAX_DST]->sa_family == AF_INET) { 863 /* 864 * XXX workaround for SIN_PROXY case; proxy arp 865 * entry should be in an interface that has 866 * a network route including the destination, 867 * not a local (link) route that may not be a 868 * desired place, for example a tap. 869 */ 870 const struct sockaddr_inarp *sina = 871 (const struct sockaddr_inarp *) 872 info.rti_info[RTAX_DST]; 873 if (sina->sin_other & SIN_PROXY) { 874 error = route_get_sdl_index(&info, 875 &sdl_index); 876 if (error != 0) 877 goto fallback; 878 } 879 } 880 error = lla_rt_output(rtm->rtm_type, rtm->rtm_flags, 881 rtm->rtm_rmx.rmx_expire, &info, sdl_index); 882 break; 883 } 884 fallback: 885 #endif /* defined(INET) || defined(INET6) */ 886 error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); 887 if (error == 0) { 888 rt_setmetrics(rtm->rtm_inits, rtm, saved_nrt); 889 rt_unref(saved_nrt); 890 } 891 break; 892 893 case RTM_DELETE: 894 #if defined(INET) || defined(INET6) 895 /* support for new ARP/NDP code */ 896 if (info.rti_info[RTAX_GATEWAY] && 897 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 898 (rtm->rtm_flags & RTF_LLDATA) != 0) { 899 const struct sockaddr_dl *sdlp = 900 satocsdl(info.rti_info[RTAX_GATEWAY]); 901 error = lla_rt_output(rtm->rtm_type, rtm->rtm_flags, 902 rtm->rtm_rmx.rmx_expire, &info, sdlp->sdl_index); 903 rtm->rtm_flags &= ~RTF_UP; 904 break; 905 } 906 #endif 907 error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); 908 if (error != 0) 909 break; 910 911 rt = saved_nrt; 912 do_rt_free = true; 913 info.rti_info[RTAX_DST] = rt_getkey(rt); 914 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 915 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 916 info.rti_info[RTAX_TAG] = rt_gettag(rt); 917 error = route_output_report(rt, &info, rtm, &new_rtm); 918 if (error) 919 senderr(error); 920 if (new_rtm != NULL) { 921 old_rtm = rtm; 922 rtm = new_rtm; 923 } 924 break; 925 926 case RTM_GET: 927 case RTM_CHANGE: 928 case RTM_LOCK: 929 /* XXX This will mask info.rti_info[RTAX_DST] with 930 * info.rti_info[RTAX_NETMASK] before 931 * searching. It did not used to do that. --dyoung 932 */ 933 rt = NULL; 934 error = rtrequest1(RTM_GET, &info, &rt); 935 if (error != 0) 936 senderr(error); 937 if (rtm->rtm_type != RTM_GET) {/* XXX: too grotty */ 938 if (memcmp(info.rti_info[RTAX_DST], rt_getkey(rt), 939 info.rti_info[RTAX_DST]->sa_len) != 0) 940 senderr(ESRCH); 941 if (info.rti_info[RTAX_NETMASK] == NULL && 942 rt_mask(rt) != NULL) 943 senderr(ETOOMANYREFS); 944 } 945 946 /* 947 * XXX if arp/ndp requests an L2 entry, we have to obtain 948 * it from lltable while for the route command we have to 949 * return a route as it is. How to distinguish them? 950 * For newer arp/ndp, RTF_LLDATA flag set by arp/ndp 951 * indicates an L2 entry is requested. For old arp/ndp 952 * binaries, we check RTF_UP flag is NOT set; it works 953 * by the fact that arp/ndp don't set it while the route 954 * command sets it. 955 */ 956 if (((rtm->rtm_flags & RTF_LLDATA) != 0 || 957 (rtm->rtm_flags & RTF_UP) == 0) && 958 rtm->rtm_type == RTM_GET && 959 sockaddr_cmp(rt_getkey(rt), info.rti_info[RTAX_DST]) != 0) { 960 int ll_flags = 0; 961 route_get_sdl(rt->rt_ifp, info.rti_info[RTAX_DST], &sdl, 962 &ll_flags); 963 info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl); 964 error = route_output_report(rt, &info, rtm, &new_rtm); 965 if (error) 966 senderr(error); 967 if (new_rtm != NULL) { 968 old_rtm = rtm; 969 rtm = new_rtm; 970 } 971 rtm->rtm_flags |= RTF_LLDATA; 972 rtm->rtm_flags &= ~RTF_CONNECTED; 973 rtm->rtm_flags |= (ll_flags & LLE_STATIC) ? RTF_STATIC : 0; 974 break; 975 } 976 977 switch (rtm->rtm_type) { 978 case RTM_GET: 979 info.rti_info[RTAX_DST] = rt_getkey(rt); 980 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 981 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 982 info.rti_info[RTAX_TAG] = rt_gettag(rt); 983 error = route_output_report(rt, &info, rtm, &new_rtm); 984 if (error) 985 senderr(error); 986 if (new_rtm != NULL) { 987 old_rtm = rtm; 988 rtm = new_rtm; 989 } 990 break; 991 992 case RTM_CHANGE: 993 #ifdef NET_MPSAFE 994 error = rt_update_prepare(rt); 995 if (error == 0) { 996 error = route_output_change(rt, &info, rtm); 997 rt_update_finish(rt); 998 } 999 #else 1000 error = route_output_change(rt, &info, rtm); 1001 #endif 1002 if (error != 0) 1003 goto flush; 1004 /*FALLTHROUGH*/ 1005 case RTM_LOCK: 1006 rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); 1007 rt->rt_rmx.rmx_locks |= 1008 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); 1009 break; 1010 } 1011 break; 1012 1013 default: 1014 senderr(EOPNOTSUPP); 1015 } 1016 1017 flush: 1018 if (rtm) { 1019 if (error) 1020 rtm->rtm_errno = error; 1021 else 1022 rtm->rtm_flags |= RTF_DONE; 1023 } 1024 family = info.rti_info[RTAX_DST] ? info.rti_info[RTAX_DST]->sa_family : 1025 0; 1026 /* We cannot free old_rtm until we have stopped using the 1027 * pointers in info, some of which may point to sockaddrs 1028 * in old_rtm. 1029 */ 1030 if (old_rtm != NULL) 1031 Free(old_rtm); 1032 if (rt) { 1033 if (do_rt_free) 1034 rt_free(rt); 1035 else 1036 rt_unref(rt); 1037 } 1038 { 1039 struct rawcb *rp = NULL; 1040 /* 1041 * Check to see if we don't want our own messages. 1042 */ 1043 if ((so->so_options & SO_USELOOPBACK) == 0) { 1044 if (COMPATNAME(route_info).ri_cb.any_count <= 1) { 1045 if (rtm) 1046 Free(rtm); 1047 m_freem(m); 1048 goto out; 1049 } 1050 /* There is another listener, so construct message */ 1051 rp = sotorawcb(so); 1052 } 1053 if (rtm) { 1054 m_copyback(m, 0, rtm->rtm_msglen, rtm); 1055 if (m->m_pkthdr.len < rtm->rtm_msglen) { 1056 m_freem(m); 1057 m = NULL; 1058 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 1059 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 1060 Free(rtm); 1061 } 1062 if (rp) 1063 rp->rcb_proto.sp_family = 0; /* Avoid us */ 1064 if (family) 1065 proto.sp_protocol = family; 1066 if (m) 1067 raw_input(m, &proto, &COMPATNAME(route_info).ri_src, 1068 &COMPATNAME(route_info).ri_dst, &rt_rawcb); 1069 if (rp) 1070 rp->rcb_proto.sp_family = PF_XROUTE; 1071 } 1072 out: 1073 curlwp_bindx(bound); 1074 return error; 1075 } 1076 1077 static int 1078 route_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1079 { 1080 struct routecb *rop = sotoroutecb(so); 1081 int error = 0; 1082 unsigned char *rtm_type; 1083 size_t len; 1084 unsigned int msgfilter; 1085 1086 KASSERT(solocked(so)); 1087 1088 if (sopt->sopt_level != AF_ROUTE) { 1089 error = ENOPROTOOPT; 1090 } else switch (op) { 1091 case PRCO_SETOPT: 1092 switch (sopt->sopt_name) { 1093 case RO_MSGFILTER: 1094 msgfilter = 0; 1095 for (rtm_type = sopt->sopt_data, len = sopt->sopt_size; 1096 len != 0; 1097 rtm_type++, len -= sizeof(*rtm_type)) 1098 { 1099 /* Guard against overflowing our storage. */ 1100 if (*rtm_type >= sizeof(msgfilter) * CHAR_BIT) { 1101 error = EOVERFLOW; 1102 break; 1103 } 1104 msgfilter |= RTMSGFILTER(*rtm_type); 1105 } 1106 if (error == 0) 1107 rop->rocb_msgfilter = msgfilter; 1108 break; 1109 default: 1110 error = ENOPROTOOPT; 1111 break; 1112 } 1113 break; 1114 case PRCO_GETOPT: 1115 switch (sopt->sopt_name) { 1116 case RO_MSGFILTER: 1117 error = ENOTSUP; 1118 break; 1119 default: 1120 error = ENOPROTOOPT; 1121 break; 1122 } 1123 } 1124 return error; 1125 } 1126 1127 static void 1128 rt_setmetrics(int which, const struct rt_xmsghdr *in, struct rtentry *out) 1129 { 1130 #define metric(f, e) if (which & (f)) out->rt_rmx.e = in->rtm_rmx.e; 1131 metric(RTV_RPIPE, rmx_recvpipe); 1132 metric(RTV_SPIPE, rmx_sendpipe); 1133 metric(RTV_SSTHRESH, rmx_ssthresh); 1134 metric(RTV_RTT, rmx_rtt); 1135 metric(RTV_RTTVAR, rmx_rttvar); 1136 metric(RTV_HOPCOUNT, rmx_hopcount); 1137 metric(RTV_MTU, rmx_mtu); 1138 #undef metric 1139 if (which & RTV_EXPIRE) { 1140 out->rt_rmx.rmx_expire = in->rtm_rmx.rmx_expire ? 1141 time_wall_to_mono(in->rtm_rmx.rmx_expire) : 0; 1142 } 1143 } 1144 1145 static void 1146 rtm_setmetrics(const struct rtentry *in, struct rt_xmsghdr *out) 1147 { 1148 #define metric(e) out->rtm_rmx.e = in->rt_rmx.e; 1149 metric(rmx_recvpipe); 1150 metric(rmx_sendpipe); 1151 metric(rmx_ssthresh); 1152 metric(rmx_rtt); 1153 metric(rmx_rttvar); 1154 metric(rmx_hopcount); 1155 metric(rmx_mtu); 1156 metric(rmx_locks); 1157 #undef metric 1158 out->rtm_rmx.rmx_expire = in->rt_rmx.rmx_expire ? 1159 time_mono_to_wall(in->rt_rmx.rmx_expire) : 0; 1160 } 1161 1162 static int 1163 rt_xaddrs(u_char rtmtype, const char *cp, const char *cplim, 1164 struct rt_addrinfo *rtinfo) 1165 { 1166 const struct sockaddr *sa = NULL; /* Quell compiler warning */ 1167 int i; 1168 1169 for (i = 0; i < RTAX_MAX && cp < cplim; i++) { 1170 if ((rtinfo->rti_addrs & (1 << i)) == 0) 1171 continue; 1172 rtinfo->rti_info[i] = sa = (const struct sockaddr *)cp; 1173 RT_XADVANCE(cp, sa); 1174 } 1175 1176 /* 1177 * Check for extra addresses specified, except RTM_GET asking 1178 * for interface info. 1179 */ 1180 if (rtmtype == RTM_GET) { 1181 if (((rtinfo->rti_addrs & 1182 (~((1 << RTAX_IFP) | (1 << RTAX_IFA)))) & (~0U << i)) != 0) 1183 return 1; 1184 } else if ((rtinfo->rti_addrs & (~0U << i)) != 0) 1185 return 1; 1186 /* Check for bad data length. */ 1187 if (cp != cplim) { 1188 if (i == RTAX_NETMASK + 1 && sa != NULL && 1189 cp - RT_XROUNDUP(sa->sa_len) + sa->sa_len == cplim) 1190 /* 1191 * The last sockaddr was info.rti_info[RTAX_NETMASK]. 1192 * We accept this for now for the sake of old 1193 * binaries or third party softwares. 1194 */ 1195 ; 1196 else 1197 return 1; 1198 } 1199 return 0; 1200 } 1201 1202 static int 1203 rt_getlen(int type) 1204 { 1205 #ifndef COMPAT_RTSOCK 1206 CTASSERT(__alignof(struct ifa_msghdr) >= sizeof(uint64_t)); 1207 CTASSERT(__alignof(struct if_msghdr) >= sizeof(uint64_t)); 1208 CTASSERT(__alignof(struct if_announcemsghdr) >= sizeof(uint64_t)); 1209 CTASSERT(__alignof(struct rt_msghdr) >= sizeof(uint64_t)); 1210 #endif 1211 1212 switch (type) { 1213 case RTM_ODELADDR: 1214 case RTM_ONEWADDR: 1215 case RTM_OCHGADDR: 1216 #ifdef COMPAT_70 1217 return sizeof(struct ifa_msghdr70); 1218 #else 1219 #ifdef RTSOCK_DEBUG 1220 printf("%s: unsupported RTM type %d\n", __func__, type); 1221 #endif 1222 return -1; 1223 #endif 1224 case RTM_DELADDR: 1225 case RTM_NEWADDR: 1226 case RTM_CHGADDR: 1227 return sizeof(struct ifa_xmsghdr); 1228 1229 case RTM_OOIFINFO: 1230 #ifdef COMPAT_14 1231 return sizeof(struct if_msghdr14); 1232 #else 1233 #ifdef RTSOCK_DEBUG 1234 printf("%s: unsupported RTM type RTM_OOIFINFO\n", __func__); 1235 #endif 1236 return -1; 1237 #endif 1238 case RTM_OIFINFO: 1239 #ifdef COMPAT_50 1240 return sizeof(struct if_msghdr50); 1241 #else 1242 #ifdef RTSOCK_DEBUG 1243 printf("%s: unsupported RTM type RTM_OIFINFO\n", __func__); 1244 #endif 1245 return -1; 1246 #endif 1247 1248 case RTM_IFINFO: 1249 return sizeof(struct if_xmsghdr); 1250 1251 case RTM_IFANNOUNCE: 1252 case RTM_IEEE80211: 1253 return sizeof(struct if_xannouncemsghdr); 1254 1255 default: 1256 return sizeof(struct rt_xmsghdr); 1257 } 1258 } 1259 1260 1261 struct mbuf * 1262 COMPATNAME(rt_msg1)(int type, struct rt_addrinfo *rtinfo, void *data, int datalen) 1263 { 1264 struct rt_xmsghdr *rtm; 1265 struct mbuf *m; 1266 int i; 1267 const struct sockaddr *sa; 1268 int len, dlen; 1269 1270 m = m_gethdr(M_DONTWAIT, MT_DATA); 1271 if (m == NULL) 1272 return m; 1273 MCLAIM(m, &COMPATNAME(routedomain).dom_mowner); 1274 1275 if ((len = rt_getlen(type)) == -1) 1276 goto out; 1277 if (len > MHLEN + MLEN) 1278 panic("%s: message too long", __func__); 1279 else if (len > MHLEN) { 1280 m->m_next = m_get(M_DONTWAIT, MT_DATA); 1281 if (m->m_next == NULL) 1282 goto out; 1283 MCLAIM(m->m_next, m->m_owner); 1284 m->m_pkthdr.len = len; 1285 m->m_len = MHLEN; 1286 m->m_next->m_len = len - MHLEN; 1287 } else { 1288 m->m_pkthdr.len = m->m_len = len; 1289 } 1290 m_reset_rcvif(m); 1291 m_copyback(m, 0, datalen, data); 1292 if (len > datalen) 1293 (void)memset(mtod(m, char *) + datalen, 0, len - datalen); 1294 rtm = mtod(m, struct rt_xmsghdr *); 1295 for (i = 0; i < RTAX_MAX; i++) { 1296 if ((sa = rtinfo->rti_info[i]) == NULL) 1297 continue; 1298 rtinfo->rti_addrs |= (1 << i); 1299 dlen = RT_XROUNDUP(sa->sa_len); 1300 m_copyback(m, len, sa->sa_len, sa); 1301 if (dlen != sa->sa_len) { 1302 /* 1303 * Up to 6 + 1 nul's since roundup is to 1304 * sizeof(uint64_t) (8 bytes) 1305 */ 1306 m_copyback(m, len + sa->sa_len, 1307 dlen - sa->sa_len, "\0\0\0\0\0\0"); 1308 } 1309 len += dlen; 1310 } 1311 if (m->m_pkthdr.len != len) 1312 goto out; 1313 rtm->rtm_msglen = len; 1314 rtm->rtm_version = RTM_XVERSION; 1315 rtm->rtm_type = type; 1316 return m; 1317 out: 1318 m_freem(m); 1319 return NULL; 1320 } 1321 1322 /* 1323 * rt_msg2 1324 * 1325 * fills 'cp' or 'w'.w_tmem with the routing socket message and 1326 * returns the length of the message in 'lenp'. 1327 * 1328 * if walkarg is 0, cp is expected to be 0 or a buffer large enough to hold 1329 * the message 1330 * otherwise walkarg's w_needed is updated and if the user buffer is 1331 * specified and w_needed indicates space exists the information is copied 1332 * into the temp space (w_tmem). w_tmem is [re]allocated if necessary, 1333 * if the allocation fails ENOBUFS is returned. 1334 */ 1335 static int 1336 rt_msg2(int type, struct rt_addrinfo *rtinfo, void *cpv, struct rt_walkarg *w, 1337 int *lenp) 1338 { 1339 int i; 1340 int len, dlen, second_time = 0; 1341 char *cp0, *cp = cpv; 1342 1343 rtinfo->rti_addrs = 0; 1344 again: 1345 if ((len = rt_getlen(type)) == -1) 1346 return EINVAL; 1347 1348 if ((cp0 = cp) != NULL) 1349 cp += len; 1350 for (i = 0; i < RTAX_MAX; i++) { 1351 const struct sockaddr *sa; 1352 1353 if ((sa = rtinfo->rti_info[i]) == NULL) 1354 continue; 1355 rtinfo->rti_addrs |= (1 << i); 1356 dlen = RT_XROUNDUP(sa->sa_len); 1357 if (cp) { 1358 int diff = dlen - sa->sa_len; 1359 (void)memcpy(cp, sa, (size_t)sa->sa_len); 1360 cp += sa->sa_len; 1361 if (diff > 0) { 1362 (void)memset(cp, 0, (size_t)diff); 1363 cp += diff; 1364 } 1365 } 1366 len += dlen; 1367 } 1368 if (cp == NULL && w != NULL && !second_time) { 1369 struct rt_walkarg *rw = w; 1370 1371 rw->w_needed += len; 1372 if (rw->w_needed <= 0 && rw->w_where) { 1373 if (rw->w_tmemsize < len) { 1374 if (rw->w_tmem) 1375 kmem_free(rw->w_tmem, rw->w_tmemsize); 1376 rw->w_tmem = kmem_alloc(len, KM_SLEEP); 1377 rw->w_tmemsize = len; 1378 } 1379 if (rw->w_tmem) { 1380 cp = rw->w_tmem; 1381 second_time = 1; 1382 goto again; 1383 } else { 1384 rw->w_tmemneeded = len; 1385 return ENOBUFS; 1386 } 1387 } 1388 } 1389 if (cp) { 1390 struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)cp0; 1391 1392 rtm->rtm_version = RTM_XVERSION; 1393 rtm->rtm_type = type; 1394 rtm->rtm_msglen = len; 1395 } 1396 if (lenp) 1397 *lenp = len; 1398 return 0; 1399 } 1400 1401 #ifndef COMPAT_RTSOCK 1402 int 1403 rt_msg3(int type, struct rt_addrinfo *rtinfo, void *cpv, struct rt_walkarg *w, 1404 int *lenp) 1405 { 1406 return rt_msg2(type, rtinfo, cpv, w, lenp); 1407 } 1408 #endif 1409 1410 /* 1411 * This routine is called to generate a message from the routing 1412 * socket indicating that a redirect has occurred, a routing lookup 1413 * has failed, or that a protocol has detected timeouts to a particular 1414 * destination. 1415 */ 1416 void 1417 COMPATNAME(rt_missmsg)(int type, const struct rt_addrinfo *rtinfo, int flags, 1418 int error) 1419 { 1420 struct rt_xmsghdr rtm; 1421 struct mbuf *m; 1422 const struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 1423 struct rt_addrinfo info = *rtinfo; 1424 1425 COMPATCALL(rt_missmsg, (type, rtinfo, flags, error)); 1426 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1427 return; 1428 memset(&rtm, 0, sizeof(rtm)); 1429 rtm.rtm_pid = curproc->p_pid; 1430 rtm.rtm_flags = RTF_DONE | flags; 1431 rtm.rtm_errno = error; 1432 m = COMPATNAME(rt_msg1)(type, &info, &rtm, sizeof(rtm)); 1433 if (m == NULL) 1434 return; 1435 mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs; 1436 COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0); 1437 } 1438 1439 /* 1440 * This routine is called to generate a message from the routing 1441 * socket indicating that the status of a network interface has changed. 1442 */ 1443 void 1444 COMPATNAME(rt_ifmsg)(struct ifnet *ifp) 1445 { 1446 struct if_xmsghdr ifm; 1447 struct mbuf *m; 1448 struct rt_addrinfo info; 1449 1450 COMPATCALL(rt_ifmsg, (ifp)); 1451 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1452 return; 1453 (void)memset(&info, 0, sizeof(info)); 1454 (void)memset(&ifm, 0, sizeof(ifm)); 1455 ifm.ifm_index = ifp->if_index; 1456 ifm.ifm_flags = ifp->if_flags; 1457 ifm.ifm_data = ifp->if_data; 1458 ifm.ifm_addrs = 0; 1459 m = COMPATNAME(rt_msg1)(RTM_IFINFO, &info, &ifm, sizeof(ifm)); 1460 if (m == NULL) 1461 return; 1462 COMPATNAME(route_enqueue)(m, 0); 1463 #ifdef COMPAT_14 1464 compat_14_rt_oifmsg(ifp); 1465 #endif 1466 #ifdef COMPAT_50 1467 compat_50_rt_oifmsg(ifp); 1468 #endif 1469 } 1470 1471 #ifndef COMPAT_RTSOCK 1472 static int 1473 if_addrflags(struct ifaddr *ifa) 1474 { 1475 1476 switch (ifa->ifa_addr->sa_family) { 1477 #ifdef INET 1478 case AF_INET: 1479 return ((struct in_ifaddr *)ifa)->ia4_flags; 1480 #endif 1481 #ifdef INET6 1482 case AF_INET6: 1483 return ((struct in6_ifaddr *)ifa)->ia6_flags; 1484 #endif 1485 default: 1486 return 0; 1487 } 1488 } 1489 #endif 1490 1491 /* 1492 * This is called to generate messages from the routing socket 1493 * indicating a network interface has had addresses associated with it. 1494 * if we ever reverse the logic and replace messages TO the routing 1495 * socket indicate a request to configure interfaces, then it will 1496 * be unnecessary as the routing socket will automatically generate 1497 * copies of it. 1498 */ 1499 void 1500 COMPATNAME(rt_newaddrmsg)(int cmd, struct ifaddr *ifa, int error, 1501 struct rtentry *rt) 1502 { 1503 #define cmdpass(__cmd, __pass) (((__cmd) << 2) | (__pass)) 1504 struct rt_addrinfo info; 1505 const struct sockaddr *sa; 1506 int pass; 1507 struct mbuf *m; 1508 struct ifnet *ifp; 1509 struct rt_xmsghdr rtm; 1510 struct ifa_xmsghdr ifam; 1511 int ncmd; 1512 1513 KASSERT(ifa != NULL); 1514 KASSERT(ifa->ifa_addr != NULL); 1515 ifp = ifa->ifa_ifp; 1516 #ifdef SCTP 1517 if (cmd == RTM_ADD) { 1518 sctp_add_ip_address(ifa); 1519 } else if (cmd == RTM_DELETE) { 1520 sctp_delete_ip_address(ifa); 1521 } 1522 #endif 1523 1524 COMPATCALL(rt_newaddrmsg, (cmd, ifa, error, rt)); 1525 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1526 return; 1527 for (pass = 1; pass < 3; pass++) { 1528 memset(&info, 0, sizeof(info)); 1529 switch (cmdpass(cmd, pass)) { 1530 case cmdpass(RTM_ADD, 1): 1531 case cmdpass(RTM_CHANGE, 1): 1532 case cmdpass(RTM_DELETE, 2): 1533 case cmdpass(RTM_NEWADDR, 1): 1534 case cmdpass(RTM_DELADDR, 1): 1535 case cmdpass(RTM_CHGADDR, 1): 1536 switch (cmd) { 1537 case RTM_ADD: 1538 ncmd = RTM_XNEWADDR; 1539 break; 1540 case RTM_DELETE: 1541 ncmd = RTM_XDELADDR; 1542 break; 1543 case RTM_CHANGE: 1544 ncmd = RTM_XCHGADDR; 1545 break; 1546 case RTM_NEWADDR: 1547 ncmd = RTM_XNEWADDR; 1548 break; 1549 case RTM_DELADDR: 1550 ncmd = RTM_XDELADDR; 1551 break; 1552 case RTM_CHGADDR: 1553 ncmd = RTM_XCHGADDR; 1554 break; 1555 default: 1556 panic("%s: unknown command %d", __func__, cmd); 1557 } 1558 #ifdef COMPAT_70 1559 compat_70_rt_newaddrmsg1(ncmd, ifa); 1560 #endif 1561 info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; 1562 KASSERT(ifp->if_dl != NULL); 1563 info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; 1564 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1565 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1566 memset(&ifam, 0, sizeof(ifam)); 1567 ifam.ifam_index = ifp->if_index; 1568 ifam.ifam_metric = ifa->ifa_metric; 1569 ifam.ifam_flags = ifa->ifa_flags; 1570 #ifndef COMPAT_RTSOCK 1571 ifam.ifam_pid = curproc->p_pid; 1572 ifam.ifam_addrflags = if_addrflags(ifa); 1573 #endif 1574 m = COMPATNAME(rt_msg1)(ncmd, &info, &ifam, sizeof(ifam)); 1575 if (m == NULL) 1576 continue; 1577 mtod(m, struct ifa_xmsghdr *)->ifam_addrs = 1578 info.rti_addrs; 1579 break; 1580 case cmdpass(RTM_ADD, 2): 1581 case cmdpass(RTM_CHANGE, 2): 1582 case cmdpass(RTM_DELETE, 1): 1583 if (rt == NULL) 1584 continue; 1585 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1586 info.rti_info[RTAX_DST] = sa = rt_getkey(rt); 1587 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1588 memset(&rtm, 0, sizeof(rtm)); 1589 rtm.rtm_pid = curproc->p_pid; 1590 rtm.rtm_index = ifp->if_index; 1591 rtm.rtm_flags |= rt->rt_flags; 1592 rtm.rtm_errno = error; 1593 m = COMPATNAME(rt_msg1)(cmd, &info, &rtm, sizeof(rtm)); 1594 if (m == NULL) 1595 continue; 1596 mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs; 1597 break; 1598 default: 1599 continue; 1600 } 1601 KASSERTMSG(m != NULL, "called with wrong command"); 1602 COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0); 1603 } 1604 #undef cmdpass 1605 1606 } 1607 1608 static struct mbuf * 1609 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what, 1610 struct rt_addrinfo *info) 1611 { 1612 struct if_xannouncemsghdr ifan; 1613 1614 memset(info, 0, sizeof(*info)); 1615 memset(&ifan, 0, sizeof(ifan)); 1616 ifan.ifan_index = ifp->if_index; 1617 strlcpy(ifan.ifan_name, ifp->if_xname, sizeof(ifan.ifan_name)); 1618 ifan.ifan_what = what; 1619 return COMPATNAME(rt_msg1)(type, info, &ifan, sizeof(ifan)); 1620 } 1621 1622 /* 1623 * This is called to generate routing socket messages indicating 1624 * network interface arrival and departure. 1625 */ 1626 void 1627 COMPATNAME(rt_ifannouncemsg)(struct ifnet *ifp, int what) 1628 { 1629 struct mbuf *m; 1630 struct rt_addrinfo info; 1631 1632 COMPATCALL(rt_ifannouncemsg, (ifp, what)); 1633 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1634 return; 1635 m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info); 1636 if (m == NULL) 1637 return; 1638 COMPATNAME(route_enqueue)(m, 0); 1639 } 1640 1641 /* 1642 * This is called to generate routing socket messages indicating 1643 * IEEE80211 wireless events. 1644 * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way. 1645 */ 1646 void 1647 COMPATNAME(rt_ieee80211msg)(struct ifnet *ifp, int what, void *data, 1648 size_t data_len) 1649 { 1650 struct mbuf *m; 1651 struct rt_addrinfo info; 1652 1653 COMPATCALL(rt_ieee80211msg, (ifp, what, data, data_len)); 1654 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1655 return; 1656 m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info); 1657 if (m == NULL) 1658 return; 1659 /* 1660 * Append the ieee80211 data. Try to stick it in the 1661 * mbuf containing the ifannounce msg; otherwise allocate 1662 * a new mbuf and append. 1663 * 1664 * NB: we assume m is a single mbuf. 1665 */ 1666 if (data_len > M_TRAILINGSPACE(m)) { 1667 struct mbuf *n = m_get(M_NOWAIT, MT_DATA); 1668 if (n == NULL) { 1669 m_freem(m); 1670 return; 1671 } 1672 (void)memcpy(mtod(n, void *), data, data_len); 1673 n->m_len = data_len; 1674 m->m_next = n; 1675 } else if (data_len > 0) { 1676 (void)memcpy(mtod(m, uint8_t *) + m->m_len, data, data_len); 1677 m->m_len += data_len; 1678 } 1679 if (m->m_flags & M_PKTHDR) 1680 m->m_pkthdr.len += data_len; 1681 mtod(m, struct if_xannouncemsghdr *)->ifan_msglen += data_len; 1682 COMPATNAME(route_enqueue)(m, 0); 1683 } 1684 1685 #ifndef COMPAT_RTSOCK 1686 /* 1687 * Send a routing message as mimicing that a cloned route is added. 1688 */ 1689 void 1690 rt_clonedmsg(const struct sockaddr *dst, const struct ifnet *ifp, 1691 const struct rtentry *rt) 1692 { 1693 struct rt_addrinfo info; 1694 /* Mimic flags exactly */ 1695 #define RTF_LLINFO 0x400 1696 #define RTF_CLONED 0x2000 1697 int flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_LLINFO | RTF_CLONED; 1698 union { 1699 struct sockaddr sa; 1700 struct sockaddr_storage ss; 1701 struct sockaddr_dl sdl; 1702 } u; 1703 uint8_t namelen = strlen(ifp->if_xname); 1704 uint8_t addrlen = ifp->if_addrlen; 1705 1706 if (rt == NULL) 1707 return; /* XXX */ 1708 1709 memset(&info, 0, sizeof(info)); 1710 info.rti_info[RTAX_DST] = dst; 1711 sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index, ifp->if_type, 1712 NULL, namelen, NULL, addrlen); 1713 info.rti_info[RTAX_GATEWAY] = &u.sa; 1714 1715 rt_missmsg(RTM_ADD, &info, flags, 0); 1716 #undef RTF_LLINFO 1717 #undef RTF_CLONED 1718 } 1719 #endif /* COMPAT_RTSOCK */ 1720 1721 /* 1722 * This is used in dumping the kernel table via sysctl(). 1723 */ 1724 static int 1725 sysctl_dumpentry(struct rtentry *rt, void *v) 1726 { 1727 struct rt_walkarg *w = v; 1728 int error = 0, size; 1729 struct rt_addrinfo info; 1730 1731 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1732 return 0; 1733 memset(&info, 0, sizeof(info)); 1734 info.rti_info[RTAX_DST] = rt_getkey(rt); 1735 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1736 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1737 info.rti_info[RTAX_TAG] = rt_gettag(rt); 1738 if (rt->rt_ifp) { 1739 const struct ifaddr *rtifa; 1740 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr; 1741 /* rtifa used to be simply rt->rt_ifa. If rt->rt_ifa != NULL, 1742 * then rt_get_ifa() != NULL. So this ought to still be safe. 1743 * --dyoung 1744 */ 1745 rtifa = rt_get_ifa(rt); 1746 info.rti_info[RTAX_IFA] = rtifa->ifa_addr; 1747 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1748 info.rti_info[RTAX_BRD] = rtifa->ifa_dstaddr; 1749 } 1750 if ((error = rt_msg2(RTM_GET, &info, 0, w, &size))) 1751 return error; 1752 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1753 struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)w->w_tmem; 1754 1755 rtm->rtm_flags = rt->rt_flags; 1756 rtm->rtm_use = rt->rt_use; 1757 rtm_setmetrics(rt, rtm); 1758 KASSERT(rt->rt_ifp != NULL); 1759 rtm->rtm_index = rt->rt_ifp->if_index; 1760 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 1761 rtm->rtm_addrs = info.rti_addrs; 1762 if ((error = copyout(rtm, w->w_where, size)) != 0) 1763 w->w_where = NULL; 1764 else 1765 w->w_where = (char *)w->w_where + size; 1766 } 1767 return error; 1768 } 1769 1770 static int 1771 sysctl_iflist_if(struct ifnet *ifp, struct rt_walkarg *w, 1772 struct rt_addrinfo *info, size_t len) 1773 { 1774 struct if_xmsghdr *ifm; 1775 int error; 1776 1777 ifm = (struct if_xmsghdr *)w->w_tmem; 1778 ifm->ifm_index = ifp->if_index; 1779 ifm->ifm_flags = ifp->if_flags; 1780 ifm->ifm_data = ifp->if_data; 1781 ifm->ifm_addrs = info->rti_addrs; 1782 if ((error = copyout(ifm, w->w_where, len)) == 0) 1783 w->w_where = (char *)w->w_where + len; 1784 return error; 1785 } 1786 1787 static int 1788 sysctl_iflist_addr(struct rt_walkarg *w, struct ifaddr *ifa, 1789 struct rt_addrinfo *info) 1790 { 1791 int len, error; 1792 1793 if ((error = rt_msg2(RTM_XNEWADDR, info, 0, w, &len))) 1794 return error; 1795 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1796 struct ifa_xmsghdr *ifam; 1797 1798 ifam = (struct ifa_xmsghdr *)w->w_tmem; 1799 ifam->ifam_index = ifa->ifa_ifp->if_index; 1800 ifam->ifam_flags = ifa->ifa_flags; 1801 ifam->ifam_metric = ifa->ifa_metric; 1802 ifam->ifam_addrs = info->rti_addrs; 1803 #ifndef COMPAT_RTSOCK 1804 ifam->ifam_pid = 0; 1805 ifam->ifam_addrflags = if_addrflags(ifa); 1806 #endif 1807 if ((error = copyout(w->w_tmem, w->w_where, len)) == 0) 1808 w->w_where = (char *)w->w_where + len; 1809 } 1810 return error; 1811 } 1812 1813 static int 1814 sysctl_iflist(int af, struct rt_walkarg *w, int type) 1815 { 1816 struct ifnet *ifp; 1817 struct ifaddr *ifa; 1818 struct rt_addrinfo info; 1819 int cmd, len, error = 0; 1820 int (*iflist_if)(struct ifnet *, struct rt_walkarg *, 1821 struct rt_addrinfo *, size_t); 1822 int (*iflist_addr)(struct rt_walkarg *, struct ifaddr *, 1823 struct rt_addrinfo *); 1824 int s; 1825 struct psref psref; 1826 int bound; 1827 1828 switch (type) { 1829 case NET_RT_IFLIST: 1830 cmd = RTM_IFINFO; 1831 iflist_if = sysctl_iflist_if; 1832 iflist_addr = sysctl_iflist_addr; 1833 break; 1834 #ifdef COMPAT_14 1835 case NET_RT_OOOIFLIST: 1836 cmd = RTM_OOIFINFO; 1837 iflist_if = compat_14_iflist; 1838 iflist_addr = compat_70_iflist_addr; 1839 break; 1840 #endif 1841 #ifdef COMPAT_50 1842 case NET_RT_OOIFLIST: 1843 cmd = RTM_OIFINFO; 1844 iflist_if = compat_50_iflist; 1845 iflist_addr = compat_70_iflist_addr; 1846 break; 1847 #endif 1848 #ifdef COMPAT_70 1849 case NET_RT_OIFLIST: 1850 cmd = RTM_IFINFO; 1851 iflist_if = sysctl_iflist_if; 1852 iflist_addr = compat_70_iflist_addr; 1853 break; 1854 #endif 1855 default: 1856 #ifdef RTSOCK_DEBUG 1857 printf("%s: unsupported IFLIST type %d\n", __func__, type); 1858 #endif 1859 return EINVAL; 1860 } 1861 1862 memset(&info, 0, sizeof(info)); 1863 1864 bound = curlwp_bind(); 1865 s = pserialize_read_enter(); 1866 IFNET_READER_FOREACH(ifp) { 1867 int _s; 1868 if (w->w_arg && w->w_arg != ifp->if_index) 1869 continue; 1870 if (IFADDR_READER_EMPTY(ifp)) 1871 continue; 1872 1873 if_acquire(ifp, &psref); 1874 pserialize_read_exit(s); 1875 1876 info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; 1877 if ((error = rt_msg2(cmd, &info, NULL, w, &len)) != 0) 1878 goto release_exit; 1879 info.rti_info[RTAX_IFP] = NULL; 1880 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1881 if ((error = iflist_if(ifp, w, &info, len)) != 0) 1882 goto release_exit; 1883 } 1884 _s = pserialize_read_enter(); 1885 IFADDR_READER_FOREACH(ifa, ifp) { 1886 struct psref _psref; 1887 if (af && af != ifa->ifa_addr->sa_family) 1888 continue; 1889 ifa_acquire(ifa, &_psref); 1890 pserialize_read_exit(_s); 1891 1892 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1893 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1894 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1895 error = iflist_addr(w, ifa, &info); 1896 1897 _s = pserialize_read_enter(); 1898 ifa_release(ifa, &_psref); 1899 if (error != 0) { 1900 pserialize_read_exit(_s); 1901 goto release_exit; 1902 } 1903 } 1904 pserialize_read_exit(_s); 1905 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = 1906 info.rti_info[RTAX_BRD] = NULL; 1907 1908 s = pserialize_read_enter(); 1909 if_release(ifp, &psref); 1910 } 1911 pserialize_read_exit(s); 1912 curlwp_bindx(bound); 1913 1914 return 0; 1915 1916 release_exit: 1917 if_release(ifp, &psref); 1918 curlwp_bindx(bound); 1919 return error; 1920 } 1921 1922 static int 1923 sysctl_rtable(SYSCTLFN_ARGS) 1924 { 1925 void *where = oldp; 1926 size_t *given = oldlenp; 1927 int i, s, error = EINVAL; 1928 u_char af; 1929 struct rt_walkarg w; 1930 1931 if (namelen == 1 && name[0] == CTL_QUERY) 1932 return sysctl_query(SYSCTLFN_CALL(rnode)); 1933 1934 if (newp) 1935 return EPERM; 1936 if (namelen != 3) 1937 return EINVAL; 1938 af = name[0]; 1939 w.w_tmemneeded = 0; 1940 w.w_tmemsize = 0; 1941 w.w_tmem = NULL; 1942 again: 1943 /* we may return here if a later [re]alloc of the t_mem buffer fails */ 1944 if (w.w_tmemneeded) { 1945 w.w_tmem = kmem_alloc(w.w_tmemneeded, KM_SLEEP); 1946 w.w_tmemsize = w.w_tmemneeded; 1947 w.w_tmemneeded = 0; 1948 } 1949 w.w_op = name[1]; 1950 w.w_arg = name[2]; 1951 w.w_given = *given; 1952 w.w_needed = 0 - w.w_given; 1953 w.w_where = where; 1954 1955 s = splsoftnet(); 1956 switch (w.w_op) { 1957 1958 case NET_RT_DUMP: 1959 case NET_RT_FLAGS: 1960 #if defined(INET) || defined(INET6) 1961 /* 1962 * take care of llinfo entries, the caller must 1963 * specify an AF 1964 */ 1965 if (w.w_op == NET_RT_FLAGS && 1966 (w.w_arg == 0 || w.w_arg & RTF_LLDATA)) { 1967 if (af != 0) 1968 error = lltable_sysctl_dump(af, &w); 1969 else 1970 error = EINVAL; 1971 break; 1972 } 1973 #endif 1974 1975 for (i = 1; i <= AF_MAX; i++) { 1976 if (af == 0 || af == i) { 1977 error = rt_walktree(i, sysctl_dumpentry, &w); 1978 if (error != 0) 1979 break; 1980 #if defined(INET) || defined(INET6) 1981 /* 1982 * Return ARP/NDP entries too for 1983 * backward compatibility. 1984 */ 1985 error = lltable_sysctl_dump(i, &w); 1986 if (error != 0) 1987 break; 1988 #endif 1989 } 1990 } 1991 break; 1992 1993 #ifdef COMPAT_14 1994 case NET_RT_OOOIFLIST: 1995 error = sysctl_iflist(af, &w, w.w_op); 1996 break; 1997 #endif 1998 #ifdef COMPAT_50 1999 case NET_RT_OOIFLIST: 2000 error = sysctl_iflist(af, &w, w.w_op); 2001 break; 2002 #endif 2003 #ifdef COMPAT_70 2004 case NET_RT_OIFLIST: 2005 error = sysctl_iflist(af, &w, w.w_op); 2006 break; 2007 #endif 2008 case NET_RT_IFLIST: 2009 error = sysctl_iflist(af, &w, w.w_op); 2010 break; 2011 } 2012 splx(s); 2013 2014 /* check to see if we couldn't allocate memory with NOWAIT */ 2015 if (error == ENOBUFS && w.w_tmem == 0 && w.w_tmemneeded) 2016 goto again; 2017 2018 if (w.w_tmem) 2019 kmem_free(w.w_tmem, w.w_tmemsize); 2020 w.w_needed += w.w_given; 2021 if (where) { 2022 *given = (char *)w.w_where - (char *)where; 2023 if (*given < w.w_needed) 2024 return ENOMEM; 2025 } else { 2026 *given = (11 * w.w_needed) / 10; 2027 } 2028 return error; 2029 } 2030 2031 /* 2032 * Routing message software interrupt routine 2033 */ 2034 static void 2035 COMPATNAME(route_intr)(void *cookie) 2036 { 2037 struct sockproto proto = { .sp_family = PF_XROUTE, }; 2038 struct route_info * const ri = &COMPATNAME(route_info); 2039 struct mbuf *m; 2040 2041 SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); 2042 for (;;) { 2043 IFQ_LOCK(&ri->ri_intrq); 2044 IF_DEQUEUE(&ri->ri_intrq, m); 2045 IFQ_UNLOCK(&ri->ri_intrq); 2046 if (m == NULL) 2047 break; 2048 proto.sp_protocol = M_GETCTX(m, uintptr_t); 2049 #ifdef NET_MPSAFE 2050 mutex_enter(rt_so_mtx); 2051 #endif 2052 raw_input(m, &proto, &ri->ri_src, &ri->ri_dst, &rt_rawcb); 2053 #ifdef NET_MPSAFE 2054 mutex_exit(rt_so_mtx); 2055 #endif 2056 } 2057 SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 2058 } 2059 2060 /* 2061 * Enqueue a message to the software interrupt routine. 2062 */ 2063 void 2064 COMPATNAME(route_enqueue)(struct mbuf *m, int family) 2065 { 2066 struct route_info * const ri = &COMPATNAME(route_info); 2067 int wasempty; 2068 2069 IFQ_LOCK(&ri->ri_intrq); 2070 if (IF_QFULL(&ri->ri_intrq)) { 2071 IF_DROP(&ri->ri_intrq); 2072 IFQ_UNLOCK(&ri->ri_intrq); 2073 m_freem(m); 2074 } else { 2075 wasempty = IF_IS_EMPTY(&ri->ri_intrq); 2076 M_SETCTX(m, (uintptr_t)family); 2077 IF_ENQUEUE(&ri->ri_intrq, m); 2078 IFQ_UNLOCK(&ri->ri_intrq); 2079 if (wasempty) { 2080 kpreempt_disable(); 2081 softint_schedule(ri->ri_sih); 2082 kpreempt_enable(); 2083 } 2084 } 2085 } 2086 2087 static void 2088 COMPATNAME(route_init)(void) 2089 { 2090 struct route_info * const ri = &COMPATNAME(route_info); 2091 2092 #ifndef COMPAT_RTSOCK 2093 rt_init(); 2094 #endif 2095 #ifdef NET_MPSAFE 2096 rt_so_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 2097 #endif 2098 2099 sysctl_net_route_setup(NULL); 2100 ri->ri_intrq.ifq_maxlen = ri->ri_maxqlen; 2101 ri->ri_sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 2102 COMPATNAME(route_intr), NULL); 2103 IFQ_LOCK_INIT(&ri->ri_intrq); 2104 } 2105 2106 /* 2107 * Definitions of protocols supported in the ROUTE domain. 2108 */ 2109 #ifndef COMPAT_RTSOCK 2110 PR_WRAP_USRREQS(route); 2111 #else 2112 PR_WRAP_USRREQS(compat_50_route); 2113 #endif 2114 2115 static const struct pr_usrreqs route_usrreqs = { 2116 .pr_attach = COMPATNAME(route_attach_wrapper), 2117 .pr_detach = COMPATNAME(route_detach_wrapper), 2118 .pr_accept = COMPATNAME(route_accept_wrapper), 2119 .pr_bind = COMPATNAME(route_bind_wrapper), 2120 .pr_listen = COMPATNAME(route_listen_wrapper), 2121 .pr_connect = COMPATNAME(route_connect_wrapper), 2122 .pr_connect2 = COMPATNAME(route_connect2_wrapper), 2123 .pr_disconnect = COMPATNAME(route_disconnect_wrapper), 2124 .pr_shutdown = COMPATNAME(route_shutdown_wrapper), 2125 .pr_abort = COMPATNAME(route_abort_wrapper), 2126 .pr_ioctl = COMPATNAME(route_ioctl_wrapper), 2127 .pr_stat = COMPATNAME(route_stat_wrapper), 2128 .pr_peeraddr = COMPATNAME(route_peeraddr_wrapper), 2129 .pr_sockaddr = COMPATNAME(route_sockaddr_wrapper), 2130 .pr_rcvd = COMPATNAME(route_rcvd_wrapper), 2131 .pr_recvoob = COMPATNAME(route_recvoob_wrapper), 2132 .pr_send = COMPATNAME(route_send_wrapper), 2133 .pr_sendoob = COMPATNAME(route_sendoob_wrapper), 2134 .pr_purgeif = COMPATNAME(route_purgeif_wrapper), 2135 }; 2136 2137 static const struct protosw COMPATNAME(route_protosw)[] = { 2138 { 2139 .pr_type = SOCK_RAW, 2140 .pr_domain = &COMPATNAME(routedomain), 2141 .pr_flags = PR_ATOMIC|PR_ADDR, 2142 .pr_input = raw_input, 2143 .pr_ctlinput = raw_ctlinput, 2144 .pr_ctloutput = route_ctloutput, 2145 .pr_usrreqs = &route_usrreqs, 2146 .pr_init = rt_pr_init, 2147 }, 2148 }; 2149 2150 struct domain COMPATNAME(routedomain) = { 2151 .dom_family = PF_XROUTE, 2152 .dom_name = DOMAINNAME, 2153 .dom_init = COMPATNAME(route_init), 2154 .dom_protosw = COMPATNAME(route_protosw), 2155 .dom_protoswNPROTOSW = 2156 &COMPATNAME(route_protosw)[__arraycount(COMPATNAME(route_protosw))], 2157 }; 2158 2159 static void 2160 sysctl_net_route_setup(struct sysctllog **clog) 2161 { 2162 const struct sysctlnode *rnode = NULL; 2163 2164 sysctl_createv(clog, 0, NULL, &rnode, 2165 CTLFLAG_PERMANENT, 2166 CTLTYPE_NODE, DOMAINNAME, 2167 SYSCTL_DESCR("PF_ROUTE information"), 2168 NULL, 0, NULL, 0, 2169 CTL_NET, PF_XROUTE, CTL_EOL); 2170 2171 sysctl_createv(clog, 0, NULL, NULL, 2172 CTLFLAG_PERMANENT, 2173 CTLTYPE_NODE, "rtable", 2174 SYSCTL_DESCR("Routing table information"), 2175 sysctl_rtable, 0, NULL, 0, 2176 CTL_NET, PF_XROUTE, 0 /* any protocol */, CTL_EOL); 2177 2178 sysctl_createv(clog, 0, &rnode, NULL, 2179 CTLFLAG_PERMANENT, 2180 CTLTYPE_STRUCT, "stats", 2181 SYSCTL_DESCR("Routing statistics"), 2182 NULL, 0, &rtstat, sizeof(rtstat), 2183 CTL_CREATE, CTL_EOL); 2184 } 2185