^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Shared Memory Communications over RDMA (SMC-R) and RoCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Generic netlink support functions to configure an SMC-R PNET table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright IBM Corp. 2016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author(s): Thomas Richter <tmricht@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <uapi/linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <uapi/linux/smc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <rdma/ib_verbs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/netns/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "smc_netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "smc_pnet.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "smc_ib.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "smc_ism.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "smc_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct net_device *__pnet_find_base_ndev(struct net_device *ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static struct net_device *pnet_find_base_ndev(struct net_device *ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct nla_policy smc_pnet_policy[SMC_PNETID_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) [SMC_PNETID_NAME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .len = SMC_MAX_PNETID_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) [SMC_PNETID_ETHNAME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .len = IFNAMSIZ - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) [SMC_PNETID_IBNAME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .len = IB_DEVICE_NAME_MAX - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [SMC_PNETID_IBPORT] = { .type = NLA_U8 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct genl_family smc_pnet_nl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) enum smc_pnet_nametype {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) SMC_PNET_ETH = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) SMC_PNET_IB = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* pnet entry stored in pnet table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct smc_pnetentry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) char pnet_name[SMC_MAX_PNETID_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) enum smc_pnet_nametype type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) char eth_name[IFNAMSIZ + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct net_device *ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) char ib_name[IB_DEVICE_NAME_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u8 ib_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Check if the pnetid is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bool smc_pnet_is_pnetid_set(u8 *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (pnetid[0] == 0 || pnetid[0] == _S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Check if two given pnetids match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static bool smc_pnet_match(u8 *pnetid1, u8 *pnetid2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for (i = 0; i < SMC_MAX_PNETID_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if ((pnetid1[i] == 0 || pnetid1[i] == _S) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) (pnetid2[i] == 0 || pnetid2[i] == _S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (pnetid1[i] != pnetid2[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Remove a pnetid from the pnet table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct smc_pnetentry *pnetelem, *tmp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct smc_ib_device *ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct smcd_dev *smcd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int ibport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* remove table entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!pnet_name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) smc_pnet_match(pnetelem->pnet_name, pnet_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) list_del(&pnetelem->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dev_put(pnetelem->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pr_warn_ratelimited("smc: net device %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "erased user defined "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "pnetid %.16s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pnetelem->eth_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pnetelem->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) kfree(pnetelem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* if this is not the initial namespace, stop here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (net != &init_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* remove ib devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mutex_lock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) for (ibport = 0; ibport < SMC_MAX_PORTS; ibport++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (ibdev->pnetid_by_user[ibport] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) (!pnet_name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) smc_pnet_match(pnet_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ibdev->pnetid[ibport]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pr_warn_ratelimited("smc: ib device %s ibport "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "%d erased user defined "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) "pnetid %.16s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ibdev->ibdev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ibport + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ibdev->pnetid[ibport]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) memset(ibdev->pnetid[ibport], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ibdev->pnetid_by_user[ibport] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_unlock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* remove smcd devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mutex_lock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (smcd_dev->pnetid_by_user &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (!pnet_name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) smc_pnet_match(pnet_name, smcd_dev->pnetid))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pr_warn_ratelimited("smc: smcd device %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "erased user defined pnetid "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) "%.16s\n", dev_name(&smcd_dev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) smcd_dev->pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memset(smcd_dev->pnetid, 0, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) smcd_dev->pnetid_by_user = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mutex_unlock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Add the reference to a given network device to the pnet table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int smc_pnet_add_by_ndev(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct smc_pnetentry *pnetelem, *tmp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct net *net = dev_net(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (pnetelem->type == SMC_PNET_ETH && !pnetelem->ndev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) !strncmp(pnetelem->eth_name, ndev->name, IFNAMSIZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_hold(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pnetelem->ndev = ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pr_warn_ratelimited("smc: adding net device %s with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) "user defined pnetid %.16s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) pnetelem->eth_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) pnetelem->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Remove the reference to a given network device from the pnet table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int smc_pnet_remove_by_ndev(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct smc_pnetentry *pnetelem, *tmp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct net *net = dev_net(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev == ndev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_put(pnetelem->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pnetelem->ndev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pr_warn_ratelimited("smc: removing net device %s with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "user defined pnetid %.16s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pnetelem->eth_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pnetelem->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Apply pnetid to ib device when no pnetid is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static bool smc_pnet_apply_ib(struct smc_ib_device *ib_dev, u8 ib_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) char *pnet_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) bool applied = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) mutex_lock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!smc_pnet_is_pnetid_set(ib_dev->pnetid[ib_port - 1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) memcpy(ib_dev->pnetid[ib_port - 1], pnet_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ib_dev->pnetid_by_user[ib_port - 1] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) applied = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mutex_unlock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return applied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* Apply pnetid to smcd device when no pnetid is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static bool smc_pnet_apply_smcd(struct smcd_dev *smcd_dev, char *pnet_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) bool applied = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) mutex_lock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!smc_pnet_is_pnetid_set(smcd_dev->pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) memcpy(smcd_dev->pnetid, pnet_name, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) smcd_dev->pnetid_by_user = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) applied = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mutex_unlock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return applied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* The limit for pnetid is 16 characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Valid characters should be (single-byte character set) a-z, A-Z, 0-9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Lower case letters are converted to upper case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Interior blanks should not be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static bool smc_pnetid_valid(const char *pnet_name, char *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) char *bf = skip_spaces(pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) size_t len = strlen(bf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) char *end = bf + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) while (--end >= bf && isspace(*end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (end - bf >= SMC_MAX_PNETID_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) while (bf <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!isalnum(*bf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *pnetid++ = islower(*bf) ? toupper(*bf) : *bf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *pnetid = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Find an infiniband device by a given name. The device might not exist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct smc_ib_device *ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mutex_lock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!strncmp(ibdev->ibdev->name, ib_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sizeof(ibdev->ibdev->name)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) !strncmp(dev_name(ibdev->ibdev->dev.parent), ib_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) IB_DEVICE_NAME_MAX - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ibdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) mutex_unlock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Find an smcd device by a given name. The device might not exist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct smcd_dev *smcd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_lock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!strncmp(dev_name(&smcd_dev->dev), smcd_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) IB_DEVICE_NAME_MAX - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) smcd_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mutex_unlock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return smcd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) char *eth_name, char *pnet_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct smc_pnetentry *tmp_pe, *new_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct net_device *ndev, *base_ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) bool new_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* check if (base) netdev already has a pnetid. If there is one, we do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * not want to add a pnet table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ndev = dev_get_by_name(net, eth_name); /* dev_hold() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ndev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) base_ndev = pnet_find_base_ndev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!smc_pnetid_by_dev_port(base_ndev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) base_ndev->dev_port, ndev_pnetid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* add a new netdev entry to the pnet table if there isn't one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!new_pe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) new_pe->type = SMC_PNET_ETH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) memcpy(new_pe->pnet_name, pnet_name, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) strncpy(new_pe->eth_name, eth_name, IFNAMSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) new_pe->ndev = ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) new_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (tmp_pe->type == SMC_PNET_ETH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) !strncmp(tmp_pe->eth_name, eth_name, IFNAMSIZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) new_netdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (new_netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) list_add_tail(&new_pe->list, &pnettable->pnetlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) kfree(new_pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pr_warn_ratelimited("smc: net device %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) "applied user defined pnetid %.16s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) new_pe->eth_name, new_pe->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_put(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u8 ib_port, char *pnet_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct smc_pnetentry *tmp_pe, *new_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct smc_ib_device *ib_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) bool smcddev_applied = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bool ibdev_applied = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct smcd_dev *smcd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) bool new_ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* try to apply the pnetid to active devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ib_dev = smc_pnet_find_ib(ib_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (ib_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ibdev_applied = smc_pnet_apply_ib(ib_dev, ib_port, pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (ibdev_applied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pr_warn_ratelimited("smc: ib device %s ibport %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "applied user defined pnetid "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) "%.16s\n", ib_dev->ibdev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ib_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ib_dev->pnetid[ib_port - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) smcd_dev = smc_pnet_find_smcd(ib_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (smcd_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) smcddev_applied = smc_pnet_apply_smcd(smcd_dev, pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (smcddev_applied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pr_warn_ratelimited("smc: smcd device %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) "applied user defined pnetid "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) "%.16s\n", dev_name(&smcd_dev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) smcd_dev->pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Apply fails when a device has a hardware-defined pnetid set, do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * add a pnet table entry in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!ibdev_applied || !smcddev_applied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* add a new ib entry to the pnet table if there isn't one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!new_pe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) new_pe->type = SMC_PNET_IB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) memcpy(new_pe->pnet_name, pnet_name, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) strncpy(new_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) new_pe->ib_port = ib_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) new_ibdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (tmp_pe->type == SMC_PNET_IB &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) new_ibdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (new_ibdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) list_add_tail(&new_pe->list, &pnettable->pnetlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) kfree(new_pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return (new_ibdev) ? 0 : -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* Append a pnetid to the end of the pnet table if not already on this list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int smc_pnet_enter(struct net *net, struct nlattr *tb[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) char pnet_name[SMC_MAX_PNETID_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) bool new_netdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) bool new_ibdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u8 ibport = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) char *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (!tb[SMC_PNETID_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) string = (char *)nla_data(tb[SMC_PNETID_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!smc_pnetid_valid(string, pnet_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (tb[SMC_PNETID_ETHNAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) string = (char *)nla_data(tb[SMC_PNETID_ETHNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) rc = smc_pnet_add_eth(pnettable, net, string, pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) new_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) else if (rc != -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* if this is not the initial namespace, stop here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (net != &init_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return new_netdev ? 0 : -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (tb[SMC_PNETID_IBNAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) string = (char *)nla_data(tb[SMC_PNETID_IBNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) string = strim(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (tb[SMC_PNETID_IBPORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ibport = nla_get_u8(tb[SMC_PNETID_IBPORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ibport < 1 || ibport > SMC_MAX_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) rc = smc_pnet_add_ib(pnettable, string, ibport, pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) new_ibdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) else if (rc != -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return (new_netdev || new_ibdev) ? 0 : -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* Convert an smc_pnetentry to a netlink attribute sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static int smc_pnet_set_nla(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct smc_pnetentry *pnetelem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (nla_put_string(msg, SMC_PNETID_NAME, pnetelem->pnet_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (pnetelem->type == SMC_PNET_ETH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (nla_put_string(msg, SMC_PNETID_ETHNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pnetelem->eth_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (nla_put_string(msg, SMC_PNETID_ETHNAME, "n/a"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (pnetelem->type == SMC_PNET_IB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (nla_put_string(msg, SMC_PNETID_IBNAME, pnetelem->ib_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) nla_put_u8(msg, SMC_PNETID_IBPORT, pnetelem->ib_port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (nla_put_string(msg, SMC_PNETID_IBNAME, "n/a") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) nla_put_u8(msg, SMC_PNETID_IBPORT, 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return smc_pnet_enter(net, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int smc_pnet_del(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!info->attrs[SMC_PNETID_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return smc_pnet_remove_by_pnetid(net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) (char *)nla_data(info->attrs[SMC_PNETID_NAME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int smc_pnet_dump_start(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) cb->args[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int smc_pnet_dumpinfo(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u32 portid, u32 seq, u32 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct smc_pnetentry *pnetelem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) hdr = genlmsg_put(skb, portid, seq, &smc_pnet_nl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) flags, SMC_PNETID_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (smc_pnet_set_nla(skb, pnetelem) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u32 seq, u8 *pnetid, int start_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct smc_pnetentry *pnetelem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* dump pnettable entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (pnetid && !smc_pnet_match(pnetelem->pnet_name, pnetid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (idx++ < start_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* if this is not the initial namespace, dump only netdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (net != &init_net && pnetelem->type != SMC_PNET_ETH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (smc_pnet_dumpinfo(skb, portid, seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) pnetelem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) --idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int smc_pnet_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) idx = _smc_pnet_dump(net, skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) cb->nlh->nlmsg_seq, NULL, cb->args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) cb->args[0] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Retrieve one PNETID entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static int smc_pnet_get(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (!info->attrs[SMC_PNETID_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) _smc_pnet_dump(net, msg, info->snd_portid, info->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) nla_data(info->attrs[SMC_PNETID_NAME]), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* finish multi part message and send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) hdr = nlmsg_put(msg, info->snd_portid, info->snd_seq, NLMSG_DONE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* Remove and delete all pnetids from pnet table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int smc_pnet_flush(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) smc_pnet_remove_by_pnetid(net, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* SMC_PNETID generic netlink operation definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static const struct genl_ops smc_pnet_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) .cmd = SMC_PNETID_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .doit = smc_pnet_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .dumpit = smc_pnet_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .start = smc_pnet_dump_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .cmd = SMC_PNETID_ADD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .doit = smc_pnet_add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .cmd = SMC_PNETID_DEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .doit = smc_pnet_del
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) .cmd = SMC_PNETID_FLUSH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) .doit = smc_pnet_flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* SMC_PNETID family definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static struct genl_family smc_pnet_nl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) .hdrsize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .name = SMCR_GENL_FAMILY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .version = SMCR_GENL_FAMILY_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) .maxattr = SMC_PNETID_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) .policy = smc_pnet_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .ops = smc_pnet_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .n_ops = ARRAY_SIZE(smc_pnet_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) bool smc_pnet_is_ndev_pnetid(struct net *net, u8 *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct smc_net *sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct smc_pnetids_ndev_entry *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bool rc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) read_lock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) list_for_each_entry(pe, &sn->pnetids_ndev.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (smc_pnet_match(pnetid, pe->pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) rc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) read_unlock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static int smc_pnet_add_pnetid(struct net *net, u8 *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct smc_net *sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct smc_pnetids_ndev_entry *pe, *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) pe = kzalloc(sizeof(*pe), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!pe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) write_lock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) list_for_each_entry(pi, &sn->pnetids_ndev.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (smc_pnet_match(pnetid, pe->pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) refcount_inc(&pi->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) kfree(pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) refcount_set(&pe->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) memcpy(pe->pnetid, pnetid, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) list_add_tail(&pe->list, &sn->pnetids_ndev.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) write_unlock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static void smc_pnet_remove_pnetid(struct net *net, u8 *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct smc_net *sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct smc_pnetids_ndev_entry *pe, *pe2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) write_lock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) list_for_each_entry_safe(pe, pe2, &sn->pnetids_ndev.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (smc_pnet_match(pnetid, pe->pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (refcount_dec_and_test(&pe->refcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) list_del(&pe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) kfree(pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) write_unlock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static void smc_pnet_add_base_pnetid(struct net *net, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u8 *ndev_pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct net_device *base_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) base_dev = __pnet_find_base_ndev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (base_dev->flags & IFF_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) !smc_pnetid_by_dev_port(base_dev->dev.parent, base_dev->dev_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ndev_pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* add to PNETIDs list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) smc_pnet_add_pnetid(net, ndev_pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* create initial list of netdevice pnetids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static void smc_pnet_create_pnetids_list(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) for_each_netdev(net, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) smc_pnet_add_base_pnetid(net, dev, ndev_pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* clean up list of netdevice pnetids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static void smc_pnet_destroy_pnetids_list(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct smc_net *sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct smc_pnetids_ndev_entry *pe, *temp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) write_lock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) list_for_each_entry_safe(pe, temp_pe, &sn->pnetids_ndev.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) list_del(&pe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) kfree(pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) write_unlock(&sn->pnetids_ndev.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int smc_pnet_netdev_event(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct net *net = dev_net(event_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) case NETDEV_REBOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case NETDEV_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) smc_pnet_remove_by_ndev(event_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case NETDEV_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) smc_pnet_add_by_ndev(event_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) smc_pnet_add_base_pnetid(net, event_dev, ndev_pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) event_dev = __pnet_find_base_ndev(event_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (!smc_pnetid_by_dev_port(event_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) event_dev->dev_port, ndev_pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* remove from PNETIDs list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) smc_pnet_remove_pnetid(net, ndev_pnetid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static struct notifier_block smc_netdev_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .notifier_call = smc_pnet_netdev_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /* init network namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int smc_pnet_net_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct smc_net *sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct smc_pnettable *pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct smc_pnetids_ndev *pnetids_ndev = &sn->pnetids_ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) INIT_LIST_HEAD(&pnettable->pnetlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) mutex_init(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) INIT_LIST_HEAD(&pnetids_ndev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) rwlock_init(&pnetids_ndev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) smc_pnet_create_pnetids_list(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int __init smc_pnet_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) rc = genl_register_family(&smc_pnet_nl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) rc = register_netdevice_notifier(&smc_netdev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) genl_unregister_family(&smc_pnet_nl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* exit network namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) void smc_pnet_net_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* flush pnet table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) smc_pnet_remove_by_pnetid(net, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) smc_pnet_destroy_pnetids_list(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) void smc_pnet_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) unregister_netdevice_notifier(&smc_netdev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) genl_unregister_family(&smc_pnet_nl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static struct net_device *__pnet_find_base_ndev(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int i, nest_lvl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) nest_lvl = ndev->lower_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) for (i = 0; i < nest_lvl; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct list_head *lower = &ndev->adj_list.lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (list_empty(lower))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) lower = lower->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ndev = netdev_lower_get_next(ndev, &lower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* Determine one base device for stacked net devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * If the lower device level contains more than one devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * (for instance with bonding slaves), just the first device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * is used to reach a base device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static struct net_device *pnet_find_base_ndev(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ndev = __pnet_find_base_ndev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) u8 *pnetid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct net *net = dev_net(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct smc_pnetentry *pnetelem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* get pnettable for namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) sn = net_generic(net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (pnetelem->type == SMC_PNET_ETH && ndev == pnetelem->ndev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /* get pnetid of netdev device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) memcpy(pnetid, pnetelem->pnet_name, SMC_MAX_PNETID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* find a roce device for the given pnetid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static void _smc_pnet_find_roce_by_pnetid(u8 *pnet_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct smc_init_info *ini,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct smc_ib_device *known_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct smc_ib_device *ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ini->ib_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) mutex_lock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (ibdev == known_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) for (i = 1; i <= SMC_MAX_PORTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (!rdma_is_port_valid(ibdev->ibdev, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (smc_pnet_match(ibdev->pnetid[i - 1], pnet_id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) smc_ib_port_active(ibdev, i) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) !test_bit(i - 1, ibdev->ports_going_away) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) !smc_ib_determine_gid(ibdev, i, ini->vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ini->ib_gid, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ini->ib_dev = ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ini->ib_port = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) mutex_unlock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* find alternate roce device with same pnet_id and vlan_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) void smc_pnet_find_alt_roce(struct smc_link_group *lgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct smc_init_info *ini,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct smc_ib_device *known_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) _smc_pnet_find_roce_by_pnetid(lgr->pnet_id, ini, known_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* if handshake network device belongs to a roce device, return its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * IB device and port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static void smc_pnet_find_rdma_dev(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct smc_init_info *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct smc_ib_device *ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) mutex_lock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct net_device *ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) for (i = 1; i <= SMC_MAX_PORTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (!rdma_is_port_valid(ibdev->ibdev, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!ibdev->ibdev->ops.get_netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ndev = ibdev->ibdev->ops.get_netdev(ibdev->ibdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (!ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dev_put(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (netdev == ndev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) smc_ib_port_active(ibdev, i) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) !test_bit(i - 1, ibdev->ports_going_away) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) !smc_ib_determine_gid(ibdev, i, ini->vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ini->ib_gid, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ini->ib_dev = ibdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ini->ib_port = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) mutex_unlock(&smc_ib_devices.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Determine the corresponding IB device port based on the hardware PNETID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * Searching stops at the first matching active IB device port with vlan_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * If nothing found, check pnetid table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * If nothing found, try to use handshake device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct smc_init_info *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) ndev = pnet_find_base_ndev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ndev_pnetid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) smc_pnet_find_ndev_pnetid_by_table(ndev, ndev_pnetid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) smc_pnet_find_rdma_dev(ndev, ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return; /* pnetid could not be determined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) _smc_pnet_find_roce_by_pnetid(ndev_pnetid, ini, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct smc_init_info *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct smcd_dev *ismdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) ndev = pnet_find_base_ndev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) ndev_pnetid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) smc_pnet_find_ndev_pnetid_by_table(ndev, ndev_pnetid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return; /* pnetid could not be determined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) mutex_lock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) list_for_each_entry(ismdev, &smcd_dev_list.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (smc_pnet_match(ismdev->pnetid, ndev_pnetid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) !ismdev->going_away &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) (!ini->ism_peer_gid[0] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) !smc_ism_cantalk(ini->ism_peer_gid[0], ini->vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) ismdev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) ini->ism_dev[0] = ismdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) mutex_unlock(&smcd_dev_list.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* PNET table analysis for a given sock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * determine ib_device and port belonging to used internal TCP socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * ethernet interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) void smc_pnet_find_roce_resource(struct sock *sk, struct smc_init_info *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct dst_entry *dst = sk_dst_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ini->ib_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) ini->ib_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (!dst->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) goto out_rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) smc_pnet_find_roce_by_pnetid(dst->dev, ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) out_rel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dst_release(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) void smc_pnet_find_ism_resource(struct sock *sk, struct smc_init_info *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct dst_entry *dst = sk_dst_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ini->ism_dev[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!dst->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto out_rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) smc_pnet_find_ism_by_pnetid(dst->dev, ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) out_rel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) dst_release(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Lookup and apply a pnet table entry to the given ib device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) char *ib_name = smcibdev->ibdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct smc_pnetentry *tmp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* get pnettable for init namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) sn = net_generic(&init_net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (tmp_pe->type == SMC_PNET_IB &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) tmp_pe->ib_port == ib_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) smc_pnet_apply_ib(smcibdev, ib_port, tmp_pe->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /* Lookup and apply a pnet table entry to the given smcd device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) const char *ib_name = dev_name(&smcddev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct smc_pnettable *pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct smc_pnetentry *tmp_pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct smc_net *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* get pnettable for init namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) sn = net_generic(&init_net, smc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) pnettable = &sn->pnettable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) mutex_lock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (tmp_pe->type == SMC_PNET_IB &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) smc_pnet_apply_smcd(smcddev, tmp_pe->pnet_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) mutex_unlock(&pnettable->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }