linux-gbmc: mctp: add new ioctl to set MCTP tag timeout

The default timeout of automatic allocated MCTP tag is hardcoded into 6
seconds. Here we add a new SIOCMCTPSETTAGTO ioctl which can be used by
application layer to set a new MCTP tag timeout value for AF_MCTP
socket.

We just put the patch in staging layer and it needs to be enabled in
platforms which needs this feature.

Tested:
https://paste.googleplex.com/5385756586278912

Fusion-Link: NA as this CL is a NOP
Platforms-Affected: NONE, this CL is a NOP by itself.
Google-Bug-Id: 421190486
Google-Bug-Id: 336355842
Google-Bug-Id: 337932733
Change-Id: I46a5bbae0eb4f5e6573ebdebb8f9db2f12bf44b1
Signed-off-by: Jinliang Wang <jinliangw@google.com>
(cherry picked from commit 890093d98358b781f177ecbbc4c842e016eeb4c1)
diff --git a/recipes-kernel/linux/files/0001-mctp-support-setting-MCTP-tag-timeout.patch b/recipes-kernel/linux/files/0001-mctp-support-setting-MCTP-tag-timeout.patch
new file mode 100644
index 0000000..944cb38
--- /dev/null
+++ b/recipes-kernel/linux/files/0001-mctp-support-setting-MCTP-tag-timeout.patch
@@ -0,0 +1,126 @@
+From b364c96b4d976f14da46f46703737b4d9bf23fa0 Mon Sep 17 00:00:00 2001
+From: Jinliang Wang <jinliangw@google.com>
+Date: Sun, 28 Apr 2024 21:15:25 -0700
+Subject: [PATCH] mctp: support setting MCTP tag timeout
+
+Define a new ioctl command SIOCMCTPSETTAGTO which can be used to set
+MCTP tag timeout per socket granularity.
+
+Without this patch, the default timeout for automatic allocated MCTP tag
+is mctp_key_lifetime (6 seconds).
+
+Patch Tracking Bug: b/337932733
+Upstream info / review: N/A
+Upstream-Status: Pending
+Justification:  we need control the timeout setting of MCTP tag.
+
+Google-Bug-Id: 336355842
+Signed-off-by: Jinliang Wang <jinliangw@google.com>
+---
+ include/net/mctp.h        |  3 +++
+ include/uapi/linux/mctp.h |  3 +++
+ net/mctp/af_mctp.c        | 15 +++++++++++++++
+ net/mctp/route.c          |  5 ++---
+ 4 files changed, 23 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/mctp.h b/include/net/mctp.h
+index d37268fe6825..4e3da43c075c 100644
+--- a/include/net/mctp.h
++++ b/include/net/mctp.h
+@@ -82,6 +82,9 @@ struct mctp_sock {
+ 	 */
+ 	struct hlist_head keys;
+ 
++	/* tag(key) expiry jiffies */
++	unsigned long key_lifetime;
++
+ 	/* mechanism for expiring allocated keys; will release an allocated
+ 	 * tag, and any netdev state for a request/response pairing
+ 	 */
+diff --git a/include/uapi/linux/mctp.h b/include/uapi/linux/mctp.h
+index 154ab56651f1..e6529d4a7b8d 100644
+--- a/include/uapi/linux/mctp.h
++++ b/include/uapi/linux/mctp.h
+@@ -51,6 +51,9 @@ struct sockaddr_mctp_ext {
+ #define SIOCMCTPALLOCTAG	(SIOCPROTOPRIVATE + 0)
+ #define SIOCMCTPDROPTAG		(SIOCPROTOPRIVATE + 1)
+ 
++/* Use last slot to avoid collision with upstream */
++#define SIOCMCTPSETTAGTO	(SIOCPROTOPRIVATE + 15)
++
+ struct mctp_ioc_tag_ctl {
+ 	mctp_eid_t	peer_addr;
+ 
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index 786079e6d8cf..8a14900e3f94 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -416,6 +416,17 @@ static int mctp_ioctl_droptag(struct mctp_sock *msk, unsigned long arg)
+ 	return rc;
+ }
+ 
++static int mctp_ioctl_settagto(struct mctp_sock *msk,
++				      unsigned long timeoutS)
++{
++	if (timeoutS == 0)
++		return -EINVAL;
++
++	pr_info_once("set_tag_timeout, key_lifetime: %lu seconds\n", timeoutS);
++	msk->key_lifetime = timeoutS * CONFIG_HZ;
++	return 0;
++}
++
+ static int mctp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+ {
+ 	struct mctp_sock *msk = container_of(sock->sk, struct mctp_sock, sk);
+@@ -425,6 +436,8 @@ static int mctp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+ 		return mctp_ioctl_alloctag(msk, arg);
+ 	case SIOCMCTPDROPTAG:
+ 		return mctp_ioctl_droptag(msk, arg);
++	case SIOCMCTPSETTAGTO:
++		return mctp_ioctl_settagto(msk, arg);
+ 	}
+ 
+ 	return -EINVAL;
+@@ -518,6 +531,8 @@ static int mctp_sk_init(struct sock *sk)
+ 	struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk);
+ 
+ 	INIT_HLIST_HEAD(&msk->keys);
++	/* 6 seconds by default*/
++	msk->key_lifetime = 6 * CONFIG_HZ;
+ 	timer_setup(&msk->key_expiry, mctp_sk_expire_keys, 0);
+ 	return 0;
+ }
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index b9a293c1c49c..3a41a23d2f74 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -27,7 +27,6 @@
+ #include <trace/events/mctp.h>
+ 
+ static const unsigned int mctp_message_maxlen = 64 * 1024;
+-static const unsigned long mctp_key_lifetime = 6 * CONFIG_HZ;
+ 
+ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev);
+ 
+@@ -196,7 +195,7 @@ static int mctp_key_add(struct mctp_sk_key *key, struct mctp_sock *msk)
+ 
+ 	if (!rc) {
+ 		refcount_inc(&key->refs);
+-		key->expiry = jiffies + mctp_key_lifetime;
++		key->expiry = jiffies + msk->key_lifetime;
+ 		timer_reduce(&msk->key_expiry, key->expiry);
+ 
+ 		hlist_add_head(&key->hlist, &net->mctp.keys);
+@@ -578,7 +577,7 @@ static void mctp_reserve_tag(struct net *net, struct mctp_sk_key *key,
+ 
+ 	lockdep_assert_held(&mns->keys_lock);
+ 
+-	key->expiry = jiffies + mctp_key_lifetime;
++	key->expiry = jiffies + msk->key_lifetime;
+ 	timer_reduce(&msk->key_expiry, key->expiry);
+ 
+ 	/* we hold the net->key_lock here, allowing updates to both
+-- 
+2.48.1.362.g079036d154-goog
+