netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [NET 00/05]: Secondary unicast address support v2
@ 2007-06-22 12:24 Patrick McHardy
  2007-06-22 12:24 ` [NET 01/05]: dev_mcast: unexport dev_mc_upload Patrick McHardy
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

This is an updated version of the secondary unicast address patches. I've
introduced a common structure and helpers for both unicast and multicast
addresses to make it easier for virtual software devices that want to
synchronize addresses to a lower device to reuse code. Additionally I
fixed a deadlock when putting the device into promiscous mode, renamed
dev->set_address_list to dev->set_rx_mode and cleaned the code up a bit.

One remaining question is how to handle the case that too many unicast
addresses are configured and the device is put into promiscous mode
or unicast filtering is disabled by the driver. In that case we're not
getting the message that is normally printed by dev_set_promiscous
and no audit log. Not sure if that can already happen when configuring
multicast, I thought it was worth mentioning.



 drivers/net/e1000/e1000_main.c |   47 ++++++---
 include/linux/netdevice.h      |   40 +++++---
 net/core/dev.c                 |  213 ++++++++++++++++++++++++++++++++++++---
 net/core/dev_mcast.c           |  128 +++---------------------
 net/decnet/dn_dev.c            |    3 -
 5 files changed, 269 insertions(+), 162 deletions(-)

Patrick McHardy (5):
      [NET]: dev_mcast: unexport dev_mc_upload
      [NET]: dev: introduce generic net_device address lists
      [NET]: dev_mcast: switch to generic net_device address lists
      [NET]: dev: secondary unicast address support
      [E1000]: Secondary unicast address support

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [NET 01/05]: dev_mcast: unexport dev_mc_upload
  2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
@ 2007-06-22 12:24 ` Patrick McHardy
  2007-06-27  8:25   ` David Miller
  2007-06-22 12:24 ` [NET 02/05]: dev: introduce generic net_device address lists Patrick McHardy
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

[NET]: dev_mcast: unexport dev_mc_upload

dev_mc_add/dev_mc_delete take care of uploading the list when
necessary and thats the only interface other code should use.
Also remove two incorrect calls in DECnet.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit cdf660f0bd4cca9d2cbe86a31adc60d6fa8a60ec
tree 2f08c8240b7da9b17725896c3f7eb9c7a960c92c
parent 45da27ba265dba3c740c45d47f584c30d7066f82
author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 00:56:00 +0200
committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 00:56:00 +0200

 net/core/dev_mcast.c |    1 -
 net/decnet/dn_dev.c  |    3 ---
 2 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 5a54053..80bb2e3 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -292,4 +292,3 @@ void __init dev_mcast_init(void)
 
 EXPORT_SYMBOL(dev_mc_add);
 EXPORT_SYMBOL(dev_mc_delete);
-EXPORT_SYMBOL(dev_mc_upload);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index ab41c18..e31549e 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -461,7 +461,6 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
 		if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
 			dn_dn2eth(mac_addr, ifa->ifa_local);
 			dev_mc_add(dev, mac_addr, ETH_ALEN, 0);
-			dev_mc_upload(dev);
 		}
 	}
 
@@ -1064,8 +1063,6 @@ static int dn_eth_up(struct net_device *dev)
 	else
 		dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0);
 
-	dev_mc_upload(dev);
-
 	dn_db->use_long = 1;
 
 	return 0;

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [NET 02/05]: dev: introduce generic net_device address lists
  2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
  2007-06-22 12:24 ` [NET 01/05]: dev_mcast: unexport dev_mc_upload Patrick McHardy
@ 2007-06-22 12:24 ` Patrick McHardy
  2007-06-27  8:26   ` David Miller
  2007-06-22 12:24 ` [NET 03/05]: dev_mcast: switch to " Patrick McHardy
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

[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>

---
commit 6d8fd140951de7cc8faab4922dba74dd1db3cae5
tree b80412116a867d544808f140e76cdf22bbc8b248
parent cdf660f0bd4cca9d2cbe86a31adc60d6fa8a60ec
author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 03:25:26 +0200
committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 03:25:26 +0200

 include/linux/netdevice.h |   11 +++++++
 net/core/dev.c            |   69 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e7913ee..3785a8a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -177,6 +177,14 @@ struct netif_rx_stats
 
 DECLARE_PER_CPU(struct netif_rx_stats, netdev_rx_stat);
 
+struct dev_addr_list
+{
+	struct dev_addr_list	*next;
+	u8			da_addr[MAX_ADDR_LEN];
+	u8			da_addrlen;
+	int			da_users;
+	int			da_gusers;
+};
 
 /*
  *	We tag multicasts with these structures.
@@ -1004,6 +1012,9 @@ extern void		dev_mc_upload(struct net_device *dev);
 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 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);
 extern void		netdev_state_change(struct net_device *dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index 2609062..1496715 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2551,6 +2551,75 @@ void dev_set_allmulti(struct net_device *dev, int inc)
 		dev_mc_upload(dev);
 }
 
+int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,
+		      int glbl)
+{
+	struct dev_addr_list *da;
+
+	for (; (da = *list) != NULL; list = &da->next) {
+		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+		    alen == da->da_addrlen) {
+			if (glbl) {
+				int old_glbl = da->da_gusers;
+				da->da_gusers = 0;
+				if (old_glbl == 0)
+					break;
+			}
+			if (--da->da_users)
+				return 0;
+
+			*list = da->next;
+			kfree(da);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+int __dev_addr_add(struct dev_addr_list **list, void *addr, int alen, int glbl)
+{
+	struct dev_addr_list *da;
+
+	for (da = *list; da != NULL; da = da->next) {
+		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+		    da->da_addrlen == alen) {
+			if (glbl) {
+				int old_glbl = da->da_gusers;
+				da->da_gusers = 1;
+				if (old_glbl)
+					return 0;
+			}
+			da->da_users++;
+			return 0;
+		}
+	}
+
+	da = kmalloc(sizeof(*da), GFP_ATOMIC);
+	if (da == NULL)
+		return -ENOMEM;
+	memcpy(da->da_addr, addr, alen);
+	da->da_addrlen = alen;
+	da->da_users = 1;
+	da->da_gusers = glbl ? 1 : 0;
+	da->next = *list;
+	*list = da;
+	return 0;
+}
+
+void __dev_addr_discard(struct dev_addr_list **list)
+{
+	struct dev_addr_list *tmp;
+
+	while (*list != NULL) {
+		tmp = *list;
+		*list = tmp->next;
+		if (tmp->da_users > tmp->da_gusers)
+			printk("__dev_addr_discard: address leakage! "
+			       "da_users=%d\n", tmp->da_users);
+		kfree(tmp);
+	}
+}
+
 unsigned dev_get_flags(const struct net_device *dev)
 {
 	unsigned flags;

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [NET 03/05]: dev_mcast: switch to generic net_device address lists
  2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
  2007-06-22 12:24 ` [NET 01/05]: dev_mcast: unexport dev_mc_upload Patrick McHardy
  2007-06-22 12:24 ` [NET 02/05]: dev: introduce generic net_device address lists Patrick McHardy
@ 2007-06-22 12:24 ` Patrick McHardy
  2007-06-27  8:27   ` David Miller
  2007-06-22 12:24 ` [NET 04/05]: dev: secondary unicast address support Patrick McHardy
  2007-06-22 12:24 ` [E1000 05/05]: Secondary " Patrick McHardy
  4 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

[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 <kaber@trash.net>

---
commit 02536a101d6fd8b1924b1e05c44409c7b4568335
tree 6624b4f7f6fb0b10bac091ca43b733dfd1609afc
parent 6d8fd140951de7cc8faab4922dba74dd1db3cae5
author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 03:25:28 +0200
committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 03:25:28 +0200

 include/linux/netdevice.h |   17 +++-----
 net/core/dev_mcast.c      |   96 +++++++--------------------------------------
 2 files changed, 22 insertions(+), 91 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3785a8a..b2db124 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -189,15 +189,12 @@ struct dev_addr_list
 /*
  *	We tag multicasts with these structures.
  */
- 
-struct dev_mc_list
-{	
-	struct dev_mc_list	*next;
-	__u8			dmi_addr[MAX_ADDR_LEN];
-	unsigned char		dmi_addrlen;
-	int			dmi_users;
-	int			dmi_gusers;
-};
+
+#define dev_mc_list	dev_addr_list
+#define dmi_addr	da_addr
+#define dmi_addrlen	da_addrlen
+#define dmi_users	da_users
+#define dmi_gusers	da_gusers
 
 struct hh_cache
 {
@@ -396,7 +393,7 @@ struct net_device
 	unsigned char		addr_len;	/* hardware address length	*/
 	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			promiscuity;
 	int			allmulti;
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 80bb2e3..7029074 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -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 err = 0;
-	struct dev_mc_list *dmi, **dmip;
+	int err;
 
 	netif_tx_lock_bh(dev);
+	err = __dev_addr_delete(&dev->mc_list, addr, alen, glbl);
+	if (!err) {
+		dev->mc_count--;
 
-	for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
 		/*
-		 *	Find the entry we want to delete. The device could
-		 *	have variable length entries so check these too.
+		 *	We have altered the list, so the card
+		 *	loaded filter is now wrong. Fix it
 		 */
-		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--;
-
-			kfree(dmi);
-
-			/*
-			 *	We have altered the list, so the card
-			 *	loaded filter is now wrong. Fix it
-			 */
-			__dev_mc_upload(dev);
-
-			netif_tx_unlock_bh(dev);
-			return 0;
-		}
+
+		__dev_mc_upload(dev);
 	}
-	err = -ENOENT;
-done:
 	netif_tx_unlock_bh(dev);
 	return err;
 }
@@ -153,46 +126,15 @@ done:
 
 int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
 {
-	int err = 0;
-	struct dev_mc_list *dmi, *dmi1;
-
-	dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
+	int err;
 
 	netif_tx_lock_bh(dev);
-	for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-		if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-		    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;
+	err = __dev_addr_add(&dev->mc_list, addr, alen, glbl);
+	if (!err) {
+		dev->mc_count++;
+		__dev_mc_upload(dev);
 	}
-	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_upload(dev);
-
 	netif_tx_unlock_bh(dev);
-	return 0;
-
-done:
-	netif_tx_unlock_bh(dev);
-	kfree(dmi1);
 	return err;
 }
 
@@ -203,16 +145,8 @@ done:
 void dev_mc_discard(struct net_device *dev)
 {
 	netif_tx_lock_bh(dev);
-
-	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_addr_discard(&dev->mc_list);
 	dev->mc_count = 0;
-
 	netif_tx_unlock_bh(dev);
 }
 
@@ -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)
 {
-	struct dev_mc_list *m;
+	struct dev_addr_list *m;
 	struct net_device *dev = v;
 
 	netif_tx_lock_bh(dev);

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [NET 04/05]: dev: secondary unicast address support
  2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
                   ` (2 preceding siblings ...)
  2007-06-22 12:24 ` [NET 03/05]: dev_mcast: switch to " Patrick McHardy
@ 2007-06-22 12:24 ` Patrick McHardy
  2007-06-27  8:28   ` David Miller
  2007-06-22 12:24 ` [E1000 05/05]: Secondary " Patrick McHardy
  4 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

[NET]: dev: secondary unicast address support

Add support for configuring secondary unicast addresses on network
devices. To support this devices capable of filtering multiple
unicast addresses need to change their set_multicast_list function
to configure unicast filters as well and assign it to dev->set_rx_mode
instead of dev->set_multicast_list. Other devices are put into promiscous
mode when secondary unicast addresses are present.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 099e4ab74adb9418155132b093533f152a31b583
tree 7c8f52672f7b6e1323a479545225d88a2eb35670
parent 02536a101d6fd8b1924b1e05c44409c7b4568335
author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:46 +0200
committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:46 +0200

 include/linux/netdevice.h |   12 +++-
 net/core/dev.c            |  144 ++++++++++++++++++++++++++++++++++++++++-----
 net/core/dev_mcast.c      |   37 +-----------
 3 files changed, 139 insertions(+), 54 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b2db124..46585dc 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -393,6 +393,9 @@ struct net_device
 	unsigned char		addr_len;	/* hardware address length	*/
 	unsigned short          dev_id;		/* for shared network cards */
 
+	struct dev_addr_list	*uc_list;	/* Secondary unicast mac addresses */
+	int			uc_count;	/* Number of installed ucasts	*/
+	int			uc_promisc;
 	struct dev_addr_list	*mc_list;	/* Multicast mac addresses	*/
 	int			mc_count;	/* Number of installed mcasts	*/
 	int			promiscuity;
@@ -498,6 +501,8 @@ struct net_device
 						void *saddr,
 						unsigned len);
 	int			(*rebuild_header)(struct sk_buff *skb);
+#define HAVE_SET_RX_MODE
+	void			(*set_rx_mode)(struct net_device *dev);
 #define HAVE_MULTICAST			 
 	void			(*set_multicast_list)(struct net_device *dev);
 #define HAVE_SET_MAC_ADDR  		 
@@ -1004,8 +1009,11 @@ extern struct net_device *alloc_netdev(int sizeof_priv, const char *name,
 				       void (*setup)(struct net_device *));
 extern int		register_netdev(struct net_device *dev);
 extern void		unregister_netdev(struct net_device *dev);
-/* Functions used for multicast support */
-extern void		dev_mc_upload(struct net_device *dev);
+/* Functions used for secondary unicast and multicast support */
+extern void		dev_set_rx_mode(struct net_device *dev);
+extern void		__dev_set_rx_mode(struct net_device *dev);
+extern int		dev_unicast_delete(struct net_device *dev, void *addr, int alen);
+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);
diff --git a/net/core/dev.c b/net/core/dev.c
index 1496715..50a4e1e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -942,7 +942,7 @@ int dev_open(struct net_device *dev)
 		/*
 		 *	Initialize multicasting status
 		 */
-		dev_mc_upload(dev);
+		dev_set_rx_mode(dev);
 
 		/*
 		 *	Wakeup transmit queue engine
@@ -2496,17 +2496,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
 	return 0;
 }
 
-/**
- *	dev_set_promiscuity	- update promiscuity count on a device
- *	@dev: device
- *	@inc: modifier
- *
- *	Add or remove promiscuity from a device. While the count in the device
- *	remains above zero the interface remains promiscuous. Once it hits zero
- *	the device reverts back to normal filtering operation. A negative inc
- *	value is used to drop promiscuity on the device.
- */
-void dev_set_promiscuity(struct net_device *dev, int inc)
+static void __dev_set_promiscuity(struct net_device *dev, int inc)
 {
 	unsigned short old_flags = dev->flags;
 
@@ -2515,7 +2505,6 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
 	else
 		dev->flags |= IFF_PROMISC;
 	if (dev->flags != old_flags) {
-		dev_mc_upload(dev);
 		printk(KERN_INFO "device %s %s promiscuous mode\n",
 		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
 							       "left");
@@ -2529,6 +2518,25 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
 }
 
 /**
+ *	dev_set_promiscuity	- update promiscuity count on a device
+ *	@dev: device
+ *	@inc: modifier
+ *
+ *	Add or remove promiscuity from a device. While the count in the device
+ *	remains above zero the interface remains promiscuous. Once it hits zero
+ *	the device reverts back to normal filtering operation. A negative inc
+ *	value is used to drop promiscuity on the device.
+ */
+void dev_set_promiscuity(struct net_device *dev, int inc)
+{
+	unsigned short old_flags = dev->flags;
+
+	__dev_set_promiscuity(dev, inc);
+	if (dev->flags != old_flags)
+		dev_set_rx_mode(dev);
+}
+
+/**
  *	dev_set_allmulti	- update allmulti count on a device
  *	@dev: device
  *	@inc: modifier
@@ -2548,7 +2556,48 @@ void dev_set_allmulti(struct net_device *dev, int inc)
 	if ((dev->allmulti += inc) == 0)
 		dev->flags &= ~IFF_ALLMULTI;
 	if (dev->flags ^ old_flags)
-		dev_mc_upload(dev);
+		dev_set_rx_mode(dev);
+}
+
+/*
+ *	Upload unicast and multicast address lists to device and
+ *	configure RX filtering. When the device doesn't support unicast
+ *	filtering it is put in promiscous mode while unicast addresses
+ *	are present.
+ */
+void __dev_set_rx_mode(struct net_device *dev)
+{
+	/* dev_open will call this function so the list will stay sane. */
+	if (!(dev->flags&IFF_UP))
+		return;
+
+	if (!netif_device_present(dev))
+	        return;
+
+	if (dev->set_rx_mode)
+		dev->set_rx_mode(dev);
+	else {
+		/* Unicast addresses changes may only happen under the rtnl,
+		 * therefore calling __dev_set_promiscuity here is safe.
+		 */
+		if (dev->uc_count > 0 && !dev->uc_promisc) {
+			__dev_set_promiscuity(dev, 1);
+			dev->uc_promisc = 1;
+		} else if (dev->uc_count == 0 && dev->uc_promisc) {
+			__dev_set_promiscuity(dev, -1);
+			dev->uc_promisc = 0;
+		}
+
+		if (dev->set_multicast_list)
+			dev->set_multicast_list(dev);
+	}
+}
+
+void dev_set_rx_mode(struct net_device *dev)
+{
+	netif_tx_lock_bh(dev);
+	__dev_set_rx_mode(dev);
+	netif_tx_unlock_bh(dev);
 }
 
 int __dev_addr_delete(struct dev_addr_list **list, void *addr, int alen,
@@ -2620,6 +2669,66 @@ void __dev_addr_discard(struct dev_addr_list **list)
 	}
 }
 
+/**
+ *	dev_unicast_delete	- Release secondary unicast address.
+ *	@dev: device
+ *
+ *	Release reference to a secondary unicast address and remove it
+ *	from the device if the reference count drop to zero.
+ *
+ * 	The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
+{
+	int err;
+
+	ASSERT_RTNL();
+
+	netif_tx_lock_bh(dev);
+	err = __dev_addr_delete(&dev->uc_list, addr, alen, 0);
+	if (!err) {
+		dev->uc_count--;
+		__dev_set_rx_mode(dev);
+	}
+	netif_tx_unlock_bh(dev);
+	return err;
+}
+EXPORT_SYMBOL(dev_unicast_delete);
+
+/**
+ *	dev_unicast_add		- add a secondary unicast address
+ *	@dev: device
+ *
+ *	Add a secondary unicast address to the device or increase
+ *	the reference count if it already exists.
+ *
+ *	The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_add(struct net_device *dev, void *addr, int alen)
+{
+	int err;
+
+	ASSERT_RTNL();
+
+	netif_tx_lock_bh(dev);
+	err = __dev_addr_add(&dev->uc_list, addr, alen, 0);
+	if (!err) {
+		dev->uc_count++;
+		__dev_set_rx_mode(dev);
+	}
+	netif_tx_unlock_bh(dev);
+	return err;
+}
+EXPORT_SYMBOL(dev_unicast_add);
+
+static void dev_unicast_discard(struct net_device *dev)
+{
+	netif_tx_lock_bh(dev);
+	__dev_addr_discard(&dev->uc_list);
+	dev->uc_count = 0;
+	netif_tx_unlock_bh(dev);
+}
+
 unsigned dev_get_flags(const struct net_device *dev)
 {
 	unsigned flags;
@@ -2663,7 +2772,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
 	 *	Load in the correct multicast list now the flags have changed.
 	 */
 
-	dev_mc_upload(dev);
+	dev_set_rx_mode(dev);
 
 	/*
 	 *	Have we downed the interface. We handle IFF_UP ourselves
@@ -2676,7 +2785,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
 		ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
 
 		if (!ret)
-			dev_mc_upload(dev);
+			dev_set_rx_mode(dev);
 	}
 
 	if (dev->flags & IFF_UP &&
@@ -3540,8 +3649,9 @@ void unregister_netdevice(struct net_device *dev)
 	raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
 
 	/*
-	 *	Flush the multicast chain
+	 *	Flush the unicast and multicast chains
 	 */
+	dev_unicast_discard(dev);
 	dev_mc_discard(dev);
 
 	if (dev->uninit)
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 7029074..5cc9b44 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -64,39 +64,6 @@
  */
 
 /*
- *	Update the multicast list into the physical NIC controller.
- */
-
-static void __dev_mc_upload(struct net_device *dev)
-{
-	/* Don't do anything till we up the interface
-	 * [dev_open will call this function so the list will
-	 * stay sane]
-	 */
-
-	if (!(dev->flags&IFF_UP))
-		return;
-
-	/*
-	 *	Devices with no set multicast or which have been
-	 *	detached don't get set.
-	 */
-
-	if (dev->set_multicast_list == NULL ||
-	    !netif_device_present(dev))
-		return;
-
-	dev->set_multicast_list(dev);
-}
-
-void dev_mc_upload(struct net_device *dev)
-{
-	netif_tx_lock_bh(dev);
-	__dev_mc_upload(dev);
-	netif_tx_unlock_bh(dev);
-}
-
-/*
  *	Delete a device level multicast
  */
 
@@ -114,7 +81,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
 		 *	loaded filter is now wrong. Fix it
 		 */
 
-		__dev_mc_upload(dev);
+		__dev_set_rx_mode(dev);
 	}
 	netif_tx_unlock_bh(dev);
 	return err;
@@ -132,7 +99,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
 	err = __dev_addr_add(&dev->mc_list, addr, alen, glbl);
 	if (!err) {
 		dev->mc_count++;
-		__dev_mc_upload(dev);
+		__dev_set_rx_mode(dev);
 	}
 	netif_tx_unlock_bh(dev);
 	return err;

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [E1000 05/05]: Secondary unicast address support
  2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
                   ` (3 preceding siblings ...)
  2007-06-22 12:24 ` [NET 04/05]: dev: secondary unicast address support Patrick McHardy
@ 2007-06-22 12:24 ` Patrick McHardy
  2007-06-25 19:01   ` Kok, Auke
  4 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-22 12:24 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

[E1000]: Secondary unicast address support

Add support for configuring secondary unicast addresses. Unicast
addresses take precendece over multicast addresses when filling
the exact address filters to avoid going to promiscous mode.
When more unicast addresses are present than filter slots,
unicast filtering is disabled and all slots can be used for
multicast addresses.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 9613e4e4017b8bb68fcdd28cf5f9ae00bff18e28
tree e19261eea046a0404af0b26e2b99725ee33ae3c2
parent 099e4ab74adb9418155132b093533f152a31b583
author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:48 +0200
committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:48 +0200

 drivers/net/e1000/e1000_main.c |   47 ++++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cf8af92..716fc8f 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -149,7 +149,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
                                 struct e1000_tx_ring *tx_ring);
 static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
                                 struct e1000_rx_ring *rx_ring);
-static void e1000_set_multi(struct net_device *netdev);
+static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static void e1000_82547_tx_fifo_stall(unsigned long data);
@@ -513,7 +513,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
 	struct net_device *netdev = adapter->netdev;
 	int i;
 
-	e1000_set_multi(netdev);
+	e1000_set_rx_mode(netdev);
 
 	e1000_restore_vlan(adapter);
 	e1000_init_manageability(adapter);
@@ -924,7 +924,7 @@ e1000_probe(struct pci_dev *pdev,
 	netdev->stop = &e1000_close;
 	netdev->hard_start_xmit = &e1000_xmit_frame;
 	netdev->get_stats = &e1000_get_stats;
-	netdev->set_multicast_list = &e1000_set_multi;
+	netdev->set_rx_mode = &e1000_set_rx_mode;
 	netdev->set_mac_address = &e1000_set_mac;
 	netdev->change_mtu = &e1000_change_mtu;
 	netdev->do_ioctl = &e1000_ioctl;
@@ -2412,21 +2412,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
 }
 
 /**
- * e1000_set_multi - Multicast and Promiscuous mode set
+ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
  * promiscuous mode, and all-multi behavior.
  **/
 
 static void
-e1000_set_multi(struct net_device *netdev)
+e1000_set_rx_mode(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct dev_mc_list *mc_ptr;
+	struct dev_addr_list *uc_ptr;
+	struct dev_addr_list *mc_ptr;
 	uint32_t rctl;
 	uint32_t hash_value;
 	int i, rar_entries = E1000_RAR_ENTRIES;
@@ -2449,9 +2450,16 @@ e1000_set_multi(struct net_device *netdev)
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 	} else if (netdev->flags & IFF_ALLMULTI) {
 		rctl |= E1000_RCTL_MPE;
-		rctl &= ~E1000_RCTL_UPE;
 	} else {
-		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+		rctl &= ~E1000_RCTL_MPE;
+	}
+
+	uc_ptr = NULL;
+	if (netdev->uc_count > rar_entries - 1) {
+		rctl |= E1000_RCTL_UPE;
+	} else if (!(netdev->flags & IFF_PROMISC)) {
+		rctl &= ~E1000_RCTL_UPE;
+		uc_ptr = netdev->uc_list;
 	}
 
 	E1000_WRITE_REG(hw, RCTL, rctl);
@@ -2461,7 +2469,10 @@ e1000_set_multi(struct net_device *netdev)
 	if (hw->mac_type == e1000_82542_rev2_0)
 		e1000_enter_82542_rst(adapter);
 
-	/* load the first 14 multicast address into the exact filters 1-14
+	/* load the first 14 addresses into the exact filters 1-14. Unicast
+	 * addresses take precedence to avoid disabling unicast filtering
+	 * when possible.
+	 *
 	 * RAR 0 is used for the station MAC adddress
 	 * if there are not 14 addresses, go ahead and clear the filters
 	 * -- with 82571 controllers only 0-13 entries are filled here
@@ -2469,8 +2480,11 @@ e1000_set_multi(struct net_device *netdev)
 	mc_ptr = netdev->mc_list;
 
 	for (i = 1; i < rar_entries; i++) {
-		if (mc_ptr) {
-			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
+		if (uc_ptr) {
+			e1000_rar_set(hw, uc_ptr->da_addr, i);
+			uc_ptr = uc_ptr->next;
+		} else if (mc_ptr) {
+			e1000_rar_set(hw, mc_ptr->da_addr, i);
 			mc_ptr = mc_ptr->next;
 		} else {
 			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@@ -2479,6 +2493,7 @@ e1000_set_multi(struct net_device *netdev)
 			E1000_WRITE_FLUSH(hw);
 		}
 	}
+	WARN_ON(uc_ptr != NULL);
 
 	/* clear the old settings from the multicast hash table */
 
@@ -2490,7 +2505,7 @@ e1000_set_multi(struct net_device *netdev)
 	/* load any remaining addresses into the hash table */
 
 	for (; mc_ptr; mc_ptr = mc_ptr->next) {
-		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
+		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
 		e1000_mta_set(hw, hash_value);
 	}
 
@@ -5098,7 +5113,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	if (wufc) {
 		e1000_setup_rctl(adapter);
-		e1000_set_multi(netdev);
+		e1000_set_rx_mode(netdev);
 
 		/* turn on all-multi mode if wake on multicast is enabled */
 		if (wufc & E1000_WUFC_MC) {

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [E1000 05/05]: Secondary unicast address support
  2007-06-22 12:24 ` [E1000 05/05]: Secondary " Patrick McHardy
@ 2007-06-25 19:01   ` Kok, Auke
  2007-06-25 19:05     ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: Kok, Auke @ 2007-06-25 19:01 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev

Patrick McHardy wrote:
> [E1000]: Secondary unicast address support
> 
> Add support for configuring secondary unicast addresses. Unicast
> addresses take precendece over multicast addresses when filling
> the exact address filters to avoid going to promiscous mode.
> When more unicast addresses are present than filter slots,
> unicast filtering is disabled and all slots can be used for
> multicast addresses.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> 
> ---
> commit 9613e4e4017b8bb68fcdd28cf5f9ae00bff18e28
> tree e19261eea046a0404af0b26e2b99725ee33ae3c2
> parent 099e4ab74adb9418155132b093533f152a31b583
> author Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:48 +0200
> committer Patrick McHardy <kaber@trash.net> Fri, 22 Jun 2007 14:13:48 +0200
> 
>  drivers/net/e1000/e1000_main.c |   47 ++++++++++++++++++++++++++--------------
>  1 files changed, 31 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
> index cf8af92..716fc8f 100644
> --- a/drivers/net/e1000/e1000_main.c
> +++ b/drivers/net/e1000/e1000_main.c
> @@ -149,7 +149,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
>                                  struct e1000_tx_ring *tx_ring);
>  static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
>                                  struct e1000_rx_ring *rx_ring);
> -static void e1000_set_multi(struct net_device *netdev);
> +static void e1000_set_rx_mode(struct net_device *netdev);
>  static void e1000_update_phy_info(unsigned long data);
>  static void e1000_watchdog(unsigned long data);
>  static void e1000_82547_tx_fifo_stall(unsigned long data);
> @@ -513,7 +513,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
>  	struct net_device *netdev = adapter->netdev;
>  	int i;
>  
> -	e1000_set_multi(netdev);
> +	e1000_set_rx_mode(netdev);
>  
>  	e1000_restore_vlan(adapter);
>  	e1000_init_manageability(adapter);
> @@ -924,7 +924,7 @@ e1000_probe(struct pci_dev *pdev,
>  	netdev->stop = &e1000_close;
>  	netdev->hard_start_xmit = &e1000_xmit_frame;
>  	netdev->get_stats = &e1000_get_stats;
> -	netdev->set_multicast_list = &e1000_set_multi;
> +	netdev->set_rx_mode = &e1000_set_rx_mode;
>  	netdev->set_mac_address = &e1000_set_mac;
>  	netdev->change_mtu = &e1000_change_mtu;
>  	netdev->do_ioctl = &e1000_ioctl;
> @@ -2412,21 +2412,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
>  }
>  
>  /**
> - * e1000_set_multi - Multicast and Promiscuous mode set
> + * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
>   * @netdev: network interface device structure
>   *
> - * The set_multi entry point is called whenever the multicast address
> - * list or the network interface flags are updated.  This routine is
> - * responsible for configuring the hardware for proper multicast,
> + * The set_rx_mode entry point is called whenever the unicast or multicast
> + * address lists or the network interface flags are updated. This routine is
> + * responsible for configuring the hardware for proper unicast, multicast,
>   * promiscuous mode, and all-multi behavior.
>   **/
>  
>  static void
> -e1000_set_multi(struct net_device *netdev)
> +e1000_set_rx_mode(struct net_device *netdev)
>  {
>  	struct e1000_adapter *adapter = netdev_priv(netdev);
>  	struct e1000_hw *hw = &adapter->hw;
> -	struct dev_mc_list *mc_ptr;
> +	struct dev_addr_list *uc_ptr;
> +	struct dev_addr_list *mc_ptr;
>  	uint32_t rctl;
>  	uint32_t hash_value;
>  	int i, rar_entries = E1000_RAR_ENTRIES;
> @@ -2449,9 +2450,16 @@ e1000_set_multi(struct net_device *netdev)
>  		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
>  	} else if (netdev->flags & IFF_ALLMULTI) {
>  		rctl |= E1000_RCTL_MPE;
> -		rctl &= ~E1000_RCTL_UPE;
>  	} else {
> -		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
> +		rctl &= ~E1000_RCTL_MPE;
> +	}
> +
> +	uc_ptr = NULL;
> +	if (netdev->uc_count > rar_entries - 1) {
> +		rctl |= E1000_RCTL_UPE;
> +	} else if (!(netdev->flags & IFF_PROMISC)) {
> +		rctl &= ~E1000_RCTL_UPE;
> +		uc_ptr = netdev->uc_list;
>  	}
>  
>  	E1000_WRITE_REG(hw, RCTL, rctl);
> @@ -2461,7 +2469,10 @@ e1000_set_multi(struct net_device *netdev)
>  	if (hw->mac_type == e1000_82542_rev2_0)
>  		e1000_enter_82542_rst(adapter);
>  
> -	/* load the first 14 multicast address into the exact filters 1-14
> +	/* load the first 14 addresses into the exact filters 1-14. Unicast
> +	 * addresses take precedence to avoid disabling unicast filtering
> +	 * when possible.
> +	 *
>  	 * RAR 0 is used for the station MAC adddress
>  	 * if there are not 14 addresses, go ahead and clear the filters
>  	 * -- with 82571 controllers only 0-13 entries are filled here
> @@ -2469,8 +2480,11 @@ e1000_set_multi(struct net_device *netdev)
>  	mc_ptr = netdev->mc_list;
>  
>  	for (i = 1; i < rar_entries; i++) {
> -		if (mc_ptr) {
> -			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
> +		if (uc_ptr) {
> +			e1000_rar_set(hw, uc_ptr->da_addr, i);
> +			uc_ptr = uc_ptr->next;
> +		} else if (mc_ptr) {
> +			e1000_rar_set(hw, mc_ptr->da_addr, i);
>  			mc_ptr = mc_ptr->next;
>  		} else {
>  			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
> @@ -2479,6 +2493,7 @@ e1000_set_multi(struct net_device *netdev)
>  			E1000_WRITE_FLUSH(hw);
>  		}
>  	}
> +	WARN_ON(uc_ptr != NULL);
>  
>  	/* clear the old settings from the multicast hash table */
>  
> @@ -2490,7 +2505,7 @@ e1000_set_multi(struct net_device *netdev)
>  	/* load any remaining addresses into the hash table */
>  
>  	for (; mc_ptr; mc_ptr = mc_ptr->next) {
> -		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
> +		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
>  		e1000_mta_set(hw, hash_value);
>  	}
>  
> @@ -5098,7 +5113,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
>  
>  	if (wufc) {
>  		e1000_setup_rctl(adapter);
> -		e1000_set_multi(netdev);
> +		e1000_set_rx_mode(netdev);
>  
>  		/* turn on all-multi mode if wake on multicast is enabled */
>  		if (wufc & E1000_WUFC_MC) {
> -

noted. I'm (like a lot of people) on the road and still need to dig into this 
deeper. I think it's OK for as far as I can see, except the WARN_ON, can't we 
pre-check to see if we have enough room in the rar_entries first?

Auke

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [E1000 05/05]: Secondary unicast address support
  2007-06-25 19:01   ` Kok, Auke
@ 2007-06-25 19:05     ` Patrick McHardy
  0 siblings, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2007-06-25 19:05 UTC (permalink / raw)
  To: Kok, Auke; +Cc: netdev

Kok, Auke wrote:
> Patrick McHardy wrote:
>> @@ -2449,9 +2450,16 @@ e1000_set_multi(struct net_device *netdev)
>>          rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
>>      } else if (netdev->flags & IFF_ALLMULTI) {
>>          rctl |= E1000_RCTL_MPE;
>> -        rctl &= ~E1000_RCTL_UPE;
>>      } else {
>> -        rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
>> +        rctl &= ~E1000_RCTL_MPE;
>> +    }
>> +
>> +    uc_ptr = NULL;
>> +    if (netdev->uc_count > rar_entries - 1) {
>> +        rctl |= E1000_RCTL_UPE;
>> +    } else if (!(netdev->flags & IFF_PROMISC)) {
>> +        rctl &= ~E1000_RCTL_UPE;
>> +        uc_ptr = netdev->uc_list;
>>      }
>>  
>>      E1000_WRITE_REG(hw, RCTL, rctl);
>> @@ -2461,7 +2469,10 @@ e1000_set_multi(struct net_device *netdev)
>>      if (hw->mac_type == e1000_82542_rev2_0)
>>          e1000_enter_82542_rst(adapter);
>>  
>> -    /* load the first 14 multicast address into the exact filters 1-14
>> +    /* load the first 14 addresses into the exact filters 1-14. Unicast
>> +     * addresses take precedence to avoid disabling unicast filtering
>> +     * when possible.
>> +     *
>>       * RAR 0 is used for the station MAC adddress
>>       * if there are not 14 addresses, go ahead and clear the filters
>>       * -- with 82571 controllers only 0-13 entries are filled here
>> @@ -2469,8 +2480,11 @@ e1000_set_multi(struct net_device *netdev)
>>      mc_ptr = netdev->mc_list;
>>  
>>      for (i = 1; i < rar_entries; i++) {
>> -        if (mc_ptr) {
>> -            e1000_rar_set(hw, mc_ptr->dmi_addr, i);
>> +        if (uc_ptr) {
>> +            e1000_rar_set(hw, uc_ptr->da_addr, i);
>> +            uc_ptr = uc_ptr->next;
>> +        } else if (mc_ptr) {
>> +            e1000_rar_set(hw, mc_ptr->da_addr, i);
>>              mc_ptr = mc_ptr->next;
>>          } else {
>>              E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
>> @@ -2479,6 +2493,7 @@ e1000_set_multi(struct net_device *netdev)
>>              E1000_WRITE_FLUSH(hw);
>>          }
>>      }
>> +    WARN_ON(uc_ptr != NULL);
>>   
>
> noted. I'm (like a lot of people) on the road and still need to dig 
> into this deeper.

Please take your time, this was mainly an example and for testing.
If its OK I wouldn't object to you applying it of course :)

> I think it's OK for as far as I can see, except the WARN_ON, can't we 
> pre-check to see if we have enough room in the rar_entries first?


It does, the WARN_ON would only trigger if I made a mistake:

+    if (netdev->uc_count > rar_entries - 1) {



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 01/05]: dev_mcast: unexport dev_mc_upload
  2007-06-22 12:24 ` [NET 01/05]: dev_mcast: unexport dev_mc_upload Patrick McHardy
@ 2007-06-27  8:25   ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2007-06-27  8:25 UTC (permalink / raw)
  To: kaber; +Cc: netdev

From: Patrick McHardy <kaber@trash.net>
Date: Fri, 22 Jun 2007 14:24:07 +0200 (MEST)

> [NET]: dev_mcast: unexport dev_mc_upload
> 
> dev_mc_add/dev_mc_delete take care of uploading the list when
> necessary and thats the only interface other code should use.
> Also remove two incorrect calls in DECnet.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied to net-2.6.23, thanks Patrick.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 02/05]: dev: introduce generic net_device address lists
  2007-06-22 12:24 ` [NET 02/05]: dev: introduce generic net_device address lists Patrick McHardy
@ 2007-06-27  8:26   ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2007-06-27  8:26 UTC (permalink / raw)
  To: kaber; +Cc: netdev

From: Patrick McHardy <kaber@trash.net>
Date: Fri, 22 Jun 2007 14:24:09 +0200 (MEST)

> [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>

Applied to net-2.6.23

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 03/05]: dev_mcast: switch to generic net_device address lists
  2007-06-22 12:24 ` [NET 03/05]: dev_mcast: switch to " Patrick McHardy
@ 2007-06-27  8:27   ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2007-06-27  8:27 UTC (permalink / raw)
  To: kaber; +Cc: netdev

From: Patrick McHardy <kaber@trash.net>
Date: Fri, 22 Jun 2007 14:24:10 +0200 (MEST)

> [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 <kaber@trash.net>

Applied, thanks Patrick.

Hopefully we can convert the drivers over time and
eventually at some future point kill the macros.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 04/05]: dev: secondary unicast address support
  2007-06-22 12:24 ` [NET 04/05]: dev: secondary unicast address support Patrick McHardy
@ 2007-06-27  8:28   ` David Miller
  2007-06-27  8:30     ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2007-06-27  8:28 UTC (permalink / raw)
  To: kaber; +Cc: netdev

From: Patrick McHardy <kaber@trash.net>
Date: Fri, 22 Jun 2007 14:24:12 +0200 (MEST)

> [NET]: dev: secondary unicast address support
> 
> Add support for configuring secondary unicast addresses on network
> devices. To support this devices capable of filtering multiple
> unicast addresses need to change their set_multicast_list function
> to configure unicast filters as well and assign it to dev->set_rx_mode
> instead of dev->set_multicast_list. Other devices are put into promiscous
> mode when secondary unicast addresses are present.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Also applied, thanks for doing this work Patrick.

I'll let the driver maintainers approve and merge individual
device support.

Thanks again.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 04/05]: dev: secondary unicast address support
  2007-06-27  8:28   ` David Miller
@ 2007-06-27  8:30     ` Patrick McHardy
  2007-06-27  8:55       ` David Miller
  0 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-06-27  8:30 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

David Miller wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Fri, 22 Jun 2007 14:24:12 +0200 (MEST)
> 
> 
>>[NET]: dev: secondary unicast address support
>>
>>Add support for configuring secondary unicast addresses on network
>>devices. To support this devices capable of filtering multiple
>>unicast addresses need to change their set_multicast_list function
>>to configure unicast filters as well and assign it to dev->set_rx_mode
>>instead of dev->set_multicast_list. Other devices are put into promiscous
>>mode when secondary unicast addresses are present.
>>
>>Signed-off-by: Patrick McHardy <kaber@trash.net>
> 
> 
> Also applied, thanks for doing this work Patrick.


Thanks. Please hold off on the MACVLAN patch, I want to convert it
to use this stuff before adding it.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [NET 04/05]: dev: secondary unicast address support
  2007-06-27  8:30     ` Patrick McHardy
@ 2007-06-27  8:55       ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2007-06-27  8:55 UTC (permalink / raw)
  To: kaber; +Cc: netdev

From: Patrick McHardy <kaber@trash.net>
Date: Wed, 27 Jun 2007 10:30:09 +0200

> David Miller wrote:
> > From: Patrick McHardy <kaber@trash.net>
> > Date: Fri, 22 Jun 2007 14:24:12 +0200 (MEST)
> > 
> > 
> >>[NET]: dev: secondary unicast address support
> >>
> >>Add support for configuring secondary unicast addresses on network
> >>devices. To support this devices capable of filtering multiple
> >>unicast addresses need to change their set_multicast_list function
> >>to configure unicast filters as well and assign it to dev->set_rx_mode
> >>instead of dev->set_multicast_list. Other devices are put into promiscous
> >>mode when secondary unicast addresses are present.
> >>
> >>Signed-off-by: Patrick McHardy <kaber@trash.net>
> > 
> > 
> > Also applied, thanks for doing this work Patrick.
> 
> 
> Thanks. Please hold off on the MACVLAN patch, I want to convert it
> to use this stuff before adding it.

Ok.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2007-06-27  8:55 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-22 12:24 [NET 00/05]: Secondary unicast address support v2 Patrick McHardy
2007-06-22 12:24 ` [NET 01/05]: dev_mcast: unexport dev_mc_upload Patrick McHardy
2007-06-27  8:25   ` David Miller
2007-06-22 12:24 ` [NET 02/05]: dev: introduce generic net_device address lists Patrick McHardy
2007-06-27  8:26   ` David Miller
2007-06-22 12:24 ` [NET 03/05]: dev_mcast: switch to " Patrick McHardy
2007-06-27  8:27   ` David Miller
2007-06-22 12:24 ` [NET 04/05]: dev: secondary unicast address support Patrick McHardy
2007-06-27  8:28   ` David Miller
2007-06-27  8:30     ` Patrick McHardy
2007-06-27  8:55       ` David Miller
2007-06-22 12:24 ` [E1000 05/05]: Secondary " Patrick McHardy
2007-06-25 19:01   ` Kok, Auke
2007-06-25 19:05     ` Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).