diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2015-11-21 15:59:54 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2015-11-21 15:59:54 +0300 |
commit | 0f7d57ebac59c8ece1173f7043296942201128aa (patch) | |
tree | 0a5036dd3085d624d88a72654b0f13661504b50f | |
parent | 4a41fc593e56691172a58b511a1d9ade63982c32 (diff) | |
download | accel-ppp-0f7d57ebac59c8ece1173f7043296942201128aa.tar.gz accel-ppp-0f7d57ebac59c8ece1173f7043296942201128aa.zip |
vlan_mon module fixes
-rw-r--r-- | drivers/vlan_mon/vlan_mon.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/vlan_mon/vlan_mon.c b/drivers/vlan_mon/vlan_mon.c index f61d932..f2915b1 100644 --- a/drivers/vlan_mon/vlan_mon.c +++ b/drivers/vlan_mon/vlan_mon.c @@ -323,6 +323,8 @@ static int vlan_mon_nl_cmd_add_vlan_mon(struct sk_buff *skb, struct genl_info *i d->proto = 0; rcu_assign_pointer(dev->ml_priv, d); + + list_add_tail(&d->entry, &vlan_devices); } d->proto |= 1 << proto; @@ -351,11 +353,12 @@ static int vlan_mon_nl_cmd_add_vlan_mon(struct sk_buff *skb, struct genl_info *i #endif } - list_add_tail_rcu(&d->entry, &vlan_devices); up(&vlan_mon_lock); dev_put(dev); + synchronize_rcu(); + return 0; } @@ -449,7 +452,8 @@ static int vlan_mon_nl_cmd_del_vlan_mon(struct sk_buff *skb, struct genl_info *i ifindex = -1; down(&vlan_mon_lock); - list_for_each_entry(d, &vlan_devices, entry) { + list_for_each_safe(pos, n, &vlan_devices) { + d = list_entry(pos, typeof(*d), entry); if ((ifindex == -1 || d->ifindex == ifindex) && (d->proto & proto)) { //pr_info("del net %08x/%08x\n", n->addr, n->mask); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) @@ -460,9 +464,10 @@ static int vlan_mon_nl_cmd_del_vlan_mon(struct sk_buff *skb, struct genl_info *i dev = dev_get_by_index(&init_net, d->ifindex); #endif + d->proto &= ~proto; + if (dev) { if (dev->ml_priv == d) { - d->proto &= ~proto; if (!d->proto) rcu_assign_pointer(dev->ml_priv, NULL); } @@ -471,7 +476,7 @@ static int vlan_mon_nl_cmd_del_vlan_mon(struct sk_buff *skb, struct genl_info *i if (!d->proto) { //pr_info("vlan_mon del %i\n", ifindex); - list_del_rcu(&d->entry); + list_del(&d->entry); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) kfree_rcu(d, rcu_head); #else @@ -492,6 +497,8 @@ static int vlan_mon_nl_cmd_del_vlan_mon(struct sk_buff *skb, struct genl_info *i } spin_unlock_irqrestore(&vlan_lock, flags); + synchronize_rcu(); + return 0; } |