static void __mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port) { struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; struct mlx5e_vxlan *vxlan; spin_lock_irq(&vxlan_db->lock); vxlan = radix_tree_delete(&vxlan_db->tree, port); spin_unlock_irq(&vxlan_db->lock); if (!vxlan) return; mlx5_vxlan_debugfs_remove(priv->mdev, vxlan); mlx5e_del_tunneling_rule(priv, &vxlan->flow_rule); mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port); kfree(vxlan); }
static void mlx5e_vxlan_add_port(struct work_struct *work) { struct mlx5e_vxlan_work *vxlan_work = container_of(work, struct mlx5e_vxlan_work, work); struct mlx5e_priv *priv = vxlan_work->priv; struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; u16 port = vxlan_work->port; struct mlx5e_vxlan *vxlan; int err; if (mlx5e_vxlan_lookup_port(priv, port)) goto free_work; if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) goto free_work; vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); if (!vxlan) goto err_delete_port; vxlan->udp_port = port; spin_lock_irq(&vxlan_db->lock); err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); spin_unlock_irq(&vxlan_db->lock); if (err) goto err_free; goto free_work; err_free: kfree(vxlan); err_delete_port: mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); free_work: kfree(vxlan_work); }