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