netdev
[Top] [All Lists]

Re: Source Specific Query of MLDv2 [PATCH]

To: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@xxxxxxxxxxxxxx>
Subject: Re: Source Specific Query of MLDv2 [PATCH]
From: David Stevens <dlstevens@xxxxxxxxxx>
Date: Wed, 11 Feb 2004 14:00:39 -0700
Cc: davem@xxxxxxxxxx, hibi665@xxxxxxx, netdev@xxxxxxxxxxx, netdev-bounce@xxxxxxxxxxx, yoshfuji@xxxxxxxxxxxxxx
In-reply-to: <20040211.160152.48476158.yoshfuji@xxxxxxxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx

Ok, here's what I hope is the final version of the patch, so we can
finally put this to bed. :-)

+-DLS

diff -ruN linux-2.6.2/include/net/addrconf.h linux-2.6.2F2/include/net/addrconf.h
--- linux-2.6.2/include/net/addrconf.h 2004-02-03 19:44:17.000000000 -0800
+++ linux-2.6.2F2/include/net/addrconf.h 2004-02-10 15:17:00.000000000 -0800
@@ -98,6 +98,7 @@

extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
struct in6_addr *src_addr);
+extern int ipv6_is_mld(struct sk_buff *skb);

extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len);

diff -ruN linux-2.6.2/net/ipv6/ip6_input.c linux-2.6.2F2/net/ipv6/ip6_input.c
--- linux-2.6.2/net/ipv6/ip6_input.c 2004-02-03 19:44:14.000000000 -0800
+++ linux-2.6.2F2/net/ipv6/ip6_input.c 2004-02-11 12:34:27.000000000 -0800
@@ -168,11 +168,19 @@

smp_read_barrier_depends();
if (ipprot->flags & INET6_PROTO_FINAL) {
+ struct ipv6hdr *hdr;
+
if (!cksum_sub && skb->ip_summed == CHECKSUM_HW) {
skb->csum = csum_sub(skb->csum,
csum_partial(skb->nh.raw, skb->h.raw-skb->nh.raw, 0));
cksum_sub++;
}
+ hdr = skb->nh.ipv6h;
+ if (ipv6_addr_is_multicast(&hdr->daddr) &&
+ !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
+ &hdr->saddr) &&
+ !ipv6_is_mld(skb))
+ goto discard;
}
if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -211,15 +219,14 @@

int ip6_mc_input(struct sk_buff *skb)
{
- struct ipv6hdr *hdr;
- int deliver = 0;
- int discard = 1;
+ struct ipv6hdr *hdr;
+ int deliver;

IP6_INC_STATS_BH(Ip6InMcastPkts);

hdr = skb->nh.ipv6h;
- if (ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, &hdr->saddr))
- deliver = 1;
+ deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
+ ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);

/*
* IPv6 multicast router mode isnt currently supported.
@@ -238,23 +245,21 @@

if (deliver) {
skb2 = skb_clone(skb, GFP_ATOMIC);
+ dst_output(skb2);
} else {
- discard = 0;
- skb2 = skb;
+ dst_output(skb);
+ return 0;
}
-
- dst_output(skb2);
}
}
#endif

- if (deliver) {
- discard = 0;
+ if (likely(deliver)) {
ip6_input(skb);
+ return 0;
}
-
- if (discard)
- kfree_skb(skb);
+ /* discard */
+ kfree_skb(skb);

return 0;
}
diff -ruN linux-2.6.2/net/ipv6/mcast.c linux-2.6.2F2/net/ipv6/mcast.c
--- linux-2.6.2/net/ipv6/mcast.c 2004-02-03 19:44:28.000000000 -0800
+++ linux-2.6.2F2/net/ipv6/mcast.c 2004-02-11 12:34:34.000000000 -0800
@@ -901,6 +901,30 @@
}

/*
+ * identify MLD packets for MLD filter exceptions
+ */
+int ipv6_is_mld(struct sk_buff *skb)
+{
+ struct icmp6hdr *pic;
+
+ if (!pskb_may_pull(skb, sizeof(struct icmp6hdr)))
+ return 0;
+
+ pic = (struct icmp6hdr *)skb->h.raw;
+
+ switch (pic->icmp6_type) {
+ case ICMPV6_MGM_QUERY:
+ case ICMPV6_MGM_REPORT:
+ case ICMPV6_MGM_REDUCTION:
+ case ICMPV6_MLD2_REPORT:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
* check if the interface/address pair is valid
*/
int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
@@ -918,7 +942,7 @@
break;
}
if (mc) {
- if (!ipv6_addr_any(src_addr)) {
+ if (src_addr && !ipv6_addr_any(src_addr)) {
struct ip6_sf_list *psf;

spin_lock_bh(&mc->mca_lock);
(See attached file: mldx5.patch)

Attachment: mldx5.patch
Description: Binary data

<Prev in Thread] Current Thread [Next in Thread>