2 * Multicast support for IPv6
3 * Linux INET6 implementation
6 * Pedro Roque <roque@di.fc.ul.pt>
8 * $Id: mcast.c,v 1.1.1.1 2005/04/11 02:51:13 jack Exp $
10 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
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.
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.
29 #define __NO_VERSION__
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/errno.h>
33 #include <linux/types.h>
34 #include <linux/string.h>
35 #include <linux/socket.h>
36 #include <linux/sockios.h>
37 #include <linux/sched.h>
38 #include <linux/net.h>
39 #include <linux/in6.h>
40 #include <linux/netdevice.h>
41 #include <linux/if_arp.h>
42 #include <linux/route.h>
43 #include <linux/init.h>
44 #include <linux/proc_fs.h>
50 #include <net/protocol.h>
51 #include <net/if_inet6.h>
52 #include <net/ndisc.h>
53 #include <net/addrconf.h>
54 #include <net/ip6_route.h>
56 #include <net/checksum.h>
58 /* Set to 3 to get tracing... */
62 #define MDBG(x) printk x
67 /* Big mc list lock for all the sockets */
68 static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
70 static struct socket *igmp6_socket;
72 static void igmp6_join_group(struct ifmcaddr6 *ma);
73 static void igmp6_leave_group(struct ifmcaddr6 *ma);
74 void igmp6_timer_handler(unsigned long data);
76 #define IGMP6_UNSOLICITED_IVAL (10*HZ)
79 * socket join on multicast group
82 int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
84 struct net_device *dev = NULL;
85 struct ipv6_mc_socklist *mc_lst;
86 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
89 if (!(ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST))
92 mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
98 memcpy(&mc_lst->addr, addr, sizeof(struct in6_addr));
102 rt = rt6_lookup(addr, NULL, 0, 0);
106 dst_release(&rt->u.dst);
109 dev = dev_get_by_index(ifindex);
112 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
116 mc_lst->ifindex = dev->ifindex;
119 * now add/increase the group membership on the device
122 err = ipv6_dev_mc_inc(dev, addr);
125 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
130 write_lock_bh(&ipv6_sk_mc_lock);
131 mc_lst->next = np->ipv6_mc_list;
132 np->ipv6_mc_list = mc_lst;
133 write_unlock_bh(&ipv6_sk_mc_lock);
141 * socket leave on multicast group
143 int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
145 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
146 struct ipv6_mc_socklist *mc_lst, **lnk;
148 write_lock_bh(&ipv6_sk_mc_lock);
149 for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) {
150 if (mc_lst->ifindex == ifindex &&
151 ipv6_addr_cmp(&mc_lst->addr, addr) == 0) {
152 struct net_device *dev;
155 write_unlock_bh(&ipv6_sk_mc_lock);
157 if ((dev = dev_get_by_index(ifindex)) != NULL) {
158 ipv6_dev_mc_dec(dev, &mc_lst->addr);
161 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
165 write_unlock_bh(&ipv6_sk_mc_lock);
170 void ipv6_sock_mc_close(struct sock *sk)
172 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
173 struct ipv6_mc_socklist *mc_lst;
175 write_lock_bh(&ipv6_sk_mc_lock);
176 while ((mc_lst = np->ipv6_mc_list) != NULL) {
177 struct net_device *dev;
179 np->ipv6_mc_list = mc_lst->next;
180 write_unlock_bh(&ipv6_sk_mc_lock);
182 dev = dev_get_by_index(mc_lst->ifindex);
184 ipv6_dev_mc_dec(dev, &mc_lst->addr);
188 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
190 write_lock_bh(&ipv6_sk_mc_lock);
192 write_unlock_bh(&ipv6_sk_mc_lock);
195 int inet6_mc_check(struct sock *sk, struct in6_addr *addr)
197 struct ipv6_mc_socklist *mc;
199 read_lock(&ipv6_sk_mc_lock);
200 for (mc = sk->net_pinfo.af_inet6.ipv6_mc_list; mc; mc=mc->next) {
201 if (ipv6_addr_cmp(&mc->addr, addr) == 0) {
202 read_unlock(&ipv6_sk_mc_lock);
206 read_unlock(&ipv6_sk_mc_lock);
211 static void ma_put(struct ifmcaddr6 *mc)
213 if (atomic_dec_and_test(&mc->mca_refcnt)) {
214 in6_dev_put(mc->idev);
219 static int igmp6_group_added(struct ifmcaddr6 *mc)
221 struct net_device *dev = mc->idev->dev;
222 char buf[MAX_ADDR_LEN];
224 spin_lock_bh(&mc->mca_lock);
225 if (!(mc->mca_flags&MAF_LOADED)) {
226 mc->mca_flags |= MAF_LOADED;
227 if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
228 dev_mc_add(dev, buf, dev->addr_len, 0);
230 spin_unlock_bh(&mc->mca_lock);
232 if (dev->flags&IFF_UP)
233 igmp6_join_group(mc);
237 static int igmp6_group_dropped(struct ifmcaddr6 *mc)
239 struct net_device *dev = mc->idev->dev;
240 char buf[MAX_ADDR_LEN];
242 spin_lock_bh(&mc->mca_lock);
243 if (mc->mca_flags&MAF_LOADED) {
244 mc->mca_flags &= ~MAF_LOADED;
245 if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
246 dev_mc_delete(dev, buf, dev->addr_len, 0);
248 spin_unlock_bh(&mc->mca_lock);
250 if (dev->flags&IFF_UP)
251 igmp6_leave_group(mc);
257 * device multicast group inc (add if not found)
259 int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
261 struct ifmcaddr6 *mc;
262 struct inet6_dev *idev;
264 idev = in6_dev_get(dev);
269 write_lock_bh(&idev->lock);
271 write_unlock_bh(&idev->lock);
276 for (mc = idev->mc_list; mc; mc = mc->next) {
277 if (ipv6_addr_cmp(&mc->mca_addr, addr) == 0) {
279 write_unlock_bh(&idev->lock);
286 * not found: create a new one.
289 mc = kmalloc(sizeof(struct ifmcaddr6), GFP_ATOMIC);
292 write_unlock_bh(&idev->lock);
297 memset(mc, 0, sizeof(struct ifmcaddr6));
298 mc->mca_timer.function = igmp6_timer_handler;
299 mc->mca_timer.data = (unsigned long) mc;
301 memcpy(&mc->mca_addr, addr, sizeof(struct in6_addr));
304 atomic_set(&mc->mca_refcnt, 2);
305 mc->mca_lock = SPIN_LOCK_UNLOCKED;
307 mc->next = idev->mc_list;
309 write_unlock_bh(&idev->lock);
311 igmp6_group_added(mc);
317 * device multicast group del
319 int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr)
321 struct inet6_dev *idev;
322 struct ifmcaddr6 *ma, **map;
324 idev = in6_dev_get(dev);
328 write_lock_bh(&idev->lock);
329 for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) {
330 if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0) {
331 if (--ma->mca_users == 0) {
333 write_unlock_bh(&idev->lock);
335 igmp6_group_dropped(ma);
341 write_unlock_bh(&idev->lock);
346 write_unlock_bh(&idev->lock);
353 * check if the interface/address pair is valid
355 int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *addr)
357 struct inet6_dev *idev;
358 struct ifmcaddr6 *mc;
360 idev = in6_dev_get(dev);
362 read_lock_bh(&idev->lock);
363 for (mc = idev->mc_list; mc; mc=mc->next) {
364 if (ipv6_addr_cmp(&mc->mca_addr, addr) == 0) {
365 read_unlock_bh(&idev->lock);
370 read_unlock_bh(&idev->lock);
377 * IGMP handling (alias multicast ICMPv6 messages)
380 static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime)
382 unsigned long delay = resptime;
384 /* Do not start timer for addresses with link/host scope */
385 if (ipv6_addr_type(&ma->mca_addr)&(IPV6_ADDR_LINKLOCAL|IPV6_ADDR_LOOPBACK))
388 spin_lock(&ma->mca_lock);
389 if (del_timer(&ma->mca_timer)) {
390 atomic_dec(&ma->mca_refcnt);
391 delay = ma->mca_timer.expires - jiffies;
394 if (delay >= resptime) {
396 delay = net_random() % resptime;
401 ma->mca_timer.expires = jiffies + delay;
402 if (!mod_timer(&ma->mca_timer, jiffies + delay))
403 atomic_inc(&ma->mca_refcnt);
404 spin_unlock(&ma->mca_lock);
407 int igmp6_event_query(struct sk_buff *skb)
409 struct ifmcaddr6 *ma;
410 struct in6_addr *addrp;
411 unsigned long resptime;
412 struct inet6_dev *idev;
413 struct icmp6hdr *hdr;
416 if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
419 hdr = (struct icmp6hdr*) skb->h.raw;
421 /* Drop queries with not link local source */
422 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
425 resptime = ntohs(hdr->icmp6_maxdelay);
426 /* Translate milliseconds to jiffies */
427 resptime = (resptime<<10)/(1024000/HZ);
429 addrp = (struct in6_addr *) (hdr + 1);
430 addr_type = ipv6_addr_type(addrp);
432 if (addr_type != IPV6_ADDR_ANY &&
433 !(addr_type&IPV6_ADDR_MULTICAST))
436 idev = in6_dev_get(skb->dev);
441 read_lock(&idev->lock);
442 if (addr_type == IPV6_ADDR_ANY) {
443 for (ma = idev->mc_list; ma; ma=ma->next)
444 igmp6_group_queried(ma, resptime);
446 for (ma = idev->mc_list; ma; ma=ma->next) {
447 if (ipv6_addr_cmp(addrp, &ma->mca_addr) == 0) {
448 igmp6_group_queried(ma, resptime);
453 read_unlock(&idev->lock);
460 int igmp6_event_report(struct sk_buff *skb)
462 struct ifmcaddr6 *ma;
463 struct in6_addr *addrp;
464 struct inet6_dev *idev;
465 struct icmp6hdr *hdr;
468 /* Our own report looped back. Ignore it. */
469 if (skb->pkt_type == PACKET_LOOPBACK)
472 if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
475 hdr = (struct icmp6hdr*) skb->h.raw;
477 /* Drop reports with not link local source */
478 addr_type = ipv6_addr_type(&skb->nh.ipv6h->saddr);
479 if (addr_type != IPV6_ADDR_ANY &&
480 !(addr_type&IPV6_ADDR_LINKLOCAL))
483 addrp = (struct in6_addr *) (hdr + 1);
485 idev = in6_dev_get(skb->dev);
490 * Cancel the timer for this group
493 read_lock(&idev->lock);
494 for (ma = idev->mc_list; ma; ma=ma->next) {
495 if (ipv6_addr_cmp(&ma->mca_addr, addrp) == 0) {
496 spin_lock(&ma->mca_lock);
497 if (del_timer(&ma->mca_timer))
498 atomic_dec(&ma->mca_refcnt);
499 ma->mca_flags &= ~(MAF_LAST_REPORTER|MAF_TIMER_RUNNING);
500 spin_unlock(&ma->mca_lock);
504 read_unlock(&idev->lock);
509 void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
511 struct sock *sk = igmp6_socket->sk;
513 struct icmp6hdr *hdr;
514 struct in6_addr *snd_addr;
515 struct in6_addr *addrp;
516 struct in6_addr addr_buf;
517 struct in6_addr all_routers;
518 int err, len, payload_len, full_len;
519 u8 ra[8] = { IPPROTO_ICMPV6, 0,
520 IPV6_TLV_ROUTERALERT, 2, 0, 0,
524 if (type == ICMPV6_MGM_REDUCTION) {
525 snd_addr = &all_routers;
526 ipv6_addr_all_routers(&all_routers);
529 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
530 payload_len = len + sizeof(ra);
531 full_len = sizeof(struct ipv6hdr) + payload_len;
533 skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 0, &err);
538 skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
539 if (dev->hard_header) {
540 unsigned char ha[MAX_ADDR_LEN];
541 ndisc_mc_map(snd_addr, ha, dev, 1);
542 if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
546 if (ipv6_get_lladdr(dev, &addr_buf)) {
547 /* <draft-ietf-magma-mld-source-02.txt>:
548 * use unspecified address as the source address
549 * when a valid link-local address is not available.
551 memset(&addr_buf, 0, sizeof(addr_buf));
554 ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len);
556 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
558 hdr = (struct icmp6hdr *) skb_put(skb, sizeof(struct icmp6hdr));
559 memset(hdr, 0, sizeof(struct icmp6hdr));
560 hdr->icmp6_type = type;
562 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr));
563 ipv6_addr_copy(addrp, addr);
565 hdr->icmp6_cksum = csum_ipv6_magic(&addr_buf, snd_addr, len,
567 csum_partial((__u8 *) hdr, len, 0));
570 if (type == ICMPV6_MGM_REDUCTION)
571 ICMP6_INC_STATS(Icmp6OutGroupMembReductions);
573 ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
574 ICMP6_INC_STATS(Icmp6OutMsgs);
581 static void igmp6_join_group(struct ifmcaddr6 *ma)
585 if (IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL ||
586 ipv6_addr_is_ll_all_nodes(&ma->mca_addr))
589 igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
591 delay = net_random() % IGMP6_UNSOLICITED_IVAL;
593 spin_lock_bh(&ma->mca_lock);
594 if (del_timer(&ma->mca_timer)) {
595 atomic_dec(&ma->mca_refcnt);
596 delay = ma->mca_timer.expires - jiffies;
599 if (!mod_timer(&ma->mca_timer, jiffies + delay))
600 atomic_inc(&ma->mca_refcnt);
601 ma->mca_flags |= MAF_TIMER_RUNNING | MAF_LAST_REPORTER;
602 spin_unlock_bh(&ma->mca_lock);
605 static void igmp6_leave_group(struct ifmcaddr6 *ma)
607 if (IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL ||
608 ipv6_addr_is_ll_all_nodes(&ma->mca_addr))
611 if (ma->mca_flags & MAF_LAST_REPORTER)
612 igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REDUCTION);
614 spin_lock_bh(&ma->mca_lock);
615 if (del_timer(&ma->mca_timer))
616 atomic_dec(&ma->mca_refcnt);
617 spin_unlock_bh(&ma->mca_lock);
620 void igmp6_timer_handler(unsigned long data)
622 struct ifmcaddr6 *ma = (struct ifmcaddr6 *) data;
624 igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
626 spin_lock(&ma->mca_lock);
627 ma->mca_flags |= MAF_LAST_REPORTER;
628 ma->mca_flags &= ~MAF_TIMER_RUNNING;
629 spin_unlock(&ma->mca_lock);
633 /* Device going down */
635 void ipv6_mc_down(struct inet6_dev *idev)
639 /* Withdraw multicast list */
641 read_lock_bh(&idev->lock);
642 for (i = idev->mc_list; i; i=i->next)
643 igmp6_group_dropped(i);
644 read_unlock_bh(&idev->lock);
648 /* Device going up */
650 void ipv6_mc_up(struct inet6_dev *idev)
654 /* Install multicast list, except for all-nodes (already installed) */
656 read_lock_bh(&idev->lock);
657 for (i = idev->mc_list; i; i=i->next)
658 igmp6_group_added(i);
659 read_unlock_bh(&idev->lock);
662 /* IPv6 device initialization. */
664 void ipv6_mc_init_dev(struct inet6_dev *idev)
666 struct in6_addr maddr;
668 /* Add all-nodes address. */
669 ipv6_addr_all_nodes(&maddr);
670 ipv6_dev_mc_inc(idev->dev, &maddr);
674 * Device is about to be destroyed: clean up.
677 void ipv6_mc_destroy_dev(struct inet6_dev *idev)
680 struct in6_addr maddr;
682 /* Delete all-nodes address. */
683 ipv6_addr_all_nodes(&maddr);
684 ipv6_dev_mc_dec(idev->dev, &maddr);
686 write_lock_bh(&idev->lock);
687 while ((i = idev->mc_list) != NULL) {
688 idev->mc_list = i->next;
689 write_unlock_bh(&idev->lock);
691 igmp6_group_dropped(i);
694 write_lock_bh(&idev->lock);
696 write_unlock_bh(&idev->lock);
699 #ifdef CONFIG_PROC_FS
700 static int igmp6_read_proc(char *buffer, char **start, off_t offset,
701 int length, int *eof, void *data)
703 off_t pos=0, begin=0;
704 struct ifmcaddr6 *im;
706 struct net_device *dev;
708 read_lock(&dev_base_lock);
709 for (dev = dev_base; dev; dev = dev->next) {
710 struct inet6_dev *idev;
712 if ((idev = in6_dev_get(dev)) == NULL)
715 read_lock_bh(&idev->lock);
716 for (im = idev->mc_list; im; im = im->next) {
719 len += sprintf(buffer+len,"%-4d %-15s ", dev->ifindex, dev->name);
722 len += sprintf(buffer+len, "%02x", im->mca_addr.s6_addr[i]);
724 len+=sprintf(buffer+len,
728 (im->mca_flags&MAF_TIMER_RUNNING) ? im->mca_timer.expires-jiffies : 0);
735 if (pos > offset+length) {
736 read_unlock_bh(&idev->lock);
741 read_unlock_bh(&idev->lock);
747 read_unlock(&dev_base_lock);
749 *start=buffer+(offset-begin);
759 int __init igmp6_init(struct net_proto_family *ops)
764 igmp6_socket = sock_alloc();
765 if (igmp6_socket == NULL) {
767 "Failed to create the IGMP6 control socket.\n");
770 igmp6_socket->inode->i_uid = 0;
771 igmp6_socket->inode->i_gid = 0;
772 igmp6_socket->type = SOCK_RAW;
774 if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) {
776 "Failed to initialize the IGMP6 control socket (err %d).\n",
778 sock_release(igmp6_socket);
779 igmp6_socket = NULL; /* For safety. */
783 sk = igmp6_socket->sk;
784 sk->allocation = GFP_ATOMIC;
785 sk->prot->unhash(sk);
787 sk->net_pinfo.af_inet6.hop_limit = 1;
788 #ifdef CONFIG_PROC_FS
789 create_proc_read_entry("net/igmp6", 0, 0, igmp6_read_proc, NULL);
795 void igmp6_cleanup(void)
797 sock_release(igmp6_socket);
798 igmp6_socket = NULL; /* for safety */
799 #ifdef CONFIG_PROC_FS
800 remove_proc_entry("net/igmp6", 0);