Commit 3fba5a8b authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NET]: dev_mcast: switch to generic net_device address lists

Use generic net_device address lists for multicast list handling.
Some defines are used to keep drivers working.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf742482
...@@ -190,14 +190,11 @@ struct dev_addr_list ...@@ -190,14 +190,11 @@ struct dev_addr_list
* We tag multicasts with these structures. * We tag multicasts with these structures.
*/ */
struct dev_mc_list #define dev_mc_list dev_addr_list
{ #define dmi_addr da_addr
struct dev_mc_list *next; #define dmi_addrlen da_addrlen
__u8 dmi_addr[MAX_ADDR_LEN]; #define dmi_users da_users
unsigned char dmi_addrlen; #define dmi_gusers da_gusers
int dmi_users;
int dmi_gusers;
};
struct hh_cache struct hh_cache
{ {
...@@ -400,7 +397,7 @@ struct net_device ...@@ -400,7 +397,7 @@ struct net_device
unsigned char addr_len; /* hardware address length */ unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */ unsigned short dev_id; /* for shared network cards */
struct dev_mc_list *mc_list; /* Multicast mac addresses */ struct dev_addr_list *mc_list; /* Multicast mac addresses */
int mc_count; /* Number of installed mcasts */ int mc_count; /* Number of installed mcasts */
int promiscuity; int promiscuity;
int allmulti; int allmulti;
......
...@@ -102,47 +102,20 @@ void dev_mc_upload(struct net_device *dev) ...@@ -102,47 +102,20 @@ void dev_mc_upload(struct net_device *dev)
int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
{ {
int err = 0; int err;
struct dev_mc_list *dmi, **dmip;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
err = __dev_addr_delete(&dev->mc_list, addr, alen, glbl);
for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { if (!err) {
/*
* Find the entry we want to delete. The device could
* have variable length entries so check these too.
*/
if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
alen == dmi->dmi_addrlen) {
if (glbl) {
int old_glbl = dmi->dmi_gusers;
dmi->dmi_gusers = 0;
if (old_glbl == 0)
break;
}
if (--dmi->dmi_users)
goto done;
/*
* Last user. So delete the entry.
*/
*dmip = dmi->next;
dev->mc_count--; dev->mc_count--;
kfree(dmi);
/* /*
* We have altered the list, so the card * We have altered the list, so the card
* loaded filter is now wrong. Fix it * loaded filter is now wrong. Fix it
*/ */
__dev_mc_upload(dev);
netif_tx_unlock_bh(dev); __dev_mc_upload(dev);
return 0;
}
} }
err = -ENOENT;
done:
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return err; return err;
} }
...@@ -153,46 +126,15 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) ...@@ -153,46 +126,15 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
{ {
int err = 0; int err;
struct dev_mc_list *dmi, *dmi1;
dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { err = __dev_addr_add(&dev->mc_list, addr, alen, glbl);
if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && if (!err) {
dmi->dmi_addrlen == alen) {
if (glbl) {
int old_glbl = dmi->dmi_gusers;
dmi->dmi_gusers = 1;
if (old_glbl)
goto done;
}
dmi->dmi_users++;
goto done;
}
}
if ((dmi = dmi1) == NULL) {
netif_tx_unlock_bh(dev);
return -ENOMEM;
}
memcpy(dmi->dmi_addr, addr, alen);
dmi->dmi_addrlen = alen;
dmi->next = dev->mc_list;
dmi->dmi_users = 1;
dmi->dmi_gusers = glbl ? 1 : 0;
dev->mc_list = dmi;
dev->mc_count++; dev->mc_count++;
__dev_mc_upload(dev); __dev_mc_upload(dev);
}
netif_tx_unlock_bh(dev);
return 0;
done:
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
kfree(dmi1);
return err; return err;
} }
...@@ -203,16 +145,8 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) ...@@ -203,16 +145,8 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
void dev_mc_discard(struct net_device *dev) void dev_mc_discard(struct net_device *dev)
{ {
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
__dev_addr_discard(&dev->mc_list);
while (dev->mc_list != NULL) {
struct dev_mc_list *tmp = dev->mc_list;
dev->mc_list = tmp->next;
if (tmp->dmi_users > tmp->dmi_gusers)
printk("dev_mc_discard: multicast leakage! dmi_users=%d\n", tmp->dmi_users);
kfree(tmp);
}
dev->mc_count = 0; dev->mc_count = 0;
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
...@@ -244,7 +178,7 @@ static void dev_mc_seq_stop(struct seq_file *seq, void *v) ...@@ -244,7 +178,7 @@ static void dev_mc_seq_stop(struct seq_file *seq, void *v)
static int dev_mc_seq_show(struct seq_file *seq, void *v) static int dev_mc_seq_show(struct seq_file *seq, void *v)
{ {
struct dev_mc_list *m; struct dev_addr_list *m;
struct net_device *dev = v; struct net_device *dev = v;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment