patch-2.4.4 linux/net/ipv6/mcast.c

Next file: linux/net/ipv6/ndisc.c
Previous file: linux/net/ipv6/ip6_output.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/net/ipv6/mcast.c linux/net/ipv6/mcast.c
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: mcast.c,v 1.33 2000/09/18 05:59:48 davem Exp $
+ *	$Id: mcast.c,v 1.37 2001/04/25 20:46:34 davem Exp $
  *
  *	Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c 
  *
@@ -15,6 +15,11 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+/* Changes:
+ *
+ *	yoshfuji	: fix format of router-alert option
+ */
+
 #define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/module.h>
@@ -392,17 +397,19 @@
 	spin_unlock(&ma->mca_lock);
 }
 
-int igmp6_event_query(struct sk_buff *skb, struct icmp6hdr *hdr, int len)
+int igmp6_event_query(struct sk_buff *skb)
 {
 	struct ifmcaddr6 *ma;
 	struct in6_addr *addrp;
 	unsigned long resptime;
 	struct inet6_dev *idev;
+	struct icmp6hdr *hdr;
 
-
-	if (len < sizeof(struct icmp6hdr) + sizeof(struct in6_addr))
+	if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
 		return -EINVAL;
 
+	hdr = (struct icmp6hdr*) skb->h.raw;
+
 	/* Drop queries with not link local source */
 	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
 		return -EINVAL;
@@ -437,19 +444,22 @@
 }
 
 
-int igmp6_event_report(struct sk_buff *skb, struct icmp6hdr *hdr, int len)
+int igmp6_event_report(struct sk_buff *skb)
 {
 	struct ifmcaddr6 *ma;
 	struct in6_addr *addrp;
 	struct inet6_dev *idev;
+	struct icmp6hdr *hdr;
 
 	/* Our own report looped back. Ignore it. */
 	if (skb->pkt_type == PACKET_LOOPBACK)
 		return 0;
 
-	if (len < sizeof(struct icmp6hdr) + sizeof(struct in6_addr))
+	if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
 		return -EINVAL;
 
+	hdr = (struct icmp6hdr*) skb->h.raw;
+
 	/* Drop reports with not link local source */
 	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
 		return -EINVAL;
@@ -491,7 +501,7 @@
 	struct in6_addr all_routers;
 	int err, len, payload_len, full_len;
 	u8 ra[8] = { IPPROTO_ICMPV6, 0,
-		     IPV6_TLV_ROUTERALERT, 0, 0, 0,
+		     IPV6_TLV_ROUTERALERT, 2, 0, 0,
 		     IPV6_TLV_PADN, 0 };
 
 	snd_addr = addr;
@@ -504,7 +514,7 @@
 	payload_len = len + sizeof(ra);
 	full_len = sizeof(struct ipv6hdr) + payload_len;
 
-	skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 0, 0, &err);
+	skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 0, &err);
 
 	if (skb == NULL)
 		return;
@@ -614,7 +624,6 @@
 void ipv6_mc_down(struct inet6_dev *idev)
 {
 	struct ifmcaddr6 *i;
-	struct in6_addr maddr;
 
 	/* Withdraw multicast list */
 
@@ -622,24 +631,14 @@
 	for (i = idev->mc_list; i; i=i->next)
 		igmp6_group_dropped(i);
 	read_unlock_bh(&idev->lock);
-
-	/* Delete all-nodes address. */
-
-	ipv6_addr_all_nodes(&maddr);
-	ipv6_dev_mc_dec(idev->dev, &maddr);
 }
 
+
 /* Device going up */
 
 void ipv6_mc_up(struct inet6_dev *idev)
 {
 	struct ifmcaddr6 *i;
-	struct in6_addr maddr;
-
-	/* Add all-nodes address. */
-
-	ipv6_addr_all_nodes(&maddr);
-	ipv6_dev_mc_inc(idev->dev, &maddr);
 
 	/* Install multicast list, except for all-nodes (already installed) */
 
@@ -649,6 +648,17 @@
 	read_unlock_bh(&idev->lock);
 }
 
+/* IPv6 device initialization. */
+
+void ipv6_mc_init_dev(struct inet6_dev *idev)
+{
+	struct in6_addr maddr;
+
+	/* Add all-nodes address. */
+	ipv6_addr_all_nodes(&maddr);
+	ipv6_dev_mc_inc(idev->dev, &maddr);
+}
+
 /*
  *	Device is about to be destroyed: clean up.
  */
@@ -656,6 +666,11 @@
 void ipv6_mc_destroy_dev(struct inet6_dev *idev)
 {
 	struct ifmcaddr6 *i;
+	struct in6_addr maddr;
+
+	/* Delete all-nodes address. */
+	ipv6_addr_all_nodes(&maddr);
+	ipv6_dev_mc_dec(idev->dev, &maddr);
 
 	write_lock_bh(&idev->lock);
 	while ((i = idev->mc_list) != NULL) {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)