From bc94984d599e2e8cbc408c42896973745c533bb7 Mon Sep 17 00:00:00 2001
From: Wen Gu <guwen@linux.alibaba.com>
Date: Sat, 7 Jan 2023 16:58:37 +0800
Subject: [PATCH] net/smc: define SEID and CHID of loopback device

This patch defines SEID and CHID of loopback device and take it as
SMC-Dv2 device.

Besides, this patch delete the most logic of RFC patch 2/5 as well
because device selection will be covered by SMC-Dv2 protocol.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/af_smc.c       | 50 +++++---------------------------------------------
 net/smc/smc_clc.c      |  4 +---
 net/smc/smc_loopback.c | 11 +++++++----
 3 files changed, 13 insertions(+), 52 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index c7de566..4396392 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -979,28 +979,6 @@ static int smc_find_ism_device(struct smc_sock *smc, struct smc_init_info *ini)
 	return 0;
 }
 
-/* check if there is a lo device available for this connection. */
-static int smc_find_lo_device(struct smc_sock *smc, struct smc_init_info *ini)
-{
-	struct smcd_dev *sdev;
-
-	mutex_lock(&smcd_dev_list.mutex);
-	list_for_each_entry(sdev, &smcd_dev_list.list, list) {
-		if (sdev->is_loopback && !sdev->going_away &&
-		    (!ini->ism_peer_gid[0] ||
-		     !smc_ism_cantalk(ini->ism_peer_gid[0], ini->vlan_id,
-				      sdev))) {
-			ini->ism_dev[0] = sdev;
-			break;
-		}
-	}
-	mutex_unlock(&smcd_dev_list.mutex);
-	if (!ini->ism_dev[0])
-		return SMC_CLC_DECL_NOSMCDDEV;
-	ini->ism_chid[0] = smc_ism_get_chid(ini->ism_dev[0]);
-	return 0;
-}
-
 /* is chid unique for the ism devices that are already determined? */
 static bool smc_find_ism_v2_is_unique_chid(u16 chid, struct smc_init_info *ini,
 					   int cnt)
@@ -1066,19 +1044,10 @@ static int smc_find_proposal_devices(struct smc_sock *smc,
 {
 	int rc = 0;
 
-	/* TODO:
-	 * How to indicate to peer if ism device and loopback
-	 * device are both available ?
-	 *
-	 * The RFC patch hasn't resolved this, just simply always
-	 * chooses loopback device first, and fallback if loopback
-	 * communication is impossible.
-	 */
 	/* check if there is an ism or loopback device available */
 	if (!(ini->smcd_version & SMC_V1) ||
-	    (smc_find_lo_device(smc, ini) &&
-	    (smc_find_ism_device(smc, ini) ||
-	    smc_connect_ism_vlan_setup(smc, ini))))
+	    smc_find_ism_device(smc, ini) ||
+	    smc_connect_ism_vlan_setup(smc, ini))
 		ini->smcd_version &= ~SMC_V1;
 	/* else ISM V1 is supported for this connection */
 
@@ -2178,18 +2147,9 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
 	ini->is_smcd = true; /* prepare ISM check */
 	ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
 
-	/* TODO:
-	 * How to know that peer has both loopback and ism device ?
-	 *
-	 * The RFC patch hasn't resolved this, simply tries loopback
-	 * device first, then ism device.
-	 */
-	/* find available loopback or ism device */
-	if (smc_find_lo_device(new_smc, ini)) {
-		rc = smc_find_ism_device(new_smc, ini);
-		if (rc)
-			goto not_found;
-	}
+	rc = smc_find_ism_device(new_smc, ini);
+	if (rc)
+		goto not_found;
 
 	ini->ism_selected = 0;
 	rc = smc_listen_ism_init(new_smc, ini);
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 3887692..dfb9797 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -486,9 +486,7 @@ static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
 		return -ENODEV;
 
 	in_dev_for_each_ifa_rcu(ifa, in_dev) {
-		/* add loopback support */
-		if (inet_addr_type(dev_net(dst->dev), ipv4) != RTN_LOCAL &&
-		    !inet_ifa_match(ipv4, ifa))
+		if (!inet_ifa_match(ipv4, ifa))
 			continue;
 		prop->prefix_len = inet_mask_len(ifa->ifa_mask);
 		prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
diff --git a/net/smc/smc_loopback.c b/net/smc/smc_loopback.c
index 3dedcc4..642b241 100644
--- a/net/smc/smc_loopback.c
+++ b/net/smc/smc_loopback.c
@@ -19,13 +19,14 @@
 #include "smc_loopback.h"
 
 #define DRV_NAME "smc_lodev"
+#define LO_CHID	0xFFFF	/* specific for lo dev */
 
 struct smc_lo_dev *lo_dev;
 
 static struct smc_lo_systemeid LO_SYSTEM_EID = {
 	.seid_string = "SMC-SYSZ-LOSEID000000000",
-	.serial_number = "0000",
-	.type = "0000",
+	.serial_number = "1000",
+	.type = "1000",
 };
 
 static int smc_lo_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
@@ -33,7 +34,9 @@ static int smc_lo_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
 {
 	struct smc_lo_dev *ldev = smcd->priv;
 
-	/* return local gid */
+	if (!vid_valid || vid != ISM_RESERVED_VLANID)
+		return -EINVAL;
+	/* rgid should be equal to lgid */
 	if (!ldev || rgid != ldev->lgid)
 		return -ENETUNREACH;
 	return 0;
@@ -255,7 +258,7 @@ static u8 *smc_lo_get_system_eid(void)
 
 static u16 smc_lo_get_chid(struct smcd_dev *smcd)
 {
-	return 0;
+	return LO_CHID;
 }
 
 static const struct smcd_ops lo_ops = {
-- 
1.8.3.1