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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Linux NET3:     Internet Group Management Protocol  [IGMP]
3
 *
4
 *      This code implements the IGMP protocol as defined in RFC1112. There has
5
 *      been a further revision of this protocol since which is now supported.
6
 *
7
 *      If you have trouble with this module be careful what gcc you have used,
8
 *      the older version didn't come out right using gcc 2.5.8, the newer one
9
 *      seems to fall out with gcc 2.6.2.
10
 *
11
 *      Version: $Id: igmp.c,v 1.1.1.1 2004-04-15 01:13:48 phoenix Exp $
12
 *
13
 *      Authors:
14
 *              Alan Cox <Alan.Cox@linux.org>
15
 *
16
 *      This program is free software; you can redistribute it and/or
17
 *      modify it under the terms of the GNU General Public License
18
 *      as published by the Free Software Foundation; either version
19
 *      2 of the License, or (at your option) any later version.
20
 *
21
 *      Fixes:
22
 *
23
 *              Alan Cox        :       Added lots of __inline__ to optimise
24
 *                                      the memory usage of all the tiny little
25
 *                                      functions.
26
 *              Alan Cox        :       Dumped the header building experiment.
27
 *              Alan Cox        :       Minor tweaks ready for multicast routing
28
 *                                      and extended IGMP protocol.
29
 *              Alan Cox        :       Removed a load of inline directives. Gcc 2.5.8
30
 *                                      writes utterly bogus code otherwise (sigh)
31
 *                                      fixed IGMP loopback to behave in the manner
32
 *                                      desired by mrouted, fixed the fact it has been
33
 *                                      broken since 1.3.6 and cleaned up a few minor
34
 *                                      points.
35
 *
36
 *              Chih-Jen Chang  :       Tried to revise IGMP to Version 2
37
 *              Tsu-Sheng Tsao          E-mail: chihjenc@scf.usc.edu and tsusheng@scf.usc.edu
38
 *                                      The enhancements are mainly based on Steve Deering's
39
 *                                      ipmulti-3.5 source code.
40
 *              Chih-Jen Chang  :       Added the igmp_get_mrouter_info and
41
 *              Tsu-Sheng Tsao          igmp_set_mrouter_info to keep track of
42
 *                                      the mrouted version on that device.
43
 *              Chih-Jen Chang  :       Added the max_resp_time parameter to
44
 *              Tsu-Sheng Tsao          igmp_heard_query(). Using this parameter
45
 *                                      to identify the multicast router version
46
 *                                      and do what the IGMP version 2 specified.
47
 *              Chih-Jen Chang  :       Added a timer to revert to IGMP V2 router
48
 *              Tsu-Sheng Tsao          if the specified time expired.
49
 *              Alan Cox        :       Stop IGMP from 0.0.0.0 being accepted.
50
 *              Alan Cox        :       Use GFP_ATOMIC in the right places.
51
 *              Christian Daudt :       igmp timer wasn't set for local group
52
 *                                      memberships but was being deleted,
53
 *                                      which caused a "del_timer() called
54
 *                                      from %p with timer not initialized\n"
55
 *                                      message (960131).
56
 *              Christian Daudt :       removed del_timer from
57
 *                                      igmp_timer_expire function (960205).
58
 *             Christian Daudt :       igmp_heard_report now only calls
59
 *                                     igmp_timer_expire if tm->running is
60
 *                                     true (960216).
61
 *              Malcolm Beattie :       ttl comparison wrong in igmp_rcv made
62
 *                                      igmp_heard_query never trigger. Expiry
63
 *                                      miscalculation fixed in igmp_heard_query
64
 *                                      and random() made to return unsigned to
65
 *                                      prevent negative expiry times.
66
 *              Alexey Kuznetsov:       Wrong group leaving behaviour, backport
67
 *                                      fix from pending 2.1.x patches.
68
 *              Alan Cox:               Forget to enable FDDI support earlier.
69
 *              Alexey Kuznetsov:       Fixed leaving groups on device down.
70
 *              Alexey Kuznetsov:       Accordance to igmp-v2-06 draft.
71
 *              David L Stevens:        IGMPv3 support, with help from
72
 *                                      Vinay Kulkarni
73
 */
74
 
75
 
76
#include <linux/config.h>
77
#include <asm/uaccess.h>
78
#include <asm/system.h>
79
#include <linux/types.h>
80
#include <linux/kernel.h>
81
#include <linux/sched.h>
82
#include <linux/string.h>
83
#include <linux/socket.h>
84
#include <linux/sockios.h>
85
#include <linux/in.h>
86
#include <linux/inet.h>
87
#include <linux/netdevice.h>
88
#include <linux/skbuff.h>
89
#include <linux/inetdevice.h>
90
#include <linux/igmp.h>
91
#include <linux/if_arp.h>
92
#include <linux/rtnetlink.h>
93
#include <net/ip.h>
94
#include <net/protocol.h>
95
#include <net/route.h>
96
#include <net/sock.h>
97
#include <net/checksum.h>
98
#include <linux/netfilter_ipv4.h>
99
#ifdef CONFIG_IP_MROUTE
100
#include <linux/mroute.h>
101
#endif
102
 
103
 
104
#define IP_MAX_MEMBERSHIPS      20
105
#define IP_MAX_MSF              10
106
 
107
#ifdef CONFIG_IP_MULTICAST
108
/* Parameter names and values are taken from igmp-v2-06 draft */
109
 
110
#define IGMP_V1_Router_Present_Timeout          (400*HZ)
111
#define IGMP_V2_Router_Present_Timeout          (400*HZ)
112
#define IGMP_Unsolicited_Report_Interval        (10*HZ)
113
#define IGMP_Query_Response_Interval            (10*HZ)
114
#define IGMP_Unsolicited_Report_Count           2
115
 
116
 
117
#define IGMP_Initial_Report_Delay               (1)
118
 
119
/* IGMP_Initial_Report_Delay is not from IGMP specs!
120
 * IGMP specs require to report membership immediately after
121
 * joining a group, but we delay the first report by a
122
 * small interval. It seems more natural and still does not
123
 * contradict to specs provided this delay is small enough.
124
 */
125
 
126
#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \
127
                (in_dev)->cnf.force_igmp_version == 1 || \
128
                ((in_dev)->mr_v1_seen && \
129
                time_before(jiffies, (in_dev)->mr_v1_seen)))
130
#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \
131
                (in_dev)->cnf.force_igmp_version == 2 || \
132
                ((in_dev)->mr_v2_seen && \
133
                time_before(jiffies, (in_dev)->mr_v2_seen)))
134
 
135
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
136
static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr);
137
static void igmpv3_clear_delrec(struct in_device *in_dev);
138
static int sf_setstate(struct ip_mc_list *pmc);
139
static void sf_markstate(struct ip_mc_list *pmc);
140
#endif
141
static void ip_mc_clear_src(struct ip_mc_list *pmc);
142
int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
143
        int sfcount, __u32 *psfsrc, int delta);
144
 
145
static void ip_ma_put(struct ip_mc_list *im)
146
{
147
        if (atomic_dec_and_test(&im->refcnt)) {
148
                in_dev_put(im->interface);
149
                kfree(im);
150
        }
151
}
152
 
153
#ifdef CONFIG_IP_MULTICAST
154
 
155
/*
156
 *      Timer management
157
 */
158
 
159
static __inline__ void igmp_stop_timer(struct ip_mc_list *im)
160
{
161
        spin_lock_bh(&im->lock);
162
        if (del_timer(&im->timer))
163
                atomic_dec(&im->refcnt);
164
        im->tm_running=0;
165
        im->reporter = 0;
166
        im->unsolicit_count = 0;
167
        spin_unlock_bh(&im->lock);
168
}
169
 
170
/* It must be called with locked im->lock */
171
static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
172
{
173
        int tv=net_random() % max_delay;
174
 
175
        im->tm_running=1;
176
        if (!mod_timer(&im->timer, jiffies+tv+2))
177
                atomic_inc(&im->refcnt);
178
}
179
 
180
static void igmp_gq_start_timer(struct in_device *in_dev)
181
{
182
        int tv = net_random() % in_dev->mr_maxdelay;
183
 
184
        in_dev->mr_gq_running = 1;
185
        if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
186
                in_dev_hold(in_dev);
187
}
188
 
189
static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
190
{
191
        int tv = net_random() % delay;
192
 
193
        if (!mod_timer(&in_dev->mr_ifc_timer, jiffies+tv+2))
194
                in_dev_hold(in_dev);
195
}
196
 
197
static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
198
{
199
        spin_lock_bh(&im->lock);
200
        im->unsolicit_count = 0;
201
        if (del_timer(&im->timer)) {
202
                if ((long)(im->timer.expires-jiffies) < max_delay) {
203
                        add_timer(&im->timer);
204
                        im->tm_running=1;
205
                        spin_unlock_bh(&im->lock);
206
                        return;
207
                }
208
                atomic_dec(&im->refcnt);
209
        }
210
        igmp_start_timer(im, max_delay);
211
        spin_unlock_bh(&im->lock);
212
}
213
 
214
 
215
/*
216
 *      Send an IGMP report.
217
 */
218
 
219
#define IGMP_SIZE (sizeof(struct igmphdr)+sizeof(struct iphdr)+4)
220
 
221
/* Don't just hand NF_HOOK skb->dst->output, in case netfilter hook
222
   changes route */
223
static inline int
224
output_maybe_reroute(struct sk_buff *skb)
225
{
226
        return skb->dst->output(skb);
227
}
228
 
229
 
230
static int is_in(struct ip_mc_list *pmc, struct ip_sf_list *psf, int type,
231
        int gdeleted, int sdeleted)
232
{
233
        switch (type) {
234
        case IGMPV3_MODE_IS_INCLUDE:
235
        case IGMPV3_MODE_IS_EXCLUDE:
236
                if (gdeleted || sdeleted)
237
                        return 0;
238
                return !(pmc->gsquery && !psf->sf_gsresp);
239
        case IGMPV3_CHANGE_TO_INCLUDE:
240
                if (gdeleted || sdeleted)
241
                        return 0;
242
                return psf->sf_count[MCAST_INCLUDE] != 0;
243
        case IGMPV3_CHANGE_TO_EXCLUDE:
244
                if (gdeleted || sdeleted)
245
                        return 0;
246
                if (pmc->sfcount[MCAST_EXCLUDE] == 0 ||
247
                    psf->sf_count[MCAST_INCLUDE])
248
                        return 0;
249
                return pmc->sfcount[MCAST_EXCLUDE] ==
250
                        psf->sf_count[MCAST_EXCLUDE];
251
        case IGMPV3_ALLOW_NEW_SOURCES:
252
                if (gdeleted || !psf->sf_crcount)
253
                        return 0;
254
                return (pmc->sfmode == MCAST_INCLUDE) ^ sdeleted;
255
        case IGMPV3_BLOCK_OLD_SOURCES:
256
                if (pmc->sfmode == MCAST_INCLUDE)
257
                        return gdeleted || (psf->sf_crcount && sdeleted);
258
                return psf->sf_crcount && !gdeleted && !sdeleted;
259
        }
260
        return 0;
261
}
262
 
263
static int
264
igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
265
{
266
        struct ip_sf_list *psf;
267
        int scount = 0;
268
 
269
        for (psf=pmc->sources; psf; psf=psf->sf_next) {
270
                if (!is_in(pmc, psf, type, gdeleted, sdeleted))
271
                        continue;
272
                scount++;
273
        }
274
        return scount;
275
}
276
 
277
static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
278
{
279
        struct sk_buff *skb;
280
        struct rtable *rt;
281
        struct iphdr *pip;
282
        struct igmpv3_report *pig;
283
        u32     dst;
284
 
285
        dst = IGMPV3_ALL_MCR;
286
        if (ip_route_output(&rt, dst, 0, 0, dev->ifindex))
287
                return 0;
288
        if (rt->rt_src == 0) {
289
                ip_rt_put(rt);
290
                return 0;
291
        }
292
        skb = alloc_skb(size + dev->hard_header_len + 15, GFP_ATOMIC);
293
        if (skb == NULL) {
294
                ip_rt_put(rt);
295
                return 0;
296
        }
297
 
298
        skb->dst = &rt->u.dst;
299
        skb->dev = dev;
300
 
301
        skb_reserve(skb, (dev->hard_header_len+15)&~15);
302
 
303
        skb->nh.iph = pip =(struct iphdr *)skb_put(skb, sizeof(struct iphdr)+4);
304
 
305
        pip->version  = 4;
306
        pip->ihl      = (sizeof(struct iphdr)+4)>>2;
307
        pip->tos      = 0xc0;
308
        pip->frag_off = htons(IP_DF);
309
        pip->ttl      = 1;
310
        pip->daddr    = rt->rt_dst;
311
        pip->saddr    = rt->rt_src;
312
        pip->protocol = IPPROTO_IGMP;
313
        pip->tot_len  = 0;       /* filled in later */
314
        ip_select_ident(pip, &rt->u.dst, NULL);
315
        ((u8*)&pip[1])[0] = IPOPT_RA;
316
        ((u8*)&pip[1])[1] = 4;
317
        ((u8*)&pip[1])[2] = 0;
318
        ((u8*)&pip[1])[3] = 0;
319
 
320
        pig =(struct igmpv3_report *)skb_put(skb, sizeof(*pig));
321
        skb->h.igmph = (struct igmphdr *)pig;
322
        pig->type = IGMPV3_HOST_MEMBERSHIP_REPORT;
323
        pig->resv1 = 0;
324
        pig->csum = 0;
325
        pig->resv2 = 0;
326
        pig->ngrec = 0;
327
        return skb;
328
}
329
 
330
static int igmpv3_sendpack(struct sk_buff *skb)
331
{
332
        struct iphdr *pip = skb->nh.iph;
333
        struct igmphdr *pig = skb->h.igmph;
334
        int iplen, igmplen;
335
 
336
        iplen = skb->tail - (unsigned char *)skb->nh.iph;
337
        pip->tot_len = htons(iplen);
338
        ip_send_check(pip);
339
 
340
        igmplen = skb->tail - (unsigned char *)skb->h.igmph;
341
        pig->csum = ip_compute_csum((void *)skb->h.igmph, igmplen);
342
 
343
        return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
344
                       output_maybe_reroute);
345
}
346
 
347
static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
348
{
349
        return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc,type,gdel,sdel);
350
}
351
 
352
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
353
        int type, struct igmpv3_grec **ppgr)
354
{
355
        struct net_device *dev = pmc->interface->dev;
356
        struct igmpv3_report *pih;
357
        struct igmpv3_grec *pgr;
358
 
359
        if (!skb)
360
                skb = igmpv3_newpack(dev, dev->mtu);
361
        if (!skb)
362
                return 0;
363
        pgr = (struct igmpv3_grec *)skb_put(skb, sizeof(struct igmpv3_grec));
364
        pgr->grec_type = type;
365
        pgr->grec_auxwords = 0;
366
        pgr->grec_nsrcs = 0;
367
        pgr->grec_mca = pmc->multiaddr;
368
        pih = (struct igmpv3_report *)skb->h.igmph;
369
        pih->ngrec = htons(ntohs(pih->ngrec)+1);
370
        *ppgr = pgr;
371
        return skb;
372
}
373
 
374
#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \
375
        skb_tailroom(skb)) : 0)
376
 
377
static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
378
        int type, int gdeleted, int sdeleted)
379
{
380
        struct net_device *dev = pmc->interface->dev;
381
        struct igmpv3_report *pih;
382
        struct igmpv3_grec *pgr = 0;
383
        struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
384
        int scount, first, isquery, truncate;
385
 
386
        if (pmc->multiaddr == IGMP_ALL_HOSTS)
387
                return skb;
388
 
389
        isquery = type == IGMPV3_MODE_IS_INCLUDE ||
390
                  type == IGMPV3_MODE_IS_EXCLUDE;
391
        truncate = type == IGMPV3_MODE_IS_EXCLUDE ||
392
                    type == IGMPV3_CHANGE_TO_EXCLUDE;
393
 
394
        psf_list = sdeleted ? &pmc->tomb : &pmc->sources;
395
 
396
        if (!*psf_list) {
397
                if (type == IGMPV3_ALLOW_NEW_SOURCES ||
398
                    type == IGMPV3_BLOCK_OLD_SOURCES)
399
                        return skb;
400
                if (pmc->crcount || isquery) {
401
                        /* make sure we have room for group header and at
402
                         * least one source.
403
                         */
404
                        if (skb && AVAILABLE(skb) < sizeof(struct igmpv3_grec)+
405
                            sizeof(__u32)) {
406
                                igmpv3_sendpack(skb);
407
                                skb = 0; /* add_grhead will get a new one */
408
                        }
409
                        skb = add_grhead(skb, pmc, type, &pgr);
410
                }
411
                return skb;
412
        }
413
        pih = skb ? (struct igmpv3_report *)skb->h.igmph : 0;
414
 
415
        /* EX and TO_EX get a fresh packet, if needed */
416
        if (truncate) {
417
                if (pih && pih->ngrec &&
418
                    AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
419
                        if (skb)
420
                                igmpv3_sendpack(skb);
421
                        skb = igmpv3_newpack(dev, dev->mtu);
422
                }
423
        }
424
        first = 1;
425
        scount = 0;
426
        psf_prev = 0;
427
        for (psf=*psf_list; psf; psf=psf_next) {
428
                u32 *psrc;
429
 
430
                psf_next = psf->sf_next;
431
 
432
                if (!is_in(pmc, psf, type, gdeleted, sdeleted)) {
433
                        psf_prev = psf;
434
                        continue;
435
                }
436
 
437
                /* clear marks on query responses */
438
                if (isquery)
439
                        psf->sf_gsresp = 0;
440
 
441
                if (AVAILABLE(skb) < sizeof(u32) +
442
                    first*sizeof(struct igmpv3_grec)) {
443
                        if (truncate && !first)
444
                                break;   /* truncate these */
445
                        if (pgr)
446
                                pgr->grec_nsrcs = htons(scount);
447
                        if (skb)
448
                                igmpv3_sendpack(skb);
449
                        skb = igmpv3_newpack(dev, dev->mtu);
450
                        first = 1;
451
                        scount = 0;
452
                }
453
                if (first) {
454
                        skb = add_grhead(skb, pmc, type, &pgr);
455
                        first = 0;
456
                }
457
                psrc = (u32 *)skb_put(skb, sizeof(u32));
458
                *psrc = psf->sf_inaddr;
459
                scount++;
460
                if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
461
                     type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
462
                        psf->sf_crcount--;
463
                        if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
464
                                if (psf_prev)
465
                                        psf_prev->sf_next = psf->sf_next;
466
                                else
467
                                        *psf_list = psf->sf_next;
468
                                kfree(psf);
469
                                continue;
470
                        }
471
                }
472
                psf_prev = psf;
473
        }
474
        if (pgr)
475
                pgr->grec_nsrcs = htons(scount);
476
 
477
        if (isquery)
478
                pmc->gsquery = 0;        /* clear query state on report */
479
        return skb;
480
}
481
 
482
static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
483
{
484
        struct sk_buff *skb = 0;
485
        int type;
486
 
487
        if (!pmc) {
488
                read_lock(&in_dev->lock);
489
                for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
490
                        if (pmc->multiaddr == IGMP_ALL_HOSTS)
491
                                continue;
492
                        spin_lock_bh(&pmc->lock);
493
                        if (pmc->sfcount[MCAST_EXCLUDE])
494
                                type = IGMPV3_MODE_IS_EXCLUDE;
495
                        else
496
                                type = IGMPV3_MODE_IS_INCLUDE;
497
                        skb = add_grec(skb, pmc, type, 0, 0);
498
                        spin_unlock_bh(&pmc->lock);
499
                }
500
                read_unlock(&in_dev->lock);
501
        } else {
502
                spin_lock_bh(&pmc->lock);
503
                if (pmc->sfcount[MCAST_EXCLUDE])
504
                        type = IGMPV3_MODE_IS_EXCLUDE;
505
                else
506
                        type = IGMPV3_MODE_IS_INCLUDE;
507
                skb = add_grec(skb, pmc, type, 0, 0);
508
                spin_unlock_bh(&pmc->lock);
509
        }
510
        if (!skb)
511
                return 0;
512
        return igmpv3_sendpack(skb);
513
}
514
 
515
/*
516
 * remove zero-count source records from a source filter list
517
 */
518
static void igmpv3_clear_zeros(struct ip_sf_list **ppsf)
519
{
520
        struct ip_sf_list *psf_prev, *psf_next, *psf;
521
 
522
        psf_prev = 0;
523
        for (psf=*ppsf; psf; psf = psf_next) {
524
                psf_next = psf->sf_next;
525
                if (psf->sf_crcount == 0) {
526
                        if (psf_prev)
527
                                psf_prev->sf_next = psf->sf_next;
528
                        else
529
                                *ppsf = psf->sf_next;
530
                        kfree(psf);
531
                } else
532
                        psf_prev = psf;
533
        }
534
}
535
 
536
static void igmpv3_send_cr(struct in_device *in_dev)
537
{
538
        struct ip_mc_list *pmc, *pmc_prev, *pmc_next;
539
        struct sk_buff *skb = 0;
540
        int type, dtype;
541
 
542
        read_lock(&in_dev->lock);
543
        write_lock_bh(&in_dev->mc_lock);
544
 
545
        /* deleted MCA's */
546
        pmc_prev = 0;
547
        for (pmc=in_dev->mc_tomb; pmc; pmc=pmc_next) {
548
                pmc_next = pmc->next;
549
                if (pmc->sfmode == MCAST_INCLUDE) {
550
                        type = IGMPV3_BLOCK_OLD_SOURCES;
551
                        dtype = IGMPV3_BLOCK_OLD_SOURCES;
552
                        skb = add_grec(skb, pmc, type, 1, 0);
553
                        skb = add_grec(skb, pmc, dtype, 1, 1);
554
                }
555
                if (pmc->crcount) {
556
                        pmc->crcount--;
557
                        if (pmc->sfmode == MCAST_EXCLUDE) {
558
                                type = IGMPV3_CHANGE_TO_INCLUDE;
559
                                skb = add_grec(skb, pmc, type, 1, 0);
560
                        }
561
                        if (pmc->crcount == 0) {
562
                                igmpv3_clear_zeros(&pmc->tomb);
563
                                igmpv3_clear_zeros(&pmc->sources);
564
                        }
565
                }
566
                if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) {
567
                        if (pmc_prev)
568
                                pmc_prev->next = pmc_next;
569
                        else
570
                                in_dev->mc_tomb = pmc_next;
571
                        in_dev_put(pmc->interface);
572
                        kfree(pmc);
573
                } else
574
                        pmc_prev = pmc;
575
        }
576
        write_unlock_bh(&in_dev->mc_lock);
577
 
578
        /* change recs */
579
        for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
580
                spin_lock_bh(&pmc->lock);
581
                if (pmc->sfcount[MCAST_EXCLUDE]) {
582
                        type = IGMPV3_BLOCK_OLD_SOURCES;
583
                        dtype = IGMPV3_ALLOW_NEW_SOURCES;
584
                } else {
585
                        type = IGMPV3_ALLOW_NEW_SOURCES;
586
                        dtype = IGMPV3_BLOCK_OLD_SOURCES;
587
                }
588
                skb = add_grec(skb, pmc, type, 0, 0);
589
                skb = add_grec(skb, pmc, dtype, 0, 1);   /* deleted sources */
590
 
591
                /* filter mode changes */
592
                if (pmc->crcount) {
593
                        pmc->crcount--;
594
                        if (pmc->sfmode == MCAST_EXCLUDE)
595
                                type = IGMPV3_CHANGE_TO_EXCLUDE;
596
                        else
597
                                type = IGMPV3_CHANGE_TO_INCLUDE;
598
                        skb = add_grec(skb, pmc, type, 0, 0);
599
                }
600
                spin_unlock_bh(&pmc->lock);
601
        }
602
        read_unlock(&in_dev->lock);
603
        if (!skb)
604
                return;
605
        (void) igmpv3_sendpack(skb);
606
}
607
 
608
static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
609
        int type)
610
{
611
        struct sk_buff *skb;
612
        struct iphdr *iph;
613
        struct igmphdr *ih;
614
        struct rtable *rt;
615
        struct net_device *dev = in_dev->dev;
616
        u32     group = pmc ? pmc->multiaddr : 0;
617
        u32     dst;
618
 
619
        if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
620
                return igmpv3_send_report(in_dev, pmc);
621
        else if (type == IGMP_HOST_LEAVE_MESSAGE)
622
                dst = IGMP_ALL_ROUTER;
623
        else
624
                dst = group;
625
 
626
        if (ip_route_output(&rt, dst, 0, 0, dev->ifindex))
627
                return -1;
628
        if (rt->rt_src == 0) {
629
                ip_rt_put(rt);
630
                return -1;
631
        }
632
 
633
        skb=alloc_skb(IGMP_SIZE+dev->hard_header_len+15, GFP_ATOMIC);
634
        if (skb == NULL) {
635
                ip_rt_put(rt);
636
                return -1;
637
        }
638
 
639
        skb->dst = &rt->u.dst;
640
 
641
        skb_reserve(skb, (dev->hard_header_len+15)&~15);
642
 
643
        skb->nh.iph = iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)+4);
644
 
645
        iph->version  = 4;
646
        iph->ihl      = (sizeof(struct iphdr)+4)>>2;
647
        iph->tos      = 0xc0;
648
        iph->frag_off = htons(IP_DF);
649
        iph->ttl      = 1;
650
        iph->daddr    = dst;
651
        iph->saddr    = rt->rt_src;
652
        iph->protocol = IPPROTO_IGMP;
653
        iph->tot_len  = htons(IGMP_SIZE);
654
        ip_select_ident(iph, &rt->u.dst, NULL);
655
        ((u8*)&iph[1])[0] = IPOPT_RA;
656
        ((u8*)&iph[1])[1] = 4;
657
        ((u8*)&iph[1])[2] = 0;
658
        ((u8*)&iph[1])[3] = 0;
659
        ip_send_check(iph);
660
 
661
        ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
662
        ih->type=type;
663
        ih->code=0;
664
        ih->csum=0;
665
        ih->group=group;
666
        ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
667
 
668
        return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
669
                       output_maybe_reroute);
670
}
671
 
672
static void igmp_gq_timer_expire(unsigned long data)
673
{
674
        struct in_device *in_dev = (struct in_device *)data;
675
 
676
        in_dev->mr_gq_running = 0;
677
        igmpv3_send_report(in_dev, 0);
678
        __in_dev_put(in_dev);
679
}
680
 
681
static void igmp_ifc_timer_expire(unsigned long data)
682
{
683
        struct in_device *in_dev = (struct in_device *)data;
684
 
685
        igmpv3_send_cr(in_dev);
686
        if (in_dev->mr_ifc_count) {
687
                in_dev->mr_ifc_count--;
688
                igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval);
689
        }
690
        __in_dev_put(in_dev);
691
}
692
 
693
static void igmp_ifc_event(struct in_device *in_dev)
694
{
695
        if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
696
                return;
697
        in_dev->mr_ifc_count = in_dev->mr_qrv ? in_dev->mr_qrv :
698
                IGMP_Unsolicited_Report_Count;
699
        igmp_ifc_start_timer(in_dev, 1);
700
}
701
 
702
 
703
static void igmp_timer_expire(unsigned long data)
704
{
705
        struct ip_mc_list *im=(struct ip_mc_list *)data;
706
        struct in_device *in_dev = im->interface;
707
 
708
        spin_lock(&im->lock);
709
        im->tm_running=0;
710
 
711
        if (im->unsolicit_count) {
712
                im->unsolicit_count--;
713
                igmp_start_timer(im, IGMP_Unsolicited_Report_Interval);
714
        }
715
        im->reporter = 1;
716
        spin_unlock(&im->lock);
717
 
718
        if (IGMP_V1_SEEN(in_dev))
719
                igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT);
720
        else if (IGMP_V2_SEEN(in_dev))
721
                igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT);
722
        else
723
                igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT);
724
 
725
        ip_ma_put(im);
726
}
727
 
728
static void igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
729
{
730
        struct ip_sf_list *psf;
731
        int i, scount;
732
 
733
        scount = 0;
734
        for (psf=pmc->sources; psf; psf=psf->sf_next) {
735
                if (scount == nsrcs)
736
                        break;
737
                for (i=0; i<nsrcs; i++)
738
                        if (srcs[i] == psf->sf_inaddr) {
739
                                psf->sf_gsresp = 1;
740
                                scount++;
741
                                break;
742
                        }
743
        }
744
}
745
 
746
static void igmp_heard_report(struct in_device *in_dev, u32 group)
747
{
748
        struct ip_mc_list *im;
749
 
750
        /* Timers are only set for non-local groups */
751
 
752
        if (group == IGMP_ALL_HOSTS)
753
                return;
754
 
755
        read_lock(&in_dev->lock);
756
        for (im=in_dev->mc_list; im!=NULL; im=im->next) {
757
                if (im->multiaddr == group) {
758
                        igmp_stop_timer(im);
759
                        break;
760
                }
761
        }
762
        read_unlock(&in_dev->lock);
763
}
764
 
765
static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
766
        int len)
767
{
768
        struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
769
        struct ip_mc_list       *im;
770
        u32                     group = ih->group;
771
        int                     max_delay;
772
        int                     mark = 0;
773
 
774
 
775
        if (len == 8) {
776
                if (ih->code == 0) {
777
                        /* Alas, old v1 router presents here. */
778
 
779
                        max_delay = IGMP_Query_Response_Interval;
780
                        in_dev->mr_v1_seen = jiffies +
781
                                IGMP_V1_Router_Present_Timeout;
782
                        group = 0;
783
                } else {
784
                        /* v2 router present */
785
                        max_delay = ih->code*(HZ/IGMP_TIMER_SCALE);
786
                        in_dev->mr_v2_seen = jiffies +
787
                                IGMP_V2_Router_Present_Timeout;
788
                }
789
                /* cancel the interface change timer */
790
                in_dev->mr_ifc_count = 0;
791
                if (del_timer(&in_dev->mr_ifc_timer))
792
                        __in_dev_put(in_dev);
793
                /* clear deleted report items */
794
                igmpv3_clear_delrec(in_dev);
795
        } else if (len < 12) {
796
                return; /* ignore bogus packet; freed by caller */
797
        } else { /* v3 */
798
                max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
799
                if (!max_delay)
800
                        max_delay = 1;  /* can't mod w/ 0 */
801
                in_dev->mr_maxdelay = max_delay;
802
                if (ih3->qrv)
803
                        in_dev->mr_qrv = ih3->qrv;
804
                if (!group) { /* general query */
805
                        if (ih3->nsrcs)
806
                                return; /* no sources allowed */
807
                        igmp_gq_start_timer(in_dev);
808
                        return;
809
                }
810
                /* mark sources to include, if group & source-specific */
811
                mark = ih3->nsrcs != 0;
812
        }
813
 
814
        /*
815
         * - Start the timers in all of our membership records
816
         *   that the query applies to for the interface on
817
         *   which the query arrived excl. those that belong
818
         *   to a "local" group (224.0.0.X)
819
         * - For timers already running check if they need to
820
         *   be reset.
821
         * - Use the igmp->igmp_code field as the maximum
822
         *   delay possible
823
         */
824
        read_lock(&in_dev->lock);
825
        for (im=in_dev->mc_list; im!=NULL; im=im->next) {
826
                if (group && group != im->multiaddr)
827
                        continue;
828
                if (im->multiaddr == IGMP_ALL_HOSTS)
829
                        continue;
830
                spin_lock_bh(&im->lock);
831
                if (im->tm_running)
832
                        im->gsquery = im->gsquery && mark;
833
                else
834
                        im->gsquery = mark;
835
                if (im->gsquery)
836
                        igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs);
837
                spin_unlock_bh(&im->lock);
838
                igmp_mod_timer(im, max_delay);
839
        }
840
        read_unlock(&in_dev->lock);
841
}
842
 
843
int igmp_rcv(struct sk_buff *skb)
844
{
845
        /* This basically follows the spec line by line -- see RFC1112 */
846
        struct igmphdr *ih = skb->h.igmph;
847
        struct in_device *in_dev = in_dev_get(skb->dev);
848
        int len = skb->len;
849
 
850
        if (in_dev==NULL) {
851
                kfree_skb(skb);
852
                return 0;
853
        }
854
 
855
        if (skb_is_nonlinear(skb)) {
856
                if (skb_linearize(skb, GFP_ATOMIC) != 0) {
857
                        kfree_skb(skb);
858
                        return -ENOMEM;
859
                }
860
                ih = skb->h.igmph;
861
        }
862
 
863
        if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) {
864
                in_dev_put(in_dev);
865
                kfree_skb(skb);
866
                return 0;
867
        }
868
 
869
        switch (ih->type) {
870
        case IGMP_HOST_MEMBERSHIP_QUERY:
871
                igmp_heard_query(in_dev, ih, len);
872
                break;
873
        case IGMP_HOST_MEMBERSHIP_REPORT:
874
        case IGMPV2_HOST_MEMBERSHIP_REPORT:
875
        case IGMPV3_HOST_MEMBERSHIP_REPORT:
876
                /* Is it our report looped back? */
877
                if (((struct rtable*)skb->dst)->key.iif == 0)
878
                        break;
879
                igmp_heard_report(in_dev, ih->group);
880
                break;
881
        case IGMP_PIM:
882
#ifdef CONFIG_IP_PIMSM_V1
883
                in_dev_put(in_dev);
884
                return pim_rcv_v1(skb);
885
#endif
886
        case IGMP_DVMRP:
887
        case IGMP_TRACE:
888
        case IGMP_HOST_LEAVE_MESSAGE:
889
        case IGMP_MTRACE:
890
        case IGMP_MTRACE_RESP:
891
                break;
892
        default:
893
                NETDEBUG(printk(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type));
894
        }
895
        in_dev_put(in_dev);
896
        kfree_skb(skb);
897
        return 0;
898
}
899
 
900
#endif
901
 
902
 
903
/*
904
 *      Add a filter to a device
905
 */
906
 
907
static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
908
{
909
        char buf[MAX_ADDR_LEN];
910
        struct net_device *dev = in_dev->dev;
911
 
912
        /* Checking for IFF_MULTICAST here is WRONG-WRONG-WRONG.
913
           We will get multicast token leakage, when IFF_MULTICAST
914
           is changed. This check should be done in dev->set_multicast_list
915
           routine. Something sort of:
916
           if (dev->mc_list && dev->flags&IFF_MULTICAST) { do it; }
917
           --ANK
918
           */
919
        if (arp_mc_map(addr, buf, dev, 0) == 0)
920
                dev_mc_add(dev,buf,dev->addr_len,0);
921
}
922
 
923
/*
924
 *      Remove a filter from a device
925
 */
926
 
927
static void ip_mc_filter_del(struct in_device *in_dev, u32 addr)
928
{
929
        char buf[MAX_ADDR_LEN];
930
        struct net_device *dev = in_dev->dev;
931
 
932
        if (arp_mc_map(addr, buf, dev, 0) == 0)
933
                dev_mc_delete(dev,buf,dev->addr_len,0);
934
}
935
 
936
#ifdef CONFIG_IP_MULTICAST
937
/*
938
 * deleted ip_mc_list manipulation
939
 */
940
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
941
{
942
        struct ip_mc_list *pmc;
943
 
944
        /* this is an "ip_mc_list" for convenience; only the fields below
945
         * are actually used. In particular, the refcnt and users are not
946
         * used for management of the delete list. Using the same structure
947
         * for deleted items allows change reports to use common code with
948
         * non-deleted or query-response MCA's.
949
         */
950
        pmc = (struct ip_mc_list *)kmalloc(sizeof(*pmc), GFP_KERNEL);
951
        if (!pmc)
952
                return;
953
        memset(pmc, 0, sizeof(*pmc));
954
        spin_lock_bh(&im->lock);
955
        pmc->interface = im->interface;
956
        in_dev_hold(in_dev);
957
        pmc->multiaddr = im->multiaddr;
958
        pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
959
                IGMP_Unsolicited_Report_Count;
960
        pmc->sfmode = im->sfmode;
961
        if (pmc->sfmode == MCAST_INCLUDE) {
962
                struct ip_sf_list *psf;
963
 
964
                pmc->tomb = im->tomb;
965
                pmc->sources = im->sources;
966
                im->tomb = im->sources = 0;
967
                for (psf=pmc->sources; psf; psf=psf->sf_next)
968
                        psf->sf_crcount = pmc->crcount;
969
        }
970
        spin_unlock_bh(&im->lock);
971
 
972
        write_lock_bh(&in_dev->mc_lock);
973
        pmc->next = in_dev->mc_tomb;
974
        in_dev->mc_tomb = pmc;
975
        write_unlock_bh(&in_dev->mc_lock);
976
}
977
 
978
static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr)
979
{
980
        struct ip_mc_list *pmc, *pmc_prev;
981
        struct ip_sf_list *psf, *psf_next;
982
 
983
        write_lock_bh(&in_dev->mc_lock);
984
        pmc_prev = 0;
985
        for (pmc=in_dev->mc_tomb; pmc; pmc=pmc->next) {
986
                if (pmc->multiaddr == multiaddr)
987
                        break;
988
                pmc_prev = pmc;
989
        }
990
        if (pmc) {
991
                if (pmc_prev)
992
                        pmc_prev->next = pmc->next;
993
                else
994
                        in_dev->mc_tomb = pmc->next;
995
        }
996
        write_unlock_bh(&in_dev->mc_lock);
997
        if (pmc) {
998
                for (psf=pmc->tomb; psf; psf=psf_next) {
999
                        psf_next = psf->sf_next;
1000
                        kfree(psf);
1001
                }
1002
                in_dev_put(pmc->interface);
1003
                kfree(pmc);
1004
        }
1005
}
1006
 
1007
static void igmpv3_clear_delrec(struct in_device *in_dev)
1008
{
1009
        struct ip_mc_list *pmc, *nextpmc;
1010
 
1011
        write_lock_bh(&in_dev->mc_lock);
1012
        pmc = in_dev->mc_tomb;
1013
        in_dev->mc_tomb = 0;
1014
        write_unlock_bh(&in_dev->mc_lock);
1015
 
1016
        for (; pmc; pmc = nextpmc) {
1017
                nextpmc = pmc->next;
1018
                ip_mc_clear_src(pmc);
1019
                in_dev_put(pmc->interface);
1020
                kfree(pmc);
1021
        }
1022
        /* clear dead sources, too */
1023
        read_lock(&in_dev->lock);
1024
        for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
1025
                struct ip_sf_list *psf, *psf_next;
1026
 
1027
                spin_lock_bh(&pmc->lock);
1028
                psf = pmc->tomb;
1029
                pmc->tomb = 0;
1030
                spin_unlock_bh(&pmc->lock);
1031
                for (; psf; psf=psf_next) {
1032
                        psf_next = psf->sf_next;
1033
                        kfree(psf);
1034
                }
1035
        }
1036
        read_unlock(&in_dev->lock);
1037
}
1038
#endif
1039
 
1040
static void igmp_group_dropped(struct ip_mc_list *im)
1041
{
1042
        struct in_device *in_dev = im->interface;
1043
#ifdef CONFIG_IP_MULTICAST
1044
        int reporter;
1045
#endif
1046
 
1047
        if (im->loaded) {
1048
                im->loaded = 0;
1049
                ip_mc_filter_del(in_dev, im->multiaddr);
1050
        }
1051
 
1052
#ifdef CONFIG_IP_MULTICAST
1053
        if (im->multiaddr == IGMP_ALL_HOSTS)
1054
                return;
1055
 
1056
        reporter = im->reporter;
1057
        igmp_stop_timer(im);
1058
 
1059
        if (!in_dev->dead) {
1060
                if (IGMP_V1_SEEN(in_dev))
1061
                        goto done;
1062
                if (IGMP_V2_SEEN(in_dev)) {
1063
                        if (reporter)
1064
                                igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE);
1065
                        goto done;
1066
                }
1067
                /* IGMPv3 */
1068
                igmpv3_add_delrec(in_dev, im);
1069
 
1070
                igmp_ifc_event(in_dev);
1071
        }
1072
done:
1073
#endif
1074
        ip_mc_clear_src(im);
1075
}
1076
 
1077
static void igmp_group_added(struct ip_mc_list *im)
1078
{
1079
        struct in_device *in_dev = im->interface;
1080
 
1081
        if (im->loaded == 0) {
1082
                im->loaded = 1;
1083
                ip_mc_filter_add(in_dev, im->multiaddr);
1084
        }
1085
 
1086
#ifdef CONFIG_IP_MULTICAST
1087
        if (im->multiaddr == IGMP_ALL_HOSTS)
1088
                return;
1089
 
1090
        if (in_dev->dead)
1091
                return;
1092
        if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
1093
                spin_lock_bh(&im->lock);
1094
                igmp_start_timer(im, IGMP_Initial_Report_Delay);
1095
                spin_unlock_bh(&im->lock);
1096
                return;
1097
        }
1098
        /* else, v3 */
1099
 
1100
        im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
1101
                IGMP_Unsolicited_Report_Count;
1102
        igmp_ifc_event(in_dev);
1103
#endif
1104
}
1105
 
1106
 
1107
/*
1108
 *      Multicast list managers
1109
 */
1110
 
1111
 
1112
/*
1113
 *      A socket has joined a multicast group on device dev.
1114
 */
1115
 
1116
void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
1117
{
1118
        struct ip_mc_list *im;
1119
 
1120
        ASSERT_RTNL();
1121
 
1122
        for (im=in_dev->mc_list; im; im=im->next) {
1123
                if (im->multiaddr == addr) {
1124
                        im->users++;
1125
                        ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, 0, 0);
1126
                        goto out;
1127
                }
1128
        }
1129
 
1130
        im = (struct ip_mc_list *)kmalloc(sizeof(*im), GFP_KERNEL);
1131
        if (!im)
1132
                goto out;
1133
 
1134
        im->users=1;
1135
        im->interface=in_dev;
1136
        in_dev_hold(in_dev);
1137
        im->multiaddr=addr;
1138
        /* initial mode is (EX, empty) */
1139
        im->sfmode = MCAST_EXCLUDE;
1140
        im->sfcount[MCAST_INCLUDE] = 0;
1141
        im->sfcount[MCAST_EXCLUDE] = 1;
1142
        im->sources = 0;
1143
        im->tomb = 0;
1144
        im->crcount = 0;
1145
        atomic_set(&im->refcnt, 1);
1146
        spin_lock_init(&im->lock);
1147
#ifdef CONFIG_IP_MULTICAST
1148
        im->tm_running=0;
1149
        init_timer(&im->timer);
1150
        im->timer.data=(unsigned long)im;
1151
        im->timer.function=&igmp_timer_expire;
1152
        im->unsolicit_count = IGMP_Unsolicited_Report_Count;
1153
        im->reporter = 0;
1154
        im->gsquery = 0;
1155
#endif
1156
        im->loaded = 0;
1157
        write_lock_bh(&in_dev->lock);
1158
        im->next=in_dev->mc_list;
1159
        in_dev->mc_list=im;
1160
        write_unlock_bh(&in_dev->lock);
1161
#ifdef CONFIG_IP_MULTICAST
1162
        igmpv3_del_delrec(in_dev, im->multiaddr);
1163
#endif
1164
        igmp_group_added(im);
1165
        if (!in_dev->dead)
1166
                ip_rt_multicast_event(in_dev);
1167
out:
1168
        return;
1169
}
1170
 
1171
/*
1172
 *      A socket has left a multicast group on device dev
1173
 */
1174
 
1175
void ip_mc_dec_group(struct in_device *in_dev, u32 addr)
1176
{
1177
        struct ip_mc_list *i, **ip;
1178
 
1179
        ASSERT_RTNL();
1180
 
1181
        for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) {
1182
                if (i->multiaddr==addr) {
1183
                        if (--i->users == 0) {
1184
                                write_lock_bh(&in_dev->lock);
1185
                                *ip = i->next;
1186
                                write_unlock_bh(&in_dev->lock);
1187
                                igmp_group_dropped(i);
1188
 
1189
                                if (!in_dev->dead)
1190
                                        ip_rt_multicast_event(in_dev);
1191
 
1192
                                ip_ma_put(i);
1193
                                return;
1194
                        }
1195
                        break;
1196
                }
1197
        }
1198
}
1199
 
1200
/* Device going down */
1201
 
1202
void ip_mc_down(struct in_device *in_dev)
1203
{
1204
        struct ip_mc_list *i;
1205
 
1206
        ASSERT_RTNL();
1207
 
1208
        for (i=in_dev->mc_list; i; i=i->next)
1209
                igmp_group_dropped(i);
1210
 
1211
#ifdef CONFIG_IP_MULTICAST
1212
        in_dev->mr_ifc_count = 0;
1213
        if (del_timer(&in_dev->mr_ifc_timer))
1214
                __in_dev_put(in_dev);
1215
        in_dev->mr_gq_running = 0;
1216
        if (del_timer(&in_dev->mr_gq_timer))
1217
                __in_dev_put(in_dev);
1218
        igmpv3_clear_delrec(in_dev);
1219
#endif
1220
 
1221
        ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
1222
}
1223
 
1224
void ip_mc_init_dev(struct in_device *in_dev)
1225
{
1226
        ASSERT_RTNL();
1227
 
1228
        in_dev->mc_tomb = 0;
1229
#ifdef CONFIG_IP_MULTICAST
1230
        in_dev->mr_gq_running = 0;
1231
        init_timer(&in_dev->mr_gq_timer);
1232
        in_dev->mr_gq_timer.data=(unsigned long) in_dev;
1233
        in_dev->mr_gq_timer.function=&igmp_gq_timer_expire;
1234
        in_dev->mr_ifc_count = 0;
1235
        init_timer(&in_dev->mr_ifc_timer);
1236
        in_dev->mr_ifc_timer.data=(unsigned long) in_dev;
1237
        in_dev->mr_ifc_timer.function=&igmp_ifc_timer_expire;
1238
        in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
1239
#endif
1240
 
1241
        in_dev->mc_lock = RW_LOCK_UNLOCKED;
1242
}
1243
 
1244
/* Device going up */
1245
 
1246
void ip_mc_up(struct in_device *in_dev)
1247
{
1248
        struct ip_mc_list *i;
1249
 
1250
        ASSERT_RTNL();
1251
 
1252
        ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
1253
 
1254
        for (i=in_dev->mc_list; i; i=i->next)
1255
                igmp_group_added(i);
1256
}
1257
 
1258
/*
1259
 *      Device is about to be destroyed: clean up.
1260
 */
1261
 
1262
void ip_mc_destroy_dev(struct in_device *in_dev)
1263
{
1264
        struct ip_mc_list *i;
1265
 
1266
        ASSERT_RTNL();
1267
 
1268
        /* Deactivate timers */
1269
        ip_mc_down(in_dev);
1270
 
1271
        write_lock_bh(&in_dev->lock);
1272
        while ((i = in_dev->mc_list) != NULL) {
1273
                in_dev->mc_list = i->next;
1274
                write_unlock_bh(&in_dev->lock);
1275
 
1276
                igmp_group_dropped(i);
1277
                ip_ma_put(i);
1278
 
1279
                write_lock_bh(&in_dev->lock);
1280
        }
1281
        write_unlock_bh(&in_dev->lock);
1282
}
1283
 
1284
static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
1285
{
1286
        struct rtable *rt;
1287
        struct net_device *dev = NULL;
1288
        struct in_device *idev = NULL;
1289
 
1290
        if (imr->imr_ifindex) {
1291
                idev = inetdev_by_index(imr->imr_ifindex);
1292
                if (idev)
1293
                        __in_dev_put(idev);
1294
                return idev;
1295
        }
1296
        if (imr->imr_address.s_addr) {
1297
                dev = ip_dev_find(imr->imr_address.s_addr);
1298
                if (!dev)
1299
                        return NULL;
1300
                __dev_put(dev);
1301
        }
1302
 
1303
        if (!dev && !ip_route_output(&rt, imr->imr_multiaddr.s_addr, 0, 0, 0)) {
1304
                dev = rt->u.dst.dev;
1305
                ip_rt_put(rt);
1306
        }
1307
        if (dev) {
1308
                imr->imr_ifindex = dev->ifindex;
1309
                idev = __in_dev_get(dev);
1310
        }
1311
        return idev;
1312
}
1313
 
1314
/*
1315
 *      Join a socket to a group
1316
 */
1317
int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS;
1318
int sysctl_igmp_max_msf = IP_MAX_MSF;
1319
 
1320
 
1321
static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
1322
        __u32 *psfsrc)
1323
{
1324
        struct ip_sf_list *psf, *psf_prev;
1325
        int rv = 0;
1326
 
1327
        psf_prev = 0;
1328
        for (psf=pmc->sources; psf; psf=psf->sf_next) {
1329
                if (psf->sf_inaddr == *psfsrc)
1330
                        break;
1331
                psf_prev = psf;
1332
        }
1333
        if (!psf || psf->sf_count[sfmode] == 0) {
1334
                /* source filter not found, or count wrong =>  bug */
1335
                return -ESRCH;
1336
        }
1337
        psf->sf_count[sfmode]--;
1338
        if (psf->sf_count[sfmode] == 0) {
1339
                ip_rt_multicast_event(pmc->interface);
1340
        }
1341
        if (!psf->sf_count[MCAST_INCLUDE] && !psf->sf_count[MCAST_EXCLUDE]) {
1342
#ifdef CONFIG_IP_MULTICAST
1343
                struct in_device *in_dev = pmc->interface;
1344
#endif
1345
 
1346
                /* no more filters for this source */
1347
                if (psf_prev)
1348
                        psf_prev->sf_next = psf->sf_next;
1349
                else
1350
                        pmc->sources = psf->sf_next;
1351
#ifdef CONFIG_IP_MULTICAST
1352
                if (psf->sf_oldin &&
1353
                    !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) {
1354
                        psf->sf_crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
1355
                                IGMP_Unsolicited_Report_Count;
1356
                        psf->sf_next = pmc->tomb;
1357
                        pmc->tomb = psf;
1358
                        rv = 1;
1359
                } else
1360
#endif
1361
                        kfree(psf);
1362
        }
1363
        return rv;
1364
}
1365
 
1366
int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
1367
        int sfcount, __u32 *psfsrc, int delta)
1368
{
1369
        struct ip_mc_list *pmc;
1370
        int     changerec = 0;
1371
        int     i, err;
1372
 
1373
        if (!in_dev)
1374
                return -ENODEV;
1375
        read_lock(&in_dev->lock);
1376
        for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
1377
                if (*pmca == pmc->multiaddr)
1378
                        break;
1379
        }
1380
        if (!pmc) {
1381
                /* MCA not found?? bug */
1382
                read_unlock(&in_dev->lock);
1383
                return -ESRCH;
1384
        }
1385
        spin_lock_bh(&pmc->lock);
1386
        read_unlock(&in_dev->lock);
1387
#ifdef CONFIG_IP_MULTICAST
1388
        sf_markstate(pmc);
1389
#endif
1390
        if (!delta) {
1391
                err = -EINVAL;
1392
                if (!pmc->sfcount[sfmode])
1393
                        goto out_unlock;
1394
                pmc->sfcount[sfmode]--;
1395
        }
1396
        err = 0;
1397
        for (i=0; i<sfcount; i++) {
1398
                int rv = ip_mc_del1_src(pmc, sfmode, &psfsrc[i]);
1399
 
1400
                changerec |= rv > 0;
1401
                if (!err && rv < 0)
1402
                        err = rv;
1403
        }
1404
        if (pmc->sfmode == MCAST_EXCLUDE &&
1405
            pmc->sfcount[MCAST_EXCLUDE] == 0 &&
1406
            pmc->sfcount[MCAST_INCLUDE]) {
1407
#ifdef CONFIG_IP_MULTICAST
1408
                struct ip_sf_list *psf;
1409
#endif
1410
 
1411
                /* filter mode change */
1412
                pmc->sfmode = MCAST_INCLUDE;
1413
#ifdef CONFIG_IP_MULTICAST
1414
                pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
1415
                        IGMP_Unsolicited_Report_Count;
1416
                in_dev->mr_ifc_count = pmc->crcount;
1417
                for (psf=pmc->sources; psf; psf = psf->sf_next)
1418
                        psf->sf_crcount = 0;
1419
                igmp_ifc_event(pmc->interface);
1420
        } else if (sf_setstate(pmc) || changerec) {
1421
                igmp_ifc_event(pmc->interface);
1422
#endif
1423
        }
1424
out_unlock:
1425
        spin_unlock_bh(&pmc->lock);
1426
        return err;
1427
}
1428
 
1429
/*
1430
 * Add multicast single-source filter to the interface list
1431
 */
1432
static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
1433
        __u32 *psfsrc, int delta)
1434
{
1435
        struct ip_sf_list *psf, *psf_prev;
1436
 
1437
        psf_prev = 0;
1438
        for (psf=pmc->sources; psf; psf=psf->sf_next) {
1439
                if (psf->sf_inaddr == *psfsrc)
1440
                        break;
1441
                psf_prev = psf;
1442
        }
1443
        if (!psf) {
1444
                psf = (struct ip_sf_list *)kmalloc(sizeof(*psf), GFP_ATOMIC);
1445
                if (!psf)
1446
                        return -ENOBUFS;
1447
                memset(psf, 0, sizeof(*psf));
1448
                psf->sf_inaddr = *psfsrc;
1449
                if (psf_prev) {
1450
                        psf_prev->sf_next = psf;
1451
                } else
1452
                        pmc->sources = psf;
1453
        }
1454
        psf->sf_count[sfmode]++;
1455
        if (psf->sf_count[sfmode] == 1) {
1456
                ip_rt_multicast_event(pmc->interface);
1457
        }
1458
        return 0;
1459
}
1460
 
1461
#ifdef CONFIG_IP_MULTICAST
1462
static void sf_markstate(struct ip_mc_list *pmc)
1463
{
1464
        struct ip_sf_list *psf;
1465
        int mca_xcount = pmc->sfcount[MCAST_EXCLUDE];
1466
 
1467
        for (psf=pmc->sources; psf; psf=psf->sf_next)
1468
                if (pmc->sfcount[MCAST_EXCLUDE]) {
1469
                        psf->sf_oldin = mca_xcount ==
1470
                                psf->sf_count[MCAST_EXCLUDE] &&
1471
                                !psf->sf_count[MCAST_INCLUDE];
1472
                } else
1473
                        psf->sf_oldin = psf->sf_count[MCAST_INCLUDE] != 0;
1474
}
1475
 
1476
static int sf_setstate(struct ip_mc_list *pmc)
1477
{
1478
        struct ip_sf_list *psf;
1479
        int mca_xcount = pmc->sfcount[MCAST_EXCLUDE];
1480
        int qrv = pmc->interface->mr_qrv;
1481
        int new_in, rv;
1482
 
1483
        rv = 0;
1484
        for (psf=pmc->sources; psf; psf=psf->sf_next) {
1485
                if (pmc->sfcount[MCAST_EXCLUDE]) {
1486
                        new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
1487
                                !psf->sf_count[MCAST_INCLUDE];
1488
                } else
1489
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
1490
                if (new_in != psf->sf_oldin) {
1491
                        psf->sf_crcount = qrv;
1492
                        rv++;
1493
                }
1494
        }
1495
        return rv;
1496
}
1497
#endif
1498
 
1499
/*
1500
 * Add multicast source filter list to the interface list
1501
 */
1502
int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
1503
        int sfcount, __u32 *psfsrc, int delta)
1504
{
1505
        struct ip_mc_list *pmc;
1506
        int     isexclude;
1507
        int     i, err;
1508
 
1509
        if (!in_dev)
1510
                return -ENODEV;
1511
        read_lock(&in_dev->lock);
1512
        for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
1513
                if (*pmca == pmc->multiaddr)
1514
                        break;
1515
        }
1516
        if (!pmc) {
1517
                /* MCA not found?? bug */
1518
                read_unlock(&in_dev->lock);
1519
                return -ESRCH;
1520
        }
1521
        spin_lock_bh(&pmc->lock);
1522
        read_unlock(&in_dev->lock);
1523
 
1524
#ifdef CONFIG_IP_MULTICAST
1525
        sf_markstate(pmc);
1526
#endif
1527
        isexclude = pmc->sfmode == MCAST_EXCLUDE;
1528
        if (!delta)
1529
                pmc->sfcount[sfmode]++;
1530
        err = 0;
1531
        for (i=0; i<sfcount; i++) {
1532
                err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i], delta);
1533
                if (err)
1534
                        break;
1535
        }
1536
        if (err) {
1537
                int j;
1538
 
1539
                pmc->sfcount[sfmode]--;
1540
                for (j=0; j<i; j++)
1541
                        (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]);
1542
        } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
1543
#ifdef CONFIG_IP_MULTICAST
1544
                struct in_device *in_dev = pmc->interface;
1545
                struct ip_sf_list *psf;
1546
#endif
1547
 
1548
                /* filter mode change */
1549
                if (pmc->sfcount[MCAST_EXCLUDE])
1550
                        pmc->sfmode = MCAST_EXCLUDE;
1551
                else if (pmc->sfcount[MCAST_INCLUDE])
1552
                        pmc->sfmode = MCAST_INCLUDE;
1553
#ifdef CONFIG_IP_MULTICAST
1554
                /* else no filters; keep old mode for reports */
1555
 
1556
                pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
1557
                        IGMP_Unsolicited_Report_Count;
1558
                in_dev->mr_ifc_count = pmc->crcount;
1559
                for (psf=pmc->sources; psf; psf = psf->sf_next)
1560
                        psf->sf_crcount = 0;
1561
                igmp_ifc_event(in_dev);
1562
        } else if (sf_setstate(pmc)) {
1563
                igmp_ifc_event(in_dev);
1564
#endif
1565
        }
1566
        spin_unlock_bh(&pmc->lock);
1567
        return err;
1568
}
1569
 
1570
static void ip_mc_clear_src(struct ip_mc_list *pmc)
1571
{
1572
        struct ip_sf_list *psf, *nextpsf;
1573
 
1574
        for (psf=pmc->tomb; psf; psf=nextpsf) {
1575
                nextpsf = psf->sf_next;
1576
                kfree(psf);
1577
        }
1578
        pmc->tomb = 0;
1579
        for (psf=pmc->sources; psf; psf=nextpsf) {
1580
                nextpsf = psf->sf_next;
1581
                kfree(psf);
1582
        }
1583
        pmc->sources = 0;
1584
        pmc->sfmode = MCAST_EXCLUDE;
1585
        pmc->sfcount[MCAST_EXCLUDE] = 0;
1586
        pmc->sfcount[MCAST_EXCLUDE] = 1;
1587
}
1588
 
1589
 
1590
/*
1591
 * Join a multicast group
1592
 */
1593
int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
1594
{
1595
        int err;
1596
        u32 addr = imr->imr_multiaddr.s_addr;
1597
        struct ip_mc_socklist *iml, *i;
1598
        struct in_device *in_dev;
1599
        struct inet_opt *inet = &sk->protinfo.af_inet;
1600
        int count = 0;
1601
 
1602
        if (!MULTICAST(addr))
1603
                return -EINVAL;
1604
 
1605
        rtnl_shlock();
1606
 
1607
        in_dev = ip_mc_find_dev(imr);
1608
 
1609
        if (!in_dev) {
1610
                iml = NULL;
1611
                err = -ENODEV;
1612
                goto done;
1613
        }
1614
 
1615
        iml = (struct ip_mc_socklist *)sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
1616
 
1617
        err = -EADDRINUSE;
1618
        for (i = inet->mc_list; i; i = i->next) {
1619
                if (memcmp(&i->multi, imr, sizeof(*imr)) == 0) {
1620
                        /* New style additions are reference counted */
1621
                        if (imr->imr_address.s_addr == 0) {
1622
                                i->count++;
1623
                                err = 0;
1624
                        }
1625
                        goto done;
1626
                }
1627
                count++;
1628
        }
1629
        err = -ENOBUFS;
1630
        if (iml == NULL || count >= sysctl_igmp_max_memberships)
1631
                goto done;
1632
        memcpy(&iml->multi, imr, sizeof(*imr));
1633
        iml->next = sk->protinfo.af_inet.mc_list;
1634
        iml->count = 1;
1635
        iml->sflist = NULL;
1636
        iml->sfmode = MCAST_EXCLUDE;
1637
        inet->mc_list = iml;
1638
        ip_mc_inc_group(in_dev, addr);
1639
        iml = NULL;
1640
        err = 0;
1641
 
1642
done:
1643
        rtnl_shunlock();
1644
        if (iml)
1645
                sock_kfree_s(sk, iml, sizeof(*iml));
1646
        return err;
1647
}
1648
 
1649
int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
1650
        struct in_device *in_dev)
1651
{
1652
        int err;
1653
 
1654
        if (iml->sflist == 0) {
1655
                /* any-source empty exclude case */
1656
                return ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,
1657
                        iml->sfmode, 0, 0, 0);
1658
        }
1659
        err = ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,
1660
                        iml->sfmode, iml->sflist->sl_count,
1661
                        iml->sflist->sl_addr, 0);
1662
        sock_kfree_s(sk, iml->sflist, IP_SFLSIZE(iml->sflist->sl_max));
1663
        iml->sflist = 0;
1664
        return err;
1665
}
1666
 
1667
/*
1668
 *      Ask a socket to leave a group.
1669
 */
1670
 
1671
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
1672
{
1673
        struct inet_opt *inet = &sk->protinfo.af_inet;
1674
        struct ip_mc_socklist *iml, **imlp;
1675
 
1676
        rtnl_lock();
1677
        for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
1678
                if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr &&
1679
                    iml->multi.imr_address.s_addr==imr->imr_address.s_addr &&
1680
                    (!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) {
1681
                        struct in_device *in_dev;
1682
 
1683
                        in_dev = inetdev_by_index(iml->multi.imr_ifindex);
1684
                        if (in_dev)
1685
                                (void) ip_mc_leave_src(sk, iml, in_dev);
1686
                        if (--iml->count) {
1687
                                rtnl_unlock();
1688
                                if (in_dev)
1689
                                        in_dev_put(in_dev);
1690
                                return 0;
1691
                        }
1692
 
1693
                        *imlp = iml->next;
1694
 
1695
                        if (in_dev) {
1696
                                ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr);
1697
                                in_dev_put(in_dev);
1698
                        }
1699
                        rtnl_unlock();
1700
                        sock_kfree_s(sk, iml, sizeof(*iml));
1701
                        return 0;
1702
                }
1703
        }
1704
        rtnl_unlock();
1705
        return -EADDRNOTAVAIL;
1706
}
1707
 
1708
int ip_mc_source(int add, int omode, struct sock *sk, struct
1709
        ip_mreq_source *mreqs, int ifindex)
1710
{
1711
        int err;
1712
        struct ip_mreqn imr;
1713
        u32 addr = mreqs->imr_multiaddr;
1714
        struct ip_mc_socklist *pmc;
1715
        struct in_device *in_dev = 0;
1716
        struct inet_opt *inet = &sk->protinfo.af_inet;
1717
        struct ip_sf_socklist *psl;
1718
        int i, j, rv;
1719
 
1720
        if (!MULTICAST(addr))
1721
                return -EINVAL;
1722
 
1723
        rtnl_shlock();
1724
 
1725
        imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
1726
        imr.imr_address.s_addr = mreqs->imr_interface;
1727
        imr.imr_ifindex = ifindex;
1728
        in_dev = ip_mc_find_dev(&imr);
1729
 
1730
        if (!in_dev) {
1731
                err = -ENODEV;
1732
                goto done;
1733
        }
1734
        err = -EADDRNOTAVAIL;
1735
 
1736
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1737
                if (memcmp(&pmc->multi, mreqs, 2*sizeof(__u32)) == 0)
1738
                        break;
1739
        }
1740
        if (!pmc)               /* must have a prior join */
1741
                goto done;
1742
        /* if a source filter was set, must be the same mode as before */
1743
        if (pmc->sflist) {
1744
                if (pmc->sfmode != omode)
1745
                        goto done;
1746
        } else if (pmc->sfmode != omode) {
1747
                /* allow mode switches for empty-set filters */
1748
                ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, 0, 0);
1749
                ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0,
1750
                        0, 0);
1751
                pmc->sfmode = omode;
1752
        }
1753
 
1754
        psl = pmc->sflist;
1755
        if (!add) {
1756
                if (!psl)
1757
                        goto done;
1758
                rv = !0;
1759
                for (i=0; i<psl->sl_count; i++) {
1760
                        rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
1761
                                sizeof(__u32));
1762
                        if (rv >= 0)
1763
                                break;
1764
                }
1765
                if (!rv)        /* source not found */
1766
                        goto done;
1767
 
1768
                /* update the interface filter */
1769
                ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
1770
                        &mreqs->imr_sourceaddr, 1);
1771
 
1772
                for (j=i+1; j<psl->sl_count; j++)
1773
                        psl->sl_addr[j-1] = psl->sl_addr[j];
1774
                psl->sl_count--;
1775
                err = 0;
1776
                goto done;
1777
        }
1778
        /* else, add a new source to the filter */
1779
 
1780
        if (psl && psl->sl_count >= sysctl_igmp_max_msf) {
1781
                err = -ENOBUFS;
1782
                goto done;
1783
        }
1784
        if (!psl || psl->sl_count == psl->sl_max) {
1785
                struct ip_sf_socklist *newpsl;
1786
                int count = IP_SFBLOCK;
1787
 
1788
                if (psl)
1789
                        count += psl->sl_max;
1790
                newpsl = (struct ip_sf_socklist *)sock_kmalloc(sk,
1791
                        IP_SFLSIZE(count), GFP_KERNEL);
1792
                if (!newpsl) {
1793
                        err = -ENOBUFS;
1794
                        goto done;
1795
                }
1796
                newpsl->sl_max = count;
1797
                newpsl->sl_count = count - IP_SFBLOCK;
1798
                if (psl) {
1799
                        for (i=0; i<psl->sl_count; i++)
1800
                                newpsl->sl_addr[i] = psl->sl_addr[i];
1801
                        sock_kfree_s(sk, psl, IP_SFLSIZE(psl->sl_max));
1802
                }
1803
                pmc->sflist = psl = newpsl;
1804
        }
1805
        rv = 1; /* > 0 for insert logic below if sl_count is 0 */
1806
        for (i=0; i<psl->sl_count; i++) {
1807
                rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
1808
                        sizeof(__u32));
1809
                if (rv >= 0)
1810
                        break;
1811
        }
1812
        if (rv == 0)             /* address already there is an error */
1813
                goto done;
1814
        for (j=psl->sl_count-1; j>=i; j--)
1815
                psl->sl_addr[j+1] = psl->sl_addr[j];
1816
        psl->sl_addr[i] = mreqs->imr_sourceaddr;
1817
        psl->sl_count++;
1818
        err = 0;
1819
        /* update the interface list */
1820
        ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
1821
                &mreqs->imr_sourceaddr, 1);
1822
done:
1823
        rtnl_shunlock();
1824
        return err;
1825
}
1826
 
1827
int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
1828
{
1829
        int err;
1830
        struct ip_mreqn imr;
1831
        u32 addr = msf->imsf_multiaddr;
1832
        struct ip_mc_socklist *pmc;
1833
        struct in_device *in_dev;
1834
        struct inet_opt *inet = &sk->protinfo.af_inet;
1835
        struct ip_sf_socklist *newpsl, *psl;
1836
 
1837
        if (!MULTICAST(addr))
1838
                return -EINVAL;
1839
        if (msf->imsf_fmode != MCAST_INCLUDE &&
1840
            msf->imsf_fmode != MCAST_EXCLUDE)
1841
                return -EINVAL;
1842
 
1843
        rtnl_shlock();
1844
 
1845
        imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
1846
        imr.imr_address.s_addr = msf->imsf_interface;
1847
        imr.imr_ifindex = ifindex;
1848
        in_dev = ip_mc_find_dev(&imr);
1849
 
1850
        if (!in_dev) {
1851
                err = -ENODEV;
1852
                goto done;
1853
        }
1854
        err = -EADDRNOTAVAIL;
1855
 
1856
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1857
                if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
1858
                    pmc->multi.imr_ifindex == imr.imr_ifindex)
1859
                        break;
1860
        }
1861
        if (!pmc)               /* must have a prior join */
1862
                goto done;
1863
        if (msf->imsf_numsrc) {
1864
                newpsl = (struct ip_sf_socklist *)sock_kmalloc(sk,
1865
                                IP_SFLSIZE(msf->imsf_numsrc), GFP_KERNEL);
1866
                if (!newpsl) {
1867
                        err = -ENOBUFS;
1868
                        goto done;
1869
                }
1870
                newpsl->sl_max = newpsl->sl_count = msf->imsf_numsrc;
1871
                memcpy(newpsl->sl_addr, msf->imsf_slist,
1872
                        msf->imsf_numsrc * sizeof(msf->imsf_slist[0]));
1873
                err = ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
1874
                        msf->imsf_fmode, newpsl->sl_count, newpsl->sl_addr, 0);
1875
                if (err) {
1876
                        sock_kfree_s(sk, newpsl, IP_SFLSIZE(newpsl->sl_max));
1877
                        goto done;
1878
                }
1879
        } else
1880
                newpsl = 0;
1881
        psl = pmc->sflist;
1882
        if (psl) {
1883
                (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
1884
                        psl->sl_count, psl->sl_addr, 0);
1885
                sock_kfree_s(sk, psl, IP_SFLSIZE(psl->sl_max));
1886
        } else
1887
                (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
1888
                        0, 0, 0);
1889
        pmc->sflist = newpsl;
1890
        pmc->sfmode = msf->imsf_fmode;
1891
done:
1892
        rtnl_shunlock();
1893
        return err;
1894
}
1895
 
1896
int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
1897
        struct ip_msfilter *optval, int *optlen)
1898
{
1899
        int err, len, count, copycount;
1900
        struct ip_mreqn imr;
1901
        u32 addr = msf->imsf_multiaddr;
1902
        struct ip_mc_socklist *pmc;
1903
        struct in_device *in_dev;
1904
        struct inet_opt *inet = &sk->protinfo.af_inet;
1905
        struct ip_sf_socklist *psl;
1906
 
1907
        if (!MULTICAST(addr))
1908
                return -EINVAL;
1909
 
1910
        rtnl_shlock();
1911
 
1912
        imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
1913
        imr.imr_address.s_addr = msf->imsf_interface;
1914
        imr.imr_ifindex = 0;
1915
        in_dev = ip_mc_find_dev(&imr);
1916
 
1917
        if (!in_dev) {
1918
                err = -ENODEV;
1919
                goto done;
1920
        }
1921
        err = -EADDRNOTAVAIL;
1922
 
1923
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1924
                if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
1925
                    pmc->multi.imr_ifindex == imr.imr_ifindex)
1926
                        break;
1927
        }
1928
        if (!pmc)               /* must have a prior join */
1929
                goto done;
1930
        msf->imsf_fmode = pmc->sfmode;
1931
        psl = pmc->sflist;
1932
        rtnl_shunlock();
1933
        if (!psl) {
1934
                len = 0;
1935
                count = 0;
1936
        } else {
1937
                count = psl->sl_count;
1938
        }
1939
        copycount = count < msf->imsf_numsrc ? count : msf->imsf_numsrc;
1940
        len = copycount * sizeof(psl->sl_addr[0]);
1941
        msf->imsf_numsrc = count;
1942
        if (put_user(IP_MSFILTER_SIZE(copycount), optlen) ||
1943
            copy_to_user((void *)optval, msf, IP_MSFILTER_SIZE(0))) {
1944
                return -EFAULT;
1945
        }
1946
        if (len &&
1947
            copy_to_user((void *)&optval->imsf_slist[0], psl->sl_addr, len))
1948
                return -EFAULT;
1949
        return 0;
1950
done:
1951
        rtnl_shunlock();
1952
        return err;
1953
}
1954
 
1955
int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
1956
        struct group_filter *optval, int *optlen)
1957
{
1958
        int err, i, count, copycount;
1959
        struct sockaddr_in *psin;
1960
        u32 addr;
1961
        struct ip_mc_socklist *pmc;
1962
        struct inet_opt *inet = &sk->protinfo.af_inet;
1963
        struct ip_sf_socklist *psl;
1964
 
1965
        psin = (struct sockaddr_in *)&gsf->gf_group;
1966
        if (psin->sin_family != AF_INET)
1967
                return -EINVAL;
1968
        addr = psin->sin_addr.s_addr;
1969
        if (!MULTICAST(addr))
1970
                return -EINVAL;
1971
 
1972
        rtnl_shlock();
1973
 
1974
        err = -EADDRNOTAVAIL;
1975
 
1976
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1977
                if (pmc->multi.imr_multiaddr.s_addr == addr &&
1978
                    pmc->multi.imr_ifindex == gsf->gf_interface)
1979
                        break;
1980
        }
1981
        if (!pmc)               /* must have a prior join */
1982
                goto done;
1983
        gsf->gf_fmode = pmc->sfmode;
1984
        psl = pmc->sflist;
1985
        rtnl_shunlock();
1986
        count = psl ? psl->sl_count : 0;
1987
        copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
1988
        gsf->gf_numsrc = count;
1989
        if (put_user(GROUP_FILTER_SIZE(copycount), optlen) ||
1990
            copy_to_user((void *)optval, gsf, GROUP_FILTER_SIZE(0))) {
1991
                return -EFAULT;
1992
        }
1993
        for (i=0; i<copycount; i++) {
1994
                struct sockaddr_in *psin;
1995
                struct sockaddr_storage ss;
1996
 
1997
                psin = (struct sockaddr_in *)&ss;
1998
                memset(&ss, 0, sizeof(ss));
1999
                psin->sin_family = AF_INET;
2000
                psin->sin_addr.s_addr = psl->sl_addr[i];
2001
                if (copy_to_user((void *)&optval->gf_slist[i], &ss, sizeof(ss)))
2002
                        return -EFAULT;
2003
        }
2004
        return 0;
2005
done:
2006
        rtnl_shunlock();
2007
        return err;
2008
}
2009
 
2010
/*
2011
 * check if a multicast source filter allows delivery for a given <src,dst,intf>
2012
 */
2013
int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif)
2014
{
2015
        struct inet_opt *inet = &sk->protinfo.af_inet;
2016
        struct ip_mc_socklist *pmc;
2017
        struct ip_sf_socklist *psl;
2018
        int i;
2019
 
2020
        if (!MULTICAST(loc_addr))
2021
                return 1;
2022
 
2023
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
2024
                if (pmc->multi.imr_multiaddr.s_addr == loc_addr &&
2025
                    pmc->multi.imr_ifindex == dif)
2026
                        break;
2027
        }
2028
        if (!pmc)
2029
                return 1;
2030
        psl = pmc->sflist;
2031
        if (!psl)
2032
                return pmc->sfmode == MCAST_EXCLUDE;
2033
 
2034
        for (i=0; i<psl->sl_count; i++) {
2035
                if (psl->sl_addr[i] == rmt_addr)
2036
                        break;
2037
        }
2038
        if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count)
2039
                return 0;
2040
        if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
2041
                return 0;
2042
        return 1;
2043
}
2044
 
2045
/*
2046
 *      A socket is closing.
2047
 */
2048
 
2049
void ip_mc_drop_socket(struct sock *sk)
2050
{
2051
        struct inet_opt *inet = &sk->protinfo.af_inet;
2052
        struct ip_mc_socklist *iml;
2053
 
2054
        if (inet->mc_list == NULL)
2055
                return;
2056
 
2057
        rtnl_lock();
2058
        while ((iml = inet->mc_list) != NULL) {
2059
                struct in_device *in_dev;
2060
                inet->mc_list = iml->next;
2061
 
2062
                if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
2063
                        (void) ip_mc_leave_src(sk, iml, in_dev);
2064
                        ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
2065
                        in_dev_put(in_dev);
2066
                }
2067
                sock_kfree_s(sk, iml, sizeof(*iml));
2068
 
2069
        }
2070
        rtnl_unlock();
2071
}
2072
 
2073
int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr)
2074
{
2075
        struct ip_mc_list *im;
2076
        struct ip_sf_list *psf;
2077
        int rv = 0;
2078
 
2079
        read_lock(&in_dev->lock);
2080
        for (im=in_dev->mc_list; im; im=im->next) {
2081
                if (im->multiaddr == mc_addr)
2082
                        break;
2083
        }
2084
        /*
2085
         * This should check the protocol and allow all IGMP packets
2086
         * here, but it isn't available in the call from ip_route_output()
2087
         * in 2.4.x. It shouldn't actually matter, since groups joined
2088
         * from within the kernel will have an {exclude, empty} filter.
2089
         * Differs from 2.5.x here.     +-DLS 4/23/03
2090
         */
2091
        if (im) {
2092
                if (src_addr) {
2093
                        for (psf=im->sources; psf; psf=psf->sf_next) {
2094
                                if (psf->sf_inaddr == src_addr)
2095
                                        break;
2096
                        }
2097
                        if (psf)
2098
                                rv = psf->sf_count[MCAST_INCLUDE] ||
2099
                                        psf->sf_count[MCAST_EXCLUDE] !=
2100
                                        im->sfcount[MCAST_EXCLUDE];
2101
                        else
2102
                                rv = im->sfcount[MCAST_EXCLUDE] != 0;
2103
                } else
2104
                        rv = 1;
2105
        }
2106
        read_unlock(&in_dev->lock);
2107
        return rv;
2108
}
2109
 
2110
 
2111
int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length)
2112
{
2113
        off_t pos=0, begin=0;
2114
        struct ip_mc_list *im;
2115
        int len=0;
2116
        struct net_device *dev;
2117
 
2118
        len=sprintf(buffer,"Idx\tDevice    : Count Querier\tGroup    Users Timer\tReporter\n");
2119
 
2120
        read_lock(&dev_base_lock);
2121
        for(dev = dev_base; dev; dev = dev->next) {
2122
                struct in_device *in_dev = in_dev_get(dev);
2123
                char   *querier = "NONE";
2124
 
2125
                if (in_dev == NULL)
2126
                        continue;
2127
 
2128
#ifdef CONFIG_IP_MULTICAST
2129
                querier = IGMP_V1_SEEN(in_dev) ? "V1" : "V2";
2130
#endif
2131
 
2132
                len+=sprintf(buffer+len,"%d\t%-10s: %5d %7s\n",
2133
                             dev->ifindex, dev->name, dev->mc_count, querier);
2134
 
2135
                read_lock(&in_dev->lock);
2136
                for (im = in_dev->mc_list; im; im = im->next) {
2137
                        len+=sprintf(buffer+len,
2138
                                     "\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n",
2139
                                     im->multiaddr, im->users,
2140
                                     im->tm_running, im->timer.expires-jiffies, im->reporter);
2141
 
2142
                        pos=begin+len;
2143
                        if(pos<offset)
2144
                        {
2145
                                len=0;
2146
                                begin=pos;
2147
                        }
2148
                        if(pos>offset+length) {
2149
                                read_unlock(&in_dev->lock);
2150
                                in_dev_put(in_dev);
2151
                                goto done;
2152
                        }
2153
                }
2154
                read_unlock(&in_dev->lock);
2155
                in_dev_put(in_dev);
2156
        }
2157
done:
2158
        read_unlock(&dev_base_lock);
2159
 
2160
        *start=buffer+(offset-begin);
2161
        len-=(offset-begin);
2162
        if(len>length)
2163
                len=length;
2164
        if(len<0)
2165
                len=0;
2166
        return len;
2167
}
2168
 
2169
int ip_mcf_procinfo(char *buffer, char **start, off_t offset, int length)
2170
{
2171
        off_t pos=0, begin=0;
2172
        int len=0;
2173
        int first = 1;
2174
        struct net_device *dev;
2175
 
2176
        read_lock(&dev_base_lock);
2177
        for(dev=dev_base; dev; dev=dev->next) {
2178
                struct in_device *in_dev = in_dev_get(dev);
2179
                struct ip_mc_list *imc;
2180
 
2181
                if (in_dev == NULL)
2182
                        continue;
2183
 
2184
                read_lock(&in_dev->lock);
2185
 
2186
                for (imc=in_dev->mc_list; imc; imc=imc->next) {
2187
                        struct ip_sf_list *psf;
2188
 
2189
                        spin_lock_bh(&imc->lock);
2190
                        for (psf=imc->sources; psf; psf=psf->sf_next) {
2191
                                if (first) {
2192
                                        len += sprintf(buffer+len, "%3s %6s "
2193
                                                "%10s %10s %6s %6s\n", "Idx",
2194
                                                "Device", "MCA", "SRC", "INC",
2195
                                                "EXC");
2196
                                        first = 0;
2197
                                }
2198
                                len += sprintf(buffer+len, "%3d %6.6s 0x%08x "
2199
                                        "0x%08x %6lu %6lu\n", dev->ifindex,
2200
                                        dev->name, ntohl(imc->multiaddr),
2201
                                        ntohl(psf->sf_inaddr),
2202
                                        psf->sf_count[MCAST_INCLUDE],
2203
                                        psf->sf_count[MCAST_EXCLUDE]);
2204
                                pos=begin+len;
2205
                                if(pos<offset)
2206
                                {
2207
                                        len=0;
2208
                                        begin=pos;
2209
                                }
2210
                                if(pos>offset+length) {
2211
                                        spin_unlock_bh(&imc->lock);
2212
                                        read_unlock(&in_dev->lock);
2213
                                        in_dev_put(in_dev);
2214
                                        goto done;
2215
                                }
2216
                        }
2217
                        spin_unlock_bh(&imc->lock);
2218
                }
2219
                read_unlock(&in_dev->lock);
2220
                in_dev_put(in_dev);
2221
        }
2222
done:
2223
        read_unlock(&dev_base_lock);
2224
 
2225
        *start=buffer+(offset-begin);
2226
        len-=(offset-begin);
2227
        if(len>length)
2228
                len=length;
2229
        if(len<0)
2230
                len=0;
2231
        return len;
2232
}
2233
 

powered by: WebSVN 2.1.0

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