diff options
author | Jiri Pirko <jpirko@redhat.com> | 2009-05-22 19:22:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-30 01:12:32 -0400 |
commit | ccffad25b5136958d4769ed6de5e87992dd9c65c (patch) | |
tree | cd5f36fe67f4deeae23d76436f7a032a201cba44 | |
parent | ae63e808f508c38fe65e23a1480c85d5bd00ecbd (diff) |
net: convert unicast addr list
This patch converts unicast address list to standard list_head using
previously introduced struct netdev_hw_addr. It also relaxes the
locking. Original spinlock (still used for multicast addresses) is not
needed and is no longer used for a protection of this list. All
reading and writing takes place under rtnl (with no changes).
I also removed a possibility to specify the length of the address
while adding or deleting unicast address. It's always dev->addr_len.
The convertion touched especially e1000 and ixgbe codes when the
change is not so trivial.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
drivers/net/bnx2.c | 13 +--
drivers/net/e1000/e1000_main.c | 24 +++--
drivers/net/ixgbe/ixgbe_common.c | 14 ++--
drivers/net/ixgbe/ixgbe_common.h | 4 +-
drivers/net/ixgbe/ixgbe_main.c | 6 +-
drivers/net/ixgbe/ixgbe_type.h | 4 +-
drivers/net/macvlan.c | 11 +-
drivers/net/mv643xx_eth.c | 11 +-
drivers/net/niu.c | 7 +-
drivers/net/virtio_net.c | 7 +-
drivers/s390/net/qeth_l2_main.c | 6 +-
drivers/scsi/fcoe/fcoe.c | 16 ++--
include/linux/netdevice.h | 18 ++--
net/8021q/vlan.c | 4 +-
net/8021q/vlan_dev.c | 10 +-
net/core/dev.c | 195 +++++++++++++++++++++++++++-----------
net/dsa/slave.c | 10 +-
net/packet/af_packet.c | 4 +-
18 files changed, 227 insertions(+), 137 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bnx2.c | 13 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 24 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.c | 14 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.h | 4 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 6 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 4 | ||||
-rw-r--r-- | drivers/net/macvlan.c | 11 | ||||
-rw-r--r-- | drivers/net/mv643xx_eth.c | 11 | ||||
-rw-r--r-- | drivers/net/niu.c | 7 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 7 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 6 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 16 | ||||
-rw-r--r-- | include/linux/netdevice.h | 18 | ||||
-rw-r--r-- | net/8021q/vlan.c | 4 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 10 | ||||
-rw-r--r-- | net/core/dev.c | 195 | ||||
-rw-r--r-- | net/dsa/slave.c | 10 | ||||
-rw-r--r-- | net/packet/af_packet.c | 4 |
18 files changed, 227 insertions, 137 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 83ee0f53f2d2..f53017250e09 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/cache.h> | 48 | #include <linux/cache.h> |
49 | #include <linux/firmware.h> | 49 | #include <linux/firmware.h> |
50 | #include <linux/log2.h> | 50 | #include <linux/log2.h> |
51 | #include <linux/list.h> | ||
51 | 52 | ||
52 | #include "bnx2.h" | 53 | #include "bnx2.h" |
53 | #include "bnx2_fw.h" | 54 | #include "bnx2_fw.h" |
@@ -3310,7 +3311,7 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3310 | { | 3311 | { |
3311 | struct bnx2 *bp = netdev_priv(dev); | 3312 | struct bnx2 *bp = netdev_priv(dev); |
3312 | u32 rx_mode, sort_mode; | 3313 | u32 rx_mode, sort_mode; |
3313 | struct dev_addr_list *uc_ptr; | 3314 | struct netdev_hw_addr *ha; |
3314 | int i; | 3315 | int i; |
3315 | 3316 | ||
3316 | if (!netif_running(dev)) | 3317 | if (!netif_running(dev)) |
@@ -3369,21 +3370,19 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3369 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; | 3370 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; |
3370 | } | 3371 | } |
3371 | 3372 | ||
3372 | uc_ptr = NULL; | ||
3373 | if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { | 3373 | if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { |
3374 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; | 3374 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; |
3375 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | | 3375 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | |
3376 | BNX2_RPM_SORT_USER0_PROM_VLAN; | 3376 | BNX2_RPM_SORT_USER0_PROM_VLAN; |
3377 | } else if (!(dev->flags & IFF_PROMISC)) { | 3377 | } else if (!(dev->flags & IFF_PROMISC)) { |
3378 | uc_ptr = dev->uc_list; | ||
3379 | |||
3380 | /* Add all entries into to the match filter list */ | 3378 | /* Add all entries into to the match filter list */ |
3381 | for (i = 0; i < dev->uc_count; i++) { | 3379 | i = 0; |
3382 | bnx2_set_mac_addr(bp, uc_ptr->da_addr, | 3380 | list_for_each_entry(ha, &dev->uc_list, list) { |
3381 | bnx2_set_mac_addr(bp, ha->addr, | ||
3383 | i + BNX2_START_UNICAST_ADDRESS_INDEX); | 3382 | i + BNX2_START_UNICAST_ADDRESS_INDEX); |
3384 | sort_mode |= (1 << | 3383 | sort_mode |= (1 << |
3385 | (i + BNX2_START_UNICAST_ADDRESS_INDEX)); | 3384 | (i + BNX2_START_UNICAST_ADDRESS_INDEX)); |
3386 | uc_ptr = uc_ptr->next; | 3385 | i++; |
3387 | } | 3386 | } |
3388 | 3387 | ||
3389 | } | 3388 | } |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 79fe1ee3da52..74667e521431 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2330,7 +2330,8 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2330 | { | 2330 | { |
2331 | struct e1000_adapter *adapter = netdev_priv(netdev); | 2331 | struct e1000_adapter *adapter = netdev_priv(netdev); |
2332 | struct e1000_hw *hw = &adapter->hw; | 2332 | struct e1000_hw *hw = &adapter->hw; |
2333 | struct dev_addr_list *uc_ptr; | 2333 | struct netdev_hw_addr *ha; |
2334 | bool use_uc = false; | ||
2334 | struct dev_addr_list *mc_ptr; | 2335 | struct dev_addr_list *mc_ptr; |
2335 | u32 rctl; | 2336 | u32 rctl; |
2336 | u32 hash_value; | 2337 | u32 hash_value; |
@@ -2369,12 +2370,11 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2369 | rctl |= E1000_RCTL_VFE; | 2370 | rctl |= E1000_RCTL_VFE; |
2370 | } | 2371 | } |
2371 | 2372 | ||
2372 | uc_ptr = NULL; | ||
2373 | if (netdev->uc_count > rar_entries - 1) { | 2373 | if (netdev->uc_count > rar_entries - 1) { |
2374 | rctl |= E1000_RCTL_UPE; | 2374 | rctl |= E1000_RCTL_UPE; |
2375 | } else if (!(netdev->flags & IFF_PROMISC)) { | 2375 | } else if (!(netdev->flags & IFF_PROMISC)) { |
2376 | rctl &= ~E1000_RCTL_UPE; | 2376 | rctl &= ~E1000_RCTL_UPE; |
2377 | uc_ptr = netdev->uc_list; | 2377 | use_uc = true; |
2378 | } | 2378 | } |
2379 | 2379 | ||
2380 | ew32(RCTL, rctl); | 2380 | ew32(RCTL, rctl); |
@@ -2392,13 +2392,20 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2392 | * if there are not 14 addresses, go ahead and clear the filters | 2392 | * if there are not 14 addresses, go ahead and clear the filters |
2393 | * -- with 82571 controllers only 0-13 entries are filled here | 2393 | * -- with 82571 controllers only 0-13 entries are filled here |
2394 | */ | 2394 | */ |
2395 | i = 1; | ||
2396 | if (use_uc) | ||
2397 | list_for_each_entry(ha, &netdev->uc_list, list) { | ||
2398 | if (i == rar_entries) | ||
2399 | break; | ||
2400 | e1000_rar_set(hw, ha->addr, i++); | ||
2401 | } | ||
2402 | |||
2403 | WARN_ON(i == rar_entries); | ||
2404 | |||
2395 | mc_ptr = netdev->mc_list; | 2405 | mc_ptr = netdev->mc_list; |
2396 | 2406 | ||
2397 | for (i = 1; i < rar_entries; i++) { | 2407 | for (; i < rar_entries; i++) { |
2398 | if (uc_ptr) { | 2408 | if (mc_ptr) { |
2399 | e1000_rar_set(hw, uc_ptr->da_addr, i); | ||
2400 | uc_ptr = uc_ptr->next; | ||
2401 | } else if (mc_ptr) { | ||
2402 | e1000_rar_set(hw, mc_ptr->da_addr, i); | 2409 | e1000_rar_set(hw, mc_ptr->da_addr, i); |
2403 | mc_ptr = mc_ptr->next; | 2410 | mc_ptr = mc_ptr->next; |
2404 | } else { | 2411 | } else { |
@@ -2408,7 +2415,6 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2408 | E1000_WRITE_FLUSH(); | 2415 | E1000_WRITE_FLUSH(); |
2409 | } | 2416 | } |
2410 | } | 2417 | } |
2411 | WARN_ON(uc_ptr != NULL); | ||
2412 | 2418 | ||
2413 | /* load any remaining addresses into the hash table */ | 2419 | /* load any remaining addresses into the hash table */ |
2414 | 2420 | ||
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 0cc3c47cb453..6f79409270a7 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/list.h> | ||
32 | #include <linux/netdevice.h> | ||
31 | 33 | ||
32 | #include "ixgbe.h" | 34 | #include "ixgbe.h" |
33 | #include "ixgbe_common.h" | 35 | #include "ixgbe_common.h" |
@@ -1356,15 +1358,14 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) | |||
1356 | * Drivers using secondary unicast addresses must set user_set_promisc when | 1358 | * Drivers using secondary unicast addresses must set user_set_promisc when |
1357 | * manually putting the device into promiscuous mode. | 1359 | * manually putting the device into promiscuous mode. |
1358 | **/ | 1360 | **/ |
1359 | s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, | 1361 | s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, |
1360 | u32 addr_count, ixgbe_mc_addr_itr next) | 1362 | struct list_head *uc_list) |
1361 | { | 1363 | { |
1362 | u8 *addr; | ||
1363 | u32 i; | 1364 | u32 i; |
1364 | u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; | 1365 | u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; |
1365 | u32 uc_addr_in_use; | 1366 | u32 uc_addr_in_use; |
1366 | u32 fctrl; | 1367 | u32 fctrl; |
1367 | u32 vmdq; | 1368 | struct netdev_hw_addr *ha; |
1368 | 1369 | ||
1369 | /* | 1370 | /* |
1370 | * Clear accounting of old secondary address list, | 1371 | * Clear accounting of old secondary address list, |
@@ -1382,10 +1383,9 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, | |||
1382 | } | 1383 | } |
1383 | 1384 | ||
1384 | /* Add the new addresses */ | 1385 | /* Add the new addresses */ |
1385 | for (i = 0; i < addr_count; i++) { | 1386 | list_for_each_entry(ha, uc_list, list) { |
1386 | hw_dbg(hw, " Adding the secondary addresses:\n"); | 1387 | hw_dbg(hw, " Adding the secondary addresses:\n"); |
1387 | addr = next(hw, &addr_list, &vmdq); | 1388 | ixgbe_add_uc_addr(hw, ha->addr, 0); |
1388 | ixgbe_add_uc_addr(hw, addr, vmdq); | ||
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | if (hw->addr_ctrl.overflow_promisc) { | 1391 | if (hw->addr_ctrl.overflow_promisc) { |
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index dd260890ad0a..b2a4b2c99c40 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h | |||
@@ -59,8 +59,8 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); | |||
59 | s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, | 59 | s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, |
60 | u32 mc_addr_count, | 60 | u32 mc_addr_count, |
61 | ixgbe_mc_addr_itr func); | 61 | ixgbe_mc_addr_itr func); |
62 | s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, | 62 | s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, |
63 | u32 addr_count, ixgbe_mc_addr_itr func); | 63 | struct list_head *uc_list); |
64 | s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); | 64 | s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); |
65 | s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); | 65 | s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); |
66 | s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); | 66 | s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 924aa5ed02ce..de70a2df9aeb 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2181,11 +2181,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev) | |||
2181 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 2181 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
2182 | 2182 | ||
2183 | /* reprogram secondary unicast list */ | 2183 | /* reprogram secondary unicast list */ |
2184 | addr_count = netdev->uc_count; | 2184 | hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list); |
2185 | if (addr_count) | ||
2186 | addr_list = netdev->uc_list->dmi_addr; | ||
2187 | hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count, | ||
2188 | ixgbe_addr_list_itr); | ||
2189 | 2185 | ||
2190 | /* reprogram multicast list */ | 2186 | /* reprogram multicast list */ |
2191 | addr_count = netdev->mc_count; | 2187 | addr_count = netdev->mc_count; |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index df1f7034c284..a8a8243d8fdb 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/mdio.h> | 32 | #include <linux/mdio.h> |
33 | #include <linux/list.h> | ||
33 | 34 | ||
34 | /* Vendor ID */ | 35 | /* Vendor ID */ |
35 | #define IXGBE_INTEL_VENDOR_ID 0x8086 | 36 | #define IXGBE_INTEL_VENDOR_ID 0x8086 |
@@ -2223,8 +2224,7 @@ struct ixgbe_mac_operations { | |||
2223 | s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); | 2224 | s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); |
2224 | s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); | 2225 | s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); |
2225 | s32 (*init_rx_addrs)(struct ixgbe_hw *); | 2226 | s32 (*init_rx_addrs)(struct ixgbe_hw *); |
2226 | s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32, | 2227 | s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *); |
2227 | ixgbe_mc_addr_itr); | ||
2228 | s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, | 2228 | s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, |
2229 | ixgbe_mc_addr_itr); | 2229 | ixgbe_mc_addr_itr); |
2230 | s32 (*enable_mc)(struct ixgbe_hw *); | 2230 | s32 (*enable_mc)(struct ixgbe_hw *); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index d5334b41e4b4..021d9941c292 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -232,7 +232,7 @@ static int macvlan_open(struct net_device *dev) | |||
232 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) | 232 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) |
233 | goto out; | 233 | goto out; |
234 | 234 | ||
235 | err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN); | 235 | err = dev_unicast_add(lowerdev, dev->dev_addr); |
236 | if (err < 0) | 236 | if (err < 0) |
237 | goto out; | 237 | goto out; |
238 | if (dev->flags & IFF_ALLMULTI) { | 238 | if (dev->flags & IFF_ALLMULTI) { |
@@ -244,7 +244,7 @@ static int macvlan_open(struct net_device *dev) | |||
244 | return 0; | 244 | return 0; |
245 | 245 | ||
246 | del_unicast: | 246 | del_unicast: |
247 | dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); | 247 | dev_unicast_delete(lowerdev, dev->dev_addr); |
248 | out: | 248 | out: |
249 | return err; | 249 | return err; |
250 | } | 250 | } |
@@ -258,7 +258,7 @@ static int macvlan_stop(struct net_device *dev) | |||
258 | if (dev->flags & IFF_ALLMULTI) | 258 | if (dev->flags & IFF_ALLMULTI) |
259 | dev_set_allmulti(lowerdev, -1); | 259 | dev_set_allmulti(lowerdev, -1); |
260 | 260 | ||
261 | dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); | 261 | dev_unicast_delete(lowerdev, dev->dev_addr); |
262 | 262 | ||
263 | macvlan_hash_del(vlan); | 263 | macvlan_hash_del(vlan); |
264 | return 0; | 264 | return 0; |
@@ -282,10 +282,11 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p) | |||
282 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) | 282 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) |
283 | return -EBUSY; | 283 | return -EBUSY; |
284 | 284 | ||
285 | if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN))) | 285 | err = dev_unicast_add(lowerdev, addr->sa_data); |
286 | if (err) | ||
286 | return err; | 287 | return err; |
287 | 288 | ||
288 | dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); | 289 | dev_unicast_delete(lowerdev, dev->dev_addr); |
289 | 290 | ||
290 | macvlan_hash_change_addr(vlan, addr->sa_data); | 291 | macvlan_hash_change_addr(vlan, addr->sa_data); |
291 | } | 292 | } |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 1361ddc8d31f..b4e18a58cb1b 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/types.h> | 55 | #include <linux/types.h> |
56 | #include <linux/inet_lro.h> | 56 | #include <linux/inet_lro.h> |
57 | #include <asm/system.h> | 57 | #include <asm/system.h> |
58 | #include <linux/list.h> | ||
58 | 59 | ||
59 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; | 60 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; |
60 | static char mv643xx_eth_driver_version[] = "1.4"; | 61 | static char mv643xx_eth_driver_version[] = "1.4"; |
@@ -1721,20 +1722,20 @@ static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr) | |||
1721 | 1722 | ||
1722 | static u32 uc_addr_filter_mask(struct net_device *dev) | 1723 | static u32 uc_addr_filter_mask(struct net_device *dev) |
1723 | { | 1724 | { |
1724 | struct dev_addr_list *uc_ptr; | 1725 | struct netdev_hw_addr *ha; |
1725 | u32 nibbles; | 1726 | u32 nibbles; |
1726 | 1727 | ||
1727 | if (dev->flags & IFF_PROMISC) | 1728 | if (dev->flags & IFF_PROMISC) |
1728 | return 0; | 1729 | return 0; |
1729 | 1730 | ||
1730 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); | 1731 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); |
1731 | for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) { | 1732 | list_for_each_entry(ha, &dev->uc_list, list) { |
1732 | if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5)) | 1733 | if (memcmp(dev->dev_addr, ha->addr, 5)) |
1733 | return 0; | 1734 | return 0; |
1734 | if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0) | 1735 | if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) |
1735 | return 0; | 1736 | return 0; |
1736 | 1737 | ||
1737 | nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f); | 1738 | nibbles |= 1 << (ha->addr[5] & 0x0f); |
1738 | } | 1739 | } |
1739 | 1740 | ||
1740 | return nibbles; | 1741 | return nibbles; |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index edac3a0b02d6..fa61a12c5e15 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/log2.h> | 22 | #include <linux/log2.h> |
23 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
24 | #include <linux/crc32.h> | 24 | #include <linux/crc32.h> |
25 | #include <linux/list.h> | ||
25 | 26 | ||
26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
27 | 28 | ||
@@ -6362,6 +6363,7 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6362 | struct niu *np = netdev_priv(dev); | 6363 | struct niu *np = netdev_priv(dev); |
6363 | int i, alt_cnt, err; | 6364 | int i, alt_cnt, err; |
6364 | struct dev_addr_list *addr; | 6365 | struct dev_addr_list *addr; |
6366 | struct netdev_hw_addr *ha; | ||
6365 | unsigned long flags; | 6367 | unsigned long flags; |
6366 | u16 hash[16] = { 0, }; | 6368 | u16 hash[16] = { 0, }; |
6367 | 6369 | ||
@@ -6383,9 +6385,8 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6383 | if (alt_cnt) { | 6385 | if (alt_cnt) { |
6384 | int index = 0; | 6386 | int index = 0; |
6385 | 6387 | ||
6386 | for (addr = dev->uc_list; addr; addr = addr->next) { | 6388 | list_for_each_entry(ha, &dev->uc_list, list) { |
6387 | err = niu_set_alt_mac(np, index, | 6389 | err = niu_set_alt_mac(np, index, ha->addr); |
6388 | addr->da_addr); | ||
6389 | if (err) | 6390 | if (err) |
6390 | printk(KERN_WARNING PFX "%s: Error %d " | 6391 | printk(KERN_WARNING PFX "%s: Error %d " |
6391 | "adding alt mac %d\n", | 6392 | "adding alt mac %d\n", |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 6cc5bcd34fb0..0c9ca67f66e6 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -680,6 +680,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
680 | u8 promisc, allmulti; | 680 | u8 promisc, allmulti; |
681 | struct virtio_net_ctrl_mac *mac_data; | 681 | struct virtio_net_ctrl_mac *mac_data; |
682 | struct dev_addr_list *addr; | 682 | struct dev_addr_list *addr; |
683 | struct netdev_hw_addr *ha; | ||
683 | void *buf; | 684 | void *buf; |
684 | int i; | 685 | int i; |
685 | 686 | ||
@@ -718,9 +719,9 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
718 | 719 | ||
719 | /* Store the unicast list and count in the front of the buffer */ | 720 | /* Store the unicast list and count in the front of the buffer */ |
720 | mac_data->entries = dev->uc_count; | 721 | mac_data->entries = dev->uc_count; |
721 | addr = dev->uc_list; | 722 | i = 0; |
722 | for (i = 0; i < dev->uc_count; i++, addr = addr->next) | 723 | list_for_each_entry(ha, &dev->uc_list, list) |
723 | memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN); | 724 | memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); |
724 | 725 | ||
725 | sg_set_buf(&sg[0], mac_data, | 726 | sg_set_buf(&sg[0], mac_data, |
726 | sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN)); | 727 | sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN)); |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 9ca6bab7c9ba..ecd3d06c0d5c 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/etherdevice.h> | 19 | #include <linux/etherdevice.h> |
20 | #include <linux/mii.h> | 20 | #include <linux/mii.h> |
21 | #include <linux/ip.h> | 21 | #include <linux/ip.h> |
22 | #include <linux/list.h> | ||
22 | 23 | ||
23 | #include "qeth_core.h" | 24 | #include "qeth_core.h" |
24 | 25 | ||
@@ -640,6 +641,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) | |||
640 | { | 641 | { |
641 | struct qeth_card *card = dev->ml_priv; | 642 | struct qeth_card *card = dev->ml_priv; |
642 | struct dev_addr_list *dm; | 643 | struct dev_addr_list *dm; |
644 | struct netdev_hw_addr *ha; | ||
643 | 645 | ||
644 | if (card->info.type == QETH_CARD_TYPE_OSN) | 646 | if (card->info.type == QETH_CARD_TYPE_OSN) |
645 | return ; | 647 | return ; |
@@ -653,8 +655,8 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) | |||
653 | for (dm = dev->mc_list; dm; dm = dm->next) | 655 | for (dm = dev->mc_list; dm; dm = dm->next) |
654 | qeth_l2_add_mc(card, dm->da_addr, 0); | 656 | qeth_l2_add_mc(card, dm->da_addr, 0); |
655 | 657 | ||
656 | for (dm = dev->uc_list; dm; dm = dm->next) | 658 | list_for_each_entry(ha, &dev->uc_list, list) |
657 | qeth_l2_add_mc(card, dm->da_addr, 1); | 659 | qeth_l2_add_mc(card, ha->addr, 1); |
658 | 660 | ||
659 | spin_unlock_bh(&card->mclock); | 661 | spin_unlock_bh(&card->mclock); |
660 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) | 662 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index ce33f107b0a0..f791348871fc 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -182,8 +182,8 @@ static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) | |||
182 | fc = fcoe_from_ctlr(fip); | 182 | fc = fcoe_from_ctlr(fip); |
183 | rtnl_lock(); | 183 | rtnl_lock(); |
184 | if (!is_zero_ether_addr(old)) | 184 | if (!is_zero_ether_addr(old)) |
185 | dev_unicast_delete(fc->real_dev, old, ETH_ALEN); | 185 | dev_unicast_delete(fc->real_dev, old); |
186 | dev_unicast_add(fc->real_dev, new, ETH_ALEN); | 186 | dev_unicast_add(fc->real_dev, new); |
187 | rtnl_unlock(); | 187 | rtnl_unlock(); |
188 | } | 188 | } |
189 | 189 | ||
@@ -233,13 +233,11 @@ void fcoe_netdev_cleanup(struct fcoe_softc *fc) | |||
233 | /* Delete secondary MAC addresses */ | 233 | /* Delete secondary MAC addresses */ |
234 | rtnl_lock(); | 234 | rtnl_lock(); |
235 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | 235 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); |
236 | dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN); | 236 | dev_unicast_delete(fc->real_dev, flogi_maddr); |
237 | if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) | 237 | if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) |
238 | dev_unicast_delete(fc->real_dev, | 238 | dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr); |
239 | fc->ctlr.data_src_addr, ETH_ALEN); | ||
240 | if (fc->ctlr.spma) | 239 | if (fc->ctlr.spma) |
241 | dev_unicast_delete(fc->real_dev, | 240 | dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr); |
242 | fc->ctlr.ctl_src_addr, ETH_ALEN); | ||
243 | dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | 241 | dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); |
244 | rtnl_unlock(); | 242 | rtnl_unlock(); |
245 | } | 243 | } |
@@ -347,9 +345,9 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
347 | */ | 345 | */ |
348 | rtnl_lock(); | 346 | rtnl_lock(); |
349 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | 347 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); |
350 | dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN); | 348 | dev_unicast_add(fc->real_dev, flogi_maddr); |
351 | if (fc->ctlr.spma) | 349 | if (fc->ctlr.spma) |
352 | dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr, ETH_ALEN); | 350 | dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr); |
353 | dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | 351 | dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); |
354 | rtnl_unlock(); | 352 | rtnl_unlock(); |
355 | 353 | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1eaf5ae14fea..bbfabf3012b6 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -215,9 +215,12 @@ struct netdev_hw_addr { | |||
215 | struct list_head list; | 215 | struct list_head list; |
216 | unsigned char addr[MAX_ADDR_LEN]; | 216 | unsigned char addr[MAX_ADDR_LEN]; |
217 | unsigned char type; | 217 | unsigned char type; |
218 | #define NETDEV_HW_ADDR_T_LAN 1 | 218 | #define NETDEV_HW_ADDR_T_LAN 1 |
219 | #define NETDEV_HW_ADDR_T_SAN 2 | 219 | #define NETDEV_HW_ADDR_T_SAN 2 |
220 | #define NETDEV_HW_ADDR_T_SLAVE 3 | 220 | #define NETDEV_HW_ADDR_T_SLAVE 3 |
221 | #define NETDEV_HW_ADDR_T_UNICAST 4 | ||
222 | int refcount; | ||
223 | bool synced; | ||
221 | struct rcu_head rcu_head; | 224 | struct rcu_head rcu_head; |
222 | }; | 225 | }; |
223 | 226 | ||
@@ -773,10 +776,11 @@ struct net_device | |||
773 | unsigned char addr_len; /* hardware address length */ | 776 | unsigned char addr_len; /* hardware address length */ |
774 | unsigned short dev_id; /* for shared network cards */ | 777 | unsigned short dev_id; /* for shared network cards */ |
775 | 778 | ||
776 | spinlock_t addr_list_lock; | 779 | struct list_head uc_list; /* Secondary unicast mac |
777 | struct dev_addr_list *uc_list; /* Secondary unicast mac addresses */ | 780 | addresses */ |
778 | int uc_count; /* Number of installed ucasts */ | 781 | int uc_count; /* Number of installed ucasts */ |
779 | int uc_promisc; | 782 | int uc_promisc; |
783 | spinlock_t addr_list_lock; | ||
780 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ | 784 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ |
781 | int mc_count; /* Number of installed mcasts */ | 785 | int mc_count; /* Number of installed mcasts */ |
782 | unsigned int promiscuity; | 786 | unsigned int promiscuity; |
@@ -1836,8 +1840,8 @@ extern int dev_addr_del_multiple(struct net_device *to_dev, | |||
1836 | /* Functions used for secondary unicast and multicast support */ | 1840 | /* Functions used for secondary unicast and multicast support */ |
1837 | extern void dev_set_rx_mode(struct net_device *dev); | 1841 | extern void dev_set_rx_mode(struct net_device *dev); |
1838 | extern void __dev_set_rx_mode(struct net_device *dev); | 1842 | extern void __dev_set_rx_mode(struct net_device *dev); |
1839 | extern int dev_unicast_delete(struct net_device *dev, void *addr, int alen); | 1843 | extern int dev_unicast_delete(struct net_device *dev, void *addr); |
1840 | extern int dev_unicast_add(struct net_device *dev, void *addr, int alen); | 1844 | extern int dev_unicast_add(struct net_device *dev, void *addr); |
1841 | extern int dev_unicast_sync(struct net_device *to, struct net_device *from); | 1845 | extern int dev_unicast_sync(struct net_device *to, struct net_device *from); |
1842 | extern void dev_unicast_unsync(struct net_device *to, struct net_device *from); | 1846 | extern void dev_unicast_unsync(struct net_device *to, struct net_device *from); |
1843 | extern int dev_mc_delete(struct net_device *dev, void *addr, int alen, int all); | 1847 | extern int dev_mc_delete(struct net_device *dev, void *addr, int alen, int all); |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index d1e10546eb85..714e1c3536be 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -378,13 +378,13 @@ static void vlan_sync_address(struct net_device *dev, | |||
378 | * the new address */ | 378 | * the new address */ |
379 | if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && | 379 | if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
380 | !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) | 380 | !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
381 | dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN); | 381 | dev_unicast_delete(dev, vlandev->dev_addr); |
382 | 382 | ||
383 | /* vlan address was equal to the old address and is different from | 383 | /* vlan address was equal to the old address and is different from |
384 | * the new address */ | 384 | * the new address */ |
385 | if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && | 385 | if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
386 | compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) | 386 | compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
387 | dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN); | 387 | dev_unicast_add(dev, vlandev->dev_addr); |
388 | 388 | ||
389 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); | 389 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); |
390 | } | 390 | } |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 1e2ad4c7c59b..96bad8f233e2 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -441,7 +441,7 @@ static int vlan_dev_open(struct net_device *dev) | |||
441 | return -ENETDOWN; | 441 | return -ENETDOWN; |
442 | 442 | ||
443 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { | 443 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { |
444 | err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN); | 444 | err = dev_unicast_add(real_dev, dev->dev_addr); |
445 | if (err < 0) | 445 | if (err < 0) |
446 | goto out; | 446 | goto out; |
447 | } | 447 | } |
@@ -470,7 +470,7 @@ clear_allmulti: | |||
470 | dev_set_allmulti(real_dev, -1); | 470 | dev_set_allmulti(real_dev, -1); |
471 | del_unicast: | 471 | del_unicast: |
472 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 472 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
473 | dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); | 473 | dev_unicast_delete(real_dev, dev->dev_addr); |
474 | out: | 474 | out: |
475 | netif_carrier_off(dev); | 475 | netif_carrier_off(dev); |
476 | return err; | 476 | return err; |
@@ -492,7 +492,7 @@ static int vlan_dev_stop(struct net_device *dev) | |||
492 | dev_set_promiscuity(real_dev, -1); | 492 | dev_set_promiscuity(real_dev, -1); |
493 | 493 | ||
494 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 494 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
495 | dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); | 495 | dev_unicast_delete(real_dev, dev->dev_addr); |
496 | 496 | ||
497 | netif_carrier_off(dev); | 497 | netif_carrier_off(dev); |
498 | return 0; | 498 | return 0; |
@@ -511,13 +511,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) | |||
511 | goto out; | 511 | goto out; |
512 | 512 | ||
513 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { | 513 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { |
514 | err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); | 514 | err = dev_unicast_add(real_dev, addr->sa_data); |
515 | if (err < 0) | 515 | if (err < 0) |
516 | return err; | 516 | return err; |
517 | } | 517 | } |
518 | 518 | ||
519 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 519 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
520 | dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); | 520 | dev_unicast_delete(real_dev, dev->dev_addr); |
521 | 521 | ||
522 | out: | 522 | out: |
523 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 523 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
diff --git a/net/core/dev.c b/net/core/dev.c index 32ceee17896e..e2fcc5f10177 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3473,8 +3473,9 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3473 | 3473 | ||
3474 | /* hw addresses list handling functions */ | 3474 | /* hw addresses list handling functions */ |
3475 | 3475 | ||
3476 | static int __hw_addr_add(struct list_head *list, unsigned char *addr, | 3476 | static int __hw_addr_add(struct list_head *list, int *delta, |
3477 | int addr_len, unsigned char addr_type) | 3477 | unsigned char *addr, int addr_len, |
3478 | unsigned char addr_type) | ||
3478 | { | 3479 | { |
3479 | struct netdev_hw_addr *ha; | 3480 | struct netdev_hw_addr *ha; |
3480 | int alloc_size; | 3481 | int alloc_size; |
@@ -3482,6 +3483,15 @@ static int __hw_addr_add(struct list_head *list, unsigned char *addr, | |||
3482 | if (addr_len > MAX_ADDR_LEN) | 3483 | if (addr_len > MAX_ADDR_LEN) |
3483 | return -EINVAL; | 3484 | return -EINVAL; |
3484 | 3485 | ||
3486 | list_for_each_entry(ha, list, list) { | ||
3487 | if (!memcmp(ha->addr, addr, addr_len) && | ||
3488 | ha->type == addr_type) { | ||
3489 | ha->refcount++; | ||
3490 | return 0; | ||
3491 | } | ||
3492 | } | ||
3493 | |||
3494 | |||
3485 | alloc_size = sizeof(*ha); | 3495 | alloc_size = sizeof(*ha); |
3486 | if (alloc_size < L1_CACHE_BYTES) | 3496 | if (alloc_size < L1_CACHE_BYTES) |
3487 | alloc_size = L1_CACHE_BYTES; | 3497 | alloc_size = L1_CACHE_BYTES; |
@@ -3490,7 +3500,11 @@ static int __hw_addr_add(struct list_head *list, unsigned char *addr, | |||
3490 | return -ENOMEM; | 3500 | return -ENOMEM; |
3491 | memcpy(ha->addr, addr, addr_len); | 3501 | memcpy(ha->addr, addr, addr_len); |
3492 | ha->type = addr_type; | 3502 | ha->type = addr_type; |
3503 | ha->refcount = 1; | ||
3504 | ha->synced = false; | ||
3493 | list_add_tail_rcu(&ha->list, list); | 3505 | list_add_tail_rcu(&ha->list, list); |
3506 | if (delta) | ||
3507 | (*delta)++; | ||
3494 | return 0; | 3508 | return 0; |
3495 | } | 3509 | } |
3496 | 3510 | ||
@@ -3502,29 +3516,30 @@ static void ha_rcu_free(struct rcu_head *head) | |||
3502 | kfree(ha); | 3516 | kfree(ha); |
3503 | } | 3517 | } |
3504 | 3518 | ||
3505 | static int __hw_addr_del_ii(struct list_head *list, unsigned char *addr, | 3519 | static int __hw_addr_del(struct list_head *list, int *delta, |
3506 | int addr_len, unsigned char addr_type, | 3520 | unsigned char *addr, int addr_len, |
3507 | int ignore_index) | 3521 | unsigned char addr_type) |
3508 | { | 3522 | { |
3509 | struct netdev_hw_addr *ha; | 3523 | struct netdev_hw_addr *ha; |
3510 | int i = 0; | ||
3511 | 3524 | ||
3512 | list_for_each_entry(ha, list, list) { | 3525 | list_for_each_entry(ha, list, list) { |
3513 | if (i++ != ignore_index && | 3526 | if (!memcmp(ha->addr, addr, addr_len) && |
3514 | !memcmp(ha->addr, addr, addr_len) && | ||
3515 | (ha->type == addr_type || !addr_type)) { | 3527 | (ha->type == addr_type || !addr_type)) { |
3528 | if (--ha->refcount) | ||
3529 | return 0; | ||
3516 | list_del_rcu(&ha->list); | 3530 | list_del_rcu(&ha->list); |
3517 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3531 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3532 | if (delta) | ||
3533 | (*delta)--; | ||
3518 | return 0; | 3534 | return 0; |
3519 | } | 3535 | } |
3520 | } | 3536 | } |
3521 | return -ENOENT; | 3537 | return -ENOENT; |
3522 | } | 3538 | } |
3523 | 3539 | ||
3524 | static int __hw_addr_add_multiple_ii(struct list_head *to_list, | 3540 | static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, |
3525 | struct list_head *from_list, | 3541 | struct list_head *from_list, int addr_len, |
3526 | int addr_len, unsigned char addr_type, | 3542 | unsigned char addr_type) |
3527 | int ignore_index) | ||
3528 | { | 3543 | { |
3529 | int err; | 3544 | int err; |
3530 | struct netdev_hw_addr *ha, *ha2; | 3545 | struct netdev_hw_addr *ha, *ha2; |
@@ -3532,7 +3547,8 @@ static int __hw_addr_add_multiple_ii(struct list_head *to_list, | |||
3532 | 3547 | ||
3533 | list_for_each_entry(ha, from_list, list) { | 3548 | list_for_each_entry(ha, from_list, list) { |
3534 | type = addr_type ? addr_type : ha->type; | 3549 | type = addr_type ? addr_type : ha->type; |
3535 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); | 3550 | err = __hw_addr_add(to_list, to_delta, ha->addr, |
3551 | addr_len, type); | ||
3536 | if (err) | 3552 | if (err) |
3537 | goto unroll; | 3553 | goto unroll; |
3538 | } | 3554 | } |
@@ -3543,27 +3559,69 @@ unroll: | |||
3543 | if (ha2 == ha) | 3559 | if (ha2 == ha) |
3544 | break; | 3560 | break; |
3545 | type = addr_type ? addr_type : ha2->type; | 3561 | type = addr_type ? addr_type : ha2->type; |
3546 | __hw_addr_del_ii(to_list, ha2->addr, addr_len, type, | 3562 | __hw_addr_del(to_list, to_delta, ha2->addr, |
3547 | ignore_index); | 3563 | addr_len, type); |
3548 | } | 3564 | } |
3549 | return err; | 3565 | return err; |
3550 | } | 3566 | } |
3551 | 3567 | ||
3552 | static void __hw_addr_del_multiple_ii(struct list_head *to_list, | 3568 | static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, |
3553 | struct list_head *from_list, | 3569 | struct list_head *from_list, int addr_len, |
3554 | int addr_len, unsigned char addr_type, | 3570 | unsigned char addr_type) |
3555 | int ignore_index) | ||
3556 | { | 3571 | { |
3557 | struct netdev_hw_addr *ha; | 3572 | struct netdev_hw_addr *ha; |
3558 | unsigned char type; | 3573 | unsigned char type; |
3559 | 3574 | ||
3560 | list_for_each_entry(ha, from_list, list) { | 3575 | list_for_each_entry(ha, from_list, list) { |
3561 | type = addr_type ? addr_type : ha->type; | 3576 | type = addr_type ? addr_type : ha->type; |
3562 | __hw_addr_del_ii(to_list, ha->addr, addr_len, addr_type, | 3577 | __hw_addr_del(to_list, to_delta, ha->addr, |
3563 | ignore_index); | 3578 | addr_len, addr_type); |
3579 | } | ||
3580 | } | ||
3581 | |||
3582 | static int __hw_addr_sync(struct list_head *to_list, int *to_delta, | ||
3583 | struct list_head *from_list, int *from_delta, | ||
3584 | int addr_len) | ||
3585 | { | ||
3586 | int err = 0; | ||
3587 | struct netdev_hw_addr *ha, *tmp; | ||
3588 | |||
3589 | list_for_each_entry_safe(ha, tmp, from_list, list) { | ||
3590 | if (!ha->synced) { | ||
3591 | err = __hw_addr_add(to_list, to_delta, ha->addr, | ||
3592 | addr_len, ha->type); | ||
3593 | if (err) | ||
3594 | break; | ||
3595 | ha->synced = true; | ||
3596 | ha->refcount++; | ||
3597 | } else if (ha->refcount == 1) { | ||
3598 | __hw_addr_del(to_list, to_delta, ha->addr, | ||
3599 | addr_len, ha->type); | ||
3600 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3601 | addr_len, ha->type); | ||
3602 | } | ||
3564 | } | 3603 | } |
3604 | return err; | ||
3565 | } | 3605 | } |
3566 | 3606 | ||
3607 | static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, | ||
3608 | struct list_head *from_list, int *from_delta, | ||
3609 | int addr_len) | ||
3610 | { | ||
3611 | struct netdev_hw_addr *ha, *tmp; | ||
3612 | |||
3613 | list_for_each_entry_safe(ha, tmp, from_list, list) { | ||
3614 | if (ha->synced) { | ||
3615 | __hw_addr_del(to_list, to_delta, ha->addr, | ||
3616 | addr_len, ha->type); | ||
3617 | ha->synced = false; | ||
3618 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3619 | addr_len, ha->type); | ||
3620 | } | ||
3621 | } | ||
3622 | } | ||
3623 | |||
3624 | |||
3567 | static void __hw_addr_flush(struct list_head *list) | 3625 | static void __hw_addr_flush(struct list_head *list) |
3568 | { | 3626 | { |
3569 | struct netdev_hw_addr *ha, *tmp; | 3627 | struct netdev_hw_addr *ha, *tmp; |
@@ -3594,7 +3652,7 @@ static int dev_addr_init(struct net_device *dev) | |||
3594 | 3652 | ||
3595 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3653 | INIT_LIST_HEAD(&dev->dev_addr_list); |
3596 | memset(addr, 0, sizeof(*addr)); | 3654 | memset(addr, 0, sizeof(*addr)); |
3597 | err = __hw_addr_add(&dev->dev_addr_list, addr, sizeof(*addr), | 3655 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(*addr), |
3598 | NETDEV_HW_ADDR_T_LAN); | 3656 | NETDEV_HW_ADDR_T_LAN); |
3599 | if (!err) { | 3657 | if (!err) { |
3600 | /* | 3658 | /* |
@@ -3626,7 +3684,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, | |||
3626 | 3684 | ||
3627 | ASSERT_RTNL(); | 3685 | ASSERT_RTNL(); |
3628 | 3686 | ||
3629 | err = __hw_addr_add(&dev->dev_addr_list, addr, dev->addr_len, | 3687 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, |
3630 | addr_type); | 3688 | addr_type); |
3631 | if (!err) | 3689 | if (!err) |
3632 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3690 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
@@ -3649,11 +3707,20 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, | |||
3649 | unsigned char addr_type) | 3707 | unsigned char addr_type) |
3650 | { | 3708 | { |
3651 | int err; | 3709 | int err; |
3710 | struct netdev_hw_addr *ha; | ||
3652 | 3711 | ||
3653 | ASSERT_RTNL(); | 3712 | ASSERT_RTNL(); |
3654 | 3713 | ||
3655 | err = __hw_addr_del_ii(&dev->dev_addr_list, addr, dev->addr_len, | 3714 | /* |
3656 | addr_type, 0); | 3715 | * We can not remove the first address from the list because |
3716 | * dev->dev_addr points to that. | ||
3717 | */ | ||
3718 | ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); | ||
3719 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | ||
3720 | return -ENOENT; | ||
3721 | |||
3722 | err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, | ||
3723 | addr_type); | ||
3657 | if (!err) | 3724 | if (!err) |
3658 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3725 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3659 | return err; | 3726 | return err; |
@@ -3680,9 +3747,9 @@ int dev_addr_add_multiple(struct net_device *to_dev, | |||
3680 | 3747 | ||
3681 | if (from_dev->addr_len != to_dev->addr_len) | 3748 | if (from_dev->addr_len != to_dev->addr_len) |
3682 | return -EINVAL; | 3749 | return -EINVAL; |
3683 | err = __hw_addr_add_multiple_ii(&to_dev->dev_addr_list, | 3750 | err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, |
3684 | &from_dev->dev_addr_list, | 3751 | &from_dev->dev_addr_list, |
3685 | to_dev->addr_len, addr_type, 0); | 3752 | to_dev->addr_len, addr_type); |
3686 | if (!err) | 3753 | if (!err) |
3687 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3754 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3688 | return err; | 3755 | return err; |
@@ -3707,9 +3774,9 @@ int dev_addr_del_multiple(struct net_device *to_dev, | |||
3707 | 3774 | ||
3708 | if (from_dev->addr_len != to_dev->addr_len) | 3775 | if (from_dev->addr_len != to_dev->addr_len) |
3709 | return -EINVAL; | 3776 | return -EINVAL; |
3710 | __hw_addr_del_multiple_ii(&to_dev->dev_addr_list, | 3777 | __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, |
3711 | &from_dev->dev_addr_list, | 3778 | &from_dev->dev_addr_list, |
3712 | to_dev->addr_len, addr_type, 0); | 3779 | to_dev->addr_len, addr_type); |
3713 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3780 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3714 | return 0; | 3781 | return 0; |
3715 | } | 3782 | } |
@@ -3779,24 +3846,22 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, | |||
3779 | * dev_unicast_delete - Release secondary unicast address. | 3846 | * dev_unicast_delete - Release secondary unicast address. |
3780 | * @dev: device | 3847 | * @dev: device |
3781 | * @addr: address to delete | 3848 | * @addr: address to delete |
3782 | * @alen: length of @addr | ||
3783 | * | 3849 | * |
3784 | * Release reference to a secondary unicast address and remove it | 3850 | * Release reference to a secondary unicast address and remove it |
3785 | * from the device if the reference count drops to zero. | 3851 | * from the device if the reference count drops to zero. |
3786 | * | 3852 | * |
3787 | * The caller must hold the rtnl_mutex. | 3853 | * The caller must hold the rtnl_mutex. |
3788 | */ | 3854 | */ |
3789 | int dev_unicast_delete(struct net_device *dev, void *addr, int alen) | 3855 | int dev_unicast_delete(struct net_device *dev, void *addr) |
3790 | { | 3856 | { |
3791 | int err; | 3857 | int err; |
3792 | 3858 | ||
3793 | ASSERT_RTNL(); | 3859 | ASSERT_RTNL(); |
3794 | 3860 | ||
3795 | netif_addr_lock_bh(dev); | 3861 | err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, |
3796 | err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); | 3862 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); |
3797 | if (!err) | 3863 | if (!err) |
3798 | __dev_set_rx_mode(dev); | 3864 | __dev_set_rx_mode(dev); |
3799 | netif_addr_unlock_bh(dev); | ||
3800 | return err; | 3865 | return err; |
3801 | } | 3866 | } |
3802 | EXPORT_SYMBOL(dev_unicast_delete); | 3867 | EXPORT_SYMBOL(dev_unicast_delete); |
@@ -3805,24 +3870,22 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
3805 | * dev_unicast_add - add a secondary unicast address | 3870 | * dev_unicast_add - add a secondary unicast address |
3806 | * @dev: device | 3871 | * @dev: device |
3807 | * @addr: address to add | 3872 | * @addr: address to add |
3808 | * @alen: length of @addr | ||
3809 | * | 3873 | * |
3810 | * Add a secondary unicast address to the device or increase | 3874 | * Add a secondary unicast address to the device or increase |
3811 | * the reference count if it already exists. | 3875 | * the reference count if it already exists. |
3812 | * | 3876 | * |
3813 | * The caller must hold the rtnl_mutex. | 3877 | * The caller must hold the rtnl_mutex. |
3814 | */ | 3878 | */ |
3815 | int dev_unicast_add(struct net_device *dev, void *addr, int alen) | 3879 | int dev_unicast_add(struct net_device *dev, void *addr) |
3816 | { | 3880 | { |
3817 | int err; | 3881 | int err; |
3818 | 3882 | ||
3819 | ASSERT_RTNL(); | 3883 | ASSERT_RTNL(); |
3820 | 3884 | ||
3821 | netif_addr_lock_bh(dev); | 3885 | err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, |
3822 | err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); | 3886 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); |
3823 | if (!err) | 3887 | if (!err) |
3824 | __dev_set_rx_mode(dev); | 3888 | __dev_set_rx_mode(dev); |
3825 | netif_addr_unlock_bh(dev); | ||
3826 | return err; | 3889 | return err; |
3827 | } | 3890 | } |
3828 | EXPORT_SYMBOL(dev_unicast_add); | 3891 | EXPORT_SYMBOL(dev_unicast_add); |
@@ -3879,8 +3942,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, | |||
3879 | * @from: source device | 3942 | * @from: source device |
3880 | * | 3943 | * |
3881 | * Add newly added addresses to the destination device and release | 3944 | * Add newly added addresses to the destination device and release |
3882 | * addresses that have no users left. The source device must be | 3945 | * addresses that have no users left. |
3883 | * locked by netif_tx_lock_bh. | ||
3884 | * | 3946 | * |
3885 | * This function is intended to be called from the dev->set_rx_mode | 3947 | * This function is intended to be called from the dev->set_rx_mode |
3886 | * function of layered software devices. | 3948 | * function of layered software devices. |
@@ -3889,12 +3951,15 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3889 | { | 3951 | { |
3890 | int err = 0; | 3952 | int err = 0; |
3891 | 3953 | ||
3892 | netif_addr_lock_bh(to); | 3954 | ASSERT_RTNL(); |
3893 | err = __dev_addr_sync(&to->uc_list, &to->uc_count, | 3955 | |
3894 | &from->uc_list, &from->uc_count); | 3956 | if (to->addr_len != from->addr_len) |
3957 | return -EINVAL; | ||
3958 | |||
3959 | err = __hw_addr_sync(&to->uc_list, &to->uc_count, | ||
3960 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3895 | if (!err) | 3961 | if (!err) |
3896 | __dev_set_rx_mode(to); | 3962 | __dev_set_rx_mode(to); |
3897 | netif_addr_unlock_bh(to); | ||
3898 | return err; | 3963 | return err; |
3899 | } | 3964 | } |
3900 | EXPORT_SYMBOL(dev_unicast_sync); | 3965 | EXPORT_SYMBOL(dev_unicast_sync); |
@@ -3910,18 +3975,33 @@ EXPORT_SYMBOL(dev_unicast_sync); | |||
3910 | */ | 3975 | */ |
3911 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) | 3976 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) |
3912 | { | 3977 | { |
3913 | netif_addr_lock_bh(from); | 3978 | ASSERT_RTNL(); |
3914 | netif_addr_lock(to); | ||
3915 | 3979 | ||
3916 | __dev_addr_unsync(&to->uc_list, &to->uc_count, | 3980 | if (to->addr_len != from->addr_len) |
3917 | &from->uc_list, &from->uc_count); | 3981 | return; |
3918 | __dev_set_rx_mode(to); | ||
3919 | 3982 | ||
3920 | netif_addr_unlock(to); | 3983 | __hw_addr_unsync(&to->uc_list, &to->uc_count, |
3921 | netif_addr_unlock_bh(from); | 3984 | &from->uc_list, &from->uc_count, to->addr_len); |
3985 | __dev_set_rx_mode(to); | ||
3922 | } | 3986 | } |
3923 | EXPORT_SYMBOL(dev_unicast_unsync); | 3987 | EXPORT_SYMBOL(dev_unicast_unsync); |
3924 | 3988 | ||
3989 | static void dev_unicast_flush(struct net_device *dev) | ||
3990 | { | ||
3991 | /* rtnl_mutex must be held here */ | ||
3992 | |||
3993 | __hw_addr_flush(&dev->uc_list); | ||
3994 | dev->uc_count = 0; | ||
3995 | } | ||
3996 | |||
3997 | static void dev_unicast_init(struct net_device *dev) | ||
3998 | { | ||
3999 | /* rtnl_mutex must be held here */ | ||
4000 | |||
4001 | INIT_LIST_HEAD(&dev->uc_list); | ||
4002 | } | ||
4003 | |||
4004 | |||
3925 | static void __dev_addr_discard(struct dev_addr_list **list) | 4005 | static void __dev_addr_discard(struct dev_addr_list **list) |
3926 | { | 4006 | { |
3927 | struct dev_addr_list *tmp; | 4007 | struct dev_addr_list *tmp; |
@@ -3940,9 +4020,6 @@ static void dev_addr_discard(struct net_device *dev) | |||
3940 | { | 4020 | { |
3941 | netif_addr_lock_bh(dev); | 4021 | netif_addr_lock_bh(dev); |
3942 | 4022 | ||
3943 | __dev_addr_discard(&dev->uc_list); | ||
3944 | dev->uc_count = 0; | ||
3945 | |||
3946 | __dev_addr_discard(&dev->mc_list); | 4023 | __dev_addr_discard(&dev->mc_list); |
3947 | dev->mc_count = 0; | 4024 | dev->mc_count = 0; |
3948 | 4025 | ||
@@ -4535,6 +4612,7 @@ static void rollback_registered(struct net_device *dev) | |||
4535 | /* | 4612 | /* |
4536 | * Flush the unicast and multicast chains | 4613 | * Flush the unicast and multicast chains |
4537 | */ | 4614 | */ |
4615 | dev_unicast_flush(dev); | ||
4538 | dev_addr_discard(dev); | 4616 | dev_addr_discard(dev); |
4539 | 4617 | ||
4540 | if (dev->netdev_ops->ndo_uninit) | 4618 | if (dev->netdev_ops->ndo_uninit) |
@@ -5020,6 +5098,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5020 | if (dev_addr_init(dev)) | 5098 | if (dev_addr_init(dev)) |
5021 | goto free_tx; | 5099 | goto free_tx; |
5022 | 5100 | ||
5101 | dev_unicast_init(dev); | ||
5102 | |||
5023 | dev_net_set(dev, &init_net); | 5103 | dev_net_set(dev, &init_net); |
5024 | 5104 | ||
5025 | dev->_tx = tx; | 5105 | dev->_tx = tx; |
@@ -5223,6 +5303,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
5223 | /* | 5303 | /* |
5224 | * Flush the unicast and multicast chains | 5304 | * Flush the unicast and multicast chains |
5225 | */ | 5305 | */ |
5306 | dev_unicast_flush(dev); | ||
5226 | dev_addr_discard(dev); | 5307 | dev_addr_discard(dev); |
5227 | 5308 | ||
5228 | netdev_unregister_kobject(dev); | 5309 | netdev_unregister_kobject(dev); |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index ed131181215d..2175e6d5cc8d 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
@@ -67,7 +67,7 @@ static int dsa_slave_open(struct net_device *dev) | |||
67 | return -ENETDOWN; | 67 | return -ENETDOWN; |
68 | 68 | ||
69 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { | 69 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { |
70 | err = dev_unicast_add(master, dev->dev_addr, ETH_ALEN); | 70 | err = dev_unicast_add(master, dev->dev_addr); |
71 | if (err < 0) | 71 | if (err < 0) |
72 | goto out; | 72 | goto out; |
73 | } | 73 | } |
@@ -90,7 +90,7 @@ clear_allmulti: | |||
90 | dev_set_allmulti(master, -1); | 90 | dev_set_allmulti(master, -1); |
91 | del_unicast: | 91 | del_unicast: |
92 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 92 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
93 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | 93 | dev_unicast_delete(master, dev->dev_addr); |
94 | out: | 94 | out: |
95 | return err; | 95 | return err; |
96 | } | 96 | } |
@@ -108,7 +108,7 @@ static int dsa_slave_close(struct net_device *dev) | |||
108 | dev_set_promiscuity(master, -1); | 108 | dev_set_promiscuity(master, -1); |
109 | 109 | ||
110 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 110 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
111 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | 111 | dev_unicast_delete(master, dev->dev_addr); |
112 | 112 | ||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
@@ -147,13 +147,13 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) | |||
147 | goto out; | 147 | goto out; |
148 | 148 | ||
149 | if (compare_ether_addr(addr->sa_data, master->dev_addr)) { | 149 | if (compare_ether_addr(addr->sa_data, master->dev_addr)) { |
150 | err = dev_unicast_add(master, addr->sa_data, ETH_ALEN); | 150 | err = dev_unicast_add(master, addr->sa_data); |
151 | if (err < 0) | 151 | if (err < 0) |
152 | return err; | 152 | return err; |
153 | } | 153 | } |
154 | 154 | ||
155 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 155 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
156 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | 156 | dev_unicast_delete(master, dev->dev_addr); |
157 | 157 | ||
158 | out: | 158 | out: |
159 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 159 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index c7c5d524967e..6da9f38ef5c1 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1582,9 +1582,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
1582 | break; | 1582 | break; |
1583 | case PACKET_MR_UNICAST: | 1583 | case PACKET_MR_UNICAST: |
1584 | if (what > 0) | 1584 | if (what > 0) |
1585 | return dev_unicast_add(dev, i->addr, i->alen); | 1585 | return dev_unicast_add(dev, i->addr); |
1586 | else | 1586 | else |
1587 | return dev_unicast_delete(dev, i->addr, i->alen); | 1587 | return dev_unicast_delete(dev, i->addr); |
1588 | break; | 1588 | break; |
1589 | default:; | 1589 | default:; |
1590 | } | 1590 | } |