]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/in_mcast.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.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 #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         INIT_VNET_INET(ifp->if_vnet);
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(&V_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         INIT_VNET_NET(curvnet);
468         INIT_VNET_INET(curvnet);
469         struct group_source_req          gsr;
470         sockunion_t                     *gsa, *ssa;
471         struct ifnet                    *ifp;
472         struct in_mfilter               *imf;
473         struct ip_moptions              *imo;
474         struct in_msource               *ims;
475         size_t                           idx;
476         int                              error;
477         int                              block;
478
479         ifp = NULL;
480         error = 0;
481         block = 0;
482
483         memset(&gsr, 0, sizeof(struct group_source_req));
484         gsa = (sockunion_t *)&gsr.gsr_group;
485         ssa = (sockunion_t *)&gsr.gsr_source;
486
487         switch (sopt->sopt_name) {
488         case IP_BLOCK_SOURCE:
489         case IP_UNBLOCK_SOURCE: {
490                 struct ip_mreq_source    mreqs;
491
492                 error = sooptcopyin(sopt, &mreqs,
493                     sizeof(struct ip_mreq_source),
494                     sizeof(struct ip_mreq_source));
495                 if (error)
496                         return (error);
497
498                 gsa->sin.sin_family = AF_INET;
499                 gsa->sin.sin_len = sizeof(struct sockaddr_in);
500                 gsa->sin.sin_addr = mreqs.imr_multiaddr;
501
502                 ssa->sin.sin_family = AF_INET;
503                 ssa->sin.sin_len = sizeof(struct sockaddr_in);
504                 ssa->sin.sin_addr = mreqs.imr_sourceaddr;
505
506                 if (mreqs.imr_interface.s_addr != INADDR_ANY)
507                         INADDR_TO_IFP(mreqs.imr_interface, ifp);
508
509                 if (sopt->sopt_name == IP_BLOCK_SOURCE)
510                         block = 1;
511
512 #ifdef DIAGNOSTIC
513                 if (bootverbose) {
514                         printf("%s: imr_interface = %s, ifp = %p\n",
515                             __func__, inet_ntoa(mreqs.imr_interface), ifp);
516                 }
517 #endif
518                 break;
519             }
520
521         case MCAST_BLOCK_SOURCE:
522         case MCAST_UNBLOCK_SOURCE:
523                 error = sooptcopyin(sopt, &gsr,
524                     sizeof(struct group_source_req),
525                     sizeof(struct group_source_req));
526                 if (error)
527                         return (error);
528
529                 if (gsa->sin.sin_family != AF_INET ||
530                     gsa->sin.sin_len != sizeof(struct sockaddr_in))
531                         return (EINVAL);
532
533                 if (ssa->sin.sin_family != AF_INET ||
534                     ssa->sin.sin_len != sizeof(struct sockaddr_in))
535                         return (EINVAL);
536
537                 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface)
538                         return (EADDRNOTAVAIL);
539
540                 ifp = ifnet_byindex(gsr.gsr_interface);
541
542                 if (sopt->sopt_name == MCAST_BLOCK_SOURCE)
543                         block = 1;
544                 break;
545
546         default:
547 #ifdef DIAGNOSTIC
548                 if (bootverbose) {
549                         printf("%s: unknown sopt_name %d\n", __func__,
550                             sopt->sopt_name);
551                 }
552 #endif
553                 return (EOPNOTSUPP);
554                 break;
555         }
556
557         /* XXX INET6 */
558         if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
559                 return (EINVAL);
560
561         /*
562          * Check if we are actually a member of this group.
563          */
564         imo = inp_findmoptions(inp);
565         idx = imo_match_group(imo, ifp, &gsa->sa);
566         if (idx == -1 || imo->imo_mfilters == NULL) {
567                 error = EADDRNOTAVAIL;
568                 goto out_locked;
569         }
570
571         KASSERT(imo->imo_mfilters != NULL,
572             ("%s: imo_mfilters not allocated", __func__));
573         imf = &imo->imo_mfilters[idx];
574
575         /*
576          * SSM multicast truth table for block/unblock operations.
577          *
578          * Operation   Filter Mode  Entry exists?   Action
579          *
580          * block       exclude      no              add source to filter
581          * unblock     include      no              add source to filter
582          * block       include      no              EINVAL
583          * unblock     exclude      no              EINVAL
584          * block       exclude      yes             EADDRNOTAVAIL
585          * unblock     include      yes             EADDRNOTAVAIL
586          * block       include      yes             remove source from filter
587          * unblock     exclude      yes             remove source from filter
588          *
589          * FreeBSD does not explicitly distinguish between ASM and SSM
590          * mode sockets; all sockets are assumed to have a filter list.
591          */
592 #ifdef DIAGNOSTIC
593         if (bootverbose) {
594                 printf("%s: imf_fmode is %s\n", __func__,
595                     imf->imf_fmode == MCAST_INCLUDE ? "include" : "exclude");
596         }
597 #endif
598         ims = imo_match_source(imo, idx, &ssa->sa);
599         if (ims == NULL) {
600                 if ((block == 1 && imf->imf_fmode == MCAST_EXCLUDE) ||
601                     (block == 0 && imf->imf_fmode == MCAST_INCLUDE)) {
602 #ifdef DIAGNOSTIC
603                         if (bootverbose) {
604                                 printf("%s: adding %s to filter list\n",
605                                     __func__, inet_ntoa(ssa->sin.sin_addr));
606                         }
607 #endif
608                         error = imo_join_source(imo, idx, ssa);
609                 }
610                 if ((block == 1 && imf->imf_fmode == MCAST_INCLUDE) ||
611                     (block == 0 && imf->imf_fmode == MCAST_EXCLUDE)) {
612                         /*
613                          * If the socket is in inclusive mode:
614                          *  the source is already blocked as it has no entry.
615                          * If the socket is in exclusive mode:
616                          *  the source is already unblocked as it has no entry.
617                          */
618 #ifdef DIAGNOSTIC
619                         if (bootverbose) {
620                                 printf("%s: ims %p; %s already [un]blocked\n",
621                                     __func__, ims,
622                                     inet_ntoa(ssa->sin.sin_addr));
623                         }
624 #endif
625                         error = EINVAL;
626                 }
627         } else {
628                 if ((block == 1 && imf->imf_fmode == MCAST_EXCLUDE) ||
629                     (block == 0 && imf->imf_fmode == MCAST_INCLUDE)) {
630                         /*
631                          * If the socket is in exclusive mode:
632                          *  the source is already blocked as it has an entry.
633                          * If the socket is in inclusive mode:
634                          *  the source is already unblocked as it has an entry.
635                          */
636 #ifdef DIAGNOSTIC
637                         if (bootverbose) {
638                                 printf("%s: ims %p; %s already [un]blocked\n",
639                                     __func__, ims,
640                                     inet_ntoa(ssa->sin.sin_addr));
641                         }
642 #endif
643                         error = EADDRNOTAVAIL;
644                 }
645                 if ((block == 1 && imf->imf_fmode == MCAST_INCLUDE) ||
646                     (block == 0 && imf->imf_fmode == MCAST_EXCLUDE)) {
647 #ifdef DIAGNOSTIC
648                         if (bootverbose) {
649                                 printf("%s: removing %s from filter list\n",
650                                     __func__, inet_ntoa(ssa->sin.sin_addr));
651                         }
652 #endif
653                         error = imo_leave_source(imo, idx, ssa);
654                 }
655         }
656
657 out_locked:
658         INP_WUNLOCK(inp);
659         return (error);
660 }
661
662 /*
663  * Given an inpcb, return its multicast options structure pointer.  Accepts
664  * an unlocked inpcb pointer, but will return it locked.  May sleep.
665  */
666 static struct ip_moptions *
667 inp_findmoptions(struct inpcb *inp)
668 {
669         struct ip_moptions       *imo;
670         struct in_multi         **immp;
671         struct in_mfilter        *imfp;
672         size_t                    idx;
673
674         INP_WLOCK(inp);
675         if (inp->inp_moptions != NULL)
676                 return (inp->inp_moptions);
677
678         INP_WUNLOCK(inp);
679
680         imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS,
681             M_WAITOK);
682         immp = (struct in_multi **)malloc(sizeof(*immp) * IP_MIN_MEMBERSHIPS,
683             M_IPMOPTS, M_WAITOK | M_ZERO);
684         imfp = (struct in_mfilter *)malloc(
685             sizeof(struct in_mfilter) * IP_MIN_MEMBERSHIPS,
686             M_IPMSOURCE, M_WAITOK);
687
688         imo->imo_multicast_ifp = NULL;
689         imo->imo_multicast_addr.s_addr = INADDR_ANY;
690         imo->imo_multicast_vif = -1;
691         imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
692         imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
693         imo->imo_num_memberships = 0;
694         imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
695         imo->imo_membership = immp;
696
697         /* Initialize per-group source filters. */
698         for (idx = 0; idx < IP_MIN_MEMBERSHIPS; idx++) {
699                 imfp[idx].imf_fmode = MCAST_EXCLUDE;
700                 imfp[idx].imf_nsources = 0;
701                 TAILQ_INIT(&imfp[idx].imf_sources);
702         }
703         imo->imo_mfilters = imfp;
704
705         INP_WLOCK(inp);
706         if (inp->inp_moptions != NULL) {
707                 free(imfp, M_IPMSOURCE);
708                 free(immp, M_IPMOPTS);
709                 free(imo, M_IPMOPTS);
710                 return (inp->inp_moptions);
711         }
712         inp->inp_moptions = imo;
713         return (imo);
714 }
715
716 /*
717  * Discard the IP multicast options (and source filters).
718  */
719 void
720 inp_freemoptions(struct ip_moptions *imo)
721 {
722         struct in_mfilter       *imf;
723         struct in_msource       *ims, *tims;
724         size_t                   idx, nmships;
725
726         KASSERT(imo != NULL, ("%s: ip_moptions is NULL", __func__));
727
728         nmships = imo->imo_num_memberships;
729         for (idx = 0; idx < nmships; ++idx) {
730                 in_delmulti(imo->imo_membership[idx]);
731
732                 if (imo->imo_mfilters != NULL) {
733                         imf = &imo->imo_mfilters[idx];
734                         TAILQ_FOREACH_SAFE(ims, &imf->imf_sources,
735                             ims_next, tims) {
736                                 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next);
737                                 FREE(ims, M_IPMSOURCE);
738                                 imf->imf_nsources--;
739                         }
740                         KASSERT(imf->imf_nsources == 0,
741                             ("%s: did not free all imf_nsources", __func__));
742                 }
743         }
744
745         if (imo->imo_mfilters != NULL)
746                 free(imo->imo_mfilters, M_IPMSOURCE);
747         free(imo->imo_membership, M_IPMOPTS);
748         free(imo, M_IPMOPTS);
749 }
750
751 /*
752  * Atomically get source filters on a socket for an IPv4 multicast group.
753  * Called with INP lock held; returns with lock released.
754  */
755 static int
756 inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt)
757 {
758         INIT_VNET_NET(curvnet);
759         struct __msfilterreq     msfr;
760         sockunion_t             *gsa;
761         struct ifnet            *ifp;
762         struct ip_moptions      *imo;
763         struct in_mfilter       *imf;
764         struct in_msource       *ims;
765         struct sockaddr_storage *ptss;
766         struct sockaddr_storage *tss;
767         int                      error;
768         size_t                   idx;
769
770         INP_WLOCK_ASSERT(inp);
771
772         imo = inp->inp_moptions;
773         KASSERT(imo != NULL, ("%s: null ip_moptions", __func__));
774
775         INP_WUNLOCK(inp);
776
777         error = sooptcopyin(sopt, &msfr, sizeof(struct __msfilterreq),
778             sizeof(struct __msfilterreq));
779         if (error)
780                 return (error);
781
782         if (msfr.msfr_ifindex == 0 || V_if_index < msfr.msfr_ifindex)
783                 return (EINVAL);
784
785         ifp = ifnet_byindex(msfr.msfr_ifindex);
786         if (ifp == NULL)
787                 return (EINVAL);
788
789         INP_WLOCK(inp);
790
791         /*
792          * Lookup group on the socket.
793          */
794         gsa = (sockunion_t *)&msfr.msfr_group;
795         idx = imo_match_group(imo, ifp, &gsa->sa);
796         if (idx == -1 || imo->imo_mfilters == NULL) {
797                 INP_WUNLOCK(inp);
798                 return (EADDRNOTAVAIL);
799         }
800
801         imf = &imo->imo_mfilters[idx];
802         msfr.msfr_fmode = imf->imf_fmode;
803         msfr.msfr_nsrcs = imf->imf_nsources;
804
805         /*
806          * If the user specified a buffer, copy out the source filter
807          * entries to userland gracefully.
808          * msfr.msfr_nsrcs is always set to the total number of filter
809          * entries which the kernel currently has for this group.
810          */
811         tss = NULL;
812         if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) {
813                 /*
814                  * Make a copy of the source vector so that we do not
815                  * thrash the inpcb lock whilst copying it out.
816                  * We only copy out the number of entries which userland
817                  * has asked for, but we always tell userland how big the
818                  * buffer really needs to be.
819                  */
820                 MALLOC(tss, struct sockaddr_storage *,
821                     sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
822                     M_TEMP, M_NOWAIT);
823                 if (tss == NULL) {
824                         error = ENOBUFS;
825                 } else {
826                         ptss = tss;
827                         TAILQ_FOREACH(ims, &imf->imf_sources, ims_next) {
828                                 memcpy(ptss++, &ims->ims_addr,
829                                     sizeof(struct sockaddr_storage));
830                         }
831                 }
832         }
833
834         INP_WUNLOCK(inp);
835
836         if (tss != NULL) {
837                 error = copyout(tss, msfr.msfr_srcs,
838                     sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs);
839                 FREE(tss, M_TEMP);
840         }
841
842         if (error)
843                 return (error);
844
845         error = sooptcopyout(sopt, &msfr, sizeof(struct __msfilterreq));
846
847         return (error);
848 }
849
850 /*
851  * Return the IP multicast options in response to user getsockopt().
852  */
853 int
854 inp_getmoptions(struct inpcb *inp, struct sockopt *sopt)
855 {
856         INIT_VNET_INET(curvnet);
857         struct ip_mreqn          mreqn;
858         struct ip_moptions      *imo;
859         struct ifnet            *ifp;
860         struct in_ifaddr        *ia;
861         int                      error, optval;
862         u_char                   coptval;
863
864         INP_WLOCK(inp);
865         imo = inp->inp_moptions;
866         /*
867          * If socket is neither of type SOCK_RAW or SOCK_DGRAM,
868          * or is a divert socket, reject it.
869          */
870         if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT ||
871             (inp->inp_socket->so_proto->pr_type != SOCK_RAW &&
872             inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) {
873                 INP_WUNLOCK(inp);
874                 return (EOPNOTSUPP);
875         }
876
877         error = 0;
878         switch (sopt->sopt_name) {
879         case IP_MULTICAST_VIF:
880                 if (imo != NULL)
881                         optval = imo->imo_multicast_vif;
882                 else
883                         optval = -1;
884                 INP_WUNLOCK(inp);
885                 error = sooptcopyout(sopt, &optval, sizeof(int));
886                 break;
887
888         case IP_MULTICAST_IF:
889                 memset(&mreqn, 0, sizeof(struct ip_mreqn));
890                 if (imo != NULL) {
891                         ifp = imo->imo_multicast_ifp;
892                         if (imo->imo_multicast_addr.s_addr != INADDR_ANY) {
893                                 mreqn.imr_address = imo->imo_multicast_addr;
894                         } else if (ifp != NULL) {
895                                 mreqn.imr_ifindex = ifp->if_index;
896                                 IFP_TO_IA(ifp, ia);
897                                 if (ia != NULL) {
898                                         mreqn.imr_address =
899                                             IA_SIN(ia)->sin_addr;
900                                 }
901                         }
902                 }
903                 INP_WUNLOCK(inp);
904                 if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) {
905                         error = sooptcopyout(sopt, &mreqn,
906                             sizeof(struct ip_mreqn));
907                 } else {
908                         error = sooptcopyout(sopt, &mreqn.imr_address,
909                             sizeof(struct in_addr));
910                 }
911                 break;
912
913         case IP_MULTICAST_TTL:
914                 if (imo == 0)
915                         optval = coptval = IP_DEFAULT_MULTICAST_TTL;
916                 else
917                         optval = coptval = imo->imo_multicast_ttl;
918                 INP_WUNLOCK(inp);
919                 if (sopt->sopt_valsize == sizeof(u_char))
920                         error = sooptcopyout(sopt, &coptval, sizeof(u_char));
921                 else
922                         error = sooptcopyout(sopt, &optval, sizeof(int));
923                 break;
924
925         case IP_MULTICAST_LOOP:
926                 if (imo == 0)
927                         optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
928                 else
929                         optval = coptval = imo->imo_multicast_loop;
930                 INP_WUNLOCK(inp);
931                 if (sopt->sopt_valsize == sizeof(u_char))
932                         error = sooptcopyout(sopt, &coptval, sizeof(u_char));
933                 else
934                         error = sooptcopyout(sopt, &optval, sizeof(int));
935                 break;
936
937         case IP_MSFILTER:
938                 if (imo == NULL) {
939                         error = EADDRNOTAVAIL;
940                         INP_WUNLOCK(inp);
941                 } else {
942                         error = inp_get_source_filters(inp, sopt);
943                 }
944                 break;
945
946         default:
947                 INP_WUNLOCK(inp);
948                 error = ENOPROTOOPT;
949                 break;
950         }
951
952         INP_UNLOCK_ASSERT(inp);
953
954         return (error);
955 }
956
957 /*
958  * Join an IPv4 multicast group, possibly with a source.
959  */
960 static int
961 inp_join_group(struct inpcb *inp, struct sockopt *sopt)
962 {
963         INIT_VNET_NET(curvnet);
964         INIT_VNET_INET(curvnet);
965         struct group_source_req          gsr;
966         sockunion_t                     *gsa, *ssa;
967         struct ifnet                    *ifp;
968         struct in_mfilter               *imf;
969         struct ip_moptions              *imo;
970         struct in_multi                 *inm;
971         size_t                           idx;
972         int                              error;
973
974         ifp = NULL;
975         error = 0;
976
977         memset(&gsr, 0, sizeof(struct group_source_req));
978         gsa = (sockunion_t *)&gsr.gsr_group;
979         gsa->ss.ss_family = AF_UNSPEC;
980         ssa = (sockunion_t *)&gsr.gsr_source;
981         ssa->ss.ss_family = AF_UNSPEC;
982
983         switch (sopt->sopt_name) {
984         case IP_ADD_MEMBERSHIP:
985         case IP_ADD_SOURCE_MEMBERSHIP: {
986                 struct ip_mreq_source    mreqs;
987
988                 if (sopt->sopt_name == IP_ADD_MEMBERSHIP) {
989                         error = sooptcopyin(sopt, &mreqs,
990                             sizeof(struct ip_mreq),
991                             sizeof(struct ip_mreq));
992                         /*
993                          * Do argument switcharoo from ip_mreq into
994                          * ip_mreq_source to avoid using two instances.
995                          */
996                         mreqs.imr_interface = mreqs.imr_sourceaddr;
997                         mreqs.imr_sourceaddr.s_addr = INADDR_ANY;
998                 } else if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) {
999                         error = sooptcopyin(sopt, &mreqs,
1000                             sizeof(struct ip_mreq_source),
1001                             sizeof(struct ip_mreq_source));
1002                 }
1003                 if (error)
1004                         return (error);
1005
1006                 gsa->sin.sin_family = AF_INET;
1007                 gsa->sin.sin_len = sizeof(struct sockaddr_in);
1008                 gsa->sin.sin_addr = mreqs.imr_multiaddr;
1009
1010                 if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) {
1011                         ssa->sin.sin_family = AF_INET;
1012                         ssa->sin.sin_len = sizeof(struct sockaddr_in);
1013                         ssa->sin.sin_addr = mreqs.imr_sourceaddr;
1014                 }
1015
1016                 /*
1017                  * Obtain ifp. If no interface address was provided,
1018                  * use the interface of the route in the unicast FIB for
1019                  * the given multicast destination; usually, this is the
1020                  * default route.
1021                  * If this lookup fails, attempt to use the first non-loopback
1022                  * interface with multicast capability in the system as a
1023                  * last resort. The legacy IPv4 ASM API requires that we do
1024                  * this in order to allow groups to be joined when the routing
1025                  * table has not yet been populated during boot.
1026                  * If all of these conditions fail, return EADDRNOTAVAIL, and
1027                  * reject the IPv4 multicast join.
1028                  */
1029                 if (mreqs.imr_interface.s_addr != INADDR_ANY) {
1030                         INADDR_TO_IFP(mreqs.imr_interface, ifp);
1031                 } else {
1032                         struct route ro;
1033
1034                         ro.ro_rt = NULL;
1035                         *(struct sockaddr_in *)&ro.ro_dst = gsa->sin;
1036                         in_rtalloc_ign(&ro, RTF_CLONING,
1037                            inp->inp_inc.inc_fibnum);
1038                         if (ro.ro_rt != NULL) {
1039                                 ifp = ro.ro_rt->rt_ifp;
1040                                 KASSERT(ifp != NULL, ("%s: null ifp",
1041                                     __func__));
1042                                 RTFREE(ro.ro_rt);
1043                         } else {
1044                                 struct in_ifaddr *ia;
1045                                 struct ifnet *mfp = NULL;
1046                                 TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
1047                                         mfp = ia->ia_ifp;
1048                                         if (!(mfp->if_flags & IFF_LOOPBACK) &&
1049                                              (mfp->if_flags & IFF_MULTICAST)) {
1050                                                 ifp = mfp;
1051                                                 break;
1052                                         }
1053                                 }
1054                         }
1055                 }
1056 #ifdef DIAGNOSTIC
1057                 if (bootverbose) {
1058                         printf("%s: imr_interface = %s, ifp = %p\n",
1059                             __func__, inet_ntoa(mreqs.imr_interface), ifp);
1060                 }
1061 #endif
1062                 break;
1063         }
1064
1065         case MCAST_JOIN_GROUP:
1066         case MCAST_JOIN_SOURCE_GROUP:
1067                 if (sopt->sopt_name == MCAST_JOIN_GROUP) {
1068                         error = sooptcopyin(sopt, &gsr,
1069                             sizeof(struct group_req),
1070                             sizeof(struct group_req));
1071                 } else if (sopt->sopt_name == MCAST_JOIN_SOURCE_GROUP) {
1072                         error = sooptcopyin(sopt, &gsr,
1073                             sizeof(struct group_source_req),
1074                             sizeof(struct group_source_req));
1075                 }
1076                 if (error)
1077                         return (error);
1078
1079                 if (gsa->sin.sin_family != AF_INET ||
1080                     gsa->sin.sin_len != sizeof(struct sockaddr_in))
1081                         return (EINVAL);
1082
1083                 /*
1084                  * Overwrite the port field if present, as the sockaddr
1085                  * being copied in may be matched with a binary comparison.
1086                  * XXX INET6
1087                  */
1088                 gsa->sin.sin_port = 0;
1089                 if (sopt->sopt_name == MCAST_JOIN_SOURCE_GROUP) {
1090                         if (ssa->sin.sin_family != AF_INET ||
1091                             ssa->sin.sin_len != sizeof(struct sockaddr_in))
1092                                 return (EINVAL);
1093                         ssa->sin.sin_port = 0;
1094                 }
1095
1096                 /*
1097                  * Obtain the ifp.
1098                  */
1099                 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface)
1100                         return (EADDRNOTAVAIL);
1101                 ifp = ifnet_byindex(gsr.gsr_interface);
1102
1103                 break;
1104
1105         default:
1106 #ifdef DIAGNOSTIC
1107                 if (bootverbose) {
1108                         printf("%s: unknown sopt_name %d\n", __func__,
1109                             sopt->sopt_name);
1110                 }
1111 #endif
1112                 return (EOPNOTSUPP);
1113                 break;
1114         }
1115
1116         if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
1117                 return (EINVAL);
1118
1119         if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0)
1120                 return (EADDRNOTAVAIL);
1121
1122         /*
1123          * Check if we already hold membership of this group for this inpcb.
1124          * If so, we do not need to perform the initial join.
1125          */
1126         imo = inp_findmoptions(inp);
1127         idx = imo_match_group(imo, ifp, &gsa->sa);
1128         if (idx != -1) {
1129                 if (ssa->ss.ss_family != AF_UNSPEC) {
1130                         /*
1131                          * Attempting to join an ASM group (when already
1132                          * an ASM or SSM member) is an error.
1133                          */
1134                         error = EADDRNOTAVAIL;
1135                 } else {
1136                         imf = &imo->imo_mfilters[idx];
1137                         if (imf->imf_nsources == 0) {
1138                                 /*
1139                                  * Attempting to join an SSM group (when
1140                                  * already an ASM member) is an error.
1141                                  */
1142                                 error = EINVAL;
1143                         } else {
1144                                 /*
1145                                  * Attempting to join an SSM group (when
1146                                  * already an SSM member) means "add this
1147                                  * source to the inclusive filter list".
1148                                  */
1149                                 error = imo_join_source(imo, idx, ssa);
1150                         }
1151                 }
1152                 goto out_locked;
1153         }
1154
1155         /*
1156          * Call imo_grow() to reallocate the membership and source filter
1157          * vectors if they are full. If the size would exceed the hard limit,
1158          * then we know we've really run out of entries. We keep the INP
1159          * lock held to avoid introducing a race condition.
1160          */
1161         if (imo->imo_num_memberships == imo->imo_max_memberships) {
1162                 error = imo_grow(imo);
1163                 if (error)
1164                         goto out_locked;
1165         }
1166
1167         /*
1168          * So far, so good: perform the layer 3 join, layer 2 join,
1169          * and make an IGMP announcement if needed.
1170          */
1171         inm = in_addmulti(&gsa->sin.sin_addr, ifp);
1172         if (inm == NULL) {
1173                 error = ENOBUFS;
1174                 goto out_locked;
1175         }
1176         idx = imo->imo_num_memberships;
1177         imo->imo_membership[idx] = inm;
1178         imo->imo_num_memberships++;
1179
1180         KASSERT(imo->imo_mfilters != NULL,
1181             ("%s: imf_mfilters vector was not allocated", __func__));
1182         imf = &imo->imo_mfilters[idx];
1183         KASSERT(TAILQ_EMPTY(&imf->imf_sources),
1184             ("%s: imf_sources not empty", __func__));
1185
1186         /*
1187          * If this is a new SSM group join (i.e. a source was specified
1188          * with this group), add this source to the filter list.
1189          */
1190         if (ssa->ss.ss_family != AF_UNSPEC) {
1191                 /*
1192                  * An initial SSM join implies that this socket's membership
1193                  * of the multicast group is now in inclusive mode.
1194                  */
1195                 imf->imf_fmode = MCAST_INCLUDE;
1196
1197                 error = imo_join_source(imo, idx, ssa);
1198                 if (error) {
1199                         /*
1200                          * Drop inp lock before calling in_delmulti(),
1201                          * to prevent a lock order reversal.
1202                          */
1203                         --imo->imo_num_memberships;
1204                         INP_WUNLOCK(inp);
1205                         in_delmulti(inm);
1206                         return (error);
1207                 }
1208         }
1209
1210 out_locked:
1211         INP_WUNLOCK(inp);
1212         return (error);
1213 }
1214
1215 /*
1216  * Leave an IPv4 multicast group on an inpcb, possibly with a source.
1217  */
1218 static int
1219 inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
1220 {
1221         INIT_VNET_NET(curvnet);
1222         INIT_VNET_INET(curvnet);
1223         struct group_source_req          gsr;
1224         struct ip_mreq_source            mreqs;
1225         sockunion_t                     *gsa, *ssa;
1226         struct ifnet                    *ifp;
1227         struct in_mfilter               *imf;
1228         struct ip_moptions              *imo;
1229         struct in_msource               *ims, *tims;
1230         struct in_multi                 *inm;
1231         size_t                           idx;
1232         int                              error;
1233
1234         ifp = NULL;
1235         error = 0;
1236
1237         memset(&gsr, 0, sizeof(struct group_source_req));
1238         gsa = (sockunion_t *)&gsr.gsr_group;
1239         gsa->ss.ss_family = AF_UNSPEC;
1240         ssa = (sockunion_t *)&gsr.gsr_source;
1241         ssa->ss.ss_family = AF_UNSPEC;
1242
1243         switch (sopt->sopt_name) {
1244         case IP_DROP_MEMBERSHIP:
1245         case IP_DROP_SOURCE_MEMBERSHIP:
1246                 if (sopt->sopt_name == IP_DROP_MEMBERSHIP) {
1247                         error = sooptcopyin(sopt, &mreqs,
1248                             sizeof(struct ip_mreq),
1249                             sizeof(struct ip_mreq));
1250                         /*
1251                          * Swap interface and sourceaddr arguments,
1252                          * as ip_mreq and ip_mreq_source are laid
1253                          * out differently.
1254                          */
1255                         mreqs.imr_interface = mreqs.imr_sourceaddr;
1256                         mreqs.imr_sourceaddr.s_addr = INADDR_ANY;
1257                 } else if (sopt->sopt_name == IP_DROP_SOURCE_MEMBERSHIP) {
1258                         error = sooptcopyin(sopt, &mreqs,
1259                             sizeof(struct ip_mreq_source),
1260                             sizeof(struct ip_mreq_source));
1261                 }
1262                 if (error)
1263                         return (error);
1264
1265                 gsa->sin.sin_family = AF_INET;
1266                 gsa->sin.sin_len = sizeof(struct sockaddr_in);
1267                 gsa->sin.sin_addr = mreqs.imr_multiaddr;
1268
1269                 if (sopt->sopt_name == IP_DROP_SOURCE_MEMBERSHIP) {
1270                         ssa->sin.sin_family = AF_INET;
1271                         ssa->sin.sin_len = sizeof(struct sockaddr_in);
1272                         ssa->sin.sin_addr = mreqs.imr_sourceaddr;
1273                 }
1274
1275                 if (gsa->sin.sin_addr.s_addr != INADDR_ANY)
1276                         INADDR_TO_IFP(mreqs.imr_interface, ifp);
1277
1278 #ifdef DIAGNOSTIC
1279                 if (bootverbose) {
1280                         printf("%s: imr_interface = %s, ifp = %p\n",
1281                             __func__, inet_ntoa(mreqs.imr_interface), ifp);
1282                 }
1283 #endif
1284                 break;
1285
1286         case MCAST_LEAVE_GROUP:
1287         case MCAST_LEAVE_SOURCE_GROUP:
1288                 if (sopt->sopt_name == MCAST_LEAVE_GROUP) {
1289                         error = sooptcopyin(sopt, &gsr,
1290                             sizeof(struct group_req),
1291                             sizeof(struct group_req));
1292                 } else if (sopt->sopt_name == MCAST_LEAVE_SOURCE_GROUP) {
1293                         error = sooptcopyin(sopt, &gsr,
1294                             sizeof(struct group_source_req),
1295                             sizeof(struct group_source_req));
1296                 }
1297                 if (error)
1298                         return (error);
1299
1300                 if (gsa->sin.sin_family != AF_INET ||
1301                     gsa->sin.sin_len != sizeof(struct sockaddr_in))
1302                         return (EINVAL);
1303
1304                 if (sopt->sopt_name == MCAST_LEAVE_SOURCE_GROUP) {
1305                         if (ssa->sin.sin_family != AF_INET ||
1306                             ssa->sin.sin_len != sizeof(struct sockaddr_in))
1307                                 return (EINVAL);
1308                 }
1309
1310                 if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface)
1311                         return (EADDRNOTAVAIL);
1312
1313                 ifp = ifnet_byindex(gsr.gsr_interface);
1314                 break;
1315
1316         default:
1317 #ifdef DIAGNOSTIC
1318                 if (bootverbose) {
1319                         printf("%s: unknown sopt_name %d\n", __func__,
1320                             sopt->sopt_name);
1321                 }
1322 #endif
1323                 return (EOPNOTSUPP);
1324                 break;
1325         }
1326
1327         if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
1328                 return (EINVAL);
1329
1330         /*
1331          * Find the membership in the membership array.
1332          */
1333         imo = inp_findmoptions(inp);
1334         idx = imo_match_group(imo, ifp, &gsa->sa);
1335         if (idx == -1) {
1336                 error = EADDRNOTAVAIL;
1337                 goto out_locked;
1338         }
1339         imf = &imo->imo_mfilters[idx];
1340
1341         /*
1342          * If we were instructed only to leave a given source, do so.
1343          */
1344         if (ssa->ss.ss_family != AF_UNSPEC) {
1345                 if (imf->imf_nsources == 0 ||
1346                     imf->imf_fmode == MCAST_EXCLUDE) {
1347                         /*
1348                          * Attempting to SSM leave an ASM group
1349                          * is an error; should use *_BLOCK_SOURCE instead.
1350                          * Attempting to SSM leave a source in a group when
1351                          * the socket is in 'exclude mode' is also an error.
1352                          */
1353                         error = EINVAL;
1354                 } else {
1355                         error = imo_leave_source(imo, idx, ssa);
1356                 }
1357                 /*
1358                  * If an error occurred, or this source is not the last
1359                  * source in the group, do not leave the whole group.
1360                  */
1361                 if (error || imf->imf_nsources > 0)
1362                         goto out_locked;
1363         }
1364
1365         /*
1366          * Give up the multicast address record to which the membership points.
1367          */
1368         inm = imo->imo_membership[idx];
1369         in_delmulti(inm);
1370
1371         /*
1372          * Free any source filters for this group if they exist.
1373          * Revert inpcb to the default MCAST_EXCLUDE state.
1374          */
1375         if (imo->imo_mfilters != NULL) {
1376                 TAILQ_FOREACH_SAFE(ims, &imf->imf_sources, ims_next, tims) {
1377                         TAILQ_REMOVE(&imf->imf_sources, ims, ims_next);
1378                         FREE(ims, M_IPMSOURCE);
1379                         imf->imf_nsources--;
1380                 }
1381                 KASSERT(imf->imf_nsources == 0,
1382                     ("%s: imf_nsources not 0", __func__));
1383                 KASSERT(TAILQ_EMPTY(&imf->imf_sources),
1384                     ("%s: imf_sources not empty", __func__));
1385                 imf->imf_fmode = MCAST_EXCLUDE;
1386         }
1387
1388         /*
1389          * Remove the gap in the membership array.
1390          */
1391         for (++idx; idx < imo->imo_num_memberships; ++idx)
1392                 imo->imo_membership[idx-1] = imo->imo_membership[idx];
1393         imo->imo_num_memberships--;
1394
1395 out_locked:
1396         INP_WUNLOCK(inp);
1397         return (error);
1398 }
1399
1400 /*
1401  * Select the interface for transmitting IPv4 multicast datagrams.
1402  *
1403  * Either an instance of struct in_addr or an instance of struct ip_mreqn
1404  * may be passed to this socket option. An address of INADDR_ANY or an
1405  * interface index of 0 is used to remove a previous selection.
1406  * When no interface is selected, one is chosen for every send.
1407  */
1408 static int
1409 inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
1410 {
1411         INIT_VNET_NET(curvnet);
1412         struct in_addr           addr;
1413         struct ip_mreqn          mreqn;
1414         struct ifnet            *ifp;
1415         struct ip_moptions      *imo;
1416         int                      error;
1417
1418         if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) {
1419                 /*
1420                  * An interface index was specified using the
1421                  * Linux-derived ip_mreqn structure.
1422                  */
1423                 error = sooptcopyin(sopt, &mreqn, sizeof(struct ip_mreqn),
1424                     sizeof(struct ip_mreqn));
1425                 if (error)
1426                         return (error);
1427
1428                 if (mreqn.imr_ifindex < 0 || V_if_index < mreqn.imr_ifindex)
1429                         return (EINVAL);
1430
1431                 if (mreqn.imr_ifindex == 0) {
1432                         ifp = NULL;
1433                 } else {
1434                         ifp = ifnet_byindex(mreqn.imr_ifindex);
1435                         if (ifp == NULL)
1436                                 return (EADDRNOTAVAIL);
1437                 }
1438         } else {
1439                 /*
1440                  * An interface was specified by IPv4 address.
1441                  * This is the traditional BSD usage.
1442                  */
1443                 error = sooptcopyin(sopt, &addr, sizeof(struct in_addr),
1444                     sizeof(struct in_addr));
1445                 if (error)
1446                         return (error);
1447                 if (addr.s_addr == INADDR_ANY) {
1448                         ifp = NULL;
1449                 } else {
1450                         INADDR_TO_IFP(addr, ifp);
1451                         if (ifp == NULL)
1452                                 return (EADDRNOTAVAIL);
1453                 }
1454 #ifdef DIAGNOSTIC
1455                 if (bootverbose) {
1456                         printf("%s: ifp = %p, addr = %s\n",
1457                             __func__, ifp, inet_ntoa(addr)); /* XXX INET6 */
1458                 }
1459 #endif
1460         }
1461
1462         /* Reject interfaces which do not support multicast. */
1463         if (ifp != NULL && (ifp->if_flags & IFF_MULTICAST) == 0)
1464                 return (EOPNOTSUPP);
1465
1466         imo = inp_findmoptions(inp);
1467         imo->imo_multicast_ifp = ifp;
1468         imo->imo_multicast_addr.s_addr = INADDR_ANY;
1469         INP_WUNLOCK(inp);
1470
1471         return (0);
1472 }
1473
1474 /*
1475  * Atomically set source filters on a socket for an IPv4 multicast group.
1476  */
1477 static int
1478 inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
1479 {
1480         INIT_VNET_NET(curvnet);
1481         struct __msfilterreq     msfr;
1482         sockunion_t             *gsa;
1483         struct ifnet            *ifp;
1484         struct in_mfilter       *imf;
1485         struct ip_moptions      *imo;
1486         struct in_msource       *ims, *tims;
1487         size_t                   idx;
1488         int                      error;
1489
1490         error = sooptcopyin(sopt, &msfr, sizeof(struct __msfilterreq),
1491             sizeof(struct __msfilterreq));
1492         if (error)
1493                 return (error);
1494
1495         if (msfr.msfr_nsrcs > IP_MAX_SOURCE_FILTER ||
1496             (msfr.msfr_fmode != MCAST_EXCLUDE &&
1497              msfr.msfr_fmode != MCAST_INCLUDE))
1498                 return (EINVAL);
1499
1500         if (msfr.msfr_group.ss_family != AF_INET ||
1501             msfr.msfr_group.ss_len != sizeof(struct sockaddr_in))
1502                 return (EINVAL);
1503
1504         gsa = (sockunion_t *)&msfr.msfr_group;
1505         if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
1506                 return (EINVAL);
1507
1508         gsa->sin.sin_port = 0;  /* ignore port */
1509
1510         if (msfr.msfr_ifindex == 0 || V_if_index < msfr.msfr_ifindex)
1511                 return (EADDRNOTAVAIL);
1512
1513         ifp = ifnet_byindex(msfr.msfr_ifindex);
1514         if (ifp == NULL)
1515                 return (EADDRNOTAVAIL);
1516
1517         /*
1518          * Take the INP lock.
1519          * Check if this socket is a member of this group.
1520          */
1521         imo = inp_findmoptions(inp);
1522         idx = imo_match_group(imo, ifp, &gsa->sa);
1523         if (idx == -1 || imo->imo_mfilters == NULL) {
1524                 error = EADDRNOTAVAIL;
1525                 goto out_locked;
1526         }
1527         imf = &imo->imo_mfilters[idx];
1528
1529 #ifdef DIAGNOSTIC
1530         if (bootverbose)
1531                 printf("%s: clearing source list\n", __func__);
1532 #endif
1533
1534         /*
1535          * Remove any existing source filters.
1536          */
1537         TAILQ_FOREACH_SAFE(ims, &imf->imf_sources, ims_next, tims) {
1538                 TAILQ_REMOVE(&imf->imf_sources, ims, ims_next);
1539                 FREE(ims, M_IPMSOURCE);
1540                 imf->imf_nsources--;
1541         }
1542         KASSERT(imf->imf_nsources == 0,
1543             ("%s: source list not cleared", __func__));
1544
1545         /*
1546          * Apply any new source filters, if present.
1547          */
1548         if (msfr.msfr_nsrcs > 0) {
1549                 struct in_msource       **pnims;
1550                 struct in_msource       *nims;
1551                 struct sockaddr_storage *kss;
1552                 struct sockaddr_storage *pkss;
1553                 sockunion_t             *psu;
1554                 int                      i, j;
1555
1556                 /*
1557                  * Drop the inp lock so we may sleep if we need to
1558                  * in order to satisfy a malloc request.
1559                  * We will re-take it before changing socket state.
1560                  */
1561                 INP_WUNLOCK(inp);
1562 #ifdef DIAGNOSTIC
1563                 if (bootverbose) {
1564                         printf("%s: loading %lu source list entries\n",
1565                             __func__, (unsigned long)msfr.msfr_nsrcs);
1566                 }
1567 #endif
1568                 /*
1569                  * Make a copy of the user-space source vector so
1570                  * that we may copy them with a single copyin. This
1571                  * allows us to deal with page faults up-front.
1572                  */
1573                 MALLOC(kss, struct sockaddr_storage *,
1574                     sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
1575                     M_TEMP, M_WAITOK);
1576                 error = copyin(msfr.msfr_srcs, kss,
1577                     sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs);
1578                 if (error) {
1579                         FREE(kss, M_TEMP);
1580                         return (error);
1581                 }
1582
1583                 /*
1584                  * Perform argument checking on every sockaddr_storage
1585                  * structure in the vector provided to us. Overwrite
1586                  * fields which should not apply to source entries.
1587                  * TODO: Check for duplicate sources on this pass.
1588                  */
1589                 psu = (sockunion_t *)kss;
1590                 for (i = 0; i < msfr.msfr_nsrcs; i++, psu++) {
1591                         switch (psu->ss.ss_family) {
1592                         case AF_INET:
1593                                 if (psu->sin.sin_len !=
1594                                     sizeof(struct sockaddr_in)) {
1595                                         error = EINVAL;
1596                                 } else {
1597                                         psu->sin.sin_port = 0;
1598                                 }
1599                                 break;
1600 #ifdef notyet
1601                         case AF_INET6;
1602                                 if (psu->sin6.sin6_len !=
1603                                     sizeof(struct sockaddr_in6)) {
1604                                         error = EINVAL;
1605                                 } else {
1606                                         psu->sin6.sin6_port = 0;
1607                                         psu->sin6.sin6_flowinfo = 0;
1608                                 }
1609                                 break;
1610 #endif
1611                         default:
1612                                 error = EAFNOSUPPORT;
1613                                 break;
1614                         }
1615                         if (error)
1616                                 break;
1617                 }
1618                 if (error) {
1619                         FREE(kss, M_TEMP);
1620                         return (error);
1621                 }
1622
1623                 /*
1624                  * Allocate a block to track all the in_msource
1625                  * entries we are about to allocate, in case we
1626                  * abruptly need to free them.
1627                  */
1628                 MALLOC(pnims, struct in_msource **,
1629                     sizeof(struct in_msource *) * msfr.msfr_nsrcs,
1630                     M_TEMP, M_WAITOK | M_ZERO);
1631
1632                 /*
1633                  * Allocate up to nsrcs individual chunks.
1634                  * If we encounter an error, backtrack out of
1635                  * all allocations cleanly; updates must be atomic.
1636                  */
1637                 pkss = kss;
1638                 nims = NULL;
1639                 for (i = 0; i < msfr.msfr_nsrcs; i++, pkss++) {
1640                         MALLOC(nims, struct in_msource *,
1641                             sizeof(struct in_msource) * msfr.msfr_nsrcs,
1642                             M_IPMSOURCE, M_WAITOK | M_ZERO);
1643                         pnims[i] = nims;
1644                 }
1645                 if (i < msfr.msfr_nsrcs) {
1646                         for (j = 0; j < i; j++) {
1647                                 if (pnims[j] != NULL)
1648                                         FREE(pnims[j], M_IPMSOURCE);
1649                         }
1650                         FREE(pnims, M_TEMP);
1651                         FREE(kss, M_TEMP);
1652                         return (ENOBUFS);
1653                 }
1654
1655                 INP_UNLOCK_ASSERT(inp);
1656
1657                 /*
1658                  * Finally, apply the filters to the socket.
1659                  * Re-take the inp lock; we are changing socket state.
1660                  */
1661                 pkss = kss;
1662                 INP_WLOCK(inp);
1663                 for (i = 0; i < msfr.msfr_nsrcs; i++, pkss++) {
1664                         memcpy(&(pnims[i]->ims_addr), pkss,
1665                             sizeof(struct sockaddr_storage));
1666                         TAILQ_INSERT_TAIL(&imf->imf_sources, pnims[i],
1667                             ims_next);
1668                         imf->imf_nsources++;
1669                 }
1670                 FREE(pnims, M_TEMP);
1671                 FREE(kss, M_TEMP);
1672         }
1673
1674         /*
1675          * Update the filter mode on the socket before releasing the inpcb.
1676          */
1677         INP_WLOCK_ASSERT(inp);
1678         imf->imf_fmode = msfr.msfr_fmode;
1679
1680 out_locked:
1681         INP_WUNLOCK(inp);
1682         return (error);
1683 }
1684
1685 /*
1686  * Set the IP multicast options in response to user setsockopt().
1687  *
1688  * Many of the socket options handled in this function duplicate the
1689  * functionality of socket options in the regular unicast API. However,
1690  * it is not possible to merge the duplicate code, because the idempotence
1691  * of the IPv4 multicast part of the BSD Sockets API must be preserved;
1692  * the effects of these options must be treated as separate and distinct.
1693  */
1694 int
1695 inp_setmoptions(struct inpcb *inp, struct sockopt *sopt)
1696 {
1697         struct ip_moptions      *imo;
1698         int                      error;
1699
1700         error = 0;
1701
1702         /*
1703          * If socket is neither of type SOCK_RAW or SOCK_DGRAM,
1704          * or is a divert socket, reject it.
1705          * XXX Unlocked read of inp_socket believed OK.
1706          */
1707         if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT ||
1708             (inp->inp_socket->so_proto->pr_type != SOCK_RAW &&
1709             inp->inp_socket->so_proto->pr_type != SOCK_DGRAM))
1710                 return (EOPNOTSUPP);
1711
1712         switch (sopt->sopt_name) {
1713         case IP_MULTICAST_VIF: {
1714                 int vifi;
1715                 /*
1716                  * Select a multicast VIF for transmission.
1717                  * Only useful if multicast forwarding is active.
1718                  */
1719                 if (legal_vif_num == NULL) {
1720                         error = EOPNOTSUPP;
1721                         break;
1722                 }
1723                 error = sooptcopyin(sopt, &vifi, sizeof(int), sizeof(int));
1724                 if (error)
1725                         break;
1726                 if (!legal_vif_num(vifi) && (vifi != -1)) {
1727                         error = EINVAL;
1728                         break;
1729                 }
1730                 imo = inp_findmoptions(inp);
1731                 imo->imo_multicast_vif = vifi;
1732                 INP_WUNLOCK(inp);
1733                 break;
1734         }
1735
1736         case IP_MULTICAST_IF:
1737                 error = inp_set_multicast_if(inp, sopt);
1738                 break;
1739
1740         case IP_MULTICAST_TTL: {
1741                 u_char ttl;
1742
1743                 /*
1744                  * Set the IP time-to-live for outgoing multicast packets.
1745                  * The original multicast API required a char argument,
1746                  * which is inconsistent with the rest of the socket API.
1747                  * We allow either a char or an int.
1748                  */
1749                 if (sopt->sopt_valsize == sizeof(u_char)) {
1750                         error = sooptcopyin(sopt, &ttl, sizeof(u_char),
1751                             sizeof(u_char));
1752                         if (error)
1753                                 break;
1754                 } else {
1755                         u_int ittl;
1756
1757                         error = sooptcopyin(sopt, &ittl, sizeof(u_int),
1758                             sizeof(u_int));
1759                         if (error)
1760                                 break;
1761                         if (ittl > 255) {
1762                                 error = EINVAL;
1763                                 break;
1764                         }
1765                         ttl = (u_char)ittl;
1766                 }
1767                 imo = inp_findmoptions(inp);
1768                 imo->imo_multicast_ttl = ttl;
1769                 INP_WUNLOCK(inp);
1770                 break;
1771         }
1772
1773         case IP_MULTICAST_LOOP: {
1774                 u_char loop;
1775
1776                 /*
1777                  * Set the loopback flag for outgoing multicast packets.
1778                  * Must be zero or one.  The original multicast API required a
1779                  * char argument, which is inconsistent with the rest
1780                  * of the socket API.  We allow either a char or an int.
1781                  */
1782                 if (sopt->sopt_valsize == sizeof(u_char)) {
1783                         error = sooptcopyin(sopt, &loop, sizeof(u_char),
1784                             sizeof(u_char));
1785                         if (error)
1786                                 break;
1787                 } else {
1788                         u_int iloop;
1789
1790                         error = sooptcopyin(sopt, &iloop, sizeof(u_int),
1791                                             sizeof(u_int));
1792                         if (error)
1793                                 break;
1794                         loop = (u_char)iloop;
1795                 }
1796                 imo = inp_findmoptions(inp);
1797                 imo->imo_multicast_loop = !!loop;
1798                 INP_WUNLOCK(inp);
1799                 break;
1800         }
1801
1802         case IP_ADD_MEMBERSHIP:
1803         case IP_ADD_SOURCE_MEMBERSHIP:
1804         case MCAST_JOIN_GROUP:
1805         case MCAST_JOIN_SOURCE_GROUP:
1806                 error = inp_join_group(inp, sopt);
1807                 break;
1808
1809         case IP_DROP_MEMBERSHIP:
1810         case IP_DROP_SOURCE_MEMBERSHIP:
1811         case MCAST_LEAVE_GROUP:
1812         case MCAST_LEAVE_SOURCE_GROUP:
1813                 error = inp_leave_group(inp, sopt);
1814                 break;
1815
1816         case IP_BLOCK_SOURCE:
1817         case IP_UNBLOCK_SOURCE:
1818         case MCAST_BLOCK_SOURCE:
1819         case MCAST_UNBLOCK_SOURCE:
1820                 error = inp_change_source_filter(inp, sopt);
1821                 break;
1822
1823         case IP_MSFILTER:
1824                 error = inp_set_source_filters(inp, sopt);
1825                 break;
1826
1827         default:
1828                 error = EOPNOTSUPP;
1829                 break;
1830         }
1831
1832         INP_UNLOCK_ASSERT(inp);
1833
1834         return (error);
1835 }