diff options
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index a3c46d78d216..077f1b9f2761 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1731,6 +1731,14 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) goto drop; } + rcu_read_lock(); + + if (unlikely(!(vxlan->dev->flags & IFF_UP))) { + rcu_read_unlock(); + atomic_long_inc(&vxlan->dev->rx_dropped); + goto drop; + } + stats = this_cpu_ptr(vxlan->dev->tstats); u64_stats_update_begin(&stats->syncp); stats->rx_packets++; @@ -1738,6 +1746,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) u64_stats_update_end(&stats->syncp); gro_cells_receive(&vxlan->gro_cells, skb); + + rcu_read_unlock(); + return 0; drop: @@ -2690,7 +2701,7 @@ static void vxlan_cleanup(struct timer_list *t) for (h = 0; h < FDB_HASH_SIZE; ++h) { struct hlist_node *p, *n; - spin_lock_bh(&vxlan->hash_lock); + spin_lock(&vxlan->hash_lock); hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) { struct vxlan_fdb *f = container_of(p, struct vxlan_fdb, hlist); @@ -2712,7 +2723,7 @@ static void vxlan_cleanup(struct timer_list *t) } else if (time_before(timeout, next_timer)) next_timer = timeout; } - spin_unlock_bh(&vxlan->hash_lock); + spin_unlock(&vxlan->hash_lock); } mod_timer(&vxlan->age_timer, next_timer); @@ -2767,6 +2778,8 @@ static void vxlan_uninit(struct net_device *dev) { struct vxlan_dev *vxlan = netdev_priv(dev); + gro_cells_destroy(&vxlan->gro_cells); + vxlan_fdb_delete_default(vxlan, vxlan->cfg.vni); free_percpu(dev->tstats); @@ -3942,7 +3955,6 @@ static void vxlan_dellink(struct net_device *dev, struct list_head *head) vxlan_flush(vxlan, true); - gro_cells_destroy(&vxlan->gro_cells); list_del(&vxlan->next); unregister_netdevice_queue(dev, head); } |