aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-06-30 16:35:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:16:23 -0400
commit61cbc2fca6335be52788773b21efdc52a2750924 (patch)
tree489e6a9571c7fabd49dcff384dd634635fe66555 /net
parentd62733c8e437fdb58325617c4b3331769ba82d70 (diff)
[NET]: Fix secondary unicast/multicast address count maintenance
When a reference to an existing address is increased or decreased without hitting zero, the address count is incorrectly adjusted. 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.c21
-rw-r--r--net/core/dev_mcast.c11
2 files changed, 14 insertions, 18 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 7ddf66d0ad5e..4221dcda88d7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2607,8 +2607,8 @@ void dev_set_rx_mode(struct net_device *dev)
2607 netif_tx_unlock_bh(dev); 2607 netif_tx_unlock_bh(dev);
2608} 2608}
2609 2609
2610int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen, 2610int __dev_addr_delete(struct dev_addr_list **list, int *count,
2611 int glbl) 2611 void *addr, int alen, int glbl)
2612{ 2612{
2613 struct dev_addr_list *da; 2613 struct dev_addr_list *da;
2614 2614
@@ -2626,13 +2626,15 @@ int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,
2626 2626
2627 *list = da->next; 2627 *list = da->next;
2628 kfree(da); 2628 kfree(da);
2629 (*count)--;
2629 return 0; 2630 return 0;
2630 } 2631 }
2631 } 2632 }
2632 return -ENOENT; 2633 return -ENOENT;
2633} 2634}
2634 2635
2635int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl) 2636int __dev_addr_add(struct dev_addr_list **list, int *count,
2637 void *addr, int alen, int glbl)
2636{ 2638{
2637 struct dev_addr_list *da; 2639 struct dev_addr_list *da;
2638 2640
@@ -2659,6 +2661,7 @@ int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl)
2659 da->da_gusers = glbl ? 1 : 0; 2661 da->da_gusers = glbl ? 1 : 0;
2660 da->next = *list; 2662 da->next = *list;
2661 *list = da; 2663 *list = da;
2664 (*count)++;
2662 return 0; 2665 return 0;
2663} 2666}
2664 2667
@@ -2692,11 +2695,9 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
2692 ASSERT_RTNL(); 2695 ASSERT_RTNL();
2693 2696
2694 netif_tx_lock_bh(dev); 2697 netif_tx_lock_bh(dev);
2695 err = __dev_addr_delete(&dev->uc_list, addr, alen, 0); 2698 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
2696 if (!err) { 2699 if (!err)
2697 dev->uc_count--;
2698 __dev_set_rx_mode(dev); 2700 __dev_set_rx_mode(dev);
2699 }
2700 netif_tx_unlock_bh(dev); 2701 netif_tx_unlock_bh(dev);
2701 return err; 2702 return err;
2702} 2703}
@@ -2718,11 +2719,9 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
2718 ASSERT_RTNL(); 2719 ASSERT_RTNL();
2719 2720
2720 netif_tx_lock_bh(dev); 2721 netif_tx_lock_bh(dev);
2721 err = __dev_addr_add(&dev->uc_list, addr, alen, 0); 2722 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
2722 if (!err) { 2723 if (!err)
2723 dev->uc_count++;
2724 __dev_set_rx_mode(dev); 2724 __dev_set_rx_mode(dev);
2725 }
2726 netif_tx_unlock_bh(dev); 2725 netif_tx_unlock_bh(dev);
2727 return err; 2726 return err;
2728} 2727}
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 5cc9b448c443..aa38100601fb 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -72,10 +72,9 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
72 int err; 72 int err;
73 73
74 netif_tx_lock_bh(dev); 74 netif_tx_lock_bh(dev);
75 err = __dev_addr_delete(&dev->mc_list, addr, alen, glbl); 75 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
76 addr, alen, glbl);
76 if (!err) { 77 if (!err) {
77 dev->mc_count--;
78
79 /* 78 /*
80 * We have altered the list, so the card 79 * We have altered the list, so the card
81 * loaded filter is now wrong. Fix it 80 * loaded filter is now wrong. Fix it
@@ -96,11 +95,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
96 int err; 95 int err;
97 96
98 netif_tx_lock_bh(dev); 97 netif_tx_lock_bh(dev);
99 err = __dev_addr_add(&dev->mc_list, addr, alen, glbl); 98 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
100 if (!err) { 99 if (!err)
101 dev->mc_count++;
102 __dev_set_rx_mode(dev); 100 __dev_set_rx_mode(dev);
103 }
104 netif_tx_unlock_bh(dev); 101 netif_tx_unlock_bh(dev);
105 return err; 102 return err;
106} 103}