patch-2.4.25 linux-2.4.25/net/ipv6/mcast.c
Next file: linux-2.4.25/net/ipv6/netfilter/ip6_queue.c
Previous file: linux-2.4.25/net/ipv4/tcp.c
Back to the patch index
Back to the overall index
- Lines: 151
- Date:
2004-02-18 05:36:32.000000000 -0800
- Orig file:
linux-2.4.24/net/ipv6/mcast.c
- Orig date:
2003-11-28 10:26:21.000000000 -0800
diff -urN linux-2.4.24/net/ipv6/mcast.c linux-2.4.25/net/ipv6/mcast.c
@@ -45,6 +45,9 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv6.h>
+
#include <net/sock.h>
#include <net/snmp.h>
@@ -368,9 +371,9 @@
goto done;
} else if (pmc->sfmode != omode) {
/* allow mode switches for empty-set filters */
+ ip6_mc_add_src(idev, group, omode, 0, 0, 0);
ip6_mc_del_src(idev, group, pmc->sfmode, 0, 0, 0);
pmc->sfmode = omode;
- ip6_mc_del_src(idev, group, pmc->sfmode, 0, 0, 0);
}
psl = pmc->sflist;
@@ -664,7 +667,7 @@
goto done;
spin_unlock_bh(&mc->mca_lock);
- if (dev->flags&IFF_UP)
+ if (!mc->idev->dead)
igmp6_leave_group(mc);
spin_lock_bh(&mc->mca_lock);
@@ -911,20 +914,24 @@
break;
}
if (mc) {
- struct ip6_sf_list *psf;
+ if (!ipv6_addr_any(src_addr)) {
+ struct ip6_sf_list *psf;
- spin_lock_bh(&mc->mca_lock);
- for (psf=mc->mca_sources; psf; psf=psf->sf_next) {
- if (ipv6_addr_cmp(&psf->sf_addr, src_addr) == 0)
- break;
- }
- if (psf)
- rv = psf->sf_count[MCAST_INCLUDE] ||
- psf->sf_count[MCAST_EXCLUDE] !=
- mc->mca_sfcount[MCAST_EXCLUDE];
- else
- rv = mc->mca_sfcount[MCAST_EXCLUDE] != 0;
- spin_unlock_bh(&mc->mca_lock);
+ spin_lock_bh(&mc->mca_lock);
+ for (psf=mc->mca_sources;psf;psf=psf->sf_next) {
+ if (ipv6_addr_cmp(&psf->sf_addr,
+ src_addr) == 0)
+ break;
+ }
+ if (psf)
+ rv = psf->sf_count[MCAST_INCLUDE] ||
+ psf->sf_count[MCAST_EXCLUDE] !=
+ mc->mca_sfcount[MCAST_EXCLUDE];
+ else
+ rv = mc->mca_sfcount[MCAST_EXCLUDE] !=0;
+ spin_unlock_bh(&mc->mca_lock);
+ } else
+ rv = 1; /* don't filter unspecified source */
}
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
@@ -957,8 +964,9 @@
{
unsigned long delay = resptime;
- /* Do not start timer for addresses with link/host scope */
- if (ipv6_addr_type(&ma->mca_addr)&(IPV6_ADDR_LINKLOCAL|IPV6_ADDR_LOOPBACK))
+ /* Do not start timer for these addresses */
+ if (ipv6_addr_is_ll_all_nodes(&ma->mca_addr) ||
+ IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
return;
if (del_timer(&ma->mca_timer)) {
@@ -976,6 +984,7 @@
ma->mca_timer.expires = jiffies + delay;
if (!mod_timer(&ma->mca_timer, jiffies + delay))
atomic_inc(&ma->mca_refcnt);
+ ma->mca_flags |= MAF_TIMER_RUNNING;
spin_unlock(&ma->mca_lock);
}
@@ -1039,7 +1048,7 @@
/* MLDv1 router present */
/* Translate milliseconds to jiffies */
- max_delay = ntohs(hdr->icmp6_maxdelay)*(HZ/10);
+ max_delay = (ntohs(hdr->icmp6_maxdelay)*HZ)/1000;
switchback = (idev->mc_qrv + 1) * max_delay;
idev->mc_v1_seen = jiffies + switchback;
@@ -1051,7 +1060,7 @@
/* clear deleted report items */
mld_clear_delrec(idev);
} else if (len >= 28) {
- max_delay = MLDV2_MRC(ntohs(mlh2->mrc))*(HZ/10);
+ max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
if (!max_delay)
max_delay = 1;
idev->mc_maxdelay = max_delay;
@@ -1262,7 +1271,7 @@
{
struct ipv6hdr *pip6 = skb->nh.ipv6h;
struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
- int payload_len, mldlen;
+ int payload_len, mldlen, err;
payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
sizeof(struct ipv6hdr);
@@ -1271,8 +1280,10 @@
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
- dev_queue_xmit(skb);
- ICMP6_INC_STATS(Icmp6OutMsgs);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+ dev_queue_xmit);
+ if (!err)
+ ICMP6_INC_STATS(Icmp6OutMsgs);
}
static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
@@ -1596,12 +1607,16 @@
IPPROTO_ICMPV6,
csum_partial((__u8 *) hdr, len, 0));
- dev_queue_xmit(skb);
- if (type == ICMPV6_MGM_REDUCTION)
- ICMP6_INC_STATS(Icmp6OutGroupMembReductions);
- else
- ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
- ICMP6_INC_STATS(Icmp6OutMsgs);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+ dev_queue_xmit);
+ if (!err) {
+ if (type == ICMPV6_MGM_REDUCTION)
+ ICMP6_INC_STATS(Icmp6OutGroupMembReductions);
+ else
+ ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
+ ICMP6_INC_STATS(Icmp6OutMsgs);
+ }
+
return;
out:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)