OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv6/] [mcast.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Multicast support for IPv6
3
 *      Linux INET6 implementation
4
 *
5
 *      Authors:
6
 *      Pedro Roque             <roque@di.fc.ul.pt>
7
 *
8
 *      $Id: mcast.c,v 1.1.1.1 2004-04-15 01:14:41 phoenix Exp $
9
 *
10
 *      Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
11
 *
12
 *      This program is free software; you can redistribute it and/or
13
 *      modify it under the terms of the GNU General Public License
14
 *      as published by the Free Software Foundation; either version
15
 *      2 of the License, or (at your option) any later version.
16
 */
17
 
18
/* Changes:
19
 *
20
 *      yoshfuji        : fix format of router-alert option
21
 *      YOSHIFUJI Hideaki @USAGI:
22
 *              Fixed source address for MLD message based on
23
 *              <draft-ietf-magma-mld-source-02.txt>.
24
 *      YOSHIFUJI Hideaki @USAGI:
25
 *              - Ignore Queries for invalid addresses.
26
 *              - MLD for link-local addresses.
27
 *      David L Stevens <dlstevens@us.ibm.com>:
28
                - MLDv2 support
29
 */
30
 
31
#include <linux/config.h>
32
#include <linux/module.h>
33
#include <linux/errno.h>
34
#include <linux/types.h>
35
#include <linux/string.h>
36
#include <linux/socket.h>
37
#include <linux/sockios.h>
38
#include <linux/sched.h>
39
#include <linux/net.h>
40
#include <linux/in.h>
41
#include <linux/in6.h>
42
#include <linux/netdevice.h>
43
#include <linux/if_arp.h>
44
#include <linux/route.h>
45
#include <linux/init.h>
46
#include <linux/proc_fs.h>
47
 
48
#include <linux/netfilter.h>
49
#include <linux/netfilter_ipv6.h>
50
 
51
#include <net/sock.h>
52
#include <net/snmp.h>
53
 
54
#include <net/ipv6.h>
55
#include <net/protocol.h>
56
#include <net/if_inet6.h>
57
#include <net/ndisc.h>
58
#include <net/addrconf.h>
59
#include <net/ip6_route.h>
60
 
61
#include <net/checksum.h>
62
 
63
/* Set to 3 to get tracing... */
64
#define MCAST_DEBUG 2
65
 
66
#if MCAST_DEBUG >= 3
67
#define MDBG(x) printk x
68
#else
69
#define MDBG(x)
70
#endif
71
 
72
/*
73
 *  These header formats should be in a separate include file, but icmpv6.h
74
 *  doesn't have in6_addr defined in all cases, there is no __u128, and no
75
 *  other files reference these.
76
 *
77
 *                      +-DLS 4/14/03
78
 */
79
 
80
/* Multicast Listener Discovery version 2 headers */
81
 
82
struct mld2_grec {
83
        __u8            grec_type;
84
        __u8            grec_auxwords;
85
        __u16           grec_nsrcs;
86
        struct in6_addr grec_mca;
87
        struct in6_addr grec_src[0];
88
};
89
 
90
struct mld2_report {
91
        __u8    type;
92
        __u8    resv1;
93
        __u16   csum;
94
        __u16   resv2;
95
        __u16   ngrec;
96
        struct mld2_grec grec[0];
97
};
98
 
99
struct mld2_query {
100
        __u8 type;
101
        __u8 code;
102
        __u16 csum;
103
        __u16 mrc;
104
        __u16 resv1;
105
        struct in6_addr mca;
106
#if defined(__LITTLE_ENDIAN_BITFIELD)
107
        __u8 qrv:3,
108
             suppress:1,
109
             resv2:4;
110
#elif defined(__BIG_ENDIAN_BITFIELD)
111
        __u8 resv2:4,
112
             suppress:1,
113
             qrv:3;
114
#else
115
#error "Please fix <asm/byteorder.h>"
116
#endif
117
        __u8 qqic;
118
        __u16 nsrcs;
119
        struct in6_addr srcs[0];
120
};
121
 
122
struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
123
struct in6_addr all_nodes_addr = {{{0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1}}};
124
 
125
/* Big mc list lock for all the sockets */
126
static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
127
 
128
static struct socket *igmp6_socket;
129
 
130
static void igmp6_join_group(struct ifmcaddr6 *ma);
131
static void igmp6_leave_group(struct ifmcaddr6 *ma);
132
static void igmp6_timer_handler(unsigned long data);
133
 
134
static void mld_gq_timer_expire(unsigned long data);
135
static void mld_ifc_timer_expire(unsigned long data);
136
static void mld_ifc_event(struct inet6_dev *idev);
137
static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
138
static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *addr);
139
static void mld_clear_delrec(struct inet6_dev *idev);
140
static int sf_setstate(struct ifmcaddr6 *pmc);
141
static void sf_markstate(struct ifmcaddr6 *pmc);
142
static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
143
int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
144
        int sfcount, struct in6_addr *psfsrc, int delta);
145
int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
146
        int sfcount, struct in6_addr *psfsrc, int delta);
147
int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
148
        struct inet6_dev *idev);
149
 
150
 
151
#define IGMP6_UNSOLICITED_IVAL  (10*HZ)
152
#define MLD_QRV_DEFAULT         2
153
 
154
#define MLD_V1_SEEN(idev) ((idev)->mc_v1_seen && \
155
                time_before(jiffies, (idev)->mc_v1_seen))
156
 
157
#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
158
#define MLDV2_EXP(thresh, nbmant, nbexp, value) \
159
        ((value) < (thresh) ? (value) : \
160
        ((MLDV2_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \
161
        (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
162
 
163
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
164
#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
165
 
166
#define IPV6_MLD_MAX_MSF        10
167
 
168
int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
169
 
170
/*
171
 *      socket join on multicast group
172
 */
173
 
174
int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
175
{
176
        struct net_device *dev = NULL;
177
        struct ipv6_mc_socklist *mc_lst;
178
        struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
179
        int err;
180
 
181
        if (!(ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST))
182
                return -EINVAL;
183
 
184
        mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
185
 
186
        if (mc_lst == NULL)
187
                return -ENOMEM;
188
 
189
        mc_lst->next = NULL;
190
        memcpy(&mc_lst->addr, addr, sizeof(struct in6_addr));
191
 
192
        if (ifindex == 0) {
193
                struct rt6_info *rt;
194
                rt = rt6_lookup(addr, NULL, 0, 0);
195
                if (rt) {
196
                        dev = rt->rt6i_dev;
197
                        dev_hold(dev);
198
                        dst_release(&rt->u.dst);
199
                }
200
        } else
201
                dev = dev_get_by_index(ifindex);
202
 
203
        if (dev == NULL) {
204
                sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
205
                return -ENODEV;
206
        }
207
 
208
        mc_lst->ifindex = dev->ifindex;
209
        mc_lst->sfmode = MCAST_EXCLUDE;
210
        mc_lst->sflist = 0;
211
 
212
        /*
213
         *      now add/increase the group membership on the device
214
         */
215
 
216
        err = ipv6_dev_mc_inc(dev, addr);
217
 
218
        if (err) {
219
                sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
220
                dev_put(dev);
221
                return err;
222
        }
223
 
224
        write_lock_bh(&ipv6_sk_mc_lock);
225
        mc_lst->next = np->ipv6_mc_list;
226
        np->ipv6_mc_list = mc_lst;
227
        write_unlock_bh(&ipv6_sk_mc_lock);
228
 
229
        dev_put(dev);
230
 
231
        return 0;
232
}
233
 
234
/*
235
 *      socket leave on multicast group
236
 */
237
int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
238
{
239
        struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
240
        struct ipv6_mc_socklist *mc_lst, **lnk;
241
 
242
        write_lock_bh(&ipv6_sk_mc_lock);
243
        for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) {
244
                if (mc_lst->ifindex == ifindex &&
245
                    ipv6_addr_cmp(&mc_lst->addr, addr) == 0) {
246
                        struct net_device *dev;
247
 
248
                        *lnk = mc_lst->next;
249
                        write_unlock_bh(&ipv6_sk_mc_lock);
250
 
251
                        if ((dev = dev_get_by_index(ifindex)) != NULL) {
252
                                struct inet6_dev *idev = in6_dev_get(dev);
253
 
254
                                if (idev) {
255
                                        (void) ip6_mc_leave_src(sk,mc_lst,idev);
256
                                        in6_dev_put(idev);
257
                                }
258
                                ipv6_dev_mc_dec(dev, &mc_lst->addr);
259
                                dev_put(dev);
260
                        }
261
                        sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
262
                        return 0;
263
                }
264
        }
265
        write_unlock_bh(&ipv6_sk_mc_lock);
266
 
267
        return -ENOENT;
268
}
269
 
270
struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
271
{
272
        struct net_device *dev = 0;
273
        struct inet6_dev *idev = 0;
274
 
275
        if (ifindex == 0) {
276
                struct rt6_info *rt;
277
 
278
                rt = rt6_lookup(group, NULL, 0, 0);
279
                if (rt) {
280
                        dev = rt->rt6i_dev;
281
                        dev_hold(dev);
282
                        dst_release(&rt->u.dst);
283
                }
284
        } else
285
                dev = dev_get_by_index(ifindex);
286
 
287
        if (!dev)
288
                return 0;
289
        idev = in6_dev_get(dev);
290
        if (!idev) {
291
                dev_put(dev);
292
                return 0;
293
        }
294
        read_lock_bh(&idev->lock);
295
        if (idev->dead) {
296
                read_unlock_bh(&idev->lock);
297
                in6_dev_put(idev);
298
                dev_put(dev);
299
                return 0;
300
        }
301
        return idev;
302
}
303
 
304
void ipv6_sock_mc_close(struct sock *sk)
305
{
306
        struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
307
        struct ipv6_mc_socklist *mc_lst;
308
 
309
        write_lock_bh(&ipv6_sk_mc_lock);
310
        while ((mc_lst = np->ipv6_mc_list) != NULL) {
311
                struct net_device *dev;
312
 
313
                np->ipv6_mc_list = mc_lst->next;
314
                write_unlock_bh(&ipv6_sk_mc_lock);
315
 
316
                dev = dev_get_by_index(mc_lst->ifindex);
317
                if (dev) {
318
                        struct inet6_dev *idev = in6_dev_get(dev);
319
 
320
                        if (idev) {
321
                                (void) ip6_mc_leave_src(sk, mc_lst, idev);
322
                                in6_dev_put(idev);
323
                        }
324
                        ipv6_dev_mc_dec(dev, &mc_lst->addr);
325
                        dev_put(dev);
326
                }
327
 
328
                sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
329
 
330
                write_lock_bh(&ipv6_sk_mc_lock);
331
        }
332
        write_unlock_bh(&ipv6_sk_mc_lock);
333
}
334
 
335
int ip6_mc_source(int add, int omode, struct sock *sk,
336
        struct group_source_req *pgsr)
337
{
338
        struct in6_addr *source, *group;
339
        struct ipv6_mc_socklist *pmc;
340
        struct net_device *dev;
341
        struct inet6_dev *idev;
342
        struct ipv6_pinfo *inet6 = &sk->net_pinfo.af_inet6;
343
        struct ip6_sf_socklist *psl;
344
        int i, j, rv;
345
        int err;
346
 
347
        if (pgsr->gsr_group.ss_family != AF_INET6 ||
348
            pgsr->gsr_source.ss_family != AF_INET6)
349
                return -EINVAL;
350
 
351
        source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
352
        group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
353
 
354
        if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
355
                return -EINVAL;
356
 
357
        idev = ip6_mc_find_dev(group, pgsr->gsr_interface);
358
        if (!idev)
359
                return -ENODEV;
360
        dev = idev->dev;
361
 
362
        err = -EADDRNOTAVAIL;
363
 
364
        for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
365
                if (pmc->ifindex != pgsr->gsr_interface)
366
                        continue;
367
                if (ipv6_addr_cmp(&pmc->addr, group) == 0)
368
                        break;
369
        }
370
        if (!pmc)               /* must have a prior join */
371
                goto done;
372
        /* if a source filter was set, must be the same mode as before */
373
        if (pmc->sflist) {
374
                if (pmc->sfmode != omode)
375
                        goto done;
376
        } else if (pmc->sfmode != omode) {
377
                /* allow mode switches for empty-set filters */
378
                ip6_mc_add_src(idev, group, omode, 0, 0, 0);
379
                ip6_mc_del_src(idev, group, pmc->sfmode, 0, 0, 0);
380
                pmc->sfmode = omode;
381
        }
382
 
383
        psl = pmc->sflist;
384
        if (!add) {
385
                if (!psl)
386
                        goto done;
387
                rv = !0;
388
                for (i=0; i<psl->sl_count; i++) {
389
                        rv = memcmp(&psl->sl_addr, group,
390
                                sizeof(struct in6_addr));
391
                        if (rv >= 0)
392
                                break;
393
                }
394
                if (!rv)        /* source not found */
395
                        goto done;
396
 
397
                /* update the interface filter */
398
                ip6_mc_del_src(idev, group, omode, 1, source, 1);
399
 
400
                for (j=i+1; j<psl->sl_count; j++)
401
                        psl->sl_addr[j-1] = psl->sl_addr[j];
402
                psl->sl_count--;
403
                err = 0;
404
                goto done;
405
        }
406
        /* else, add a new source to the filter */
407
 
408
        if (psl && psl->sl_count >= sysctl_mld_max_msf) {
409
                err = -ENOBUFS;
410
                goto done;
411
        }
412
        if (!psl || psl->sl_count == psl->sl_max) {
413
                struct ip6_sf_socklist *newpsl;
414
                int count = IP6_SFBLOCK;
415
 
416
                if (psl)
417
                        count += psl->sl_max;
418
                newpsl = (struct ip6_sf_socklist *)sock_kmalloc(sk,
419
                        IP6_SFLSIZE(count), GFP_ATOMIC);
420
                if (!newpsl) {
421
                        err = -ENOBUFS;
422
                        goto done;
423
                }
424
                newpsl->sl_max = count;
425
                newpsl->sl_count = count - IP6_SFBLOCK;
426
                if (psl) {
427
                        for (i=0; i<psl->sl_count; i++)
428
                                newpsl->sl_addr[i] = psl->sl_addr[i];
429
                        sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max));
430
                }
431
                pmc->sflist = psl = newpsl;
432
        }
433
        rv = 1; /* > 0 for insert logic below if sl_count is 0 */
434
        for (i=0; i<psl->sl_count; i++) {
435
                rv = memcmp(&psl->sl_addr, group, sizeof(struct in6_addr));
436
                if (rv >= 0)
437
                        break;
438
        }
439
        if (rv == 0)             /* address already there is an error */
440
                goto done;
441
        for (j=psl->sl_count-1; j>=i; j--)
442
                psl->sl_addr[j+1] = psl->sl_addr[j];
443
        psl->sl_addr[i] = *source;
444
        psl->sl_count++;
445
        err = 0;
446
        /* update the interface list */
447
        ip6_mc_add_src(idev, group, omode, 1, source, 1);
448
done:
449
        read_unlock_bh(&idev->lock);
450
        in6_dev_put(idev);
451
        dev_put(dev);
452
        return err;
453
}
454
 
455
int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
456
{
457
        struct in6_addr *group;
458
        struct ipv6_mc_socklist *pmc;
459
        struct net_device *dev;
460
        struct inet6_dev *idev;
461
        struct ipv6_pinfo *inet6 = &sk->net_pinfo.af_inet6;
462
        struct ip6_sf_socklist *newpsl, *psl;
463
        int i, err;
464
 
465
        group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
466
 
467
        if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
468
                return -EINVAL;
469
        if (gsf->gf_fmode != MCAST_INCLUDE &&
470
            gsf->gf_fmode != MCAST_EXCLUDE)
471
                return -EINVAL;
472
 
473
        idev = ip6_mc_find_dev(group, gsf->gf_interface);
474
 
475
        if (!idev)
476
                return -ENODEV;
477
        dev = idev->dev;
478
        err = -EADDRNOTAVAIL;
479
 
480
        for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
481
                if (pmc->ifindex != gsf->gf_interface)
482
                        continue;
483
                if (ipv6_addr_cmp(&pmc->addr, group) == 0)
484
                        break;
485
        }
486
        if (!pmc)               /* must have a prior join */
487
                goto done;
488
        if (gsf->gf_numsrc) {
489
                newpsl = (struct ip6_sf_socklist *)sock_kmalloc(sk,
490
                                IP6_SFLSIZE(gsf->gf_numsrc), GFP_ATOMIC);
491
                if (!newpsl) {
492
                        err = -ENOBUFS;
493
                        goto done;
494
                }
495
                newpsl->sl_max = newpsl->sl_count = gsf->gf_numsrc;
496
                for (i=0; i<newpsl->sl_count; ++i) {
497
                        struct sockaddr_in6 *psin6;
498
 
499
                        psin6 = (struct sockaddr_in6 *)&gsf->gf_slist[i];
500
                        newpsl->sl_addr[i] = psin6->sin6_addr;
501
                }
502
                err = ip6_mc_add_src(idev, group, gsf->gf_fmode,
503
                        newpsl->sl_count, newpsl->sl_addr, 0);
504
                if (err) {
505
                        sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max));
506
                        goto done;
507
                }
508
        } else
509
                newpsl = 0;
510
        psl = pmc->sflist;
511
        if (psl) {
512
                (void) ip6_mc_del_src(idev, group, pmc->sfmode,
513
                        psl->sl_count, psl->sl_addr, 0);
514
                sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max));
515
        } else
516
                (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, 0, 0);
517
        pmc->sflist = newpsl;
518
        pmc->sfmode = gsf->gf_fmode;
519
done:
520
        read_unlock_bh(&idev->lock);
521
        in6_dev_put(idev);
522
        dev_put(dev);
523
        return err;
524
}
525
 
526
int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
527
        struct group_filter *optval, int *optlen)
528
{
529
        int err, i, count, copycount;
530
        struct in6_addr *group;
531
        struct ipv6_mc_socklist *pmc;
532
        struct inet6_dev *idev;
533
        struct net_device *dev;
534
        struct ipv6_pinfo *inet6 = &sk->net_pinfo.af_inet6;
535
        struct ip6_sf_socklist *psl;
536
 
537
        group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
538
 
539
        if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
540
                return -EINVAL;
541
 
542
        idev = ip6_mc_find_dev(group, gsf->gf_interface);
543
 
544
        if (!idev)
545
                return -ENODEV;
546
 
547
        dev = idev->dev;
548
 
549
        err = -EADDRNOTAVAIL;
550
 
551
        for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
552
                if (pmc->ifindex != gsf->gf_interface)
553
                        continue;
554
                if (ipv6_addr_cmp(group, &pmc->addr) == 0)
555
                        break;
556
        }
557
        if (!pmc)               /* must have a prior join */
558
                goto done;
559
        gsf->gf_fmode = pmc->sfmode;
560
        psl = pmc->sflist;
561
        count = psl ? psl->sl_count : 0;
562
        read_unlock_bh(&idev->lock);
563
        in6_dev_put(idev);
564
        dev_put(dev);
565
 
566
        copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
567
        gsf->gf_numsrc = count;
568
        if (put_user(GROUP_FILTER_SIZE(copycount), optlen) ||
569
            copy_to_user((void *)optval, gsf, GROUP_FILTER_SIZE(0))) {
570
                return -EFAULT;
571
        }
572
        for (i=0; i<copycount; i++) {
573
                struct sockaddr_in6 *psin6;
574
                struct sockaddr_storage ss;
575
 
576
                psin6 = (struct sockaddr_in6 *)&ss;
577
                memset(&ss, 0, sizeof(ss));
578
                psin6->sin6_family = AF_INET6;
579
                psin6->sin6_addr = psl->sl_addr[i];
580
                if (copy_to_user((void *)&optval->gf_slist[i], &ss, sizeof(ss)))
581
                        return -EFAULT;
582
        }
583
        return 0;
584
done:
585
        read_unlock_bh(&idev->lock);
586
        in6_dev_put(idev);
587
        dev_put(dev);
588
        return err;
589
}
590
 
591
int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr,
592
        struct in6_addr *src_addr)
593
{
594
        struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
595
        struct ipv6_mc_socklist *mc;
596
        struct ip6_sf_socklist *psl;
597
        int rv = 1;
598
 
599
        read_lock(&ipv6_sk_mc_lock);
600
        for (mc = np->ipv6_mc_list; mc; mc = mc->next) {
601
                if (ipv6_addr_cmp(&mc->addr, mc_addr) == 0)
602
                        break;
603
        }
604
        if (!mc) {
605
                read_unlock(&ipv6_sk_mc_lock);
606
                return 1;
607
        }
608
        psl = mc->sflist;
609
        if (!psl) {
610
                rv = mc->sfmode == MCAST_EXCLUDE;
611
        } else {
612
                int i;
613
 
614
                for (i=0; i<psl->sl_count; i++) {
615
                        if (ipv6_addr_cmp(&psl->sl_addr[i], src_addr) == 0)
616
                                break;
617
                }
618
                if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count)
619
                        rv = 0;
620
                if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
621
                        rv = 0;
622
        }
623
        read_unlock(&ipv6_sk_mc_lock);
624
 
625
        return rv;
626
}
627
 
628
static void ma_put(struct ifmcaddr6 *mc)
629
{
630
        if (atomic_dec_and_test(&mc->mca_refcnt)) {
631
                in6_dev_put(mc->idev);
632
                kfree(mc);
633
        }
634
}
635
 
636
static void igmp6_group_added(struct ifmcaddr6 *mc)
637
{
638
        struct net_device *dev = mc->idev->dev;
639
        char buf[MAX_ADDR_LEN];
640
 
641
        spin_lock_bh(&mc->mca_lock);
642
        if (!(mc->mca_flags&MAF_LOADED)) {
643
                mc->mca_flags |= MAF_LOADED;
644
                if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
645
                        dev_mc_add(dev, buf, dev->addr_len, 0);
646
        }
647
        spin_unlock_bh(&mc->mca_lock);
648
 
649
        if (!(dev->flags & IFF_UP) || (mc->mca_flags & MAF_NOREPORT))
650
                return;
651
 
652
        if (MLD_V1_SEEN(mc->idev)) {
653
                igmp6_join_group(mc);
654
                return;
655
        }
656
        /* else v2 */
657
 
658
        mc->mca_crcount = mc->idev->mc_qrv;
659
        mld_ifc_event(mc->idev);
660
}
661
 
662
static void igmp6_group_dropped(struct ifmcaddr6 *mc)
663
{
664
        struct net_device *dev = mc->idev->dev;
665
        char buf[MAX_ADDR_LEN];
666
 
667
        spin_lock_bh(&mc->mca_lock);
668
        if (mc->mca_flags&MAF_LOADED) {
669
                mc->mca_flags &= ~MAF_LOADED;
670
                if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
671
                        dev_mc_delete(dev, buf, dev->addr_len, 0);
672
        }
673
 
674
        if (mc->mca_flags & MAF_NOREPORT)
675
                goto done;
676
        spin_unlock_bh(&mc->mca_lock);
677
 
678
        if (!mc->idev->dead)
679
                igmp6_leave_group(mc);
680
 
681
        spin_lock_bh(&mc->mca_lock);
682
        if (del_timer(&mc->mca_timer))
683
                atomic_dec(&mc->mca_refcnt);
684
done:
685
        ip6_mc_clear_src(mc);
686
        spin_unlock_bh(&mc->mca_lock);
687
}
688
 
689
/*
690
 * deleted ifmcaddr6 manipulation
691
 */
692
static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
693
{
694
        struct ifmcaddr6 *pmc;
695
 
696
        /* this is an "ifmcaddr6" for convenience; only the fields below
697
         * are actually used. In particular, the refcnt and users are not
698
         * used for management of the delete list. Using the same structure
699
         * for deleted items allows change reports to use common code with
700
         * non-deleted or query-response MCA's.
701
         */
702
        pmc = (struct ifmcaddr6 *)kmalloc(sizeof(*pmc), GFP_ATOMIC);
703
        if (!pmc)
704
                return;
705
        memset(pmc, 0, sizeof(*pmc));
706
        spin_lock_bh(&im->mca_lock);
707
        pmc->mca_lock = SPIN_LOCK_UNLOCKED;
708
        pmc->idev = im->idev;
709
        in6_dev_hold(idev);
710
        pmc->mca_addr = im->mca_addr;
711
        pmc->mca_crcount = idev->mc_qrv;
712
        pmc->mca_sfmode = im->mca_sfmode;
713
        if (pmc->mca_sfmode == MCAST_INCLUDE) {
714
                struct ip6_sf_list *psf;
715
 
716
                pmc->mca_tomb = im->mca_tomb;
717
                pmc->mca_sources = im->mca_sources;
718
                im->mca_tomb = im->mca_sources = 0;
719
                for (psf=pmc->mca_sources; psf; psf=psf->sf_next)
720
                        psf->sf_crcount = pmc->mca_crcount;
721
        }
722
        spin_unlock_bh(&im->mca_lock);
723
 
724
        write_lock_bh(&idev->mc_lock);
725
        pmc->next = idev->mc_tomb;
726
        idev->mc_tomb = pmc;
727
        write_unlock_bh(&idev->mc_lock);
728
}
729
 
730
static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
731
{
732
        struct ifmcaddr6 *pmc, *pmc_prev;
733
        struct ip6_sf_list *psf, *psf_next;
734
 
735
        write_lock_bh(&idev->mc_lock);
736
        pmc_prev = 0;
737
        for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) {
738
                if (ipv6_addr_cmp(&pmc->mca_addr, pmca) == 0)
739
                        break;
740
                pmc_prev = pmc;
741
        }
742
        if (pmc) {
743
                if (pmc_prev)
744
                        pmc_prev->next = pmc->next;
745
                else
746
                        idev->mc_tomb = pmc->next;
747
        }
748
        write_unlock_bh(&idev->mc_lock);
749
        if (pmc) {
750
                for (psf=pmc->mca_tomb; psf; psf=psf_next) {
751
                        psf_next = psf->sf_next;
752
                        kfree(psf);
753
                }
754
                in6_dev_put(pmc->idev);
755
                kfree(pmc);
756
        }
757
}
758
 
759
static void mld_clear_delrec(struct inet6_dev *idev)
760
{
761
        struct ifmcaddr6 *pmc, *nextpmc;
762
 
763
        write_lock_bh(&idev->mc_lock);
764
        pmc = idev->mc_tomb;
765
        idev->mc_tomb = 0;
766
        write_unlock_bh(&idev->mc_lock);
767
 
768
        for (; pmc; pmc = nextpmc) {
769
                nextpmc = pmc->next;
770
                ip6_mc_clear_src(pmc);
771
                in6_dev_put(pmc->idev);
772
                kfree(pmc);
773
        }
774
 
775
        /* clear dead sources, too */
776
        read_lock_bh(&idev->lock);
777
        for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
778
                struct ip6_sf_list *psf, *psf_next;
779
 
780
                spin_lock_bh(&pmc->mca_lock);
781
                psf = pmc->mca_tomb;
782
                pmc->mca_tomb = 0;
783
                spin_unlock_bh(&pmc->mca_lock);
784
                for (; psf; psf=psf_next) {
785
                        psf_next = psf->sf_next;
786
                        kfree(psf);
787
                }
788
        }
789
        read_unlock_bh(&idev->lock);
790
}
791
 
792
 
793
/*
794
 *      device multicast group inc (add if not found)
795
 */
796
int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
797
{
798
        struct ifmcaddr6 *mc;
799
        struct inet6_dev *idev;
800
 
801
        idev = in6_dev_get(dev);
802
 
803
        if (idev == NULL)
804
                return -EINVAL;
805
 
806
        write_lock_bh(&idev->lock);
807
        if (idev->dead) {
808
                write_unlock_bh(&idev->lock);
809
                in6_dev_put(idev);
810
                return -ENODEV;
811
        }
812
 
813
        for (mc = idev->mc_list; mc; mc = mc->next) {
814
                if (ipv6_addr_cmp(&mc->mca_addr, addr) == 0) {
815
                        mc->mca_users++;
816
                        write_unlock_bh(&idev->lock);
817
                        ip6_mc_add_src(idev, &mc->mca_addr, MCAST_EXCLUDE, 0,
818
                                0, 0);
819
                        in6_dev_put(idev);
820
                        return 0;
821
                }
822
        }
823
 
824
        /*
825
         *      not found: create a new one.
826
         */
827
 
828
        mc = kmalloc(sizeof(struct ifmcaddr6), GFP_ATOMIC);
829
 
830
        if (mc == NULL) {
831
                write_unlock_bh(&idev->lock);
832
                in6_dev_put(idev);
833
                return -ENOMEM;
834
        }
835
 
836
        memset(mc, 0, sizeof(struct ifmcaddr6));
837
        mc->mca_timer.function = igmp6_timer_handler;
838
        mc->mca_timer.data = (unsigned long) mc;
839
 
840
        memcpy(&mc->mca_addr, addr, sizeof(struct in6_addr));
841
        mc->idev = idev;
842
        mc->mca_users = 1;
843
        atomic_set(&mc->mca_refcnt, 2);
844
        mc->mca_lock = SPIN_LOCK_UNLOCKED;
845
 
846
        /* initial mode is (EX, empty) */
847
        mc->mca_sfmode = MCAST_EXCLUDE;
848
        mc->mca_sfcount[MCAST_EXCLUDE] = 1;
849
 
850
        if (ipv6_addr_cmp(&mc->mca_addr, &all_nodes_addr) == 0 ||
851
            IPV6_ADDR_MC_SCOPE(&mc->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
852
                mc->mca_flags |= MAF_NOREPORT;
853
 
854
        mc->next = idev->mc_list;
855
        idev->mc_list = mc;
856
        write_unlock_bh(&idev->lock);
857
 
858
        mld_del_delrec(idev, &mc->mca_addr);
859
        igmp6_group_added(mc);
860
        ma_put(mc);
861
        return 0;
862
}
863
 
864
/*
865
 *      device multicast group del
866
 */
867
static int __ipv6_dev_mc_dec(struct net_device *dev, struct inet6_dev *idev, struct in6_addr *addr)
868
{
869
        struct ifmcaddr6 *ma, **map;
870
 
871
        write_lock_bh(&idev->lock);
872
        for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) {
873
                if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0) {
874
                        if (--ma->mca_users == 0) {
875
                                *map = ma->next;
876
                                write_unlock_bh(&idev->lock);
877
 
878
                                igmp6_group_dropped(ma);
879
 
880
                                ma_put(ma);
881
                                return 0;
882
                        }
883
                        write_unlock_bh(&idev->lock);
884
                        return 0;
885
                }
886
        }
887
        write_unlock_bh(&idev->lock);
888
 
889
        return -ENOENT;
890
}
891
 
892
int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr)
893
{
894
        struct inet6_dev *idev = in6_dev_get(dev);
895
        int err;
896
 
897
        if (!idev)
898
                return -ENODEV;
899
 
900
        err = __ipv6_dev_mc_dec(dev, idev, addr);
901
 
902
        in6_dev_put(idev);
903
 
904
        return err;
905
}
906
 
907
/*
908
 *      check if the interface/address pair is valid
909
 */
910
int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
911
        struct in6_addr *src_addr)
912
{
913
        struct inet6_dev *idev;
914
        struct ifmcaddr6 *mc;
915
        int rv = 0;
916
 
917
        idev = in6_dev_get(dev);
918
        if (idev) {
919
                read_lock_bh(&idev->lock);
920
                for (mc = idev->mc_list; mc; mc=mc->next) {
921
                        if (ipv6_addr_cmp(&mc->mca_addr, group) == 0)
922
                                break;
923
                }
924
                if (mc) {
925
                        if (!ipv6_addr_any(src_addr)) {
926
                                struct ip6_sf_list *psf;
927
 
928
                                spin_lock_bh(&mc->mca_lock);
929
                                for (psf=mc->mca_sources;psf;psf=psf->sf_next) {
930
                                        if (ipv6_addr_cmp(&psf->sf_addr,
931
                                            src_addr) == 0)
932
                                                break;
933
                                }
934
                                if (psf)
935
                                        rv = psf->sf_count[MCAST_INCLUDE] ||
936
                                                psf->sf_count[MCAST_EXCLUDE] !=
937
                                                mc->mca_sfcount[MCAST_EXCLUDE];
938
                                else
939
                                        rv = mc->mca_sfcount[MCAST_EXCLUDE] !=0;
940
                                spin_unlock_bh(&mc->mca_lock);
941
                        } else
942
                                rv = 1; /* don't filter unspecified source */
943
                }
944
                read_unlock_bh(&idev->lock);
945
                in6_dev_put(idev);
946
        }
947
        return rv;
948
}
949
 
950
static void mld_gq_start_timer(struct inet6_dev *idev)
951
{
952
        int tv = net_random() % idev->mc_maxdelay;
953
 
954
        idev->mc_gq_running = 1;
955
        if (!mod_timer(&idev->mc_gq_timer, jiffies+tv+2))
956
                in6_dev_hold(idev);
957
}
958
 
959
static void mld_ifc_start_timer(struct inet6_dev *idev, int delay)
960
{
961
        int tv = net_random() % delay;
962
 
963
        if (!mod_timer(&idev->mc_ifc_timer, jiffies+tv+2))
964
                in6_dev_hold(idev);
965
}
966
 
967
/*
968
 *      IGMP handling (alias multicast ICMPv6 messages)
969
 */
970
 
971
static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime)
972
{
973
        unsigned long delay = resptime;
974
 
975
        /* Do not start timer for these addresses */
976
        if (ipv6_addr_is_ll_all_nodes(&ma->mca_addr) ||
977
            IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
978
                return;
979
 
980
        if (del_timer(&ma->mca_timer)) {
981
                atomic_dec(&ma->mca_refcnt);
982
                delay = ma->mca_timer.expires - jiffies;
983
        }
984
 
985
        if (delay >= resptime) {
986
                if (resptime)
987
                        delay = net_random() % resptime;
988
                else
989
                        delay = 1;
990
        }
991
 
992
        ma->mca_timer.expires = jiffies + delay;
993
        if (!mod_timer(&ma->mca_timer, jiffies + delay))
994
                atomic_inc(&ma->mca_refcnt);
995
        ma->mca_flags |= MAF_TIMER_RUNNING;
996
        spin_unlock(&ma->mca_lock);
997
}
998
 
999
static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
1000
        struct in6_addr *srcs)
1001
{
1002
        struct ip6_sf_list *psf;
1003
        int i, scount;
1004
 
1005
        scount = 0;
1006
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
1007
                if (scount == nsrcs)
1008
                        break;
1009
                for (i=0; i<nsrcs; i++)
1010
                        if (ipv6_addr_cmp(&srcs[i], &psf->sf_addr) == 0) {
1011
                                psf->sf_gsresp = 1;
1012
                                scount++;
1013
                                break;
1014
                        }
1015
        }
1016
}
1017
 
1018
int igmp6_event_query(struct sk_buff *skb)
1019
{
1020
        struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw;
1021
        struct ifmcaddr6 *ma;
1022
        struct in6_addr *group;
1023
        unsigned long max_delay;
1024
        struct inet6_dev *idev;
1025
        struct icmp6hdr *hdr;
1026
        int group_type;
1027
        int mark = 0;
1028
        int len;
1029
 
1030
        if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
1031
                return -EINVAL;
1032
 
1033
        len = ntohs(skb->nh.ipv6h->payload_len);
1034
 
1035
        /* Drop queries with not link local source */
1036
        if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
1037
                return -EINVAL;
1038
 
1039
        idev = in6_dev_get(skb->dev);
1040
 
1041
        if (idev == NULL)
1042
                return 0;
1043
 
1044
        hdr = (struct icmp6hdr *) skb->h.raw;
1045
        group = (struct in6_addr *) (hdr + 1);
1046
        group_type = ipv6_addr_type(group);
1047
 
1048
        if (group_type != IPV6_ADDR_ANY &&
1049
            !(group_type&IPV6_ADDR_MULTICAST)) {
1050
                in6_dev_put(idev);
1051
                return -EINVAL;
1052
        }
1053
 
1054
        if (len == 24) {
1055
                int switchback;
1056
                /* MLDv1 router present */
1057
 
1058
                /* Translate milliseconds to jiffies */
1059
                max_delay = (ntohs(hdr->icmp6_maxdelay)*HZ)/1000;
1060
 
1061
                switchback = (idev->mc_qrv + 1) * max_delay;
1062
                idev->mc_v1_seen = jiffies + switchback;
1063
 
1064
                /* cancel the interface change timer */
1065
                idev->mc_ifc_count = 0;
1066
                if (del_timer(&idev->mc_ifc_timer))
1067
                        __in6_dev_put(idev);
1068
                /* clear deleted report items */
1069
                mld_clear_delrec(idev);
1070
        } else if (len >= 28) {
1071
                max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
1072
                if (!max_delay)
1073
                        max_delay = 1;
1074
                idev->mc_maxdelay = max_delay;
1075
                if (mlh2->qrv)
1076
                        idev->mc_qrv = mlh2->qrv;
1077
                if (group_type == IPV6_ADDR_ANY) { /* general query */
1078
                        if (mlh2->nsrcs) {
1079
                                in6_dev_put(idev);
1080
                                return -EINVAL; /* no sources allowed */
1081
                        }
1082
                        mld_gq_start_timer(idev);
1083
                        in6_dev_put(idev);
1084
                        return 0;
1085
                }
1086
                /* mark sources to include, if group & source-specific */
1087
                mark = mlh2->nsrcs != 0;
1088
        } else {
1089
                in6_dev_put(idev);
1090
                return -EINVAL;
1091
        }
1092
 
1093
        read_lock_bh(&idev->lock);
1094
        if (group_type == IPV6_ADDR_ANY) {
1095
                for (ma = idev->mc_list; ma; ma=ma->next) {
1096
                        spin_lock_bh(&ma->mca_lock);
1097
                        igmp6_group_queried(ma, max_delay);
1098
                        spin_unlock_bh(&ma->mca_lock);
1099
                }
1100
        } else {
1101
                for (ma = idev->mc_list; ma; ma=ma->next) {
1102
                        if (group_type != IPV6_ADDR_ANY &&
1103
                            ipv6_addr_cmp(group, &ma->mca_addr) != 0)
1104
                                continue;
1105
                        spin_lock_bh(&ma->mca_lock);
1106
                        if (ma->mca_flags & MAF_TIMER_RUNNING) {
1107
                                /* gsquery <- gsquery && mark */
1108
                                if (!mark)
1109
                                        ma->mca_flags &= ~MAF_GSQUERY;
1110
                        } else {
1111
                                /* gsquery <- mark */
1112
                                if (mark)
1113
                                        ma->mca_flags |= MAF_GSQUERY;
1114
                                else
1115
                                        ma->mca_flags &= ~MAF_GSQUERY;
1116
                        }
1117
                        if (ma->mca_flags & MAF_GSQUERY)
1118
                                mld_marksources(ma, ntohs(mlh2->nsrcs),
1119
                                        mlh2->srcs);
1120
                        igmp6_group_queried(ma, max_delay);
1121
                        spin_unlock_bh(&ma->mca_lock);
1122
                        if (group_type != IPV6_ADDR_ANY)
1123
                                break;
1124
                }
1125
        }
1126
        read_unlock_bh(&idev->lock);
1127
        in6_dev_put(idev);
1128
 
1129
        return 0;
1130
}
1131
 
1132
 
1133
int igmp6_event_report(struct sk_buff *skb)
1134
{
1135
        struct ifmcaddr6 *ma;
1136
        struct in6_addr *addrp;
1137
        struct inet6_dev *idev;
1138
        struct icmp6hdr *hdr;
1139
        int addr_type;
1140
 
1141
        /* Our own report looped back. Ignore it. */
1142
        if (skb->pkt_type == PACKET_LOOPBACK)
1143
                return 0;
1144
 
1145
        if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
1146
                return -EINVAL;
1147
 
1148
        hdr = (struct icmp6hdr*) skb->h.raw;
1149
 
1150
        /* Drop reports with not link local source */
1151
        addr_type = ipv6_addr_type(&skb->nh.ipv6h->saddr);
1152
        if (addr_type != IPV6_ADDR_ANY &&
1153
            !(addr_type&IPV6_ADDR_LINKLOCAL))
1154
                return -EINVAL;
1155
 
1156
        addrp = (struct in6_addr *) (hdr + 1);
1157
 
1158
        idev = in6_dev_get(skb->dev);
1159
        if (idev == NULL)
1160
                return -ENODEV;
1161
 
1162
        /*
1163
         *      Cancel the timer for this group
1164
         */
1165
 
1166
        read_lock_bh(&idev->lock);
1167
        for (ma = idev->mc_list; ma; ma=ma->next) {
1168
                if (ipv6_addr_cmp(&ma->mca_addr, addrp) == 0) {
1169
                        spin_lock(&ma->mca_lock);
1170
                        if (del_timer(&ma->mca_timer))
1171
                                atomic_dec(&ma->mca_refcnt);
1172
                        ma->mca_flags &= ~(MAF_LAST_REPORTER|MAF_TIMER_RUNNING);
1173
                        spin_unlock(&ma->mca_lock);
1174
                        break;
1175
                }
1176
        }
1177
        read_unlock_bh(&idev->lock);
1178
        in6_dev_put(idev);
1179
        return 0;
1180
}
1181
 
1182
static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type,
1183
        int gdeleted, int sdeleted)
1184
{
1185
        switch (type) {
1186
        case MLD2_MODE_IS_INCLUDE:
1187
        case MLD2_MODE_IS_EXCLUDE:
1188
                if (gdeleted || sdeleted)
1189
                        return 0;
1190
                return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp);
1191
        case MLD2_CHANGE_TO_INCLUDE:
1192
                if (gdeleted || sdeleted)
1193
                        return 0;
1194
                return psf->sf_count[MCAST_INCLUDE] != 0;
1195
        case MLD2_CHANGE_TO_EXCLUDE:
1196
                if (gdeleted || sdeleted)
1197
                        return 0;
1198
                if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 ||
1199
                    psf->sf_count[MCAST_INCLUDE])
1200
                        return 0;
1201
                return pmc->mca_sfcount[MCAST_EXCLUDE] ==
1202
                        psf->sf_count[MCAST_EXCLUDE];
1203
        case MLD2_ALLOW_NEW_SOURCES:
1204
                if (gdeleted || !psf->sf_crcount)
1205
                        return 0;
1206
                return (pmc->mca_sfmode == MCAST_INCLUDE) ^ sdeleted;
1207
        case MLD2_BLOCK_OLD_SOURCES:
1208
                if (pmc->mca_sfmode == MCAST_INCLUDE)
1209
                        return gdeleted || (psf->sf_crcount && sdeleted);
1210
                return psf->sf_crcount && !gdeleted && !sdeleted;
1211
        }
1212
        return 0;
1213
}
1214
 
1215
static int
1216
mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted)
1217
{
1218
        struct ip6_sf_list *psf;
1219
        int scount = 0;
1220
 
1221
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
1222
                if (!is_in(pmc, psf, type, gdeleted, sdeleted))
1223
                        continue;
1224
                scount++;
1225
        }
1226
        return scount;
1227
}
1228
 
1229
static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1230
{
1231
        struct sock *sk = igmp6_socket->sk;
1232
        struct sk_buff *skb;
1233
        struct mld2_report *pmr;
1234
        struct in6_addr addr_buf;
1235
        int err;
1236
        u8 ra[8] = { IPPROTO_ICMPV6, 0,
1237
                     IPV6_TLV_ROUTERALERT, 2, 0, 0,
1238
                     IPV6_TLV_PADN, 0 };
1239
 
1240
        skb = sock_alloc_send_skb(sk, size + dev->hard_header_len+15, 1, &err);
1241
 
1242
        if (skb == 0)
1243
                return 0;
1244
 
1245
        skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
1246
        if (dev->hard_header) {
1247
                unsigned char ha[MAX_ADDR_LEN];
1248
 
1249
                ndisc_mc_map(&mld2_all_mcr, ha, dev, 1);
1250
                if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) {
1251
                        kfree_skb(skb);
1252
                        return 0;
1253
                }
1254
        }
1255
 
1256
        if (ipv6_get_lladdr(dev, &addr_buf)) {
1257
                /* <draft-ietf-magma-mld-source-02.txt>:
1258
                 * use unspecified address as the source address
1259
                 * when a valid link-local address is not available.
1260
                 */
1261
                memset(&addr_buf, 0, sizeof(addr_buf));
1262
        }
1263
 
1264
        ip6_nd_hdr(sk, skb, dev, &addr_buf, &mld2_all_mcr, NEXTHDR_HOP, 0);
1265
 
1266
        memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1267
 
1268
        pmr =(struct mld2_report *)skb_put(skb, sizeof(*pmr));
1269
        skb->h.raw = (unsigned char *)pmr;
1270
        pmr->type = ICMPV6_MLD2_REPORT;
1271
        pmr->resv1 = 0;
1272
        pmr->csum = 0;
1273
        pmr->resv2 = 0;
1274
        pmr->ngrec = 0;
1275
        return skb;
1276
}
1277
 
1278
static void mld_sendpack(struct sk_buff *skb)
1279
{
1280
        struct ipv6hdr *pip6 = skb->nh.ipv6h;
1281
        struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
1282
        int payload_len, mldlen, err;
1283
 
1284
        payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
1285
                sizeof(struct ipv6hdr);
1286
        mldlen = skb->tail - skb->h.raw;
1287
        pip6->payload_len = htons(payload_len);
1288
 
1289
        pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
1290
                IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
1291
        err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
1292
                      dev_queue_xmit);
1293
        if (!err)
1294
                ICMP6_INC_STATS(Icmp6OutMsgs);
1295
}
1296
 
1297
static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
1298
{
1299
        return sizeof(struct mld2_grec) + 4*mld_scount(pmc,type,gdel,sdel);
1300
}
1301
 
1302
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1303
        int type, struct mld2_grec **ppgr)
1304
{
1305
        struct net_device *dev = pmc->idev->dev;
1306
        struct mld2_report *pmr;
1307
        struct mld2_grec *pgr;
1308
 
1309
        if (!skb)
1310
                skb = mld_newpack(dev, dev->mtu);
1311
        if (!skb)
1312
                return 0;
1313
        pgr = (struct mld2_grec *)skb_put(skb, sizeof(struct mld2_grec));
1314
        pgr->grec_type = type;
1315
        pgr->grec_auxwords = 0;
1316
        pgr->grec_nsrcs = 0;
1317
        pgr->grec_mca = pmc->mca_addr;  /* structure copy */
1318
        pmr = (struct mld2_report *)skb->h.raw;
1319
        pmr->ngrec = htons(ntohs(pmr->ngrec)+1);
1320
        *ppgr = pgr;
1321
        return skb;
1322
}
1323
 
1324
#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \
1325
        skb_tailroom(skb)) : 0)
1326
 
1327
static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1328
        int type, int gdeleted, int sdeleted)
1329
{
1330
        struct net_device *dev = pmc->idev->dev;
1331
        struct mld2_report *pmr;
1332
        struct mld2_grec *pgr = 0;
1333
        struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list;
1334
        int scount, first, isquery, truncate;
1335
 
1336
        if (pmc->mca_flags & MAF_NOREPORT)
1337
                return skb;
1338
 
1339
        isquery = type == MLD2_MODE_IS_INCLUDE ||
1340
                  type == MLD2_MODE_IS_EXCLUDE;
1341
        truncate = type == MLD2_MODE_IS_EXCLUDE ||
1342
                    type == MLD2_CHANGE_TO_EXCLUDE;
1343
 
1344
        psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources;
1345
 
1346
        if (!*psf_list) {
1347
                if (type == MLD2_ALLOW_NEW_SOURCES ||
1348
                    type == MLD2_BLOCK_OLD_SOURCES)
1349
                        return skb;
1350
                if (pmc->mca_crcount || isquery) {
1351
                        /* make sure we have room for group header and at
1352
                         * least one source.
1353
                         */
1354
                        if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+
1355
                            sizeof(struct in6_addr)) {
1356
                                mld_sendpack(skb);
1357
                                skb = 0; /* add_grhead will get a new one */
1358
                        }
1359
                        skb = add_grhead(skb, pmc, type, &pgr);
1360
                }
1361
                return skb;
1362
        }
1363
        pmr = skb ? (struct mld2_report *)skb->h.raw : 0;
1364
 
1365
        /* EX and TO_EX get a fresh packet, if needed */
1366
        if (truncate) {
1367
                if (pmr && pmr->ngrec &&
1368
                    AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
1369
                        if (skb)
1370
                                mld_sendpack(skb);
1371
                        skb = mld_newpack(dev, dev->mtu);
1372
                }
1373
        }
1374
        first = 1;
1375
        scount = 0;
1376
        psf_prev = 0;
1377
        for (psf=*psf_list; psf; psf=psf_next) {
1378
                struct in6_addr *psrc;
1379
 
1380
                psf_next = psf->sf_next;
1381
 
1382
                if (!is_in(pmc, psf, type, gdeleted, sdeleted)) {
1383
                        psf_prev = psf;
1384
                        continue;
1385
                }
1386
 
1387
                /* clear marks on query responses */
1388
                if (isquery)
1389
                        psf->sf_gsresp = 0;
1390
 
1391
                if (AVAILABLE(skb) < sizeof(*psrc) +
1392
                    first*sizeof(struct mld2_grec)) {
1393
                        if (truncate && !first)
1394
                                break;   /* truncate these */
1395
                        if (pgr)
1396
                                pgr->grec_nsrcs = htons(scount);
1397
                        if (skb)
1398
                                mld_sendpack(skb);
1399
                        skb = mld_newpack(dev, dev->mtu);
1400
                        first = 1;
1401
                        scount = 0;
1402
                }
1403
                if (first) {
1404
                        skb = add_grhead(skb, pmc, type, &pgr);
1405
                        first = 0;
1406
                }
1407
                psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc));
1408
                *psrc = psf->sf_addr;
1409
                scount++;
1410
                if ((type == MLD2_ALLOW_NEW_SOURCES ||
1411
                     type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
1412
                        psf->sf_crcount--;
1413
                        if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
1414
                                if (psf_prev)
1415
                                        psf_prev->sf_next = psf->sf_next;
1416
                                else
1417
                                        *psf_list = psf->sf_next;
1418
                                kfree(psf);
1419
                                continue;
1420
                        }
1421
                }
1422
                psf_prev = psf;
1423
        }
1424
        if (pgr)
1425
                pgr->grec_nsrcs = htons(scount);
1426
 
1427
        if (isquery)
1428
                pmc->mca_flags &= ~MAF_GSQUERY; /* clear query state */
1429
        return skb;
1430
}
1431
 
1432
static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc)
1433
{
1434
        struct sk_buff *skb = 0;
1435
        int type;
1436
 
1437
        if (!pmc) {
1438
                read_lock_bh(&idev->lock);
1439
                for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
1440
                        if (pmc->mca_flags & MAF_NOREPORT)
1441
                                continue;
1442
                        spin_lock_bh(&pmc->mca_lock);
1443
                        if (pmc->mca_sfcount[MCAST_EXCLUDE])
1444
                                type = MLD2_MODE_IS_EXCLUDE;
1445
                        else
1446
                                type = MLD2_MODE_IS_INCLUDE;
1447
                        skb = add_grec(skb, pmc, type, 0, 0);
1448
                        spin_unlock_bh(&pmc->mca_lock);
1449
                }
1450
                read_unlock_bh(&idev->lock);
1451
        } else {
1452
                spin_lock_bh(&pmc->mca_lock);
1453
                if (pmc->mca_sfcount[MCAST_EXCLUDE])
1454
                        type = MLD2_MODE_IS_EXCLUDE;
1455
                else
1456
                        type = MLD2_MODE_IS_INCLUDE;
1457
                skb = add_grec(skb, pmc, type, 0, 0);
1458
                spin_unlock_bh(&pmc->mca_lock);
1459
        }
1460
        if (skb)
1461
                mld_sendpack(skb);
1462
}
1463
 
1464
/*
1465
 * remove zero-count source records from a source filter list
1466
 */
1467
static void mld_clear_zeros(struct ip6_sf_list **ppsf)
1468
{
1469
        struct ip6_sf_list *psf_prev, *psf_next, *psf;
1470
 
1471
        psf_prev = 0;
1472
        for (psf=*ppsf; psf; psf = psf_next) {
1473
                psf_next = psf->sf_next;
1474
                if (psf->sf_crcount == 0) {
1475
                        if (psf_prev)
1476
                                psf_prev->sf_next = psf->sf_next;
1477
                        else
1478
                                *ppsf = psf->sf_next;
1479
                        kfree(psf);
1480
                } else
1481
                        psf_prev = psf;
1482
        }
1483
}
1484
 
1485
static void mld_send_cr(struct inet6_dev *idev)
1486
{
1487
        struct ifmcaddr6 *pmc, *pmc_prev, *pmc_next;
1488
        struct sk_buff *skb = 0;
1489
        int type, dtype;
1490
 
1491
        read_lock_bh(&idev->lock);
1492
        write_lock_bh(&idev->mc_lock);
1493
 
1494
        /* deleted MCA's */
1495
        pmc_prev = 0;
1496
        for (pmc=idev->mc_tomb; pmc; pmc=pmc_next) {
1497
                pmc_next = pmc->next;
1498
                if (pmc->mca_sfmode == MCAST_INCLUDE) {
1499
                        type = MLD2_BLOCK_OLD_SOURCES;
1500
                        dtype = MLD2_BLOCK_OLD_SOURCES;
1501
                        skb = add_grec(skb, pmc, type, 1, 0);
1502
                        skb = add_grec(skb, pmc, dtype, 1, 1);
1503
                }
1504
                if (pmc->mca_crcount) {
1505
                        pmc->mca_crcount--;
1506
                        if (pmc->mca_sfmode == MCAST_EXCLUDE) {
1507
                                type = MLD2_CHANGE_TO_INCLUDE;
1508
                                skb = add_grec(skb, pmc, type, 1, 0);
1509
                        }
1510
                        if (pmc->mca_crcount == 0) {
1511
                                mld_clear_zeros(&pmc->mca_tomb);
1512
                                mld_clear_zeros(&pmc->mca_sources);
1513
                        }
1514
                }
1515
                if (pmc->mca_crcount == 0 && !pmc->mca_tomb &&
1516
                    !pmc->mca_sources) {
1517
                        if (pmc_prev)
1518
                                pmc_prev->next = pmc_next;
1519
                        else
1520
                                idev->mc_tomb = pmc_next;
1521
                        in6_dev_put(pmc->idev);
1522
                        kfree(pmc);
1523
                } else
1524
                        pmc_prev = pmc;
1525
        }
1526
        write_unlock_bh(&idev->mc_lock);
1527
 
1528
        /* change recs */
1529
        for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
1530
                spin_lock_bh(&pmc->mca_lock);
1531
                if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
1532
                        type = MLD2_BLOCK_OLD_SOURCES;
1533
                        dtype = MLD2_ALLOW_NEW_SOURCES;
1534
                } else {
1535
                        type = MLD2_ALLOW_NEW_SOURCES;
1536
                        dtype = MLD2_BLOCK_OLD_SOURCES;
1537
                }
1538
                skb = add_grec(skb, pmc, type, 0, 0);
1539
                skb = add_grec(skb, pmc, dtype, 0, 1);   /* deleted sources */
1540
 
1541
                /* filter mode changes */
1542
                if (pmc->mca_crcount) {
1543
                        pmc->mca_crcount--;
1544
                        if (pmc->mca_sfmode == MCAST_EXCLUDE)
1545
                                type = MLD2_CHANGE_TO_EXCLUDE;
1546
                        else
1547
                                type = MLD2_CHANGE_TO_INCLUDE;
1548
                        skb = add_grec(skb, pmc, type, 0, 0);
1549
                }
1550
                spin_unlock_bh(&pmc->mca_lock);
1551
        }
1552
        read_unlock_bh(&idev->lock);
1553
        if (!skb)
1554
                return;
1555
        (void) mld_sendpack(skb);
1556
}
1557
 
1558
void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1559
{
1560
        struct sock *sk = igmp6_socket->sk;
1561
        struct sk_buff *skb;
1562
        struct icmp6hdr *hdr;
1563
        struct in6_addr *snd_addr;
1564
        struct in6_addr *addrp;
1565
        struct in6_addr addr_buf;
1566
        struct in6_addr all_routers;
1567
        int err, len, payload_len, full_len;
1568
        u8 ra[8] = { IPPROTO_ICMPV6, 0,
1569
                     IPV6_TLV_ROUTERALERT, 2, 0, 0,
1570
                     IPV6_TLV_PADN, 0 };
1571
 
1572
        snd_addr = addr;
1573
        if (type == ICMPV6_MGM_REDUCTION) {
1574
                snd_addr = &all_routers;
1575
                ipv6_addr_all_routers(&all_routers);
1576
        }
1577
 
1578
        len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
1579
        payload_len = len + sizeof(ra);
1580
        full_len = sizeof(struct ipv6hdr) + payload_len;
1581
 
1582
        skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 1, &err);
1583
 
1584
        if (skb == NULL)
1585
                return;
1586
 
1587
        skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
1588
        if (dev->hard_header) {
1589
                unsigned char ha[MAX_ADDR_LEN];
1590
                ndisc_mc_map(snd_addr, ha, dev, 1);
1591
                if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
1592
                        goto out;
1593
        }
1594
 
1595
        if (ipv6_get_lladdr(dev, &addr_buf)) {
1596
                /* <draft-ietf-magma-mld-source-02.txt>:
1597
                 * use unspecified address as the source address
1598
                 * when a valid link-local address is not available.
1599
                 */
1600
                memset(&addr_buf, 0, sizeof(addr_buf));
1601
        }
1602
 
1603
        ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len);
1604
 
1605
        memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1606
 
1607
        hdr = (struct icmp6hdr *) skb_put(skb, sizeof(struct icmp6hdr));
1608
        memset(hdr, 0, sizeof(struct icmp6hdr));
1609
        hdr->icmp6_type = type;
1610
 
1611
        addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr));
1612
        ipv6_addr_copy(addrp, addr);
1613
 
1614
        hdr->icmp6_cksum = csum_ipv6_magic(&addr_buf, snd_addr, len,
1615
                                           IPPROTO_ICMPV6,
1616
                                           csum_partial((__u8 *) hdr, len, 0));
1617
 
1618
        err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
1619
                      dev_queue_xmit);
1620
        if (!err) {
1621
                if (type == ICMPV6_MGM_REDUCTION)
1622
                        ICMP6_INC_STATS(Icmp6OutGroupMembReductions);
1623
                else
1624
                        ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
1625
                ICMP6_INC_STATS(Icmp6OutMsgs);
1626
        }
1627
 
1628
        return;
1629
 
1630
out:
1631
        kfree_skb(skb);
1632
}
1633
 
1634
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
1635
        struct in6_addr *psfsrc)
1636
{
1637
        struct ip6_sf_list *psf, *psf_prev;
1638
        int rv = 0;
1639
 
1640
        psf_prev = 0;
1641
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
1642
                if (ipv6_addr_cmp(&psf->sf_addr, psfsrc) == 0)
1643
                        break;
1644
                psf_prev = psf;
1645
        }
1646
        if (!psf || psf->sf_count[sfmode] == 0) {
1647
                /* source filter not found, or count wrong =>  bug */
1648
                return -ESRCH;
1649
        }
1650
        psf->sf_count[sfmode]--;
1651
        if (!psf->sf_count[MCAST_INCLUDE] && !psf->sf_count[MCAST_EXCLUDE]) {
1652
                struct inet6_dev *idev = pmc->idev;
1653
 
1654
                /* no more filters for this source */
1655
                if (psf_prev)
1656
                        psf_prev->sf_next = psf->sf_next;
1657
                else
1658
                        pmc->mca_sources = psf->sf_next;
1659
                if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) &&
1660
                    !MLD_V1_SEEN(idev)) {
1661
                        psf->sf_crcount = idev->mc_qrv;
1662
                        psf->sf_next = pmc->mca_tomb;
1663
                        pmc->mca_tomb = psf;
1664
                        rv = 1;
1665
                } else
1666
                        kfree(psf);
1667
        }
1668
        return rv;
1669
}
1670
 
1671
int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
1672
        int sfcount, struct in6_addr *psfsrc, int delta)
1673
{
1674
        struct ifmcaddr6 *pmc;
1675
        int     changerec = 0;
1676
        int     i, err;
1677
 
1678
        if (!idev)
1679
                return -ENODEV;
1680
        read_lock_bh(&idev->lock);
1681
        for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
1682
                if (ipv6_addr_cmp(pmca, &pmc->mca_addr) == 0)
1683
                        break;
1684
        }
1685
        if (!pmc) {
1686
                /* MCA not found?? bug */
1687
                read_unlock_bh(&idev->lock);
1688
                return -ESRCH;
1689
        }
1690
        spin_lock_bh(&pmc->mca_lock);
1691
        sf_markstate(pmc);
1692
        if (!delta) {
1693
                if (!pmc->mca_sfcount[sfmode]) {
1694
                        spin_unlock_bh(&pmc->mca_lock);
1695
                        read_unlock_bh(&idev->lock);
1696
                        return -EINVAL;
1697
                }
1698
                pmc->mca_sfcount[sfmode]--;
1699
        }
1700
        err = 0;
1701
        for (i=0; i<sfcount; i++) {
1702
                int rv = ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
1703
 
1704
                changerec |= rv > 0;
1705
                if (!err && rv < 0)
1706
                        err = rv;
1707
        }
1708
        if (pmc->mca_sfmode == MCAST_EXCLUDE &&
1709
            pmc->mca_sfcount[MCAST_EXCLUDE] == 0 &&
1710
            pmc->mca_sfcount[MCAST_INCLUDE]) {
1711
                struct ip6_sf_list *psf;
1712
 
1713
                /* filter mode change */
1714
                pmc->mca_sfmode = MCAST_INCLUDE;
1715
                pmc->mca_crcount = idev->mc_qrv;
1716
                idev->mc_ifc_count = pmc->mca_crcount;
1717
                for (psf=pmc->mca_sources; psf; psf = psf->sf_next)
1718
                        psf->sf_crcount = 0;
1719
                mld_ifc_event(pmc->idev);
1720
        } else if (sf_setstate(pmc) || changerec)
1721
                mld_ifc_event(pmc->idev);
1722
        spin_unlock_bh(&pmc->mca_lock);
1723
        read_unlock_bh(&idev->lock);
1724
        return err;
1725
}
1726
 
1727
/*
1728
 * Add multicast single-source filter to the interface list
1729
 */
1730
static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode,
1731
        struct in6_addr *psfsrc, int delta)
1732
{
1733
        struct ip6_sf_list *psf, *psf_prev;
1734
 
1735
        psf_prev = 0;
1736
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
1737
                if (ipv6_addr_cmp(&psf->sf_addr, psfsrc) == 0)
1738
                        break;
1739
                psf_prev = psf;
1740
        }
1741
        if (!psf) {
1742
                psf = (struct ip6_sf_list *)kmalloc(sizeof(*psf), GFP_ATOMIC);
1743
                if (!psf)
1744
                        return -ENOBUFS;
1745
                memset(psf, 0, sizeof(*psf));
1746
                psf->sf_addr = *psfsrc;
1747
                if (psf_prev) {
1748
                        psf_prev->sf_next = psf;
1749
                } else
1750
                        pmc->mca_sources = psf;
1751
        }
1752
        psf->sf_count[sfmode]++;
1753
        return 0;
1754
}
1755
 
1756
static void sf_markstate(struct ifmcaddr6 *pmc)
1757
{
1758
        struct ip6_sf_list *psf;
1759
        int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
1760
 
1761
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next)
1762
                if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
1763
                        psf->sf_oldin = mca_xcount ==
1764
                                psf->sf_count[MCAST_EXCLUDE] &&
1765
                                !psf->sf_count[MCAST_INCLUDE];
1766
                } else
1767
                        psf->sf_oldin = psf->sf_count[MCAST_INCLUDE] != 0;
1768
}
1769
 
1770
static int sf_setstate(struct ifmcaddr6 *pmc)
1771
{
1772
        struct ip6_sf_list *psf;
1773
        int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
1774
        int qrv = pmc->idev->mc_qrv;
1775
        int new_in, rv;
1776
 
1777
        rv = 0;
1778
        for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
1779
                if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
1780
                        new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
1781
                                !psf->sf_count[MCAST_INCLUDE];
1782
                } else
1783
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
1784
                if (new_in != psf->sf_oldin) {
1785
                        psf->sf_crcount = qrv;
1786
                        rv++;
1787
                }
1788
        }
1789
        return rv;
1790
}
1791
 
1792
/*
1793
 * Add multicast source filter list to the interface list
1794
 */
1795
int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
1796
        int sfcount, struct in6_addr *psfsrc, int delta)
1797
{
1798
        struct ifmcaddr6 *pmc;
1799
        int     isexclude;
1800
        int     i, err;
1801
 
1802
        if (!idev)
1803
                return -ENODEV;
1804
        read_lock_bh(&idev->lock);
1805
        for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
1806
                if (ipv6_addr_cmp(pmca, &pmc->mca_addr) == 0)
1807
                        break;
1808
        }
1809
        if (!pmc) {
1810
                /* MCA not found?? bug */
1811
                read_unlock_bh(&idev->lock);
1812
                return -ESRCH;
1813
        }
1814
        spin_lock_bh(&pmc->mca_lock);
1815
 
1816
        sf_markstate(pmc);
1817
        isexclude = pmc->mca_sfmode == MCAST_EXCLUDE;
1818
        if (!delta)
1819
                pmc->mca_sfcount[sfmode]++;
1820
        err = 0;
1821
        for (i=0; i<sfcount; i++) {
1822
                err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i], delta);
1823
                if (err)
1824
                        break;
1825
        }
1826
        if (err) {
1827
                int j;
1828
 
1829
                pmc->mca_sfcount[sfmode]--;
1830
                for (j=0; j<i; j++)
1831
                        (void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
1832
        } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
1833
                struct inet6_dev *idev = pmc->idev;
1834
                struct ip6_sf_list *psf;
1835
 
1836
                /* filter mode change */
1837
                if (pmc->mca_sfcount[MCAST_EXCLUDE])
1838
                        pmc->mca_sfmode = MCAST_EXCLUDE;
1839
                else if (pmc->mca_sfcount[MCAST_INCLUDE])
1840
                        pmc->mca_sfmode = MCAST_INCLUDE;
1841
                /* else no filters; keep old mode for reports */
1842
 
1843
                pmc->mca_crcount = idev->mc_qrv;
1844
                idev->mc_ifc_count = pmc->mca_crcount;
1845
                for (psf=pmc->mca_sources; psf; psf = psf->sf_next)
1846
                        psf->sf_crcount = 0;
1847
                mld_ifc_event(idev);
1848
        } else if (sf_setstate(pmc))
1849
                mld_ifc_event(idev);
1850
        spin_unlock_bh(&pmc->mca_lock);
1851
        read_unlock_bh(&idev->lock);
1852
        return err;
1853
}
1854
 
1855
static void ip6_mc_clear_src(struct ifmcaddr6 *pmc)
1856
{
1857
        struct ip6_sf_list *psf, *nextpsf;
1858
 
1859
        for (psf=pmc->mca_tomb; psf; psf=nextpsf) {
1860
                nextpsf = psf->sf_next;
1861
                kfree(psf);
1862
        }
1863
        pmc->mca_tomb = 0;
1864
        for (psf=pmc->mca_sources; psf; psf=nextpsf) {
1865
                nextpsf = psf->sf_next;
1866
                kfree(psf);
1867
        }
1868
        pmc->mca_sources = 0;
1869
        pmc->mca_sfmode = MCAST_EXCLUDE;
1870
        pmc->mca_sfcount[MCAST_EXCLUDE] = 0;
1871
        pmc->mca_sfcount[MCAST_EXCLUDE] = 1;
1872
}
1873
 
1874
static void igmp6_join_group(struct ifmcaddr6 *ma)
1875
{
1876
        unsigned long delay;
1877
 
1878
        if (ma->mca_flags & MAF_NOREPORT)
1879
                return;
1880
 
1881
        igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
1882
 
1883
        delay = net_random() % IGMP6_UNSOLICITED_IVAL;
1884
 
1885
        spin_lock_bh(&ma->mca_lock);
1886
        if (del_timer(&ma->mca_timer)) {
1887
                atomic_dec(&ma->mca_refcnt);
1888
                delay = ma->mca_timer.expires - jiffies;
1889
        }
1890
 
1891
        if (!mod_timer(&ma->mca_timer, jiffies + delay))
1892
                atomic_inc(&ma->mca_refcnt);
1893
        ma->mca_flags |= MAF_TIMER_RUNNING | MAF_LAST_REPORTER;
1894
        spin_unlock_bh(&ma->mca_lock);
1895
}
1896
 
1897
int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
1898
        struct inet6_dev *idev)
1899
{
1900
        int err;
1901
 
1902
        if (iml->sflist == 0) {
1903
                /* any-source empty exclude case */
1904
                return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, 0, 0);
1905
        }
1906
        err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode,
1907
                iml->sflist->sl_count, iml->sflist->sl_addr, 0);
1908
        sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max));
1909
        iml->sflist = 0;
1910
        return err;
1911
}
1912
 
1913
static void igmp6_leave_group(struct ifmcaddr6 *ma)
1914
{
1915
        if (MLD_V1_SEEN(ma->idev)) {
1916
                if (ma->mca_flags & MAF_LAST_REPORTER)
1917
                        igmp6_send(&ma->mca_addr, ma->idev->dev,
1918
                                ICMPV6_MGM_REDUCTION);
1919
        } else {
1920
                mld_add_delrec(ma->idev, ma);
1921
                mld_ifc_event(ma->idev);
1922
        }
1923
}
1924
 
1925
static void mld_gq_timer_expire(unsigned long data)
1926
{
1927
        struct inet6_dev *idev = (struct inet6_dev *)data;
1928
 
1929
        idev->mc_gq_running = 0;
1930
        mld_send_report(idev, 0);
1931
        __in6_dev_put(idev);
1932
}
1933
 
1934
static void mld_ifc_timer_expire(unsigned long data)
1935
{
1936
        struct inet6_dev *idev = (struct inet6_dev *)data;
1937
 
1938
        mld_send_cr(idev);
1939
        if (idev->mc_ifc_count) {
1940
                idev->mc_ifc_count--;
1941
                if (idev->mc_ifc_count)
1942
                        mld_ifc_start_timer(idev, idev->mc_maxdelay);
1943
        }
1944
        __in6_dev_put(idev);
1945
}
1946
 
1947
static void mld_ifc_event(struct inet6_dev *idev)
1948
{
1949
        if (MLD_V1_SEEN(idev))
1950
                return;
1951
        idev->mc_ifc_count = idev->mc_qrv;
1952
        mld_ifc_start_timer(idev, 1);
1953
}
1954
 
1955
 
1956
static void igmp6_timer_handler(unsigned long data)
1957
{
1958
        struct ifmcaddr6 *ma = (struct ifmcaddr6 *) data;
1959
 
1960
        if (MLD_V1_SEEN(ma->idev))
1961
                igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
1962
        else
1963
                mld_send_report(ma->idev, ma);
1964
 
1965
        spin_lock(&ma->mca_lock);
1966
        ma->mca_flags |=  MAF_LAST_REPORTER;
1967
        ma->mca_flags &= ~MAF_TIMER_RUNNING;
1968
        spin_unlock(&ma->mca_lock);
1969
        ma_put(ma);
1970
}
1971
 
1972
/* Device going down */
1973
 
1974
void ipv6_mc_down(struct inet6_dev *idev)
1975
{
1976
        struct ifmcaddr6 *i;
1977
 
1978
        /* Withdraw multicast list */
1979
 
1980
        read_lock_bh(&idev->lock);
1981
        idev->mc_ifc_count = 0;
1982
        if (del_timer(&idev->mc_ifc_timer))
1983
                __in6_dev_put(idev);
1984
        idev->mc_gq_running = 0;
1985
        if (del_timer(&idev->mc_gq_timer))
1986
                __in6_dev_put(idev);
1987
 
1988
        for (i = idev->mc_list; i; i=i->next)
1989
                igmp6_group_dropped(i);
1990
        read_unlock_bh(&idev->lock);
1991
 
1992
        mld_clear_delrec(idev);
1993
}
1994
 
1995
 
1996
/* Device going up */
1997
 
1998
void ipv6_mc_up(struct inet6_dev *idev)
1999
{
2000
        struct ifmcaddr6 *i;
2001
 
2002
        /* Install multicast list, except for all-nodes (already installed) */
2003
 
2004
        read_lock_bh(&idev->lock);
2005
        for (i = idev->mc_list; i; i=i->next)
2006
                igmp6_group_added(i);
2007
        read_unlock_bh(&idev->lock);
2008
}
2009
 
2010
/* IPv6 device initialization. */
2011
 
2012
void ipv6_mc_init_dev(struct inet6_dev *idev)
2013
{
2014
        struct in6_addr maddr;
2015
 
2016
        write_lock_bh(&idev->lock);
2017
        idev->mc_lock = RW_LOCK_UNLOCKED;
2018
        idev->mc_gq_running = 0;
2019
        init_timer(&idev->mc_gq_timer);
2020
        idev->mc_gq_timer.data = (unsigned long) idev;
2021
        idev->mc_gq_timer.function = &mld_gq_timer_expire;
2022
        idev->mc_tomb = 0;
2023
        idev->mc_ifc_count = 0;
2024
        init_timer(&idev->mc_ifc_timer);
2025
        idev->mc_ifc_timer.data = (unsigned long) idev;
2026
        idev->mc_ifc_timer.function = &mld_ifc_timer_expire;
2027
        idev->mc_qrv = MLD_QRV_DEFAULT;
2028
        idev->mc_maxdelay = IGMP6_UNSOLICITED_IVAL;
2029
        idev->mc_v1_seen = 0;
2030
        write_unlock_bh(&idev->lock);
2031
 
2032
        /* Add all-nodes address. */
2033
        ipv6_addr_all_nodes(&maddr);
2034
        ipv6_dev_mc_inc(idev->dev, &maddr);
2035
}
2036
 
2037
/*
2038
 *      Device is about to be destroyed: clean up.
2039
 */
2040
 
2041
void ipv6_mc_destroy_dev(struct inet6_dev *idev)
2042
{
2043
        struct ifmcaddr6 *i;
2044
        struct in6_addr maddr;
2045
 
2046
        /* Deactivate timers */
2047
        ipv6_mc_down(idev);
2048
 
2049
        /* Delete all-nodes address. */
2050
        ipv6_addr_all_nodes(&maddr);
2051
 
2052
        /* We cannot call ipv6_dev_mc_dec() directly, our caller in
2053
         * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will
2054
         * fail.
2055
         */
2056
        __ipv6_dev_mc_dec(idev->dev, idev, &maddr);
2057
 
2058
        write_lock_bh(&idev->lock);
2059
        while ((i = idev->mc_list) != NULL) {
2060
                idev->mc_list = i->next;
2061
                write_unlock_bh(&idev->lock);
2062
 
2063
                igmp6_group_dropped(i);
2064
                ma_put(i);
2065
 
2066
                write_lock_bh(&idev->lock);
2067
        }
2068
        write_unlock_bh(&idev->lock);
2069
}
2070
 
2071
#ifdef CONFIG_PROC_FS
2072
static int igmp6_read_proc(char *buffer, char **start, off_t offset,
2073
                           int length, int *eof, void *data)
2074
{
2075
        off_t pos=0, begin=0;
2076
        struct ifmcaddr6 *im;
2077
        int len=0;
2078
        struct net_device *dev;
2079
 
2080
        read_lock(&dev_base_lock);
2081
        for (dev = dev_base; dev; dev = dev->next) {
2082
                struct inet6_dev *idev;
2083
 
2084
                if ((idev = in6_dev_get(dev)) == NULL)
2085
                        continue;
2086
 
2087
                read_lock_bh(&idev->lock);
2088
                for (im = idev->mc_list; im; im = im->next) {
2089
                        int i;
2090
 
2091
                        len += sprintf(buffer+len,"%-4d %-15s ", dev->ifindex, dev->name);
2092
 
2093
                        for (i=0; i<16; i++)
2094
                                len += sprintf(buffer+len, "%02x", im->mca_addr.s6_addr[i]);
2095
 
2096
                        len+=sprintf(buffer+len,
2097
                                     " %5d %08X %ld\n",
2098
                                     im->mca_users,
2099
                                     im->mca_flags,
2100
                                     (im->mca_flags&MAF_TIMER_RUNNING) ? im->mca_timer.expires-jiffies : 0);
2101
 
2102
                        pos=begin+len;
2103
                        if (pos < offset) {
2104
                                len=0;
2105
                                begin=pos;
2106
                        }
2107
                        if (pos > offset+length) {
2108
                                read_unlock_bh(&idev->lock);
2109
                                in6_dev_put(idev);
2110
                                goto done;
2111
                        }
2112
                }
2113
                read_unlock_bh(&idev->lock);
2114
                in6_dev_put(idev);
2115
        }
2116
        *eof = 1;
2117
 
2118
done:
2119
        read_unlock(&dev_base_lock);
2120
 
2121
        *start=buffer+(offset-begin);
2122
        len-=(offset-begin);
2123
        if(len>length)
2124
                len=length;
2125
        if (len<0)
2126
                len=0;
2127
        return len;
2128
}
2129
 
2130
static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
2131
                           int length, int *eof, void *data)
2132
{
2133
        off_t pos=0, begin=0;
2134
        int len=0;
2135
        int first=1;
2136
        struct net_device *dev;
2137
 
2138
        read_lock(&dev_base_lock);
2139
        for (dev=dev_base; dev; dev=dev->next) {
2140
                struct inet6_dev *idev = in6_dev_get(dev);
2141
                struct ifmcaddr6 *imc;
2142
 
2143
                if (idev == NULL)
2144
                        continue;
2145
 
2146
                read_lock_bh(&idev->lock);
2147
 
2148
                for (imc=idev->mc_list; imc; imc=imc->next) {
2149
                        struct ip6_sf_list *psf;
2150
                        unsigned long i;
2151
 
2152
                        spin_lock_bh(&imc->mca_lock);
2153
                        for (psf=imc->mca_sources; psf; psf=psf->sf_next) {
2154
                                if (first) {
2155
                                        len += sprintf(buffer+len, "%3s %6s "
2156
                                                "%32s %32s %6s %6s\n", "Idx",
2157
                                                "Device", "Multicast Address",
2158
                                                "Source Address", "INC", "EXC");
2159
                                        first = 0;
2160
                                }
2161
                                len += sprintf(buffer+len,"%3d %6.6s ",
2162
                                        dev->ifindex, dev->name);
2163
 
2164
                                for (i=0; i<16; i++)
2165
                                        len += sprintf(buffer+len, "%02x",
2166
                                                imc->mca_addr.s6_addr[i]);
2167
                                buffer[len++] = ' ';
2168
                                for (i=0; i<16; i++)
2169
                                        len += sprintf(buffer+len, "%02x",
2170
                                                psf->sf_addr.s6_addr[i]);
2171
                                len += sprintf(buffer+len, " %6lu %6lu\n",
2172
                                        psf->sf_count[MCAST_INCLUDE],
2173
                                        psf->sf_count[MCAST_EXCLUDE]);
2174
                                pos = begin+len;
2175
                                if (pos < offset) {
2176
                                        len=0;
2177
                                        begin=pos;
2178
                                }
2179
                                if (pos > offset+length) {
2180
                                        spin_unlock_bh(&imc->mca_lock);
2181
                                        read_unlock_bh(&idev->lock);
2182
                                        in6_dev_put(idev);
2183
                                        goto done;
2184
                                }
2185
                        }
2186
                        spin_unlock_bh(&imc->mca_lock);
2187
                }
2188
                read_unlock_bh(&idev->lock);
2189
                in6_dev_put(idev);
2190
        }
2191
        *eof = 1;
2192
 
2193
done:
2194
        read_unlock(&dev_base_lock);
2195
 
2196
        *start=buffer+(offset-begin);
2197
        len-=(offset-begin);
2198
        if(len>length)
2199
                len=length;
2200
        if (len<0)
2201
                len=0;
2202
        return len;
2203
}
2204
#endif
2205
 
2206
int __init igmp6_init(struct net_proto_family *ops)
2207
{
2208
        struct sock *sk;
2209
        int err;
2210
 
2211
        igmp6_socket = sock_alloc();
2212
        if (igmp6_socket == NULL) {
2213
                printk(KERN_ERR
2214
                       "Failed to create the IGMP6 control socket.\n");
2215
                return -1;
2216
        }
2217
        igmp6_socket->inode->i_uid = 0;
2218
        igmp6_socket->inode->i_gid = 0;
2219
        igmp6_socket->type = SOCK_RAW;
2220
 
2221
        if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) {
2222
                printk(KERN_DEBUG
2223
                       "Failed to initialize the IGMP6 control socket (err %d).\n",
2224
                       err);
2225
                sock_release(igmp6_socket);
2226
                igmp6_socket = NULL; /* For safety. */
2227
                return err;
2228
        }
2229
 
2230
        sk = igmp6_socket->sk;
2231
        sk->allocation = GFP_ATOMIC;
2232
        sk->prot->unhash(sk);
2233
 
2234
        sk->net_pinfo.af_inet6.hop_limit = 1;
2235
#ifdef CONFIG_PROC_FS
2236
        create_proc_read_entry("net/igmp6", 0, 0, igmp6_read_proc, NULL);
2237
        create_proc_read_entry("net/mcfilter6", 0, 0, ip6_mcf_read_proc, NULL);
2238
#endif
2239
 
2240
        return 0;
2241
}
2242
 
2243
void igmp6_cleanup(void)
2244
{
2245
        sock_release(igmp6_socket);
2246
        igmp6_socket = NULL; /* for safety */
2247
#ifdef CONFIG_PROC_FS
2248
        remove_proc_entry("net/igmp6", 0);
2249
#endif
2250
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.