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