1 /*- 2 * Copyright (c) 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)rtsock.c 8.7 (Berkeley) 10/12/95 30 * $FreeBSD$ 31 */ 32 #include "opt_sctp.h" 33 #include "opt_mpath.h" 34 #include "opt_route.h" 35 #include "opt_inet.h" 36 #include "opt_inet6.h" 37 38 #include <sys/param.h> 39 #include <sys/domain.h> 40 #include <sys/jail.h> 41 #include <sys/kernel.h> 42 #include <sys/lock.h> 43 #include <sys/malloc.h> 44 #include <sys/mbuf.h> 45 #include <sys/priv.h> 46 #include <sys/proc.h> 47 #include <sys/protosw.h> 48 #include <sys/rwlock.h> 49 #include <sys/signalvar.h> 50 #include <sys/socket.h> 51 #include <sys/socketvar.h> 52 #include <sys/sysctl.h> 53 #include <sys/systm.h> 54 #include <sys/vimage.h> 55 56 #include <net/if.h> 57 #include <net/if_dl.h> 58 #include <net/if_llatbl.h> 59 #include <net/netisr.h> 60 #include <net/raw_cb.h> 61 #include <net/route.h> 62 #include <net/vnet.h> 63 64 #include <netinet/in.h> 65 #ifdef INET6 66 #include <netinet6/scope6_var.h> 67 #endif 68 69 #ifdef SCTP 70 extern void sctp_addr_change(struct ifaddr *ifa, int cmd); 71 #endif /* SCTP */ 72 73 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables"); 74 75 /* NB: these are not modified */ 76 static struct sockaddr route_src = { 2, PF_ROUTE, }; 77 static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, }; 78 79 static struct { 80 int ip_count; /* attached w/ AF_INET */ 81 int ip6_count; /* attached w/ AF_INET6 */ 82 int ipx_count; /* attached w/ AF_IPX */ 83 int any_count; /* total attached */ 84 } route_cb; 85 86 struct mtx rtsock_mtx; 87 MTX_SYSINIT(rtsock, &rtsock_mtx, "rtsock route_cb lock", MTX_DEF); 88 89 #define RTSOCK_LOCK() mtx_lock(&rtsock_mtx) 90 #define RTSOCK_UNLOCK() mtx_unlock(&rtsock_mtx) 91 #define RTSOCK_LOCK_ASSERT() mtx_assert(&rtsock_mtx, MA_OWNED) 92 93 static struct ifqueue rtsintrq; 94 95 SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD, 0, ""); 96 SYSCTL_INT(_net_route, OID_AUTO, netisr_maxqlen, CTLFLAG_RW, 97 &rtsintrq.ifq_maxlen, 0, "maximum routing socket dispatch queue length"); 98 99 struct walkarg { 100 int w_tmemsize; 101 int w_op, w_arg; 102 caddr_t w_tmem; 103 struct sysctl_req *w_req; 104 }; 105 106 static void rts_input(struct mbuf *m); 107 static struct mbuf *rt_msg1(int type, struct rt_addrinfo *rtinfo); 108 static int rt_msg2(int type, struct rt_addrinfo *rtinfo, 109 caddr_t cp, struct walkarg *w); 110 static int rt_xaddrs(caddr_t cp, caddr_t cplim, 111 struct rt_addrinfo *rtinfo); 112 static int sysctl_dumpentry(struct radix_node *rn, void *vw); 113 static int sysctl_iflist(int af, struct walkarg *w); 114 static int sysctl_ifmalist(int af, struct walkarg *w); 115 static int route_output(struct mbuf *m, struct socket *so); 116 static void rt_setmetrics(u_long which, const struct rt_metrics *in, 117 struct rt_metrics_lite *out); 118 static void rt_getmetrics(const struct rt_metrics_lite *in, 119 struct rt_metrics *out); 120 static void rt_dispatch(struct mbuf *, const struct sockaddr *); 121 122 static void 123 rts_init(void) 124 { 125 int tmp; 126 127 rtsintrq.ifq_maxlen = 256; 128 if (TUNABLE_INT_FETCH("net.route.netisr_maxqlen", &tmp)) 129 rtsintrq.ifq_maxlen = tmp; 130 mtx_init(&rtsintrq.ifq_mtx, "rts_inq", NULL, MTX_DEF); 131 netisr_register(NETISR_ROUTE, rts_input, &rtsintrq, 0); 132 } 133 SYSINIT(rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rts_init, 0); 134 135 static void 136 rts_input(struct mbuf *m) 137 { 138 struct sockproto route_proto; 139 unsigned short *family; 140 struct m_tag *tag; 141 142 route_proto.sp_family = PF_ROUTE; 143 tag = m_tag_find(m, PACKET_TAG_RTSOCKFAM, NULL); 144 if (tag != NULL) { 145 family = (unsigned short *)(tag + 1); 146 route_proto.sp_protocol = *family; 147 m_tag_delete(m, tag); 148 } else 149 route_proto.sp_protocol = 0; 150 151 raw_input(m, &route_proto, &route_src); 152 } 153 154 /* 155 * It really doesn't make any sense at all for this code to share much 156 * with raw_usrreq.c, since its functionality is so restricted. XXX 157 */ 158 static void 159 rts_abort(struct socket *so) 160 { 161 162 raw_usrreqs.pru_abort(so); 163 } 164 165 static void 166 rts_close(struct socket *so) 167 { 168 169 raw_usrreqs.pru_close(so); 170 } 171 172 /* pru_accept is EOPNOTSUPP */ 173 174 static int 175 rts_attach(struct socket *so, int proto, struct thread *td) 176 { 177 struct rawcb *rp; 178 int s, error; 179 180 KASSERT(so->so_pcb == NULL, ("rts_attach: so_pcb != NULL")); 181 182 /* XXX */ 183 rp = malloc(sizeof *rp, M_PCB, M_WAITOK | M_ZERO); 184 if (rp == NULL) 185 return ENOBUFS; 186 187 /* 188 * The splnet() is necessary to block protocols from sending 189 * error notifications (like RTM_REDIRECT or RTM_LOSING) while 190 * this PCB is extant but incompletely initialized. 191 * Probably we should try to do more of this work beforehand and 192 * eliminate the spl. 193 */ 194 s = splnet(); 195 so->so_pcb = (caddr_t)rp; 196 so->so_fibnum = td->td_proc->p_fibnum; 197 error = raw_attach(so, proto); 198 rp = sotorawcb(so); 199 if (error) { 200 splx(s); 201 so->so_pcb = NULL; 202 free(rp, M_PCB); 203 return error; 204 } 205 RTSOCK_LOCK(); 206 switch(rp->rcb_proto.sp_protocol) { 207 case AF_INET: 208 route_cb.ip_count++; 209 break; 210 case AF_INET6: 211 route_cb.ip6_count++; 212 break; 213 case AF_IPX: 214 route_cb.ipx_count++; 215 break; 216 } 217 route_cb.any_count++; 218 RTSOCK_UNLOCK(); 219 soisconnected(so); 220 so->so_options |= SO_USELOOPBACK; 221 splx(s); 222 return 0; 223 } 224 225 static int 226 rts_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 227 { 228 229 return (raw_usrreqs.pru_bind(so, nam, td)); /* xxx just EINVAL */ 230 } 231 232 static int 233 rts_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 234 { 235 236 return (raw_usrreqs.pru_connect(so, nam, td)); /* XXX just EINVAL */ 237 } 238 239 /* pru_connect2 is EOPNOTSUPP */ 240 /* pru_control is EOPNOTSUPP */ 241 242 static void 243 rts_detach(struct socket *so) 244 { 245 struct rawcb *rp = sotorawcb(so); 246 247 KASSERT(rp != NULL, ("rts_detach: rp == NULL")); 248 249 RTSOCK_LOCK(); 250 switch(rp->rcb_proto.sp_protocol) { 251 case AF_INET: 252 route_cb.ip_count--; 253 break; 254 case AF_INET6: 255 route_cb.ip6_count--; 256 break; 257 case AF_IPX: 258 route_cb.ipx_count--; 259 break; 260 } 261 route_cb.any_count--; 262 RTSOCK_UNLOCK(); 263 raw_usrreqs.pru_detach(so); 264 } 265 266 static int 267 rts_disconnect(struct socket *so) 268 { 269 270 return (raw_usrreqs.pru_disconnect(so)); 271 } 272 273 /* pru_listen is EOPNOTSUPP */ 274 275 static int 276 rts_peeraddr(struct socket *so, struct sockaddr **nam) 277 { 278 279 return (raw_usrreqs.pru_peeraddr(so, nam)); 280 } 281 282 /* pru_rcvd is EOPNOTSUPP */ 283 /* pru_rcvoob is EOPNOTSUPP */ 284 285 static int 286 rts_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 287 struct mbuf *control, struct thread *td) 288 { 289 290 return (raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 291 } 292 293 /* pru_sense is null */ 294 295 static int 296 rts_shutdown(struct socket *so) 297 { 298 299 return (raw_usrreqs.pru_shutdown(so)); 300 } 301 302 static int 303 rts_sockaddr(struct socket *so, struct sockaddr **nam) 304 { 305 306 return (raw_usrreqs.pru_sockaddr(so, nam)); 307 } 308 309 static struct pr_usrreqs route_usrreqs = { 310 .pru_abort = rts_abort, 311 .pru_attach = rts_attach, 312 .pru_bind = rts_bind, 313 .pru_connect = rts_connect, 314 .pru_detach = rts_detach, 315 .pru_disconnect = rts_disconnect, 316 .pru_peeraddr = rts_peeraddr, 317 .pru_send = rts_send, 318 .pru_shutdown = rts_shutdown, 319 .pru_sockaddr = rts_sockaddr, 320 .pru_close = rts_close, 321 }; 322 323 #ifndef _SOCKADDR_UNION_DEFINED 324 #define _SOCKADDR_UNION_DEFINED 325 /* 326 * The union of all possible address formats we handle. 327 */ 328 union sockaddr_union { 329 struct sockaddr sa; 330 struct sockaddr_in sin; 331 struct sockaddr_in6 sin6; 332 }; 333 #endif /* _SOCKADDR_UNION_DEFINED */ 334 335 static int 336 rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp, 337 struct rtentry *rt, union sockaddr_union *saun, struct ucred *cred) 338 { 339 340 switch (info->rti_info[RTAX_DST]->sa_family) { 341 #ifdef INET 342 case AF_INET: 343 { 344 struct in_addr ia; 345 346 /* 347 * 1. Check if the returned address is part of the jail. 348 */ 349 ia = ((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->sin_addr; 350 if (prison_check_ip4(cred, &ia) != 0) { 351 info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 352 353 } else { 354 struct ifaddr *ifa; 355 int found; 356 357 found = 0; 358 359 /* 360 * 2. Try to find an address on the given outgoing 361 * interface that belongs to the jail. 362 */ 363 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 364 struct sockaddr *sa; 365 sa = ifa->ifa_addr; 366 if (sa->sa_family != AF_INET) 367 continue; 368 ia = ((struct sockaddr_in *)sa)->sin_addr; 369 if (prison_check_ip4(cred, &ia) != 0) { 370 found = 1; 371 break; 372 } 373 } 374 if (!found) { 375 /* 376 * 3. As a last resort return the 'default' 377 * jail address. 378 */ 379 if (prison_getip4(cred, &ia) != 0) 380 return (ESRCH); 381 } 382 bzero(&saun->sin, sizeof(struct sockaddr_in)); 383 saun->sin.sin_len = sizeof(struct sockaddr_in); 384 saun->sin.sin_family = AF_INET; 385 saun->sin.sin_addr.s_addr = ia.s_addr; 386 info->rti_info[RTAX_IFA] = 387 (struct sockaddr *)&saun->sin; 388 } 389 break; 390 } 391 #endif 392 #ifdef INET6 393 case AF_INET6: 394 { 395 struct in6_addr ia6; 396 397 /* 398 * 1. Check if the returned address is part of the jail. 399 */ 400 bcopy(&((struct sockaddr_in6 *)rt->rt_ifa->ifa_addr)->sin6_addr, 401 &ia6, sizeof(struct in6_addr)); 402 if (prison_check_ip6(cred, &ia6) != 0) { 403 info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 404 } else { 405 struct ifaddr *ifa; 406 int found; 407 408 found = 0; 409 410 /* 411 * 2. Try to find an address on the given outgoing 412 * interface that belongs to the jail. 413 */ 414 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 415 struct sockaddr *sa; 416 sa = ifa->ifa_addr; 417 if (sa->sa_family != AF_INET6) 418 continue; 419 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 420 &ia6, sizeof(struct in6_addr)); 421 if (prison_check_ip6(cred, &ia6) != 0) { 422 found = 1; 423 break; 424 } 425 } 426 if (!found) { 427 /* 428 * 3. As a last resort return the 'default' 429 * jail address. 430 */ 431 if (prison_getip6(cred, &ia6) != 0) 432 return (ESRCH); 433 } 434 bzero(&saun->sin6, sizeof(struct sockaddr_in6)); 435 saun->sin6.sin6_len = sizeof(struct sockaddr_in6); 436 saun->sin6.sin6_family = AF_INET6; 437 bcopy(&ia6, &saun->sin6.sin6_addr, 438 sizeof(struct in6_addr)); 439 if (sa6_recoverscope(&saun->sin6) != 0) 440 return (ESRCH); 441 info->rti_info[RTAX_IFA] = 442 (struct sockaddr *)&saun->sin6; 443 } 444 break; 445 } 446 #endif 447 default: 448 return (ESRCH); 449 } 450 return (0); 451 } 452 453 /*ARGSUSED*/ 454 static int 455 route_output(struct mbuf *m, struct socket *so) 456 { 457 #define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) 458 INIT_VNET_NET(so->so_vnet); 459 struct rt_msghdr *rtm = NULL; 460 struct rtentry *rt = NULL; 461 struct radix_node_head *rnh; 462 struct rt_addrinfo info; 463 int len, error = 0; 464 struct ifnet *ifp = NULL; 465 union sockaddr_union saun; 466 467 #define senderr(e) { error = e; goto flush;} 468 if (m == NULL || ((m->m_len < sizeof(long)) && 469 (m = m_pullup(m, sizeof(long))) == NULL)) 470 return (ENOBUFS); 471 if ((m->m_flags & M_PKTHDR) == 0) 472 panic("route_output"); 473 len = m->m_pkthdr.len; 474 if (len < sizeof(*rtm) || 475 len != mtod(m, struct rt_msghdr *)->rtm_msglen) { 476 info.rti_info[RTAX_DST] = NULL; 477 senderr(EINVAL); 478 } 479 R_Malloc(rtm, struct rt_msghdr *, len); 480 if (rtm == NULL) { 481 info.rti_info[RTAX_DST] = NULL; 482 senderr(ENOBUFS); 483 } 484 m_copydata(m, 0, len, (caddr_t)rtm); 485 if (rtm->rtm_version != RTM_VERSION) { 486 info.rti_info[RTAX_DST] = NULL; 487 senderr(EPROTONOSUPPORT); 488 } 489 rtm->rtm_pid = curproc->p_pid; 490 bzero(&info, sizeof(info)); 491 info.rti_addrs = rtm->rtm_addrs; 492 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 493 info.rti_info[RTAX_DST] = NULL; 494 senderr(EINVAL); 495 } 496 info.rti_flags = rtm->rtm_flags; 497 if (info.rti_info[RTAX_DST] == NULL || 498 info.rti_info[RTAX_DST]->sa_family >= AF_MAX || 499 (info.rti_info[RTAX_GATEWAY] != NULL && 500 info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) 501 senderr(EINVAL); 502 /* 503 * Verify that the caller has the appropriate privilege; RTM_GET 504 * is the only operation the non-superuser is allowed. 505 */ 506 if (rtm->rtm_type != RTM_GET) { 507 error = priv_check(curthread, PRIV_NET_ROUTE); 508 if (error) 509 senderr(error); 510 } 511 512 switch (rtm->rtm_type) { 513 struct rtentry *saved_nrt; 514 515 case RTM_ADD: 516 if (info.rti_info[RTAX_GATEWAY] == NULL) 517 senderr(EINVAL); 518 saved_nrt = NULL; 519 520 /* support for new ARP code */ 521 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && 522 (rtm->rtm_flags & RTF_LLDATA) != 0) { 523 error = lla_rt_output(rtm, &info); 524 break; 525 } 526 error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt, 527 so->so_fibnum); 528 if (error == 0 && saved_nrt) { 529 RT_LOCK(saved_nrt); 530 rt_setmetrics(rtm->rtm_inits, 531 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 532 rtm->rtm_index = saved_nrt->rt_ifp->if_index; 533 RT_REMREF(saved_nrt); 534 RT_UNLOCK(saved_nrt); 535 } 536 break; 537 538 case RTM_DELETE: 539 saved_nrt = NULL; 540 /* support for new ARP code */ 541 if (info.rti_info[RTAX_GATEWAY] && 542 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 543 (rtm->rtm_flags & RTF_LLDATA) != 0) { 544 error = lla_rt_output(rtm, &info); 545 break; 546 } 547 error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, 548 so->so_fibnum); 549 if (error == 0) { 550 RT_LOCK(saved_nrt); 551 rt = saved_nrt; 552 goto report; 553 } 554 break; 555 556 case RTM_GET: 557 case RTM_CHANGE: 558 case RTM_LOCK: 559 rnh = V_rt_tables[so->so_fibnum][info.rti_info[RTAX_DST]->sa_family]; 560 if (rnh == NULL) 561 senderr(EAFNOSUPPORT); 562 RADIX_NODE_HEAD_RLOCK(rnh); 563 rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST], 564 info.rti_info[RTAX_NETMASK], rnh); 565 if (rt == NULL) { /* XXX looks bogus */ 566 RADIX_NODE_HEAD_RUNLOCK(rnh); 567 senderr(ESRCH); 568 } 569 #ifdef RADIX_MPATH 570 /* 571 * for RTM_CHANGE/LOCK, if we got multipath routes, 572 * we require users to specify a matching RTAX_GATEWAY. 573 * 574 * for RTM_GET, gate is optional even with multipath. 575 * if gate == NULL the first match is returned. 576 * (no need to call rt_mpath_matchgate if gate == NULL) 577 */ 578 if (rn_mpath_capable(rnh) && 579 (rtm->rtm_type != RTM_GET || info.rti_info[RTAX_GATEWAY])) { 580 rt = rt_mpath_matchgate(rt, info.rti_info[RTAX_GATEWAY]); 581 if (!rt) { 582 RADIX_NODE_HEAD_RUNLOCK(rnh); 583 senderr(ESRCH); 584 } 585 } 586 #endif 587 RT_LOCK(rt); 588 RT_ADDREF(rt); 589 RADIX_NODE_HEAD_RUNLOCK(rnh); 590 591 /* 592 * Fix for PR: 82974 593 * 594 * RTM_CHANGE/LOCK need a perfect match, rn_lookup() 595 * returns a perfect match in case a netmask is 596 * specified. For host routes only a longest prefix 597 * match is returned so it is necessary to compare the 598 * existence of the netmask. If both have a netmask 599 * rnh_lookup() did a perfect match and if none of them 600 * have a netmask both are host routes which is also a 601 * perfect match. 602 */ 603 604 if (rtm->rtm_type != RTM_GET && 605 (!rt_mask(rt) != !info.rti_info[RTAX_NETMASK])) { 606 RT_UNLOCK(rt); 607 senderr(ESRCH); 608 } 609 610 switch(rtm->rtm_type) { 611 612 case RTM_GET: 613 report: 614 RT_LOCK_ASSERT(rt); 615 if (jailed(curthread->td_ucred) && 616 ((rt->rt_flags & RTF_HOST) == 0 || 617 !prison_if(curthread->td_ucred, rt_key(rt)))) { 618 RT_UNLOCK(rt); 619 senderr(ESRCH); 620 } 621 info.rti_info[RTAX_DST] = rt_key(rt); 622 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 623 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 624 info.rti_info[RTAX_GENMASK] = 0; 625 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 626 ifp = rt->rt_ifp; 627 if (ifp) { 628 info.rti_info[RTAX_IFP] = 629 ifp->if_addr->ifa_addr; 630 if (jailed(curthread->td_ucred)) { 631 error = rtm_get_jailed( 632 &info, ifp, rt, &saun, 633 curthread->td_ucred); 634 if (error != 0) { 635 RT_UNLOCK(rt); 636 senderr(ESRCH); 637 } 638 } else { 639 info.rti_info[RTAX_IFA] = 640 rt->rt_ifa->ifa_addr; 641 } 642 if (ifp->if_flags & IFF_POINTOPOINT) 643 info.rti_info[RTAX_BRD] = 644 rt->rt_ifa->ifa_dstaddr; 645 rtm->rtm_index = ifp->if_index; 646 } else { 647 info.rti_info[RTAX_IFP] = NULL; 648 info.rti_info[RTAX_IFA] = NULL; 649 } 650 } else if ((ifp = rt->rt_ifp) != NULL) { 651 rtm->rtm_index = ifp->if_index; 652 } 653 len = rt_msg2(rtm->rtm_type, &info, NULL, NULL); 654 if (len > rtm->rtm_msglen) { 655 struct rt_msghdr *new_rtm; 656 R_Malloc(new_rtm, struct rt_msghdr *, len); 657 if (new_rtm == NULL) { 658 RT_UNLOCK(rt); 659 senderr(ENOBUFS); 660 } 661 bcopy(rtm, new_rtm, rtm->rtm_msglen); 662 Free(rtm); rtm = new_rtm; 663 } 664 (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL); 665 rtm->rtm_flags = rt->rt_flags; 666 rtm->rtm_use = 0; 667 rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 668 rtm->rtm_addrs = info.rti_addrs; 669 break; 670 671 case RTM_CHANGE: 672 /* 673 * New gateway could require new ifaddr, ifp; 674 * flags may also be different; ifp may be specified 675 * by ll sockaddr when protocol address is ambiguous 676 */ 677 if (((rt->rt_flags & RTF_GATEWAY) && 678 info.rti_info[RTAX_GATEWAY] != NULL) || 679 info.rti_info[RTAX_IFP] != NULL || 680 (info.rti_info[RTAX_IFA] != NULL && 681 !sa_equal(info.rti_info[RTAX_IFA], 682 rt->rt_ifa->ifa_addr))) { 683 RT_UNLOCK(rt); 684 RADIX_NODE_HEAD_LOCK(rnh); 685 error = rt_getifa_fib(&info, rt->rt_fibnum); 686 RADIX_NODE_HEAD_UNLOCK(rnh); 687 if (error != 0) 688 senderr(error); 689 RT_LOCK(rt); 690 } 691 if (info.rti_ifa != NULL && 692 info.rti_ifa != rt->rt_ifa && 693 rt->rt_ifa != NULL && 694 rt->rt_ifa->ifa_rtrequest != NULL) { 695 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, 696 &info); 697 IFAFREE(rt->rt_ifa); 698 } 699 if (info.rti_info[RTAX_GATEWAY] != NULL) { 700 RT_UNLOCK(rt); 701 RADIX_NODE_HEAD_LOCK(rnh); 702 RT_LOCK(rt); 703 704 error = rt_setgate(rt, rt_key(rt), 705 info.rti_info[RTAX_GATEWAY]); 706 RADIX_NODE_HEAD_UNLOCK(rnh); 707 if (error != 0) { 708 RT_UNLOCK(rt); 709 senderr(error); 710 } 711 rt->rt_flags |= RTF_GATEWAY; 712 } 713 if (info.rti_ifa != NULL && 714 info.rti_ifa != rt->rt_ifa) { 715 IFAREF(info.rti_ifa); 716 rt->rt_ifa = info.rti_ifa; 717 rt->rt_ifp = info.rti_ifp; 718 } 719 /* Allow some flags to be toggled on change. */ 720 if (rtm->rtm_fmask & RTF_FMASK) 721 rt->rt_flags = (rt->rt_flags & 722 ~rtm->rtm_fmask) | 723 (rtm->rtm_flags & rtm->rtm_fmask); 724 rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 725 &rt->rt_rmx); 726 rtm->rtm_index = rt->rt_ifp->if_index; 727 if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) 728 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); 729 /* FALLTHROUGH */ 730 case RTM_LOCK: 731 /* We don't support locks anymore */ 732 break; 733 } 734 RT_UNLOCK(rt); 735 break; 736 737 default: 738 senderr(EOPNOTSUPP); 739 } 740 741 flush: 742 if (rtm) { 743 if (error) 744 rtm->rtm_errno = error; 745 else 746 rtm->rtm_flags |= RTF_DONE; 747 } 748 if (rt) /* XXX can this be true? */ 749 RTFREE(rt); 750 { 751 struct rawcb *rp = NULL; 752 /* 753 * Check to see if we don't want our own messages. 754 */ 755 if ((so->so_options & SO_USELOOPBACK) == 0) { 756 if (route_cb.any_count <= 1) { 757 if (rtm) 758 Free(rtm); 759 m_freem(m); 760 return (error); 761 } 762 /* There is another listener, so construct message */ 763 rp = sotorawcb(so); 764 } 765 if (rtm) { 766 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 767 if (m->m_pkthdr.len < rtm->rtm_msglen) { 768 m_freem(m); 769 m = NULL; 770 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 771 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 772 Free(rtm); 773 } 774 if (m) { 775 if (rp) { 776 /* 777 * XXX insure we don't get a copy by 778 * invalidating our protocol 779 */ 780 unsigned short family = rp->rcb_proto.sp_family; 781 rp->rcb_proto.sp_family = 0; 782 rt_dispatch(m, info.rti_info[RTAX_DST]); 783 rp->rcb_proto.sp_family = family; 784 } else 785 rt_dispatch(m, info.rti_info[RTAX_DST]); 786 } 787 } 788 return (error); 789 #undef sa_equal 790 } 791 792 static void 793 rt_setmetrics(u_long which, const struct rt_metrics *in, 794 struct rt_metrics_lite *out) 795 { 796 #define metric(f, e) if (which & (f)) out->e = in->e; 797 /* 798 * Only these are stored in the routing entry since introduction 799 * of tcp hostcache. The rest is ignored. 800 */ 801 metric(RTV_MTU, rmx_mtu); 802 /* Userland -> kernel timebase conversion. */ 803 if (which & RTV_EXPIRE) 804 out->rmx_expire = in->rmx_expire ? 805 in->rmx_expire - time_second + time_uptime : 0; 806 #undef metric 807 } 808 809 static void 810 rt_getmetrics(const struct rt_metrics_lite *in, struct rt_metrics *out) 811 { 812 #define metric(e) out->e = in->e; 813 bzero(out, sizeof(*out)); 814 metric(rmx_mtu); 815 /* Kernel -> userland timebase conversion. */ 816 out->rmx_expire = in->rmx_expire ? 817 in->rmx_expire - time_uptime + time_second : 0; 818 #undef metric 819 } 820 821 /* 822 * Extract the addresses of the passed sockaddrs. 823 * Do a little sanity checking so as to avoid bad memory references. 824 * This data is derived straight from userland. 825 */ 826 static int 827 rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) 828 { 829 struct sockaddr *sa; 830 int i; 831 832 for (i = 0; i < RTAX_MAX && cp < cplim; i++) { 833 if ((rtinfo->rti_addrs & (1 << i)) == 0) 834 continue; 835 sa = (struct sockaddr *)cp; 836 /* 837 * It won't fit. 838 */ 839 if (cp + sa->sa_len > cplim) 840 return (EINVAL); 841 /* 842 * there are no more.. quit now 843 * If there are more bits, they are in error. 844 * I've seen this. route(1) can evidently generate these. 845 * This causes kernel to core dump. 846 * for compatibility, If we see this, point to a safe address. 847 */ 848 if (sa->sa_len == 0) { 849 rtinfo->rti_info[i] = &sa_zero; 850 return (0); /* should be EINVAL but for compat */ 851 } 852 /* accept it */ 853 rtinfo->rti_info[i] = sa; 854 cp += SA_SIZE(sa); 855 } 856 return (0); 857 } 858 859 static struct mbuf * 860 rt_msg1(int type, struct rt_addrinfo *rtinfo) 861 { 862 struct rt_msghdr *rtm; 863 struct mbuf *m; 864 int i; 865 struct sockaddr *sa; 866 int len, dlen; 867 868 switch (type) { 869 870 case RTM_DELADDR: 871 case RTM_NEWADDR: 872 len = sizeof(struct ifa_msghdr); 873 break; 874 875 case RTM_DELMADDR: 876 case RTM_NEWMADDR: 877 len = sizeof(struct ifma_msghdr); 878 break; 879 880 case RTM_IFINFO: 881 len = sizeof(struct if_msghdr); 882 break; 883 884 case RTM_IFANNOUNCE: 885 case RTM_IEEE80211: 886 len = sizeof(struct if_announcemsghdr); 887 break; 888 889 default: 890 len = sizeof(struct rt_msghdr); 891 } 892 if (len > MCLBYTES) 893 panic("rt_msg1"); 894 m = m_gethdr(M_DONTWAIT, MT_DATA); 895 if (m && len > MHLEN) { 896 MCLGET(m, M_DONTWAIT); 897 if ((m->m_flags & M_EXT) == 0) { 898 m_free(m); 899 m = NULL; 900 } 901 } 902 if (m == NULL) 903 return (m); 904 m->m_pkthdr.len = m->m_len = len; 905 m->m_pkthdr.rcvif = NULL; 906 rtm = mtod(m, struct rt_msghdr *); 907 bzero((caddr_t)rtm, len); 908 for (i = 0; i < RTAX_MAX; i++) { 909 if ((sa = rtinfo->rti_info[i]) == NULL) 910 continue; 911 rtinfo->rti_addrs |= (1 << i); 912 dlen = SA_SIZE(sa); 913 m_copyback(m, len, dlen, (caddr_t)sa); 914 len += dlen; 915 } 916 if (m->m_pkthdr.len != len) { 917 m_freem(m); 918 return (NULL); 919 } 920 rtm->rtm_msglen = len; 921 rtm->rtm_version = RTM_VERSION; 922 rtm->rtm_type = type; 923 return (m); 924 } 925 926 static int 927 rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w) 928 { 929 int i; 930 int len, dlen, second_time = 0; 931 caddr_t cp0; 932 933 rtinfo->rti_addrs = 0; 934 again: 935 switch (type) { 936 937 case RTM_DELADDR: 938 case RTM_NEWADDR: 939 len = sizeof(struct ifa_msghdr); 940 break; 941 942 case RTM_IFINFO: 943 len = sizeof(struct if_msghdr); 944 break; 945 946 case RTM_NEWMADDR: 947 len = sizeof(struct ifma_msghdr); 948 break; 949 950 default: 951 len = sizeof(struct rt_msghdr); 952 } 953 cp0 = cp; 954 if (cp0) 955 cp += len; 956 for (i = 0; i < RTAX_MAX; i++) { 957 struct sockaddr *sa; 958 959 if ((sa = rtinfo->rti_info[i]) == NULL) 960 continue; 961 rtinfo->rti_addrs |= (1 << i); 962 dlen = SA_SIZE(sa); 963 if (cp) { 964 bcopy((caddr_t)sa, cp, (unsigned)dlen); 965 cp += dlen; 966 } 967 len += dlen; 968 } 969 len = ALIGN(len); 970 if (cp == NULL && w != NULL && !second_time) { 971 struct walkarg *rw = w; 972 973 if (rw->w_req) { 974 if (rw->w_tmemsize < len) { 975 if (rw->w_tmem) 976 free(rw->w_tmem, M_RTABLE); 977 rw->w_tmem = (caddr_t) 978 malloc(len, M_RTABLE, M_NOWAIT); 979 if (rw->w_tmem) 980 rw->w_tmemsize = len; 981 } 982 if (rw->w_tmem) { 983 cp = rw->w_tmem; 984 second_time = 1; 985 goto again; 986 } 987 } 988 } 989 if (cp) { 990 struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; 991 992 rtm->rtm_version = RTM_VERSION; 993 rtm->rtm_type = type; 994 rtm->rtm_msglen = len; 995 } 996 return (len); 997 } 998 999 /* 1000 * This routine is called to generate a message from the routing 1001 * socket indicating that a redirect has occured, a routing lookup 1002 * has failed, or that a protocol has detected timeouts to a particular 1003 * destination. 1004 */ 1005 void 1006 rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error) 1007 { 1008 struct rt_msghdr *rtm; 1009 struct mbuf *m; 1010 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 1011 1012 if (route_cb.any_count == 0) 1013 return; 1014 m = rt_msg1(type, rtinfo); 1015 if (m == NULL) 1016 return; 1017 rtm = mtod(m, struct rt_msghdr *); 1018 rtm->rtm_flags = RTF_DONE | flags; 1019 rtm->rtm_errno = error; 1020 rtm->rtm_addrs = rtinfo->rti_addrs; 1021 rt_dispatch(m, sa); 1022 } 1023 1024 /* 1025 * This routine is called to generate a message from the routing 1026 * socket indicating that the status of a network interface has changed. 1027 */ 1028 void 1029 rt_ifmsg(struct ifnet *ifp) 1030 { 1031 struct if_msghdr *ifm; 1032 struct mbuf *m; 1033 struct rt_addrinfo info; 1034 1035 if (route_cb.any_count == 0) 1036 return; 1037 bzero((caddr_t)&info, sizeof(info)); 1038 m = rt_msg1(RTM_IFINFO, &info); 1039 if (m == NULL) 1040 return; 1041 ifm = mtod(m, struct if_msghdr *); 1042 ifm->ifm_index = ifp->if_index; 1043 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; 1044 ifm->ifm_data = ifp->if_data; 1045 ifm->ifm_addrs = 0; 1046 rt_dispatch(m, NULL); 1047 } 1048 1049 /* 1050 * This is called to generate messages from the routing socket 1051 * indicating a network interface has had addresses associated with it. 1052 * if we ever reverse the logic and replace messages TO the routing 1053 * socket indicate a request to configure interfaces, then it will 1054 * be unnecessary as the routing socket will automatically generate 1055 * copies of it. 1056 */ 1057 void 1058 rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt) 1059 { 1060 struct rt_addrinfo info; 1061 struct sockaddr *sa = NULL; 1062 int pass; 1063 struct mbuf *m = NULL; 1064 struct ifnet *ifp = ifa->ifa_ifp; 1065 1066 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1067 ("unexpected cmd %u", cmd)); 1068 #ifdef SCTP 1069 /* 1070 * notify the SCTP stack 1071 * this will only get called when an address is added/deleted 1072 * XXX pass the ifaddr struct instead if ifa->ifa_addr... 1073 */ 1074 sctp_addr_change(ifa, cmd); 1075 #endif /* SCTP */ 1076 if (route_cb.any_count == 0) 1077 return; 1078 for (pass = 1; pass < 3; pass++) { 1079 bzero((caddr_t)&info, sizeof(info)); 1080 if ((cmd == RTM_ADD && pass == 1) || 1081 (cmd == RTM_DELETE && pass == 2)) { 1082 struct ifa_msghdr *ifam; 1083 int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; 1084 1085 info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; 1086 info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr; 1087 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1088 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1089 if ((m = rt_msg1(ncmd, &info)) == NULL) 1090 continue; 1091 ifam = mtod(m, struct ifa_msghdr *); 1092 ifam->ifam_index = ifp->if_index; 1093 ifam->ifam_metric = ifa->ifa_metric; 1094 ifam->ifam_flags = ifa->ifa_flags; 1095 ifam->ifam_addrs = info.rti_addrs; 1096 } 1097 if ((cmd == RTM_ADD && pass == 2) || 1098 (cmd == RTM_DELETE && pass == 1)) { 1099 struct rt_msghdr *rtm; 1100 1101 if (rt == NULL) 1102 continue; 1103 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1104 info.rti_info[RTAX_DST] = sa = rt_key(rt); 1105 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1106 if ((m = rt_msg1(cmd, &info)) == NULL) 1107 continue; 1108 rtm = mtod(m, struct rt_msghdr *); 1109 rtm->rtm_index = ifp->if_index; 1110 rtm->rtm_flags |= rt->rt_flags; 1111 rtm->rtm_errno = error; 1112 rtm->rtm_addrs = info.rti_addrs; 1113 } 1114 rt_dispatch(m, sa); 1115 } 1116 } 1117 1118 /* 1119 * This is the analogue to the rt_newaddrmsg which performs the same 1120 * function but for multicast group memberhips. This is easier since 1121 * there is no route state to worry about. 1122 */ 1123 void 1124 rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma) 1125 { 1126 struct rt_addrinfo info; 1127 struct mbuf *m = NULL; 1128 struct ifnet *ifp = ifma->ifma_ifp; 1129 struct ifma_msghdr *ifmam; 1130 1131 if (route_cb.any_count == 0) 1132 return; 1133 1134 bzero((caddr_t)&info, sizeof(info)); 1135 info.rti_info[RTAX_IFA] = ifma->ifma_addr; 1136 info.rti_info[RTAX_IFP] = ifp ? ifp->if_addr->ifa_addr : NULL; 1137 /* 1138 * If a link-layer address is present, present it as a ``gateway'' 1139 * (similarly to how ARP entries, e.g., are presented). 1140 */ 1141 info.rti_info[RTAX_GATEWAY] = ifma->ifma_lladdr; 1142 m = rt_msg1(cmd, &info); 1143 if (m == NULL) 1144 return; 1145 ifmam = mtod(m, struct ifma_msghdr *); 1146 KASSERT(ifp != NULL, ("%s: link-layer multicast address w/o ifp\n", 1147 __func__)); 1148 ifmam->ifmam_index = ifp->if_index; 1149 ifmam->ifmam_addrs = info.rti_addrs; 1150 rt_dispatch(m, ifma->ifma_addr); 1151 } 1152 1153 static struct mbuf * 1154 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what, 1155 struct rt_addrinfo *info) 1156 { 1157 struct if_announcemsghdr *ifan; 1158 struct mbuf *m; 1159 1160 if (route_cb.any_count == 0) 1161 return NULL; 1162 bzero((caddr_t)info, sizeof(*info)); 1163 m = rt_msg1(type, info); 1164 if (m != NULL) { 1165 ifan = mtod(m, struct if_announcemsghdr *); 1166 ifan->ifan_index = ifp->if_index; 1167 strlcpy(ifan->ifan_name, ifp->if_xname, 1168 sizeof(ifan->ifan_name)); 1169 ifan->ifan_what = what; 1170 } 1171 return m; 1172 } 1173 1174 /* 1175 * This is called to generate routing socket messages indicating 1176 * IEEE80211 wireless events. 1177 * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way. 1178 */ 1179 void 1180 rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len) 1181 { 1182 struct mbuf *m; 1183 struct rt_addrinfo info; 1184 1185 m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info); 1186 if (m != NULL) { 1187 /* 1188 * Append the ieee80211 data. Try to stick it in the 1189 * mbuf containing the ifannounce msg; otherwise allocate 1190 * a new mbuf and append. 1191 * 1192 * NB: we assume m is a single mbuf. 1193 */ 1194 if (data_len > M_TRAILINGSPACE(m)) { 1195 struct mbuf *n = m_get(M_NOWAIT, MT_DATA); 1196 if (n == NULL) { 1197 m_freem(m); 1198 return; 1199 } 1200 bcopy(data, mtod(n, void *), data_len); 1201 n->m_len = data_len; 1202 m->m_next = n; 1203 } else if (data_len > 0) { 1204 bcopy(data, mtod(m, u_int8_t *) + m->m_len, data_len); 1205 m->m_len += data_len; 1206 } 1207 if (m->m_flags & M_PKTHDR) 1208 m->m_pkthdr.len += data_len; 1209 mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len; 1210 rt_dispatch(m, NULL); 1211 } 1212 } 1213 1214 /* 1215 * This is called to generate routing socket messages indicating 1216 * network interface arrival and departure. 1217 */ 1218 void 1219 rt_ifannouncemsg(struct ifnet *ifp, int what) 1220 { 1221 struct mbuf *m; 1222 struct rt_addrinfo info; 1223 1224 m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info); 1225 if (m != NULL) 1226 rt_dispatch(m, NULL); 1227 } 1228 1229 static void 1230 rt_dispatch(struct mbuf *m, const struct sockaddr *sa) 1231 { 1232 INIT_VNET_NET(curvnet); 1233 struct m_tag *tag; 1234 1235 /* 1236 * Preserve the family from the sockaddr, if any, in an m_tag for 1237 * use when injecting the mbuf into the routing socket buffer from 1238 * the netisr. 1239 */ 1240 if (sa != NULL) { 1241 tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short), 1242 M_NOWAIT); 1243 if (tag == NULL) { 1244 m_freem(m); 1245 return; 1246 } 1247 *(unsigned short *)(tag + 1) = sa->sa_family; 1248 m_tag_prepend(m, tag); 1249 } 1250 netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */ 1251 } 1252 1253 /* 1254 * This is used in dumping the kernel table via sysctl(). 1255 */ 1256 static int 1257 sysctl_dumpentry(struct radix_node *rn, void *vw) 1258 { 1259 struct walkarg *w = vw; 1260 struct rtentry *rt = (struct rtentry *)rn; 1261 int error = 0, size; 1262 struct rt_addrinfo info; 1263 1264 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1265 return 0; 1266 if (jailed(w->w_req->td->td_ucred) && 1267 ((rt->rt_flags & RTF_HOST) == 0 || 1268 !prison_if(w->w_req->td->td_ucred, rt_key(rt)))) 1269 return (0); 1270 bzero((caddr_t)&info, sizeof(info)); 1271 info.rti_info[RTAX_DST] = rt_key(rt); 1272 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1273 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1274 info.rti_info[RTAX_GENMASK] = 0; 1275 if (rt->rt_ifp) { 1276 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_addr->ifa_addr; 1277 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1278 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1279 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 1280 } 1281 size = rt_msg2(RTM_GET, &info, NULL, w); 1282 if (w->w_req && w->w_tmem) { 1283 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 1284 1285 rtm->rtm_flags = rt->rt_flags; 1286 rtm->rtm_use = rt->rt_rmx.rmx_pksent; 1287 rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 1288 rtm->rtm_index = rt->rt_ifp->if_index; 1289 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 1290 rtm->rtm_addrs = info.rti_addrs; 1291 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); 1292 return (error); 1293 } 1294 return (error); 1295 } 1296 1297 static int 1298 sysctl_iflist(int af, struct walkarg *w) 1299 { 1300 INIT_VNET_NET(curvnet); 1301 struct ifnet *ifp; 1302 struct ifaddr *ifa; 1303 struct rt_addrinfo info; 1304 int len, error = 0; 1305 1306 bzero((caddr_t)&info, sizeof(info)); 1307 IFNET_RLOCK(); 1308 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 1309 if (w->w_arg && w->w_arg != ifp->if_index) 1310 continue; 1311 ifa = ifp->if_addr; 1312 info.rti_info[RTAX_IFP] = ifa->ifa_addr; 1313 len = rt_msg2(RTM_IFINFO, &info, NULL, w); 1314 info.rti_info[RTAX_IFP] = NULL; 1315 if (w->w_req && w->w_tmem) { 1316 struct if_msghdr *ifm; 1317 1318 ifm = (struct if_msghdr *)w->w_tmem; 1319 ifm->ifm_index = ifp->if_index; 1320 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; 1321 ifm->ifm_data = ifp->if_data; 1322 ifm->ifm_addrs = info.rti_addrs; 1323 error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); 1324 if (error) 1325 goto done; 1326 } 1327 while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) { 1328 if (af && af != ifa->ifa_addr->sa_family) 1329 continue; 1330 if (jailed(w->w_req->td->td_ucred) && 1331 !prison_if(w->w_req->td->td_ucred, ifa->ifa_addr)) 1332 continue; 1333 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1334 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1335 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1336 len = rt_msg2(RTM_NEWADDR, &info, NULL, w); 1337 if (w->w_req && w->w_tmem) { 1338 struct ifa_msghdr *ifam; 1339 1340 ifam = (struct ifa_msghdr *)w->w_tmem; 1341 ifam->ifam_index = ifa->ifa_ifp->if_index; 1342 ifam->ifam_flags = ifa->ifa_flags; 1343 ifam->ifam_metric = ifa->ifa_metric; 1344 ifam->ifam_addrs = info.rti_addrs; 1345 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 1346 if (error) 1347 goto done; 1348 } 1349 } 1350 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = 1351 info.rti_info[RTAX_BRD] = NULL; 1352 } 1353 done: 1354 IFNET_RUNLOCK(); 1355 return (error); 1356 } 1357 1358 static int 1359 sysctl_ifmalist(int af, struct walkarg *w) 1360 { 1361 INIT_VNET_NET(curvnet); 1362 struct ifnet *ifp; 1363 struct ifmultiaddr *ifma; 1364 struct rt_addrinfo info; 1365 int len, error = 0; 1366 struct ifaddr *ifa; 1367 1368 bzero((caddr_t)&info, sizeof(info)); 1369 IFNET_RLOCK(); 1370 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 1371 if (w->w_arg && w->w_arg != ifp->if_index) 1372 continue; 1373 ifa = ifp->if_addr; 1374 info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL; 1375 IF_ADDR_LOCK(ifp); 1376 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1377 if (af && af != ifma->ifma_addr->sa_family) 1378 continue; 1379 if (jailed(w->w_req->td->td_ucred) && 1380 !prison_if(w->w_req->td->td_ucred, ifma->ifma_addr)) 1381 continue; 1382 info.rti_info[RTAX_IFA] = ifma->ifma_addr; 1383 info.rti_info[RTAX_GATEWAY] = 1384 (ifma->ifma_addr->sa_family != AF_LINK) ? 1385 ifma->ifma_lladdr : NULL; 1386 len = rt_msg2(RTM_NEWMADDR, &info, NULL, w); 1387 if (w->w_req && w->w_tmem) { 1388 struct ifma_msghdr *ifmam; 1389 1390 ifmam = (struct ifma_msghdr *)w->w_tmem; 1391 ifmam->ifmam_index = ifma->ifma_ifp->if_index; 1392 ifmam->ifmam_flags = 0; 1393 ifmam->ifmam_addrs = info.rti_addrs; 1394 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 1395 if (error) { 1396 IF_ADDR_UNLOCK(ifp); 1397 goto done; 1398 } 1399 } 1400 } 1401 IF_ADDR_UNLOCK(ifp); 1402 } 1403 done: 1404 IFNET_RUNLOCK(); 1405 return (error); 1406 } 1407 1408 static int 1409 sysctl_rtsock(SYSCTL_HANDLER_ARGS) 1410 { 1411 INIT_VNET_NET(curvnet); 1412 int *name = (int *)arg1; 1413 u_int namelen = arg2; 1414 struct radix_node_head *rnh; 1415 int i, lim, error = EINVAL; 1416 u_char af; 1417 struct walkarg w; 1418 1419 name ++; 1420 namelen--; 1421 if (req->newptr) 1422 return (EPERM); 1423 if (namelen != 3) 1424 return ((namelen < 3) ? EISDIR : ENOTDIR); 1425 af = name[0]; 1426 if (af > AF_MAX) 1427 return (EINVAL); 1428 bzero(&w, sizeof(w)); 1429 w.w_op = name[1]; 1430 w.w_arg = name[2]; 1431 w.w_req = req; 1432 1433 error = sysctl_wire_old_buffer(req, 0); 1434 if (error) 1435 return (error); 1436 switch (w.w_op) { 1437 1438 case NET_RT_DUMP: 1439 case NET_RT_FLAGS: 1440 if (af == 0) { /* dump all tables */ 1441 i = 1; 1442 lim = AF_MAX; 1443 } else /* dump only one table */ 1444 i = lim = af; 1445 1446 /* 1447 * take care of llinfo entries, the caller must 1448 * specify an AF 1449 */ 1450 if (w.w_op == NET_RT_FLAGS && 1451 #if defined(COMPAT_ROUTE_FLAGS) 1452 (w.w_arg & RTF_LLINFO)) { 1453 #else 1454 w.w_arg == 0) { 1455 #endif 1456 if (af != 0) 1457 error = lltable_sysctl_dumparp(af, w.w_req); 1458 else 1459 error = EINVAL; 1460 break; 1461 } 1462 /* 1463 * take care of routing entries 1464 */ 1465 for (error = 0; error == 0 && i <= lim; i++) 1466 if ((rnh = V_rt_tables[req->td->td_proc->p_fibnum][i]) != NULL) { 1467 RADIX_NODE_HEAD_LOCK(rnh); 1468 error = rnh->rnh_walktree(rnh, 1469 sysctl_dumpentry, &w); 1470 RADIX_NODE_HEAD_UNLOCK(rnh); 1471 } else if (af != 0) 1472 error = EAFNOSUPPORT; 1473 break; 1474 1475 case NET_RT_IFLIST: 1476 error = sysctl_iflist(af, &w); 1477 break; 1478 1479 case NET_RT_IFMALIST: 1480 error = sysctl_ifmalist(af, &w); 1481 break; 1482 } 1483 if (w.w_tmem) 1484 free(w.w_tmem, M_RTABLE); 1485 return (error); 1486 } 1487 1488 SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); 1489 1490 /* 1491 * Definitions of protocols supported in the ROUTE domain. 1492 */ 1493 1494 static struct domain routedomain; /* or at least forward */ 1495 1496 static struct protosw routesw[] = { 1497 { 1498 .pr_type = SOCK_RAW, 1499 .pr_domain = &routedomain, 1500 .pr_flags = PR_ATOMIC|PR_ADDR, 1501 .pr_output = route_output, 1502 .pr_ctlinput = raw_ctlinput, 1503 .pr_init = raw_init, 1504 .pr_usrreqs = &route_usrreqs 1505 } 1506 }; 1507 1508 static struct domain routedomain = { 1509 .dom_family = PF_ROUTE, 1510 .dom_name = "route", 1511 .dom_protosw = routesw, 1512 .dom_protoswNPROTOSW = &routesw[sizeof(routesw)/sizeof(routesw[0])] 1513 }; 1514 1515 DOMAIN_SET(route); 1516