patch-2.1.79 linux/net/ipv4/igmp.c
Next file: linux/net/ipv4/ip_forward.c
Previous file: linux/net/ipv4/fib_semantics.c
Back to the patch index
Back to the overall index
- Lines: 206
- Date:
Mon Jan 12 15:28:27 1998
- Orig file:
v2.1.78/linux/net/ipv4/igmp.c
- Orig date:
Mon Dec 1 12:04:16 1997
diff -u --recursive --new-file v2.1.78/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c
@@ -8,7 +8,7 @@
* the older version didn't come out right using gcc 2.5.8, the newer one
* seems to fall out with gcc 2.6.2.
*
- * Version: $Id: igmp.c,v 1.22 1997/10/29 20:27:24 kuznet Exp $
+ * Version: $Id: igmp.c,v 1.24 1997/12/17 20:14:10 kuznet Exp $
*
* Authors:
* Alan Cox <Alan.Cox@linux.org>
@@ -131,19 +131,12 @@
}
}
-extern __inline__ unsigned int random(void)
-{
- static unsigned long seed=152L;
- seed=seed*69069L+1;
- return seed^jiffies;
-}
-
static __inline__ void igmp_start_timer(struct ip_mc_list *im, int max_delay)
{
int tv;
if (im->tm_running)
return;
- tv=random() % max_delay;
+ tv=net_random() % max_delay;
im->timer.expires=jiffies+tv+2;
im->tm_running=1;
add_timer(&im->timer);
@@ -186,7 +179,6 @@
skb->dst = &rt->u.dst;
skb_reserve(skb, (dev->hard_header_len+15)&~15);
- ip_ll_header(skb);
skb->nh.iph = iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)+4);
@@ -342,22 +334,6 @@
#endif
-/*
- * Map a multicast IP onto multicast MAC for type ethernet.
- */
-
-extern __inline__ void ip_mc_map(u32 addr, char *buf)
-{
- addr=ntohl(addr);
- buf[0]=0x01;
- buf[1]=0x00;
- buf[2]=0x5e;
- buf[5]=addr&0xFF;
- addr>>=8;
- buf[4]=addr&0xFF;
- addr>>=8;
- buf[3]=addr&0x7F;
-}
/*
* Add a filter to a device
@@ -365,15 +341,18 @@
static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
{
- char buf[6];
+ char buf[MAX_ADDR_LEN];
struct device *dev = in_dev->dev;
- if (!(dev->flags & IFF_MULTICAST))
- return;
- if (dev->type!=ARPHRD_ETHER && dev->type!=ARPHRD_FDDI)
- return; /* Only do ethernet or FDDI for now */
- ip_mc_map(addr, buf);
- dev_mc_add(dev,buf,ETH_ALEN,0);
+ /* Checking for IFF_MULTICAST here is WRONG-WRONG-WRONG.
+ We will get multicast token leakage, when IFF_MULTICAST
+ is changed. This check should be done in dev->set_multicast_list
+ routine. Something sort of:
+ if (dev->mc_list && dev->flags&IFF_MULTICAST) { do it; }
+ --ANK
+ */
+ if (arp_mc_map(addr, buf, dev, 0) == 0)
+ dev_mc_add(dev,buf,dev->addr_len,0);
}
/*
@@ -382,18 +361,19 @@
static void ip_mc_filter_del(struct in_device *in_dev, u32 addr)
{
- char buf[6];
+ char buf[MAX_ADDR_LEN];
struct device *dev = in_dev->dev;
- if (dev->type!=ARPHRD_ETHER && dev->type!=ARPHRD_FDDI)
- return; /* Only do ethernet or FDDI for now */
- ip_mc_map(addr,buf);
- dev_mc_delete(dev,buf,ETH_ALEN,0);
+ if (arp_mc_map(addr, buf, dev, 0) == 0)
+ dev_mc_delete(dev,buf,dev->addr_len,0);
}
static void igmp_group_dropped(struct ip_mc_list *im)
{
- ip_mc_filter_del(im->interface, im->multiaddr);
+ if (im->loaded) {
+ im->loaded = 0;
+ ip_mc_filter_del(im->interface, im->multiaddr);
+ }
#ifdef CONFIG_IP_MULTICAST
if (LOCAL_MCAST(im->multiaddr))
@@ -410,7 +390,10 @@
static void igmp_group_added(struct ip_mc_list *im)
{
- ip_mc_filter_add(im->interface, im->multiaddr);
+ if (im->loaded == 0) {
+ im->loaded = 1;
+ ip_mc_filter_add(im->interface, im->multiaddr);
+ }
#ifdef CONFIG_IP_MULTICAST
if (LOCAL_MCAST(im->multiaddr))
@@ -458,13 +441,13 @@
im->timer.function=&igmp_timer_expire;
im->unsolicit_count = IGMP_Unsolicited_Report_Count;
im->reporter = 0;
+ im->loaded = 0;
#endif
im->next=in_dev->mc_list;
in_dev->mc_list=im;
- if (in_dev->dev->flags & IFF_UP) {
- igmp_group_added(im);
+ igmp_group_added(im);
+ if (in_dev->dev->flags & IFF_UP)
ip_rt_multicast_event(in_dev);
- }
return;
}
@@ -480,10 +463,9 @@
if (i->multiaddr==addr) {
if (--i->users == 0) {
*ip = i->next;
- if (in_dev->dev->flags & IFF_UP) {
- igmp_group_dropped(i);
+ igmp_group_dropped(i);
+ if (in_dev->dev->flags & IFF_UP)
ip_rt_multicast_event(in_dev);
- }
kfree_s(i, sizeof(*i));
}
return 0;
@@ -500,6 +482,8 @@
for (i=in_dev->mc_list; i; i=i->next)
igmp_group_dropped(i);
+
+ ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
}
/* Device going up */
@@ -508,6 +492,8 @@
{
struct ip_mc_list *i;
+ ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
+
for (i=in_dev->mc_list; i; i=i->next)
igmp_group_added(i);
}
@@ -522,19 +508,11 @@
while ((i = in_dev->mc_list) != NULL) {
in_dev->mc_list = i->next;
+ igmp_group_dropped(i);
kfree_s(i, sizeof(*i));
}
}
-/* Initialize multicasting on an IP interface */
-
-void ip_mc_init_dev(struct in_device *in_dev)
-{
- in_dev->mc_list = NULL;
- in_dev->mr_v1_seen = 0;
- ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
-}
-
static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
{
struct rtable *rt;
@@ -697,9 +675,10 @@
begin=pos;
}
if(pos>offset+length)
- break;
+ goto done;
}
}
+done:
*start=buffer+(offset-begin);
len-=(offset-begin);
if(len>length)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov