aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-06-27 04:26:19 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:15:54 -0400
commitbf742482d7a647c5c6f03f78eb35a862e159ecf5 (patch)
tree80a822df5fa5eb6b766489b1983c4dc83d4f7668 /net
parent75ebe8f73610636be8bbd8d73db883512850e6be (diff)
[NET]: dev: introduce generic net_device address lists
Introduce struct dev_addr_list and list maintenance functions based on dev_mc_list and the related functions. This will be used by follow-up patches for both multicast and secondary unicast addresses. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index a0a46e7ed137..18759ccdf219 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2553,6 +2553,75 @@ void dev_set_allmulti(struct net_device *dev, int inc)
2553 dev_mc_upload(dev); 2553 dev_mc_upload(dev);
2554} 2554}
2555 2555
2556int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,
2557 int glbl)
2558{
2559 struct dev_addr_list *da;
2560
2561 for (; (da = *list) != NULL; list = &da->next) {
2562 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
2563 alen == da->da_addrlen) {
2564 if (glbl) {
2565 int old_glbl = da->da_gusers;
2566 da->da_gusers = 0;
2567 if (old_glbl == 0)
2568 break;
2569 }
2570 if (--da->da_users)
2571 return 0;
2572
2573 *list = da->next;
2574 kfree(da);
2575 return 0;
2576 }
2577 }
2578 return -ENOENT;
2579}
2580
2581int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl)
2582{
2583 struct dev_addr_list *da;
2584
2585 for (da = *list; da != NULL; da = da->next) {
2586 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
2587 da->da_addrlen == alen) {
2588 if (glbl) {
2589 int old_glbl = da->da_gusers;
2590 da->da_gusers = 1;
2591 if (old_glbl)
2592 return 0;
2593 }
2594 da->da_users++;
2595 return 0;
2596 }
2597 }
2598
2599 da = kmalloc(sizeof(*da), GFP_ATOMIC);
2600 if (da == NULL)
2601 return -ENOMEM;
2602 memcpy(da->da_addr, addr, alen);
2603 da->da_addrlen = alen;
2604 da->da_users = 1;
2605 da->da_gusers = glbl ? 1 : 0;
2606 da->next = *list;
2607 *list = da;
2608 return 0;
2609}
2610
2611void __dev_addr_discard(struct dev_addr_list **list)
2612{
2613 struct dev_addr_list *tmp;
2614
2615 while (*list != NULL) {
2616 tmp = *list;
2617 *list = tmp->next;
2618 if (tmp->da_users > tmp->da_gusers)
2619 printk("__dev_addr_discard: address leakage! "
2620 "da_users=%d\n", tmp->da_users);
2621 kfree(tmp);
2622 }
2623}
2624
2556unsigned dev_get_flags(const struct net_device *dev) 2625unsigned dev_get_flags(const struct net_device *dev)
2557{ 2626{
2558 unsigned flags; 2627 unsigned flags;