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