0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/list.h>
0014 #include <linux/ctype.h>
0015 #include <linux/mutex.h>
0016 #include <net/netlink.h>
0017 #include <net/genetlink.h>
0018
0019 #include <uapi/linux/if.h>
0020 #include <uapi/linux/smc.h>
0021
0022 #include <rdma/ib_verbs.h>
0023
0024 #include <net/netns/generic.h>
0025 #include "smc_netns.h"
0026
0027 #include "smc_pnet.h"
0028 #include "smc_ib.h"
0029 #include "smc_ism.h"
0030 #include "smc_core.h"
0031
0032 static struct net_device *__pnet_find_base_ndev(struct net_device *ndev);
0033 static struct net_device *pnet_find_base_ndev(struct net_device *ndev);
0034
0035 static const struct nla_policy smc_pnet_policy[SMC_PNETID_MAX + 1] = {
0036 [SMC_PNETID_NAME] = {
0037 .type = NLA_NUL_STRING,
0038 .len = SMC_MAX_PNETID_LEN
0039 },
0040 [SMC_PNETID_ETHNAME] = {
0041 .type = NLA_NUL_STRING,
0042 .len = IFNAMSIZ - 1
0043 },
0044 [SMC_PNETID_IBNAME] = {
0045 .type = NLA_NUL_STRING,
0046 .len = IB_DEVICE_NAME_MAX - 1
0047 },
0048 [SMC_PNETID_IBPORT] = { .type = NLA_U8 }
0049 };
0050
0051 static struct genl_family smc_pnet_nl_family;
0052
0053 enum smc_pnet_nametype {
0054 SMC_PNET_ETH = 1,
0055 SMC_PNET_IB = 2,
0056 };
0057
0058
0059 struct smc_pnetentry {
0060 struct list_head list;
0061 char pnet_name[SMC_MAX_PNETID_LEN + 1];
0062 enum smc_pnet_nametype type;
0063 union {
0064 struct {
0065 char eth_name[IFNAMSIZ + 1];
0066 struct net_device *ndev;
0067 netdevice_tracker dev_tracker;
0068 };
0069 struct {
0070 char ib_name[IB_DEVICE_NAME_MAX + 1];
0071 u8 ib_port;
0072 };
0073 };
0074 };
0075
0076
0077 bool smc_pnet_is_pnetid_set(u8 *pnetid)
0078 {
0079 if (pnetid[0] == 0 || pnetid[0] == _S)
0080 return false;
0081 return true;
0082 }
0083
0084
0085 static bool smc_pnet_match(u8 *pnetid1, u8 *pnetid2)
0086 {
0087 int i;
0088
0089 for (i = 0; i < SMC_MAX_PNETID_LEN; i++) {
0090 if ((pnetid1[i] == 0 || pnetid1[i] == _S) &&
0091 (pnetid2[i] == 0 || pnetid2[i] == _S))
0092 break;
0093 if (pnetid1[i] != pnetid2[i])
0094 return false;
0095 }
0096 return true;
0097 }
0098
0099
0100
0101 static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
0102 {
0103 struct smc_pnetentry *pnetelem, *tmp_pe;
0104 struct smc_pnettable *pnettable;
0105 struct smc_ib_device *ibdev;
0106 struct smcd_dev *smcd_dev;
0107 struct smc_net *sn;
0108 int rc = -ENOENT;
0109 int ibport;
0110
0111
0112 sn = net_generic(net, smc_net_id);
0113 pnettable = &sn->pnettable;
0114
0115
0116 mutex_lock(&pnettable->lock);
0117 list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist,
0118 list) {
0119 if (!pnet_name ||
0120 smc_pnet_match(pnetelem->pnet_name, pnet_name)) {
0121 list_del(&pnetelem->list);
0122 if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev) {
0123 netdev_put(pnetelem->ndev,
0124 &pnetelem->dev_tracker);
0125 pr_warn_ratelimited("smc: net device %s "
0126 "erased user defined "
0127 "pnetid %.16s\n",
0128 pnetelem->eth_name,
0129 pnetelem->pnet_name);
0130 }
0131 kfree(pnetelem);
0132 rc = 0;
0133 }
0134 }
0135 mutex_unlock(&pnettable->lock);
0136
0137
0138 if (net != &init_net)
0139 return rc;
0140
0141
0142 mutex_lock(&smc_ib_devices.mutex);
0143 list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
0144 for (ibport = 0; ibport < SMC_MAX_PORTS; ibport++) {
0145 if (ibdev->pnetid_by_user[ibport] &&
0146 (!pnet_name ||
0147 smc_pnet_match(pnet_name,
0148 ibdev->pnetid[ibport]))) {
0149 pr_warn_ratelimited("smc: ib device %s ibport "
0150 "%d erased user defined "
0151 "pnetid %.16s\n",
0152 ibdev->ibdev->name,
0153 ibport + 1,
0154 ibdev->pnetid[ibport]);
0155 memset(ibdev->pnetid[ibport], 0,
0156 SMC_MAX_PNETID_LEN);
0157 ibdev->pnetid_by_user[ibport] = false;
0158 rc = 0;
0159 }
0160 }
0161 }
0162 mutex_unlock(&smc_ib_devices.mutex);
0163
0164 mutex_lock(&smcd_dev_list.mutex);
0165 list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
0166 if (smcd_dev->pnetid_by_user &&
0167 (!pnet_name ||
0168 smc_pnet_match(pnet_name, smcd_dev->pnetid))) {
0169 pr_warn_ratelimited("smc: smcd device %s "
0170 "erased user defined pnetid "
0171 "%.16s\n", dev_name(&smcd_dev->dev),
0172 smcd_dev->pnetid);
0173 memset(smcd_dev->pnetid, 0, SMC_MAX_PNETID_LEN);
0174 smcd_dev->pnetid_by_user = false;
0175 rc = 0;
0176 }
0177 }
0178 mutex_unlock(&smcd_dev_list.mutex);
0179 return rc;
0180 }
0181
0182
0183
0184 static int smc_pnet_add_by_ndev(struct net_device *ndev)
0185 {
0186 struct smc_pnetentry *pnetelem, *tmp_pe;
0187 struct smc_pnettable *pnettable;
0188 struct net *net = dev_net(ndev);
0189 struct smc_net *sn;
0190 int rc = -ENOENT;
0191
0192
0193 sn = net_generic(net, smc_net_id);
0194 pnettable = &sn->pnettable;
0195
0196 mutex_lock(&pnettable->lock);
0197 list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
0198 if (pnetelem->type == SMC_PNET_ETH && !pnetelem->ndev &&
0199 !strncmp(pnetelem->eth_name, ndev->name, IFNAMSIZ)) {
0200 netdev_hold(ndev, &pnetelem->dev_tracker, GFP_ATOMIC);
0201 pnetelem->ndev = ndev;
0202 rc = 0;
0203 pr_warn_ratelimited("smc: adding net device %s with "
0204 "user defined pnetid %.16s\n",
0205 pnetelem->eth_name,
0206 pnetelem->pnet_name);
0207 break;
0208 }
0209 }
0210 mutex_unlock(&pnettable->lock);
0211 return rc;
0212 }
0213
0214
0215
0216 static int smc_pnet_remove_by_ndev(struct net_device *ndev)
0217 {
0218 struct smc_pnetentry *pnetelem, *tmp_pe;
0219 struct smc_pnettable *pnettable;
0220 struct net *net = dev_net(ndev);
0221 struct smc_net *sn;
0222 int rc = -ENOENT;
0223
0224
0225 sn = net_generic(net, smc_net_id);
0226 pnettable = &sn->pnettable;
0227
0228 mutex_lock(&pnettable->lock);
0229 list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
0230 if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev == ndev) {
0231 netdev_put(pnetelem->ndev, &pnetelem->dev_tracker);
0232 pnetelem->ndev = NULL;
0233 rc = 0;
0234 pr_warn_ratelimited("smc: removing net device %s with "
0235 "user defined pnetid %.16s\n",
0236 pnetelem->eth_name,
0237 pnetelem->pnet_name);
0238 break;
0239 }
0240 }
0241 mutex_unlock(&pnettable->lock);
0242 return rc;
0243 }
0244
0245
0246
0247 static bool smc_pnet_apply_ib(struct smc_ib_device *ib_dev, u8 ib_port,
0248 char *pnet_name)
0249 {
0250 bool applied = false;
0251
0252 mutex_lock(&smc_ib_devices.mutex);
0253 if (!smc_pnet_is_pnetid_set(ib_dev->pnetid[ib_port - 1])) {
0254 memcpy(ib_dev->pnetid[ib_port - 1], pnet_name,
0255 SMC_MAX_PNETID_LEN);
0256 ib_dev->pnetid_by_user[ib_port - 1] = true;
0257 applied = true;
0258 }
0259 mutex_unlock(&smc_ib_devices.mutex);
0260 return applied;
0261 }
0262
0263
0264
0265 static bool smc_pnet_apply_smcd(struct smcd_dev *smcd_dev, char *pnet_name)
0266 {
0267 bool applied = false;
0268
0269 mutex_lock(&smcd_dev_list.mutex);
0270 if (!smc_pnet_is_pnetid_set(smcd_dev->pnetid)) {
0271 memcpy(smcd_dev->pnetid, pnet_name, SMC_MAX_PNETID_LEN);
0272 smcd_dev->pnetid_by_user = true;
0273 applied = true;
0274 }
0275 mutex_unlock(&smcd_dev_list.mutex);
0276 return applied;
0277 }
0278
0279
0280
0281
0282
0283
0284 static bool smc_pnetid_valid(const char *pnet_name, char *pnetid)
0285 {
0286 char *bf = skip_spaces(pnet_name);
0287 size_t len = strlen(bf);
0288 char *end = bf + len;
0289
0290 if (!len)
0291 return false;
0292 while (--end >= bf && isspace(*end))
0293 ;
0294 if (end - bf >= SMC_MAX_PNETID_LEN)
0295 return false;
0296 while (bf <= end) {
0297 if (!isalnum(*bf))
0298 return false;
0299 *pnetid++ = islower(*bf) ? toupper(*bf) : *bf;
0300 bf++;
0301 }
0302 *pnetid = '\0';
0303 return true;
0304 }
0305
0306
0307 static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
0308 {
0309 struct smc_ib_device *ibdev;
0310
0311 mutex_lock(&smc_ib_devices.mutex);
0312 list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
0313 if (!strncmp(ibdev->ibdev->name, ib_name,
0314 sizeof(ibdev->ibdev->name)) ||
0315 (ibdev->ibdev->dev.parent &&
0316 !strncmp(dev_name(ibdev->ibdev->dev.parent), ib_name,
0317 IB_DEVICE_NAME_MAX - 1))) {
0318 goto out;
0319 }
0320 }
0321 ibdev = NULL;
0322 out:
0323 mutex_unlock(&smc_ib_devices.mutex);
0324 return ibdev;
0325 }
0326
0327
0328 static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)
0329 {
0330 struct smcd_dev *smcd_dev;
0331
0332 mutex_lock(&smcd_dev_list.mutex);
0333 list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
0334 if (!strncmp(dev_name(&smcd_dev->dev), smcd_name,
0335 IB_DEVICE_NAME_MAX - 1))
0336 goto out;
0337 }
0338 smcd_dev = NULL;
0339 out:
0340 mutex_unlock(&smcd_dev_list.mutex);
0341 return smcd_dev;
0342 }
0343
0344 static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
0345 char *eth_name, char *pnet_name)
0346 {
0347 struct smc_pnetentry *tmp_pe, *new_pe;
0348 struct net_device *ndev, *base_ndev;
0349 u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
0350 bool new_netdev;
0351 int rc;
0352
0353
0354
0355
0356 rc = -EEXIST;
0357 ndev = dev_get_by_name(net, eth_name);
0358 if (ndev) {
0359 base_ndev = pnet_find_base_ndev(ndev);
0360 if (!smc_pnetid_by_dev_port(base_ndev->dev.parent,
0361 base_ndev->dev_port, ndev_pnetid))
0362 goto out_put;
0363 }
0364
0365
0366 rc = -ENOMEM;
0367 new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL);
0368 if (!new_pe)
0369 goto out_put;
0370 new_pe->type = SMC_PNET_ETH;
0371 memcpy(new_pe->pnet_name, pnet_name, SMC_MAX_PNETID_LEN);
0372 strncpy(new_pe->eth_name, eth_name, IFNAMSIZ);
0373 rc = -EEXIST;
0374 new_netdev = true;
0375 mutex_lock(&pnettable->lock);
0376 list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
0377 if (tmp_pe->type == SMC_PNET_ETH &&
0378 !strncmp(tmp_pe->eth_name, eth_name, IFNAMSIZ)) {
0379 new_netdev = false;
0380 break;
0381 }
0382 }
0383 if (new_netdev) {
0384 if (ndev) {
0385 new_pe->ndev = ndev;
0386 netdev_tracker_alloc(ndev, &new_pe->dev_tracker,
0387 GFP_ATOMIC);
0388 }
0389 list_add_tail(&new_pe->list, &pnettable->pnetlist);
0390 mutex_unlock(&pnettable->lock);
0391 } else {
0392 mutex_unlock(&pnettable->lock);
0393 kfree(new_pe);
0394 goto out_put;
0395 }
0396 if (ndev)
0397 pr_warn_ratelimited("smc: net device %s "
0398 "applied user defined pnetid %.16s\n",
0399 new_pe->eth_name, new_pe->pnet_name);
0400 return 0;
0401
0402 out_put:
0403 dev_put(ndev);
0404 return rc;
0405 }
0406
0407 static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
0408 u8 ib_port, char *pnet_name)
0409 {
0410 struct smc_pnetentry *tmp_pe, *new_pe;
0411 struct smc_ib_device *ib_dev;
0412 bool smcddev_applied = true;
0413 bool ibdev_applied = true;
0414 struct smcd_dev *smcd_dev;
0415 bool new_ibdev;
0416
0417
0418 ib_dev = smc_pnet_find_ib(ib_name);
0419 if (ib_dev) {
0420 ibdev_applied = smc_pnet_apply_ib(ib_dev, ib_port, pnet_name);
0421 if (ibdev_applied)
0422 pr_warn_ratelimited("smc: ib device %s ibport %d "
0423 "applied user defined pnetid "
0424 "%.16s\n", ib_dev->ibdev->name,
0425 ib_port,
0426 ib_dev->pnetid[ib_port - 1]);
0427 }
0428 smcd_dev = smc_pnet_find_smcd(ib_name);
0429 if (smcd_dev) {
0430 smcddev_applied = smc_pnet_apply_smcd(smcd_dev, pnet_name);
0431 if (smcddev_applied)
0432 pr_warn_ratelimited("smc: smcd device %s "
0433 "applied user defined pnetid "
0434 "%.16s\n", dev_name(&smcd_dev->dev),
0435 smcd_dev->pnetid);
0436 }
0437
0438
0439
0440 if (!ibdev_applied || !smcddev_applied)
0441 return -EEXIST;
0442
0443
0444 new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL);
0445 if (!new_pe)
0446 return -ENOMEM;
0447 new_pe->type = SMC_PNET_IB;
0448 memcpy(new_pe->pnet_name, pnet_name, SMC_MAX_PNETID_LEN);
0449 strncpy(new_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX);
0450 new_pe->ib_port = ib_port;
0451
0452 new_ibdev = true;
0453 mutex_lock(&pnettable->lock);
0454 list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
0455 if (tmp_pe->type == SMC_PNET_IB &&
0456 !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
0457 new_ibdev = false;
0458 break;
0459 }
0460 }
0461 if (new_ibdev) {
0462 list_add_tail(&new_pe->list, &pnettable->pnetlist);
0463 mutex_unlock(&pnettable->lock);
0464 } else {
0465 mutex_unlock(&pnettable->lock);
0466 kfree(new_pe);
0467 }
0468 return (new_ibdev) ? 0 : -EEXIST;
0469 }
0470
0471
0472
0473 static int smc_pnet_enter(struct net *net, struct nlattr *tb[])
0474 {
0475 char pnet_name[SMC_MAX_PNETID_LEN + 1];
0476 struct smc_pnettable *pnettable;
0477 bool new_netdev = false;
0478 bool new_ibdev = false;
0479 struct smc_net *sn;
0480 u8 ibport = 1;
0481 char *string;
0482 int rc;
0483
0484
0485 sn = net_generic(net, smc_net_id);
0486 pnettable = &sn->pnettable;
0487
0488 rc = -EINVAL;
0489 if (!tb[SMC_PNETID_NAME])
0490 goto error;
0491 string = (char *)nla_data(tb[SMC_PNETID_NAME]);
0492 if (!smc_pnetid_valid(string, pnet_name))
0493 goto error;
0494
0495 if (tb[SMC_PNETID_ETHNAME]) {
0496 string = (char *)nla_data(tb[SMC_PNETID_ETHNAME]);
0497 rc = smc_pnet_add_eth(pnettable, net, string, pnet_name);
0498 if (!rc)
0499 new_netdev = true;
0500 else if (rc != -EEXIST)
0501 goto error;
0502 }
0503
0504
0505 if (net != &init_net)
0506 return new_netdev ? 0 : -EEXIST;
0507
0508 rc = -EINVAL;
0509 if (tb[SMC_PNETID_IBNAME]) {
0510 string = (char *)nla_data(tb[SMC_PNETID_IBNAME]);
0511 string = strim(string);
0512 if (tb[SMC_PNETID_IBPORT]) {
0513 ibport = nla_get_u8(tb[SMC_PNETID_IBPORT]);
0514 if (ibport < 1 || ibport > SMC_MAX_PORTS)
0515 goto error;
0516 }
0517 rc = smc_pnet_add_ib(pnettable, string, ibport, pnet_name);
0518 if (!rc)
0519 new_ibdev = true;
0520 else if (rc != -EEXIST)
0521 goto error;
0522 }
0523 return (new_netdev || new_ibdev) ? 0 : -EEXIST;
0524
0525 error:
0526 return rc;
0527 }
0528
0529
0530 static int smc_pnet_set_nla(struct sk_buff *msg,
0531 struct smc_pnetentry *pnetelem)
0532 {
0533 if (nla_put_string(msg, SMC_PNETID_NAME, pnetelem->pnet_name))
0534 return -1;
0535 if (pnetelem->type == SMC_PNET_ETH) {
0536 if (nla_put_string(msg, SMC_PNETID_ETHNAME,
0537 pnetelem->eth_name))
0538 return -1;
0539 } else {
0540 if (nla_put_string(msg, SMC_PNETID_ETHNAME, "n/a"))
0541 return -1;
0542 }
0543 if (pnetelem->type == SMC_PNET_IB) {
0544 if (nla_put_string(msg, SMC_PNETID_IBNAME, pnetelem->ib_name) ||
0545 nla_put_u8(msg, SMC_PNETID_IBPORT, pnetelem->ib_port))
0546 return -1;
0547 } else {
0548 if (nla_put_string(msg, SMC_PNETID_IBNAME, "n/a") ||
0549 nla_put_u8(msg, SMC_PNETID_IBPORT, 0xff))
0550 return -1;
0551 }
0552
0553 return 0;
0554 }
0555
0556 static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info)
0557 {
0558 struct net *net = genl_info_net(info);
0559
0560 return smc_pnet_enter(net, info->attrs);
0561 }
0562
0563 static int smc_pnet_del(struct sk_buff *skb, struct genl_info *info)
0564 {
0565 struct net *net = genl_info_net(info);
0566
0567 if (!info->attrs[SMC_PNETID_NAME])
0568 return -EINVAL;
0569 return smc_pnet_remove_by_pnetid(net,
0570 (char *)nla_data(info->attrs[SMC_PNETID_NAME]));
0571 }
0572
0573 static int smc_pnet_dump_start(struct netlink_callback *cb)
0574 {
0575 cb->args[0] = 0;
0576 return 0;
0577 }
0578
0579 static int smc_pnet_dumpinfo(struct sk_buff *skb,
0580 u32 portid, u32 seq, u32 flags,
0581 struct smc_pnetentry *pnetelem)
0582 {
0583 void *hdr;
0584
0585 hdr = genlmsg_put(skb, portid, seq, &smc_pnet_nl_family,
0586 flags, SMC_PNETID_GET);
0587 if (!hdr)
0588 return -ENOMEM;
0589 if (smc_pnet_set_nla(skb, pnetelem) < 0) {
0590 genlmsg_cancel(skb, hdr);
0591 return -EMSGSIZE;
0592 }
0593 genlmsg_end(skb, hdr);
0594 return 0;
0595 }
0596
0597 static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid,
0598 u32 seq, u8 *pnetid, int start_idx)
0599 {
0600 struct smc_pnettable *pnettable;
0601 struct smc_pnetentry *pnetelem;
0602 struct smc_net *sn;
0603 int idx = 0;
0604
0605
0606 sn = net_generic(net, smc_net_id);
0607 pnettable = &sn->pnettable;
0608
0609
0610 mutex_lock(&pnettable->lock);
0611 list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
0612 if (pnetid && !smc_pnet_match(pnetelem->pnet_name, pnetid))
0613 continue;
0614 if (idx++ < start_idx)
0615 continue;
0616
0617 if (net != &init_net && pnetelem->type != SMC_PNET_ETH)
0618 continue;
0619 if (smc_pnet_dumpinfo(skb, portid, seq, NLM_F_MULTI,
0620 pnetelem)) {
0621 --idx;
0622 break;
0623 }
0624 }
0625 mutex_unlock(&pnettable->lock);
0626 return idx;
0627 }
0628
0629 static int smc_pnet_dump(struct sk_buff *skb, struct netlink_callback *cb)
0630 {
0631 struct net *net = sock_net(skb->sk);
0632 int idx;
0633
0634 idx = _smc_pnet_dump(net, skb, NETLINK_CB(cb->skb).portid,
0635 cb->nlh->nlmsg_seq, NULL, cb->args[0]);
0636
0637 cb->args[0] = idx;
0638 return skb->len;
0639 }
0640
0641
0642 static int smc_pnet_get(struct sk_buff *skb, struct genl_info *info)
0643 {
0644 struct net *net = genl_info_net(info);
0645 struct sk_buff *msg;
0646 void *hdr;
0647
0648 if (!info->attrs[SMC_PNETID_NAME])
0649 return -EINVAL;
0650
0651 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
0652 if (!msg)
0653 return -ENOMEM;
0654
0655 _smc_pnet_dump(net, msg, info->snd_portid, info->snd_seq,
0656 nla_data(info->attrs[SMC_PNETID_NAME]), 0);
0657
0658
0659 hdr = nlmsg_put(msg, info->snd_portid, info->snd_seq, NLMSG_DONE, 0,
0660 NLM_F_MULTI);
0661 if (!hdr) {
0662 nlmsg_free(msg);
0663 return -EMSGSIZE;
0664 }
0665 return genlmsg_reply(msg, info);
0666 }
0667
0668
0669
0670 static int smc_pnet_flush(struct sk_buff *skb, struct genl_info *info)
0671 {
0672 struct net *net = genl_info_net(info);
0673
0674 smc_pnet_remove_by_pnetid(net, NULL);
0675 return 0;
0676 }
0677
0678
0679 static const struct genl_ops smc_pnet_ops[] = {
0680 {
0681 .cmd = SMC_PNETID_GET,
0682 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
0683
0684 .doit = smc_pnet_get,
0685 .dumpit = smc_pnet_dump,
0686 .start = smc_pnet_dump_start
0687 },
0688 {
0689 .cmd = SMC_PNETID_ADD,
0690 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
0691 .flags = GENL_ADMIN_PERM,
0692 .doit = smc_pnet_add
0693 },
0694 {
0695 .cmd = SMC_PNETID_DEL,
0696 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
0697 .flags = GENL_ADMIN_PERM,
0698 .doit = smc_pnet_del
0699 },
0700 {
0701 .cmd = SMC_PNETID_FLUSH,
0702 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
0703 .flags = GENL_ADMIN_PERM,
0704 .doit = smc_pnet_flush
0705 }
0706 };
0707
0708
0709 static struct genl_family smc_pnet_nl_family __ro_after_init = {
0710 .hdrsize = 0,
0711 .name = SMCR_GENL_FAMILY_NAME,
0712 .version = SMCR_GENL_FAMILY_VERSION,
0713 .maxattr = SMC_PNETID_MAX,
0714 .policy = smc_pnet_policy,
0715 .netnsok = true,
0716 .module = THIS_MODULE,
0717 .ops = smc_pnet_ops,
0718 .n_ops = ARRAY_SIZE(smc_pnet_ops)
0719 };
0720
0721 bool smc_pnet_is_ndev_pnetid(struct net *net, u8 *pnetid)
0722 {
0723 struct smc_net *sn = net_generic(net, smc_net_id);
0724 struct smc_pnetids_ndev_entry *pe;
0725 bool rc = false;
0726
0727 read_lock(&sn->pnetids_ndev.lock);
0728 list_for_each_entry(pe, &sn->pnetids_ndev.list, list) {
0729 if (smc_pnet_match(pnetid, pe->pnetid)) {
0730 rc = true;
0731 goto unlock;
0732 }
0733 }
0734
0735 unlock:
0736 read_unlock(&sn->pnetids_ndev.lock);
0737 return rc;
0738 }
0739
0740 static int smc_pnet_add_pnetid(struct net *net, u8 *pnetid)
0741 {
0742 struct smc_net *sn = net_generic(net, smc_net_id);
0743 struct smc_pnetids_ndev_entry *pe, *pi;
0744
0745 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
0746 if (!pe)
0747 return -ENOMEM;
0748
0749 write_lock(&sn->pnetids_ndev.lock);
0750 list_for_each_entry(pi, &sn->pnetids_ndev.list, list) {
0751 if (smc_pnet_match(pnetid, pe->pnetid)) {
0752 refcount_inc(&pi->refcnt);
0753 kfree(pe);
0754 goto unlock;
0755 }
0756 }
0757 refcount_set(&pe->refcnt, 1);
0758 memcpy(pe->pnetid, pnetid, SMC_MAX_PNETID_LEN);
0759 list_add_tail(&pe->list, &sn->pnetids_ndev.list);
0760
0761 unlock:
0762 write_unlock(&sn->pnetids_ndev.lock);
0763 return 0;
0764 }
0765
0766 static void smc_pnet_remove_pnetid(struct net *net, u8 *pnetid)
0767 {
0768 struct smc_net *sn = net_generic(net, smc_net_id);
0769 struct smc_pnetids_ndev_entry *pe, *pe2;
0770
0771 write_lock(&sn->pnetids_ndev.lock);
0772 list_for_each_entry_safe(pe, pe2, &sn->pnetids_ndev.list, list) {
0773 if (smc_pnet_match(pnetid, pe->pnetid)) {
0774 if (refcount_dec_and_test(&pe->refcnt)) {
0775 list_del(&pe->list);
0776 kfree(pe);
0777 }
0778 break;
0779 }
0780 }
0781 write_unlock(&sn->pnetids_ndev.lock);
0782 }
0783
0784 static void smc_pnet_add_base_pnetid(struct net *net, struct net_device *dev,
0785 u8 *ndev_pnetid)
0786 {
0787 struct net_device *base_dev;
0788
0789 base_dev = __pnet_find_base_ndev(dev);
0790 if (base_dev->flags & IFF_UP &&
0791 !smc_pnetid_by_dev_port(base_dev->dev.parent, base_dev->dev_port,
0792 ndev_pnetid)) {
0793
0794 smc_pnet_add_pnetid(net, ndev_pnetid);
0795 }
0796 }
0797
0798
0799 static void smc_pnet_create_pnetids_list(struct net *net)
0800 {
0801 u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
0802 struct net_device *dev;
0803
0804 rtnl_lock();
0805 for_each_netdev(net, dev)
0806 smc_pnet_add_base_pnetid(net, dev, ndev_pnetid);
0807 rtnl_unlock();
0808 }
0809
0810
0811 static void smc_pnet_destroy_pnetids_list(struct net *net)
0812 {
0813 struct smc_net *sn = net_generic(net, smc_net_id);
0814 struct smc_pnetids_ndev_entry *pe, *temp_pe;
0815
0816 write_lock(&sn->pnetids_ndev.lock);
0817 list_for_each_entry_safe(pe, temp_pe, &sn->pnetids_ndev.list, list) {
0818 list_del(&pe->list);
0819 kfree(pe);
0820 }
0821 write_unlock(&sn->pnetids_ndev.lock);
0822 }
0823
0824 static int smc_pnet_netdev_event(struct notifier_block *this,
0825 unsigned long event, void *ptr)
0826 {
0827 struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
0828 struct net *net = dev_net(event_dev);
0829 u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
0830
0831 switch (event) {
0832 case NETDEV_REBOOT:
0833 case NETDEV_UNREGISTER:
0834 smc_pnet_remove_by_ndev(event_dev);
0835 smc_ib_ndev_change(event_dev, event);
0836 return NOTIFY_OK;
0837 case NETDEV_REGISTER:
0838 smc_pnet_add_by_ndev(event_dev);
0839 smc_ib_ndev_change(event_dev, event);
0840 return NOTIFY_OK;
0841 case NETDEV_UP:
0842 smc_pnet_add_base_pnetid(net, event_dev, ndev_pnetid);
0843 return NOTIFY_OK;
0844 case NETDEV_DOWN:
0845 event_dev = __pnet_find_base_ndev(event_dev);
0846 if (!smc_pnetid_by_dev_port(event_dev->dev.parent,
0847 event_dev->dev_port, ndev_pnetid)) {
0848
0849 smc_pnet_remove_pnetid(net, ndev_pnetid);
0850 }
0851 return NOTIFY_OK;
0852 default:
0853 return NOTIFY_DONE;
0854 }
0855 }
0856
0857 static struct notifier_block smc_netdev_notifier = {
0858 .notifier_call = smc_pnet_netdev_event
0859 };
0860
0861
0862 int smc_pnet_net_init(struct net *net)
0863 {
0864 struct smc_net *sn = net_generic(net, smc_net_id);
0865 struct smc_pnettable *pnettable = &sn->pnettable;
0866 struct smc_pnetids_ndev *pnetids_ndev = &sn->pnetids_ndev;
0867
0868 INIT_LIST_HEAD(&pnettable->pnetlist);
0869 mutex_init(&pnettable->lock);
0870 INIT_LIST_HEAD(&pnetids_ndev->list);
0871 rwlock_init(&pnetids_ndev->lock);
0872
0873 smc_pnet_create_pnetids_list(net);
0874
0875
0876 net->smc.limit_smc_hs = 0;
0877
0878 return 0;
0879 }
0880
0881 int __init smc_pnet_init(void)
0882 {
0883 int rc;
0884
0885 rc = genl_register_family(&smc_pnet_nl_family);
0886 if (rc)
0887 return rc;
0888 rc = register_netdevice_notifier(&smc_netdev_notifier);
0889 if (rc)
0890 genl_unregister_family(&smc_pnet_nl_family);
0891
0892 return rc;
0893 }
0894
0895
0896 void smc_pnet_net_exit(struct net *net)
0897 {
0898
0899 smc_pnet_remove_by_pnetid(net, NULL);
0900 smc_pnet_destroy_pnetids_list(net);
0901 }
0902
0903 void smc_pnet_exit(void)
0904 {
0905 unregister_netdevice_notifier(&smc_netdev_notifier);
0906 genl_unregister_family(&smc_pnet_nl_family);
0907 }
0908
0909 static struct net_device *__pnet_find_base_ndev(struct net_device *ndev)
0910 {
0911 int i, nest_lvl;
0912
0913 ASSERT_RTNL();
0914 nest_lvl = ndev->lower_level;
0915 for (i = 0; i < nest_lvl; i++) {
0916 struct list_head *lower = &ndev->adj_list.lower;
0917
0918 if (list_empty(lower))
0919 break;
0920 lower = lower->next;
0921 ndev = netdev_lower_get_next(ndev, &lower);
0922 }
0923 return ndev;
0924 }
0925
0926
0927
0928
0929
0930
0931 static struct net_device *pnet_find_base_ndev(struct net_device *ndev)
0932 {
0933 rtnl_lock();
0934 ndev = __pnet_find_base_ndev(ndev);
0935 rtnl_unlock();
0936 return ndev;
0937 }
0938
0939 static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev,
0940 u8 *pnetid)
0941 {
0942 struct smc_pnettable *pnettable;
0943 struct net *net = dev_net(ndev);
0944 struct smc_pnetentry *pnetelem;
0945 struct smc_net *sn;
0946 int rc = -ENOENT;
0947
0948
0949 sn = net_generic(net, smc_net_id);
0950 pnettable = &sn->pnettable;
0951
0952 mutex_lock(&pnettable->lock);
0953 list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
0954 if (pnetelem->type == SMC_PNET_ETH && ndev == pnetelem->ndev) {
0955
0956 memcpy(pnetid, pnetelem->pnet_name, SMC_MAX_PNETID_LEN);
0957 rc = 0;
0958 break;
0959 }
0960 }
0961 mutex_unlock(&pnettable->lock);
0962 return rc;
0963 }
0964
0965 static int smc_pnet_determine_gid(struct smc_ib_device *ibdev, int i,
0966 struct smc_init_info *ini)
0967 {
0968 if (!ini->check_smcrv2 &&
0969 !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->ib_gid, NULL,
0970 NULL)) {
0971 ini->ib_dev = ibdev;
0972 ini->ib_port = i;
0973 return 0;
0974 }
0975 if (ini->check_smcrv2 &&
0976 !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->smcrv2.ib_gid_v2,
0977 NULL, &ini->smcrv2)) {
0978 ini->smcrv2.ib_dev_v2 = ibdev;
0979 ini->smcrv2.ib_port_v2 = i;
0980 return 0;
0981 }
0982 return -ENODEV;
0983 }
0984
0985
0986 static void _smc_pnet_find_roce_by_pnetid(u8 *pnet_id,
0987 struct smc_init_info *ini,
0988 struct smc_ib_device *known_dev,
0989 struct net *net)
0990 {
0991 struct smc_ib_device *ibdev;
0992 int i;
0993
0994 mutex_lock(&smc_ib_devices.mutex);
0995 list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
0996 if (ibdev == known_dev ||
0997 !rdma_dev_access_netns(ibdev->ibdev, net))
0998 continue;
0999 for (i = 1; i <= SMC_MAX_PORTS; i++) {
1000 if (!rdma_is_port_valid(ibdev->ibdev, i))
1001 continue;
1002 if (smc_pnet_match(ibdev->pnetid[i - 1], pnet_id) &&
1003 smc_ib_port_active(ibdev, i) &&
1004 !test_bit(i - 1, ibdev->ports_going_away)) {
1005 if (!smc_pnet_determine_gid(ibdev, i, ini))
1006 goto out;
1007 }
1008 }
1009 }
1010 out:
1011 mutex_unlock(&smc_ib_devices.mutex);
1012 }
1013
1014
1015 void smc_pnet_find_alt_roce(struct smc_link_group *lgr,
1016 struct smc_init_info *ini,
1017 struct smc_ib_device *known_dev)
1018 {
1019 struct net *net = lgr->net;
1020
1021 _smc_pnet_find_roce_by_pnetid(lgr->pnet_id, ini, known_dev, net);
1022 }
1023
1024
1025
1026
1027 static void smc_pnet_find_rdma_dev(struct net_device *netdev,
1028 struct smc_init_info *ini)
1029 {
1030 struct net *net = dev_net(netdev);
1031 struct smc_ib_device *ibdev;
1032
1033 mutex_lock(&smc_ib_devices.mutex);
1034 list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
1035 struct net_device *ndev;
1036 int i;
1037
1038
1039 if (!rdma_dev_access_netns(ibdev->ibdev, net))
1040 continue;
1041
1042 for (i = 1; i <= SMC_MAX_PORTS; i++) {
1043 if (!rdma_is_port_valid(ibdev->ibdev, i))
1044 continue;
1045 if (!ibdev->ibdev->ops.get_netdev)
1046 continue;
1047 ndev = ibdev->ibdev->ops.get_netdev(ibdev->ibdev, i);
1048 if (!ndev)
1049 continue;
1050 dev_put(ndev);
1051 if (netdev == ndev &&
1052 smc_ib_port_active(ibdev, i) &&
1053 !test_bit(i - 1, ibdev->ports_going_away)) {
1054 if (!smc_pnet_determine_gid(ibdev, i, ini))
1055 break;
1056 }
1057 }
1058 }
1059 mutex_unlock(&smc_ib_devices.mutex);
1060 }
1061
1062
1063
1064
1065
1066
1067
1068 static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
1069 struct smc_init_info *ini)
1070 {
1071 u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
1072 struct net *net;
1073
1074 ndev = pnet_find_base_ndev(ndev);
1075 net = dev_net(ndev);
1076 if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
1077 ndev_pnetid) &&
1078 smc_pnet_find_ndev_pnetid_by_table(ndev, ndev_pnetid)) {
1079 smc_pnet_find_rdma_dev(ndev, ini);
1080 return;
1081 }
1082 _smc_pnet_find_roce_by_pnetid(ndev_pnetid, ini, NULL, net);
1083 }
1084
1085 static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,
1086 struct smc_init_info *ini)
1087 {
1088 u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
1089 struct smcd_dev *ismdev;
1090
1091 ndev = pnet_find_base_ndev(ndev);
1092 if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
1093 ndev_pnetid) &&
1094 smc_pnet_find_ndev_pnetid_by_table(ndev, ndev_pnetid))
1095 return;
1096
1097 mutex_lock(&smcd_dev_list.mutex);
1098 list_for_each_entry(ismdev, &smcd_dev_list.list, list) {
1099 if (smc_pnet_match(ismdev->pnetid, ndev_pnetid) &&
1100 !ismdev->going_away &&
1101 (!ini->ism_peer_gid[0] ||
1102 !smc_ism_cantalk(ini->ism_peer_gid[0], ini->vlan_id,
1103 ismdev))) {
1104 ini->ism_dev[0] = ismdev;
1105 break;
1106 }
1107 }
1108 mutex_unlock(&smcd_dev_list.mutex);
1109 }
1110
1111
1112
1113
1114
1115 void smc_pnet_find_roce_resource(struct sock *sk, struct smc_init_info *ini)
1116 {
1117 struct dst_entry *dst = sk_dst_get(sk);
1118
1119 if (!dst)
1120 goto out;
1121 if (!dst->dev)
1122 goto out_rel;
1123
1124 smc_pnet_find_roce_by_pnetid(dst->dev, ini);
1125
1126 out_rel:
1127 dst_release(dst);
1128 out:
1129 return;
1130 }
1131
1132 void smc_pnet_find_ism_resource(struct sock *sk, struct smc_init_info *ini)
1133 {
1134 struct dst_entry *dst = sk_dst_get(sk);
1135
1136 ini->ism_dev[0] = NULL;
1137 if (!dst)
1138 goto out;
1139 if (!dst->dev)
1140 goto out_rel;
1141
1142 smc_pnet_find_ism_by_pnetid(dst->dev, ini);
1143
1144 out_rel:
1145 dst_release(dst);
1146 out:
1147 return;
1148 }
1149
1150
1151
1152 int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
1153 {
1154 char *ib_name = smcibdev->ibdev->name;
1155 struct smc_pnettable *pnettable;
1156 struct smc_pnetentry *tmp_pe;
1157 struct smc_net *sn;
1158 int rc = -ENOENT;
1159
1160
1161 sn = net_generic(&init_net, smc_net_id);
1162 pnettable = &sn->pnettable;
1163
1164 mutex_lock(&pnettable->lock);
1165 list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
1166 if (tmp_pe->type == SMC_PNET_IB &&
1167 !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX) &&
1168 tmp_pe->ib_port == ib_port) {
1169 smc_pnet_apply_ib(smcibdev, ib_port, tmp_pe->pnet_name);
1170 rc = 0;
1171 break;
1172 }
1173 }
1174 mutex_unlock(&pnettable->lock);
1175
1176 return rc;
1177 }
1178
1179
1180
1181 int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
1182 {
1183 const char *ib_name = dev_name(&smcddev->dev);
1184 struct smc_pnettable *pnettable;
1185 struct smc_pnetentry *tmp_pe;
1186 struct smc_net *sn;
1187 int rc = -ENOENT;
1188
1189
1190 sn = net_generic(&init_net, smc_net_id);
1191 pnettable = &sn->pnettable;
1192
1193 mutex_lock(&pnettable->lock);
1194 list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
1195 if (tmp_pe->type == SMC_PNET_IB &&
1196 !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
1197 smc_pnet_apply_smcd(smcddev, tmp_pe->pnet_name);
1198 rc = 0;
1199 break;
1200 }
1201 }
1202 mutex_unlock(&pnettable->lock);
1203
1204 return rc;
1205 }