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 /* First, see if the returned address is part of the jail. */ 341 if (prison_if(cred, rt->rt_ifa->ifa_addr) == 0) { 342 info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 343 return (0); 344 } 345 346 switch (info->rti_info[RTAX_DST]->sa_family) { 347 #ifdef INET 348 case AF_INET: 349 { 350 struct in_addr ia; 351 struct ifaddr *ifa; 352 int found; 353 354 found = 0; 355 /* 356 * Try to find an address on the given outgoing interface 357 * that belongs to the jail. 358 */ 359 IF_ADDR_LOCK(ifp); 360 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 361 struct sockaddr *sa; 362 sa = ifa->ifa_addr; 363 if (sa->sa_family != AF_INET) 364 continue; 365 ia = ((struct sockaddr_in *)sa)->sin_addr; 366 if (prison_check_ip4(cred, &ia) == 0) { 367 found = 1; 368 break; 369 } 370 } 371 IF_ADDR_UNLOCK(ifp); 372 if (!found) { 373 /* 374 * As a last resort return the 'default' jail address. 375 */ 376 if (prison_get_ip4(cred, &ia) != 0) 377 return (ESRCH); 378 } 379 bzero(&saun->sin, sizeof(struct sockaddr_in)); 380 saun->sin.sin_len = sizeof(struct sockaddr_in); 381 saun->sin.sin_family = AF_INET; 382 saun->sin.sin_addr.s_addr = ia.s_addr; 383 info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin; 384 break; 385 } 386 #endif 387 #ifdef INET6 388 case AF_INET6: 389 { 390 struct in6_addr ia6; 391 struct ifaddr *ifa; 392 int found; 393 394 found = 0; 395 /* 396 * Try to find an address on the given outgoing interface 397 * that belongs to the jail. 398 */ 399 IF_ADDR_LOCK(ifp); 400 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 401 struct sockaddr *sa; 402 sa = ifa->ifa_addr; 403 if (sa->sa_family != AF_INET6) 404 continue; 405 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 406 &ia6, sizeof(struct in6_addr)); 407 if (prison_check_ip6(cred, &ia6) == 0) { 408 found = 1; 409 break; 410 } 411 } 412 IF_ADDR_UNLOCK(ifp); 413 if (!found) { 414 /* 415 * As a last resort return the 'default' jail address. 416 */ 417 if (prison_get_ip6(cred, &ia6) != 0) 418 return (ESRCH); 419 } 420 bzero(&saun->sin6, sizeof(struct sockaddr_in6)); 421 saun->sin6.sin6_len = sizeof(struct sockaddr_in6); 422 saun->sin6.sin6_family = AF_INET6; 423 bcopy(&ia6, &saun->sin6.sin6_addr, sizeof(struct in6_addr)); 424 if (sa6_recoverscope(&saun->sin6) != 0) 425 return (ESRCH); 426 info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin6; 427 break; 428 } 429 #endif 430 default: 431 return (ESRCH); 432 } 433 return (0); 434 } 435 436 /*ARGSUSED*/ 437 static int 438 route_output(struct mbuf *m, struct socket *so) 439 { 440 #define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) 441 INIT_VNET_NET(so->so_vnet); 442 struct rt_msghdr *rtm = NULL; 443 struct rtentry *rt = NULL; 444 struct radix_node_head *rnh; 445 struct rt_addrinfo info; 446 int len, error = 0; 447 struct ifnet *ifp = NULL; 448 union sockaddr_union saun; 449 450 #define senderr(e) { error = e; goto flush;} 451 if (m == NULL || ((m->m_len < sizeof(long)) && 452 (m = m_pullup(m, sizeof(long))) == NULL)) 453 return (ENOBUFS); 454 if ((m->m_flags & M_PKTHDR) == 0) 455 panic("route_output"); 456 len = m->m_pkthdr.len; 457 if (len < sizeof(*rtm) || 458 len != mtod(m, struct rt_msghdr *)->rtm_msglen) { 459 info.rti_info[RTAX_DST] = NULL; 460 senderr(EINVAL); 461 } 462 R_Malloc(rtm, struct rt_msghdr *, len); 463 if (rtm == NULL) { 464 info.rti_info[RTAX_DST] = NULL; 465 senderr(ENOBUFS); 466 } 467 m_copydata(m, 0, len, (caddr_t)rtm); 468 if (rtm->rtm_version != RTM_VERSION) { 469 info.rti_info[RTAX_DST] = NULL; 470 senderr(EPROTONOSUPPORT); 471 } 472 rtm->rtm_pid = curproc->p_pid; 473 bzero(&info, sizeof(info)); 474 info.rti_addrs = rtm->rtm_addrs; 475 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 476 info.rti_info[RTAX_DST] = NULL; 477 senderr(EINVAL); 478 } 479 info.rti_flags = rtm->rtm_flags; 480 if (info.rti_info[RTAX_DST] == NULL || 481 info.rti_info[RTAX_DST]->sa_family >= AF_MAX || 482 (info.rti_info[RTAX_GATEWAY] != NULL && 483 info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) 484 senderr(EINVAL); 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 (rtm->rtm_type != RTM_GET) { 490 error = priv_check(curthread, PRIV_NET_ROUTE); 491 if (error) 492 senderr(error); 493 } 494 495 switch (rtm->rtm_type) { 496 struct rtentry *saved_nrt; 497 498 case RTM_ADD: 499 if (info.rti_info[RTAX_GATEWAY] == NULL) 500 senderr(EINVAL); 501 saved_nrt = NULL; 502 503 /* support for new ARP code */ 504 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && 505 (rtm->rtm_flags & RTF_LLDATA) != 0) { 506 error = lla_rt_output(rtm, &info); 507 break; 508 } 509 error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt, 510 so->so_fibnum); 511 if (error == 0 && saved_nrt) { 512 RT_LOCK(saved_nrt); 513 rt_setmetrics(rtm->rtm_inits, 514 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 515 rtm->rtm_index = saved_nrt->rt_ifp->if_index; 516 RT_REMREF(saved_nrt); 517 RT_UNLOCK(saved_nrt); 518 } 519 break; 520 521 case RTM_DELETE: 522 saved_nrt = NULL; 523 /* support for new ARP code */ 524 if (info.rti_info[RTAX_GATEWAY] && 525 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 526 (rtm->rtm_flags & RTF_LLDATA) != 0) { 527 error = lla_rt_output(rtm, &info); 528 break; 529 } 530 error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, 531 so->so_fibnum); 532 if (error == 0) { 533 RT_LOCK(saved_nrt); 534 rt = saved_nrt; 535 goto report; 536 } 537 break; 538 539 case RTM_GET: 540 case RTM_CHANGE: 541 case RTM_LOCK: 542 rnh = V_rt_tables[so->so_fibnum][info.rti_info[RTAX_DST]->sa_family]; 543 if (rnh == NULL) 544 senderr(EAFNOSUPPORT); 545 RADIX_NODE_HEAD_RLOCK(rnh); 546 rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST], 547 info.rti_info[RTAX_NETMASK], rnh); 548 if (rt == NULL) { /* XXX looks bogus */ 549 RADIX_NODE_HEAD_RUNLOCK(rnh); 550 senderr(ESRCH); 551 } 552 #ifdef RADIX_MPATH 553 /* 554 * for RTM_CHANGE/LOCK, if we got multipath routes, 555 * we require users to specify a matching RTAX_GATEWAY. 556 * 557 * for RTM_GET, gate is optional even with multipath. 558 * if gate == NULL the first match is returned. 559 * (no need to call rt_mpath_matchgate if gate == NULL) 560 */ 561 if (rn_mpath_capable(rnh) && 562 (rtm->rtm_type != RTM_GET || info.rti_info[RTAX_GATEWAY])) { 563 rt = rt_mpath_matchgate(rt, info.rti_info[RTAX_GATEWAY]); 564 if (!rt) { 565 RADIX_NODE_HEAD_RUNLOCK(rnh); 566 senderr(ESRCH); 567 } 568 } 569 #endif 570 RT_LOCK(rt); 571 RT_ADDREF(rt); 572 RADIX_NODE_HEAD_RUNLOCK(rnh); 573 574 /* 575 * Fix for PR: 82974 576 * 577 * RTM_CHANGE/LOCK need a perfect match, rn_lookup() 578 * returns a perfect match in case a netmask is 579 * specified. For host routes only a longest prefix 580 * match is returned so it is necessary to compare the 581 * existence of the netmask. If both have a netmask 582 * rnh_lookup() did a perfect match and if none of them 583 * have a netmask both are host routes which is also a 584 * perfect match. 585 */ 586 587 if (rtm->rtm_type != RTM_GET && 588 (!rt_mask(rt) != !info.rti_info[RTAX_NETMASK])) { 589 RT_UNLOCK(rt); 590 senderr(ESRCH); 591 } 592 593 switch(rtm->rtm_type) { 594 595 case RTM_GET: 596 report: 597 RT_LOCK_ASSERT(rt); 598 if ((rt->rt_flags & RTF_HOST) == 0 599 ? jailed(curthread->td_ucred) 600 : prison_if(curthread->td_ucred, 601 rt_key(rt)) != 0) { 602 RT_UNLOCK(rt); 603 senderr(ESRCH); 604 } 605 info.rti_info[RTAX_DST] = rt_key(rt); 606 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 607 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 608 info.rti_info[RTAX_GENMASK] = 0; 609 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 610 ifp = rt->rt_ifp; 611 if (ifp) { 612 info.rti_info[RTAX_IFP] = 613 ifp->if_addr->ifa_addr; 614 error = rtm_get_jailed(&info, ifp, rt, 615 &saun, curthread->td_ucred); 616 if (error != 0) { 617 RT_UNLOCK(rt); 618 senderr(error); 619 } 620 if (ifp->if_flags & IFF_POINTOPOINT) 621 info.rti_info[RTAX_BRD] = 622 rt->rt_ifa->ifa_dstaddr; 623 rtm->rtm_index = ifp->if_index; 624 } else { 625 info.rti_info[RTAX_IFP] = NULL; 626 info.rti_info[RTAX_IFA] = NULL; 627 } 628 } else if ((ifp = rt->rt_ifp) != NULL) { 629 rtm->rtm_index = ifp->if_index; 630 } 631 len = rt_msg2(rtm->rtm_type, &info, NULL, NULL); 632 if (len > rtm->rtm_msglen) { 633 struct rt_msghdr *new_rtm; 634 R_Malloc(new_rtm, struct rt_msghdr *, len); 635 if (new_rtm == NULL) { 636 RT_UNLOCK(rt); 637 senderr(ENOBUFS); 638 } 639 bcopy(rtm, new_rtm, rtm->rtm_msglen); 640 Free(rtm); rtm = new_rtm; 641 } 642 (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL); 643 rtm->rtm_flags = rt->rt_flags; 644 rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 645 rtm->rtm_addrs = info.rti_addrs; 646 break; 647 648 case RTM_CHANGE: 649 /* 650 * New gateway could require new ifaddr, ifp; 651 * flags may also be different; ifp may be specified 652 * by ll sockaddr when protocol address is ambiguous 653 */ 654 if (((rt->rt_flags & RTF_GATEWAY) && 655 info.rti_info[RTAX_GATEWAY] != NULL) || 656 info.rti_info[RTAX_IFP] != NULL || 657 (info.rti_info[RTAX_IFA] != NULL && 658 !sa_equal(info.rti_info[RTAX_IFA], 659 rt->rt_ifa->ifa_addr))) { 660 RT_UNLOCK(rt); 661 RADIX_NODE_HEAD_LOCK(rnh); 662 error = rt_getifa_fib(&info, rt->rt_fibnum); 663 RADIX_NODE_HEAD_UNLOCK(rnh); 664 if (error != 0) 665 senderr(error); 666 RT_LOCK(rt); 667 } 668 if (info.rti_ifa != NULL && 669 info.rti_ifa != rt->rt_ifa && 670 rt->rt_ifa != NULL && 671 rt->rt_ifa->ifa_rtrequest != NULL) { 672 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, 673 &info); 674 IFAFREE(rt->rt_ifa); 675 } 676 if (info.rti_info[RTAX_GATEWAY] != NULL) { 677 RT_UNLOCK(rt); 678 RADIX_NODE_HEAD_LOCK(rnh); 679 RT_LOCK(rt); 680 681 error = rt_setgate(rt, rt_key(rt), 682 info.rti_info[RTAX_GATEWAY]); 683 RADIX_NODE_HEAD_UNLOCK(rnh); 684 if (error != 0) { 685 RT_UNLOCK(rt); 686 senderr(error); 687 } 688 rt->rt_flags |= RTF_GATEWAY; 689 } 690 if (info.rti_ifa != NULL && 691 info.rti_ifa != rt->rt_ifa) { 692 IFAREF(info.rti_ifa); 693 rt->rt_ifa = info.rti_ifa; 694 rt->rt_ifp = info.rti_ifp; 695 } 696 /* Allow some flags to be toggled on change. */ 697 rt->rt_flags = (rt->rt_flags & ~RTF_FMASK) | 698 (rtm->rtm_flags & RTF_FMASK); 699 rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 700 &rt->rt_rmx); 701 rtm->rtm_index = rt->rt_ifp->if_index; 702 if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) 703 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); 704 /* FALLTHROUGH */ 705 case RTM_LOCK: 706 /* We don't support locks anymore */ 707 break; 708 } 709 RT_UNLOCK(rt); 710 break; 711 712 default: 713 senderr(EOPNOTSUPP); 714 } 715 716 flush: 717 if (rtm) { 718 if (error) 719 rtm->rtm_errno = error; 720 else 721 rtm->rtm_flags |= RTF_DONE; 722 } 723 if (rt) /* XXX can this be true? */ 724 RTFREE(rt); 725 { 726 struct rawcb *rp = NULL; 727 /* 728 * Check to see if we don't want our own messages. 729 */ 730 if ((so->so_options & SO_USELOOPBACK) == 0) { 731 if (route_cb.any_count <= 1) { 732 if (rtm) 733 Free(rtm); 734 m_freem(m); 735 return (error); 736 } 737 /* There is another listener, so construct message */ 738 rp = sotorawcb(so); 739 } 740 if (rtm) { 741 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 742 if (m->m_pkthdr.len < rtm->rtm_msglen) { 743 m_freem(m); 744 m = NULL; 745 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 746 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 747 Free(rtm); 748 } 749 if (m) { 750 if (rp) { 751 /* 752 * XXX insure we don't get a copy by 753 * invalidating our protocol 754 */ 755 unsigned short family = rp->rcb_proto.sp_family; 756 rp->rcb_proto.sp_family = 0; 757 rt_dispatch(m, info.rti_info[RTAX_DST]); 758 rp->rcb_proto.sp_family = family; 759 } else 760 rt_dispatch(m, info.rti_info[RTAX_DST]); 761 } 762 } 763 return (error); 764 #undef sa_equal 765 } 766 767 static void 768 rt_setmetrics(u_long which, const struct rt_metrics *in, 769 struct rt_metrics_lite *out) 770 { 771 #define metric(f, e) if (which & (f)) out->e = in->e; 772 /* 773 * Only these are stored in the routing entry since introduction 774 * of tcp hostcache. The rest is ignored. 775 */ 776 metric(RTV_MTU, rmx_mtu); 777 metric(RTV_WEIGHT, rmx_weight); 778 /* Userland -> kernel timebase conversion. */ 779 if (which & RTV_EXPIRE) 780 out->rmx_expire = in->rmx_expire ? 781 in->rmx_expire - time_second + time_uptime : 0; 782 #undef metric 783 } 784 785 static void 786 rt_getmetrics(const struct rt_metrics_lite *in, struct rt_metrics *out) 787 { 788 #define metric(e) out->e = in->e; 789 bzero(out, sizeof(*out)); 790 metric(rmx_mtu); 791 metric(rmx_weight); 792 /* Kernel -> userland timebase conversion. */ 793 out->rmx_expire = in->rmx_expire ? 794 in->rmx_expire - time_uptime + time_second : 0; 795 #undef metric 796 } 797 798 /* 799 * Extract the addresses of the passed sockaddrs. 800 * Do a little sanity checking so as to avoid bad memory references. 801 * This data is derived straight from userland. 802 */ 803 static int 804 rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) 805 { 806 struct sockaddr *sa; 807 int i; 808 809 for (i = 0; i < RTAX_MAX && cp < cplim; i++) { 810 if ((rtinfo->rti_addrs & (1 << i)) == 0) 811 continue; 812 sa = (struct sockaddr *)cp; 813 /* 814 * It won't fit. 815 */ 816 if (cp + sa->sa_len > cplim) 817 return (EINVAL); 818 /* 819 * there are no more.. quit now 820 * If there are more bits, they are in error. 821 * I've seen this. route(1) can evidently generate these. 822 * This causes kernel to core dump. 823 * for compatibility, If we see this, point to a safe address. 824 */ 825 if (sa->sa_len == 0) { 826 rtinfo->rti_info[i] = &sa_zero; 827 return (0); /* should be EINVAL but for compat */ 828 } 829 /* accept it */ 830 rtinfo->rti_info[i] = sa; 831 cp += SA_SIZE(sa); 832 } 833 return (0); 834 } 835 836 static struct mbuf * 837 rt_msg1(int type, struct rt_addrinfo *rtinfo) 838 { 839 struct rt_msghdr *rtm; 840 struct mbuf *m; 841 int i; 842 struct sockaddr *sa; 843 int len, dlen; 844 845 switch (type) { 846 847 case RTM_DELADDR: 848 case RTM_NEWADDR: 849 len = sizeof(struct ifa_msghdr); 850 break; 851 852 case RTM_DELMADDR: 853 case RTM_NEWMADDR: 854 len = sizeof(struct ifma_msghdr); 855 break; 856 857 case RTM_IFINFO: 858 len = sizeof(struct if_msghdr); 859 break; 860 861 case RTM_IFANNOUNCE: 862 case RTM_IEEE80211: 863 len = sizeof(struct if_announcemsghdr); 864 break; 865 866 default: 867 len = sizeof(struct rt_msghdr); 868 } 869 if (len > MCLBYTES) 870 panic("rt_msg1"); 871 m = m_gethdr(M_DONTWAIT, MT_DATA); 872 if (m && len > MHLEN) { 873 MCLGET(m, M_DONTWAIT); 874 if ((m->m_flags & M_EXT) == 0) { 875 m_free(m); 876 m = NULL; 877 } 878 } 879 if (m == NULL) 880 return (m); 881 m->m_pkthdr.len = m->m_len = len; 882 m->m_pkthdr.rcvif = NULL; 883 rtm = mtod(m, struct rt_msghdr *); 884 bzero((caddr_t)rtm, len); 885 for (i = 0; i < RTAX_MAX; i++) { 886 if ((sa = rtinfo->rti_info[i]) == NULL) 887 continue; 888 rtinfo->rti_addrs |= (1 << i); 889 dlen = SA_SIZE(sa); 890 m_copyback(m, len, dlen, (caddr_t)sa); 891 len += dlen; 892 } 893 if (m->m_pkthdr.len != len) { 894 m_freem(m); 895 return (NULL); 896 } 897 rtm->rtm_msglen = len; 898 rtm->rtm_version = RTM_VERSION; 899 rtm->rtm_type = type; 900 return (m); 901 } 902 903 static int 904 rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w) 905 { 906 int i; 907 int len, dlen, second_time = 0; 908 caddr_t cp0; 909 910 rtinfo->rti_addrs = 0; 911 again: 912 switch (type) { 913 914 case RTM_DELADDR: 915 case RTM_NEWADDR: 916 len = sizeof(struct ifa_msghdr); 917 break; 918 919 case RTM_IFINFO: 920 len = sizeof(struct if_msghdr); 921 break; 922 923 case RTM_NEWMADDR: 924 len = sizeof(struct ifma_msghdr); 925 break; 926 927 default: 928 len = sizeof(struct rt_msghdr); 929 } 930 cp0 = cp; 931 if (cp0) 932 cp += len; 933 for (i = 0; i < RTAX_MAX; i++) { 934 struct sockaddr *sa; 935 936 if ((sa = rtinfo->rti_info[i]) == NULL) 937 continue; 938 rtinfo->rti_addrs |= (1 << i); 939 dlen = SA_SIZE(sa); 940 if (cp) { 941 bcopy((caddr_t)sa, cp, (unsigned)dlen); 942 cp += dlen; 943 } 944 len += dlen; 945 } 946 len = ALIGN(len); 947 if (cp == NULL && w != NULL && !second_time) { 948 struct walkarg *rw = w; 949 950 if (rw->w_req) { 951 if (rw->w_tmemsize < len) { 952 if (rw->w_tmem) 953 free(rw->w_tmem, M_RTABLE); 954 rw->w_tmem = (caddr_t) 955 malloc(len, M_RTABLE, M_NOWAIT); 956 if (rw->w_tmem) 957 rw->w_tmemsize = len; 958 } 959 if (rw->w_tmem) { 960 cp = rw->w_tmem; 961 second_time = 1; 962 goto again; 963 } 964 } 965 } 966 if (cp) { 967 struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; 968 969 rtm->rtm_version = RTM_VERSION; 970 rtm->rtm_type = type; 971 rtm->rtm_msglen = len; 972 } 973 return (len); 974 } 975 976 /* 977 * This routine is called to generate a message from the routing 978 * socket indicating that a redirect has occured, a routing lookup 979 * has failed, or that a protocol has detected timeouts to a particular 980 * destination. 981 */ 982 void 983 rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error) 984 { 985 struct rt_msghdr *rtm; 986 struct mbuf *m; 987 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 988 989 if (route_cb.any_count == 0) 990 return; 991 m = rt_msg1(type, rtinfo); 992 if (m == NULL) 993 return; 994 rtm = mtod(m, struct rt_msghdr *); 995 rtm->rtm_flags = RTF_DONE | flags; 996 rtm->rtm_errno = error; 997 rtm->rtm_addrs = rtinfo->rti_addrs; 998 rt_dispatch(m, sa); 999 } 1000 1001 /* 1002 * This routine is called to generate a message from the routing 1003 * socket indicating that the status of a network interface has changed. 1004 */ 1005 void 1006 rt_ifmsg(struct ifnet *ifp) 1007 { 1008 struct if_msghdr *ifm; 1009 struct mbuf *m; 1010 struct rt_addrinfo info; 1011 1012 if (route_cb.any_count == 0) 1013 return; 1014 bzero((caddr_t)&info, sizeof(info)); 1015 m = rt_msg1(RTM_IFINFO, &info); 1016 if (m == NULL) 1017 return; 1018 ifm = mtod(m, struct if_msghdr *); 1019 ifm->ifm_index = ifp->if_index; 1020 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; 1021 ifm->ifm_data = ifp->if_data; 1022 ifm->ifm_addrs = 0; 1023 rt_dispatch(m, NULL); 1024 } 1025 1026 /* 1027 * This is called to generate messages from the routing socket 1028 * indicating a network interface has had addresses associated with it. 1029 * if we ever reverse the logic and replace messages TO the routing 1030 * socket indicate a request to configure interfaces, then it will 1031 * be unnecessary as the routing socket will automatically generate 1032 * copies of it. 1033 */ 1034 void 1035 rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt) 1036 { 1037 struct rt_addrinfo info; 1038 struct sockaddr *sa = NULL; 1039 int pass; 1040 struct mbuf *m = NULL; 1041 struct ifnet *ifp = ifa->ifa_ifp; 1042 1043 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1044 ("unexpected cmd %u", cmd)); 1045 #ifdef SCTP 1046 /* 1047 * notify the SCTP stack 1048 * this will only get called when an address is added/deleted 1049 * XXX pass the ifaddr struct instead if ifa->ifa_addr... 1050 */ 1051 sctp_addr_change(ifa, cmd); 1052 #endif /* SCTP */ 1053 if (route_cb.any_count == 0) 1054 return; 1055 for (pass = 1; pass < 3; pass++) { 1056 bzero((caddr_t)&info, sizeof(info)); 1057 if ((cmd == RTM_ADD && pass == 1) || 1058 (cmd == RTM_DELETE && pass == 2)) { 1059 struct ifa_msghdr *ifam; 1060 int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; 1061 1062 info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; 1063 info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr; 1064 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1065 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1066 if ((m = rt_msg1(ncmd, &info)) == NULL) 1067 continue; 1068 ifam = mtod(m, struct ifa_msghdr *); 1069 ifam->ifam_index = ifp->if_index; 1070 ifam->ifam_metric = ifa->ifa_metric; 1071 ifam->ifam_flags = ifa->ifa_flags; 1072 ifam->ifam_addrs = info.rti_addrs; 1073 } 1074 if ((cmd == RTM_ADD && pass == 2) || 1075 (cmd == RTM_DELETE && pass == 1)) { 1076 struct rt_msghdr *rtm; 1077 1078 if (rt == NULL) 1079 continue; 1080 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1081 info.rti_info[RTAX_DST] = sa = rt_key(rt); 1082 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1083 if ((m = rt_msg1(cmd, &info)) == NULL) 1084 continue; 1085 rtm = mtod(m, struct rt_msghdr *); 1086 rtm->rtm_index = ifp->if_index; 1087 rtm->rtm_flags |= rt->rt_flags; 1088 rtm->rtm_errno = error; 1089 rtm->rtm_addrs = info.rti_addrs; 1090 } 1091 rt_dispatch(m, sa); 1092 } 1093 } 1094 1095 /* 1096 * This is the analogue to the rt_newaddrmsg which performs the same 1097 * function but for multicast group memberhips. This is easier since 1098 * there is no route state to worry about. 1099 */ 1100 void 1101 rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma) 1102 { 1103 struct rt_addrinfo info; 1104 struct mbuf *m = NULL; 1105 struct ifnet *ifp = ifma->ifma_ifp; 1106 struct ifma_msghdr *ifmam; 1107 1108 if (route_cb.any_count == 0) 1109 return; 1110 1111 bzero((caddr_t)&info, sizeof(info)); 1112 info.rti_info[RTAX_IFA] = ifma->ifma_addr; 1113 info.rti_info[RTAX_IFP] = ifp ? ifp->if_addr->ifa_addr : NULL; 1114 /* 1115 * If a link-layer address is present, present it as a ``gateway'' 1116 * (similarly to how ARP entries, e.g., are presented). 1117 */ 1118 info.rti_info[RTAX_GATEWAY] = ifma->ifma_lladdr; 1119 m = rt_msg1(cmd, &info); 1120 if (m == NULL) 1121 return; 1122 ifmam = mtod(m, struct ifma_msghdr *); 1123 KASSERT(ifp != NULL, ("%s: link-layer multicast address w/o ifp\n", 1124 __func__)); 1125 ifmam->ifmam_index = ifp->if_index; 1126 ifmam->ifmam_addrs = info.rti_addrs; 1127 rt_dispatch(m, ifma->ifma_addr); 1128 } 1129 1130 static struct mbuf * 1131 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what, 1132 struct rt_addrinfo *info) 1133 { 1134 struct if_announcemsghdr *ifan; 1135 struct mbuf *m; 1136 1137 if (route_cb.any_count == 0) 1138 return NULL; 1139 bzero((caddr_t)info, sizeof(*info)); 1140 m = rt_msg1(type, info); 1141 if (m != NULL) { 1142 ifan = mtod(m, struct if_announcemsghdr *); 1143 ifan->ifan_index = ifp->if_index; 1144 strlcpy(ifan->ifan_name, ifp->if_xname, 1145 sizeof(ifan->ifan_name)); 1146 ifan->ifan_what = what; 1147 } 1148 return m; 1149 } 1150 1151 /* 1152 * This is called to generate routing socket messages indicating 1153 * IEEE80211 wireless events. 1154 * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way. 1155 */ 1156 void 1157 rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len) 1158 { 1159 struct mbuf *m; 1160 struct rt_addrinfo info; 1161 1162 m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info); 1163 if (m != NULL) { 1164 /* 1165 * Append the ieee80211 data. Try to stick it in the 1166 * mbuf containing the ifannounce msg; otherwise allocate 1167 * a new mbuf and append. 1168 * 1169 * NB: we assume m is a single mbuf. 1170 */ 1171 if (data_len > M_TRAILINGSPACE(m)) { 1172 struct mbuf *n = m_get(M_NOWAIT, MT_DATA); 1173 if (n == NULL) { 1174 m_freem(m); 1175 return; 1176 } 1177 bcopy(data, mtod(n, void *), data_len); 1178 n->m_len = data_len; 1179 m->m_next = n; 1180 } else if (data_len > 0) { 1181 bcopy(data, mtod(m, u_int8_t *) + m->m_len, data_len); 1182 m->m_len += data_len; 1183 } 1184 if (m->m_flags & M_PKTHDR) 1185 m->m_pkthdr.len += data_len; 1186 mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len; 1187 rt_dispatch(m, NULL); 1188 } 1189 } 1190 1191 /* 1192 * This is called to generate routing socket messages indicating 1193 * network interface arrival and departure. 1194 */ 1195 void 1196 rt_ifannouncemsg(struct ifnet *ifp, int what) 1197 { 1198 struct mbuf *m; 1199 struct rt_addrinfo info; 1200 1201 m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info); 1202 if (m != NULL) 1203 rt_dispatch(m, NULL); 1204 } 1205 1206 static void 1207 rt_dispatch(struct mbuf *m, const struct sockaddr *sa) 1208 { 1209 INIT_VNET_NET(curvnet); 1210 struct m_tag *tag; 1211 1212 /* 1213 * Preserve the family from the sockaddr, if any, in an m_tag for 1214 * use when injecting the mbuf into the routing socket buffer from 1215 * the netisr. 1216 */ 1217 if (sa != NULL) { 1218 tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short), 1219 M_NOWAIT); 1220 if (tag == NULL) { 1221 m_freem(m); 1222 return; 1223 } 1224 *(unsigned short *)(tag + 1) = sa->sa_family; 1225 m_tag_prepend(m, tag); 1226 } 1227 #ifdef VIMAGE 1228 if (V_loif) 1229 m->m_pkthdr.rcvif = V_loif; 1230 else { 1231 m_freem(m); 1232 return; 1233 } 1234 #endif 1235 netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */ 1236 } 1237 1238 /* 1239 * This is used in dumping the kernel table via sysctl(). 1240 */ 1241 static int 1242 sysctl_dumpentry(struct radix_node *rn, void *vw) 1243 { 1244 struct walkarg *w = vw; 1245 struct rtentry *rt = (struct rtentry *)rn; 1246 int error = 0, size; 1247 struct rt_addrinfo info; 1248 1249 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1250 return 0; 1251 if ((rt->rt_flags & RTF_HOST) == 0 1252 ? jailed(w->w_req->td->td_ucred) 1253 : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0) 1254 return (0); 1255 bzero((caddr_t)&info, sizeof(info)); 1256 info.rti_info[RTAX_DST] = rt_key(rt); 1257 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1258 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1259 info.rti_info[RTAX_GENMASK] = 0; 1260 if (rt->rt_ifp) { 1261 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_addr->ifa_addr; 1262 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1263 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1264 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 1265 } 1266 size = rt_msg2(RTM_GET, &info, NULL, w); 1267 if (w->w_req && w->w_tmem) { 1268 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 1269 1270 rtm->rtm_flags = rt->rt_flags; 1271 /* 1272 * let's be honest about this being a retarded hack 1273 */ 1274 rtm->rtm_fmask = rt->rt_rmx.rmx_pksent; 1275 rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 1276 rtm->rtm_index = rt->rt_ifp->if_index; 1277 rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; 1278 rtm->rtm_addrs = info.rti_addrs; 1279 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size); 1280 return (error); 1281 } 1282 return (error); 1283 } 1284 1285 static int 1286 sysctl_iflist(int af, struct walkarg *w) 1287 { 1288 INIT_VNET_NET(curvnet); 1289 struct ifnet *ifp; 1290 struct ifaddr *ifa; 1291 struct rt_addrinfo info; 1292 int len, error = 0; 1293 1294 bzero((caddr_t)&info, sizeof(info)); 1295 IFNET_RLOCK(); 1296 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 1297 if (w->w_arg && w->w_arg != ifp->if_index) 1298 continue; 1299 ifa = ifp->if_addr; 1300 info.rti_info[RTAX_IFP] = ifa->ifa_addr; 1301 len = rt_msg2(RTM_IFINFO, &info, NULL, w); 1302 info.rti_info[RTAX_IFP] = NULL; 1303 if (w->w_req && w->w_tmem) { 1304 struct if_msghdr *ifm; 1305 1306 ifm = (struct if_msghdr *)w->w_tmem; 1307 ifm->ifm_index = ifp->if_index; 1308 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; 1309 ifm->ifm_data = ifp->if_data; 1310 ifm->ifm_addrs = info.rti_addrs; 1311 error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); 1312 if (error) 1313 goto done; 1314 } 1315 while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) { 1316 if (af && af != ifa->ifa_addr->sa_family) 1317 continue; 1318 if (prison_if(w->w_req->td->td_ucred, 1319 ifa->ifa_addr) != 0) 1320 continue; 1321 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1322 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1323 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1324 len = rt_msg2(RTM_NEWADDR, &info, NULL, w); 1325 if (w->w_req && w->w_tmem) { 1326 struct ifa_msghdr *ifam; 1327 1328 ifam = (struct ifa_msghdr *)w->w_tmem; 1329 ifam->ifam_index = ifa->ifa_ifp->if_index; 1330 ifam->ifam_flags = ifa->ifa_flags; 1331 ifam->ifam_metric = ifa->ifa_metric; 1332 ifam->ifam_addrs = info.rti_addrs; 1333 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 1334 if (error) 1335 goto done; 1336 } 1337 } 1338 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = 1339 info.rti_info[RTAX_BRD] = NULL; 1340 } 1341 done: 1342 IFNET_RUNLOCK(); 1343 return (error); 1344 } 1345 1346 static int 1347 sysctl_ifmalist(int af, struct walkarg *w) 1348 { 1349 INIT_VNET_NET(curvnet); 1350 struct ifnet *ifp; 1351 struct ifmultiaddr *ifma; 1352 struct rt_addrinfo info; 1353 int len, error = 0; 1354 struct ifaddr *ifa; 1355 1356 bzero((caddr_t)&info, sizeof(info)); 1357 IFNET_RLOCK(); 1358 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 1359 if (w->w_arg && w->w_arg != ifp->if_index) 1360 continue; 1361 ifa = ifp->if_addr; 1362 info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL; 1363 IF_ADDR_LOCK(ifp); 1364 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1365 if (af && af != ifma->ifma_addr->sa_family) 1366 continue; 1367 if (prison_if(w->w_req->td->td_ucred, 1368 ifma->ifma_addr) != 0) 1369 continue; 1370 info.rti_info[RTAX_IFA] = ifma->ifma_addr; 1371 info.rti_info[RTAX_GATEWAY] = 1372 (ifma->ifma_addr->sa_family != AF_LINK) ? 1373 ifma->ifma_lladdr : NULL; 1374 len = rt_msg2(RTM_NEWMADDR, &info, NULL, w); 1375 if (w->w_req && w->w_tmem) { 1376 struct ifma_msghdr *ifmam; 1377 1378 ifmam = (struct ifma_msghdr *)w->w_tmem; 1379 ifmam->ifmam_index = ifma->ifma_ifp->if_index; 1380 ifmam->ifmam_flags = 0; 1381 ifmam->ifmam_addrs = info.rti_addrs; 1382 error = SYSCTL_OUT(w->w_req, w->w_tmem, len); 1383 if (error) { 1384 IF_ADDR_UNLOCK(ifp); 1385 goto done; 1386 } 1387 } 1388 } 1389 IF_ADDR_UNLOCK(ifp); 1390 } 1391 done: 1392 IFNET_RUNLOCK(); 1393 return (error); 1394 } 1395 1396 static int 1397 sysctl_rtsock(SYSCTL_HANDLER_ARGS) 1398 { 1399 INIT_VNET_NET(curvnet); 1400 int *name = (int *)arg1; 1401 u_int namelen = arg2; 1402 struct radix_node_head *rnh; 1403 int i, lim, error = EINVAL; 1404 u_char af; 1405 struct walkarg w; 1406 1407 name ++; 1408 namelen--; 1409 if (req->newptr) 1410 return (EPERM); 1411 if (namelen != 3) 1412 return ((namelen < 3) ? EISDIR : ENOTDIR); 1413 af = name[0]; 1414 if (af > AF_MAX) 1415 return (EINVAL); 1416 bzero(&w, sizeof(w)); 1417 w.w_op = name[1]; 1418 w.w_arg = name[2]; 1419 w.w_req = req; 1420 1421 error = sysctl_wire_old_buffer(req, 0); 1422 if (error) 1423 return (error); 1424 switch (w.w_op) { 1425 1426 case NET_RT_DUMP: 1427 case NET_RT_FLAGS: 1428 if (af == 0) { /* dump all tables */ 1429 i = 1; 1430 lim = AF_MAX; 1431 } else /* dump only one table */ 1432 i = lim = af; 1433 1434 /* 1435 * take care of llinfo entries, the caller must 1436 * specify an AF 1437 */ 1438 if (w.w_op == NET_RT_FLAGS && 1439 (w.w_arg == 0 || w.w_arg & RTF_LLINFO)) { 1440 if (af != 0) 1441 error = lltable_sysctl_dumparp(af, w.w_req); 1442 else 1443 error = EINVAL; 1444 break; 1445 } 1446 /* 1447 * take care of routing entries 1448 */ 1449 for (error = 0; error == 0 && i <= lim; i++) 1450 if ((rnh = V_rt_tables[req->td->td_proc->p_fibnum][i]) != NULL) { 1451 RADIX_NODE_HEAD_LOCK(rnh); 1452 error = rnh->rnh_walktree(rnh, 1453 sysctl_dumpentry, &w); 1454 RADIX_NODE_HEAD_UNLOCK(rnh); 1455 } else if (af != 0) 1456 error = EAFNOSUPPORT; 1457 break; 1458 1459 case NET_RT_IFLIST: 1460 error = sysctl_iflist(af, &w); 1461 break; 1462 1463 case NET_RT_IFMALIST: 1464 error = sysctl_ifmalist(af, &w); 1465 break; 1466 } 1467 if (w.w_tmem) 1468 free(w.w_tmem, M_RTABLE); 1469 return (error); 1470 } 1471 1472 SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); 1473 1474 /* 1475 * Definitions of protocols supported in the ROUTE domain. 1476 */ 1477 1478 static struct domain routedomain; /* or at least forward */ 1479 1480 static struct protosw routesw[] = { 1481 { 1482 .pr_type = SOCK_RAW, 1483 .pr_domain = &routedomain, 1484 .pr_flags = PR_ATOMIC|PR_ADDR, 1485 .pr_output = route_output, 1486 .pr_ctlinput = raw_ctlinput, 1487 .pr_init = raw_init, 1488 .pr_usrreqs = &route_usrreqs 1489 } 1490 }; 1491 1492 static struct domain routedomain = { 1493 .dom_family = PF_ROUTE, 1494 .dom_name = "route", 1495 .dom_protosw = routesw, 1496 .dom_protoswNPROTOSW = &routesw[sizeof(routesw)/sizeof(routesw[0])] 1497 }; 1498 1499 DOMAIN_SET(route); 1500