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