1 /* $OpenBSD: rtsock.c,v 1.286 2019/05/11 16:47:02 claudio Exp $ */ 2 /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1988, 1991, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)rtsock.c 8.6 (Berkeley) 2/11/95 62 */ 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/proc.h> 67 #include <sys/sysctl.h> 68 #include <sys/mbuf.h> 69 #include <sys/socket.h> 70 #include <sys/socketvar.h> 71 #include <sys/domain.h> 72 #include <sys/protosw.h> 73 #include <sys/srp.h> 74 75 #include <net/if.h> 76 #include <net/if_dl.h> 77 #include <net/if_var.h> 78 #include <net/route.h> 79 80 #include <netinet/in.h> 81 82 #ifdef MPLS 83 #include <netmpls/mpls.h> 84 #endif 85 #ifdef IPSEC 86 #include <netinet/ip_ipsp.h> 87 #include <net/if_enc.h> 88 #endif 89 #ifdef BFD 90 #include <net/bfd.h> 91 #endif 92 93 #include <sys/stdarg.h> 94 #include <sys/kernel.h> 95 #include <sys/timeout.h> 96 97 #define ROUTESNDQ 8192 98 #define ROUTERCVQ 8192 99 100 const struct sockaddr route_src = { 2, PF_ROUTE, }; 101 102 struct walkarg { 103 int w_op, w_arg, w_given, w_needed, w_tmemsize; 104 caddr_t w_where, w_tmem; 105 }; 106 107 void route_prinit(void); 108 void rcb_ref(void *, void *); 109 void rcb_unref(void *, void *); 110 int route_output(struct mbuf *, struct socket *, struct sockaddr *, 111 struct mbuf *); 112 int route_ctloutput(int, struct socket *, int, int, struct mbuf *); 113 int route_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, 114 struct mbuf *, struct proc *); 115 void route_input(struct mbuf *m0, struct socket *, sa_family_t); 116 int route_arp_conflict(struct rtentry *, struct rt_addrinfo *); 117 int route_cleargateway(struct rtentry *, void *, unsigned int); 118 void rtm_senddesync_timer(void *); 119 void rtm_senddesync(struct socket *); 120 int rtm_sendup(struct socket *, struct mbuf *, int); 121 122 int rtm_getifa(struct rt_addrinfo *, unsigned int); 123 int rtm_output(struct rt_msghdr *, struct rtentry **, struct rt_addrinfo *, 124 uint8_t, unsigned int); 125 struct rt_msghdr *rtm_report(struct rtentry *, u_char, int, int); 126 struct mbuf *rtm_msg1(int, struct rt_addrinfo *); 127 int rtm_msg2(int, int, struct rt_addrinfo *, caddr_t, 128 struct walkarg *); 129 int rtm_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); 130 int rtm_validate_proposal(struct rt_addrinfo *); 131 void rtm_setmetrics(u_long, const struct rt_metrics *, 132 struct rt_kmetrics *); 133 void rtm_getmetrics(const struct rt_kmetrics *, 134 struct rt_metrics *); 135 136 int sysctl_iflist(int, struct walkarg *); 137 int sysctl_ifnames(struct walkarg *); 138 int sysctl_rtable_rtstat(void *, size_t *, void *); 139 140 struct rtpcb { 141 struct socket *rop_socket; 142 143 SRPL_ENTRY(rtpcb) rop_list; 144 struct refcnt rop_refcnt; 145 struct timeout rop_timeout; 146 unsigned int rop_msgfilter; 147 unsigned int rop_flags; 148 u_int rop_rtableid; 149 unsigned short rop_proto; 150 u_char rop_priority; 151 }; 152 #define sotortpcb(so) ((struct rtpcb *)(so)->so_pcb) 153 154 struct rtptable { 155 SRPL_HEAD(, rtpcb) rtp_list; 156 struct srpl_rc rtp_rc; 157 struct rwlock rtp_lk; 158 unsigned int rtp_count; 159 }; 160 161 struct rtptable rtptable; 162 163 /* 164 * These flags and timeout are used for indicating to userland (via a 165 * RTM_DESYNC msg) when the route socket has overflowed and messages 166 * have been lost. 167 */ 168 #define ROUTECB_FLAG_DESYNC 0x1 /* Route socket out of memory */ 169 #define ROUTECB_FLAG_FLUSH 0x2 /* Wait until socket is empty before 170 queueing more packets */ 171 172 #define ROUTE_DESYNC_RESEND_TIMEOUT 200 /* In ms */ 173 174 void 175 route_prinit(void) 176 { 177 srpl_rc_init(&rtptable.rtp_rc, rcb_ref, rcb_unref, NULL); 178 rw_init(&rtptable.rtp_lk, "rtsock"); 179 SRPL_INIT(&rtptable.rtp_list); 180 } 181 182 void 183 rcb_ref(void *null, void *v) 184 { 185 struct rtpcb *rop = v; 186 187 refcnt_take(&rop->rop_refcnt); 188 } 189 190 void 191 rcb_unref(void *null, void *v) 192 { 193 struct rtpcb *rop = v; 194 195 refcnt_rele_wake(&rop->rop_refcnt); 196 } 197 198 int 199 route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, 200 struct mbuf *control, struct proc *p) 201 { 202 struct rtpcb *rop; 203 int error = 0; 204 205 if (req == PRU_CONTROL) 206 return (EOPNOTSUPP); 207 208 soassertlocked(so); 209 210 if (control && control->m_len) { 211 error = EOPNOTSUPP; 212 goto release; 213 } 214 215 rop = sotortpcb(so); 216 if (rop == NULL) { 217 error = EINVAL; 218 goto release; 219 } 220 221 switch (req) { 222 /* no connect, bind, accept. Socket is connected from the start */ 223 case PRU_CONNECT: 224 case PRU_BIND: 225 case PRU_CONNECT2: 226 case PRU_LISTEN: 227 case PRU_ACCEPT: 228 error = EOPNOTSUPP; 229 break; 230 231 case PRU_DISCONNECT: 232 case PRU_ABORT: 233 soisdisconnected(so); 234 break; 235 case PRU_SHUTDOWN: 236 socantsendmore(so); 237 break; 238 case PRU_SENSE: 239 /* stat: don't bother with a blocksize. */ 240 break; 241 242 /* minimal support, just implement a fake peer address */ 243 case PRU_SOCKADDR: 244 error = EINVAL; 245 break; 246 case PRU_PEERADDR: 247 bcopy(&route_src, mtod(nam, caddr_t), route_src.sa_len); 248 nam->m_len = route_src.sa_len; 249 break; 250 251 case PRU_RCVD: 252 /* 253 * If we are in a FLUSH state, check if the buffer is 254 * empty so that we can clear the flag. 255 */ 256 if (((rop->rop_flags & ROUTECB_FLAG_FLUSH) != 0) && 257 ((sbspace(rop->rop_socket, &rop->rop_socket->so_rcv) == 258 rop->rop_socket->so_rcv.sb_hiwat))) 259 rop->rop_flags &= ~ROUTECB_FLAG_FLUSH; 260 break; 261 262 case PRU_RCVOOB: 263 case PRU_SENDOOB: 264 error = EOPNOTSUPP; 265 break; 266 case PRU_SEND: 267 if (nam) { 268 error = EISCONN; 269 break; 270 } 271 error = (*so->so_proto->pr_output)(m, so, NULL, NULL); 272 m = NULL; 273 break; 274 default: 275 panic("route_usrreq"); 276 } 277 278 release: 279 if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) { 280 m_freem(control); 281 m_freem(m); 282 } 283 return (error); 284 } 285 286 int 287 route_attach(struct socket *so, int proto) 288 { 289 struct rtpcb *rop; 290 int error; 291 292 /* 293 * use the rawcb but allocate a rtpcb, this 294 * code does not care about the additional fields 295 * and works directly on the raw socket. 296 */ 297 rop = malloc(sizeof(struct rtpcb), M_PCB, M_WAITOK|M_ZERO); 298 so->so_pcb = rop; 299 /* Init the timeout structure */ 300 timeout_set(&rop->rop_timeout, rtm_senddesync_timer, so); 301 refcnt_init(&rop->rop_refcnt); 302 303 if (curproc == NULL) 304 error = EACCES; 305 else 306 error = soreserve(so, ROUTESNDQ, ROUTERCVQ); 307 if (error) { 308 free(rop, M_PCB, sizeof(struct rtpcb)); 309 return (error); 310 } 311 312 rop->rop_socket = so; 313 rop->rop_proto = proto; 314 315 rop->rop_rtableid = curproc->p_p->ps_rtableid; 316 317 soisconnected(so); 318 so->so_options |= SO_USELOOPBACK; 319 320 rw_enter(&rtptable.rtp_lk, RW_WRITE); 321 SRPL_INSERT_HEAD_LOCKED(&rtptable.rtp_rc, &rtptable.rtp_list, rop, rop_list); 322 rtptable.rtp_count++; 323 rw_exit(&rtptable.rtp_lk); 324 325 return (0); 326 } 327 328 int 329 route_detach(struct socket *so) 330 { 331 struct rtpcb *rop; 332 333 soassertlocked(so); 334 335 rop = sotortpcb(so); 336 if (rop == NULL) 337 return (EINVAL); 338 339 rw_enter(&rtptable.rtp_lk, RW_WRITE); 340 341 timeout_del(&rop->rop_timeout); 342 rtptable.rtp_count--; 343 344 SRPL_REMOVE_LOCKED(&rtptable.rtp_rc, &rtptable.rtp_list, rop, rtpcb, 345 rop_list); 346 rw_exit(&rtptable.rtp_lk); 347 348 /* wait for all references to drop */ 349 refcnt_finalize(&rop->rop_refcnt, "rtsockrefs"); 350 351 so->so_pcb = NULL; 352 KASSERT((so->so_state & SS_NOFDREF) == 0); 353 free(rop, M_PCB, sizeof(struct rtpcb)); 354 355 return (0); 356 } 357 358 int 359 route_ctloutput(int op, struct socket *so, int level, int optname, 360 struct mbuf *m) 361 { 362 struct rtpcb *rop = sotortpcb(so); 363 int error = 0; 364 unsigned int tid, prio; 365 366 if (level != AF_ROUTE) 367 return (EINVAL); 368 369 switch (op) { 370 case PRCO_SETOPT: 371 switch (optname) { 372 case ROUTE_MSGFILTER: 373 if (m == NULL || m->m_len != sizeof(unsigned int)) 374 error = EINVAL; 375 else 376 rop->rop_msgfilter = *mtod(m, unsigned int *); 377 break; 378 case ROUTE_TABLEFILTER: 379 if (m == NULL || m->m_len != sizeof(unsigned int)) { 380 error = EINVAL; 381 break; 382 } 383 tid = *mtod(m, unsigned int *); 384 if (tid != RTABLE_ANY && !rtable_exists(tid)) 385 error = ENOENT; 386 else 387 rop->rop_rtableid = tid; 388 break; 389 case ROUTE_PRIOFILTER: 390 if (m == NULL || m->m_len != sizeof(unsigned int)) { 391 error = EINVAL; 392 break; 393 } 394 prio = *mtod(m, unsigned int *); 395 if (prio > RTP_MAX) 396 error = EINVAL; 397 else 398 rop->rop_priority = prio; 399 break; 400 default: 401 error = ENOPROTOOPT; 402 break; 403 } 404 break; 405 case PRCO_GETOPT: 406 switch (optname) { 407 case ROUTE_MSGFILTER: 408 m->m_len = sizeof(unsigned int); 409 *mtod(m, unsigned int *) = rop->rop_msgfilter; 410 break; 411 case ROUTE_TABLEFILTER: 412 m->m_len = sizeof(unsigned int); 413 *mtod(m, unsigned int *) = rop->rop_rtableid; 414 break; 415 case ROUTE_PRIOFILTER: 416 m->m_len = sizeof(unsigned int); 417 *mtod(m, unsigned int *) = rop->rop_priority; 418 break; 419 default: 420 error = ENOPROTOOPT; 421 break; 422 } 423 } 424 return (error); 425 } 426 427 void 428 rtm_senddesync_timer(void *xso) 429 { 430 struct socket *so = xso; 431 int s; 432 433 s = solock(so); 434 rtm_senddesync(so); 435 sounlock(so, s); 436 } 437 438 void 439 rtm_senddesync(struct socket *so) 440 { 441 struct rtpcb *rop = sotortpcb(so); 442 struct mbuf *desync_mbuf; 443 444 soassertlocked(so); 445 446 /* If we are in a DESYNC state, try to send a RTM_DESYNC packet */ 447 if ((rop->rop_flags & ROUTECB_FLAG_DESYNC) == 0) 448 return; 449 450 /* 451 * If we fail to alloc memory or if sbappendaddr() 452 * fails, re-add timeout and try again. 453 */ 454 desync_mbuf = rtm_msg1(RTM_DESYNC, NULL); 455 if (desync_mbuf != NULL) { 456 if (sbappendaddr(so, &so->so_rcv, &route_src, 457 desync_mbuf, NULL) != 0) { 458 rop->rop_flags &= ~ROUTECB_FLAG_DESYNC; 459 sorwakeup(rop->rop_socket); 460 return; 461 } 462 m_freem(desync_mbuf); 463 } 464 /* Re-add timeout to try sending msg again */ 465 timeout_add_msec(&rop->rop_timeout, ROUTE_DESYNC_RESEND_TIMEOUT); 466 } 467 468 void 469 route_input(struct mbuf *m0, struct socket *so0, sa_family_t sa_family) 470 { 471 struct socket *so; 472 struct rtpcb *rop; 473 struct rt_msghdr *rtm; 474 struct mbuf *m = m0; 475 struct socket *last = NULL; 476 struct srp_ref sr; 477 int s; 478 479 /* ensure that we can access the rtm_type via mtod() */ 480 if (m->m_len < offsetof(struct rt_msghdr, rtm_type) + 1) { 481 m_freem(m); 482 return; 483 } 484 485 SRPL_FOREACH(rop, &sr, &rtptable.rtp_list, rop_list) { 486 /* 487 * If route socket is bound to an address family only send 488 * messages that match the address family. Address family 489 * agnostic messages are always sent. 490 */ 491 if (sa_family != AF_UNSPEC && rop->rop_proto != AF_UNSPEC && 492 rop->rop_proto != sa_family) 493 continue; 494 495 496 so = rop->rop_socket; 497 s = solock(so); 498 499 /* 500 * Check to see if we don't want our own messages and 501 * if we can receive anything. 502 */ 503 if ((so0 == so && !(so0->so_options & SO_USELOOPBACK)) || 504 !(so->so_state & SS_ISCONNECTED) || 505 (so->so_state & SS_CANTRCVMORE)) { 506 next: 507 sounlock(so, s); 508 continue; 509 } 510 511 /* filter messages that the process does not want */ 512 rtm = mtod(m, struct rt_msghdr *); 513 /* but RTM_DESYNC can't be filtered */ 514 if (rtm->rtm_type != RTM_DESYNC && rop->rop_msgfilter != 0 && 515 !(rop->rop_msgfilter & (1 << rtm->rtm_type))) 516 goto next; 517 switch (rtm->rtm_type) { 518 case RTM_IFANNOUNCE: 519 case RTM_DESYNC: 520 /* no tableid */ 521 break; 522 case RTM_RESOLVE: 523 case RTM_NEWADDR: 524 case RTM_DELADDR: 525 case RTM_IFINFO: 526 case RTM_80211INFO: 527 case RTM_BFD: 528 /* check against rdomain id */ 529 if (rop->rop_rtableid != RTABLE_ANY && 530 rtable_l2(rop->rop_rtableid) != rtm->rtm_tableid) 531 goto next; 532 break; 533 default: 534 if (rop->rop_priority != 0 && 535 rop->rop_priority < rtm->rtm_priority) 536 goto next; 537 /* check against rtable id */ 538 if (rop->rop_rtableid != RTABLE_ANY && 539 rop->rop_rtableid != rtm->rtm_tableid) 540 goto next; 541 break; 542 } 543 544 /* 545 * Check to see if the flush flag is set. If so, don't queue 546 * any more messages until the flag is cleared. 547 */ 548 if ((rop->rop_flags & ROUTECB_FLAG_FLUSH) != 0) 549 goto next; 550 sounlock(so, s); 551 552 if (last) { 553 s = solock(last); 554 rtm_sendup(last, m, 1); 555 sounlock(last, s); 556 refcnt_rele_wake(&sotortpcb(last)->rop_refcnt); 557 } 558 /* keep a reference for last */ 559 refcnt_take(&rop->rop_refcnt); 560 last = rop->rop_socket; 561 } 562 SRPL_LEAVE(&sr); 563 564 if (last) { 565 s = solock(last); 566 rtm_sendup(last, m, 0); 567 sounlock(last, s); 568 refcnt_rele_wake(&sotortpcb(last)->rop_refcnt); 569 } else 570 m_freem(m); 571 } 572 573 int 574 rtm_sendup(struct socket *so, struct mbuf *m0, int more) 575 { 576 struct rtpcb *rop = sotortpcb(so); 577 struct mbuf *m; 578 579 soassertlocked(so); 580 581 if (more) { 582 m = m_copym(m0, 0, M_COPYALL, M_NOWAIT); 583 if (m == NULL) 584 return (ENOMEM); 585 } else 586 m = m0; 587 588 if (sbspace(so, &so->so_rcv) < (2 * MSIZE) || 589 sbappendaddr(so, &so->so_rcv, &route_src, m, NULL) == 0) { 590 /* Flag socket as desync'ed and flush required */ 591 rop->rop_flags |= ROUTECB_FLAG_DESYNC | ROUTECB_FLAG_FLUSH; 592 rtm_senddesync(so); 593 m_freem(m); 594 return (ENOBUFS); 595 } 596 597 sorwakeup(so); 598 return (0); 599 } 600 601 struct rt_msghdr * 602 rtm_report(struct rtentry *rt, u_char type, int seq, int tableid) 603 { 604 struct rt_msghdr *rtm; 605 struct rt_addrinfo info; 606 struct sockaddr_rtlabel sa_rl; 607 struct sockaddr_in6 sa_mask; 608 #ifdef BFD 609 struct sockaddr_bfd sa_bfd; 610 #endif 611 struct ifnet *ifp = NULL; 612 int len; 613 614 bzero(&info, sizeof(info)); 615 info.rti_info[RTAX_DST] = rt_key(rt); 616 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 617 info.rti_info[RTAX_NETMASK] = rt_plen2mask(rt, &sa_mask); 618 info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, &sa_rl); 619 #ifdef BFD 620 if (rt->rt_flags & RTF_BFD) 621 info.rti_info[RTAX_BFD] = bfd2sa(rt, &sa_bfd); 622 #endif 623 #ifdef MPLS 624 if (rt->rt_flags & RTF_MPLS) { 625 struct sockaddr_mpls sa_mpls; 626 627 bzero(&sa_mpls, sizeof(sa_mpls)); 628 sa_mpls.smpls_family = AF_MPLS; 629 sa_mpls.smpls_len = sizeof(sa_mpls); 630 sa_mpls.smpls_label = ((struct rt_mpls *) 631 rt->rt_llinfo)->mpls_label; 632 info.rti_info[RTAX_SRC] = (struct sockaddr *)&sa_mpls; 633 info.rti_mpls = ((struct rt_mpls *) 634 rt->rt_llinfo)->mpls_operation; 635 } 636 #endif 637 ifp = if_get(rt->rt_ifidx); 638 if (ifp != NULL) { 639 info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); 640 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 641 if (ifp->if_flags & IFF_POINTOPOINT) 642 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 643 } 644 if_put(ifp); 645 /* RTAX_GENMASK, RTAX_AUTHOR, RTAX_SRCMASK ignored */ 646 647 /* build new route message */ 648 len = rtm_msg2(type, RTM_VERSION, &info, NULL, NULL); 649 rtm = malloc(len, M_RTABLE, M_WAITOK | M_ZERO); 650 651 rtm_msg2(type, RTM_VERSION, &info, (caddr_t)rtm, NULL); 652 rtm->rtm_type = type; 653 rtm->rtm_index = rt->rt_ifidx; 654 rtm->rtm_tableid = tableid; 655 rtm->rtm_priority = rt->rt_priority & RTP_MASK; 656 rtm->rtm_flags = rt->rt_flags; 657 rtm->rtm_pid = curproc->p_p->ps_pid; 658 rtm->rtm_seq = seq; 659 rtm_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 660 rtm->rtm_addrs = info.rti_addrs; 661 #ifdef MPLS 662 rtm->rtm_mpls = info.rti_mpls; 663 #endif 664 return rtm; 665 } 666 667 int 668 route_output(struct mbuf *m, struct socket *so, struct sockaddr *dstaddr, 669 struct mbuf *control) 670 { 671 struct rt_msghdr *rtm = NULL; 672 struct rtentry *rt = NULL; 673 struct rt_addrinfo info; 674 int len, seq, error = 0; 675 u_int tableid; 676 u_int8_t prio; 677 u_char vers, type; 678 679 if (m == NULL || ((m->m_len < sizeof(int32_t)) && 680 (m = m_pullup(m, sizeof(int32_t))) == 0)) 681 return (ENOBUFS); 682 if ((m->m_flags & M_PKTHDR) == 0) 683 panic("route_output"); 684 len = m->m_pkthdr.len; 685 if (len < offsetof(struct rt_msghdr, rtm_hdrlen) + 1 || 686 len != mtod(m, struct rt_msghdr *)->rtm_msglen) { 687 error = EINVAL; 688 goto fail; 689 } 690 vers = mtod(m, struct rt_msghdr *)->rtm_version; 691 switch (vers) { 692 case RTM_VERSION: 693 if (len < sizeof(struct rt_msghdr)) { 694 error = EINVAL; 695 goto fail; 696 } 697 if (len > RTM_MAXSIZE) { 698 error = EMSGSIZE; 699 goto fail; 700 } 701 rtm = malloc(len, M_RTABLE, M_WAITOK); 702 m_copydata(m, 0, len, (caddr_t)rtm); 703 break; 704 default: 705 error = EPROTONOSUPPORT; 706 goto fail; 707 } 708 709 /* Verify that the caller is sending an appropriate message early */ 710 switch (rtm->rtm_type) { 711 case RTM_ADD: 712 case RTM_DELETE: 713 case RTM_GET: 714 case RTM_CHANGE: 715 case RTM_PROPOSAL: 716 break; 717 default: 718 error = EOPNOTSUPP; 719 goto fail; 720 } 721 /* 722 * Verify that the header length is valid. 723 * All messages from userland start with a struct rt_msghdr. 724 */ 725 if (rtm->rtm_hdrlen == 0) /* old client */ 726 rtm->rtm_hdrlen = sizeof(struct rt_msghdr); 727 if (rtm->rtm_hdrlen < sizeof(struct rt_msghdr) || 728 len < rtm->rtm_hdrlen) { 729 error = EINVAL; 730 goto fail; 731 } 732 733 rtm->rtm_pid = curproc->p_p->ps_pid; 734 735 /* 736 * Verify that the caller has the appropriate privilege; RTM_GET 737 * is the only operation the non-superuser is allowed. 738 */ 739 if (rtm->rtm_type != RTM_GET && suser(curproc) != 0) { 740 error = EACCES; 741 goto fail; 742 } 743 tableid = rtm->rtm_tableid; 744 if (!rtable_exists(tableid)) { 745 if (rtm->rtm_type == RTM_ADD) { 746 if ((error = rtable_add(tableid)) != 0) 747 goto fail; 748 } else { 749 error = EINVAL; 750 goto fail; 751 } 752 } 753 754 755 /* Do not let userland play with kernel-only flags. */ 756 if ((rtm->rtm_flags & (RTF_LOCAL|RTF_BROADCAST)) != 0) { 757 error = EINVAL; 758 goto fail; 759 } 760 761 /* make sure that kernel-only bits are not set */ 762 rtm->rtm_priority &= RTP_MASK; 763 rtm->rtm_flags &= ~(RTF_DONE|RTF_CLONED|RTF_CACHED); 764 rtm->rtm_fmask &= RTF_FMASK; 765 766 if (rtm->rtm_priority != 0) { 767 if (rtm->rtm_priority > RTP_MAX || 768 rtm->rtm_priority == RTP_LOCAL) { 769 error = EINVAL; 770 goto fail; 771 } 772 prio = rtm->rtm_priority; 773 } else if (rtm->rtm_type != RTM_ADD) 774 prio = RTP_ANY; 775 else if (rtm->rtm_flags & RTF_STATIC) 776 prio = 0; 777 else 778 prio = RTP_DEFAULT; 779 780 bzero(&info, sizeof(info)); 781 info.rti_addrs = rtm->rtm_addrs; 782 if ((error = rtm_xaddrs(rtm->rtm_hdrlen + (caddr_t)rtm, 783 len + (caddr_t)rtm, &info)) != 0) 784 goto fail; 785 info.rti_flags = rtm->rtm_flags; 786 if (rtm->rtm_type != RTM_PROPOSAL && 787 (info.rti_info[RTAX_DST] == NULL || 788 info.rti_info[RTAX_DST]->sa_family >= AF_MAX || 789 (info.rti_info[RTAX_GATEWAY] != NULL && 790 info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX) || 791 info.rti_info[RTAX_GENMASK] != NULL)) { 792 error = EINVAL; 793 goto fail; 794 } 795 #ifdef MPLS 796 info.rti_mpls = rtm->rtm_mpls; 797 #endif 798 799 if (info.rti_info[RTAX_GATEWAY] != NULL && 800 info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && 801 (info.rti_flags & RTF_CLONING) == 0) { 802 info.rti_flags |= RTF_LLINFO; 803 } 804 805 /* 806 * Validate RTM_PROPOSAL and pass it along or error out. 807 */ 808 if (rtm->rtm_type == RTM_PROPOSAL) { 809 if (rtm_validate_proposal(&info) == -1) { 810 error = EINVAL; 811 goto fail; 812 } 813 } else { 814 error = rtm_output(rtm, &rt, &info, prio, tableid); 815 if (!error) { 816 type = rtm->rtm_type; 817 seq = rtm->rtm_seq; 818 free(rtm, M_RTABLE, len); 819 rtm = rtm_report(rt, type, seq, tableid); 820 len = rtm->rtm_msglen; 821 } 822 } 823 824 rtfree(rt); 825 if (error) { 826 rtm->rtm_errno = error; 827 } else { 828 rtm->rtm_flags |= RTF_DONE; 829 } 830 831 /* 832 * Check to see if we don't want our own messages. 833 */ 834 if (!(so->so_options & SO_USELOOPBACK)) { 835 if (rtptable.rtp_count <= 1) { 836 /* no other listener and no loopback of messages */ 837 fail: 838 free(rtm, M_RTABLE, len); 839 m_freem(m); 840 return (error); 841 } 842 } 843 if (rtm) { 844 if (m_copyback(m, 0, len, rtm, M_NOWAIT)) { 845 m_freem(m); 846 m = NULL; 847 } else if (m->m_pkthdr.len > len) 848 m_adj(m, len - m->m_pkthdr.len); 849 free(rtm, M_RTABLE, len); 850 } 851 if (m) 852 route_input(m, so, info.rti_info[RTAX_DST] ? 853 info.rti_info[RTAX_DST]->sa_family : AF_UNSPEC); 854 855 return (error); 856 } 857 858 int 859 rtm_output(struct rt_msghdr *rtm, struct rtentry **prt, 860 struct rt_addrinfo *info, uint8_t prio, unsigned int tableid) 861 { 862 struct rtentry *rt = *prt; 863 struct ifnet *ifp = NULL; 864 int plen, newgate = 0, error = 0; 865 866 switch (rtm->rtm_type) { 867 case RTM_ADD: 868 if (info->rti_info[RTAX_GATEWAY] == NULL) { 869 error = EINVAL; 870 break; 871 } 872 873 rt = rtable_match(tableid, info->rti_info[RTAX_DST], NULL); 874 if ((error = route_arp_conflict(rt, info))) { 875 rtfree(rt); 876 rt = NULL; 877 break; 878 } 879 880 /* 881 * We cannot go through a delete/create/insert cycle for 882 * cached route because this can lead to races in the 883 * receive path. Instead we update the L2 cache. 884 */ 885 if ((rt != NULL) && ISSET(rt->rt_flags, RTF_CACHED)) 886 goto change; 887 888 rtfree(rt); 889 rt = NULL; 890 891 NET_LOCK(); 892 if ((error = rtm_getifa(info, tableid)) != 0) { 893 NET_UNLOCK(); 894 break; 895 } 896 error = rtrequest(RTM_ADD, info, prio, &rt, tableid); 897 NET_UNLOCK(); 898 if (error == 0) 899 rtm_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 900 &rt->rt_rmx); 901 break; 902 case RTM_DELETE: 903 rt = rtable_lookup(tableid, info->rti_info[RTAX_DST], 904 info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], 905 prio); 906 if (rt == NULL) { 907 error = ESRCH; 908 break; 909 } 910 911 /* 912 * If we got multipath routes, we require users to specify 913 * a matching gateway. 914 */ 915 if (ISSET(rt->rt_flags, RTF_MPATH) && 916 info->rti_info[RTAX_GATEWAY] == NULL) { 917 error = ESRCH; 918 break; 919 } 920 921 /* Detaching an interface requires the KERNEL_LOCK(). */ 922 ifp = if_get(rt->rt_ifidx); 923 KASSERT(ifp != NULL); 924 925 /* 926 * Invalidate the cache of automagically created and 927 * referenced L2 entries to make sure that ``rt_gwroute'' 928 * pointer stays valid for other CPUs. 929 */ 930 if ((ISSET(rt->rt_flags, RTF_CACHED))) { 931 NET_LOCK(); 932 ifp->if_rtrequest(ifp, RTM_INVALIDATE, rt); 933 /* Reset the MTU of the gateway route. */ 934 rtable_walk(tableid, rt_key(rt)->sa_family, 935 route_cleargateway, rt); 936 NET_UNLOCK(); 937 if_put(ifp); 938 break; 939 } 940 941 /* 942 * Make sure that local routes are only modified by the 943 * kernel. 944 */ 945 if (ISSET(rt->rt_flags, RTF_LOCAL|RTF_BROADCAST)) { 946 if_put(ifp); 947 error = EINVAL; 948 break; 949 } 950 951 rtfree(rt); 952 rt = NULL; 953 954 NET_LOCK(); 955 error = rtrequest_delete(info, prio, ifp, &rt, tableid); 956 NET_UNLOCK(); 957 if_put(ifp); 958 break; 959 case RTM_CHANGE: 960 rt = rtable_lookup(tableid, info->rti_info[RTAX_DST], 961 info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], 962 prio); 963 /* 964 * If we got multipath routes, we require users to specify 965 * a matching gateway. 966 */ 967 if ((rt != NULL) && ISSET(rt->rt_flags, RTF_MPATH) && 968 (info->rti_info[RTAX_GATEWAY] == NULL)) { 969 rtfree(rt); 970 rt = NULL; 971 } 972 /* 973 * If RTAX_GATEWAY is the argument we're trying to 974 * change, try to find a compatible route. 975 */ 976 if ((rt == NULL) && (info->rti_info[RTAX_GATEWAY] != NULL) && 977 (rtm->rtm_type == RTM_CHANGE)) { 978 rt = rtable_lookup(tableid, info->rti_info[RTAX_DST], 979 info->rti_info[RTAX_NETMASK], NULL, prio); 980 /* Ensure we don't pick a multipath one. */ 981 if ((rt != NULL) && ISSET(rt->rt_flags, RTF_MPATH)) { 982 rtfree(rt); 983 rt = NULL; 984 } 985 } 986 987 if (rt == NULL) { 988 error = ESRCH; 989 break; 990 } 991 992 /* 993 * Make sure that local routes are only modified by the 994 * kernel. 995 */ 996 if (ISSET(rt->rt_flags, RTF_LOCAL|RTF_BROADCAST)) { 997 error = EINVAL; 998 break; 999 } 1000 1001 /* 1002 * RTM_CHANGE/LOCK need a perfect match. 1003 */ 1004 plen = rtable_satoplen(info->rti_info[RTAX_DST]->sa_family, 1005 info->rti_info[RTAX_NETMASK]); 1006 if (rt_plen(rt) != plen) { 1007 error = ESRCH; 1008 break; 1009 } 1010 1011 switch (rtm->rtm_type) { 1012 case RTM_CHANGE: 1013 if (info->rti_info[RTAX_GATEWAY] != NULL) 1014 if (rt->rt_gateway == NULL || 1015 bcmp(rt->rt_gateway, 1016 info->rti_info[RTAX_GATEWAY], 1017 info->rti_info[RTAX_GATEWAY]->sa_len)) { 1018 newgate = 1; 1019 } 1020 /* 1021 * Check reachable gateway before changing the route. 1022 * New gateway could require new ifaddr, ifp; 1023 * flags may also be different; ifp may be specified 1024 * by ll sockaddr when protocol address is ambiguous. 1025 */ 1026 if (newgate || info->rti_info[RTAX_IFP] != NULL || 1027 info->rti_info[RTAX_IFA] != NULL) { 1028 struct ifaddr *ifa = NULL; 1029 1030 NET_LOCK(); 1031 if ((error = rtm_getifa(info, tableid)) != 0) { 1032 NET_UNLOCK(); 1033 break; 1034 } 1035 ifa = info->rti_ifa; 1036 if (rt->rt_ifa != ifa) { 1037 ifp = if_get(rt->rt_ifidx); 1038 KASSERT(ifp != NULL); 1039 ifp->if_rtrequest(ifp, RTM_DELETE, rt); 1040 ifafree(rt->rt_ifa); 1041 if_put(ifp); 1042 1043 ifa->ifa_refcnt++; 1044 rt->rt_ifa = ifa; 1045 rt->rt_ifidx = ifa->ifa_ifp->if_index; 1046 /* recheck link state after ifp change*/ 1047 rt_if_linkstate_change(rt, ifa->ifa_ifp, 1048 tableid); 1049 } 1050 NET_UNLOCK(); 1051 } 1052 change: 1053 if (info->rti_info[RTAX_GATEWAY] != NULL) { 1054 /* 1055 * When updating the gateway, make sure it's 1056 * valid. 1057 */ 1058 if (!newgate && rt->rt_gateway->sa_family != 1059 info->rti_info[RTAX_GATEWAY]->sa_family) { 1060 error = EINVAL; 1061 break; 1062 } 1063 1064 NET_LOCK(); 1065 error = rt_setgate(rt, 1066 info->rti_info[RTAX_GATEWAY], tableid); 1067 NET_UNLOCK(); 1068 if (error) 1069 break; 1070 } 1071 #ifdef MPLS 1072 if (rtm->rtm_flags & RTF_MPLS) { 1073 NET_LOCK(); 1074 error = rt_mpls_set(rt, 1075 info->rti_info[RTAX_SRC], info->rti_mpls); 1076 NET_UNLOCK(); 1077 if (error) 1078 break; 1079 } else if (newgate || (rtm->rtm_fmask & RTF_MPLS)) { 1080 NET_LOCK(); 1081 /* if gateway changed remove MPLS information */ 1082 rt_mpls_clear(rt); 1083 NET_UNLOCK(); 1084 } 1085 #endif 1086 1087 #ifdef BFD 1088 if (ISSET(rtm->rtm_flags, RTF_BFD)) { 1089 if ((error = bfdset(rt))) 1090 break; 1091 } else if (!ISSET(rtm->rtm_flags, RTF_BFD) && 1092 ISSET(rtm->rtm_fmask, RTF_BFD)) { 1093 bfdclear(rt); 1094 } 1095 #endif 1096 1097 NET_LOCK(); 1098 /* Hack to allow some flags to be toggled */ 1099 if (rtm->rtm_fmask) { 1100 /* MPLS flag it is set by rt_mpls_set() */ 1101 rtm->rtm_fmask &= ~RTF_MPLS; 1102 rtm->rtm_flags &= ~RTF_MPLS; 1103 rt->rt_flags = 1104 (rt->rt_flags & ~rtm->rtm_fmask) | 1105 (rtm->rtm_flags & rtm->rtm_fmask); 1106 } 1107 rtm_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, 1108 &rt->rt_rmx); 1109 1110 ifp = if_get(rt->rt_ifidx); 1111 KASSERT(ifp != NULL); 1112 ifp->if_rtrequest(ifp, RTM_ADD, rt); 1113 if_put(ifp); 1114 1115 if (info->rti_info[RTAX_LABEL] != NULL) { 1116 char *rtlabel = ((struct sockaddr_rtlabel *) 1117 info->rti_info[RTAX_LABEL])->sr_label; 1118 rtlabel_unref(rt->rt_labelid); 1119 rt->rt_labelid = rtlabel_name2id(rtlabel); 1120 } 1121 if_group_routechange(info->rti_info[RTAX_DST], 1122 info->rti_info[RTAX_NETMASK]); 1123 rt->rt_locks &= ~(rtm->rtm_inits); 1124 rt->rt_locks |= 1125 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); 1126 NET_UNLOCK(); 1127 break; 1128 } 1129 break; 1130 case RTM_GET: 1131 rt = rtable_lookup(tableid, info->rti_info[RTAX_DST], 1132 info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], 1133 prio); 1134 if (rt == NULL) 1135 error = ESRCH; 1136 break; 1137 } 1138 1139 *prt = rt; 1140 return (error); 1141 } 1142 1143 struct ifaddr * 1144 ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, 1145 unsigned int rtableid) 1146 { 1147 struct ifaddr *ifa; 1148 1149 if ((flags & RTF_GATEWAY) == 0) { 1150 /* 1151 * If we are adding a route to an interface, 1152 * and the interface is a pt to pt link 1153 * we should search for the destination 1154 * as our clue to the interface. Otherwise 1155 * we can use the local address. 1156 */ 1157 ifa = NULL; 1158 if (flags & RTF_HOST) 1159 ifa = ifa_ifwithdstaddr(dst, rtableid); 1160 if (ifa == NULL) 1161 ifa = ifa_ifwithaddr(gateway, rtableid); 1162 } else { 1163 /* 1164 * If we are adding a route to a remote net 1165 * or host, the gateway may still be on the 1166 * other end of a pt to pt link. 1167 */ 1168 ifa = ifa_ifwithdstaddr(gateway, rtableid); 1169 } 1170 if (ifa == NULL) { 1171 if (gateway->sa_family == AF_LINK) { 1172 struct sockaddr_dl *sdl = satosdl(gateway); 1173 struct ifnet *ifp = if_get(sdl->sdl_index); 1174 1175 if (ifp != NULL) 1176 ifa = ifaof_ifpforaddr(dst, ifp); 1177 if_put(ifp); 1178 } else { 1179 struct rtentry *rt; 1180 1181 rt = rtalloc(gateway, RT_RESOLVE, rtable_l2(rtableid)); 1182 if (rt != NULL) 1183 ifa = rt->rt_ifa; 1184 rtfree(rt); 1185 } 1186 } 1187 if (ifa == NULL) 1188 return (NULL); 1189 if (ifa->ifa_addr->sa_family != dst->sa_family) { 1190 struct ifaddr *oifa = ifa; 1191 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 1192 if (ifa == NULL) 1193 ifa = oifa; 1194 } 1195 return (ifa); 1196 } 1197 1198 int 1199 rtm_getifa(struct rt_addrinfo *info, unsigned int rtid) 1200 { 1201 struct ifnet *ifp = NULL; 1202 1203 /* 1204 * The "returned" `ifa' is guaranteed to be alive only if 1205 * the NET_LOCK() is held. 1206 */ 1207 NET_ASSERT_LOCKED(); 1208 1209 /* 1210 * ifp may be specified by sockaddr_dl when protocol address 1211 * is ambiguous 1212 */ 1213 if (info->rti_info[RTAX_IFP] != NULL) { 1214 struct sockaddr_dl *sdl; 1215 1216 sdl = satosdl(info->rti_info[RTAX_IFP]); 1217 ifp = if_get(sdl->sdl_index); 1218 } 1219 1220 #ifdef IPSEC 1221 /* 1222 * If the destination is a PF_KEY address, we'll look 1223 * for the existence of a encap interface number or address 1224 * in the options list of the gateway. By default, we'll return 1225 * enc0. 1226 */ 1227 if (info->rti_info[RTAX_DST] && 1228 info->rti_info[RTAX_DST]->sa_family == PF_KEY) 1229 info->rti_ifa = enc_getifa(rtid, 0); 1230 #endif 1231 1232 if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL) 1233 info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid); 1234 1235 if (info->rti_ifa == NULL) { 1236 struct sockaddr *sa; 1237 1238 if ((sa = info->rti_info[RTAX_IFA]) == NULL) 1239 if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL) 1240 sa = info->rti_info[RTAX_DST]; 1241 1242 if (sa != NULL && ifp != NULL) 1243 info->rti_ifa = ifaof_ifpforaddr(sa, ifp); 1244 else if (info->rti_info[RTAX_DST] != NULL && 1245 info->rti_info[RTAX_GATEWAY] != NULL) 1246 info->rti_ifa = ifa_ifwithroute(info->rti_flags, 1247 info->rti_info[RTAX_DST], 1248 info->rti_info[RTAX_GATEWAY], 1249 rtid); 1250 else if (sa != NULL) 1251 info->rti_ifa = ifa_ifwithroute(info->rti_flags, 1252 sa, sa, rtid); 1253 } 1254 1255 if_put(ifp); 1256 1257 if (info->rti_ifa == NULL) 1258 return (ENETUNREACH); 1259 1260 return (0); 1261 } 1262 1263 int 1264 route_cleargateway(struct rtentry *rt, void *arg, unsigned int rtableid) 1265 { 1266 struct rtentry *nhrt = arg; 1267 1268 if (ISSET(rt->rt_flags, RTF_GATEWAY) && rt->rt_gwroute == nhrt && 1269 !ISSET(rt->rt_locks, RTV_MTU)) 1270 rt->rt_mtu = 0; 1271 1272 return (0); 1273 } 1274 1275 /* 1276 * Check if the user request to insert an ARP entry does not conflict 1277 * with existing ones. 1278 * 1279 * Only two entries are allowed for a given IP address: a private one 1280 * (priv) and a public one (pub). 1281 */ 1282 int 1283 route_arp_conflict(struct rtentry *rt, struct rt_addrinfo *info) 1284 { 1285 int proxy = (info->rti_flags & RTF_ANNOUNCE); 1286 1287 if ((info->rti_flags & RTF_LLINFO) == 0 || 1288 (info->rti_info[RTAX_DST]->sa_family != AF_INET)) 1289 return (0); 1290 1291 if (rt == NULL || !ISSET(rt->rt_flags, RTF_LLINFO)) 1292 return (0); 1293 1294 /* If the entry is cached, it can be updated. */ 1295 if (ISSET(rt->rt_flags, RTF_CACHED)) 1296 return (0); 1297 1298 /* 1299 * Same destination, not cached and both "priv" or "pub" conflict. 1300 * If a second entry exists, it always conflict. 1301 */ 1302 if ((ISSET(rt->rt_flags, RTF_ANNOUNCE) == proxy) || 1303 ISSET(rt->rt_flags, RTF_MPATH)) 1304 return (EEXIST); 1305 1306 /* No conflict but an entry exist so we need to force mpath. */ 1307 info->rti_flags |= RTF_MPATH; 1308 return (0); 1309 } 1310 1311 void 1312 rtm_setmetrics(u_long which, const struct rt_metrics *in, 1313 struct rt_kmetrics *out) 1314 { 1315 int64_t expire; 1316 1317 if (which & RTV_MTU) 1318 out->rmx_mtu = in->rmx_mtu; 1319 if (which & RTV_EXPIRE) { 1320 expire = in->rmx_expire; 1321 if (expire != 0) { 1322 expire -= time_second; 1323 expire += time_uptime; 1324 } 1325 1326 out->rmx_expire = expire; 1327 } 1328 } 1329 1330 void 1331 rtm_getmetrics(const struct rt_kmetrics *in, struct rt_metrics *out) 1332 { 1333 int64_t expire; 1334 1335 expire = in->rmx_expire; 1336 if (expire != 0) { 1337 expire -= time_uptime; 1338 expire += time_second; 1339 } 1340 1341 bzero(out, sizeof(*out)); 1342 out->rmx_locks = in->rmx_locks; 1343 out->rmx_mtu = in->rmx_mtu; 1344 out->rmx_expire = expire; 1345 out->rmx_pksent = in->rmx_pksent; 1346 } 1347 1348 #define ROUNDUP(a) \ 1349 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 1350 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 1351 1352 int 1353 rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) 1354 { 1355 struct sockaddr *sa; 1356 int i; 1357 1358 bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); 1359 for (i = 0; i < sizeof(rtinfo->rti_addrs) * 8; i++) { 1360 if ((rtinfo->rti_addrs & (1 << i)) == 0) 1361 continue; 1362 if (i >= RTAX_MAX || cp + sizeof(socklen_t) > cplim) { 1363 /* 1364 * Clear invalid bits, userland code may set them. 1365 * After OpenBSD 6.5 release, fix OpenVPN, remove 1366 * this workaround, and return EINVAL. XXX 1367 */ 1368 rtinfo->rti_addrs &= (1 << i) - 1; 1369 break; 1370 } 1371 sa = (struct sockaddr *)cp; 1372 if (cp + sa->sa_len > cplim) 1373 return (EINVAL); 1374 rtinfo->rti_info[i] = sa; 1375 ADVANCE(cp, sa); 1376 } 1377 return (0); 1378 } 1379 1380 struct mbuf * 1381 rtm_msg1(int type, struct rt_addrinfo *rtinfo) 1382 { 1383 struct rt_msghdr *rtm; 1384 struct mbuf *m; 1385 int i; 1386 struct sockaddr *sa; 1387 int len, dlen, hlen; 1388 1389 switch (type) { 1390 case RTM_DELADDR: 1391 case RTM_NEWADDR: 1392 len = sizeof(struct ifa_msghdr); 1393 break; 1394 case RTM_IFINFO: 1395 len = sizeof(struct if_msghdr); 1396 break; 1397 case RTM_IFANNOUNCE: 1398 len = sizeof(struct if_announcemsghdr); 1399 break; 1400 #ifdef BFD 1401 case RTM_BFD: 1402 len = sizeof(struct bfd_msghdr); 1403 break; 1404 #endif 1405 case RTM_80211INFO: 1406 len = sizeof(struct if_ieee80211_msghdr); 1407 break; 1408 default: 1409 len = sizeof(struct rt_msghdr); 1410 break; 1411 } 1412 if (len > MCLBYTES) 1413 panic("rtm_msg1"); 1414 m = m_gethdr(M_DONTWAIT, MT_DATA); 1415 if (m && len > MHLEN) { 1416 MCLGET(m, M_DONTWAIT); 1417 if ((m->m_flags & M_EXT) == 0) { 1418 m_free(m); 1419 m = NULL; 1420 } 1421 } 1422 if (m == NULL) 1423 return (m); 1424 m->m_pkthdr.len = m->m_len = hlen = len; 1425 m->m_pkthdr.ph_ifidx = 0; 1426 rtm = mtod(m, struct rt_msghdr *); 1427 bzero(rtm, len); 1428 for (i = 0; i < RTAX_MAX; i++) { 1429 if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL) 1430 continue; 1431 rtinfo->rti_addrs |= (1 << i); 1432 dlen = ROUNDUP(sa->sa_len); 1433 if (m_copyback(m, len, dlen, sa, M_NOWAIT)) { 1434 m_freem(m); 1435 return (NULL); 1436 } 1437 len += dlen; 1438 } 1439 rtm->rtm_msglen = len; 1440 rtm->rtm_hdrlen = hlen; 1441 rtm->rtm_version = RTM_VERSION; 1442 rtm->rtm_type = type; 1443 return (m); 1444 } 1445 1446 int 1447 rtm_msg2(int type, int vers, struct rt_addrinfo *rtinfo, caddr_t cp, 1448 struct walkarg *w) 1449 { 1450 int i; 1451 int len, dlen, hlen, second_time = 0; 1452 caddr_t cp0; 1453 1454 rtinfo->rti_addrs = 0; 1455 again: 1456 switch (type) { 1457 case RTM_DELADDR: 1458 case RTM_NEWADDR: 1459 len = sizeof(struct ifa_msghdr); 1460 break; 1461 case RTM_IFINFO: 1462 len = sizeof(struct if_msghdr); 1463 break; 1464 default: 1465 len = sizeof(struct rt_msghdr); 1466 break; 1467 } 1468 hlen = len; 1469 if ((cp0 = cp) != NULL) 1470 cp += len; 1471 for (i = 0; i < RTAX_MAX; i++) { 1472 struct sockaddr *sa; 1473 1474 if ((sa = rtinfo->rti_info[i]) == NULL) 1475 continue; 1476 rtinfo->rti_addrs |= (1 << i); 1477 dlen = ROUNDUP(sa->sa_len); 1478 if (cp) { 1479 bcopy(sa, cp, (size_t)dlen); 1480 cp += dlen; 1481 } 1482 len += dlen; 1483 } 1484 /* align message length to the next natural boundary */ 1485 len = ALIGN(len); 1486 if (cp == 0 && w != NULL && !second_time) { 1487 w->w_needed += len; 1488 if (w->w_needed <= 0 && w->w_where) { 1489 if (w->w_tmemsize < len) { 1490 free(w->w_tmem, M_RTABLE, w->w_tmemsize); 1491 w->w_tmem = malloc(len, M_RTABLE, 1492 M_NOWAIT | M_ZERO); 1493 if (w->w_tmem) 1494 w->w_tmemsize = len; 1495 } 1496 if (w->w_tmem) { 1497 cp = w->w_tmem; 1498 second_time = 1; 1499 goto again; 1500 } else 1501 w->w_where = 0; 1502 } 1503 } 1504 if (cp && w) /* clear the message header */ 1505 bzero(cp0, hlen); 1506 1507 if (cp) { 1508 struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; 1509 1510 rtm->rtm_version = RTM_VERSION; 1511 rtm->rtm_type = type; 1512 rtm->rtm_msglen = len; 1513 rtm->rtm_hdrlen = hlen; 1514 } 1515 return (len); 1516 } 1517 1518 void 1519 rtm_send(struct rtentry *rt, int cmd, int error, unsigned int rtableid) 1520 { 1521 struct rt_addrinfo info; 1522 struct ifnet *ifp; 1523 struct sockaddr_rtlabel sa_rl; 1524 struct sockaddr_in6 sa_mask; 1525 1526 memset(&info, 0, sizeof(info)); 1527 info.rti_info[RTAX_DST] = rt_key(rt); 1528 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1529 if (!ISSET(rt->rt_flags, RTF_HOST)) 1530 info.rti_info[RTAX_NETMASK] = rt_plen2mask(rt, &sa_mask); 1531 info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, &sa_rl); 1532 ifp = if_get(rt->rt_ifidx); 1533 if (ifp != NULL) { 1534 info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); 1535 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1536 } 1537 1538 rtm_miss(cmd, &info, rt->rt_flags, rt->rt_priority, rt->rt_ifidx, error, 1539 rtableid); 1540 if_put(ifp); 1541 } 1542 1543 /* 1544 * This routine is called to generate a message from the routing 1545 * socket indicating that a redirect has occurred, a routing lookup 1546 * has failed, or that a protocol has detected timeouts to a particular 1547 * destination. 1548 */ 1549 void 1550 rtm_miss(int type, struct rt_addrinfo *rtinfo, int flags, uint8_t prio, 1551 u_int ifidx, int error, u_int tableid) 1552 { 1553 struct rt_msghdr *rtm; 1554 struct mbuf *m; 1555 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; 1556 1557 if (rtptable.rtp_count == 0) 1558 return; 1559 m = rtm_msg1(type, rtinfo); 1560 if (m == NULL) 1561 return; 1562 rtm = mtod(m, struct rt_msghdr *); 1563 rtm->rtm_flags = RTF_DONE | flags; 1564 rtm->rtm_priority = prio; 1565 rtm->rtm_errno = error; 1566 rtm->rtm_tableid = tableid; 1567 rtm->rtm_addrs = rtinfo->rti_addrs; 1568 rtm->rtm_index = ifidx; 1569 route_input(m, NULL, sa ? sa->sa_family : AF_UNSPEC); 1570 } 1571 1572 /* 1573 * This routine is called to generate a message from the routing 1574 * socket indicating that the status of a network interface has changed. 1575 */ 1576 void 1577 rtm_ifchg(struct ifnet *ifp) 1578 { 1579 struct if_msghdr *ifm; 1580 struct mbuf *m; 1581 1582 if (rtptable.rtp_count == 0) 1583 return; 1584 m = rtm_msg1(RTM_IFINFO, NULL); 1585 if (m == NULL) 1586 return; 1587 ifm = mtod(m, struct if_msghdr *); 1588 ifm->ifm_index = ifp->if_index; 1589 ifm->ifm_tableid = ifp->if_rdomain; 1590 ifm->ifm_flags = ifp->if_flags; 1591 ifm->ifm_xflags = ifp->if_xflags; 1592 if_getdata(ifp, &ifm->ifm_data); 1593 ifm->ifm_addrs = 0; 1594 route_input(m, NULL, AF_UNSPEC); 1595 } 1596 1597 /* 1598 * This is called to generate messages from the routing socket 1599 * indicating a network interface has had addresses associated with it. 1600 * if we ever reverse the logic and replace messages TO the routing 1601 * socket indicate a request to configure interfaces, then it will 1602 * be unnecessary as the routing socket will automatically generate 1603 * copies of it. 1604 */ 1605 void 1606 rtm_addr(int cmd, struct ifaddr *ifa) 1607 { 1608 struct ifnet *ifp = ifa->ifa_ifp; 1609 struct mbuf *m; 1610 struct rt_addrinfo info; 1611 struct ifa_msghdr *ifam; 1612 1613 if (rtptable.rtp_count == 0) 1614 return; 1615 1616 memset(&info, 0, sizeof(info)); 1617 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1618 info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); 1619 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1620 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1621 if ((m = rtm_msg1(cmd, &info)) == NULL) 1622 return; 1623 ifam = mtod(m, struct ifa_msghdr *); 1624 ifam->ifam_index = ifp->if_index; 1625 ifam->ifam_metric = ifa->ifa_metric; 1626 ifam->ifam_flags = ifa->ifa_flags; 1627 ifam->ifam_addrs = info.rti_addrs; 1628 ifam->ifam_tableid = ifp->if_rdomain; 1629 1630 route_input(m, NULL, 1631 ifa->ifa_addr ? ifa->ifa_addr->sa_family : AF_UNSPEC); 1632 } 1633 1634 /* 1635 * This is called to generate routing socket messages indicating 1636 * network interface arrival and departure. 1637 */ 1638 void 1639 rtm_ifannounce(struct ifnet *ifp, int what) 1640 { 1641 struct if_announcemsghdr *ifan; 1642 struct mbuf *m; 1643 1644 if (rtptable.rtp_count == 0) 1645 return; 1646 m = rtm_msg1(RTM_IFANNOUNCE, NULL); 1647 if (m == NULL) 1648 return; 1649 ifan = mtod(m, struct if_announcemsghdr *); 1650 ifan->ifan_index = ifp->if_index; 1651 strlcpy(ifan->ifan_name, ifp->if_xname, sizeof(ifan->ifan_name)); 1652 ifan->ifan_what = what; 1653 route_input(m, NULL, AF_UNSPEC); 1654 } 1655 1656 #ifdef BFD 1657 /* 1658 * This is used to generate routing socket messages indicating 1659 * the state of a BFD session. 1660 */ 1661 void 1662 rtm_bfd(struct bfd_config *bfd) 1663 { 1664 struct bfd_msghdr *bfdm; 1665 struct sockaddr_bfd sa_bfd; 1666 struct mbuf *m; 1667 struct rt_addrinfo info; 1668 1669 if (rtptable.rtp_count == 0) 1670 return; 1671 memset(&info, 0, sizeof(info)); 1672 info.rti_info[RTAX_DST] = rt_key(bfd->bc_rt); 1673 info.rti_info[RTAX_IFA] = bfd->bc_rt->rt_ifa->ifa_addr; 1674 1675 m = rtm_msg1(RTM_BFD, &info); 1676 if (m == NULL) 1677 return; 1678 bfdm = mtod(m, struct bfd_msghdr *); 1679 bfdm->bm_addrs = info.rti_addrs; 1680 1681 bfd2sa(bfd->bc_rt, &sa_bfd); 1682 memcpy(&bfdm->bm_sa, &sa_bfd, sizeof(sa_bfd)); 1683 1684 route_input(m, NULL, info.rti_info[RTAX_DST]->sa_family); 1685 } 1686 #endif /* BFD */ 1687 1688 /* 1689 * This is used to generate routing socket messages indicating 1690 * the state of an ieee80211 interface. 1691 */ 1692 void 1693 rtm_80211info(struct ifnet *ifp, struct if_ieee80211_data *ifie) 1694 { 1695 struct if_ieee80211_msghdr *ifim; 1696 struct mbuf *m; 1697 1698 if (rtptable.rtp_count == 0) 1699 return; 1700 m = rtm_msg1(RTM_80211INFO, NULL); 1701 if (m == NULL) 1702 return; 1703 ifim = mtod(m, struct if_ieee80211_msghdr *); 1704 ifim->ifim_index = ifp->if_index; 1705 ifim->ifim_tableid = ifp->if_rdomain; 1706 1707 memcpy(&ifim->ifim_ifie, ifie, sizeof(ifim->ifim_ifie)); 1708 route_input(m, NULL, AF_UNSPEC); 1709 } 1710 1711 /* 1712 * This is used in dumping the kernel table via sysctl(). 1713 */ 1714 int 1715 sysctl_dumpentry(struct rtentry *rt, void *v, unsigned int id) 1716 { 1717 struct walkarg *w = v; 1718 int error = 0, size; 1719 struct rt_addrinfo info; 1720 struct ifnet *ifp; 1721 #ifdef BFD 1722 struct sockaddr_bfd sa_bfd; 1723 #endif 1724 struct sockaddr_rtlabel sa_rl; 1725 struct sockaddr_in6 sa_mask; 1726 1727 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1728 return 0; 1729 if (w->w_op == NET_RT_DUMP && w->w_arg) { 1730 u_int8_t prio = w->w_arg & RTP_MASK; 1731 if (w->w_arg < 0) { 1732 prio = (-w->w_arg) & RTP_MASK; 1733 /* Show all routes that are not this priority */ 1734 if (prio == (rt->rt_priority & RTP_MASK)) 1735 return 0; 1736 } else { 1737 if (prio != (rt->rt_priority & RTP_MASK) && 1738 prio != RTP_ANY) 1739 return 0; 1740 } 1741 } 1742 bzero(&info, sizeof(info)); 1743 info.rti_info[RTAX_DST] = rt_key(rt); 1744 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1745 info.rti_info[RTAX_NETMASK] = rt_plen2mask(rt, &sa_mask); 1746 ifp = if_get(rt->rt_ifidx); 1747 if (ifp != NULL) { 1748 info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); 1749 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1750 if (ifp->if_flags & IFF_POINTOPOINT) 1751 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 1752 } 1753 if_put(ifp); 1754 info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, &sa_rl); 1755 #ifdef BFD 1756 if (rt->rt_flags & RTF_BFD) 1757 info.rti_info[RTAX_BFD] = bfd2sa(rt, &sa_bfd); 1758 #endif 1759 #ifdef MPLS 1760 if (rt->rt_flags & RTF_MPLS) { 1761 struct sockaddr_mpls sa_mpls; 1762 1763 bzero(&sa_mpls, sizeof(sa_mpls)); 1764 sa_mpls.smpls_family = AF_MPLS; 1765 sa_mpls.smpls_len = sizeof(sa_mpls); 1766 sa_mpls.smpls_label = ((struct rt_mpls *) 1767 rt->rt_llinfo)->mpls_label; 1768 info.rti_info[RTAX_SRC] = (struct sockaddr *)&sa_mpls; 1769 info.rti_mpls = ((struct rt_mpls *) 1770 rt->rt_llinfo)->mpls_operation; 1771 } 1772 #endif 1773 1774 size = rtm_msg2(RTM_GET, RTM_VERSION, &info, NULL, w); 1775 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1776 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 1777 1778 rtm->rtm_pid = curproc->p_p->ps_pid; 1779 rtm->rtm_flags = rt->rt_flags; 1780 rtm->rtm_priority = rt->rt_priority & RTP_MASK; 1781 rtm_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); 1782 /* Do not account the routing table's reference. */ 1783 rtm->rtm_rmx.rmx_refcnt = rt->rt_refcnt - 1; 1784 rtm->rtm_index = rt->rt_ifidx; 1785 rtm->rtm_addrs = info.rti_addrs; 1786 rtm->rtm_tableid = id; 1787 #ifdef MPLS 1788 rtm->rtm_mpls = info.rti_mpls; 1789 #endif 1790 if ((error = copyout(rtm, w->w_where, size)) != 0) 1791 w->w_where = NULL; 1792 else 1793 w->w_where += size; 1794 } 1795 return (error); 1796 } 1797 1798 int 1799 sysctl_iflist(int af, struct walkarg *w) 1800 { 1801 struct ifnet *ifp; 1802 struct ifaddr *ifa; 1803 struct rt_addrinfo info; 1804 int len, error = 0; 1805 1806 bzero(&info, sizeof(info)); 1807 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1808 if (w->w_arg && w->w_arg != ifp->if_index) 1809 continue; 1810 /* Copy the link-layer address first */ 1811 info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); 1812 len = rtm_msg2(RTM_IFINFO, RTM_VERSION, &info, 0, w); 1813 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1814 struct if_msghdr *ifm; 1815 1816 ifm = (struct if_msghdr *)w->w_tmem; 1817 ifm->ifm_index = ifp->if_index; 1818 ifm->ifm_tableid = ifp->if_rdomain; 1819 ifm->ifm_flags = ifp->if_flags; 1820 if_getdata(ifp, &ifm->ifm_data); 1821 ifm->ifm_addrs = info.rti_addrs; 1822 error = copyout(ifm, w->w_where, len); 1823 if (error) 1824 return (error); 1825 w->w_where += len; 1826 } 1827 info.rti_info[RTAX_IFP] = NULL; 1828 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1829 KASSERT(ifa->ifa_addr->sa_family != AF_LINK); 1830 if (af && af != ifa->ifa_addr->sa_family) 1831 continue; 1832 info.rti_info[RTAX_IFA] = ifa->ifa_addr; 1833 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; 1834 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; 1835 len = rtm_msg2(RTM_NEWADDR, RTM_VERSION, &info, 0, w); 1836 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 1837 struct ifa_msghdr *ifam; 1838 1839 ifam = (struct ifa_msghdr *)w->w_tmem; 1840 ifam->ifam_index = ifa->ifa_ifp->if_index; 1841 ifam->ifam_flags = ifa->ifa_flags; 1842 ifam->ifam_metric = ifa->ifa_metric; 1843 ifam->ifam_addrs = info.rti_addrs; 1844 error = copyout(w->w_tmem, w->w_where, len); 1845 if (error) 1846 return (error); 1847 w->w_where += len; 1848 } 1849 } 1850 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = 1851 info.rti_info[RTAX_BRD] = NULL; 1852 } 1853 return (0); 1854 } 1855 1856 int 1857 sysctl_ifnames(struct walkarg *w) 1858 { 1859 struct if_nameindex_msg ifn; 1860 struct ifnet *ifp; 1861 int error = 0; 1862 1863 /* XXX ignore tableid for now */ 1864 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1865 if (w->w_arg && w->w_arg != ifp->if_index) 1866 continue; 1867 w->w_needed += sizeof(ifn); 1868 if (w->w_where && w->w_needed <= 0) { 1869 1870 memset(&ifn, 0, sizeof(ifn)); 1871 ifn.if_index = ifp->if_index; 1872 strlcpy(ifn.if_name, ifp->if_xname, 1873 sizeof(ifn.if_name)); 1874 error = copyout(&ifn, w->w_where, sizeof(ifn)); 1875 if (error) 1876 return (error); 1877 w->w_where += sizeof(ifn); 1878 } 1879 } 1880 1881 return (0); 1882 } 1883 1884 int 1885 sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, 1886 size_t newlen) 1887 { 1888 int i, error = EINVAL; 1889 u_char af; 1890 struct walkarg w; 1891 struct rt_tableinfo tableinfo; 1892 u_int tableid = 0; 1893 1894 if (new) 1895 return (EPERM); 1896 if (namelen < 3 || namelen > 4) 1897 return (EINVAL); 1898 af = name[0]; 1899 bzero(&w, sizeof(w)); 1900 w.w_where = where; 1901 w.w_given = *given; 1902 w.w_needed = 0 - w.w_given; 1903 w.w_op = name[1]; 1904 w.w_arg = name[2]; 1905 1906 if (namelen == 4) { 1907 tableid = name[3]; 1908 if (!rtable_exists(tableid)) 1909 return (ENOENT); 1910 } else 1911 tableid = curproc->p_p->ps_rtableid; 1912 1913 switch (w.w_op) { 1914 case NET_RT_DUMP: 1915 case NET_RT_FLAGS: 1916 NET_LOCK(); 1917 for (i = 1; i <= AF_MAX; i++) { 1918 if (af != 0 && af != i) 1919 continue; 1920 1921 error = rtable_walk(tableid, i, sysctl_dumpentry, &w); 1922 if (error == EAFNOSUPPORT) 1923 error = 0; 1924 if (error) 1925 break; 1926 } 1927 NET_UNLOCK(); 1928 break; 1929 1930 case NET_RT_IFLIST: 1931 NET_LOCK(); 1932 error = sysctl_iflist(af, &w); 1933 NET_UNLOCK(); 1934 break; 1935 1936 case NET_RT_STATS: 1937 return (sysctl_rtable_rtstat(where, given, new)); 1938 case NET_RT_TABLE: 1939 tableid = w.w_arg; 1940 if (!rtable_exists(tableid)) 1941 return (ENOENT); 1942 memset(&tableinfo, 0, sizeof tableinfo); 1943 tableinfo.rti_tableid = tableid; 1944 tableinfo.rti_domainid = rtable_l2(tableid); 1945 error = sysctl_rdstruct(where, given, new, 1946 &tableinfo, sizeof(tableinfo)); 1947 return (error); 1948 case NET_RT_IFNAMES: 1949 NET_LOCK(); 1950 error = sysctl_ifnames(&w); 1951 NET_UNLOCK(); 1952 break; 1953 } 1954 free(w.w_tmem, M_RTABLE, w.w_tmemsize); 1955 w.w_needed += w.w_given; 1956 if (where) { 1957 *given = w.w_where - (caddr_t)where; 1958 if (*given < w.w_needed) 1959 return (ENOMEM); 1960 } else 1961 *given = (11 * w.w_needed) / 10; 1962 1963 return (error); 1964 } 1965 1966 int 1967 sysctl_rtable_rtstat(void *oldp, size_t *oldlenp, void *newp) 1968 { 1969 extern struct cpumem *rtcounters; 1970 uint64_t counters[rts_ncounters]; 1971 struct rtstat rtstat; 1972 uint32_t *words = (uint32_t *)&rtstat; 1973 int i; 1974 1975 CTASSERT(sizeof(rtstat) == (nitems(counters) * sizeof(uint32_t))); 1976 memset(&rtstat, 0, sizeof rtstat); 1977 counters_read(rtcounters, counters, nitems(counters)); 1978 1979 for (i = 0; i < nitems(counters); i++) 1980 words[i] = (uint32_t)counters[i]; 1981 1982 return (sysctl_rdstruct(oldp, oldlenp, newp, &rtstat, sizeof(rtstat))); 1983 } 1984 1985 int 1986 rtm_validate_proposal(struct rt_addrinfo *info) 1987 { 1988 if (info->rti_addrs & ~(RTA_NETMASK | RTA_IFA | RTA_DNS | RTA_STATIC | 1989 RTA_SEARCH)) { 1990 return -1; 1991 } 1992 1993 if (ISSET(info->rti_addrs, RTA_NETMASK)) { 1994 struct sockaddr *sa = info->rti_info[RTAX_NETMASK]; 1995 if (sa == NULL) 1996 return -1; 1997 switch (sa->sa_family) { 1998 case AF_INET: 1999 if (sa->sa_len != sizeof(struct sockaddr_in)) 2000 return -1; 2001 break; 2002 case AF_INET6: 2003 if (sa->sa_len != sizeof(struct sockaddr_in6)) 2004 return -1; 2005 break; 2006 default: 2007 return -1; 2008 } 2009 } 2010 2011 if (ISSET(info->rti_addrs, RTA_IFA)) { 2012 struct sockaddr *sa = info->rti_info[RTAX_IFA]; 2013 if (sa == NULL) 2014 return -1; 2015 switch (sa->sa_family) { 2016 case AF_INET: 2017 if (sa->sa_len != sizeof(struct sockaddr_in)) 2018 return -1; 2019 break; 2020 case AF_INET6: 2021 if (sa->sa_len != sizeof(struct sockaddr_in6)) 2022 return -1; 2023 break; 2024 default: 2025 return -1; 2026 } 2027 } 2028 2029 if (ISSET(info->rti_addrs, RTA_DNS)) { 2030 struct sockaddr_rtdns *rtdns = 2031 (struct sockaddr_rtdns *)info->rti_info[RTAX_DNS]; 2032 if (rtdns == NULL) 2033 return -1; 2034 if (rtdns->sr_len > sizeof(*rtdns)) 2035 return -1; 2036 if (rtdns->sr_len <= 2037 offsetof(struct sockaddr_rtdns, sr_dns)) 2038 return -1; 2039 } 2040 2041 if (ISSET(info->rti_addrs, RTA_STATIC)) { 2042 struct sockaddr_rtstatic *rtstatic = 2043 (struct sockaddr_rtstatic *)info->rti_info[RTAX_STATIC]; 2044 if (rtstatic == NULL) 2045 return -1; 2046 if (rtstatic->sr_len > sizeof(*rtstatic)) 2047 return -1; 2048 if (rtstatic->sr_len <= 2049 offsetof(struct sockaddr_rtstatic, sr_static)) 2050 return -1; 2051 } 2052 2053 if (ISSET(info->rti_addrs, RTA_SEARCH)) { 2054 struct sockaddr_rtsearch *rtsearch = 2055 (struct sockaddr_rtsearch *)info->rti_info[RTAX_SEARCH]; 2056 if (rtsearch == NULL) 2057 return -1; 2058 if (rtsearch->sr_len > sizeof(*rtsearch)) 2059 return -1; 2060 if (rtsearch->sr_len <= 2061 offsetof(struct sockaddr_rtsearch, sr_search)) 2062 return -1; 2063 } 2064 2065 return 0; 2066 } 2067 2068 /* 2069 * Definitions of protocols supported in the ROUTE domain. 2070 */ 2071 2072 extern struct domain routedomain; /* or at least forward */ 2073 2074 struct protosw routesw[] = { 2075 { 2076 .pr_type = SOCK_RAW, 2077 .pr_domain = &routedomain, 2078 .pr_flags = PR_ATOMIC|PR_ADDR|PR_WANTRCVD, 2079 .pr_output = route_output, 2080 .pr_ctloutput = route_ctloutput, 2081 .pr_usrreq = route_usrreq, 2082 .pr_attach = route_attach, 2083 .pr_detach = route_detach, 2084 .pr_init = route_prinit, 2085 .pr_sysctl = sysctl_rtable 2086 } 2087 }; 2088 2089 struct domain routedomain = { 2090 .dom_family = PF_ROUTE, 2091 .dom_name = "route", 2092 .dom_init = route_init, 2093 .dom_protosw = routesw, 2094 .dom_protoswNPROTOSW = &routesw[nitems(routesw)] 2095 }; 2096