1 /* 2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33 #include <linux/sched/signal.h> 34 35 #include <linux/init.h> 36 #include <linux/seq_file.h> 37 38 #include <linux/uaccess.h> 39 40 #include "ipoib.h" 41 42 static ssize_t parent_show(struct device *d, struct device_attribute *attr, 43 char *buf) 44 { 45 struct net_device *dev = to_net_dev(d); 46 struct ipoib_dev_priv *priv = ipoib_priv(dev); 47 48 return sysfs_emit(buf, "%s\n", priv->parent->name); 49 } 50 static DEVICE_ATTR_RO(parent); 51 52 static bool is_child_unique(struct ipoib_dev_priv *ppriv, 53 struct ipoib_dev_priv *priv) 54 { 55 struct ipoib_dev_priv *tpriv; 56 bool result = true; 57 58 /* 59 * Since the legacy sysfs interface uses pkey for deletion it cannot 60 * support more than one interface with the same pkey, it creates 61 * ambiguity. The RTNL interface deletes using the netdev so it does 62 * not have a problem to support duplicated pkeys. 63 */ 64 if (priv->child_type != IPOIB_LEGACY_CHILD) 65 return true; 66 67 /* 68 * First ensure this isn't a duplicate. We check the parent device and 69 * then all of the legacy child interfaces to make sure the Pkey 70 * doesn't match. 71 */ 72 if (ppriv->pkey == priv->pkey) 73 return false; 74 75 netdev_lock(ppriv->dev); 76 list_for_each_entry(tpriv, &ppriv->child_intfs, list) { 77 if (tpriv->pkey == priv->pkey && 78 tpriv->child_type == IPOIB_LEGACY_CHILD) { 79 result = false; 80 break; 81 } 82 } 83 netdev_unlock(ppriv->dev); 84 85 return result; 86 } 87 88 /* 89 * NOTE: If this function fails then the priv->dev will remain valid, however 90 * priv will have been freed and must not be touched by caller in the error 91 * case. 92 * 93 * If (ndev->reg_state == NETREG_UNINITIALIZED) then it is up to the caller to 94 * free the net_device (just as rtnl_newlink does) otherwise the net_device 95 * will be freed when the rtnl is unlocked. 96 */ 97 int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv, 98 u16 pkey, int type) 99 { 100 struct net_device *ndev = priv->dev; 101 int result; 102 struct rdma_netdev *rn = netdev_priv(ndev); 103 104 /* 105 * We do not need to touch priv if register_netdevice fails, so just 106 * always use this flow. 107 */ 108 ndev->priv_destructor = ipoib_intf_free; 109 110 /* 111 * Racing with unregister of the parent must be prevented by the 112 * caller. 113 */ 114 WARN_ON(ppriv->dev->reg_state != NETREG_REGISTERED); 115 116 if (pkey == 0 || pkey == 0x8000) { 117 result = -EINVAL; 118 goto out_early; 119 } 120 121 rn->mtu = priv->mcast_mtu; 122 123 priv->parent = ppriv->dev; 124 priv->pkey = pkey; 125 priv->child_type = type; 126 127 if (!is_child_unique(ppriv, priv)) { 128 result = -ENOTUNIQ; 129 goto out_early; 130 } 131 132 result = register_netdevice(ndev); 133 if (result) { 134 ipoib_warn(priv, "failed to initialize; error %i", result); 135 136 /* 137 * register_netdevice sometimes calls priv_destructor, 138 * sometimes not. Make sure it was done. 139 */ 140 goto out_early; 141 } 142 143 /* RTNL childs don't need proprietary sysfs entries */ 144 if (type == IPOIB_LEGACY_CHILD) { 145 if (ipoib_cm_add_mode_attr(ndev)) 146 goto sysfs_failed; 147 if (ipoib_add_pkey_attr(ndev)) 148 goto sysfs_failed; 149 if (ipoib_add_umcast_attr(ndev)) 150 goto sysfs_failed; 151 152 if (device_create_file(&ndev->dev, &dev_attr_parent)) 153 goto sysfs_failed; 154 } 155 156 return 0; 157 158 sysfs_failed: 159 unregister_netdevice(priv->dev); 160 return -ENOMEM; 161 162 out_early: 163 if (ndev->priv_destructor) 164 ndev->priv_destructor(ndev); 165 return result; 166 } 167 168 int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) 169 { 170 struct ipoib_dev_priv *ppriv, *priv; 171 char intf_name[IFNAMSIZ]; 172 struct net_device *ndev; 173 int result; 174 175 if (!capable(CAP_NET_ADMIN)) 176 return -EPERM; 177 178 if (!rtnl_trylock()) 179 return restart_syscall(); 180 181 if (pdev->reg_state != NETREG_REGISTERED) { 182 rtnl_unlock(); 183 return -EPERM; 184 } 185 186 ppriv = ipoib_priv(pdev); 187 188 /* If you increase IFNAMSIZ, update snprintf below 189 * to allow longer names. 190 */ 191 BUILD_BUG_ON(IFNAMSIZ != 16); 192 snprintf(intf_name, sizeof(intf_name), "%.10s.%04x", ppriv->dev->name, 193 pkey); 194 195 ndev = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); 196 if (IS_ERR(ndev)) { 197 result = PTR_ERR(ndev); 198 goto out; 199 } 200 priv = ipoib_priv(ndev); 201 202 ndev->rtnl_link_ops = ipoib_get_link_ops(); 203 204 result = __ipoib_vlan_add(ppriv, priv, pkey, IPOIB_LEGACY_CHILD); 205 206 if (result && ndev->reg_state == NETREG_UNINITIALIZED) 207 free_netdev(ndev); 208 209 out: 210 rtnl_unlock(); 211 212 return result; 213 } 214 215 struct ipoib_vlan_delete_work { 216 struct work_struct work; 217 struct net_device *dev; 218 }; 219 220 /* 221 * sysfs callbacks of a netdevice cannot obtain the rtnl lock as 222 * unregister_netdev ultimately deletes the sysfs files while holding the rtnl 223 * lock. This deadlocks the system. 224 * 225 * A callback can use rtnl_trylock to avoid the deadlock but it cannot call 226 * unregister_netdev as that internally takes and releases the rtnl_lock. So 227 * instead we find the netdev to unregister and then do the actual unregister 228 * from the global work queue where we can obtain the rtnl_lock safely. 229 */ 230 static void ipoib_vlan_delete_task(struct work_struct *work) 231 { 232 struct ipoib_vlan_delete_work *pwork = 233 container_of(work, struct ipoib_vlan_delete_work, work); 234 struct net_device *dev = pwork->dev; 235 236 rtnl_lock(); 237 238 /* Unregistering tasks can race with another task or parent removal */ 239 if (dev->reg_state == NETREG_REGISTERED) { 240 struct ipoib_dev_priv *priv = ipoib_priv(dev); 241 struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); 242 243 ipoib_dbg(ppriv, "delete child vlan %s\n", dev->name); 244 unregister_netdevice(dev); 245 } 246 247 rtnl_unlock(); 248 249 kfree(pwork); 250 } 251 252 int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) 253 { 254 struct ipoib_dev_priv *ppriv, *priv, *tpriv; 255 int rc; 256 257 if (!capable(CAP_NET_ADMIN)) 258 return -EPERM; 259 260 if (!rtnl_trylock()) 261 return restart_syscall(); 262 263 if (pdev->reg_state != NETREG_REGISTERED) { 264 rtnl_unlock(); 265 return -EPERM; 266 } 267 268 ppriv = ipoib_priv(pdev); 269 270 rc = -ENODEV; 271 netdev_lock(ppriv->dev); 272 list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { 273 if (priv->pkey == pkey && 274 priv->child_type == IPOIB_LEGACY_CHILD) { 275 struct ipoib_vlan_delete_work *work; 276 277 work = kmalloc(sizeof(*work), GFP_KERNEL); 278 if (!work) { 279 rc = -ENOMEM; 280 goto out; 281 } 282 283 list_del_init(&priv->list); 284 work->dev = priv->dev; 285 INIT_WORK(&work->work, ipoib_vlan_delete_task); 286 queue_work(ipoib_workqueue, &work->work); 287 288 rc = 0; 289 break; 290 } 291 } 292 293 out: 294 netdev_unlock(ppriv->dev); 295 rtnl_unlock(); 296 297 return rc; 298 } 299