Skip to content

Commit

Permalink
net: count hw_addr syncs so that unsync works properly.
Browse files Browse the repository at this point in the history
A few drivers use dev_uc_sync/unsync to synchronize the
address lists from master down to slave/lower devices.  In
some cases (bond/team) a single address list is synched down
to multiple devices.  At the time of unsync, we have a leak
in these lower devices, because "synced" is treated as a
boolean and the address will not be unsynced for anything after
the first device/call.

Treat "synced" as a count (same as refcount) and allow all
unsync calls to work.

Signed-off-by: Vlad Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Vlad Yasevich authored and davem330 committed Apr 5, 2013
1 parent e2409d8 commit 4543fbe
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ struct netdev_hw_addr {
#define NETDEV_HW_ADDR_T_SLAVE 3
#define NETDEV_HW_ADDR_T_UNICAST 4
#define NETDEV_HW_ADDR_T_MULTICAST 5
bool synced;
bool global_use;
int refcount;
int synced;
struct rcu_head rcu_head;
};

Expand Down
6 changes: 3 additions & 3 deletions net/core/dev_addr_lists.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
ha->type = addr_type;
ha->refcount = 1;
ha->global_use = global;
ha->synced = false;
ha->synced = 0;
list_add_tail_rcu(&ha->list, &list->list);
list->count++;

Expand Down Expand Up @@ -165,7 +165,7 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
addr_len, ha->type);
if (err)
break;
ha->synced = true;
ha->synced++;
ha->refcount++;
} else if (ha->refcount == 1) {
__hw_addr_del(to_list, ha->addr, addr_len, ha->type);
Expand All @@ -186,7 +186,7 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
if (ha->synced) {
__hw_addr_del(to_list, ha->addr,
addr_len, ha->type);
ha->synced = false;
ha->synced--;
__hw_addr_del(from_list, ha->addr,
addr_len, ha->type);
}
Expand Down

0 comments on commit 4543fbe

Please sign in to comment.