1 /* $OpenBSD: ip_mroute.c,v 1.128 2019/09/02 13:12:09 bluhm 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(); 271 error = get_vif_cnt(inp->inp_rtableid, 272 (struct sioc_vif_req *)data); 273 NET_RUNLOCK(); 274 break; 275 case SIOCGETSGCNT: 276 NET_RLOCK(); 277 error = get_sg_cnt(inp->inp_rtableid, 278 (struct sioc_sg_req *)data); 279 NET_RUNLOCK(); 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 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 776 777 free(v, M_MRTABLE, sizeof(*v)); 778 } 779 780 void 781 mfc_expire_route(struct rtentry *rt, struct rttimer *rtt) 782 { 783 struct mfc *mfc = (struct mfc *)rt->rt_llinfo; 784 unsigned int rtableid = rtt->rtt_tableid; 785 786 /* Skip entry being deleted. */ 787 if (mfc == NULL) 788 return; 789 790 DPRINTF("Route domain %d origin %#08X group %#08x interface %d " 791 "expire %s", rtt->rtt_tableid, 792 satosin(rt->rt_gateway)->sin_addr.s_addr, 793 satosin(rt_key(rt))->sin_addr.s_addr, 794 rt->rt_ifidx, mfc->mfc_expire ? "yes" : "no"); 795 796 /* Not expired, add it back to the queue. */ 797 if (mfc->mfc_expire == 0) { 798 mfc->mfc_expire = 1; 799 rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid], 800 rtableid); 801 return; 802 } 803 804 mrt_mcast_del(rt, rtableid); 805 } 806 807 int 808 mfc_add_route(struct ifnet *ifp, struct sockaddr *origin, 809 struct sockaddr *group, struct mfcctl2 *mfccp, int wait) 810 { 811 struct vif *v = (struct vif *)ifp->if_mcast; 812 struct rtentry *rt; 813 struct mfc *mfc; 814 unsigned int rtableid = ifp->if_rdomain; 815 816 rt = rt_mcast_add(ifp, origin, group); 817 if (rt == NULL) 818 return (EHOSTUNREACH); 819 820 mfc = malloc(sizeof(*mfc), M_MRTABLE, wait | M_ZERO); 821 if (mfc == NULL) { 822 DPRINTF("origin %#08X group %#08X parent %d (%s) " 823 "malloc failed", 824 satosin(origin)->sin_addr.s_addr, 825 satosin(group)->sin_addr.s_addr, 826 mfccp->mfcc_parent, ifp->if_xname); 827 mrt_mcast_del(rt, rtableid); 828 rtfree(rt); 829 return (ENOMEM); 830 } 831 832 rt->rt_llinfo = (caddr_t)mfc; 833 834 rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid], 835 rtableid); 836 837 mfc->mfc_parent = mfccp->mfcc_parent; 838 mfc->mfc_pkt_cnt = 0; 839 mfc->mfc_byte_cnt = 0; 840 mfc->mfc_wrong_if = 0; 841 mfc->mfc_ttl = mfccp->mfcc_ttls[v->v_id]; 842 mfc->mfc_flags = mfccp->mfcc_flags[v->v_id] & mrt_api_config & 843 MRT_MFC_FLAGS_ALL; 844 mfc->mfc_expire = 0; 845 846 /* set the RP address */ 847 if (mrt_api_config & MRT_MFC_RP) 848 mfc->mfc_rp = mfccp->mfcc_rp; 849 else 850 mfc->mfc_rp = zeroin_addr; 851 852 rtfree(rt); 853 854 return (0); 855 } 856 857 void 858 update_mfc_params(struct mfcctl2 *mfccp, int wait, unsigned int rtableid) 859 { 860 struct rtentry *rt; 861 struct mfc *mfc; 862 struct ifnet *ifp; 863 int i; 864 struct sockaddr_in osin, msin; 865 866 memset(&osin, 0, sizeof(osin)); 867 osin.sin_len = sizeof(osin); 868 osin.sin_family = AF_INET; 869 osin.sin_addr = mfccp->mfcc_origin; 870 871 memset(&msin, 0, sizeof(msin)); 872 msin.sin_len = sizeof(msin); 873 msin.sin_family = AF_INET; 874 msin.sin_addr = mfccp->mfcc_mcastgrp; 875 876 for (i = 0; i < MAXVIFS; i++) { 877 /* Don't add/del upstream routes here. */ 878 if (i == mfccp->mfcc_parent) 879 continue; 880 881 /* Test for vif existence and then update the entry. */ 882 if ((ifp = if_lookupbyvif(i, rtableid)) == NULL) 883 continue; 884 885 rt = mfc_find(ifp, &mfccp->mfcc_origin, 886 &mfccp->mfcc_mcastgrp, rtableid); 887 888 /* vif not configured or removed. */ 889 if (mfccp->mfcc_ttls[i] == 0) { 890 /* Route doesn't exist, nothing to do. */ 891 if (rt == NULL) 892 continue; 893 894 DPRINTF("del route (group %#08X) for vif %d (%s)", 895 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 896 mrt_mcast_del(rt, rtableid); 897 rtfree(rt); 898 continue; 899 } 900 901 /* Route exists, look for changes. */ 902 if (rt != NULL) { 903 mfc = (struct mfc *)rt->rt_llinfo; 904 /* Skip route being deleted. */ 905 if (mfc == NULL) { 906 rtfree(rt); 907 continue; 908 } 909 910 /* No new changes to apply. */ 911 if (mfccp->mfcc_ttls[i] == mfc->mfc_ttl && 912 mfccp->mfcc_parent == mfc->mfc_parent) { 913 rtfree(rt); 914 continue; 915 } 916 917 DPRINTF("update route (group %#08X) for vif %d (%s)", 918 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 919 mfc->mfc_ttl = mfccp->mfcc_ttls[i]; 920 mfc->mfc_parent = mfccp->mfcc_parent; 921 rtfree(rt); 922 continue; 923 } 924 925 DPRINTF("add route (group %#08X) for vif %d (%s)", 926 mfccp->mfcc_mcastgrp.s_addr, i, ifp->if_xname); 927 928 mfc_add_route(ifp, sintosa(&osin), sintosa(&msin), 929 mfccp, wait); 930 } 931 932 /* Create route for the parent interface. */ 933 if ((ifp = if_lookupbyvif(mfccp->mfcc_parent, rtableid)) == NULL) { 934 DPRINTF("failed to find upstream interface %d", 935 mfccp->mfcc_parent); 936 return; 937 } 938 939 /* We already have a route, nothing to do here. */ 940 if ((rt = mfc_find(ifp, &mfccp->mfcc_origin, 941 &mfccp->mfcc_mcastgrp, rtableid)) != NULL) { 942 rtfree(rt); 943 return; 944 } 945 946 DPRINTF("add upstream route (group %#08X) for if %s", 947 mfccp->mfcc_mcastgrp.s_addr, ifp->if_xname); 948 mfc_add_route(ifp, sintosa(&osin), sintosa(&msin), mfccp, wait); 949 } 950 951 int 952 mfc_add(struct mfcctl2 *mfcctl2, struct in_addr *origin, 953 struct in_addr *group, int vidx, unsigned int rtableid, int wait) 954 { 955 struct ifnet *ifp; 956 struct vif *v; 957 struct mfcctl2 mfcctl; 958 959 ifp = if_lookupbyvif(vidx, rtableid); 960 if (ifp == NULL || 961 (v = (struct vif *)ifp->if_mcast) == NULL) 962 return (EHOSTUNREACH); 963 964 memset(&mfcctl, 0, sizeof(mfcctl)); 965 if (mfcctl2 == NULL) { 966 mfcctl.mfcc_origin = *origin; 967 mfcctl.mfcc_mcastgrp = *group; 968 mfcctl.mfcc_parent = vidx; 969 } else 970 memcpy(&mfcctl, mfcctl2, sizeof(mfcctl)); 971 972 update_mfc_params(&mfcctl, wait, rtableid); 973 974 return (0); 975 } 976 977 int 978 add_mfc(struct socket *so, struct mbuf *m) 979 { 980 struct inpcb *inp = sotoinpcb(so); 981 struct mfcctl2 mfcctl2; 982 int mfcctl_size = sizeof(struct mfcctl); 983 unsigned int rtableid = inp->inp_rtableid; 984 985 NET_ASSERT_LOCKED(); 986 987 if (mrt_api_config & MRT_API_FLAGS_ALL) 988 mfcctl_size = sizeof(struct mfcctl2); 989 990 if (m == NULL || m->m_len < mfcctl_size) 991 return (EINVAL); 992 993 /* 994 * select data size depending on API version. 995 */ 996 if (mrt_api_config & MRT_API_FLAGS_ALL) { 997 struct mfcctl2 *mp2 = mtod(m, struct mfcctl2 *); 998 memcpy((caddr_t)&mfcctl2, mp2, sizeof(*mp2)); 999 } else { 1000 struct mfcctl *mp = mtod(m, struct mfcctl *); 1001 memcpy((caddr_t)&mfcctl2, mp, sizeof(*mp)); 1002 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1003 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1004 } 1005 1006 if (mfc_add(&mfcctl2, &mfcctl2.mfcc_origin, &mfcctl2.mfcc_mcastgrp, 1007 mfcctl2.mfcc_parent, rtableid, M_WAITOK) == -1) 1008 return (EINVAL); 1009 1010 return (0); 1011 } 1012 1013 int 1014 del_mfc(struct socket *so, struct mbuf *m) 1015 { 1016 struct inpcb *inp = sotoinpcb(so); 1017 struct rtentry *rt; 1018 struct mfcctl2 mfcctl2; 1019 int mfcctl_size = sizeof(struct mfcctl); 1020 struct mfcctl *mp; 1021 unsigned int rtableid = inp->inp_rtableid; 1022 1023 NET_ASSERT_LOCKED(); 1024 1025 /* 1026 * XXX: for deleting MFC entries the information in entries 1027 * of size "struct mfcctl" is sufficient. 1028 */ 1029 1030 if (m == NULL || m->m_len < mfcctl_size) 1031 return (EINVAL); 1032 1033 mp = mtod(m, struct mfcctl *); 1034 1035 memcpy((caddr_t)&mfcctl2, mp, sizeof(*mp)); 1036 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1037 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1038 1039 DPRINTF("origin %#08X group %#08X rtableid %d", 1040 mfcctl2.mfcc_origin.s_addr, mfcctl2.mfcc_mcastgrp.s_addr, rtableid); 1041 1042 while ((rt = mfc_find(NULL, &mfcctl2.mfcc_origin, 1043 &mfcctl2.mfcc_mcastgrp, rtableid)) != NULL) { 1044 mrt_mcast_del(rt, rtableid); 1045 rtfree(rt); 1046 } 1047 1048 return (0); 1049 } 1050 1051 int 1052 socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src) 1053 { 1054 if (s != NULL) { 1055 if (sbappendaddr(s, &s->so_rcv, sintosa(src), mm, NULL) != 0) { 1056 sorwakeup(s); 1057 return (0); 1058 } 1059 } 1060 m_freem(mm); 1061 return (-1); 1062 } 1063 1064 /* 1065 * IP multicast forwarding function. This function assumes that the packet 1066 * pointed to by "ip" has arrived on (or is about to be sent to) the interface 1067 * pointed to by "ifp", and the packet is to be relayed to other networks 1068 * that have members of the packet's destination IP multicast group. 1069 * 1070 * The packet is returned unscathed to the caller, unless it is 1071 * erroneous, in which case a non-zero return value tells the caller to 1072 * discard it. 1073 */ 1074 1075 #define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */ 1076 #define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */ 1077 1078 int 1079 ip_mforward(struct mbuf *m, struct ifnet *ifp) 1080 { 1081 struct ip *ip = mtod(m, struct ip *); 1082 struct vif *v; 1083 struct rtentry *rt; 1084 static int srctun = 0; 1085 struct mbuf *mm; 1086 unsigned int rtableid = ifp->if_rdomain; 1087 1088 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 1089 ((u_char *)(ip + 1))[1] != IPOPT_LSRR) { 1090 /* 1091 * Packet arrived via a physical interface or 1092 * an encapsulated tunnel or a register_vif. 1093 */ 1094 } else { 1095 /* 1096 * Packet arrived through a source-route tunnel. 1097 * Source-route tunnels are no longer supported. 1098 */ 1099 if ((srctun++ % 1000) == 0) 1100 log(LOG_ERR, "ip_mforward: received source-routed " 1101 "packet from %x\n", ntohl(ip->ip_src.s_addr)); 1102 return (EOPNOTSUPP); 1103 } 1104 1105 /* 1106 * Don't forward a packet with time-to-live of zero or one, 1107 * or a packet destined to a local-only group. 1108 */ 1109 if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ip->ip_dst.s_addr)) 1110 return (0); 1111 1112 /* 1113 * Determine forwarding vifs from the forwarding cache table 1114 */ 1115 ++mrtstat.mrts_mfc_lookups; 1116 rt = mfc_find(NULL, &ip->ip_src, &ip->ip_dst, rtableid); 1117 1118 /* Entry exists, so forward if necessary */ 1119 if (rt != NULL) { 1120 return (ip_mdq(m, ifp, rt)); 1121 } else { 1122 /* 1123 * If we don't have a route for packet's origin, 1124 * Make a copy of the packet & send message to routing daemon 1125 */ 1126 int hlen = ip->ip_hl << 2; 1127 1128 ++mrtstat.mrts_mfc_misses; 1129 mrtstat.mrts_no_route++; 1130 1131 { 1132 struct igmpmsg *im; 1133 1134 /* 1135 * Locate the vifi for the incoming interface for 1136 * this packet. 1137 * If none found, drop packet. 1138 */ 1139 if ((v = (struct vif *)ifp->if_mcast) == NULL) 1140 return (EHOSTUNREACH); 1141 /* 1142 * Make a copy of the header to send to the user level 1143 * process 1144 */ 1145 mm = m_copym(m, 0, hlen, M_NOWAIT); 1146 if (mm == NULL || 1147 (mm = m_pullup(mm, hlen)) == NULL) 1148 return (ENOBUFS); 1149 1150 /* 1151 * Send message to routing daemon to install 1152 * a route into the kernel table 1153 */ 1154 1155 im = mtod(mm, struct igmpmsg *); 1156 im->im_msgtype = IGMPMSG_NOCACHE; 1157 im->im_mbz = 0; 1158 im->im_vif = v->v_id; 1159 1160 mrtstat.mrts_upcalls++; 1161 1162 sin.sin_addr = ip->ip_src; 1163 if (socket_send(ip_mrouter[rtableid], mm, &sin) < 0) { 1164 log(LOG_WARNING, "ip_mforward: ip_mrouter " 1165 "socket queue full\n"); 1166 ++mrtstat.mrts_upq_sockfull; 1167 return (ENOBUFS); 1168 } 1169 1170 mfc_add(NULL, &ip->ip_src, &ip->ip_dst, v->v_id, 1171 rtableid, M_NOWAIT); 1172 } 1173 1174 return (0); 1175 } 1176 } 1177 1178 /* 1179 * Packet forwarding routine once entry in the cache is made 1180 */ 1181 int 1182 ip_mdq(struct mbuf *m, struct ifnet *ifp0, struct rtentry *rt) 1183 { 1184 struct ip *ip = mtod(m, struct ip *); 1185 struct mfc *mfc = (struct mfc *)rt->rt_llinfo; 1186 struct vif *v = (struct vif *)ifp0->if_mcast; 1187 struct ifnet *ifp; 1188 struct mbuf *mc; 1189 struct ip_moptions imo; 1190 1191 /* Sanity check: we have all promised pointers. */ 1192 if (v == NULL || mfc == NULL) { 1193 rtfree(rt); 1194 return (EHOSTUNREACH); 1195 } 1196 1197 /* 1198 * Don't forward if it didn't arrive from the parent vif for its origin. 1199 */ 1200 if (mfc->mfc_parent != v->v_id) { 1201 /* came in the wrong interface */ 1202 ++mrtstat.mrts_wrong_if; 1203 mfc->mfc_wrong_if++; 1204 rtfree(rt); 1205 return (0); 1206 } 1207 1208 /* If I sourced this packet, it counts as output, else it was input. */ 1209 if (in_hosteq(ip->ip_src, v->v_lcl_addr)) { 1210 v->v_pkt_out++; 1211 v->v_bytes_out += m->m_pkthdr.len; 1212 } else { 1213 v->v_pkt_in++; 1214 v->v_bytes_in += m->m_pkthdr.len; 1215 } 1216 1217 /* 1218 * For each vif, decide if a copy of the packet should be forwarded. 1219 * Forward if: 1220 * - the ttl exceeds the vif's threshold 1221 * - there are group members downstream on interface 1222 */ 1223 do { 1224 /* Don't consider non multicast routes. */ 1225 if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) != 1226 (RTF_HOST | RTF_MULTICAST)) 1227 continue; 1228 1229 mfc = (struct mfc *)rt->rt_llinfo; 1230 if (mfc == NULL) 1231 continue; 1232 1233 mfc->mfc_pkt_cnt++; 1234 mfc->mfc_byte_cnt += m->m_pkthdr.len; 1235 1236 /* Don't let this route expire. */ 1237 mfc->mfc_expire = 0; 1238 1239 if (ip->ip_ttl <= mfc->mfc_ttl) 1240 continue; 1241 if ((ifp = if_get(rt->rt_ifidx)) == NULL) 1242 continue; 1243 1244 /* Sanity check: did we configure this? */ 1245 if ((v = (struct vif *)ifp->if_mcast) == NULL) { 1246 if_put(ifp); 1247 continue; 1248 } 1249 1250 /* Don't send in the upstream interface. */ 1251 if (mfc->mfc_parent == v->v_id) { 1252 if_put(ifp); 1253 continue; 1254 } 1255 1256 v->v_pkt_out++; 1257 v->v_bytes_out += m->m_pkthdr.len; 1258 1259 /* 1260 * Make a new reference to the packet; make sure 1261 * that the IP header is actually copied, not 1262 * just referenced, so that ip_output() only 1263 * scribbles on the copy. 1264 */ 1265 mc = m_dup_pkt(m, max_linkhdr, M_NOWAIT); 1266 if (mc == NULL) { 1267 if_put(ifp); 1268 rtfree(rt); 1269 return (ENOBUFS); 1270 } 1271 1272 /* 1273 * if physical interface option, extract the options 1274 * and then send 1275 */ 1276 imo.imo_ifidx = rt->rt_ifidx; 1277 imo.imo_ttl = ip->ip_ttl - IPTTLDEC; 1278 imo.imo_loop = 1; 1279 1280 ip_output(mc, NULL, NULL, IP_FORWARDING, &imo, NULL, 0); 1281 if_put(ifp); 1282 } while ((rt = rtable_iterate(rt)) != NULL); 1283 1284 return (0); 1285 } 1286 1287 struct ifnet * 1288 if_lookupbyvif(vifi_t vifi, unsigned int rtableid) 1289 { 1290 struct vif *v; 1291 struct ifnet *ifp; 1292 1293 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1294 if (ifp->if_rdomain != rtableid) 1295 continue; 1296 if ((v = (struct vif *)ifp->if_mcast) == NULL) 1297 continue; 1298 if (v->v_id != vifi) 1299 continue; 1300 1301 return (ifp); 1302 } 1303 1304 return (NULL); 1305 } 1306 1307 struct rtentry * 1308 rt_mcast_add(struct ifnet *ifp, struct sockaddr *origin, struct sockaddr *group) 1309 { 1310 struct ifaddr *ifa; 1311 int rv; 1312 unsigned int rtableid = ifp->if_rdomain; 1313 1314 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1315 if (ifa->ifa_addr->sa_family == AF_INET) 1316 break; 1317 } 1318 if (ifa == NULL) { 1319 DPRINTF("ifa == NULL"); 1320 return (NULL); 1321 } 1322 1323 rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, 1324 group, ifp->if_rdomain); 1325 if (rv != 0) { 1326 DPRINTF("rt_ifa_add failed (%d)", rv); 1327 return (NULL); 1328 } 1329 1330 mrt_count[rtableid]++; 1331 1332 return (mfc_find(ifp, NULL, &satosin(group)->sin_addr, rtableid)); 1333 } 1334 1335 void 1336 mrt_mcast_del(struct rtentry *rt, unsigned int rtableid) 1337 { 1338 struct ifnet *ifp; 1339 int error; 1340 1341 /* Remove all timers related to this route. */ 1342 rt_timer_remove_all(rt); 1343 1344 free(rt->rt_llinfo, M_MRTABLE, sizeof(struct mfc)); 1345 rt->rt_llinfo = NULL; 1346 1347 ifp = if_get(rt->rt_ifidx); 1348 if (ifp == NULL) 1349 return; 1350 error = rtdeletemsg(rt, ifp, rtableid); 1351 if_put(ifp); 1352 1353 if (error) 1354 DPRINTF("delete route error %d\n", error); 1355 1356 mrt_count[rtableid]--; 1357 } 1358