1 /*- 2 * Copyright (c) 2007 Bruce M. Simpson. 3 * Copyright (c) 2005 Robert N. M. Watson. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 /* 32 * IPv4 multicast socket, group, and socket option processing module. 33 * Until further notice, this file requires INET to compile. 34 * TODO: Make this infrastructure independent of address family. 35 * TODO: Teach netinet6 to use this code. 36 * TODO: Hook up SSM logic to IGMPv3/MLDv2. 37 */ 38 39 #include <sys/cdefs.h> 40 __FBSDID("$FreeBSD$"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/malloc.h> 46 #include <sys/mbuf.h> 47 #include <sys/protosw.h> 48 #include <sys/socket.h> 49 #include <sys/socketvar.h> 50 #include <sys/sysctl.h> 51 #include <sys/vimage.h> 52 53 #include <net/if.h> 54 #include <net/if_dl.h> 55 #include <net/route.h> 56 57 #include <netinet/in.h> 58 #include <netinet/in_systm.h> 59 #include <netinet/in_pcb.h> 60 #include <netinet/in_var.h> 61 #include <netinet/ip_var.h> 62 #include <netinet/igmp_var.h> 63 64 #ifndef __SOCKUNION_DECLARED 65 union sockunion { 66 struct sockaddr_storage ss; 67 struct sockaddr sa; 68 struct sockaddr_dl sdl; 69 struct sockaddr_in sin; 70 #ifdef INET6 71 struct sockaddr_in6 sin6; 72 #endif 73 }; 74 typedef union sockunion sockunion_t; 75 #define __SOCKUNION_DECLARED 76 #endif /* __SOCKUNION_DECLARED */ 77 78 static MALLOC_DEFINE(M_IPMADDR, "in_multi", "IPv4 multicast group"); 79 static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "IPv4 multicast options"); 80 static MALLOC_DEFINE(M_IPMSOURCE, "in_msource", "IPv4 multicast source filter"); 81 82 /* 83 * The IPv4 multicast list (in_multihead and associated structures) are 84 * protected by the global in_multi_mtx. See in_var.h for more details. For 85 * now, in_multi_mtx is marked as recursible due to IGMP's calling back into 86 * ip_output() to send IGMP packets while holding the lock; this probably is 87 * not quite desirable. 88 */ 89 struct in_multihead in_multihead; /* XXX BSS initialization */ 90 struct mtx in_multi_mtx; 91 MTX_SYSINIT(in_multi_mtx, &in_multi_mtx, "in_multi_mtx", MTX_DEF | MTX_RECURSE); 92 93 /* 94 * Functions with non-static linkage defined in this file should be 95 * declared in in_var.h: 96 * imo_match_group() 97 * imo_match_source() 98 * in_addmulti() 99 * in_delmulti() 100 * in_delmulti_locked() 101 * and ip_var.h: 102 * inp_freemoptions() 103 * inp_getmoptions() 104 * inp_setmoptions() 105 */ 106 static int imo_grow(struct ip_moptions *); 107 static int imo_join_source(struct ip_moptions *, size_t, sockunion_t *); 108 static int imo_leave_source(struct ip_moptions *, size_t, sockunion_t *); 109 static int inp_change_source_filter(struct inpcb *, struct sockopt *); 110 static struct ip_moptions * 111 inp_findmoptions(struct inpcb *); 112 static int inp_get_source_filters(struct inpcb *, struct sockopt *); 113 static int inp_join_group(struct inpcb *, struct sockopt *); 114 static int inp_leave_group(struct inpcb *, struct sockopt *); 115 static int inp_set_multicast_if(struct inpcb *, struct sockopt *); 116 static int inp_set_source_filters(struct inpcb *, struct sockopt *); 117 118 /* 119 * Resize the ip_moptions vector to the next power-of-two minus 1. 120 * May be called with locks held; do not sleep. 121 */ 122 static int 123 imo_grow(struct ip_moptions *imo) 124 { 125 struct in_multi **nmships; 126 struct in_multi **omships; 127 struct in_mfilter *nmfilters; 128 struct in_mfilter *omfilters; 129 size_t idx; 130 size_t newmax; 131 size_t oldmax; 132 133 nmships = NULL; 134 nmfilters = NULL; 135 omships = imo->imo_membership; 136 omfilters = imo->imo_mfilters; 137 oldmax = imo->imo_max_memberships; 138 newmax = ((oldmax + 1) * 2) - 1; 139 140 if (newmax <= IP_MAX_MEMBERSHIPS) { 141 nmships = (struct in_multi **)realloc(omships, 142 sizeof(struct in_multi *) * newmax, M_IPMOPTS, M_NOWAIT); 143 nmfilters = (struct in_mfilter *)realloc(omfilters, 144 sizeof(struct in_mfilter) * newmax, M_IPMSOURCE, M_NOWAIT); 145 if (nmships != NULL && nmfilters != NULL) { 146 /* Initialize newly allocated source filter heads. */ 147 for (idx = oldmax; idx < newmax; idx++) { 148 nmfilters[idx].imf_fmode = MCAST_EXCLUDE; 149 nmfilters[idx].imf_nsources = 0; 150 TAILQ_INIT(&nmfilters[idx].imf_sources); 151 } 152 imo->imo_max_memberships = newmax; 153 imo->imo_membership = nmships; 154 imo->imo_mfilters = nmfilters; 155 } 156 } 157 158 if (nmships == NULL || nmfilters == NULL) { 159 if (nmships != NULL) 160 free(nmships, M_IPMOPTS); 161 if (nmfilters != NULL) 162 free(nmfilters, M_IPMSOURCE); 163 return (ETOOMANYREFS); 164 } 165 166 return (0); 167 } 168 169 /* 170 * Add a source to a multicast filter list. 171 * Assumes the associated inpcb is locked. 172 */ 173 static int 174 imo_join_source(struct ip_moptions *imo, size_t gidx, sockunion_t *src) 175 { 176 struct in_msource *ims, *nims; 177 struct in_mfilter *imf; 178 179 KASSERT(src->ss.ss_family == AF_INET, ("%s: !AF_INET", __func__)); 180 KASSERT(imo->imo_mfilters != NULL, 181 ("%s: imo_mfilters vector not allocated", __func__)); 182 183 imf = &imo->imo_mfilters[gidx]; 184 if (imf->imf_nsources == IP_MAX_SOURCE_FILTER) 185 return (ENOBUFS); 186 187 ims = imo_match_source(imo, gidx, &src->sa); 188 if (ims != NULL) 189 return (EADDRNOTAVAIL); 190 191 /* Do not sleep with inp lock held. */ 192 MALLOC(nims, struct in_msource *, sizeof(struct in_msource), 193 M_IPMSOURCE, M_NOWAIT | M_ZERO); 194 if (nims == NULL) 195 return (ENOBUFS); 196 197 nims->ims_addr = src->ss; 198 TAILQ_INSERT_TAIL(&imf->imf_sources, nims, ims_next); 199 imf->imf_nsources++; 200 201 return (0); 202 } 203 204 static int 205 imo_leave_source(struct ip_moptions *imo, size_t gidx, sockunion_t *src) 206 { 207 struct in_msource *ims; 208 struct in_mfilter *imf; 209 210 KASSERT(src->ss.ss_family == AF_INET, ("%s: !AF_INET", __func__)); 211 KASSERT(imo->imo_mfilters != NULL, 212 ("%s: imo_mfilters vector not allocated", __func__)); 213 214 imf = &imo->imo_mfilters[gidx]; 215 if (imf->imf_nsources == IP_MAX_SOURCE_FILTER) 216 return (ENOBUFS); 217 218 ims = imo_match_source(imo, gidx, &src->sa); 219 if (ims == NULL) 220 return (EADDRNOTAVAIL); 221 222 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next); 223 FREE(ims, M_IPMSOURCE); 224 imf->imf_nsources--; 225 226 return (0); 227 } 228 229 /* 230 * Find an IPv4 multicast group entry for this ip_moptions instance 231 * which matches the specified group, and optionally an interface. 232 * Return its index into the array, or -1 if not found. 233 */ 234 size_t 235 imo_match_group(struct ip_moptions *imo, struct ifnet *ifp, 236 struct sockaddr *group) 237 { 238 sockunion_t *gsa; 239 struct in_multi **pinm; 240 int idx; 241 int nmships; 242 243 gsa = (sockunion_t *)group; 244 245 /* The imo_membership array may be lazy allocated. */ 246 if (imo->imo_membership == NULL || imo->imo_num_memberships == 0) 247 return (-1); 248 249 nmships = imo->imo_num_memberships; 250 pinm = &imo->imo_membership[0]; 251 for (idx = 0; idx < nmships; idx++, pinm++) { 252 if (*pinm == NULL) 253 continue; 254 #if 0 255 printf("%s: trying ifp = %p, inaddr = %s ", __func__, 256 ifp, inet_ntoa(gsa->sin.sin_addr)); 257 printf("against %p, %s\n", 258 (*pinm)->inm_ifp, inet_ntoa((*pinm)->inm_addr)); 259 #endif 260 if ((ifp == NULL || ((*pinm)->inm_ifp == ifp)) && 261 (*pinm)->inm_addr.s_addr == gsa->sin.sin_addr.s_addr) { 262 break; 263 } 264 } 265 if (idx >= nmships) 266 idx = -1; 267 268 return (idx); 269 } 270 271 /* 272 * Find a multicast source entry for this imo which matches 273 * the given group index for this socket, and source address. 274 */ 275 struct in_msource * 276 imo_match_source(struct ip_moptions *imo, size_t gidx, struct sockaddr *src) 277 { 278 struct in_mfilter *imf; 279 struct in_msource *ims, *pims; 280 281 KASSERT(src->sa_family == AF_INET, ("%s: !AF_INET", __func__)); 282 KASSERT(gidx != -1 && gidx < imo->imo_num_memberships, 283 ("%s: invalid index %d\n", __func__, (int)gidx)); 284 285 /* The imo_mfilters array may be lazy allocated. */ 286 if (imo->imo_mfilters == NULL) 287 return (NULL); 288 289 pims = NULL; 290 imf = &imo->imo_mfilters[gidx]; 291 TAILQ_FOREACH(ims, &imf->imf_sources, ims_next) { 292 /* 293 * Perform bitwise comparison of two IPv4 addresses. 294 * TODO: Do the same for IPv6. 295 * Do not use sa_equal() for this as it is not aware of 296 * deeper structure in sockaddr_in or sockaddr_in6. 297 */ 298 if (((struct sockaddr_in *)&ims->ims_addr)->sin_addr.s_addr == 299 ((struct sockaddr_in *)src)->sin_addr.s_addr) { 300 pims = ims; 301 break; 302 } 303 } 304 305 return (pims); 306 } 307 308 /* 309 * Join an IPv4 multicast group. 310 */ 311 struct in_multi * 312 in_addmulti(struct in_addr *ap, struct ifnet *ifp) 313 { 314 struct in_multi *inm; 315 316 inm = NULL; 317 318 IFF_LOCKGIANT(ifp); 319 IN_MULTI_LOCK(); 320 321 IN_LOOKUP_MULTI(*ap, ifp, inm); 322 if (inm != NULL) { 323 /* 324 * If we already joined this group, just bump the 325 * refcount and return it. 326 */ 327 KASSERT(inm->inm_refcount >= 1, 328 ("%s: bad refcount %d", __func__, inm->inm_refcount)); 329 ++inm->inm_refcount; 330 } else do { 331 sockunion_t gsa; 332 struct ifmultiaddr *ifma; 333 struct in_multi *ninm; 334 int error; 335 336 memset(&gsa, 0, sizeof(gsa)); 337 gsa.sin.sin_family = AF_INET; 338 gsa.sin.sin_len = sizeof(struct sockaddr_in); 339 gsa.sin.sin_addr = *ap; 340 341 /* 342 * Check if a link-layer group is already associated 343 * with this network-layer group on the given ifnet. 344 * If so, bump the refcount on the existing network-layer 345 * group association and return it. 346 */ 347 error = if_addmulti(ifp, &gsa.sa, &ifma); 348 if (error) 349 break; 350 if (ifma->ifma_protospec != NULL) { 351 inm = (struct in_multi *)ifma->ifma_protospec; 352 #ifdef INVARIANTS 353 if (inm->inm_ifma != ifma || inm->inm_ifp != ifp || 354 inm->inm_addr.s_addr != ap->s_addr) 355 panic("%s: ifma is inconsistent", __func__); 356 #endif 357 ++inm->inm_refcount; 358 break; 359 } 360 361 /* 362 * A new membership is needed; construct it and 363 * perform the IGMP join. 364 */ 365 ninm = malloc(sizeof(*ninm), M_IPMADDR, M_NOWAIT | M_ZERO); 366 if (ninm == NULL) { 367 if_delmulti_ifma(ifma); 368 break; 369 } 370 ninm->inm_addr = *ap; 371 ninm->inm_ifp = ifp; 372 ninm->inm_ifma = ifma; 373 ninm->inm_refcount = 1; 374 ifma->ifma_protospec = ninm; 375 LIST_INSERT_HEAD(&V_in_multihead, ninm, inm_link); 376 377 igmp_joingroup(ninm); 378 379 inm = ninm; 380 } while (0); 381 382 IN_MULTI_UNLOCK(); 383 IFF_UNLOCKGIANT(ifp); 384 385 return (inm); 386 } 387 388 /* 389 * Leave an IPv4 multicast group. 390 * It is OK to call this routine if the underlying ifnet went away. 391 * 392 * XXX: To deal with the ifp going away, we cheat; the link-layer code in net 393 * will set ifma_ifp to NULL when the associated ifnet instance is detached 394 * from the system. 395 * 396 * The only reason we need to violate layers and check ifma_ifp here at all 397 * is because certain hardware drivers still require Giant to be held, 398 * and it must always be taken before other locks. 399 */ 400 void 401 in_delmulti(struct in_multi *inm) 402 { 403 struct ifnet *ifp; 404 405 KASSERT(inm != NULL, ("%s: inm is NULL", __func__)); 406 KASSERT(inm->inm_ifma != NULL, ("%s: no ifma", __func__)); 407 ifp = inm->inm_ifma->ifma_ifp; 408 409 if (ifp != NULL) { 410 /* 411 * Sanity check that netinet's notion of ifp is the 412 * same as net's. 413 */ 414 KASSERT(inm->inm_ifp == ifp, ("%s: bad ifp", __func__)); 415 IFF_LOCKGIANT(ifp); 416 } 417 418 IN_MULTI_LOCK(); 419 in_delmulti_locked(inm); 420 IN_MULTI_UNLOCK(); 421 422 if (ifp != NULL) 423 IFF_UNLOCKGIANT(ifp); 424 } 425 426 /* 427 * Delete a multicast address record, with locks held. 428 * 429 * It is OK to call this routine if the ifp went away. 430 * Assumes that caller holds the IN_MULTI lock, and that 431 * Giant was taken before other locks if required by the hardware. 432 */ 433 void 434 in_delmulti_locked(struct in_multi *inm) 435 { 436 struct ifmultiaddr *ifma; 437 438 IN_MULTI_LOCK_ASSERT(); 439 KASSERT(inm->inm_refcount >= 1, ("%s: freeing freed inm", __func__)); 440 441 if (--inm->inm_refcount == 0) { 442 igmp_leavegroup(inm); 443 444 ifma = inm->inm_ifma; 445 #ifdef DIAGNOSTIC 446 if (bootverbose) 447 printf("%s: purging ifma %p\n", __func__, ifma); 448 #endif 449 KASSERT(ifma->ifma_protospec == inm, 450 ("%s: ifma_protospec != inm", __func__)); 451 ifma->ifma_protospec = NULL; 452 453 LIST_REMOVE(inm, inm_link); 454 free(inm, M_IPMADDR); 455 456 if_delmulti_ifma(ifma); 457 } 458 } 459 460 /* 461 * Block or unblock an ASM/SSM multicast source on an inpcb. 462 */ 463 static int 464 inp_change_source_filter(struct inpcb *inp, struct sockopt *sopt) 465 { 466 struct group_source_req gsr; 467 sockunion_t *gsa, *ssa; 468 struct ifnet *ifp; 469 struct in_mfilter *imf; 470 struct ip_moptions *imo; 471 struct in_msource *ims; 472 size_t idx; 473 int error; 474 int block; 475 476 ifp = NULL; 477 error = 0; 478 block = 0; 479 480 memset(&gsr, 0, sizeof(struct group_source_req)); 481 gsa = (sockunion_t *)&gsr.gsr_group; 482 ssa = (sockunion_t *)&gsr.gsr_source; 483 484 switch (sopt->sopt_name) { 485 case IP_BLOCK_SOURCE: 486 case IP_UNBLOCK_SOURCE: { 487 struct ip_mreq_source mreqs; 488 489 error = sooptcopyin(sopt, &mreqs, 490 sizeof(struct ip_mreq_source), 491 sizeof(struct ip_mreq_source)); 492 if (error) 493 return (error); 494 495 gsa->sin.sin_family = AF_INET; 496 gsa->sin.sin_len = sizeof(struct sockaddr_in); 497 gsa->sin.sin_addr = mreqs.imr_multiaddr; 498 499 ssa->sin.sin_family = AF_INET; 500 ssa->sin.sin_len = sizeof(struct sockaddr_in); 501 ssa->sin.sin_addr = mreqs.imr_sourceaddr; 502 503 if (mreqs.imr_interface.s_addr != INADDR_ANY) 504 INADDR_TO_IFP(mreqs.imr_interface, ifp); 505 506 if (sopt->sopt_name == IP_BLOCK_SOURCE) 507 block = 1; 508 509 #ifdef DIAGNOSTIC 510 if (bootverbose) { 511 printf("%s: imr_interface = %s, ifp = %p\n", 512 __func__, inet_ntoa(mreqs.imr_interface), ifp); 513 } 514 #endif 515 break; 516 } 517 518 case MCAST_BLOCK_SOURCE: 519 case MCAST_UNBLOCK_SOURCE: 520 error = sooptcopyin(sopt, &gsr, 521 sizeof(struct group_source_req), 522 sizeof(struct group_source_req)); 523 if (error) 524 return (error); 525 526 if (gsa->sin.sin_family != AF_INET || 527 gsa->sin.sin_len != sizeof(struct sockaddr_in)) 528 return (EINVAL); 529 530 if (ssa->sin.sin_family != AF_INET || 531 ssa->sin.sin_len != sizeof(struct sockaddr_in)) 532 return (EINVAL); 533 534 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface) 535 return (EADDRNOTAVAIL); 536 537 ifp = ifnet_byindex(gsr.gsr_interface); 538 539 if (sopt->sopt_name == MCAST_BLOCK_SOURCE) 540 block = 1; 541 break; 542 543 default: 544 #ifdef DIAGNOSTIC 545 if (bootverbose) { 546 printf("%s: unknown sopt_name %d\n", __func__, 547 sopt->sopt_name); 548 } 549 #endif 550 return (EOPNOTSUPP); 551 break; 552 } 553 554 /* XXX INET6 */ 555 if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr))) 556 return (EINVAL); 557 558 /* 559 * Check if we are actually a member of this group. 560 */ 561 imo = inp_findmoptions(inp); 562 idx = imo_match_group(imo, ifp, &gsa->sa); 563 if (idx == -1 || imo->imo_mfilters == NULL) { 564 error = EADDRNOTAVAIL; 565 goto out_locked; 566 } 567 568 KASSERT(imo->imo_mfilters != NULL, 569 ("%s: imo_mfilters not allocated", __func__)); 570 imf = &imo->imo_mfilters[idx]; 571 572 /* 573 * SSM multicast truth table for block/unblock operations. 574 * 575 * Operation Filter Mode Entry exists? Action 576 * 577 * block exclude no add source to filter 578 * unblock include no add source to filter 579 * block include no EINVAL 580 * unblock exclude no EINVAL 581 * block exclude yes EADDRNOTAVAIL 582 * unblock include yes EADDRNOTAVAIL 583 * block include yes remove source from filter 584 * unblock exclude yes remove source from filter 585 * 586 * FreeBSD does not explicitly distinguish between ASM and SSM 587 * mode sockets; all sockets are assumed to have a filter list. 588 */ 589 #ifdef DIAGNOSTIC 590 if (bootverbose) { 591 printf("%s: imf_fmode is %s\n", __func__, 592 imf->imf_fmode == MCAST_INCLUDE ? "include" : "exclude"); 593 } 594 #endif 595 ims = imo_match_source(imo, idx, &ssa->sa); 596 if (ims == NULL) { 597 if ((block == 1 && imf->imf_fmode == MCAST_EXCLUDE) || 598 (block == 0 && imf->imf_fmode == MCAST_INCLUDE)) { 599 #ifdef DIAGNOSTIC 600 if (bootverbose) { 601 printf("%s: adding %s to filter list\n", 602 __func__, inet_ntoa(ssa->sin.sin_addr)); 603 } 604 #endif 605 error = imo_join_source(imo, idx, ssa); 606 } 607 if ((block == 1 && imf->imf_fmode == MCAST_INCLUDE) || 608 (block == 0 && imf->imf_fmode == MCAST_EXCLUDE)) { 609 /* 610 * If the socket is in inclusive mode: 611 * the source is already blocked as it has no entry. 612 * If the socket is in exclusive mode: 613 * the source is already unblocked as it has no entry. 614 */ 615 #ifdef DIAGNOSTIC 616 if (bootverbose) { 617 printf("%s: ims %p; %s already [un]blocked\n", 618 __func__, ims, 619 inet_ntoa(ssa->sin.sin_addr)); 620 } 621 #endif 622 error = EINVAL; 623 } 624 } else { 625 if ((block == 1 && imf->imf_fmode == MCAST_EXCLUDE) || 626 (block == 0 && imf->imf_fmode == MCAST_INCLUDE)) { 627 /* 628 * If the socket is in exclusive mode: 629 * the source is already blocked as it has an entry. 630 * If the socket is in inclusive mode: 631 * the source is already unblocked as it has an entry. 632 */ 633 #ifdef DIAGNOSTIC 634 if (bootverbose) { 635 printf("%s: ims %p; %s already [un]blocked\n", 636 __func__, ims, 637 inet_ntoa(ssa->sin.sin_addr)); 638 } 639 #endif 640 error = EADDRNOTAVAIL; 641 } 642 if ((block == 1 && imf->imf_fmode == MCAST_INCLUDE) || 643 (block == 0 && imf->imf_fmode == MCAST_EXCLUDE)) { 644 #ifdef DIAGNOSTIC 645 if (bootverbose) { 646 printf("%s: removing %s from filter list\n", 647 __func__, inet_ntoa(ssa->sin.sin_addr)); 648 } 649 #endif 650 error = imo_leave_source(imo, idx, ssa); 651 } 652 } 653 654 out_locked: 655 INP_WUNLOCK(inp); 656 return (error); 657 } 658 659 /* 660 * Given an inpcb, return its multicast options structure pointer. Accepts 661 * an unlocked inpcb pointer, but will return it locked. May sleep. 662 */ 663 static struct ip_moptions * 664 inp_findmoptions(struct inpcb *inp) 665 { 666 struct ip_moptions *imo; 667 struct in_multi **immp; 668 struct in_mfilter *imfp; 669 size_t idx; 670 671 INP_WLOCK(inp); 672 if (inp->inp_moptions != NULL) 673 return (inp->inp_moptions); 674 675 INP_WUNLOCK(inp); 676 677 imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS, 678 M_WAITOK); 679 immp = (struct in_multi **)malloc(sizeof(*immp) * IP_MIN_MEMBERSHIPS, 680 M_IPMOPTS, M_WAITOK | M_ZERO); 681 imfp = (struct in_mfilter *)malloc( 682 sizeof(struct in_mfilter) * IP_MIN_MEMBERSHIPS, 683 M_IPMSOURCE, M_WAITOK); 684 685 imo->imo_multicast_ifp = NULL; 686 imo->imo_multicast_addr.s_addr = INADDR_ANY; 687 imo->imo_multicast_vif = -1; 688 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; 689 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; 690 imo->imo_num_memberships = 0; 691 imo->imo_max_memberships = IP_MIN_MEMBERSHIPS; 692 imo->imo_membership = immp; 693 694 /* Initialize per-group source filters. */ 695 for (idx = 0; idx < IP_MIN_MEMBERSHIPS; idx++) { 696 imfp[idx].imf_fmode = MCAST_EXCLUDE; 697 imfp[idx].imf_nsources = 0; 698 TAILQ_INIT(&imfp[idx].imf_sources); 699 } 700 imo->imo_mfilters = imfp; 701 702 INP_WLOCK(inp); 703 if (inp->inp_moptions != NULL) { 704 free(imfp, M_IPMSOURCE); 705 free(immp, M_IPMOPTS); 706 free(imo, M_IPMOPTS); 707 return (inp->inp_moptions); 708 } 709 inp->inp_moptions = imo; 710 return (imo); 711 } 712 713 /* 714 * Discard the IP multicast options (and source filters). 715 */ 716 void 717 inp_freemoptions(struct ip_moptions *imo) 718 { 719 struct in_mfilter *imf; 720 struct in_msource *ims, *tims; 721 size_t idx, nmships; 722 723 KASSERT(imo != NULL, ("%s: ip_moptions is NULL", __func__)); 724 725 nmships = imo->imo_num_memberships; 726 for (idx = 0; idx < nmships; ++idx) { 727 in_delmulti(imo->imo_membership[idx]); 728 729 if (imo->imo_mfilters != NULL) { 730 imf = &imo->imo_mfilters[idx]; 731 TAILQ_FOREACH_SAFE(ims, &imf->imf_sources, 732 ims_next, tims) { 733 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next); 734 FREE(ims, M_IPMSOURCE); 735 imf->imf_nsources--; 736 } 737 KASSERT(imf->imf_nsources == 0, 738 ("%s: did not free all imf_nsources", __func__)); 739 } 740 } 741 742 if (imo->imo_mfilters != NULL) 743 free(imo->imo_mfilters, M_IPMSOURCE); 744 free(imo->imo_membership, M_IPMOPTS); 745 free(imo, M_IPMOPTS); 746 } 747 748 /* 749 * Atomically get source filters on a socket for an IPv4 multicast group. 750 * Called with INP lock held; returns with lock released. 751 */ 752 static int 753 inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt) 754 { 755 struct __msfilterreq msfr; 756 sockunion_t *gsa; 757 struct ifnet *ifp; 758 struct ip_moptions *imo; 759 struct in_mfilter *imf; 760 struct in_msource *ims; 761 struct sockaddr_storage *ptss; 762 struct sockaddr_storage *tss; 763 int error; 764 size_t idx; 765 766 INP_WLOCK_ASSERT(inp); 767 768 imo = inp->inp_moptions; 769 KASSERT(imo != NULL, ("%s: null ip_moptions", __func__)); 770 771 INP_WUNLOCK(inp); 772 773 error = sooptcopyin(sopt, &msfr, sizeof(struct __msfilterreq), 774 sizeof(struct __msfilterreq)); 775 if (error) 776 return (error); 777 778 if (msfr.msfr_ifindex == 0 || V_if_index < msfr.msfr_ifindex) 779 return (EINVAL); 780 781 ifp = ifnet_byindex(msfr.msfr_ifindex); 782 if (ifp == NULL) 783 return (EINVAL); 784 785 INP_WLOCK(inp); 786 787 /* 788 * Lookup group on the socket. 789 */ 790 gsa = (sockunion_t *)&msfr.msfr_group; 791 idx = imo_match_group(imo, ifp, &gsa->sa); 792 if (idx == -1 || imo->imo_mfilters == NULL) { 793 INP_WUNLOCK(inp); 794 return (EADDRNOTAVAIL); 795 } 796 797 imf = &imo->imo_mfilters[idx]; 798 msfr.msfr_fmode = imf->imf_fmode; 799 msfr.msfr_nsrcs = imf->imf_nsources; 800 801 /* 802 * If the user specified a buffer, copy out the source filter 803 * entries to userland gracefully. 804 * msfr.msfr_nsrcs is always set to the total number of filter 805 * entries which the kernel currently has for this group. 806 */ 807 tss = NULL; 808 if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) { 809 /* 810 * Make a copy of the source vector so that we do not 811 * thrash the inpcb lock whilst copying it out. 812 * We only copy out the number of entries which userland 813 * has asked for, but we always tell userland how big the 814 * buffer really needs to be. 815 */ 816 MALLOC(tss, struct sockaddr_storage *, 817 sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs, 818 M_TEMP, M_NOWAIT); 819 if (tss == NULL) { 820 error = ENOBUFS; 821 } else { 822 ptss = tss; 823 TAILQ_FOREACH(ims, &imf->imf_sources, ims_next) { 824 memcpy(ptss++, &ims->ims_addr, 825 sizeof(struct sockaddr_storage)); 826 } 827 } 828 } 829 830 INP_WUNLOCK(inp); 831 832 if (tss != NULL) { 833 error = copyout(tss, msfr.msfr_srcs, 834 sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs); 835 FREE(tss, M_TEMP); 836 } 837 838 if (error) 839 return (error); 840 841 error = sooptcopyout(sopt, &msfr, sizeof(struct __msfilterreq)); 842 843 return (error); 844 } 845 846 /* 847 * Return the IP multicast options in response to user getsockopt(). 848 */ 849 int 850 inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) 851 { 852 struct ip_mreqn mreqn; 853 struct ip_moptions *imo; 854 struct ifnet *ifp; 855 struct in_ifaddr *ia; 856 int error, optval; 857 u_char coptval; 858 859 INP_WLOCK(inp); 860 imo = inp->inp_moptions; 861 /* 862 * If socket is neither of type SOCK_RAW or SOCK_DGRAM, 863 * or is a divert socket, reject it. 864 */ 865 if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || 866 (inp->inp_socket->so_proto->pr_type != SOCK_RAW && 867 inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) { 868 INP_WUNLOCK(inp); 869 return (EOPNOTSUPP); 870 } 871 872 error = 0; 873 switch (sopt->sopt_name) { 874 case IP_MULTICAST_VIF: 875 if (imo != NULL) 876 optval = imo->imo_multicast_vif; 877 else 878 optval = -1; 879 INP_WUNLOCK(inp); 880 error = sooptcopyout(sopt, &optval, sizeof(int)); 881 break; 882 883 case IP_MULTICAST_IF: 884 memset(&mreqn, 0, sizeof(struct ip_mreqn)); 885 if (imo != NULL) { 886 ifp = imo->imo_multicast_ifp; 887 if (imo->imo_multicast_addr.s_addr != INADDR_ANY) { 888 mreqn.imr_address = imo->imo_multicast_addr; 889 } else if (ifp != NULL) { 890 mreqn.imr_ifindex = ifp->if_index; 891 IFP_TO_IA(ifp, ia); 892 if (ia != NULL) { 893 mreqn.imr_address = 894 IA_SIN(ia)->sin_addr; 895 } 896 } 897 } 898 INP_WUNLOCK(inp); 899 if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { 900 error = sooptcopyout(sopt, &mreqn, 901 sizeof(struct ip_mreqn)); 902 } else { 903 error = sooptcopyout(sopt, &mreqn.imr_address, 904 sizeof(struct in_addr)); 905 } 906 break; 907 908 case IP_MULTICAST_TTL: 909 if (imo == 0) 910 optval = coptval = IP_DEFAULT_MULTICAST_TTL; 911 else 912 optval = coptval = imo->imo_multicast_ttl; 913 INP_WUNLOCK(inp); 914 if (sopt->sopt_valsize == sizeof(u_char)) 915 error = sooptcopyout(sopt, &coptval, sizeof(u_char)); 916 else 917 error = sooptcopyout(sopt, &optval, sizeof(int)); 918 break; 919 920 case IP_MULTICAST_LOOP: 921 if (imo == 0) 922 optval = coptval = IP_DEFAULT_MULTICAST_LOOP; 923 else 924 optval = coptval = imo->imo_multicast_loop; 925 INP_WUNLOCK(inp); 926 if (sopt->sopt_valsize == sizeof(u_char)) 927 error = sooptcopyout(sopt, &coptval, sizeof(u_char)); 928 else 929 error = sooptcopyout(sopt, &optval, sizeof(int)); 930 break; 931 932 case IP_MSFILTER: 933 if (imo == NULL) { 934 error = EADDRNOTAVAIL; 935 INP_WUNLOCK(inp); 936 } else { 937 error = inp_get_source_filters(inp, sopt); 938 } 939 break; 940 941 default: 942 INP_WUNLOCK(inp); 943 error = ENOPROTOOPT; 944 break; 945 } 946 947 INP_UNLOCK_ASSERT(inp); 948 949 return (error); 950 } 951 952 /* 953 * Join an IPv4 multicast group, possibly with a source. 954 */ 955 static int 956 inp_join_group(struct inpcb *inp, struct sockopt *sopt) 957 { 958 struct group_source_req gsr; 959 sockunion_t *gsa, *ssa; 960 struct ifnet *ifp; 961 struct in_mfilter *imf; 962 struct ip_moptions *imo; 963 struct in_multi *inm; 964 size_t idx; 965 int error; 966 967 ifp = NULL; 968 error = 0; 969 970 memset(&gsr, 0, sizeof(struct group_source_req)); 971 gsa = (sockunion_t *)&gsr.gsr_group; 972 gsa->ss.ss_family = AF_UNSPEC; 973 ssa = (sockunion_t *)&gsr.gsr_source; 974 ssa->ss.ss_family = AF_UNSPEC; 975 976 switch (sopt->sopt_name) { 977 case IP_ADD_MEMBERSHIP: 978 case IP_ADD_SOURCE_MEMBERSHIP: { 979 struct ip_mreq_source mreqs; 980 981 if (sopt->sopt_name == IP_ADD_MEMBERSHIP) { 982 error = sooptcopyin(sopt, &mreqs, 983 sizeof(struct ip_mreq), 984 sizeof(struct ip_mreq)); 985 /* 986 * Do argument switcharoo from ip_mreq into 987 * ip_mreq_source to avoid using two instances. 988 */ 989 mreqs.imr_interface = mreqs.imr_sourceaddr; 990 mreqs.imr_sourceaddr.s_addr = INADDR_ANY; 991 } else if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) { 992 error = sooptcopyin(sopt, &mreqs, 993 sizeof(struct ip_mreq_source), 994 sizeof(struct ip_mreq_source)); 995 } 996 if (error) 997 return (error); 998 999 gsa->sin.sin_family = AF_INET; 1000 gsa->sin.sin_len = sizeof(struct sockaddr_in); 1001 gsa->sin.sin_addr = mreqs.imr_multiaddr; 1002 1003 if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) { 1004 ssa->sin.sin_family = AF_INET; 1005 ssa->sin.sin_len = sizeof(struct sockaddr_in); 1006 ssa->sin.sin_addr = mreqs.imr_sourceaddr; 1007 } 1008 1009 /* 1010 * Obtain ifp. If no interface address was provided, 1011 * use the interface of the route in the unicast FIB for 1012 * the given multicast destination; usually, this is the 1013 * default route. 1014 * If this lookup fails, attempt to use the first non-loopback 1015 * interface with multicast capability in the system as a 1016 * last resort. The legacy IPv4 ASM API requires that we do 1017 * this in order to allow groups to be joined when the routing 1018 * table has not yet been populated during boot. 1019 * If all of these conditions fail, return EADDRNOTAVAIL, and 1020 * reject the IPv4 multicast join. 1021 */ 1022 if (mreqs.imr_interface.s_addr != INADDR_ANY) { 1023 INADDR_TO_IFP(mreqs.imr_interface, ifp); 1024 } else { 1025 struct route ro; 1026 1027 ro.ro_rt = NULL; 1028 *(struct sockaddr_in *)&ro.ro_dst = gsa->sin; 1029 in_rtalloc_ign(&ro, RTF_CLONING, 1030 inp->inp_inc.inc_fibnum); 1031 if (ro.ro_rt != NULL) { 1032 ifp = ro.ro_rt->rt_ifp; 1033 KASSERT(ifp != NULL, ("%s: null ifp", 1034 __func__)); 1035 RTFREE(ro.ro_rt); 1036 } else { 1037 struct in_ifaddr *ia; 1038 struct ifnet *mfp = NULL; 1039 TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { 1040 mfp = ia->ia_ifp; 1041 if (!(mfp->if_flags & IFF_LOOPBACK) && 1042 (mfp->if_flags & IFF_MULTICAST)) { 1043 ifp = mfp; 1044 break; 1045 } 1046 } 1047 } 1048 } 1049 #ifdef DIAGNOSTIC 1050 if (bootverbose) { 1051 printf("%s: imr_interface = %s, ifp = %p\n", 1052 __func__, inet_ntoa(mreqs.imr_interface), ifp); 1053 } 1054 #endif 1055 break; 1056 } 1057 1058 case MCAST_JOIN_GROUP: 1059 case MCAST_JOIN_SOURCE_GROUP: 1060 if (sopt->sopt_name == MCAST_JOIN_GROUP) { 1061 error = sooptcopyin(sopt, &gsr, 1062 sizeof(struct group_req), 1063 sizeof(struct group_req)); 1064 } else if (sopt->sopt_name == MCAST_JOIN_SOURCE_GROUP) { 1065 error = sooptcopyin(sopt, &gsr, 1066 sizeof(struct group_source_req), 1067 sizeof(struct group_source_req)); 1068 } 1069 if (error) 1070 return (error); 1071 1072 if (gsa->sin.sin_family != AF_INET || 1073 gsa->sin.sin_len != sizeof(struct sockaddr_in)) 1074 return (EINVAL); 1075 1076 /* 1077 * Overwrite the port field if present, as the sockaddr 1078 * being copied in may be matched with a binary comparison. 1079 * XXX INET6 1080 */ 1081 gsa->sin.sin_port = 0; 1082 if (sopt->sopt_name == MCAST_JOIN_SOURCE_GROUP) { 1083 if (ssa->sin.sin_family != AF_INET || 1084 ssa->sin.sin_len != sizeof(struct sockaddr_in)) 1085 return (EINVAL); 1086 ssa->sin.sin_port = 0; 1087 } 1088 1089 /* 1090 * Obtain the ifp. 1091 */ 1092 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface) 1093 return (EADDRNOTAVAIL); 1094 ifp = ifnet_byindex(gsr.gsr_interface); 1095 1096 break; 1097 1098 default: 1099 #ifdef DIAGNOSTIC 1100 if (bootverbose) { 1101 printf("%s: unknown sopt_name %d\n", __func__, 1102 sopt->sopt_name); 1103 } 1104 #endif 1105 return (EOPNOTSUPP); 1106 break; 1107 } 1108 1109 if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr))) 1110 return (EINVAL); 1111 1112 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) 1113 return (EADDRNOTAVAIL); 1114 1115 /* 1116 * Check if we already hold membership of this group for this inpcb. 1117 * If so, we do not need to perform the initial join. 1118 */ 1119 imo = inp_findmoptions(inp); 1120 idx = imo_match_group(imo, ifp, &gsa->sa); 1121 if (idx != -1) { 1122 if (ssa->ss.ss_family != AF_UNSPEC) { 1123 /* 1124 * Attempting to join an ASM group (when already 1125 * an ASM or SSM member) is an error. 1126 */ 1127 error = EADDRNOTAVAIL; 1128 } else { 1129 imf = &imo->imo_mfilters[idx]; 1130 if (imf->imf_nsources == 0) { 1131 /* 1132 * Attempting to join an SSM group (when 1133 * already an ASM member) is an error. 1134 */ 1135 error = EINVAL; 1136 } else { 1137 /* 1138 * Attempting to join an SSM group (when 1139 * already an SSM member) means "add this 1140 * source to the inclusive filter list". 1141 */ 1142 error = imo_join_source(imo, idx, ssa); 1143 } 1144 } 1145 goto out_locked; 1146 } 1147 1148 /* 1149 * Call imo_grow() to reallocate the membership and source filter 1150 * vectors if they are full. If the size would exceed the hard limit, 1151 * then we know we've really run out of entries. We keep the INP 1152 * lock held to avoid introducing a race condition. 1153 */ 1154 if (imo->imo_num_memberships == imo->imo_max_memberships) { 1155 error = imo_grow(imo); 1156 if (error) 1157 goto out_locked; 1158 } 1159 1160 /* 1161 * So far, so good: perform the layer 3 join, layer 2 join, 1162 * and make an IGMP announcement if needed. 1163 */ 1164 inm = in_addmulti(&gsa->sin.sin_addr, ifp); 1165 if (inm == NULL) { 1166 error = ENOBUFS; 1167 goto out_locked; 1168 } 1169 idx = imo->imo_num_memberships; 1170 imo->imo_membership[idx] = inm; 1171 imo->imo_num_memberships++; 1172 1173 KASSERT(imo->imo_mfilters != NULL, 1174 ("%s: imf_mfilters vector was not allocated", __func__)); 1175 imf = &imo->imo_mfilters[idx]; 1176 KASSERT(TAILQ_EMPTY(&imf->imf_sources), 1177 ("%s: imf_sources not empty", __func__)); 1178 1179 /* 1180 * If this is a new SSM group join (i.e. a source was specified 1181 * with this group), add this source to the filter list. 1182 */ 1183 if (ssa->ss.ss_family != AF_UNSPEC) { 1184 /* 1185 * An initial SSM join implies that this socket's membership 1186 * of the multicast group is now in inclusive mode. 1187 */ 1188 imf->imf_fmode = MCAST_INCLUDE; 1189 1190 error = imo_join_source(imo, idx, ssa); 1191 if (error) { 1192 /* 1193 * Drop inp lock before calling in_delmulti(), 1194 * to prevent a lock order reversal. 1195 */ 1196 --imo->imo_num_memberships; 1197 INP_WUNLOCK(inp); 1198 in_delmulti(inm); 1199 return (error); 1200 } 1201 } 1202 1203 out_locked: 1204 INP_WUNLOCK(inp); 1205 return (error); 1206 } 1207 1208 /* 1209 * Leave an IPv4 multicast group on an inpcb, possibly with a source. 1210 */ 1211 static int 1212 inp_leave_group(struct inpcb *inp, struct sockopt *sopt) 1213 { 1214 struct group_source_req gsr; 1215 struct ip_mreq_source mreqs; 1216 sockunion_t *gsa, *ssa; 1217 struct ifnet *ifp; 1218 struct in_mfilter *imf; 1219 struct ip_moptions *imo; 1220 struct in_msource *ims, *tims; 1221 struct in_multi *inm; 1222 size_t idx; 1223 int error; 1224 1225 ifp = NULL; 1226 error = 0; 1227 1228 memset(&gsr, 0, sizeof(struct group_source_req)); 1229 gsa = (sockunion_t *)&gsr.gsr_group; 1230 gsa->ss.ss_family = AF_UNSPEC; 1231 ssa = (sockunion_t *)&gsr.gsr_source; 1232 ssa->ss.ss_family = AF_UNSPEC; 1233 1234 switch (sopt->sopt_name) { 1235 case IP_DROP_MEMBERSHIP: 1236 case IP_DROP_SOURCE_MEMBERSHIP: 1237 if (sopt->sopt_name == IP_DROP_MEMBERSHIP) { 1238 error = sooptcopyin(sopt, &mreqs, 1239 sizeof(struct ip_mreq), 1240 sizeof(struct ip_mreq)); 1241 /* 1242 * Swap interface and sourceaddr arguments, 1243 * as ip_mreq and ip_mreq_source are laid 1244 * out differently. 1245 */ 1246 mreqs.imr_interface = mreqs.imr_sourceaddr; 1247 mreqs.imr_sourceaddr.s_addr = INADDR_ANY; 1248 } else if (sopt->sopt_name == IP_DROP_SOURCE_MEMBERSHIP) { 1249 error = sooptcopyin(sopt, &mreqs, 1250 sizeof(struct ip_mreq_source), 1251 sizeof(struct ip_mreq_source)); 1252 } 1253 if (error) 1254 return (error); 1255 1256 gsa->sin.sin_family = AF_INET; 1257 gsa->sin.sin_len = sizeof(struct sockaddr_in); 1258 gsa->sin.sin_addr = mreqs.imr_multiaddr; 1259 1260 if (sopt->sopt_name == IP_DROP_SOURCE_MEMBERSHIP) { 1261 ssa->sin.sin_family = AF_INET; 1262 ssa->sin.sin_len = sizeof(struct sockaddr_in); 1263 ssa->sin.sin_addr = mreqs.imr_sourceaddr; 1264 } 1265 1266 if (gsa->sin.sin_addr.s_addr != INADDR_ANY) 1267 INADDR_TO_IFP(mreqs.imr_interface, ifp); 1268 1269 #ifdef DIAGNOSTIC 1270 if (bootverbose) { 1271 printf("%s: imr_interface = %s, ifp = %p\n", 1272 __func__, inet_ntoa(mreqs.imr_interface), ifp); 1273 } 1274 #endif 1275 break; 1276 1277 case MCAST_LEAVE_GROUP: 1278 case MCAST_LEAVE_SOURCE_GROUP: 1279 if (sopt->sopt_name == MCAST_LEAVE_GROUP) { 1280 error = sooptcopyin(sopt, &gsr, 1281 sizeof(struct group_req), 1282 sizeof(struct group_req)); 1283 } else if (sopt->sopt_name == MCAST_LEAVE_SOURCE_GROUP) { 1284 error = sooptcopyin(sopt, &gsr, 1285 sizeof(struct group_source_req), 1286 sizeof(struct group_source_req)); 1287 } 1288 if (error) 1289 return (error); 1290 1291 if (gsa->sin.sin_family != AF_INET || 1292 gsa->sin.sin_len != sizeof(struct sockaddr_in)) 1293 return (EINVAL); 1294 1295 if (sopt->sopt_name == MCAST_LEAVE_SOURCE_GROUP) { 1296 if (ssa->sin.sin_family != AF_INET || 1297 ssa->sin.sin_len != sizeof(struct sockaddr_in)) 1298 return (EINVAL); 1299 } 1300 1301 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface) 1302 return (EADDRNOTAVAIL); 1303 1304 ifp = ifnet_byindex(gsr.gsr_interface); 1305 break; 1306 1307 default: 1308 #ifdef DIAGNOSTIC 1309 if (bootverbose) { 1310 printf("%s: unknown sopt_name %d\n", __func__, 1311 sopt->sopt_name); 1312 } 1313 #endif 1314 return (EOPNOTSUPP); 1315 break; 1316 } 1317 1318 if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr))) 1319 return (EINVAL); 1320 1321 /* 1322 * Find the membership in the membership array. 1323 */ 1324 imo = inp_findmoptions(inp); 1325 idx = imo_match_group(imo, ifp, &gsa->sa); 1326 if (idx == -1) { 1327 error = EADDRNOTAVAIL; 1328 goto out_locked; 1329 } 1330 imf = &imo->imo_mfilters[idx]; 1331 1332 /* 1333 * If we were instructed only to leave a given source, do so. 1334 */ 1335 if (ssa->ss.ss_family != AF_UNSPEC) { 1336 if (imf->imf_nsources == 0 || 1337 imf->imf_fmode == MCAST_EXCLUDE) { 1338 /* 1339 * Attempting to SSM leave an ASM group 1340 * is an error; should use *_BLOCK_SOURCE instead. 1341 * Attempting to SSM leave a source in a group when 1342 * the socket is in 'exclude mode' is also an error. 1343 */ 1344 error = EINVAL; 1345 } else { 1346 error = imo_leave_source(imo, idx, ssa); 1347 } 1348 /* 1349 * If an error occurred, or this source is not the last 1350 * source in the group, do not leave the whole group. 1351 */ 1352 if (error || imf->imf_nsources > 0) 1353 goto out_locked; 1354 } 1355 1356 /* 1357 * Give up the multicast address record to which the membership points. 1358 */ 1359 inm = imo->imo_membership[idx]; 1360 in_delmulti(inm); 1361 1362 /* 1363 * Free any source filters for this group if they exist. 1364 * Revert inpcb to the default MCAST_EXCLUDE state. 1365 */ 1366 if (imo->imo_mfilters != NULL) { 1367 TAILQ_FOREACH_SAFE(ims, &imf->imf_sources, ims_next, tims) { 1368 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next); 1369 FREE(ims, M_IPMSOURCE); 1370 imf->imf_nsources--; 1371 } 1372 KASSERT(imf->imf_nsources == 0, 1373 ("%s: imf_nsources not 0", __func__)); 1374 KASSERT(TAILQ_EMPTY(&imf->imf_sources), 1375 ("%s: imf_sources not empty", __func__)); 1376 imf->imf_fmode = MCAST_EXCLUDE; 1377 } 1378 1379 /* 1380 * Remove the gap in the membership array. 1381 */ 1382 for (++idx; idx < imo->imo_num_memberships; ++idx) 1383 imo->imo_membership[idx-1] = imo->imo_membership[idx]; 1384 imo->imo_num_memberships--; 1385 1386 out_locked: 1387 INP_WUNLOCK(inp); 1388 return (error); 1389 } 1390 1391 /* 1392 * Select the interface for transmitting IPv4 multicast datagrams. 1393 * 1394 * Either an instance of struct in_addr or an instance of struct ip_mreqn 1395 * may be passed to this socket option. An address of INADDR_ANY or an 1396 * interface index of 0 is used to remove a previous selection. 1397 * When no interface is selected, one is chosen for every send. 1398 */ 1399 static int 1400 inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) 1401 { 1402 struct in_addr addr; 1403 struct ip_mreqn mreqn; 1404 struct ifnet *ifp; 1405 struct ip_moptions *imo; 1406 int error; 1407 1408 if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { 1409 /* 1410 * An interface index was specified using the 1411 * Linux-derived ip_mreqn structure. 1412 */ 1413 error = sooptcopyin(sopt, &mreqn, sizeof(struct ip_mreqn), 1414 sizeof(struct ip_mreqn)); 1415 if (error) 1416 return (error); 1417 1418 if (mreqn.imr_ifindex < 0 || V_if_index < mreqn.imr_ifindex) 1419 return (EINVAL); 1420 1421 if (mreqn.imr_ifindex == 0) { 1422 ifp = NULL; 1423 } else { 1424 ifp = ifnet_byindex(mreqn.imr_ifindex); 1425 if (ifp == NULL) 1426 return (EADDRNOTAVAIL); 1427 } 1428 } else { 1429 /* 1430 * An interface was specified by IPv4 address. 1431 * This is the traditional BSD usage. 1432 */ 1433 error = sooptcopyin(sopt, &addr, sizeof(struct in_addr), 1434 sizeof(struct in_addr)); 1435 if (error) 1436 return (error); 1437 if (addr.s_addr == INADDR_ANY) { 1438 ifp = NULL; 1439 } else { 1440 INADDR_TO_IFP(addr, ifp); 1441 if (ifp == NULL) 1442 return (EADDRNOTAVAIL); 1443 } 1444 #ifdef DIAGNOSTIC 1445 if (bootverbose) { 1446 printf("%s: ifp = %p, addr = %s\n", 1447 __func__, ifp, inet_ntoa(addr)); /* XXX INET6 */ 1448 } 1449 #endif 1450 } 1451 1452 /* Reject interfaces which do not support multicast. */ 1453 if (ifp != NULL && (ifp->if_flags & IFF_MULTICAST) == 0) 1454 return (EOPNOTSUPP); 1455 1456 imo = inp_findmoptions(inp); 1457 imo->imo_multicast_ifp = ifp; 1458 imo->imo_multicast_addr.s_addr = INADDR_ANY; 1459 INP_WUNLOCK(inp); 1460 1461 return (0); 1462 } 1463 1464 /* 1465 * Atomically set source filters on a socket for an IPv4 multicast group. 1466 */ 1467 static int 1468 inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt) 1469 { 1470 struct __msfilterreq msfr; 1471 sockunion_t *gsa; 1472 struct ifnet *ifp; 1473 struct in_mfilter *imf; 1474 struct ip_moptions *imo; 1475 struct in_msource *ims, *tims; 1476 size_t idx; 1477 int error; 1478 1479 error = sooptcopyin(sopt, &msfr, sizeof(struct __msfilterreq), 1480 sizeof(struct __msfilterreq)); 1481 if (error) 1482 return (error); 1483 1484 if (msfr.msfr_nsrcs > IP_MAX_SOURCE_FILTER || 1485 (msfr.msfr_fmode != MCAST_EXCLUDE && 1486 msfr.msfr_fmode != MCAST_INCLUDE)) 1487 return (EINVAL); 1488 1489 if (msfr.msfr_group.ss_family != AF_INET || 1490 msfr.msfr_group.ss_len != sizeof(struct sockaddr_in)) 1491 return (EINVAL); 1492 1493 gsa = (sockunion_t *)&msfr.msfr_group; 1494 if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr))) 1495 return (EINVAL); 1496 1497 gsa->sin.sin_port = 0; /* ignore port */ 1498 1499 if (msfr.msfr_ifindex == 0 || V_if_index < msfr.msfr_ifindex) 1500 return (EADDRNOTAVAIL); 1501 1502 ifp = ifnet_byindex(msfr.msfr_ifindex); 1503 if (ifp == NULL) 1504 return (EADDRNOTAVAIL); 1505 1506 /* 1507 * Take the INP lock. 1508 * Check if this socket is a member of this group. 1509 */ 1510 imo = inp_findmoptions(inp); 1511 idx = imo_match_group(imo, ifp, &gsa->sa); 1512 if (idx == -1 || imo->imo_mfilters == NULL) { 1513 error = EADDRNOTAVAIL; 1514 goto out_locked; 1515 } 1516 imf = &imo->imo_mfilters[idx]; 1517 1518 #ifdef DIAGNOSTIC 1519 if (bootverbose) 1520 printf("%s: clearing source list\n", __func__); 1521 #endif 1522 1523 /* 1524 * Remove any existing source filters. 1525 */ 1526 TAILQ_FOREACH_SAFE(ims, &imf->imf_sources, ims_next, tims) { 1527 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next); 1528 FREE(ims, M_IPMSOURCE); 1529 imf->imf_nsources--; 1530 } 1531 KASSERT(imf->imf_nsources == 0, 1532 ("%s: source list not cleared", __func__)); 1533 1534 /* 1535 * Apply any new source filters, if present. 1536 */ 1537 if (msfr.msfr_nsrcs > 0) { 1538 struct in_msource **pnims; 1539 struct in_msource *nims; 1540 struct sockaddr_storage *kss; 1541 struct sockaddr_storage *pkss; 1542 sockunion_t *psu; 1543 int i, j; 1544 1545 /* 1546 * Drop the inp lock so we may sleep if we need to 1547 * in order to satisfy a malloc request. 1548 * We will re-take it before changing socket state. 1549 */ 1550 INP_WUNLOCK(inp); 1551 #ifdef DIAGNOSTIC 1552 if (bootverbose) { 1553 printf("%s: loading %lu source list entries\n", 1554 __func__, (unsigned long)msfr.msfr_nsrcs); 1555 } 1556 #endif 1557 /* 1558 * Make a copy of the user-space source vector so 1559 * that we may copy them with a single copyin. This 1560 * allows us to deal with page faults up-front. 1561 */ 1562 MALLOC(kss, struct sockaddr_storage *, 1563 sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs, 1564 M_TEMP, M_WAITOK); 1565 error = copyin(msfr.msfr_srcs, kss, 1566 sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs); 1567 if (error) { 1568 FREE(kss, M_TEMP); 1569 return (error); 1570 } 1571 1572 /* 1573 * Perform argument checking on every sockaddr_storage 1574 * structure in the vector provided to us. Overwrite 1575 * fields which should not apply to source entries. 1576 * TODO: Check for duplicate sources on this pass. 1577 */ 1578 psu = (sockunion_t *)kss; 1579 for (i = 0; i < msfr.msfr_nsrcs; i++, psu++) { 1580 switch (psu->ss.ss_family) { 1581 case AF_INET: 1582 if (psu->sin.sin_len != 1583 sizeof(struct sockaddr_in)) { 1584 error = EINVAL; 1585 } else { 1586 psu->sin.sin_port = 0; 1587 } 1588 break; 1589 #ifdef notyet 1590 case AF_INET6; 1591 if (psu->sin6.sin6_len != 1592 sizeof(struct sockaddr_in6)) { 1593 error = EINVAL; 1594 } else { 1595 psu->sin6.sin6_port = 0; 1596 psu->sin6.sin6_flowinfo = 0; 1597 } 1598 break; 1599 #endif 1600 default: 1601 error = EAFNOSUPPORT; 1602 break; 1603 } 1604 if (error) 1605 break; 1606 } 1607 if (error) { 1608 FREE(kss, M_TEMP); 1609 return (error); 1610 } 1611 1612 /* 1613 * Allocate a block to track all the in_msource 1614 * entries we are about to allocate, in case we 1615 * abruptly need to free them. 1616 */ 1617 MALLOC(pnims, struct in_msource **, 1618 sizeof(struct in_msource *) * msfr.msfr_nsrcs, 1619 M_TEMP, M_WAITOK | M_ZERO); 1620 1621 /* 1622 * Allocate up to nsrcs individual chunks. 1623 * If we encounter an error, backtrack out of 1624 * all allocations cleanly; updates must be atomic. 1625 */ 1626 pkss = kss; 1627 nims = NULL; 1628 for (i = 0; i < msfr.msfr_nsrcs; i++, pkss++) { 1629 MALLOC(nims, struct in_msource *, 1630 sizeof(struct in_msource) * msfr.msfr_nsrcs, 1631 M_IPMSOURCE, M_WAITOK | M_ZERO); 1632 pnims[i] = nims; 1633 } 1634 if (i < msfr.msfr_nsrcs) { 1635 for (j = 0; j < i; j++) { 1636 if (pnims[j] != NULL) 1637 FREE(pnims[j], M_IPMSOURCE); 1638 } 1639 FREE(pnims, M_TEMP); 1640 FREE(kss, M_TEMP); 1641 return (ENOBUFS); 1642 } 1643 1644 INP_UNLOCK_ASSERT(inp); 1645 1646 /* 1647 * Finally, apply the filters to the socket. 1648 * Re-take the inp lock; we are changing socket state. 1649 */ 1650 pkss = kss; 1651 INP_WLOCK(inp); 1652 for (i = 0; i < msfr.msfr_nsrcs; i++, pkss++) { 1653 memcpy(&(pnims[i]->ims_addr), pkss, 1654 sizeof(struct sockaddr_storage)); 1655 TAILQ_INSERT_TAIL(&imf->imf_sources, pnims[i], 1656 ims_next); 1657 imf->imf_nsources++; 1658 } 1659 FREE(pnims, M_TEMP); 1660 FREE(kss, M_TEMP); 1661 } 1662 1663 /* 1664 * Update the filter mode on the socket before releasing the inpcb. 1665 */ 1666 INP_WLOCK_ASSERT(inp); 1667 imf->imf_fmode = msfr.msfr_fmode; 1668 1669 out_locked: 1670 INP_WUNLOCK(inp); 1671 return (error); 1672 } 1673 1674 /* 1675 * Set the IP multicast options in response to user setsockopt(). 1676 * 1677 * Many of the socket options handled in this function duplicate the 1678 * functionality of socket options in the regular unicast API. However, 1679 * it is not possible to merge the duplicate code, because the idempotence 1680 * of the IPv4 multicast part of the BSD Sockets API must be preserved; 1681 * the effects of these options must be treated as separate and distinct. 1682 */ 1683 int 1684 inp_setmoptions(struct inpcb *inp, struct sockopt *sopt) 1685 { 1686 struct ip_moptions *imo; 1687 int error; 1688 1689 error = 0; 1690 1691 /* 1692 * If socket is neither of type SOCK_RAW or SOCK_DGRAM, 1693 * or is a divert socket, reject it. 1694 * XXX Unlocked read of inp_socket believed OK. 1695 */ 1696 if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || 1697 (inp->inp_socket->so_proto->pr_type != SOCK_RAW && 1698 inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) 1699 return (EOPNOTSUPP); 1700 1701 switch (sopt->sopt_name) { 1702 case IP_MULTICAST_VIF: { 1703 int vifi; 1704 /* 1705 * Select a multicast VIF for transmission. 1706 * Only useful if multicast forwarding is active. 1707 */ 1708 if (legal_vif_num == NULL) { 1709 error = EOPNOTSUPP; 1710 break; 1711 } 1712 error = sooptcopyin(sopt, &vifi, sizeof(int), sizeof(int)); 1713 if (error) 1714 break; 1715 if (!legal_vif_num(vifi) && (vifi != -1)) { 1716 error = EINVAL; 1717 break; 1718 } 1719 imo = inp_findmoptions(inp); 1720 imo->imo_multicast_vif = vifi; 1721 INP_WUNLOCK(inp); 1722 break; 1723 } 1724 1725 case IP_MULTICAST_IF: 1726 error = inp_set_multicast_if(inp, sopt); 1727 break; 1728 1729 case IP_MULTICAST_TTL: { 1730 u_char ttl; 1731 1732 /* 1733 * Set the IP time-to-live for outgoing multicast packets. 1734 * The original multicast API required a char argument, 1735 * which is inconsistent with the rest of the socket API. 1736 * We allow either a char or an int. 1737 */ 1738 if (sopt->sopt_valsize == sizeof(u_char)) { 1739 error = sooptcopyin(sopt, &ttl, sizeof(u_char), 1740 sizeof(u_char)); 1741 if (error) 1742 break; 1743 } else { 1744 u_int ittl; 1745 1746 error = sooptcopyin(sopt, &ittl, sizeof(u_int), 1747 sizeof(u_int)); 1748 if (error) 1749 break; 1750 if (ittl > 255) { 1751 error = EINVAL; 1752 break; 1753 } 1754 ttl = (u_char)ittl; 1755 } 1756 imo = inp_findmoptions(inp); 1757 imo->imo_multicast_ttl = ttl; 1758 INP_WUNLOCK(inp); 1759 break; 1760 } 1761 1762 case IP_MULTICAST_LOOP: { 1763 u_char loop; 1764 1765 /* 1766 * Set the loopback flag for outgoing multicast packets. 1767 * Must be zero or one. The original multicast API required a 1768 * char argument, which is inconsistent with the rest 1769 * of the socket API. We allow either a char or an int. 1770 */ 1771 if (sopt->sopt_valsize == sizeof(u_char)) { 1772 error = sooptcopyin(sopt, &loop, sizeof(u_char), 1773 sizeof(u_char)); 1774 if (error) 1775 break; 1776 } else { 1777 u_int iloop; 1778 1779 error = sooptcopyin(sopt, &iloop, sizeof(u_int), 1780 sizeof(u_int)); 1781 if (error) 1782 break; 1783 loop = (u_char)iloop; 1784 } 1785 imo = inp_findmoptions(inp); 1786 imo->imo_multicast_loop = !!loop; 1787 INP_WUNLOCK(inp); 1788 break; 1789 } 1790 1791 case IP_ADD_MEMBERSHIP: 1792 case IP_ADD_SOURCE_MEMBERSHIP: 1793 case MCAST_JOIN_GROUP: 1794 case MCAST_JOIN_SOURCE_GROUP: 1795 error = inp_join_group(inp, sopt); 1796 break; 1797 1798 case IP_DROP_MEMBERSHIP: 1799 case IP_DROP_SOURCE_MEMBERSHIP: 1800 case MCAST_LEAVE_GROUP: 1801 case MCAST_LEAVE_SOURCE_GROUP: 1802 error = inp_leave_group(inp, sopt); 1803 break; 1804 1805 case IP_BLOCK_SOURCE: 1806 case IP_UNBLOCK_SOURCE: 1807 case MCAST_BLOCK_SOURCE: 1808 case MCAST_UNBLOCK_SOURCE: 1809 error = inp_change_source_filter(inp, sopt); 1810 break; 1811 1812 case IP_MSFILTER: 1813 error = inp_set_source_filters(inp, sopt); 1814 break; 1815 1816 default: 1817 error = EOPNOTSUPP; 1818 break; 1819 } 1820 1821 INP_UNLOCK_ASSERT(inp); 1822 1823 return (error); 1824 } 1825