This patch looks like it should be in the 3.8-stable tree, should we apply
it?

------------------

From: "Vlad Yasevich <vyase...@redhat.com>"

commit 4543fbefe6e06a9e40d9f2b28d688393a299f079 upstream

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 <vyase...@redhat.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Jonghwan Choi <jhbird.c...@samsung.com>
---
 include/linux/netdevice.h |    2 +-
 net/core/dev_addr_lists.c |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9ef07d0..0e182f9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -208,9 +208,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;
 };
 
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index b079c7b..7841d87 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,
        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++;
 
@@ -166,7 +166,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);
@@ -187,7 +187,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);
                }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to