Files
openwrt-R7800-nss/target/linux/ipq806x/patches-6.6/990-0342-inet-pptp-Added-API-to-get-PPTP-session-info-for-NSS.patch
2025-04-14 18:03:11 +02:00

140 lines
3.9 KiB
Diff

From bd2254aed96e33fc84c24d54894fe606f474360d Mon Sep 17 00:00:00 2001
From: Murat Sezgin <msezgin@codeaurora.org>
Date: Fri, 26 Feb 2016 15:26:07 -0800
Subject: [PATCH 302/500] inet: pptp: Added API to get PPTP session info for
NSS acceleration
The API are needed by NSS modules to query PPTP session information
using the PPTP channel or session ID. The information is needed for
accelerating PPTP flows by NSS
Change-Id: I27408e9bee58f186a4ab99fa360bbef26b02c81b
Signed-off-by: Shyam Sunder <ssunde@codeaurora.org>
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
---
drivers/net/ppp/pptp.c | 75 ++++++++++++++++++++++++++++++++++++++++
include/linux/if_pppox.h | 8 +++++
2 files changed, 83 insertions(+)
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -91,6 +91,31 @@ static int lookup_chan_dst(u16 call_id,
return i < MAX_CALLID;
}
+/* Search a pptp session based on peer call id and peer ip address */
+static int lookup_session_dst(struct pptp_opt *opt, u16 call_id, __be32 d_addr)
+{
+ struct pppox_sock *sock;
+ int i = 1;
+
+ rcu_read_lock();
+ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) {
+ sock = rcu_dereference(callid_sock[i]);
+ if (!sock)
+ continue;
+
+ if (sock->proto.pptp.dst_addr.call_id == call_id &&
+ sock->proto.pptp.dst_addr.sin_addr.s_addr == d_addr) {
+ sock_hold(sk_pppox(sock));
+ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt));
+ sock_put(sk_pppox(sock));
+ rcu_read_unlock();
+ return 0;
+ }
+ }
+ rcu_read_unlock();
+ return -EINVAL;
+}
+
static int add_chan(struct pppox_sock *sock,
struct pptp_addr *sa)
{
@@ -258,7 +283,12 @@ static int pptp_xmit(struct ppp_channel
ip_select_ident(net, skb, NULL);
ip_send_check(iph);
+ /* set incoming interface as the ppp interface */
+ if (skb->skb_iif)
+ skb->skb_iif = ppp_dev_index(chan);
+
ip_local_out(net, skb->sk, skb);
+
return 1;
tx_error:
@@ -371,6 +401,7 @@ static int pptp_rcv(struct sk_buff *skb)
if (po) {
skb_dst_drop(skb);
nf_reset_ct(skb);
+ skb->skb_iif = ppp_dev_index(&po->chan);
return sk_receive_skb(sk_pppox(po), skb, 0);
}
drop:
@@ -603,6 +634,50 @@ static int pptp_ppp_ioctl(struct ppp_cha
return err;
}
+/* pptp_channel_addressing_get()
+ * Return PPTP channel specific addressing information.
+ */
+void pptp_channel_addressing_get(struct pptp_opt *opt, struct ppp_channel *chan)
+{
+ struct sock *sk;
+ struct pppox_sock *po;
+
+ if (!opt)
+ return;
+
+ sk = (struct sock *)chan->private;
+ if (!sk)
+ return;
+
+ sock_hold(sk);
+
+ /* This is very unlikely, but check the socket is connected state */
+ if (unlikely(sock_flag(sk, SOCK_DEAD) ||
+ !(sk->sk_state & PPPOX_CONNECTED))) {
+ sock_put(sk);
+ return;
+ }
+
+ po = pppox_sk(sk);
+ memcpy(opt, &po->proto.pptp, sizeof(struct pptp_opt));
+ sock_put(sk);
+}
+EXPORT_SYMBOL(pptp_channel_addressing_get);
+
+/* pptp_session_find()
+ * Search and return a PPTP session info based on peer callid and IP
+ * address. The function accepts the parameters in network byte order.
+ */
+int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id,
+ __be32 peer_ip_addr)
+{
+ if (!opt)
+ return -EINVAL;
+
+ return lookup_session_dst(opt, ntohs(peer_call_id), peer_ip_addr);
+}
+EXPORT_SYMBOL(pptp_session_find);
+
/* pptp_hold_chan() */
static void pptp_hold_chan(struct ppp_channel *chan)
{
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -105,4 +105,12 @@ struct pppoe_channel_ops {
extern int pppoe_channel_addressing_get(struct ppp_channel *chan,
struct pppoe_opt *addressing);
+/* Lookup PPTP session info and return PPTP session */
+extern int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id,
+ __be32 peer_ip_addr);
+
+/* Return PPTP session information given the channel */
+extern void pptp_channel_addressing_get(struct pptp_opt *opt,
+ struct ppp_channel *chan);
+
#endif /* !(__LINUX_IF_PPPOX_H) */