Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61cbc2fc authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d62733c8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1091,8 +1091,8 @@ extern int dev_unicast_add(struct net_device *dev, void *addr, int alen);
extern int 		dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
extern int		dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
extern void		dev_mc_discard(struct net_device *dev);
extern int 		__dev_addr_delete(struct dev_addr_list **list, void *addr, int alen, int all);
extern int		__dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int newonly);
extern int 		__dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
extern int		__dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
extern void		__dev_addr_discard(struct dev_addr_list **list);
extern void		dev_set_promiscuity(struct net_device *dev, int inc);
extern void		dev_set_allmulti(struct net_device *dev, int inc);
+10 −11
Original line number Diff line number Diff line
@@ -2607,8 +2607,8 @@ void dev_set_rx_mode(struct net_device *dev)
	netif_tx_unlock_bh(dev);
}

int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,
		      int glbl)
int __dev_addr_delete(struct dev_addr_list **list, int *count,
		      void *addr, int alen, int glbl)
{
	struct dev_addr_list *da;

@@ -2626,13 +2626,15 @@ int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,

			*list = da->next;
			kfree(da);
			(*count)--;
			return 0;
		}
	}
	return -ENOENT;
}

int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl)
int __dev_addr_add(struct dev_addr_list **list, int *count,
		   void *addr, int alen, int glbl)
{
	struct dev_addr_list *da;

@@ -2659,6 +2661,7 @@ int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl)
	da->da_gusers = glbl ? 1 : 0;
	da->next = *list;
	*list = da;
	(*count)++;
	return 0;
}

@@ -2692,11 +2695,9 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
	ASSERT_RTNL();

	netif_tx_lock_bh(dev);
	err = __dev_addr_delete(&dev->uc_list, addr, alen, 0);
	if (!err) {
		dev->uc_count--;
	err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
	if (!err)
		__dev_set_rx_mode(dev);
	}
	netif_tx_unlock_bh(dev);
	return err;
}
@@ -2718,11 +2719,9 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
	ASSERT_RTNL();

	netif_tx_lock_bh(dev);
	err = __dev_addr_add(&dev->uc_list, addr, alen, 0);
	if (!err) {
		dev->uc_count++;
	err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
	if (!err)
		__dev_set_rx_mode(dev);
	}
	netif_tx_unlock_bh(dev);
	return err;
}
+4 −7
Original line number Diff line number Diff line
@@ -72,10 +72,9 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
	int err;

	netif_tx_lock_bh(dev);
	err = __dev_addr_delete(&dev->mc_list, addr, alen, glbl);
	err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
				addr, alen, glbl);
	if (!err) {
		dev->mc_count--;

		/*
		 *	We have altered the list, so the card
		 *	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)
	int err;

	netif_tx_lock_bh(dev);
	err = __dev_addr_add(&dev->mc_list, addr, alen, glbl);
	if (!err) {
		dev->mc_count++;
	err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
	if (!err)
		__dev_set_rx_mode(dev);
	}
	netif_tx_unlock_bh(dev);
	return err;
}