1 /* $OpenBSD: ip_mroute.c,v 1.130 2020/05/27 11:19:29 mpi Exp $ */ 2 /* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */ 3 4 /* 5 * Copyright (c) 1989 Stephen Deering 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Stephen Deering of Stanford University. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)ip_mroute.c 8.2 (Berkeley) 11/15/93 37 */ 38 39 /* 40 * IP multicast forwarding procedures 41 * 42 * Written by David Waitzman, BBN Labs, August 1988. 43 * Modified by Steve Deering, Stanford, February 1989. 44 * Modified by Mark J. Steiglitz, Stanford, May, 1991 45 * Modified by Van Jacobson, LBL, January 1993 46 * Modified by Ajit Thyagarajan, PARC, August 1993 47 * Modified by Bill Fenner, PARC, April 1994 48 * Modified by Charles M. Hannum, NetBSD, May 1995. 49 * Modified by Ahmed Helmy, SGI, June 1996 50 * Modified by George Edmond Eddy (Rusty), ISI, February 1998 51 * Modified by Pavlin Radoslavov, USC/ISI, May 1998, August 1999, October 2000 52 * Modified by Hitoshi Asaeda, WIDE, August 2000 53 * Modified by Pavlin Radoslavov, ICSI, October 2002 54 * 55 * MROUTING Revision: 1.2 56 * advanced API support, bandwidth metering and signaling 57 */ 58 59 #include <sys/param.h> 60 #include <sys/systm.h> 61 #include <sys/mbuf.h> 62 #include <sys/socket.h> 63 #include <sys/socketvar.h> 64 #include <sys/protosw.h> 65 #include <sys/ioctl.h> 66 #include <sys/syslog.h> 67 68 #include <net/if.h> 69 #include <net/if_var.h> 70 #include <net/route.h> 71 72 #include <netinet/in.h> 73 #include <netinet/ip.h> 74 #include <netinet/ip_var.h> 75 #include <netinet/in_pcb.h> 76 #include <netinet/igmp.h> 77 #include <netinet/ip_mroute.h> 78 79 /* #define MCAST_DEBUG */ 80 81 #ifdef MCAST_DEBUG 82 int mcast_debug = 1; 83 #define DPRINTF(fmt, args...) \ 84 do { \ 85 if (mcast_debug) \ 86 printf("%s:%d " fmt "\n", \ 87 __func__, __LINE__, ## args); \ 88 } while (0) 89 #else 90 #define DPRINTF(fmt, args...) \ 91 do { } while (0) 92 #endif 93 94 /* 95 * Globals. All but ip_mrouter and ip_mrtproto could be static, 96 * except for netstat or debugging purposes. 97 */ 98 struct socket *ip_mrouter[RT_TABLEID_MAX + 1]; 99 struct rttimer_queue *mrouterq[RT_TABLEID_MAX + 1]; 100 uint64_t mrt_count[RT_TABLEID_MAX + 1]; 101 int ip_mrtproto = IGMP_DVMRP; /* for netstat only */ 102 103 struct mrtstat mrtstat; 104 105 struct rtentry *mfc_find(struct ifnet *, struct in_addr *, 106 struct in_addr *, unsigned int); 107 int get_sg_cnt(unsigned int, struct sioc_sg_req *); 108 int get_vif_cnt(unsigned int, struct sioc_vif_req *); 109 int mrt_rtwalk_mfcsysctl(struct rtentry *, void *, unsigned int); 110 int ip_mrouter_init(struct socket *, struct mbuf *); 111 int mrouter_rtwalk_delete(struct rtentry *, void *, unsigned int); 112 int get_version(struct mbuf *); 113 int add_vif(struct socket *, struct mbuf *); 114 int del_vif(struct socket *, struct mbuf *); 115 void update_mfc_params(struct mfcctl2 *, int, unsigned int); 116 void mfc_expire_route(struct rtentry *, struct rttimer *); 117 int mfc_add(struct mfcctl2 *, struct in_addr *, struct in_addr *, 118 int, unsigned int, int); 119 int add_mfc(struct socket *, struct mbuf *); 120 int del_mfc(struct socket *, struct mbuf *); 121 int set_api_config(struct socket *, struct mbuf *); /* chose API capabilities */ 122 int get_api_support(struct mbuf *); 123 int get_api_config(struct mbuf *); 124 int socket_send(struct socket *, struct mbuf *, 125 struct sockaddr_in *); 126 int ip_mdq(struct mbuf *, struct ifnet *, struct rtentry *); 127 struct ifnet *if_lookupbyvif(vifi_t, unsigned int); 128 struct rtentry *rt_mcast_add(struct ifnet *, struct sockaddr *, 129 struct sockaddr *); 130 void mrt_mcast_del(struct rtentry *, unsigned int); 131 132 /* 133 * Kernel multicast routing API capabilities and setup. 134 * If more API capabilities are added to the kernel, they should be 135 * recorded in `mrt_api_support'. 136 */ 137 static const u_int32_t mrt_api_support = (MRT_MFC_FLAGS_DISABLE_WRONGVIF | 138 MRT_MFC_RP); 139 static u_int32_t mrt_api_config = 0; 140 141 /* 142 * Find a route for a given origin IP address and Multicast group address 143 * Type of service parameter to be added in the future!!! 144 * Statistics are updated by the caller if needed 145 * (mrtstat.mrts_mfc_lookups and mrtstat.mrts_mfc_misses) 146 */ 147 struct rtentry * 148 mfc_find(struct ifnet *ifp, struct in_addr *origin, struct in_addr *group, 149 unsigned int rtableid) 150 { 151 struct rtentry *rt; 152 struct sockaddr_in msin; 153 154 memset(&msin, 0, sizeof(msin)); 155 msin.sin_len = sizeof(msin); 156 msin.sin_family = AF_INET; 157 msin.sin_addr = *group; 158 159 rt = rtalloc(sintosa(&msin), 0, rtableid); 160 do { 161 if (!rtisvalid(rt)) { 162 rtfree(rt); 163 return NULL; 164 } 165 /* Don't consider non multicast routes. */ 166 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 167 (RTF_HOST | RTF_MULTICAST)) 168 continue; 169 /* Return first occurrence if interface is not specified. */ 170 if (ifp == NULL) 171 return (rt); 172 if (rt->rt_ifidx == ifp->if_index) 173 return (rt); 174 } while ((rt = rtable_iterate(rt)) != NULL); 175 176 return (NULL); 177 } 178 179 /* 180 * Handle MRT setsockopt commands to modify the multicast routing tables. 181 */ 182 int 183 ip_mrouter_set(struct socket *so, int optname, struct mbuf *m) 184 { 185 struct inpcb *inp = sotoinpcb(so); 186 int error; 187 188 if (optname != MRT_INIT && 189 so != ip_mrouter[inp->inp_rtableid]) 190 error = ENOPROTOOPT; 191 else 192 switch (optname) { 193 case MRT_INIT: 194 error = ip_mrouter_init(so, m); 195 break; 196 case MRT_DONE: 197 error = ip_mrouter_done(so); 198 break; 199 case MRT_ADD_VIF: 200 error = add_vif(so, m); 201 break; 202 case MRT_DEL_VIF: 203 error = del_vif(so, m); 204 break; 205 case MRT_ADD_MFC: 206 error = add_mfc(so, m); 207 break; 208 case MRT_DEL_MFC: 209 error = del_mfc(so, m); 210 break; 211 case MRT_API_CONFIG: 212 error = set_api_config(so, m); 213 break; 214 default: 215 error = ENOPROTOOPT; 216 break; 217 } 218 219 return (error); 220 } 221 222 /* 223 * Handle MRT getsockopt commands 224 */ 225 int 226 ip_mrouter_get(struct socket *so, int optname, struct mbuf *m) 227 { 228 struct inpcb *inp = sotoinpcb(so); 229 int error; 230 231 if (so != ip_mrouter[inp->inp_rtableid]) 232 error = ENOPROTOOPT; 233 else { 234 switch (optname) { 235 case MRT_VERSION: 236 error = get_version(m); 237 break; 238 case MRT_API_SUPPORT: 239 error = get_api_support(m); 240 break; 241 case MRT_API_CONFIG: 242 error = get_api_config(m); 243 break; 244 default: 245 error = ENOPROTOOPT; 246 break; 247 } 248 } 249 250 return (error); 251 } 252 253 /* 254 * Handle ioctl commands to obtain information from the cache 255 */ 256 int 257 mrt_ioctl(struct socket *so, u_long cmd, caddr_t data) 258 { 259 struct inpcb *inp = sotoinpcb(so); 260 int error; 261 262 if (inp == NULL) 263 return (ENOTCONN); 264 265 if (so != ip_mrouter[inp->inp_rtableid]) 266 error = EINVAL; 267 else 268 switch (cmd) { 269 case SIOCGETVIFCNT: 270 NET_RLOCK_IN_IOCTL(); 271 error = get_vif_cnt(inp->inp_rtableid, 272 (struct sioc_vif_req *)data); 273 NET_RUNLOCK_IN_IOCTL(); 274 break; 275 case SIOCGETSGCNT: 276 NET_RLOCK_IN_IOCTL(); 277 error = get_sg_cnt(inp->inp_rtableid, 278 (struct sioc_sg_req *)data); 279 NET_RUNLOCK_IN_IOCTL(); 280 break; 281 default: 282 error = ENOTTY; 283 break; 284 } 285 286 return (error); 287 } 288 289 /* 290 * returns the packet, byte, rpf-failure count for the source group provided 291 */ 292 int 293 get_sg_cnt(unsigned int rtableid, struct sioc_sg_req *req) 294 { 295 struct rtentry *rt; 296 struct mfc *mfc; 297 298 rt = mfc_find(NULL, &req->src, &req->grp, rtableid); 299 if (rt == NULL) { 300 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; 301 return (EADDRNOTAVAIL); 302 } 303 304 req->pktcnt = req->bytecnt = req->wrong_if = 0; 305 do { 306 /* Don't consider non multicast routes. */ 307 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 308 (RTF_HOST | RTF_MULTICAST)) 309 continue; 310 311 mfc = (struct mfc *)rt->rt_llinfo; 312 if (mfc == NULL) 313 continue; 314 315 req->pktcnt += mfc->mfc_pkt_cnt; 316 req->bytecnt += mfc->mfc_byte_cnt; 317 req->wrong_if += mfc->mfc_wrong_if; 318 } while ((rt = rtable_iterate(rt)) != NULL); 319 320 return (0); 321 } 322 323 /* 324 * returns the input and output packet and byte counts on the vif provided 325 */ 326 int 327 get_vif_cnt(unsigned int rtableid, struct sioc_vif_req *req) 328 { 329 struct ifnet *ifp; 330 struct vif *v; 331 vifi_t vifi = req->vifi; 332 333 if ((ifp = if_lookupbyvif(vifi, rtableid)) == NULL) 334 return (EINVAL); 335 336 v = (struct vif *)ifp->if_mcast; 337 req->icount = v->v_pkt_in; 338 req->ocount = v->v_pkt_out; 339 req->ibytes = v->v_bytes_in; 340 req->obytes = v->v_bytes_out; 341 342 return (0); 343 } 344 345 int 346 mrt_sysctl_vif(void *oldp, size_t *oldlenp) 347 { 348 caddr_t where = oldp; 349 size_t needed, given; 350 struct ifnet *ifp; 351 struct vif *vifp; 352 struct vifinfo vinfo; 353 354 given = *oldlenp; 355 needed = 0; 356 TAILQ_FOREACH(ifp, &ifnet, if_list) { 357 if ((vifp = (struct vif *)ifp->if_mcast) == NULL) 358 continue; 359 360 vinfo.v_vifi = vifp->v_id; 361 vinfo.v_flags = vifp->v_flags; 362 vinfo.v_threshold = vifp->v_threshold; 363 vinfo.v_lcl_addr = vifp->v_lcl_addr; 364 vinfo.v_rmt_addr = vifp->v_rmt_addr; 365 vinfo.v_pkt_in = vifp->v_pkt_in; 366 vinfo.v_pkt_out = vifp->v_pkt_out; 367 vinfo.v_bytes_in = vifp->v_bytes_in; 368 vinfo.v_bytes_out = vifp->v_bytes_out; 369 370 needed += sizeof(vinfo); 371 if (where && needed <= given) { 372 int error; 373 374 error = copyout(&vinfo, where, sizeof(vinfo)); 375 if (error) 376 return (error); 377 where += sizeof(vinfo); 378 } 379 } 380 if (where) { 381 *oldlenp = needed; 382 if (given < needed) 383 return (ENOMEM); 384 } else 385 *oldlenp = (11 * needed) / 10; 386 387 return (0); 388 } 389 390 struct mfcsysctlarg { 391 struct mfcinfo *msa_minfos; 392 size_t msa_len; 393 size_t msa_needed; 394 }; 395 396 int 397 mrt_rtwalk_mfcsysctl(struct rtentry *rt, void *arg, unsigned int rtableid) 398 { 399 struct mfc *mfc = (struct mfc *)rt->rt_llinfo; 400 struct mfcsysctlarg *msa = (struct mfcsysctlarg *)arg; 401 struct ifnet *ifp; 402 struct vif *v; 403 struct mfcinfo *minfo; 404 int new = 0; 405 406 /* Skip entries being removed. */ 407 if (mfc == NULL) 408 return (0); 409 410 /* Skip non-multicast routes. */ 411 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 412 (RTF_HOST | RTF_MULTICAST)) 413 return (0); 414 415 /* User just asked for the output size. */ 416 if (msa->msa_minfos == NULL) { 417 msa->msa_needed += sizeof(*minfo); 418 return (0); 419 } 420 421 /* Skip route with invalid interfaces. */ 422 if ((ifp = if_get(rt->rt_ifidx)) == NULL) 423 return (0); 424 if ((v = (struct vif *)ifp->if_mcast) == NULL) { 425 if_put(ifp); 426 return (0); 427 } 428 429 for (minfo = msa->msa_minfos; 430 (uint8_t *)minfo < ((uint8_t *)msa->msa_minfos + msa->msa_len); 431 minfo++) { 432 /* Find a new entry or update old entry. */ 433 if (minfo->mfc_origin.s_addr != 434 satosin(rt->rt_gateway)->sin_addr.s_addr || 435 minfo->mfc_mcastgrp.s_addr != 436 satosin(rt_key(rt))->sin_addr.s_addr) { 437 if (minfo->mfc_origin.s_addr != 0 || 438 minfo->mfc_mcastgrp.s_addr != 0) 439 continue; 440 441 new = 1; 442 } 443 444 minfo->mfc_origin = satosin(rt->rt_gateway)->sin_addr; 445 minfo->mfc_mcastgrp = satosin(rt_key(rt))->sin_addr; 446 minfo->mfc_parent = mfc->mfc_parent; 447 minfo->mfc_pkt_cnt += mfc->mfc_pkt_cnt; 448 minfo->mfc_byte_cnt += mfc->mfc_byte_cnt; 449 minfo->mfc_ttls[v->v_id] = mfc->mfc_ttl; 450 break; 451 } 452 453 if (new != 0) 454 msa->msa_needed += sizeof(*minfo); 455 456 if_put(ifp); 457 458 return (0); 459 } 460 461 int 462 mrt_sysctl_mfc(void *oldp, size_t *oldlenp) 463 { 464 unsigned int rtableid; 465 int error; 466 struct mfcsysctlarg msa; 467 468 if (oldp != NULL && *oldlenp > MAXPHYS) 469 return (EINVAL); 470 471 if (oldp != NULL) 472 msa.msa_minfos = malloc(*oldlenp, M_TEMP, M_WAITOK | M_ZERO); 473 else 474 msa.msa_minfos = NULL; 475 476 msa.msa_len = *oldlenp; 477 msa.msa_needed = 0; 478 479 for (rtableid = 0; rtableid <= RT_TABLEID_MAX; rtableid++) { 480 rtable_walk(rtableid, AF_INET, NULL, mrt_rtwalk_mfcsysctl, 481 &msa); 482 } 483 484 if (msa.msa_minfos != NULL && msa.msa_needed > 0 && 485 (error = copyout(msa.msa_minfos, oldp, msa.msa_needed)) != 0) { 486 free(msa.msa_minfos, M_TEMP, *oldlenp); 487 return (error); 488 } 489 490 free(msa.msa_minfos, M_TEMP, *oldlenp); 491 *oldlenp = msa.msa_needed; 492 493 return (0); 494 } 495 496 /* 497 * Enable multicast routing 498 */ 499 int 500 ip_mrouter_init(struct socket *so, struct mbuf *m) 501 { 502 struct inpcb *inp = sotoinpcb(so); 503 unsigned int rtableid = inp->inp_rtableid; 504 int *v; 505 506 if (so->so_type != SOCK_RAW || 507 so->so_proto->pr_protocol != IPPROTO_IGMP) 508 return (EOPNOTSUPP); 509 510 if (m == NULL || m->m_len < sizeof(int)) 511 return (EINVAL); 512 513 v = mtod(m, int *); 514 if (*v != 1) 515 return (EINVAL); 516 517 if (ip_mrouter[rtableid] != NULL || 518 mrouterq[rtableid] != NULL) 519 return (EADDRINUSE); 520 521 ip_mrouter[rtableid] = so; 522 mrouterq[rtableid] = rt_timer_queue_create(MCAST_EXPIRE_FREQUENCY); 523 524 return (0); 525 } 526 527 int 528 mrouter_rtwalk_delete(struct rtentry *rt, void *arg, unsigned int rtableid) 529 { 530 /* Skip non-multicast routes. */ 531 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 532 (RTF_HOST | RTF_MULTICAST)) 533 return (0); 534 535 return EEXIST; 536 } 537 538 /* 539 * Disable multicast routing 540 */ 541 int 542 ip_mrouter_done(struct socket *so) 543 { 544 struct inpcb *inp = sotoinpcb(so); 545 struct ifnet *ifp; 546 unsigned int rtableid = inp->inp_rtableid; 547 int error; 548 549 NET_ASSERT_LOCKED(); 550 551 /* Delete all remaining installed multicast routes. */ 552 do { 553 struct rtentry *rt = NULL; 554 555 error = rtable_walk(rtableid, AF_INET, &rt, 556 mrouter_rtwalk_delete, NULL); 557 if (rt != NULL && error == EEXIST) { 558 mrt_mcast_del(rt, rtableid); 559 error = EAGAIN; 560 } 561 rtfree(rt); 562 } while (error == EAGAIN); 563 564 /* Unregister all interfaces in the domain. */ 565 TAILQ_FOREACH(ifp, &ifnet, if_list) { 566 if (ifp->if_rdomain != rtableid) 567 continue; 568 569 vif_delete(ifp); 570 } 571 572 mrt_api_config = 0; 573 574 rt_timer_queue_destroy(mrouterq[rtableid]); 575 mrouterq[rtableid] = NULL; 576 ip_mrouter[rtableid] = NULL; 577 mrt_count[rtableid] = 0; 578 579 return (0); 580 } 581 582 int 583 get_version(struct mbuf *m) 584 { 585 int *v = mtod(m, int *); 586 587 *v = 0x0305; /* XXX !!!! */ 588 m->m_len = sizeof(int); 589 return (0); 590 } 591 592 /* 593 * Configure API capabilities 594 */ 595 int 596 set_api_config(struct socket *so, struct mbuf *m) 597 { 598 struct inpcb *inp = sotoinpcb(so); 599 struct ifnet *ifp; 600 u_int32_t *apival; 601 unsigned int rtableid = inp->inp_rtableid; 602 603 if (m == NULL || m->m_len < sizeof(u_int32_t)) 604 return (EINVAL); 605 606 apival = mtod(m, u_int32_t *); 607 608 /* 609 * We can set the API capabilities only if it is the first operation 610 * after MRT_INIT. I.e.: 611 * - there are no vifs installed 612 * - the MFC table is empty 613 */ 614 TAILQ_FOREACH(ifp, &ifnet, if_list) { 615 if (ifp->if_rdomain != rtableid) 616 continue; 617 if (ifp->if_mcast == NULL) 618 continue; 619 620 *apival = 0; 621 return (EPERM); 622 } 623 if (mrt_count[rtableid] > 0) { 624 *apival = 0; 625 return (EPERM); 626 } 627 628 mrt_api_config = *apival & mrt_api_support; 629 *apival = mrt_api_config; 630 631 return (0); 632 } 633 634 /* 635 * Get API capabilities 636 */ 637 int 638 get_api_support(struct mbuf *m) 639 { 640 u_int32_t *apival; 641 642 if (m == NULL || m->m_len < sizeof(u_int32_t)) 643 return (EINVAL); 644 645 apival = mtod(m, u_int32_t *); 646 647 *apival = mrt_api_support; 648 649 return (0); 650 } 651 652 /* 653 * Get API configured capabilities 654 */ 655 int 656 get_api_config(struct mbuf *m) 657 { 658 u_int32_t *apival; 659 660 if (m == NULL || m->m_len < sizeof(u_int32_t)) 661 return (EINVAL); 662 663 apival = mtod(m, u_int32_t *); 664 665 *apival = mrt_api_config; 666 667 return (0); 668 } 669 670 static struct sockaddr_in sin = { sizeof(sin), AF_INET }; 671 672 int 673 add_vif(struct socket *so, struct mbuf *m) 674 { 675 struct inpcb *inp = sotoinpcb(so); 676 struct vifctl *vifcp; 677 struct vif *vifp; 678 struct ifaddr *ifa; 679 struct ifnet *ifp; 680 struct ifreq ifr; 681 int error; 682 unsigned int rtableid = inp->inp_rtableid; 683 684 NET_ASSERT_LOCKED(); 685 686 if (m == NULL || m->m_len < sizeof(struct vifctl)) 687 return (EINVAL); 688 689 vifcp = mtod(m, struct vifctl *); 690 if (vifcp->vifc_vifi >= MAXVIFS) 691 return (EINVAL); 692 if (in_nullhost(vifcp->vifc_lcl_addr)) 693 return (EADDRNOTAVAIL); 694 if (if_lookupbyvif(vifcp->vifc_vifi, rtableid) != NULL) 695 return (EADDRINUSE); 696 697 /* Tunnels are no longer supported use gif(4) instead. */ 698 if (vifcp->vifc_flags & VIFF_TUNNEL) 699 return (EOPNOTSUPP); 700 { 701 sin.sin_addr = vifcp->vifc_lcl_addr; 702 ifa = ifa_ifwithaddr(sintosa(&sin), rtableid); 703 if (ifa == NULL) 704 return (EADDRNOTAVAIL); 705 } 706 707 /* Use the physical interface associated with the address. */ 708 ifp = ifa->ifa_ifp; 709 if (ifp->if_mcast != NULL) 710 return (EADDRINUSE); 711 712 { 713 /* Make sure the interface supports multicast. */ 714 if ((ifp->if_flags & IFF_MULTICAST) == 0) 715 return (EOPNOTSUPP); 716 717 /* Enable promiscuous reception of all IP multicasts. */ 718 memset(&ifr, 0, sizeof(ifr)); 719 satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in); 720 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 721 satosin(&ifr.ifr_addr)->sin_addr = zeroin_addr; 722 error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr); 723 if (error) 724 return (error); 725 } 726 727 vifp = malloc(sizeof(*vifp), M_MRTABLE, M_WAITOK | M_ZERO); 728 ifp->if_mcast = (caddr_t)vifp; 729 730 vifp->v_id = vifcp->vifc_vifi; 731 vifp->v_flags = vifcp->vifc_flags; 732 vifp->v_threshold = vifcp->vifc_threshold; 733 vifp->v_lcl_addr = vifcp->vifc_lcl_addr; 734 vifp->v_rmt_addr = vifcp->vifc_rmt_addr; 735 736 return (0); 737 } 738 739 int 740 del_vif(struct socket *so, struct mbuf *m) 741 { 742 struct inpcb *inp = sotoinpcb(so); 743 struct ifnet *ifp; 744 vifi_t *vifip; 745 unsigned int rtableid = inp->inp_rtableid; 746 747 NET_ASSERT_LOCKED(); 748 749 if (m == NULL || m->m_len < sizeof(vifi_t)) 750 return (EINVAL); 751 752 vifip = mtod(m, vifi_t *); 753 if ((ifp = if_lookupbyvif(*vifip, rtableid)) == NULL) 754 return (EADDRNOTAVAIL); 755 756 vif_delete(ifp); 757 return (0); 758 } 759 760 void 761 vif_delete(struct ifnet *ifp) 762 { 763 struct vif *v; 764 struct ifreq ifr; 765 766 if ((v = (struct vif *)ifp->if_mcast) == NULL) 767 return; 768 769 ifp->if_mcast = NULL; 770 771 memset(&ifr, 0, sizeof(ifr)); 772 satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in); 773 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 774 satosin(&ifr.ifr_addr)->sin_addr = zeroin_addr; 775 KERNEL_LOCK(); 776 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 777 KERNEL_UNLOCK(); 778 779 free(v, M_MRTABLE, sizeof(*v)); 780 } 781 782 void 783 mfc_expire_route(struct rtentry *rt, struct rttimer *rtt) 784 { 785 struct mfc *mfc = (struct mfc *)rt->rt_llinfo; 786 unsigned int rtableid = rtt->rtt_tableid; 787 788 /* Skip entry being deleted. */ 789 if (mfc == NULL) 790 return; 791 792 DPRINTF("Route domain %d origin %#08X group %#08x interface %d " 793 "expire %s", rtt->rtt_tableid, 794 satosin(rt->rt_gateway)->sin_addr.s_addr, 795 satosin(rt_key(rt))->sin_addr.s_addr, 796 rt->rt_ifidx, mfc->mfc_expire ? "yes" : "no"); 797 798 /* Not expired, add it back to the queue. */ 799 if (mfc->mfc_expire == 0) { 800 mfc->mfc_expire = 1; 801 rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid], 802 rtableid); 803 return; 804 } 805 806 mrt_mcast_del(rt, rtableid); 807 } 808 809 int 810 mfc_add_route(struct ifnet *ifp, struct sockaddr *origin, 811 struct sockaddr *group, struct mfcctl2 *mfccp, int wait) 812 { 813 struct vif *v = (struct vif *)ifp->if_mcast; 814 struct rtentry *rt; 815 struct mfc *mfc; 816 unsigned int rtableid = ifp->if_rdomain; 817 818 rt = rt_mcast_add(ifp, origin, group); 819 if (rt == NULL) 820 return (EHOSTUNREACH); 821 822 mfc = malloc(sizeof(*mfc), M_MRTABLE, wait | M_ZERO); 823 if (mfc == NULL) { 824 DPRINTF("origin %#08X group %#08X parent %d (%s) " 825 "malloc failed", 826 satosin(origin)->sin_addr.s_addr, 827 satosin(group)->sin_addr.s_addr, 828 mfccp->mfcc_parent, ifp->if_xname); 829 mrt_mcast_del(rt, rtableid); 830 rtfree(rt); 831 return (ENOMEM); 832 } 833 834 rt->rt_llinfo = (caddr_t)mfc; 835 836 rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid], 837 rtableid); 838 839 mfc->mfc_parent = mfccp->mfcc_parent; 840 mfc->mfc_pkt_cnt = 0; 841 mfc->mfc_byte_cnt = 0; 842 mfc->mfc_wrong_if = 0; 843 mfc->mfc_ttl = mfccp->mfcc_ttls[v->v_id]; 844 mfc->mfc_flags = mfccp->mfcc_flags[v->v_id] & mrt_api_config & 845 MRT_MFC_FLAGS_ALL; 846 mfc->mfc_expire = 0; 847 848 /* set the RP address */ 849 if (mrt_api_config & MRT_MFC_RP) 850 mfc->mfc_rp = mfccp->mfcc_rp; 851 else 852 mfc->mfc_rp = zeroin_addr; 853 854 rtfree(rt); 855 856 return (0); 857 } 858 859 void 860 update_mfc_params(struct mfcctl2 *mfccp, int wait, unsigned int rtableid) 861 { 862 struct rtentry *rt; 863 struct mfc *mfc; 864 struct ifnet *ifp; 865 int i; 866 struct sockaddr_in osin, msin; 867 868 memset(&osin, 0, sizeof(osin)); 869 osin.sin_len = sizeof(osin); 870 osin.sin_family = AF_INET; 871 osin.sin_addr = mfccp->mfcc_origin; 872 873 memset(&msin, 0, sizeof(msin)); 874 msin.sin_len = sizeof(msin); 875 msin.sin_family = AF_INET; 876 msin.sin_addr = mfccp->mfcc_mcastgrp; 877 878 for (i = 0; i < MAXVIFS; i++) { 879 /* Don't add/del upstream routes here. */ 880 if (i == mfccp->mfcc_parent) 881 continue; 882 883 /* Test for vif existence and then update the entry. */ 884 if ((ifp = if_lookupbyvif(i, rtableid)) == NULL) 885 continue; 886 887 rt = mfc_find(ifp, &mfccp->mfcc_origin, 888 &mfccp->mfcc_mcastgrp, rtableid); 889 890 /* vif not configured or removed. */ 891 if (mfccp->mfcc_ttls[i] == 0) { 892 /* Route doesn't exist, nothing to do. */ 893 if (rt == NULL) 894 continue; 895 896 DPRINTF("del route (group %#08X) for vif %d (%s)", 897 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 898 mrt_mcast_del(rt, rtableid); 899 rtfree(rt); 900 continue; 901 } 902 903 /* Route exists, look for changes. */ 904 if (rt != NULL) { 905 mfc = (struct mfc *)rt->rt_llinfo; 906 /* Skip route being deleted. */ 907 if (mfc == NULL) { 908 rtfree(rt); 909 continue; 910 } 911 912 /* No new changes to apply. */ 913 if (mfccp->mfcc_ttls[i] == mfc->mfc_ttl && 914 mfccp->mfcc_parent == mfc->mfc_parent) { 915 rtfree(rt); 916 continue; 917 } 918 919 DPRINTF("update route (group %#08X) for vif %d (%s)", 920 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 921 mfc->mfc_ttl = mfccp->mfcc_ttls[i]; 922 mfc->mfc_parent = mfccp->mfcc_parent; 923 rtfree(rt); 924 continue; 925 } 926 927 DPRINTF("add route (group %#08X) for vif %d (%s)", 928 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 929 930 mfc_add_route(ifp, sintosa(&osin), sintosa(&msin), 931 mfccp, wait); 932 } 933 934 /* Create route for the parent interface. */ 935 if ((ifp = if_lookupbyvif(mfccp->mfcc_parent, rtableid)) == NULL) { 936 DPRINTF("failed to find upstream interface %d", 937 mfccp->mfcc_parent); 938 return; 939 } 940 941 /* We already have a route, nothing to do here. */ 942 if ((rt = mfc_find(ifp, &mfccp->mfcc_origin, 943 &mfccp->mfcc_mcastgrp, rtableid)) != NULL) { 944 rtfree(rt); 945 return; 946 } 947 948 DPRINTF("add upstream route (group %#08X) for if %s", 949 mfccp->mfcc_mcastgrp.s_addr, ifp->if_xname); 950 mfc_add_route(ifp, sintosa(&osin), sintosa(&msin), mfccp, wait); 951 } 952 953 int 954 mfc_add(struct mfcctl2 *mfcctl2, struct in_addr *origin, 955 struct in_addr *group, int vidx, unsigned int rtableid, int wait) 956 { 957 struct ifnet *ifp; 958 struct vif *v; 959 struct mfcctl2 mfcctl; 960 961 ifp = if_lookupbyvif(vidx, rtableid); 962 if (ifp == NULL || 963 (v = (struct vif *)ifp->if_mcast) == NULL) 964 return (EHOSTUNREACH); 965 966 memset(&mfcctl, 0, sizeof(mfcctl)); 967 if (mfcctl2 == NULL) { 968 mfcctl.mfcc_origin = *origin; 969 mfcctl.mfcc_mcastgrp = *group; 970 mfcctl.mfcc_parent = vidx; 971 } else 972 memcpy(&mfcctl, mfcctl2, sizeof(mfcctl)); 973 974 update_mfc_params(&mfcctl, wait, rtableid); 975 976 return (0); 977 } 978 979 int 980 add_mfc(struct socket *so, struct mbuf *m) 981 { 982 struct inpcb *inp = sotoinpcb(so); 983 struct mfcctl2 mfcctl2; 984 int mfcctl_size = sizeof(struct mfcctl); 985 unsigned int rtableid = inp->inp_rtableid; 986 987 NET_ASSERT_LOCKED(); 988 989 if (mrt_api_config & MRT_API_FLAGS_ALL) 990 mfcctl_size = sizeof(struct mfcctl2); 991 992 if (m == NULL || m->m_len < mfcctl_size) 993 return (EINVAL); 994 995 /* 996 * select data size depending on API version. 997 */ 998 if (mrt_api_config & MRT_API_FLAGS_ALL) { 999 struct mfcctl2 *mp2 = mtod(m, struct mfcctl2 *); 1000 memcpy((caddr_t)&mfcctl2, mp2, sizeof(*mp2)); 1001 } else { 1002 struct mfcctl *mp = mtod(m, struct mfcctl *); 1003 memcpy((caddr_t)&mfcctl2, mp, sizeof(*mp)); 1004 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1005 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1006 } 1007 1008 if (mfc_add(&mfcctl2, &mfcctl2.mfcc_origin, &mfcctl2.mfcc_mcastgrp, 1009 mfcctl2.mfcc_parent, rtableid, M_WAITOK) == -1) 1010 return (EINVAL); 1011 1012 return (0); 1013 } 1014 1015 int 1016 del_mfc(struct socket *so, struct mbuf *m) 1017 { 1018 struct inpcb *inp = sotoinpcb(so); 1019 struct rtentry *rt; 1020 struct mfcctl2 mfcctl2; 1021 int mfcctl_size = sizeof(struct mfcctl); 1022 struct mfcctl *mp; 1023 unsigned int rtableid = inp->inp_rtableid; 1024 1025 NET_ASSERT_LOCKED(); 1026 1027 /* 1028 * XXX: for deleting MFC entries the information in entries 1029 * of size "struct mfcctl" is sufficient. 1030 */ 1031 1032 if (m == NULL || m->m_len < mfcctl_size) 1033 return (EINVAL); 1034 1035 mp = mtod(m, struct mfcctl *); 1036 1037 memcpy((caddr_t)&mfcctl2, mp, sizeof(*mp)); 1038 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1039 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1040 1041 DPRINTF("origin %#08X group %#08X rtableid %d", 1042 mfcctl2.mfcc_origin.s_addr, mfcctl2.mfcc_mcastgrp.s_addr, rtableid); 1043 1044 while ((rt = mfc_find(NULL, &mfcctl2.mfcc_origin, 1045 &mfcctl2.mfcc_mcastgrp, rtableid)) != NULL) { 1046 mrt_mcast_del(rt, rtableid); 1047 rtfree(rt); 1048 } 1049 1050 return (0); 1051 } 1052 1053 int 1054 socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src) 1055 { 1056 if (s != NULL) { 1057 if (sbappendaddr(s, &s->so_rcv, sintosa(src), mm, NULL) != 0) { 1058 sorwakeup(s); 1059 return (0); 1060 } 1061 } 1062 m_freem(mm); 1063 return (-1); 1064 } 1065 1066 /* 1067 * IP multicast forwarding function. This function assumes that the packet 1068 * pointed to by "ip" has arrived on (or is about to be sent to) the interface 1069 * pointed to by "ifp", and the packet is to be relayed to other networks 1070 * that have members of the packet's destination IP multicast group. 1071 * 1072 * The packet is returned unscathed to the caller, unless it is 1073 * erroneous, in which case a non-zero return value tells the caller to 1074 * discard it. 1075 */ 1076 1077 #define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */ 1078 #define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */ 1079 1080 int 1081 ip_mforward(struct mbuf *m, struct ifnet *ifp) 1082 { 1083 struct ip *ip = mtod(m, struct ip *); 1084 struct vif *v; 1085 struct rtentry *rt; 1086 static int srctun = 0; 1087 struct mbuf *mm; 1088 unsigned int rtableid = ifp->if_rdomain; 1089 1090 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 1091 ((u_char *)(ip + 1))[1] != IPOPT_LSRR) { 1092 /* 1093 * Packet arrived via a physical interface or 1094 * an encapsulated tunnel or a register_vif. 1095 */ 1096 } else { 1097 /* 1098 * Packet arrived through a source-route tunnel. 1099 * Source-route tunnels are no longer supported. 1100 */ 1101 if ((srctun++ % 1000) == 0) 1102 log(LOG_ERR, "ip_mforward: received source-routed " 1103 "packet from %x\n", ntohl(ip->ip_src.s_addr)); 1104 return (EOPNOTSUPP); 1105 } 1106 1107 /* 1108 * Don't forward a packet with time-to-live of zero or one, 1109 * or a packet destined to a local-only group. 1110 */ 1111 if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ip->ip_dst.s_addr)) 1112 return (0); 1113 1114 /* 1115 * Determine forwarding vifs from the forwarding cache table 1116 */ 1117 ++mrtstat.mrts_mfc_lookups; 1118 rt = mfc_find(NULL, &ip->ip_src, &ip->ip_dst, rtableid); 1119 1120 /* Entry exists, so forward if necessary */ 1121 if (rt != NULL) { 1122 return (ip_mdq(m, ifp, rt)); 1123 } else { 1124 /* 1125 * If we don't have a route for packet's origin, 1126 * Make a copy of the packet & send message to routing daemon 1127 */ 1128 int hlen = ip->ip_hl << 2; 1129 1130 ++mrtstat.mrts_mfc_misses; 1131 mrtstat.mrts_no_route++; 1132 1133 { 1134 struct igmpmsg *im; 1135 1136 /* 1137 * Locate the vifi for the incoming interface for 1138 * this packet. 1139 * If none found, drop packet. 1140 */ 1141 if ((v = (struct vif *)ifp->if_mcast) == NULL) 1142 return (EHOSTUNREACH); 1143 /* 1144 * Make a copy of the header to send to the user level 1145 * process 1146 */ 1147 mm = m_copym(m, 0, hlen, M_NOWAIT); 1148 if (mm == NULL || 1149 (mm = m_pullup(mm, hlen)) == NULL) 1150 return (ENOBUFS); 1151 1152 /* 1153 * Send message to routing daemon to install 1154 * a route into the kernel table 1155 */ 1156 1157 im = mtod(mm, struct igmpmsg *); 1158 im->im_msgtype = IGMPMSG_NOCACHE; 1159 im->im_mbz = 0; 1160 im->im_vif = v->v_id; 1161 1162 mrtstat.mrts_upcalls++; 1163 1164 sin.sin_addr = ip->ip_src; 1165 if (socket_send(ip_mrouter[rtableid], mm, &sin) < 0) { 1166 log(LOG_WARNING, "ip_mforward: ip_mrouter " 1167 "socket queue full\n"); 1168 ++mrtstat.mrts_upq_sockfull; 1169 return (ENOBUFS); 1170 } 1171 1172 mfc_add(NULL, &ip->ip_src, &ip->ip_dst, v->v_id, 1173 rtableid, M_NOWAIT); 1174 } 1175 1176 return (0); 1177 } 1178 } 1179 1180 /* 1181 * Packet forwarding routine once entry in the cache is made 1182 */ 1183 int 1184 ip_mdq(struct mbuf *m, struct ifnet *ifp0, struct rtentry *rt) 1185 { 1186 struct ip *ip = mtod(m, struct ip *); 1187 struct mfc *mfc = (struct mfc *)rt->rt_llinfo; 1188 struct vif *v = (struct vif *)ifp0->if_mcast; 1189 struct ifnet *ifp; 1190 struct mbuf *mc; 1191 struct ip_moptions imo; 1192 1193 /* Sanity check: we have all promised pointers. */ 1194 if (v == NULL || mfc == NULL) { 1195 rtfree(rt); 1196 return (EHOSTUNREACH); 1197 } 1198 1199 /* 1200 * Don't forward if it didn't arrive from the parent vif for its origin. 1201 */ 1202 if (mfc->mfc_parent != v->v_id) { 1203 /* came in the wrong interface */ 1204 ++mrtstat.mrts_wrong_if; 1205 mfc->mfc_wrong_if++; 1206 rtfree(rt); 1207 return (0); 1208 } 1209 1210 /* If I sourced this packet, it counts as output, else it was input. */ 1211 if (in_hosteq(ip->ip_src, v->v_lcl_addr)) { 1212 v->v_pkt_out++; 1213 v->v_bytes_out += m->m_pkthdr.len; 1214 } else { 1215 v->v_pkt_in++; 1216 v->v_bytes_in += m->m_pkthdr.len; 1217 } 1218 1219 /* 1220 * For each vif, decide if a copy of the packet should be forwarded. 1221 * Forward if: 1222 * - the ttl exceeds the vif's threshold 1223 * - there are group members downstream on interface 1224 */ 1225 do { 1226 /* Don't consider non multicast routes. */ 1227 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 1228 (RTF_HOST | RTF_MULTICAST)) 1229 continue; 1230 1231 mfc = (struct mfc *)rt->rt_llinfo; 1232 if (mfc == NULL) 1233 continue; 1234 1235 mfc->mfc_pkt_cnt++; 1236 mfc->mfc_byte_cnt += m->m_pkthdr.len; 1237 1238 /* Don't let this route expire. */ 1239 mfc->mfc_expire = 0; 1240 1241 if (ip->ip_ttl <= mfc->mfc_ttl) 1242 continue; 1243 if ((ifp = if_get(rt->rt_ifidx)) == NULL) 1244 continue; 1245 1246 /* Sanity check: did we configure this? */ 1247 if ((v = (struct vif *)ifp->if_mcast) == NULL) { 1248 if_put(ifp); 1249 continue; 1250 } 1251 1252 /* Don't send in the upstream interface. */ 1253 if (mfc->mfc_parent == v->v_id) { 1254 if_put(ifp); 1255 continue; 1256 } 1257 1258 v->v_pkt_out++; 1259 v->v_bytes_out += m->m_pkthdr.len; 1260 1261 /* 1262 * Make a new reference to the packet; make sure 1263 * that the IP header is actually copied, not 1264 * just referenced, so that ip_output() only 1265 * scribbles on the copy. 1266 */ 1267 mc = m_dup_pkt(m, max_linkhdr, M_NOWAIT); 1268 if (mc == NULL) { 1269 if_put(ifp); 1270 rtfree(rt); 1271 return (ENOBUFS); 1272 } 1273 1274 /* 1275 * if physical interface option, extract the options 1276 * and then send 1277 */ 1278 imo.imo_ifidx = rt->rt_ifidx; 1279 imo.imo_ttl = ip->ip_ttl - IPTTLDEC; 1280 imo.imo_loop = 1; 1281 1282 ip_output(mc, NULL, NULL, IP_FORWARDING, &imo, NULL, 0); 1283 if_put(ifp); 1284 } while ((rt = rtable_iterate(rt)) != NULL); 1285 1286 return (0); 1287 } 1288 1289 struct ifnet * 1290 if_lookupbyvif(vifi_t vifi, unsigned int rtableid) 1291 { 1292 struct vif *v; 1293 struct ifnet *ifp; 1294 1295 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1296 if (ifp->if_rdomain != rtableid) 1297 continue; 1298 if ((v = (struct vif *)ifp->if_mcast) == NULL) 1299 continue; 1300 if (v->v_id != vifi) 1301 continue; 1302 1303 return (ifp); 1304 } 1305 1306 return (NULL); 1307 } 1308 1309 struct rtentry * 1310 rt_mcast_add(struct ifnet *ifp, struct sockaddr *origin, struct sockaddr *group) 1311 { 1312 struct ifaddr *ifa; 1313 int rv; 1314 unsigned int rtableid = ifp->if_rdomain; 1315 1316 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1317 if (ifa->ifa_addr->sa_family == AF_INET) 1318 break; 1319 } 1320 if (ifa == NULL) { 1321 DPRINTF("ifa == NULL"); 1322 return (NULL); 1323 } 1324 1325 rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, 1326 group, ifp->if_rdomain); 1327 if (rv != 0) { 1328 DPRINTF("rt_ifa_add failed (%d)", rv); 1329 return (NULL); 1330 } 1331 1332 mrt_count[rtableid]++; 1333 1334 return (mfc_find(ifp, NULL, &satosin(group)->sin_addr, rtableid)); 1335 } 1336 1337 void 1338 mrt_mcast_del(struct rtentry *rt, unsigned int rtableid) 1339 { 1340 struct ifnet *ifp; 1341 int error; 1342 1343 /* Remove all timers related to this route. */ 1344 rt_timer_remove_all(rt); 1345 1346 free(rt->rt_llinfo, M_MRTABLE, sizeof(struct mfc)); 1347 rt->rt_llinfo = NULL; 1348 1349 ifp = if_get(rt->rt_ifidx); 1350 if (ifp == NULL) 1351 return; 1352 error = rtdeletemsg(rt, ifp, rtableid); 1353 if_put(ifp); 1354 1355 if (error) 1356 DPRINTF("delete route error %d\n", error); 1357 1358 mrt_count[rtableid]--; 1359 } 1360