aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/dev_addr_lists.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index bb504a919e33..329d5794e7dc 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -38,7 +38,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
38 ha->type = addr_type; 38 ha->type = addr_type;
39 ha->refcount = 1; 39 ha->refcount = 1;
40 ha->global_use = global; 40 ha->global_use = global;
41 ha->synced = sync; 41 ha->synced = sync ? 1 : 0;
42 ha->sync_cnt = 0; 42 ha->sync_cnt = 0;
43 list_add_tail_rcu(&ha->list, &list->list); 43 list_add_tail_rcu(&ha->list, &list->list);
44 list->count++; 44 list->count++;
@@ -48,7 +48,8 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
48 48
49static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, 49static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
50 const unsigned char *addr, int addr_len, 50 const unsigned char *addr, int addr_len,
51 unsigned char addr_type, bool global, bool sync) 51 unsigned char addr_type, bool global, bool sync,
52 int sync_count)
52{ 53{
53 struct netdev_hw_addr *ha; 54 struct netdev_hw_addr *ha;
54 55
@@ -66,10 +67,10 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
66 ha->global_use = true; 67 ha->global_use = true;
67 } 68 }
68 if (sync) { 69 if (sync) {
69 if (ha->synced) 70 if (ha->synced && sync_count)
70 return -EEXIST; 71 return -EEXIST;
71 else 72 else
72 ha->synced = true; 73 ha->synced++;
73 } 74 }
74 ha->refcount++; 75 ha->refcount++;
75 return 0; 76 return 0;
@@ -84,7 +85,8 @@ static int __hw_addr_add(struct netdev_hw_addr_list *list,
84 const unsigned char *addr, int addr_len, 85 const unsigned char *addr, int addr_len,
85 unsigned char addr_type) 86 unsigned char addr_type)
86{ 87{
87 return __hw_addr_add_ex(list, addr, addr_len, addr_type, false, false); 88 return __hw_addr_add_ex(list, addr, addr_len, addr_type, false, false,
89 0);
88} 90}
89 91
90static int __hw_addr_del_entry(struct netdev_hw_addr_list *list, 92static int __hw_addr_del_entry(struct netdev_hw_addr_list *list,
@@ -101,7 +103,7 @@ static int __hw_addr_del_entry(struct netdev_hw_addr_list *list,
101 ha->global_use = false; 103 ha->global_use = false;
102 104
103 if (sync) 105 if (sync)
104 ha->synced = false; 106 ha->synced--;
105 107
106 if (--ha->refcount) 108 if (--ha->refcount)
107 return 0; 109 return 0;
@@ -139,7 +141,7 @@ static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list,
139 int err; 141 int err;
140 142
141 err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type, 143 err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type,
142 false, true); 144 false, true, ha->sync_cnt);
143 if (err && err != -EEXIST) 145 if (err && err != -EEXIST)
144 return err; 146 return err;
145 147
@@ -581,7 +583,7 @@ static int __dev_mc_add(struct net_device *dev, const unsigned char *addr,
581 583
582 netif_addr_lock_bh(dev); 584 netif_addr_lock_bh(dev);
583 err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, 585 err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len,
584 NETDEV_HW_ADDR_T_MULTICAST, global, false); 586 NETDEV_HW_ADDR_T_MULTICAST, global, false, 0);
585 if (!err) 587 if (!err)
586 __dev_set_rx_mode(dev); 588 __dev_set_rx_mode(dev);
587 netif_addr_unlock_bh(dev); 589 netif_addr_unlock_bh(dev);