1 /* $NetBSD: rtsock.c,v 1.231 2017/11/19 18:49:51 christos 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.231 2017/11/19 18:49:51 christos 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 /* 825 * Use the family of RTAX_DST, because RTAX_NETMASK 826 * can have a zero family if it comes from the radix 827 * tree via rt_mask(). 828 */ 829 socklen_t sa_len = sockaddr_getsize_by_family( 830 info.rti_info[RTAX_DST]->sa_family); 831 socklen_t masklen = sockaddr_getlen( 832 info.rti_info[RTAX_NETMASK]); 833 if (sa_len != 0 && sa_len > masklen) { 834 KASSERT(sa_len <= sizeof(netmask)); 835 memcpy(&netmask, info.rti_info[RTAX_NETMASK], masklen); 836 memset((char *)&netmask + masklen, 0, sa_len - masklen); 837 info.rti_info[RTAX_NETMASK] = sstocsa(&netmask); 838 } 839 } 840 841 switch (rtm->rtm_type) { 842 843 case RTM_ADD: 844 if (info.rti_info[RTAX_GATEWAY] == NULL) { 845 senderr(EINVAL); 846 } 847 #if defined(INET) || defined(INET6) 848 /* support for new ARP/NDP code with keeping backcompat */ 849 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { 850 const struct sockaddr_dl *sdlp = 851 satocsdl(info.rti_info[RTAX_GATEWAY]); 852 853 /* Allow routing requests by interface index */ 854 if (sdlp->sdl_nlen == 0 && sdlp->sdl_alen == 0 855 && sdlp->sdl_slen == 0) 856 goto fallback; 857 /* 858 * Old arp binaries don't set the sdl_index 859 * so we have to complement it. 860 */ 861 int sdl_index = sdlp->sdl_index; 862 if (sdl_index == 0) { 863 error = route_get_sdl_index(&info, &sdl_index); 864 if (error != 0) 865 goto fallback; 866 } else if ( 867 info.rti_info[RTAX_DST]->sa_family == AF_INET) { 868 /* 869 * XXX workaround for SIN_PROXY case; proxy arp 870 * entry should be in an interface that has 871 * a network route including the destination, 872 * not a local (link) route that may not be a 873 * desired place, for example a tap. 874 */ 875 const struct sockaddr_inarp *sina = 876 (const struct sockaddr_inarp *) 877 info.rti_info[RTAX_DST]; 878 if (sina->sin_other & SIN_PROXY) { 879 error = route_get_sdl_index(&info, 880 &sdl_index); 881 if (error != 0) 882 goto fallback; 883 } 884 } 885 error = lla_rt_output(rtm->rtm_type, rtm->rtm_flags, 886 rtm->rtm_rmx.rmx_expire, &info, sdl_index); 887 break; 888 } 889 fallback: 890 #endif /* defined(INET) || defined(INET6) */ 891 error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); 892 if (error == 0) { 893 rt_setmetrics(rtm->rtm_inits, rtm, saved_nrt); 894 rt_unref(saved_nrt); 895 } 896 break; 897 898 case RTM_DELETE: 899 #if defined(INET) || defined(INET6) 900 /* support for new ARP/NDP code */ 901 if (info.rti_info[RTAX_GATEWAY] && 902 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 903 (rtm->rtm_flags & RTF_LLDATA) != 0) { 904 const struct sockaddr_dl *sdlp = 905 satocsdl(info.rti_info[RTAX_GATEWAY]); 906 error = lla_rt_output(rtm->rtm_type, rtm->rtm_flags, 907 rtm->rtm_rmx.rmx_expire, &info, sdlp->sdl_index); 908 rtm->rtm_flags &= ~RTF_UP; 909 break; 910 } 911 #endif 912 error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); 913 if (error != 0) 914 break; 915 916 rt = saved_nrt; 917 do_rt_free = true; 918 info.rti_info[RTAX_DST] = rt_getkey(rt); 919 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 920 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 921 info.rti_info[RTAX_TAG] = rt_gettag(rt); 922 error = route_output_report(rt, &info, rtm, &new_rtm); 923 if (error) 924 senderr(error); 925 if (new_rtm != NULL) { 926 old_rtm = rtm; 927 rtm = new_rtm; 928 } 929 break; 930 931 case RTM_GET: 932 case RTM_CHANGE: 933 case RTM_LOCK: 934 /* XXX This will mask info.rti_info[RTAX_DST] with 935 * info.rti_info[RTAX_NETMASK] before 936 * searching. It did not used to do that. --dyoung 937 */ 938 rt = NULL; 939 error = rtrequest1(RTM_GET, &info, &rt); 940 if (error != 0) 941 senderr(error); 942 if (rtm->rtm_type != RTM_GET) {/* XXX: too grotty */ 943 if (memcmp(info.rti_info[RTAX_DST], rt_getkey(rt), 944 info.rti_info[RTAX_DST]->sa_len) != 0) 945 senderr(ESRCH); 946 if (info.rti_info[RTAX_NETMASK] == NULL && 947 rt_mask(rt) != NULL) 948 senderr(ETOOMANYREFS); 949 } 950 951 /* 952 * XXX if arp/ndp requests an L2 entry, we have to obtain 953 * it from lltable while for the route command we have to 954 * return a route as it is. How to distinguish them? 955 * For newer arp/ndp, RTF_LLDATA flag set by arp/ndp 956 * indicates an L2 entry is requested. For old arp/ndp 957 * binaries, we check RTF_UP flag is NOT set; it works 958 * by the fact that arp/ndp don't set it while the route 959 * command sets it. 960 */ 961 if (((rtm->rtm_flags & RTF_LLDATA) != 0 || 962 (rtm->rtm_flags & RTF_UP) == 0) && 963 rtm->rtm_type == RTM_GET && 964 sockaddr_cmp(rt_getkey(rt), info.rti_info[RTAX_DST]) != 0) { 965 int ll_flags = 0; 966 route_get_sdl(rt->rt_ifp, info.rti_info[RTAX_DST], &sdl, 967 &ll_flags); 968 info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl); 969 error = route_output_report(rt, &info, rtm, &new_rtm); 970 if (error) 971 senderr(error); 972 if (new_rtm != NULL) { 973 old_rtm = rtm; 974 rtm = new_rtm; 975 } 976 rtm->rtm_flags |= RTF_LLDATA; 977 rtm->rtm_flags &= ~RTF_CONNECTED; 978 rtm->rtm_flags |= (ll_flags & LLE_STATIC) ? RTF_STATIC : 0; 979 break; 980 } 981 982 switch (rtm->rtm_type) { 983 case RTM_GET: 984 info.rti_info[RTAX_DST] = rt_getkey(rt); 985 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 986 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 987 info.rti_info[RTAX_TAG] = rt_gettag(rt); 988 error = route_output_report(rt, &info, rtm, &new_rtm); 989 if (error) 990 senderr(error); 991 if (new_rtm != NULL) { 992 old_rtm = rtm; 993 rtm = new_rtm; 994 } 995 break; 996 997 case RTM_CHANGE: 998 #ifdef NET_MPSAFE 999 error = rt_update_prepare(rt); 1000 if (error == 0) { 1001 error = route_output_change(rt, &info, rtm); 1002 rt_update_finish(rt); 1003 } 1004 #else 1005 error = route_output_change(rt, &info, rtm); 1006 #endif 1007 if (error != 0) 1008 goto flush; 1009 /*FALLTHROUGH*/ 1010 case RTM_LOCK: 1011 rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); 1012 rt->rt_rmx.rmx_locks |= 1013 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); 1014 break; 1015 } 1016 break; 1017 1018 default: 1019 senderr(EOPNOTSUPP); 1020 } 1021 1022 flush: 1023 if (rtm) { 1024 if (error) 1025 rtm->rtm_errno = error; 1026 else 1027 rtm->rtm_flags |= RTF_DONE; 1028 } 1029 family = info.rti_info[RTAX_DST] ? info.rti_info[RTAX_DST]->sa_family : 1030 0; 1031 /* We cannot free old_rtm until we have stopped using the 1032 * pointers in info, some of which may point to sockaddrs 1033 * in old_rtm. 1034 */ 1035 if (old_rtm != NULL) 1036 Free(old_rtm); 1037 if (rt) { 1038 if (do_rt_free) 1039 rt_free(rt); 1040 else 1041 rt_unref(rt); 1042 } 1043 { 1044 struct rawcb *rp = NULL; 1045 /* 1046 * Check to see if we don't want our own messages. 1047 */ 1048 if ((so->so_options & SO_USELOOPBACK) == 0) { 1049 if (COMPATNAME(route_info).ri_cb.any_count <= 1) { 1050 if (rtm) 1051 Free(rtm); 1052 m_freem(m); 1053 goto out; 1054 } 1055 /* There is another listener, so construct message */ 1056 rp = sotorawcb(so); 1057 } 1058 if (rtm) { 1059 m_copyback(m, 0, rtm->rtm_msglen, rtm); 1060 if (m->m_pkthdr.len < rtm->rtm_msglen) { 1061 m_freem(m); 1062 m = NULL; 1063 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 1064 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 1065 Free(rtm); 1066 } 1067 if (rp) 1068 rp->rcb_proto.sp_family = 0; /* Avoid us */ 1069 if (family) 1070 proto.sp_protocol = family; 1071 if (m) 1072 raw_input(m, &proto, &COMPATNAME(route_info).ri_src, 1073 &COMPATNAME(route_info).ri_dst, &rt_rawcb); 1074 if (rp) 1075 rp->rcb_proto.sp_family = PF_XROUTE; 1076 } 1077 out: 1078 curlwp_bindx(bound); 1079 return error; 1080 } 1081 1082 static int 1083 route_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1084 { 1085 struct routecb *rop = sotoroutecb(so); 1086 int error = 0; 1087 unsigned char *rtm_type; 1088 size_t len; 1089 unsigned int msgfilter; 1090 1091 KASSERT(solocked(so)); 1092 1093 if (sopt->sopt_level != AF_ROUTE) { 1094 error = ENOPROTOOPT; 1095 } else switch (op) { 1096 case PRCO_SETOPT: 1097 switch (sopt->sopt_name) { 1098 case RO_MSGFILTER: 1099 msgfilter = 0; 1100 for (rtm_type = sopt->sopt_data, len = sopt->sopt_size; 1101 len != 0; 1102 rtm_type++, len -= sizeof(*rtm_type)) 1103 { 1104 /* Guard against overflowing our storage. */ 1105 if (*rtm_type >= sizeof(msgfilter) * CHAR_BIT) { 1106 error = EOVERFLOW; 1107 break; 1108 } 1109 msgfilter |= RTMSGFILTER(*rtm_type); 1110 } 1111 if (error == 0) 1112 rop->rocb_msgfilter = msgfilter; 1113 break; 1114 default: 1115 error = ENOPROTOOPT; 1116 break; 1117 } 1118 break; 1119 case PRCO_GETOPT: 1120 switch (sopt->sopt_name) { 1121 case RO_MSGFILTER: 1122 error = ENOTSUP; 1123 break; 1124 default: 1125 error = ENOPROTOOPT; 1126 break; 1127 } 1128 } 1129 return error; 1130 } 1131 1132 static void 1133 rt_setmetrics(int which, const struct rt_xmsghdr *in, struct rtentry *out) 1134 { 1135 #define metric(f, e) if (which & (f)) out->rt_rmx.e = in->rtm_rmx.e; 1136 metric(RTV_RPIPE, rmx_recvpipe); 1137 metric(RTV_SPIPE, rmx_sendpipe); 1138 metric(RTV_SSTHRESH, rmx_ssthresh); 1139 metric(RTV_RTT, rmx_rtt); 1140 metric(RTV_RTTVAR, rmx_rttvar); 1141 metric(RTV_HOPCOUNT, rmx_hopcount); 1142 metric(RTV_MTU, rmx_mtu); 1143 #undef metric 1144 if (which & RTV_EXPIRE) { 1145 out->rt_rmx.rmx_expire = in->rtm_rmx.rmx_expire ? 1146 time_wall_to_mono(in->rtm_rmx.rmx_expire) : 0; 1147 } 1148 } 1149 1150 static void 1151 rtm_setmetrics(const struct rtentry *in, struct rt_xmsghdr *out) 1152 { 1153 #define metric(e) out->rtm_rmx.e = in->rt_rmx.e; 1154 metric(rmx_recvpipe); 1155 metric(rmx_sendpipe); 1156 metric(rmx_ssthresh); 1157 metric(rmx_rtt); 1158 metric(rmx_rttvar); 1159 metric(rmx_hopcount); 1160 metric(rmx_mtu); 1161 metric(rmx_locks); 1162 #undef metric 1163 out->rtm_rmx.rmx_expire = in->rt_rmx.rmx_expire ? 1164 time_mono_to_wall(in->rt_rmx.rmx_expire) : 0; 1165 } 1166 1167 static int 1168 rt_xaddrs(u_char rtmtype, const char *cp, const char *cplim, 1169 struct rt_addrinfo *rtinfo) 1170 { 1171 const struct sockaddr *sa = NULL; /* Quell compiler warning */ 1172 int i; 1173 1174 for (i = 0; i < RTAX_MAX && cp < cplim; i++) { 1175 if ((rtinfo->rti_addrs & (1 << i)) == 0) 1176 continue; 1177 rtinfo->rti_info[i] = sa = (const struct sockaddr *)cp; 1178 RT_XADVANCE(cp, sa); 1179 } 1180 1181 /* 1182 * Check for extra addresses specified, except RTM_GET asking 1183 * for interface info. 1184 */ 1185 if (rtmtype == RTM_GET) { 1186 if (((rtinfo->rti_addrs & 1187 (~((1 << RTAX_IFP) | (1 << RTAX_IFA)))) & (~0U << i)) != 0) 1188 return 1; 1189 } else if ((rtinfo->rti_addrs & (~0U << i)) != 0) 1190 return 1; 1191 /* Check for bad data length. */ 1192 if (cp != cplim) { 1193 if (i == RTAX_NETMASK + 1 && sa != NULL && 1194 cp - RT_XROUNDUP(sa->sa_len) + sa->sa_len == cplim) 1195 /* 1196 * The last sockaddr was info.rti_info[RTAX_NETMASK]. 1197 * We accept this for now for the sake of old 1198 * binaries or third party softwares. 1199 */ 1200 ; 1201 else 1202 return 1; 1203 } 1204 return 0; 1205 } 1206 1207 static int 1208 rt_getlen(int type) 1209 { 1210 #ifndef COMPAT_RTSOCK 1211 CTASSERT(__alignof(struct ifa_msghdr) >= sizeof(uint64_t)); 1212 CTASSERT(__alignof(struct if_msghdr) >= sizeof(uint64_t)); 1213 CTASSERT(__alignof(struct if_announcemsghdr) >= sizeof(uint64_t)); 1214 CTASSERT(__alignof(struct rt_msghdr) >= sizeof(uint64_t)); 1215 #endif 1216 1217 switch (type) { 1218 case RTM_ODELADDR: 1219 case RTM_ONEWADDR: 1220 case RTM_OCHGADDR: 1221 #ifdef COMPAT_70 1222 return sizeof(struct ifa_msghdr70); 1223 #else 1224 #ifdef RTSOCK_DEBUG 1225 printf("%s: unsupported RTM type %d\n", __func__, type); 1226 #endif 1227 return -1; 1228 #endif 1229 case RTM_DELADDR: 1230 case RTM_NEWADDR: 1231 case RTM_CHGADDR: 1232 return sizeof(struct ifa_xmsghdr); 1233 1234 case RTM_OOIFINFO: 1235 #ifdef COMPAT_14 1236 return sizeof(struct if_msghdr14); 1237 #else 1238 #ifdef RTSOCK_DEBUG 1239 printf("%s: unsupported RTM type RTM_OOIFINFO\n", __func__); 1240 #endif 1241 return -1; 1242 #endif 1243 case RTM_OIFINFO: 1244 #ifdef COMPAT_50 1245 return sizeof(struct if_msghdr50); 1246 #else 1247 #ifdef RTSOCK_DEBUG 1248 printf("%s: unsupported RTM type RTM_OIFINFO\n", __func__); 1249 #endif 1250 return -1; 1251 #endif 1252 1253 case RTM_IFINFO: 1254 return sizeof(struct if_xmsghdr); 1255 1256 case RTM_IFANNOUNCE: 1257 case RTM_IEEE80211: 1258 return sizeof(struct if_xannouncemsghdr); 1259 1260 default: 1261 return sizeof(struct rt_xmsghdr); 1262 } 1263 } 1264 1265 1266 struct mbuf * 1267 COMPATNAME(rt_msg1)(int type, struct rt_addrinfo *rtinfo, void *data, int datalen) 1268 { 1269 struct rt_xmsghdr *rtm; 1270 struct mbuf *m; 1271 int i; 1272 const struct sockaddr *sa; 1273 int len, dlen; 1274 1275 m = m_gethdr(M_DONTWAIT, MT_DATA); 1276 if (m == NULL) 1277 return m; 1278 MCLAIM(m, &COMPATNAME(routedomain).dom_mowner); 1279 1280 if ((len = rt_getlen(type)) == -1) 1281 goto out; 1282 if (len > MHLEN + MLEN) 1283 panic("%s: message too long", __func__); 1284 else if (len > MHLEN) { 1285 m->m_next = m_get(M_DONTWAIT, MT_DATA); 1286 if (m->m_next == NULL) 1287 goto out; 1288 MCLAIM(m->m_next, m->m_owner); 1289 m->m_pkthdr.len = len; 1290 m->m_len = MHLEN; 1291 m->m_next->m_len = len - MHLEN; 1292 } else { 1293 m->m_pkthdr.len = m->m_len = len; 1294 } 1295 m_reset_rcvif(m); 1296 m_copyback(m, 0, datalen, data); 1297 if (len > datalen) 1298 (void)memset(mtod(m, char *) + datalen, 0, len - datalen); 1299 rtm = mtod(m, struct rt_xmsghdr *); 1300 for (i = 0; i < RTAX_MAX; i++) { 1301 if ((sa = rtinfo->rti_info[i]) == NULL) 1302 continue; 1303 rtinfo->rti_addrs |= (1 << i); 1304 dlen = RT_XROUNDUP(sa->sa_len); 1305 m_copyback(m, len, sa->sa_len, sa); 1306 if (dlen != sa->sa_len) { 1307 /* 1308 * Up to 6 + 1 nul's since roundup is to 1309 * sizeof(uint64_t) (8 bytes) 1310 */ 1311 m_copyback(m, len + sa->sa_len, 1312 dlen - sa->sa_len, "\0\0\0\0\0\0"); 1313 } 1314 len += dlen; 1315 } 1316 if (m->m_pkthdr.len != len) 1317 goto out; 1318 rtm->rtm_msglen = len; 1319 rtm->rtm_version = RTM_XVERSION; 1320 rtm->rtm_type = type; 1321 return m; 1322 out: 1323 m_freem(m); 1324 return NULL; 1325 } 1326 1327 /* 1328 * rt_msg2 1329 * 1330 * fills 'cp' or 'w'.w_tmem with the routing socket message and 1331 * returns the length of the message in 'lenp'. 1332 * 1333 * if walkarg is 0, cp is expected to be 0 or a buffer large enough to hold 1334 * the message 1335 * otherwise walkarg's w_needed is updated and if the user buffer is 1336 * specified and w_needed indicates space exists the information is copied 1337 * into the temp space (w_tmem). w_tmem is [re]allocated if necessary, 1338 * if the allocation fails ENOBUFS is returned. 1339 */ 1340 static int 1341 rt_msg2(int type, struct rt_addrinfo *rtinfo, void *cpv, struct rt_walkarg *w, 1342 int *lenp) 1343 { 1344 int i; 1345 int len, dlen, second_time = 0; 1346 char *cp0, *cp = cpv; 1347 1348 rtinfo->rti_addrs = 0; 1349 again: 1350 if ((len = rt_getlen(type)) == -1) 1351 return EINVAL; 1352 1353 if ((cp0 = cp) != NULL) 1354 cp += len; 1355 for (i = 0; i < RTAX_MAX; i++) { 1356 const struct sockaddr *sa; 1357 1358 if ((sa = rtinfo->rti_info[i]) == NULL) 1359 continue; 1360 rtinfo->rti_addrs |= (1 << i); 1361 dlen = RT_XROUNDUP(sa->sa_len); 1362 if (cp) { 1363 int diff = dlen - sa->sa_len; 1364 (void)memcpy(cp, sa, (size_t)sa->sa_len); 1365 cp += sa->sa_len; 1366 if (diff > 0) { 1367 (void)memset(cp, 0, (size_t)diff); 1368 cp += diff; 1369 } 1370 } 1371 len += dlen; 1372 } 1373 if (cp == NULL && w != NULL && !second_time) { 1374 struct rt_walkarg *rw = w; 1375 1376 rw->w_needed += len; 1377 if (rw->w_needed <= 0 && rw->w_where) { 1378 if (rw->w_tmemsize < len) { 1379 if (rw->w_tmem) 1380 kmem_free(rw->w_tmem, rw->w_tmemsize); 1381 rw->w_tmem = kmem_alloc(len, KM_SLEEP); 1382 rw->w_tmemsize = len; 1383 } 1384 if (rw->w_tmem) { 1385 cp = rw->w_tmem; 1386 second_time = 1; 1387 goto again; 1388 } else { 1389 rw->w_tmemneeded = len; 1390 return ENOBUFS; 1391 } 1392 } 1393 } 1394 if (cp) { 1395 struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)cp0; 1396 1397 rtm->rtm_version = RTM_XVERSION; 1398 rtm->rtm_type = type; 1399 rtm->rtm_msglen = len; 1400 } 1401 if (lenp) 1402 *lenp = len; 1403 return 0; 1404 } 1405 1406 #ifndef COMPAT_RTSOCK 1407 int 1408 rt_msg3(int type, struct rt_addrinfo *rtinfo, void *cpv, struct rt_walkarg *w, 1409 int *lenp) 1410 { 1411 return rt_msg2(type, rtinfo, cpv, w, lenp); 1412 } 1413 #endif 1414 1415 /* 1416 * This routine is called to generate a message from the routing 1417 * socket indicating that a redirect has occurred, a routing lookup 1418 * has failed, or that a protocol has detected timeouts to a particular 1419 * destination. 1420 */ 1421 void 1422 COMPATNAME(rt_missmsg)(int type, const struct rt_addrinfo *rtinfo, int flags, 1423 int error) 1424 { 1425 struct rt_xmsghdr rtm; 1426 struct mbuf *m; 1427 const struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 1428 struct rt_addrinfo info = *rtinfo; 1429 1430 COMPATCALL(rt_missmsg, (type, rtinfo, flags, error)); 1431 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1432 return; 1433 memset(&rtm, 0, sizeof(rtm)); 1434 rtm.rtm_pid = curproc->p_pid; 1435 rtm.rtm_flags = RTF_DONE | flags; 1436 rtm.rtm_errno = error; 1437 m = COMPATNAME(rt_msg1)(type, &info, &rtm, sizeof(rtm)); 1438 if (m == NULL) 1439 return; 1440 mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs; 1441 COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0); 1442 } 1443 1444 /* 1445 * This routine is called to generate a message from the routing 1446 * socket indicating that the status of a network interface has changed. 1447 */ 1448 void 1449 COMPATNAME(rt_ifmsg)(struct ifnet *ifp) 1450 { 1451 struct if_xmsghdr ifm; 1452 struct mbuf *m; 1453 struct rt_addrinfo info; 1454 1455 COMPATCALL(rt_ifmsg, (ifp)); 1456 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1457 return; 1458 (void)memset(&info, 0, sizeof(info)); 1459 (void)memset(&ifm, 0, sizeof(ifm)); 1460 ifm.ifm_index = ifp->if_index; 1461 ifm.ifm_flags = ifp->if_flags; 1462 ifm.ifm_data = ifp->if_data; 1463 ifm.ifm_addrs = 0; 1464 m = COMPATNAME(rt_msg1)(RTM_IFINFO, &info, &ifm, sizeof(ifm)); 1465 if (m == NULL) 1466 return; 1467 COMPATNAME(route_enqueue)(m, 0); 1468 #ifdef COMPAT_14 1469 compat_14_rt_oifmsg(ifp); 1470 #endif 1471 #ifdef COMPAT_50 1472 compat_50_rt_oifmsg(ifp); 1473 #endif 1474 } 1475 1476 #ifndef COMPAT_RTSOCK 1477 static int 1478 if_addrflags(struct ifaddr *ifa) 1479 { 1480 1481 switch (ifa->ifa_addr->sa_family) { 1482 #ifdef INET 1483 case AF_INET: 1484 return ((struct in_ifaddr *)ifa)->ia4_flags; 1485 #endif 1486 #ifdef INET6 1487 case AF_INET6: 1488 return ((struct in6_ifaddr *)ifa)->ia6_flags; 1489 #endif 1490 default: 1491 return 0; 1492 } 1493 } 1494 #endif 1495 1496 /* 1497 * This is called to generate messages from the routing socket 1498 * indicating a network interface has had addresses associated with it. 1499 * if we ever reverse the logic and replace messages TO the routing 1500 * socket indicate a request to configure interfaces, then it will 1501 * be unnecessary as the routing socket will automatically generate 1502 * copies of it. 1503 */ 1504 void 1505 COMPATNAME(rt_newaddrmsg)(int cmd, struct ifaddr *ifa, int error, 1506 struct rtentry *rt) 1507 { 1508 #define cmdpass(__cmd, __pass) (((__cmd) << 2) | (__pass)) 1509 struct rt_addrinfo info; 1510 const struct sockaddr *sa; 1511 int pass; 1512 struct mbuf *m; 1513 struct ifnet *ifp; 1514 struct rt_xmsghdr rtm; 1515 struct ifa_xmsghdr ifam; 1516 int ncmd; 1517 1518 KASSERT(ifa != NULL); 1519 KASSERT(ifa->ifa_addr != NULL); 1520 ifp = ifa->ifa_ifp; 1521 #ifdef SCTP 1522 if (cmd == RTM_ADD) { 1523 sctp_add_ip_address(ifa); 1524 } else if (cmd == RTM_DELETE) { 1525 sctp_delete_ip_address(ifa); 1526 } 1527 #endif 1528 1529 COMPATCALL(rt_newaddrmsg, (cmd, ifa, error, rt)); 1530 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1531 return; 1532 for (pass = 1; pass < 3; pass++) { 1533 memset(&info, 0, sizeof(info)); 1534 switch (cmdpass(cmd, pass)) { 1535 case cmdpass(RTM_ADD, 1): 1536 case cmdpass(RTM_CHANGE, 1): 1537 case cmdpass(RTM_DELETE, 2): 1538 case cmdpass(RTM_NEWADDR, 1): 1539 case cmdpass(RTM_DELADDR, 1): 1540 case cmdpass(RTM_CHGADDR, 1): 1541 switch (cmd) { 1542 case RTM_ADD: 1543 ncmd = RTM_XNEWADDR; 1544 break; 1545 case RTM_DELETE: 1546 ncmd = RTM_XDELADDR; 1547 break; 1548 case RTM_CHANGE: 1549 ncmd = RTM_XCHGADDR; 1550 break; 1551 case RTM_NEWADDR: 1552 ncmd = RTM_XNEWADDR; 1553 break; 1554 case RTM_DELADDR: 1555 ncmd = RTM_XDELADDR; 1556 break; 1557 case RTM_CHGADDR: 1558 ncmd = RTM_XCHGADDR; 1559 break; 1560 default: 1561 panic("%s: unknown command %d", __func__, cmd); 1562 } 1563 #ifdef COMPAT_70 1564 compat_70_rt_newaddrmsg1(ncmd, ifa); 1565 #endif 1566 info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; 1567 KASSERT(ifp->if_dl != NULL); 1568 info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; 1569 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1570 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1571 memset(&ifam, 0, sizeof(ifam)); 1572 ifam.ifam_index = ifp->if_index; 1573 ifam.ifam_metric = ifa->ifa_metric; 1574 ifam.ifam_flags = ifa->ifa_flags; 1575 #ifndef COMPAT_RTSOCK 1576 ifam.ifam_pid = curproc->p_pid; 1577 ifam.ifam_addrflags = if_addrflags(ifa); 1578 #endif 1579 m = COMPATNAME(rt_msg1)(ncmd, &info, &ifam, sizeof(ifam)); 1580 if (m == NULL) 1581 continue; 1582 mtod(m, struct ifa_xmsghdr *)->ifam_addrs = 1583 info.rti_addrs; 1584 break; 1585 case cmdpass(RTM_ADD, 2): 1586 case cmdpass(RTM_CHANGE, 2): 1587 case cmdpass(RTM_DELETE, 1): 1588 if (rt == NULL) 1589 continue; 1590 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1591 info.rti_info[RTAX_DST] = sa = rt_getkey(rt); 1592 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1593 memset(&rtm, 0, sizeof(rtm)); 1594 rtm.rtm_pid = curproc->p_pid; 1595 rtm.rtm_index = ifp->if_index; 1596 rtm.rtm_flags |= rt->rt_flags; 1597 rtm.rtm_errno = error; 1598 m = COMPATNAME(rt_msg1)(cmd, &info, &rtm, sizeof(rtm)); 1599 if (m == NULL) 1600 continue; 1601 mtod(m, struct rt_xmsghdr *)->rtm_addrs = info.rti_addrs; 1602 break; 1603 default: 1604 continue; 1605 } 1606 KASSERTMSG(m != NULL, "called with wrong command"); 1607 COMPATNAME(route_enqueue)(m, sa ? sa->sa_family : 0); 1608 } 1609 #undef cmdpass 1610 1611 } 1612 1613 static struct mbuf * 1614 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what, 1615 struct rt_addrinfo *info) 1616 { 1617 struct if_xannouncemsghdr ifan; 1618 1619 memset(info, 0, sizeof(*info)); 1620 memset(&ifan, 0, sizeof(ifan)); 1621 ifan.ifan_index = ifp->if_index; 1622 strlcpy(ifan.ifan_name, ifp->if_xname, sizeof(ifan.ifan_name)); 1623 ifan.ifan_what = what; 1624 return COMPATNAME(rt_msg1)(type, info, &ifan, sizeof(ifan)); 1625 } 1626 1627 /* 1628 * This is called to generate routing socket messages indicating 1629 * network interface arrival and departure. 1630 */ 1631 void 1632 COMPATNAME(rt_ifannouncemsg)(struct ifnet *ifp, int what) 1633 { 1634 struct mbuf *m; 1635 struct rt_addrinfo info; 1636 1637 COMPATCALL(rt_ifannouncemsg, (ifp, what)); 1638 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1639 return; 1640 m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info); 1641 if (m == NULL) 1642 return; 1643 COMPATNAME(route_enqueue)(m, 0); 1644 } 1645 1646 /* 1647 * This is called to generate routing socket messages indicating 1648 * IEEE80211 wireless events. 1649 * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way. 1650 */ 1651 void 1652 COMPATNAME(rt_ieee80211msg)(struct ifnet *ifp, int what, void *data, 1653 size_t data_len) 1654 { 1655 struct mbuf *m; 1656 struct rt_addrinfo info; 1657 1658 COMPATCALL(rt_ieee80211msg, (ifp, what, data, data_len)); 1659 if (COMPATNAME(route_info).ri_cb.any_count == 0) 1660 return; 1661 m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info); 1662 if (m == NULL) 1663 return; 1664 /* 1665 * Append the ieee80211 data. Try to stick it in the 1666 * mbuf containing the ifannounce msg; otherwise allocate 1667 * a new mbuf and append. 1668 * 1669 * NB: we assume m is a single mbuf. 1670 */ 1671 if (data_len > M_TRAILINGSPACE(m)) { 1672 struct mbuf *n = m_get(M_NOWAIT, MT_DATA); 1673 if (n == NULL) { 1674 m_freem(m); 1675 return; 1676 } 1677 (void)memcpy(mtod(n, void *), data, data_len); 1678 n->m_len = data_len; 1679 m->m_next = n; 1680 } else if (data_len > 0) { 1681 (void)memcpy(mtod(m, uint8_t *) + m->m_len, data, data_len); 1682 m->m_len += data_len; 1683 } 1684 if (m->m_flags & M_PKTHDR) 1685 m->m_pkthdr.len += data_len; 1686 mtod(m, struct if_xannouncemsghdr *)->ifan_msglen += data_len; 1687 COMPATNAME(route_enqueue)(m, 0); 1688 } 1689 1690 #ifndef COMPAT_RTSOCK 1691 /* 1692 * Send a routing message as mimicing that a cloned route is added. 1693 */ 1694 void 1695 rt_clonedmsg(const struct sockaddr *dst, const struct ifnet *ifp, 1696 const struct rtentry *rt) 1697 { 1698 struct rt_addrinfo info; 1699 /* Mimic flags exactly */ 1700 #define RTF_LLINFO 0x400 1701 #define RTF_CLONED 0x2000 1702 int flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_LLINFO | RTF_CLONED; 1703 union { 1704 struct sockaddr sa; 1705 struct sockaddr_storage ss; 1706 struct sockaddr_dl sdl; 1707 } u; 1708 uint8_t namelen = strlen(ifp->if_xname); 1709 uint8_t addrlen = ifp->if_addrlen; 1710 1711 if (rt == NULL) 1712 return; /* XXX */ 1713 1714 memset(&info, 0, sizeof(info)); 1715 info.rti_info[RTAX_DST] = dst; 1716 sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index, ifp->if_type, 1717 NULL, namelen, NULL, addrlen); 1718 info.rti_info[RTAX_GATEWAY] = &u.sa; 1719 1720 rt_missmsg(RTM_ADD, &info, flags, 0); 1721 #undef RTF_LLINFO 1722 #undef RTF_CLONED 1723 } 1724 #endif /* COMPAT_RTSOCK */ 1725 1726 /* 1727 * This is used in dumping the kernel table via sysctl(). 1728 */ 1729 static int 1730 sysctl_dumpentry(struct rtentry *rt, void *v) 1731 { 1732 struct rt_walkarg *w = v; 1733 int error = 0, size; 1734 struct rt_addrinfo info; 1735 1736 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1737 return 0; 1738 memset(&info, 0, sizeof(info)); 1739 info.rti_info[RTAX_DST] = rt_getkey(rt); 1740 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1741 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1742 info.rti_info[RTAX_TAG] = rt_gettag(rt); 1743 if (rt->rt_ifp) { 1744 const struct ifaddr *rtifa; 1745 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr; 1746 /* rtifa used to be simply rt->rt_ifa. If rt->rt_ifa != NULL, 1747 * then rt_get_ifa() != NULL. So this ought to still be safe. 1748 * --dyoung 1749 */ 1750 rtifa = rt_get_ifa(rt); 1751 info.rti_info[RTAX_IFA] = rtifa->ifa_addr; 1752 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1753 info.rti_info[RTAX_BRD] = rtifa->ifa_dstaddr; 1754 } 1755 if ((error = rt_msg2(RTM_GET, &info, 0, w, &size))) 1756 return error; 1757 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1758 struct rt_xmsghdr *rtm = (struct rt_xmsghdr *)w->w_tmem; 1759 1760 rtm->rtm_flags = rt->rt_flags; 1761 rtm->rtm_use = rt->rt_use; 1762 rtm_setmetrics(rt, rtm); 1763 KASSERT(rt->rt_ifp != NULL); 1764 rtm->rtm_index = rt->rt_ifp->if_index; 1765 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 1766 rtm->rtm_addrs = info.rti_addrs; 1767 if ((error = copyout(rtm, w->w_where, size)) != 0) 1768 w->w_where = NULL; 1769 else 1770 w->w_where = (char *)w->w_where + size; 1771 } 1772 return error; 1773 } 1774 1775 static int 1776 sysctl_iflist_if(struct ifnet *ifp, struct rt_walkarg *w, 1777 struct rt_addrinfo *info, size_t len) 1778 { 1779 struct if_xmsghdr *ifm; 1780 int error; 1781 1782 ifm = (struct if_xmsghdr *)w->w_tmem; 1783 ifm->ifm_index = ifp->if_index; 1784 ifm->ifm_flags = ifp->if_flags; 1785 ifm->ifm_data = ifp->if_data; 1786 ifm->ifm_addrs = info->rti_addrs; 1787 if ((error = copyout(ifm, w->w_where, len)) == 0) 1788 w->w_where = (char *)w->w_where + len; 1789 return error; 1790 } 1791 1792 static int 1793 sysctl_iflist_addr(struct rt_walkarg *w, struct ifaddr *ifa, 1794 struct rt_addrinfo *info) 1795 { 1796 int len, error; 1797 1798 if ((error = rt_msg2(RTM_XNEWADDR, info, 0, w, &len))) 1799 return error; 1800 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1801 struct ifa_xmsghdr *ifam; 1802 1803 ifam = (struct ifa_xmsghdr *)w->w_tmem; 1804 ifam->ifam_index = ifa->ifa_ifp->if_index; 1805 ifam->ifam_flags = ifa->ifa_flags; 1806 ifam->ifam_metric = ifa->ifa_metric; 1807 ifam->ifam_addrs = info->rti_addrs; 1808 #ifndef COMPAT_RTSOCK 1809 ifam->ifam_pid = 0; 1810 ifam->ifam_addrflags = if_addrflags(ifa); 1811 #endif 1812 if ((error = copyout(w->w_tmem, w->w_where, len)) == 0) 1813 w->w_where = (char *)w->w_where + len; 1814 } 1815 return error; 1816 } 1817 1818 static int 1819 sysctl_iflist(int af, struct rt_walkarg *w, int type) 1820 { 1821 struct ifnet *ifp; 1822 struct ifaddr *ifa; 1823 struct rt_addrinfo info; 1824 int cmd, len, error = 0; 1825 int (*iflist_if)(struct ifnet *, struct rt_walkarg *, 1826 struct rt_addrinfo *, size_t); 1827 int (*iflist_addr)(struct rt_walkarg *, struct ifaddr *, 1828 struct rt_addrinfo *); 1829 int s; 1830 struct psref psref; 1831 int bound; 1832 1833 switch (type) { 1834 case NET_RT_IFLIST: 1835 cmd = RTM_IFINFO; 1836 iflist_if = sysctl_iflist_if; 1837 iflist_addr = sysctl_iflist_addr; 1838 break; 1839 #ifdef COMPAT_14 1840 case NET_RT_OOOIFLIST: 1841 cmd = RTM_OOIFINFO; 1842 iflist_if = compat_14_iflist; 1843 iflist_addr = compat_70_iflist_addr; 1844 break; 1845 #endif 1846 #ifdef COMPAT_50 1847 case NET_RT_OOIFLIST: 1848 cmd = RTM_OIFINFO; 1849 iflist_if = compat_50_iflist; 1850 iflist_addr = compat_70_iflist_addr; 1851 break; 1852 #endif 1853 #ifdef COMPAT_70 1854 case NET_RT_OIFLIST: 1855 cmd = RTM_IFINFO; 1856 iflist_if = sysctl_iflist_if; 1857 iflist_addr = compat_70_iflist_addr; 1858 break; 1859 #endif 1860 default: 1861 #ifdef RTSOCK_DEBUG 1862 printf("%s: unsupported IFLIST type %d\n", __func__, type); 1863 #endif 1864 return EINVAL; 1865 } 1866 1867 memset(&info, 0, sizeof(info)); 1868 1869 bound = curlwp_bind(); 1870 s = pserialize_read_enter(); 1871 IFNET_READER_FOREACH(ifp) { 1872 int _s; 1873 if (w->w_arg && w->w_arg != ifp->if_index) 1874 continue; 1875 if (IFADDR_READER_EMPTY(ifp)) 1876 continue; 1877 1878 if_acquire(ifp, &psref); 1879 pserialize_read_exit(s); 1880 1881 info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; 1882 if ((error = rt_msg2(cmd, &info, NULL, w, &len)) != 0) 1883 goto release_exit; 1884 info.rti_info[RTAX_IFP] = NULL; 1885 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1886 if ((error = iflist_if(ifp, w, &info, len)) != 0) 1887 goto release_exit; 1888 } 1889 _s = pserialize_read_enter(); 1890 IFADDR_READER_FOREACH(ifa, ifp) { 1891 struct psref _psref; 1892 if (af && af != ifa->ifa_addr->sa_family) 1893 continue; 1894 ifa_acquire(ifa, &_psref); 1895 pserialize_read_exit(_s); 1896 1897 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1898 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1899 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1900 error = iflist_addr(w, ifa, &info); 1901 1902 _s = pserialize_read_enter(); 1903 ifa_release(ifa, &_psref); 1904 if (error != 0) { 1905 pserialize_read_exit(_s); 1906 goto release_exit; 1907 } 1908 } 1909 pserialize_read_exit(_s); 1910 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = 1911 info.rti_info[RTAX_BRD] = NULL; 1912 1913 s = pserialize_read_enter(); 1914 if_release(ifp, &psref); 1915 } 1916 pserialize_read_exit(s); 1917 curlwp_bindx(bound); 1918 1919 return 0; 1920 1921 release_exit: 1922 if_release(ifp, &psref); 1923 curlwp_bindx(bound); 1924 return error; 1925 } 1926 1927 static int 1928 sysctl_rtable(SYSCTLFN_ARGS) 1929 { 1930 void *where = oldp; 1931 size_t *given = oldlenp; 1932 int i, s, error = EINVAL; 1933 u_char af; 1934 struct rt_walkarg w; 1935 1936 if (namelen == 1 && name[0] == CTL_QUERY) 1937 return sysctl_query(SYSCTLFN_CALL(rnode)); 1938 1939 if (newp) 1940 return EPERM; 1941 if (namelen != 3) 1942 return EINVAL; 1943 af = name[0]; 1944 w.w_tmemneeded = 0; 1945 w.w_tmemsize = 0; 1946 w.w_tmem = NULL; 1947 again: 1948 /* we may return here if a later [re]alloc of the t_mem buffer fails */ 1949 if (w.w_tmemneeded) { 1950 w.w_tmem = kmem_alloc(w.w_tmemneeded, KM_SLEEP); 1951 w.w_tmemsize = w.w_tmemneeded; 1952 w.w_tmemneeded = 0; 1953 } 1954 w.w_op = name[1]; 1955 w.w_arg = name[2]; 1956 w.w_given = *given; 1957 w.w_needed = 0 - w.w_given; 1958 w.w_where = where; 1959 1960 s = splsoftnet(); 1961 switch (w.w_op) { 1962 1963 case NET_RT_DUMP: 1964 case NET_RT_FLAGS: 1965 #if defined(INET) || defined(INET6) 1966 /* 1967 * take care of llinfo entries, the caller must 1968 * specify an AF 1969 */ 1970 if (w.w_op == NET_RT_FLAGS && 1971 (w.w_arg == 0 || w.w_arg & RTF_LLDATA)) { 1972 if (af != 0) 1973 error = lltable_sysctl_dump(af, &w); 1974 else 1975 error = EINVAL; 1976 break; 1977 } 1978 #endif 1979 1980 for (i = 1; i <= AF_MAX; i++) { 1981 if (af == 0 || af == i) { 1982 error = rt_walktree(i, sysctl_dumpentry, &w); 1983 if (error != 0) 1984 break; 1985 #if defined(INET) || defined(INET6) 1986 /* 1987 * Return ARP/NDP entries too for 1988 * backward compatibility. 1989 */ 1990 error = lltable_sysctl_dump(i, &w); 1991 if (error != 0) 1992 break; 1993 #endif 1994 } 1995 } 1996 break; 1997 1998 #ifdef COMPAT_14 1999 case NET_RT_OOOIFLIST: 2000 error = sysctl_iflist(af, &w, w.w_op); 2001 break; 2002 #endif 2003 #ifdef COMPAT_50 2004 case NET_RT_OOIFLIST: 2005 error = sysctl_iflist(af, &w, w.w_op); 2006 break; 2007 #endif 2008 #ifdef COMPAT_70 2009 case NET_RT_OIFLIST: 2010 error = sysctl_iflist(af, &w, w.w_op); 2011 break; 2012 #endif 2013 case NET_RT_IFLIST: 2014 error = sysctl_iflist(af, &w, w.w_op); 2015 break; 2016 } 2017 splx(s); 2018 2019 /* check to see if we couldn't allocate memory with NOWAIT */ 2020 if (error == ENOBUFS && w.w_tmem == 0 && w.w_tmemneeded) 2021 goto again; 2022 2023 if (w.w_tmem) 2024 kmem_free(w.w_tmem, w.w_tmemsize); 2025 w.w_needed += w.w_given; 2026 if (where) { 2027 *given = (char *)w.w_where - (char *)where; 2028 if (*given < w.w_needed) 2029 return ENOMEM; 2030 } else { 2031 *given = (11 * w.w_needed) / 10; 2032 } 2033 return error; 2034 } 2035 2036 /* 2037 * Routing message software interrupt routine 2038 */ 2039 static void 2040 COMPATNAME(route_intr)(void *cookie) 2041 { 2042 struct sockproto proto = { .sp_family = PF_XROUTE, }; 2043 struct route_info * const ri = &COMPATNAME(route_info); 2044 struct mbuf *m; 2045 2046 SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); 2047 for (;;) { 2048 IFQ_LOCK(&ri->ri_intrq); 2049 IF_DEQUEUE(&ri->ri_intrq, m); 2050 IFQ_UNLOCK(&ri->ri_intrq); 2051 if (m == NULL) 2052 break; 2053 proto.sp_protocol = M_GETCTX(m, uintptr_t); 2054 #ifdef NET_MPSAFE 2055 mutex_enter(rt_so_mtx); 2056 #endif 2057 raw_input(m, &proto, &ri->ri_src, &ri->ri_dst, &rt_rawcb); 2058 #ifdef NET_MPSAFE 2059 mutex_exit(rt_so_mtx); 2060 #endif 2061 } 2062 SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 2063 } 2064 2065 /* 2066 * Enqueue a message to the software interrupt routine. 2067 */ 2068 void 2069 COMPATNAME(route_enqueue)(struct mbuf *m, int family) 2070 { 2071 struct route_info * const ri = &COMPATNAME(route_info); 2072 int wasempty; 2073 2074 IFQ_LOCK(&ri->ri_intrq); 2075 if (IF_QFULL(&ri->ri_intrq)) { 2076 IF_DROP(&ri->ri_intrq); 2077 IFQ_UNLOCK(&ri->ri_intrq); 2078 m_freem(m); 2079 } else { 2080 wasempty = IF_IS_EMPTY(&ri->ri_intrq); 2081 M_SETCTX(m, (uintptr_t)family); 2082 IF_ENQUEUE(&ri->ri_intrq, m); 2083 IFQ_UNLOCK(&ri->ri_intrq); 2084 if (wasempty) { 2085 kpreempt_disable(); 2086 softint_schedule(ri->ri_sih); 2087 kpreempt_enable(); 2088 } 2089 } 2090 } 2091 2092 static void 2093 COMPATNAME(route_init)(void) 2094 { 2095 struct route_info * const ri = &COMPATNAME(route_info); 2096 2097 #ifndef COMPAT_RTSOCK 2098 rt_init(); 2099 #endif 2100 #ifdef NET_MPSAFE 2101 rt_so_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 2102 #endif 2103 2104 sysctl_net_route_setup(NULL); 2105 ri->ri_intrq.ifq_maxlen = ri->ri_maxqlen; 2106 ri->ri_sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 2107 COMPATNAME(route_intr), NULL); 2108 IFQ_LOCK_INIT(&ri->ri_intrq); 2109 } 2110 2111 /* 2112 * Definitions of protocols supported in the ROUTE domain. 2113 */ 2114 #ifndef COMPAT_RTSOCK 2115 PR_WRAP_USRREQS(route); 2116 #else 2117 PR_WRAP_USRREQS(compat_50_route); 2118 #endif 2119 2120 static const struct pr_usrreqs route_usrreqs = { 2121 .pr_attach = COMPATNAME(route_attach_wrapper), 2122 .pr_detach = COMPATNAME(route_detach_wrapper), 2123 .pr_accept = COMPATNAME(route_accept_wrapper), 2124 .pr_bind = COMPATNAME(route_bind_wrapper), 2125 .pr_listen = COMPATNAME(route_listen_wrapper), 2126 .pr_connect = COMPATNAME(route_connect_wrapper), 2127 .pr_connect2 = COMPATNAME(route_connect2_wrapper), 2128 .pr_disconnect = COMPATNAME(route_disconnect_wrapper), 2129 .pr_shutdown = COMPATNAME(route_shutdown_wrapper), 2130 .pr_abort = COMPATNAME(route_abort_wrapper), 2131 .pr_ioctl = COMPATNAME(route_ioctl_wrapper), 2132 .pr_stat = COMPATNAME(route_stat_wrapper), 2133 .pr_peeraddr = COMPATNAME(route_peeraddr_wrapper), 2134 .pr_sockaddr = COMPATNAME(route_sockaddr_wrapper), 2135 .pr_rcvd = COMPATNAME(route_rcvd_wrapper), 2136 .pr_recvoob = COMPATNAME(route_recvoob_wrapper), 2137 .pr_send = COMPATNAME(route_send_wrapper), 2138 .pr_sendoob = COMPATNAME(route_sendoob_wrapper), 2139 .pr_purgeif = COMPATNAME(route_purgeif_wrapper), 2140 }; 2141 2142 static const struct protosw COMPATNAME(route_protosw)[] = { 2143 { 2144 .pr_type = SOCK_RAW, 2145 .pr_domain = &COMPATNAME(routedomain), 2146 .pr_flags = PR_ATOMIC|PR_ADDR, 2147 .pr_input = raw_input, 2148 .pr_ctlinput = raw_ctlinput, 2149 .pr_ctloutput = route_ctloutput, 2150 .pr_usrreqs = &route_usrreqs, 2151 .pr_init = rt_pr_init, 2152 }, 2153 }; 2154 2155 struct domain COMPATNAME(routedomain) = { 2156 .dom_family = PF_XROUTE, 2157 .dom_name = DOMAINNAME, 2158 .dom_init = COMPATNAME(route_init), 2159 .dom_protosw = COMPATNAME(route_protosw), 2160 .dom_protoswNPROTOSW = 2161 &COMPATNAME(route_protosw)[__arraycount(COMPATNAME(route_protosw))], 2162 }; 2163 2164 static void 2165 sysctl_net_route_setup(struct sysctllog **clog) 2166 { 2167 const struct sysctlnode *rnode = NULL; 2168 2169 sysctl_createv(clog, 0, NULL, &rnode, 2170 CTLFLAG_PERMANENT, 2171 CTLTYPE_NODE, DOMAINNAME, 2172 SYSCTL_DESCR("PF_ROUTE information"), 2173 NULL, 0, NULL, 0, 2174 CTL_NET, PF_XROUTE, CTL_EOL); 2175 2176 sysctl_createv(clog, 0, NULL, NULL, 2177 CTLFLAG_PERMANENT, 2178 CTLTYPE_NODE, "rtable", 2179 SYSCTL_DESCR("Routing table information"), 2180 sysctl_rtable, 0, NULL, 0, 2181 CTL_NET, PF_XROUTE, 0 /* any protocol */, CTL_EOL); 2182 2183 sysctl_createv(clog, 0, &rnode, NULL, 2184 CTLFLAG_PERMANENT, 2185 CTLTYPE_STRUCT, "stats", 2186 SYSCTL_DESCR("Routing statistics"), 2187 NULL, 0, &rtstat, sizeof(rtstat), 2188 CTL_CREATE, CTL_EOL); 2189 } 2190