wlan-ap-Telecominfraproject/feeds/qca-wifi-7/ipq53xx/patches-6.1/0408-net-Add-API-to-update-L4-protocol-registrant.patch
John Crispin 68cf54d9f7 qca-wifi-7: update to ath12.5.5
Signed-off-by: John Crispin <john@phrozen.org>
2025-02-27 12:45:52 +01:00

110 lines
3.6 KiB
Diff

From fa733b77929073b5ec4520da648fd82689ea96cc Mon Sep 17 00:00:00 2001
From: "Hardik S. Panchal" <hpanchal@codeaurora.org>
Date: Tue, 8 May 2018 10:16:32 +0530
Subject: [PATCH] net: Add API to update L4 protocol registrant.
Change-Id: I0d01fe33a590bb3eec596de621f86537f60c7071
Signed-off-by: Hardik S. Panchal <hpanchal@codeaurora.org>
Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
---
include/net/protocol.h | 4 ++++
net/ipv4/protocol.c | 26 ++++++++++++++++++++++++++
net/ipv6/protocol.c | 26 ++++++++++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 6aef8cb11cc8c..d8ca81fb1537e 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -101,12 +101,16 @@ int inet_add_protocol(const struct net_protocol *prot, unsigned char num);
int inet_del_protocol(const struct net_protocol *prot, unsigned char num);
int inet_add_offload(const struct net_offload *prot, unsigned char num);
int inet_del_offload(const struct net_offload *prot, unsigned char num);
+int inet_update_protocol(const struct net_protocol *new_prot,
+ unsigned char num, const struct net_protocol **old_prot);
void inet_register_protosw(struct inet_protosw *p);
void inet_unregister_protosw(struct inet_protosw *p);
#if IS_ENABLED(CONFIG_IPV6)
int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
+int inet6_update_protocol(const struct inet6_protocol *new_prot,
+ unsigned char num, const struct inet6_protocol **old_prot);
int inet6_register_protosw(struct inet_protosw *p);
void inet6_unregister_protosw(struct inet_protosw *p);
#endif
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 6913979948d73..ebfbbd9735f08 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -68,3 +68,29 @@ int inet_del_offload(const struct net_offload *prot, unsigned char protocol)
return ret;
}
EXPORT_SYMBOL(inet_del_offload);
+
+int inet_update_protocol(const struct net_protocol *new_prot,
+ unsigned char protocol, const struct net_protocol **old_prot)
+{
+ int ret;
+
+ rcu_read_lock();
+ *old_prot = rcu_dereference(inet_protos[protocol]);
+ if (!*old_prot) {
+ rcu_read_unlock();
+ return -1;
+ }
+ rcu_read_unlock();
+
+ /*
+ * old_prot is not protected as cmpxchg is successful only if
+ * old_prot matches with the value in inet_protos[protocol]
+ */
+ ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol],
+ *old_prot, new_prot) == *old_prot) ? 0 : -1;
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(inet_update_protocol);
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index d4b1806bab1b4..327f7fc78dfa7 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -44,6 +44,32 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
return ret;
}
EXPORT_SYMBOL(inet6_del_protocol);
+
+int inet6_update_protocol(const struct inet6_protocol *new_prot,
+ unsigned char protocol, const struct inet6_protocol **old_prot)
+{
+ int ret;
+
+ rcu_read_lock();
+ *old_prot = rcu_dereference(inet6_protos[protocol]);
+ if (!*old_prot) {
+ rcu_read_unlock();
+ return -1;
+ }
+ rcu_read_unlock();
+
+ /*
+ * old_prot is not protected as cmpxchg is successful only if
+ * old_prot matches with the value in inet6_protos[protocol]
+ */
+ ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol],
+ *old_prot, new_prot) == *old_prot) ? 0 : -1;
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(inet6_update_protocol);
#endif
const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
--
2.34.1