Skip to content

Commit 3fba5a8

Browse files
kaberDavid S. Miller
authored andcommitted
[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: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bf74248 commit 3fba5a8

File tree

2 files changed

+22
-91
lines changed

2 files changed

+22
-91
lines changed

include/linux/netdevice.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,12 @@ struct dev_addr_list
189189
/*
190190
* We tag multicasts with these structures.
191191
*/
192-
193-
struct dev_mc_list
194-
{
195-
struct dev_mc_list *next;
196-
__u8 dmi_addr[MAX_ADDR_LEN];
197-
unsigned char dmi_addrlen;
198-
int dmi_users;
199-
int dmi_gusers;
200-
};
192+
193+
#define dev_mc_list dev_addr_list
194+
#define dmi_addr da_addr
195+
#define dmi_addrlen da_addrlen
196+
#define dmi_users da_users
197+
#define dmi_gusers da_gusers
201198

202199
struct hh_cache
203200
{
@@ -400,7 +397,7 @@ struct net_device
400397
unsigned char addr_len; /* hardware address length */
401398
unsigned short dev_id; /* for shared network cards */
402399

403-
struct dev_mc_list *mc_list; /* Multicast mac addresses */
400+
struct dev_addr_list *mc_list; /* Multicast mac addresses */
404401
int mc_count; /* Number of installed mcasts */
405402
int promiscuity;
406403
int allmulti;

net/core/dev_mcast.c

Lines changed: 15 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -102,47 +102,20 @@ void dev_mc_upload(struct net_device *dev)
102102

103103
int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
104104
{
105-
int err = 0;
106-
struct dev_mc_list *dmi, **dmip;
105+
int err;
107106

108107
netif_tx_lock_bh(dev);
108+
err = __dev_addr_delete(&dev->mc_list, addr, alen, glbl);
109+
if (!err) {
110+
dev->mc_count--;
109111

110-
for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
111112
/*
112-
* Find the entry we want to delete. The device could
113-
* have variable length entries so check these too.
113+
* We have altered the list, so the card
114+
* loaded filter is now wrong. Fix it
114115
*/
115-
if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
116-
alen == dmi->dmi_addrlen) {
117-
if (glbl) {
118-
int old_glbl = dmi->dmi_gusers;
119-
dmi->dmi_gusers = 0;
120-
if (old_glbl == 0)
121-
break;
122-
}
123-
if (--dmi->dmi_users)
124-
goto done;
125-
126-
/*
127-
* Last user. So delete the entry.
128-
*/
129-
*dmip = dmi->next;
130-
dev->mc_count--;
131-
132-
kfree(dmi);
133-
134-
/*
135-
* We have altered the list, so the card
136-
* loaded filter is now wrong. Fix it
137-
*/
138-
__dev_mc_upload(dev);
139-
140-
netif_tx_unlock_bh(dev);
141-
return 0;
142-
}
116+
117+
__dev_mc_upload(dev);
143118
}
144-
err = -ENOENT;
145-
done:
146119
netif_tx_unlock_bh(dev);
147120
return err;
148121
}
@@ -153,46 +126,15 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
153126

154127
int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
155128
{
156-
int err = 0;
157-
struct dev_mc_list *dmi, *dmi1;
158-
159-
dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
129+
int err;
160130

161131
netif_tx_lock_bh(dev);
162-
for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
163-
if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
164-
dmi->dmi_addrlen == alen) {
165-
if (glbl) {
166-
int old_glbl = dmi->dmi_gusers;
167-
dmi->dmi_gusers = 1;
168-
if (old_glbl)
169-
goto done;
170-
}
171-
dmi->dmi_users++;
172-
goto done;
173-
}
174-
}
175-
176-
if ((dmi = dmi1) == NULL) {
177-
netif_tx_unlock_bh(dev);
178-
return -ENOMEM;
132+
err = __dev_addr_add(&dev->mc_list, addr, alen, glbl);
133+
if (!err) {
134+
dev->mc_count++;
135+
__dev_mc_upload(dev);
179136
}
180-
memcpy(dmi->dmi_addr, addr, alen);
181-
dmi->dmi_addrlen = alen;
182-
dmi->next = dev->mc_list;
183-
dmi->dmi_users = 1;
184-
dmi->dmi_gusers = glbl ? 1 : 0;
185-
dev->mc_list = dmi;
186-
dev->mc_count++;
187-
188-
__dev_mc_upload(dev);
189-
190137
netif_tx_unlock_bh(dev);
191-
return 0;
192-
193-
done:
194-
netif_tx_unlock_bh(dev);
195-
kfree(dmi1);
196138
return err;
197139
}
198140

@@ -203,16 +145,8 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
203145
void dev_mc_discard(struct net_device *dev)
204146
{
205147
netif_tx_lock_bh(dev);
206-
207-
while (dev->mc_list != NULL) {
208-
struct dev_mc_list *tmp = dev->mc_list;
209-
dev->mc_list = tmp->next;
210-
if (tmp->dmi_users > tmp->dmi_gusers)
211-
printk("dev_mc_discard: multicast leakage! dmi_users=%d\n", tmp->dmi_users);
212-
kfree(tmp);
213-
}
148+
__dev_addr_discard(&dev->mc_list);
214149
dev->mc_count = 0;
215-
216150
netif_tx_unlock_bh(dev);
217151
}
218152

@@ -244,7 +178,7 @@ static void dev_mc_seq_stop(struct seq_file *seq, void *v)
244178

245179
static int dev_mc_seq_show(struct seq_file *seq, void *v)
246180
{
247-
struct dev_mc_list *m;
181+
struct dev_addr_list *m;
248182
struct net_device *dev = v;
249183

250184
netif_tx_lock_bh(dev);

0 commit comments

Comments
 (0)