add L2TPV2 offloading
This commit is contained in:
parent
0008754a82
commit
fa79e0116d
|
@ -77,6 +77,7 @@ endef
|
||||||
define KernelPackage/qca-nss-ecm-standard
|
define KernelPackage/qca-nss-ecm-standard
|
||||||
$(call KernelPackage/qca-nss-ecm/Default)
|
$(call KernelPackage/qca-nss-ecm/Default)
|
||||||
VARIANT:=standard
|
VARIANT:=standard
|
||||||
|
DEPENDS+=+PACKAGE_kmod-pppol2tp:kmod-pppol2tp
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define KernelPackage/qca-nss-ecm-standard/Description
|
define KernelPackage/qca-nss-ecm-standard/Description
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -84,6 +96,15 @@
|
||||||
|
/* Test if ppp xmit lock is locked */
|
||||||
|
extern bool ppp_is_xmit_locked(struct net_device *dev);
|
||||||
|
|
||||||
|
+/* Test if ppp xmit lock is locked */
|
||||||
|
+extern bool ppp_is_xmit_locked(struct net_device *dev);
|
||||||
|
+
|
||||||
|
+/* Call this get protocol version */
|
||||||
|
+extern int ppp_channel_get_proto_version(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Get the device index associated with a channel, or 0, if none */
|
||||||
|
+extern int ppp_dev_index(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
/* Hold PPP channels for the PPP device */
|
||||||
|
extern int __ppp_hold_channels(struct net_device *dev,
|
||||||
|
struct ppp_channel *channels[],
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
*************** void ppp_release_channels(struct ppp_cha
|
||||||
|
*** 3706,3711 ****
|
||||||
|
--- 3706,3727 ----
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ppp_release_channels);
|
||||||
|
|
||||||
|
+ /* Return the PPP net device index */
|
||||||
|
+ int ppp_dev_index(struct ppp_channel *chan)
|
||||||
|
+ {
|
||||||
|
+ struct channel *pch = chan->ppp;
|
||||||
|
+ int ifindex = 0;
|
||||||
|
+
|
||||||
|
+ if (pch) {
|
||||||
|
+ read_lock_bh(&pch->upl);
|
||||||
|
+ if (pch->ppp && pch->ppp->dev)
|
||||||
|
+ ifindex = pch->ppp->dev->ifindex;
|
||||||
|
+ read_unlock_bh(&pch->upl);
|
||||||
|
+ }
|
||||||
|
+ return ifindex;
|
||||||
|
+ }
|
||||||
|
+ EXPORT_SYMBOL(ppp_dev_index);
|
||||||
|
+
|
||||||
|
/* Module/initialization stuff */
|
||||||
|
|
||||||
|
module_init(ppp_init);
|
|
@ -0,0 +1,348 @@
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -45,6 +56,47 @@ struct ppp_channel {
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
+/* Call this to obtain the underlying protocol of the PPP channel,
|
||||||
|
+ * e.g. PX_PROTO_OE
|
||||||
|
+ */
|
||||||
|
+extern int ppp_channel_get_protocol(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Call this to hold a channel */
|
||||||
|
+extern bool ppp_channel_hold(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Call this to release a hold you have upon a channel */
|
||||||
|
+extern void ppp_channel_release(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Release hold on PPP channels */
|
||||||
|
+extern void ppp_release_channels(struct ppp_channel *channels[],
|
||||||
|
+ unsigned int chan_sz);
|
||||||
|
+
|
||||||
|
+/* Test if ppp xmit lock is locked */
|
||||||
|
+extern bool ppp_is_xmit_locked(struct net_device *dev);
|
||||||
|
+
|
||||||
|
+/* Call this get protocol version */
|
||||||
|
+extern int ppp_channel_get_proto_version(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Get the device index associated with a channel, or 0, if none */
|
||||||
|
+extern int ppp_dev_index(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+/* Hold PPP channels for the PPP device */
|
||||||
|
+extern int ppp_hold_channels(struct net_device *dev,
|
||||||
|
+ struct ppp_channel *channels[],
|
||||||
|
+ unsigned int chan_sz);
|
||||||
|
+
|
||||||
|
+/* Test if the ppp device is a multi-link ppp device */
|
||||||
|
+extern int ppp_is_multilink(struct net_device *dev);
|
||||||
|
+
|
||||||
|
+/* Update statistics of the PPP net_device by incrementing related
|
||||||
|
+ * statistics field value with corresponding parameter
|
||||||
|
+ */
|
||||||
|
+extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
|
||||||
|
+ unsigned long rx_bytes, unsigned long tx_packets,
|
||||||
|
+ unsigned long tx_bytes, unsigned long rx_errors,
|
||||||
|
+ unsigned long tx_errors, unsigned long rx_dropped,
|
||||||
|
+ unsigned long tx_dropped);
|
||||||
|
+
|
||||||
|
/* Called by the channel when it can send some more data. */
|
||||||
|
extern void ppp_output_wakeup(struct ppp_channel *);
|
||||||
|
|
||||||
|
@@ -83,5 +135,17 @@ extern char *ppp_dev_name(struct ppp_cha
|
||||||
|
* that ppp_unregister_channel returns.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+/* QCA NSS Clients Support - Start */
|
||||||
|
+/* PPP channel connection event types */
|
||||||
|
+#define PPP_CHANNEL_DISCONNECT 0
|
||||||
|
+#define PPP_CHANNEL_CONNECT 1
|
||||||
|
+
|
||||||
|
+/* Register the PPP channel connect notifier */
|
||||||
|
+extern void ppp_channel_connection_register_notify(struct notifier_block *nb);
|
||||||
|
+
|
||||||
|
+/* Unregister the PPP channel connect notifier */
|
||||||
|
+extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb);
|
||||||
|
+/* QCA NSS Clients Support - End */
|
||||||
|
+
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
#endif
|
||||||
|
--- a/include/linux/if_pppol2tp.h
|
||||||
|
+++ b/include/linux/if_pppol2tp.h
|
||||||
|
@@ -14,4 +14,30 @@
|
||||||
|
#include <linux/in6.h>
|
||||||
|
#include <uapi/linux/if_pppol2tp.h>
|
||||||
|
|
||||||
|
+/* QCA NSS ECM support - Start */
|
||||||
|
+/*
|
||||||
|
+ * Holds L2TP channel info
|
||||||
|
+ */
|
||||||
|
+struct pppol2tp_common_addr {
|
||||||
|
+ int tunnel_version; /* v2 or v3 */
|
||||||
|
+ __u32 local_tunnel_id, remote_tunnel_id; /* tunnel id */
|
||||||
|
+ __u32 local_session_id, remote_session_id; /* session id */
|
||||||
|
+ struct sockaddr_in local_addr, remote_addr; /* ip address and port */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * L2TP channel operations
|
||||||
|
+ */
|
||||||
|
+struct pppol2tp_channel_ops {
|
||||||
|
+ struct ppp_channel_ops ops; /* ppp channel ops */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * exported function which calls pppol2tp channel's get addressing
|
||||||
|
+ * function
|
||||||
|
+ */
|
||||||
|
+extern int pppol2tp_channel_addressing_get(struct ppp_channel *,
|
||||||
|
+ struct pppol2tp_common_addr *);
|
||||||
|
+/* QCA NSS ECM support - End */
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--- a/net/l2tp/l2tp_ppp.c
|
||||||
|
+++ b/net/l2tp/l2tp_ppp.c
|
||||||
|
@@ -380,6 +392,13 @@ static int pppol2tp_xmit(struct ppp_chan
|
||||||
|
skb->data[0] = PPP_ALLSTATIONS;
|
||||||
|
skb->data[1] = PPP_UI;
|
||||||
|
|
||||||
|
+ /* QCA NSS ECM support - start */
|
||||||
|
+ /* set incoming interface as the ppp interface */
|
||||||
|
+ if ((skb->protocol == htons(ETH_P_IP)) ||
|
||||||
|
+ (skb->protocol == htons(ETH_P_IPV6)))
|
||||||
|
+ skb->skb_iif = ppp_dev_index(chan);
|
||||||
|
+ /* QCA NSS ECM support - End */
|
||||||
|
+
|
||||||
|
local_bh_disable();
|
||||||
|
l2tp_xmit_skb(session, skb, session->hdr_len);
|
||||||
|
local_bh_enable();
|
||||||
|
@@ -1749,6 +1768,109 @@ static void __exit pppol2tp_exit(void)
|
||||||
|
unregister_pernet_device(&pppol2tp_net_ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* QCA NSS ECM support - Start */
|
||||||
|
+/* pppol2tp_hold_chan() */
|
||||||
|
+static void pppol2tp_hold_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_hold(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pppol2tp_release_chan() */
|
||||||
|
+static void pppol2tp_release_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_put(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pppol2tp_get_channel_protocol()
|
||||||
|
+ * Return the protocol type of the L2TP over PPP protocol
|
||||||
|
+ */
|
||||||
|
+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)
|
||||||
|
+ sk = (struct sock *)chan->private;
|
||||||
|
+ else
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ /* 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)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+ struct l2tp_session *session;
|
||||||
|
+ struct l2tp_tunnel *tunnel;
|
||||||
|
+ struct inet_sock *isk = NULL;
|
||||||
|
+ int err = -ENXIO;
|
||||||
|
+
|
||||||
|
+ /* Get session and tunnel contexts from the socket */
|
||||||
|
+ session = pppol2tp_sock_to_session(sk);
|
||||||
|
+ if (!session)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ tunnel = session->tunnel;
|
||||||
|
+ if (!tunnel) {
|
||||||
|
+ sock_put(sk);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+ isk = inet_sk(tunnel->sock);
|
||||||
|
+
|
||||||
|
+ addr->local_tunnel_id = tunnel->tunnel_id;
|
||||||
|
+ addr->remote_tunnel_id = tunnel->peer_tunnel_id;
|
||||||
|
+ addr->local_session_id = session->session_id;
|
||||||
|
+ addr->remote_session_id = session->peer_session_id;
|
||||||
|
+
|
||||||
|
+ addr->local_addr.sin_port = isk->inet_sport;
|
||||||
|
+ addr->remote_addr.sin_port = isk->inet_dport;
|
||||||
|
+ addr->local_addr.sin_addr.s_addr = isk->inet_saddr;
|
||||||
|
+ addr->remote_addr.sin_addr.s_addr = isk->inet_daddr;
|
||||||
|
+
|
||||||
|
+ sock_put(sk);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pppol2tp_channel_addressing_get() */
|
||||||
|
+int pppol2tp_channel_addressing_get(struct ppp_channel *chan,
|
||||||
|
+ struct pppol2tp_common_addr *addr)
|
||||||
|
+{
|
||||||
|
+ return pppol2tp_get_addressing(chan, addr);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pppol2tp_channel_addressing_get);
|
||||||
|
+/* QCA NSS ECM support - End */
|
||||||
|
+
|
||||||
|
module_init(pppol2tp_init);
|
||||||
|
module_exit(pppol2tp_exit);
|
||||||
|
|
||||||
|
*** a/drivers/net/ppp/ppp_generic.c 2022-04-06 17:25:52.144576100 +0900
|
||||||
|
--- b/drivers/net/ppp/ppp_generic.c 2022-04-06 17:32:55.164576100 +0900
|
||||||
|
*************** int ppp_is_multilink(struct net_device *
|
||||||
|
*** 3502,3507 ****
|
||||||
|
--- 3502,3533 ----
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ppp_is_multilink);
|
||||||
|
|
||||||
|
+ /* __ppp_is_multilink()
|
||||||
|
+ * Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0
|
||||||
|
+ * if the device is not PPP. Caller should acquire ppp_lock before calling
|
||||||
|
+ * this function
|
||||||
|
+ */
|
||||||
|
+ int __ppp_is_multilink(struct net_device *dev)
|
||||||
|
+ {
|
||||||
|
+ struct ppp *ppp;
|
||||||
|
+ unsigned int flags;
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (dev->type != ARPHRD_PPP)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ ppp = netdev_priv(dev);
|
||||||
|
+ flags = ppp->flags;
|
||||||
|
+
|
||||||
|
+ if (flags & SC_MULTILINK)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ EXPORT_SYMBOL(__ppp_is_multilink);
|
||||||
|
+
|
||||||
|
/* ppp_channel_get_protocol()
|
||||||
|
* Call this to obtain the underlying protocol of the PPP channel,
|
||||||
|
* e.g. PX_PROTO_OE
|
||||||
|
*************** int ppp_hold_channels(struct net_device
|
||||||
|
*** 3606,3611 ****
|
||||||
|
--- 3632,3690 ----
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ppp_hold_channels);
|
||||||
|
|
||||||
|
+ /* __ppp_hold_channels()
|
||||||
|
+ * Returns the PPP channels of the PPP device, storing each one into
|
||||||
|
+ * channels[].
|
||||||
|
+ *
|
||||||
|
+ * channels[] has chan_sz elements.
|
||||||
|
+ * This function returns the number of channels stored, up to chan_sz.
|
||||||
|
+ * It will return < 0 if the device is not PPP.
|
||||||
|
+ *
|
||||||
|
+ * You MUST release the channels using ppp_release_channels().
|
||||||
|
+ */
|
||||||
|
+ int __ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[],
|
||||||
|
+ unsigned int chan_sz)
|
||||||
|
+ {
|
||||||
|
+ struct ppp *ppp;
|
||||||
|
+ int c;
|
||||||
|
+ struct channel *pch;
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (dev->type != ARPHRD_PPP)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ ppp = netdev_priv(dev);
|
||||||
|
+
|
||||||
|
+ c = 0;
|
||||||
|
+ list_for_each_entry(pch, &ppp->channels, clist) {
|
||||||
|
+ struct ppp_channel *chan;
|
||||||
|
+
|
||||||
|
+ if (!pch->chan) {
|
||||||
|
+ /* Channel is going / gone away */
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (c == chan_sz) {
|
||||||
|
+ /* No space to record channel */
|
||||||
|
+ return c;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Hold the channel, if supported */
|
||||||
|
+ chan = pch->chan;
|
||||||
|
+ if (!chan->ops->hold)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ chan->ops->hold(chan);
|
||||||
|
+
|
||||||
|
+ /* Record the channel */
|
||||||
|
+ channels[c++] = chan;
|
||||||
|
+ }
|
||||||
|
+ return c;
|
||||||
|
+ }
|
||||||
|
+ EXPORT_SYMBOL(__ppp_hold_channels);
|
||||||
|
+
|
||||||
|
/* ppp_release_channels()
|
||||||
|
* Releases channels
|
||||||
|
*/
|
||||||
|
*** a/include/linux/ppp_channel.h 2022-04-06 17:35:39.524576100 +0900
|
||||||
|
--- b/include/linux/ppp_channel.h 2022-04-06 17:36:10.684576100 +0900
|
||||||
|
*************** extern void ppp_release_channels(struct
|
||||||
|
*** 110,121 ****
|
||||||
|
--- 110,126 ----
|
||||||
|
extern int ppp_hold_channels(struct net_device *dev,
|
||||||
|
struct ppp_channel *channels[],
|
||||||
|
unsigned int chan_sz);
|
||||||
|
+ extern int __ppp_hold_channels(struct net_device *dev,
|
||||||
|
+ struct ppp_channel *channels[],
|
||||||
|
+ unsigned int chan_sz);
|
||||||
|
+
|
||||||
|
|
||||||
|
/* Test if ppp xmit lock is locked */
|
||||||
|
extern bool ppp_is_xmit_locked(struct net_device *dev);
|
||||||
|
|
||||||
|
/* Test if the ppp device is a multi-link ppp device */
|
||||||
|
extern int ppp_is_multilink(struct net_device *dev);
|
||||||
|
+ extern int __ppp_is_multilink(struct net_device *dev);
|
||||||
|
|
||||||
|
/* Register the PPP channel connect notifier */
|
||||||
|
extern void ppp_channel_connection_register_notify(struct notifier_block *nb);
|
Loading…
Reference in New Issue