wlan-ap-Telecominfraproject/feeds/qca-wifi-7/ipq53xx/patches-6.1/0343-net-l2tp-ppp_channel_proto_version-API.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

252 lines
6.8 KiB
Diff

From 025746fb8827b0bfb4ff17ef730cec46f135efb3 Mon Sep 17 00:00:00 2001
From: pavir <pavir@codeaurora.org>
Date: Mon, 26 Dec 2016 14:41:20 +0530
Subject: [PATCH] net: l2tp: ppp_channel_proto_version API
New API added to retrieve channel version info
Change-Id: Ia4fd236c7cf6170a5034609e75de8c6e4ef79f7b
Signed-off-by: Shyam Sunder <ssunde@codeaurora.org>
Signed-off-by: pavir <pavir@codeaurora.org>
---
drivers/net/ppp/ppp_generic.c | 66 ++++++++++++++++++++++++++++++++++-
include/linux/netdevice.h | 1 -
include/linux/ppp_channel.h | 9 +++++
net/l2tp/l2tp_ppp.c | 40 ++++++++++++++++++++-
4 files changed, 113 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 61eff7b85e0d..6cfc22ad6ebf 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -48,6 +48,7 @@
#include <net/slhc_vj.h>
#include <linux/atomic.h>
#include <linux/refcount.h>
+#include <linux/if_pppox.h>
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
@@ -3485,6 +3486,8 @@ ppp_connect_channel(struct channel *pch, int unit)
struct ppp_net *pn;
int ret = -ENXIO;
int hdrlen;
+ int ppp_proto;
+ int version;
int notify = 0;
pn = ppp_pernet(pch->chan_net);
@@ -3518,10 +3521,37 @@ ppp_connect_channel(struct channel *pch, int unit)
++ppp->n_channels;
pch->ppp = ppp;
refcount_inc(&ppp->file.refcnt);
+
+ ppp_proto = ppp_channel_get_protocol(pch->chan);
+ switch (ppp_proto) {
+ case PX_PROTO_OL2TP:
+ version = ppp_channel_get_proto_version(pch->chan);
+ switch (version) {
+ case 2:
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2;
+ ret = 0;
+ break;
+ case 3:
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case PX_PROTO_PPTP:
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP;
+ ret = 0;
+ break;
+
+ default:
+ break;
+ }
+
notify = 1;
ppp_unlock(ppp);
- ret = 0;
outl:
write_unlock_bh(&pch->upl);
@@ -3768,6 +3798,18 @@ int ppp_channel_get_protocol(struct ppp_channel *chan)
}
EXPORT_SYMBOL(ppp_channel_get_protocol);
+/* ppp_channel_get_proto_version()
+ * Call this to get channel protocol version
+ */
+int ppp_channel_get_proto_version(struct ppp_channel *chan)
+{
+ if (!chan->ops->get_channel_protocol_ver)
+ return -1;
+
+ return chan->ops->get_channel_protocol_ver(chan);
+}
+EXPORT_SYMBOL(ppp_channel_get_proto_version);
+
/* ppp_channel_hold()
* Call this to hold a channel.
*
@@ -3921,6 +3963,28 @@ void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz)
}
EXPORT_SYMBOL(ppp_release_channels);
+/* Check if ppp xmit lock is on hold */
+bool ppp_is_xmit_locked(struct net_device *dev)
+{
+ struct ppp *ppp;
+
+ if (!dev)
+ return false;
+
+ if (dev->type != ARPHRD_PPP)
+ return false;
+
+ ppp = netdev_priv(dev);
+ if (!ppp)
+ return false;
+
+ if (spin_is_locked(&(ppp)->wlock))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(ppp_is_xmit_locked);
+
/* Module/initialization stuff */
module_init(ppp_init);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f4af16d44436..ed23cb82d12c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2183,7 +2183,6 @@ struct net_device {
unsigned char nested_level;
#endif
-
/* Protocol-specific pointers */
struct in_device __rcu *ip_ptr;
diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h
index 249bf40cd18d..0dabc9dbc64d 100644
--- a/include/linux/ppp_channel.h
+++ b/include/linux/ppp_channel.h
@@ -44,6 +44,8 @@ struct ppp_channel_ops {
* the channel subtype
*/
int (*get_channel_protocol)(struct ppp_channel *);
+ /* Get channel protocol version */
+ int (*get_channel_protocol_ver)(struct ppp_channel *);
/* Hold the channel from being destroyed */
void (*hold)(struct ppp_channel *);
/* Release hold on the channel */
@@ -67,6 +69,9 @@ struct ppp_channel {
*/
extern int ppp_channel_get_protocol(struct ppp_channel *);
+/* Call this get protocol version */
+extern int ppp_channel_get_proto_version(struct ppp_channel *);
+
/* Call this to hold a channel */
extern bool ppp_channel_hold(struct ppp_channel *);
@@ -83,6 +88,10 @@ extern int ppp_hold_channels(struct net_device *dev,
unsigned int chan_sz);
bool ppp_is_cp_enabled(struct net_device *dev);
+
+/* Test if ppp xmit lock is locked */
+extern bool ppp_is_xmit_locked(struct net_device *dev);
+
/* Hold PPP channels for the PPP device */
extern int __ppp_hold_channels(struct net_device *dev,
struct ppp_channel *channels[],
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 943f499ec15f..b02d5b7da741 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -92,6 +92,7 @@
#include <net/ip.h>
#include <net/udp.h>
#include <net/inet_common.h>
+#include <linux/if_pppox.h>
#include <asm/byteorder.h>
#include <linux/atomic.h>
@@ -124,11 +125,13 @@ struct pppol2tp_session {
static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
static int pppol2tp_get_channel_protocol(struct ppp_channel *);
+static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *);
static void pppol2tp_hold_chan(struct ppp_channel *);
static void pppol2tp_release_chan(struct ppp_channel *);
static const struct pppol2tp_channel_ops pppol2tp_chan_ops = {
.ops.start_xmit = pppol2tp_xmit,
.ops.get_channel_protocol = pppol2tp_get_channel_protocol,
+ .ops.get_channel_protocol_ver = pppol2tp_get_channel_protocol_ver,
.ops.hold = pppol2tp_hold_chan,
.ops.release = pppol2tp_release_chan,
};
@@ -358,6 +361,40 @@ static int pppol2tp_get_channel_protocol(struct ppp_channel *chan)
return PX_PROTO_OL2TP;
}
+/* pppol2tp_get_channel_protocol_ver()
+ * Return the protocol version of the L2TP over PPP protocol
+ */
+static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *chan)
+{
+ struct sock *sk;
+ struct l2tp_session *session;
+ struct l2tp_tunnel *tunnel;
+ int version = 0;
+
+ if (!(chan && chan->private)) {
+ return -1;
+ }
+
+ sk = (struct sock *)chan->private;
+
+ /* Get session and tunnel contexts from the socket */
+ session = pppol2tp_sock_to_session(sk);
+ if (!session) {
+ return -1;
+ }
+
+ tunnel = session->tunnel;
+ if (!tunnel) {
+ sock_put(sk);
+ return -1;
+ }
+
+ version = tunnel->version;
+
+ sock_put(sk);
+ return version;
+}
+
/* pppol2tp_get_addressing() */
static int pppol2tp_get_addressing(struct ppp_channel *chan,
struct pppol2tp_common_addr *addr)
@@ -443,7 +480,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
skb->data[0] = PPP_ALLSTATIONS;
skb->data[1] = PPP_UI;
/* set incoming interface as the ppp interface */
- if (skb->skb_iif)
+ if ((skb->protocol == htons(ETH_P_IP)) ||
+ (skb->protocol == htons(ETH_P_IPV6)))
skb->skb_iif = ppp_dev_index(chan);
local_bh_disable();
--
2.34.1