On Tue, 2012-11-27 at 11:59 +0000, Thomas Graf wrote: > > Using RCU read lock is OK but that means you must be prepared to > handle additions/removals to the table between dump iterations > and thus you must introduce a seq counter bumped on each table > change and add it to the dev_base_seq above. Something like this? diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index dc73091..4c3b097 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -74,6 +74,8 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, return 0; } + cb->seq = mdb->seq; + nest = nla_nest_start(skb, MDBA_MDB); if (nest == NULL) return -EMSGSIZE; @@ -126,7 +128,6 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) s_idx = cb->args[0]; rcu_read_lock(); - cb->seq = net->dev_base_seq; for_each_netdev_rcu(net, dev) { if (dev->priv_flags & IFF_EBRIDGE) { diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 1e6ce50..ccf5cfb 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -322,6 +322,7 @@ static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max, mdb->size = old ? old->size : 0; mdb->ver = old ? old->ver ^ 1 : 0; + mdb->seq = old ? (old->seq + 1): 0; if (!old || elasticity) get_random_bytes(&mdb->secret, sizeof(mdb->secret)); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index a02921e..2f5f5b8 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -105,6 +105,7 @@ struct net_bridge_mdb_htable u32 max; u32 secret; u32 ver; + u32 seq; }; struct net_bridge_port