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