Re: [VLAN]: set_rx_mode support for unicast address list

2008-01-31 Thread David Miller

Applied.
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[VLAN]: set_rx_mode support for unicast address list

2008-01-29 Thread Patrick McHardy
 commit fbf2742ff936c751444ae610ae45c6ef54c14658
Author: Chris Leech [EMAIL PROTECTED]
Date:   Thu Jan 24 18:24:53 2008 +0100

[VLAN]: set_rx_mode support for unicast address list

Reuse the existing logic for multicast list synchronization for the unicast
address list. The core of dev_mc_sync/unsync are split out as
__dev_addr_sync/unsync and moved from dev_mcast.c to dev.c.  These are then
used to implement dev_unicast_sync/unsync as well.

I'm working on cleaning up Intel's FCoE stack, which generates new MAC
addresses from the fibre channel device id assigned by the fabric as per the
current draft specification in T11.  When using such a protocol in a VLAN
environment it would be nice to not always be forced into promiscuous mode,
assuming the underlying Ethernet driver supports multiple unicast addresses 
as
well.

Signed-off-by: Chris Leech [EMAIL PROTECTED]
Signed-off-by: Patrick McHardy [EMAIL PROTECTED]

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b0813c3..047d432 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1414,12 +1414,16 @@ 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_unicast_sync(struct net_device *to, struct 
net_device *from);
+extern voiddev_unicast_unsync(struct net_device *to, struct 
net_device *from);
 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 int dev_mc_sync(struct net_device *to, struct net_device 
*from);
 extern voiddev_mc_unsync(struct net_device *to, struct net_device 
*from);
 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 int __dev_addr_sync(struct dev_addr_list **to, int 
*to_count, struct dev_addr_list **from, int *from_count);
+extern void__dev_addr_unsync(struct dev_addr_list **to, int 
*to_count, struct dev_addr_list **from, int *from_count);
 extern voiddev_set_promiscuity(struct net_device *dev, int inc);
 extern voiddev_set_allmulti(struct net_device *dev, int inc);
 extern voidnetdev_state_change(struct net_device *dev);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8059fa4..77f04e4 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -563,6 +563,7 @@ static int vlan_dev_stop(struct net_device *dev)
struct net_device *real_dev = vlan_dev_info(dev)-real_dev;
 
dev_mc_unsync(real_dev, dev);
+   dev_unicast_unsync(real_dev, dev);
if (dev-flags  IFF_ALLMULTI)
dev_set_allmulti(real_dev, -1);
if (dev-flags  IFF_PROMISC)
@@ -634,9 +635,10 @@ static void vlan_dev_change_rx_flags(struct net_device 
*dev, int change)
dev_set_promiscuity(real_dev, dev-flags  IFF_PROMISC ? 1 : 
-1);
 }
 
-static void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
dev_mc_sync(vlan_dev_info(vlan_dev)-real_dev, vlan_dev);
+   dev_unicast_sync(vlan_dev_info(vlan_dev)-real_dev, vlan_dev);
 }
 
 /*
@@ -702,7 +704,8 @@ void vlan_setup(struct net_device *dev)
dev-open   = vlan_dev_open;
dev-stop   = vlan_dev_stop;
dev-set_mac_address= vlan_dev_set_mac_address;
-   dev-set_multicast_list = vlan_dev_set_multicast_list;
+   dev-set_rx_mode= vlan_dev_set_rx_mode;
+   dev-set_multicast_list = vlan_dev_set_rx_mode;
dev-change_rx_flags= vlan_dev_change_rx_flags;
dev-do_ioctl   = vlan_dev_ioctl;
dev-destructor = free_netdev;
diff --git a/net/core/dev.c b/net/core/dev.c
index c9c593e..edaff27 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2962,6 +2962,102 @@ int dev_unicast_add(struct net_device *dev, void *addr, 
int alen)
 }
 EXPORT_SYMBOL(dev_unicast_add);
 
+int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
+   struct dev_addr_list **from, int *from_count)
+{
+   struct dev_addr_list *da, *next;
+   int err = 0;
+
+   da = *from;
+   while (da != NULL) {
+   next = da-next;
+   if (!da-da_synced) {
+   err = __dev_addr_add(to, to_count,
+da-da_addr, da-da_addrlen, 0);
+   if (err  0

[VLAN] set_rx_mode support for unicast address list

2008-01-24 Thread Chris Leech
Reuse the existing logic for multicast list synchronization for the unicast
address list. The core of dev_mc_sync/unsync are split out as
__dev_addr_sync/unsync and moved from dev_mcast.c to dev.c.  These are then
used to implement dev_unicast_sync/unsync as well.

I'm working on cleaning up Intel's FCoE stack, which generates new MAC
addresses from the fibre channel device id assigned by the fabric as per the
current draft specification in T11.  When using such a protocol in a VLAN
environment it would be nice to not always be forced into promiscuous mode,
assuming the underlying Ethernet driver supports multiple unicast addresses as
well.

Signed-off-by: Chris Leech [EMAIL PROTECTED]
---

 include/linux/netdevice.h |4 ++
 net/8021q/vlan_dev.c  |7 ++-
 net/core/dev.c|   96 +
 net/core/dev_mcast.c  |   39 ++
 4 files changed, 110 insertions(+), 36 deletions(-)


diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b0813c3..047d432 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1414,12 +1414,16 @@ 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_unicast_sync(struct net_device *to, struct 
net_device *from);
+extern voiddev_unicast_unsync(struct net_device *to, struct 
net_device *from);
 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 int dev_mc_sync(struct net_device *to, struct net_device 
*from);
 extern voiddev_mc_unsync(struct net_device *to, struct net_device 
*from);
 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 int __dev_addr_sync(struct dev_addr_list **to, int 
*to_count, struct dev_addr_list **from, int *from_count);
+extern void__dev_addr_unsync(struct dev_addr_list **to, int 
*to_count, struct dev_addr_list **from, int *from_count);
 extern voiddev_set_promiscuity(struct net_device *dev, int inc);
 extern voiddev_set_allmulti(struct net_device *dev, int inc);
 extern voidnetdev_state_change(struct net_device *dev);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8059fa4..77f04e4 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -563,6 +563,7 @@ static int vlan_dev_stop(struct net_device *dev)
struct net_device *real_dev = vlan_dev_info(dev)-real_dev;
 
dev_mc_unsync(real_dev, dev);
+   dev_unicast_unsync(real_dev, dev);
if (dev-flags  IFF_ALLMULTI)
dev_set_allmulti(real_dev, -1);
if (dev-flags  IFF_PROMISC)
@@ -634,9 +635,10 @@ static void vlan_dev_change_rx_flags(struct net_device 
*dev, int change)
dev_set_promiscuity(real_dev, dev-flags  IFF_PROMISC ? 1 : 
-1);
 }
 
-static void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
dev_mc_sync(vlan_dev_info(vlan_dev)-real_dev, vlan_dev);
+   dev_unicast_sync(vlan_dev_info(vlan_dev)-real_dev, vlan_dev);
 }
 
 /*
@@ -702,7 +704,8 @@ void vlan_setup(struct net_device *dev)
dev-open   = vlan_dev_open;
dev-stop   = vlan_dev_stop;
dev-set_mac_address= vlan_dev_set_mac_address;
-   dev-set_multicast_list = vlan_dev_set_multicast_list;
+   dev-set_rx_mode= vlan_dev_set_rx_mode;
+   dev-set_multicast_list = vlan_dev_set_rx_mode;
dev-change_rx_flags= vlan_dev_change_rx_flags;
dev-do_ioctl   = vlan_dev_ioctl;
dev-destructor = free_netdev;
diff --git a/net/core/dev.c b/net/core/dev.c
index c9c593e..edaff27 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2962,6 +2962,102 @@ int dev_unicast_add(struct net_device *dev, void *addr, 
int alen)
 }
 EXPORT_SYMBOL(dev_unicast_add);
 
+int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
+   struct dev_addr_list **from, int *from_count)
+{
+   struct dev_addr_list *da, *next;
+   int err = 0;
+
+   da = *from;
+   while (da != NULL) {
+   next = da-next;
+   if (!da-da_synced) {
+   err = __dev_addr_add(to, to_count,
+da-da_addr, da-da_addrlen, 0);
+   if (err  0)
+   break;
+   

Re: [VLAN] set_rx_mode support for unicast address list

2008-01-24 Thread Patrick McHardy

Chris Leech wrote:

Reuse the existing logic for multicast list synchronization for the unicast
address list. The core of dev_mc_sync/unsync are split out as
__dev_addr_sync/unsync and moved from dev_mcast.c to dev.c.  These are then
used to implement dev_unicast_sync/unsync as well.

I'm working on cleaning up Intel's FCoE stack, which generates new MAC
addresses from the fibre channel device id assigned by the fabric as per the
current draft specification in T11.  When using such a protocol in a VLAN
environment it would be nice to not always be forced into promiscuous mode,
assuming the underlying Ethernet driver supports multiple unicast addresses as
well.



Looks good, applied. Thanks Chris.
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html