linux-old/net/ipv6/mcast.c
<<
>>
Prefs
   1/*
   2 *      Multicast support for IPv6
   3 *      Linux INET6 implementation 
   4 *
   5 *      Authors:
   6 *      Pedro Roque             <pedro_m@yahoo.com>     
   7 *
   8 *      $Id: mcast.c,v 1.38 2001/08/15 07:36:31 davem 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
  82struct 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
  90struct 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
  99struct 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
 122struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
 123struct 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 */
 126static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
 127
 128static struct socket *igmp6_socket;
 129
 130static void igmp6_join_group(struct ifmcaddr6 *ma);
 131static void igmp6_leave_group(struct ifmcaddr6 *ma);
 132static void igmp6_timer_handler(unsigned long data);
 133
 134static void mld_gq_timer_expire(unsigned long data);
 135static void mld_ifc_timer_expire(unsigned long data);
 136static void mld_ifc_event(struct inet6_dev *idev);
 137static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
 138static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *addr);
 139static void mld_clear_delrec(struct inet6_dev *idev);
 140static int sf_setstate(struct ifmcaddr6 *pmc);
 141static void sf_markstate(struct ifmcaddr6 *pmc);
 142static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
 143int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
 144        int sfcount, struct in6_addr *psfsrc, int delta);
 145int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
 146        int sfcount, struct in6_addr *psfsrc, int delta);
 147int 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
 168int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
 169
 170/*
 171 *      socket join on multicast group
 172 */
 173
 174int 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 */
 237int 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
 270struct 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
 304void 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
 335int 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 (pgsr->gsr_interface && 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[i], source,
 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[i], source, 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);
 448done:
 449        read_unlock_bh(&idev->lock);
 450        in6_dev_put(idev);
 451        dev_put(dev);
 452        return err;
 453}
 454
 455int 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;
 519done:
 520        read_unlock_bh(&idev->lock);
 521        in6_dev_put(idev);
 522        dev_put(dev);
 523        return err;
 524}
 525
 526int 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;
 584done:
 585        read_unlock_bh(&idev->lock);
 586        in6_dev_put(idev);
 587        dev_put(dev);
 588        return err;
 589}
 590
 591int 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
 628static 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
 636static 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
 662static 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);
 684done:
 685        ip6_mc_clear_src(mc);
 686        spin_unlock_bh(&mc->mca_lock);
 687}
 688
 689/*
 690 * deleted ifmcaddr6 manipulation
 691 */
 692static 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
 730static 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
 759static 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 */
 796int 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 */
 867static 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
 892int 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 */
 910int 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
 950static 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
 959static 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
 971static 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
 999static 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
1018int 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
1133int 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
1182static 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
1215static int
1216mld_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
1229static 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
1278static 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
1297static 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
1302static 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
1327static 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
1432static 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 */
1467static 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
1485static 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
1558void 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
1630out:
1631        kfree_skb(skb);
1632}
1633
1634static 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
1671int 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 */
1730static 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
1756static 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
1770static 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 */
1795int 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
1855static 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
1874static 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
1897int 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
1913static 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
1925static 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
1934static 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
1947static 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
1956static 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
1974void 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
1998void 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
2012void 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
2041void 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
2072static 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
2118done:
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
2130static 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
2193done:
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
2206int __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
2243void 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}
2251
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.