Updated PPPoE,PPTP,L2TP and GRE patches.
Source: codelinaro.org
This commit is contained in:
@@ -90,7 +90,7 @@
|
|||||||
{
|
{
|
||||||
--- a/include/linux/netdevice.h
|
--- a/include/linux/netdevice.h
|
||||||
+++ b/include/linux/netdevice.h
|
+++ b/include/linux/netdevice.h
|
||||||
@@ -4701,6 +4701,15 @@ void dev_uc_flush(struct net_device *dev
|
@@ -4681,6 +4681,15 @@ void dev_uc_flush(struct net_device *dev
|
||||||
void dev_uc_init(struct net_device *dev);
|
void dev_uc_init(struct net_device *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -105,7 +105,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
static inline __be16 vlan_proto(const struct sk_buff *skb)
|
static inline __be16 vlan_proto(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (skb_vlan_tag_present(skb))
|
if (skb_vlan_tag_present(skb))
|
||||||
@@ -1238,6 +1247,12 @@ static struct ctl_table brnf_table[] = {
|
@@ -1240,6 +1249,12 @@ static struct ctl_table brnf_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = brnf_sysctl_call_tables,
|
.proc_handler = brnf_sysctl_call_tables,
|
||||||
},
|
},
|
||||||
@@ -118,7 +118,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1246,6 +1261,7 @@ static inline void br_netfilter_sysctl_d
|
@@ -1248,6 +1263,7 @@ static inline void br_netfilter_sysctl_d
|
||||||
brnf->call_iptables = 1;
|
brnf->call_iptables = 1;
|
||||||
brnf->call_ip6tables = 1;
|
brnf->call_ip6tables = 1;
|
||||||
brnf->call_arptables = 1;
|
brnf->call_arptables = 1;
|
||||||
@@ -126,7 +126,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
brnf->filter_vlan_tagged = 0;
|
brnf->filter_vlan_tagged = 0;
|
||||||
brnf->filter_pppoe_tagged = 0;
|
brnf->filter_pppoe_tagged = 0;
|
||||||
brnf->pass_vlan_indev = 0;
|
brnf->pass_vlan_indev = 0;
|
||||||
@@ -1269,6 +1285,7 @@ static int br_netfilter_sysctl_init_net(
|
@@ -1271,6 +1287,7 @@ static int br_netfilter_sysctl_init_net(
|
||||||
table[3].data = &brnet->filter_vlan_tagged;
|
table[3].data = &brnet->filter_vlan_tagged;
|
||||||
table[4].data = &brnet->filter_pppoe_tagged;
|
table[4].data = &brnet->filter_pppoe_tagged;
|
||||||
table[5].data = &brnet->pass_vlan_indev;
|
table[5].data = &brnet->pass_vlan_indev;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Signed-off-by: Ken Zhu <quic_guigenz@quicinc.com>
|
|||||||
|
|
||||||
--- a/include/linux/netdevice.h
|
--- a/include/linux/netdevice.h
|
||||||
+++ b/include/linux/netdevice.h
|
+++ b/include/linux/netdevice.h
|
||||||
@@ -3183,6 +3183,8 @@ static inline int dev_direct_xmit(struct
|
@@ -3163,6 +3163,8 @@ static inline int dev_direct_xmit(struct
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
const struct dst_entry *dst = skb_dst(skb);
|
const struct dst_entry *dst = skb_dst(skb);
|
||||||
--- a/include/net/route.h
|
--- a/include/net/route.h
|
||||||
+++ b/include/net/route.h
|
+++ b/include/net/route.h
|
||||||
@@ -237,6 +237,9 @@ struct rtable *rt_dst_alloc(struct net_d
|
@@ -238,6 +238,9 @@ struct rtable *rt_dst_alloc(struct net_d
|
||||||
unsigned int flags, u16 type, bool noxfrm);
|
unsigned int flags, u16 type, bool noxfrm);
|
||||||
struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
|
struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
|
|
||||||
--- a/include/linux/netdevice.h
|
--- a/include/linux/netdevice.h
|
||||||
+++ b/include/linux/netdevice.h
|
+++ b/include/linux/netdevice.h
|
||||||
@@ -2959,6 +2959,8 @@ enum netdev_cmd {
|
@@ -2939,6 +2939,8 @@ enum netdev_cmd {
|
||||||
NETDEV_OFFLOAD_XSTATS_REPORT_USED,
|
NETDEV_OFFLOAD_XSTATS_REPORT_USED,
|
||||||
NETDEV_OFFLOAD_XSTATS_REPORT_DELTA,
|
NETDEV_OFFLOAD_XSTATS_REPORT_DELTA,
|
||||||
NETDEV_XDP_FEAT_CHANGE,
|
NETDEV_XDP_FEAT_CHANGE,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline __be16 vlan_proto(const struct sk_buff *skb)
|
static inline __be16 vlan_proto(const struct sk_buff *skb)
|
||||||
@@ -1253,6 +1254,12 @@ static struct ctl_table brnf_table[] = {
|
@@ -1255,6 +1256,12 @@ static struct ctl_table brnf_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = brnf_sysctl_call_tables,
|
.proc_handler = brnf_sysctl_call_tables,
|
||||||
},
|
},
|
||||||
@@ -48,7 +48,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1262,6 +1269,7 @@ static inline void br_netfilter_sysctl_d
|
@@ -1264,6 +1271,7 @@ static inline void br_netfilter_sysctl_d
|
||||||
brnf->call_ip6tables = 1;
|
brnf->call_ip6tables = 1;
|
||||||
brnf->call_arptables = 1;
|
brnf->call_arptables = 1;
|
||||||
brnf->call_ebtables = 1;
|
brnf->call_ebtables = 1;
|
||||||
@@ -56,7 +56,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
brnf->filter_vlan_tagged = 0;
|
brnf->filter_vlan_tagged = 0;
|
||||||
brnf->filter_pppoe_tagged = 0;
|
brnf->filter_pppoe_tagged = 0;
|
||||||
brnf->pass_vlan_indev = 0;
|
brnf->pass_vlan_indev = 0;
|
||||||
@@ -1286,6 +1294,7 @@ static int br_netfilter_sysctl_init_net(
|
@@ -1288,6 +1296,7 @@ static int br_netfilter_sysctl_init_net(
|
||||||
table[4].data = &brnet->filter_pppoe_tagged;
|
table[4].data = &brnet->filter_pppoe_tagged;
|
||||||
table[5].data = &brnet->pass_vlan_indev;
|
table[5].data = &brnet->pass_vlan_indev;
|
||||||
table[6].data = &brnet->call_ebtables;
|
table[6].data = &brnet->call_ebtables;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
|||||||
|
|
||||||
--- a/net/bridge/br_netfilter_hooks.c
|
--- a/net/bridge/br_netfilter_hooks.c
|
||||||
+++ b/net/bridge/br_netfilter_hooks.c
|
+++ b/net/bridge/br_netfilter_hooks.c
|
||||||
@@ -1268,8 +1268,8 @@ static inline void br_netfilter_sysctl_d
|
@@ -1270,8 +1270,8 @@ static inline void br_netfilter_sysctl_d
|
||||||
brnf->call_iptables = 1;
|
brnf->call_iptables = 1;
|
||||||
brnf->call_ip6tables = 1;
|
brnf->call_ip6tables = 1;
|
||||||
brnf->call_arptables = 1;
|
brnf->call_arptables = 1;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
|||||||
dev->needs_free_netdev = true;
|
dev->needs_free_netdev = true;
|
||||||
--- a/include/linux/netdevice.h
|
--- a/include/linux/netdevice.h
|
||||||
+++ b/include/linux/netdevice.h
|
+++ b/include/linux/netdevice.h
|
||||||
@@ -1781,6 +1781,32 @@ enum netdev_priv_flags {
|
@@ -1761,6 +1761,32 @@ enum netdev_priv_flags {
|
||||||
IFF_NO_IP_ALIGN = BIT_ULL(34),
|
IFF_NO_IP_ALIGN = BIT_ULL(34),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
|||||||
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
|
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
|
||||||
#define IFF_EBRIDGE IFF_EBRIDGE
|
#define IFF_EBRIDGE IFF_EBRIDGE
|
||||||
#define IFF_BONDING IFF_BONDING
|
#define IFF_BONDING IFF_BONDING
|
||||||
@@ -1901,6 +1927,8 @@ enum netdev_stat_type {
|
@@ -1881,6 +1907,8 @@ enum netdev_stat_type {
|
||||||
* @xdp_features: XDP capability supported by the device
|
* @xdp_features: XDP capability supported by the device
|
||||||
* @priv_flags: Like 'flags' but invisible to userspace,
|
* @priv_flags: Like 'flags' but invisible to userspace,
|
||||||
* see if.h for the definitions
|
* see if.h for the definitions
|
||||||
@@ -96,7 +96,7 @@ Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
|||||||
* @gflags: Global flags ( kept as legacy )
|
* @gflags: Global flags ( kept as legacy )
|
||||||
* @padded: How much padding added by alloc_netdev()
|
* @padded: How much padding added by alloc_netdev()
|
||||||
* @operstate: RFC2863 operstate
|
* @operstate: RFC2863 operstate
|
||||||
@@ -2146,6 +2174,7 @@ struct net_device {
|
@@ -2126,6 +2154,7 @@ struct net_device {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
xdp_features_t xdp_features;
|
xdp_features_t xdp_features;
|
||||||
unsigned long long priv_flags;
|
unsigned long long priv_flags;
|
||||||
@@ -104,7 +104,7 @@ Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
|||||||
const struct net_device_ops *netdev_ops;
|
const struct net_device_ops *netdev_ops;
|
||||||
const struct xdp_metadata_ops *xdp_metadata_ops;
|
const struct xdp_metadata_ops *xdp_metadata_ops;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
@@ -4306,7 +4335,6 @@ static inline bool netif_dormant(const s
|
@@ -4286,7 +4315,6 @@ static inline bool netif_dormant(const s
|
||||||
return test_bit(__LINK_STATE_DORMANT, &dev->state);
|
return test_bit(__LINK_STATE_DORMANT, &dev->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
|||||||
/**
|
/**
|
||||||
* netif_testing_on - mark device as under test.
|
* netif_testing_on - mark device as under test.
|
||||||
* @dev: network device
|
* @dev: network device
|
||||||
@@ -5258,6 +5286,11 @@ static inline bool netif_is_failover_sla
|
@@ -5238,6 +5266,11 @@ static inline bool netif_is_failover_sla
|
||||||
return dev->priv_flags & IFF_FAILOVER_SLAVE;
|
return dev->priv_flags & IFF_FAILOVER_SLAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
From 7d3846d95a5b5fa800031411d53078f2d775d2e6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
Date: Fri, 16 Jan 2015 16:54:08 -0800
|
||||||
|
Subject: [PATCH 301/500] ppp: Add PPP channel specific methods for PPTP and
|
||||||
|
L2TP types.
|
||||||
|
|
||||||
|
These methods are required for handling these types of PPP protocols
|
||||||
|
in the acceleration subsystem.
|
||||||
|
|
||||||
|
Change-Id: I7967573ee440a96af3f842300e2f021465a0a62c
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/pptp.c | 27 +++++++++++++++++++++++++++
|
||||||
|
net/l2tp/l2tp_ppp.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 57 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/pptp.c
|
||||||
|
+++ b/drivers/net/ppp/pptp.c
|
||||||
|
@@ -603,9 +603,36 @@ static int pptp_ppp_ioctl(struct ppp_cha
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* pptp_hold_chan() */
|
||||||
|
+static void pptp_hold_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_hold(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pptp_release_chan() */
|
||||||
|
+static void pptp_release_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_put(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pptp_get_channel_protocol()
|
||||||
|
+ * Return the protocol type of the PPTP over PPP protocol
|
||||||
|
+ */
|
||||||
|
+static int pptp_get_channel_protocol(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ return PX_PROTO_PPTP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct ppp_channel_ops pptp_chan_ops = {
|
||||||
|
.start_xmit = pptp_xmit,
|
||||||
|
.ioctl = pptp_ppp_ioctl,
|
||||||
|
+ .get_channel_protocol = pptp_get_channel_protocol,
|
||||||
|
+ .hold = pptp_hold_chan,
|
||||||
|
+ .release = pptp_release_chan,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct proto pptp_sk_proto __read_mostly = {
|
||||||
|
--- a/net/l2tp/l2tp_ppp.c
|
||||||
|
+++ b/net/l2tp/l2tp_ppp.c
|
||||||
|
@@ -123,9 +123,15 @@ 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 void pppol2tp_hold_chan(struct ppp_channel *);
|
||||||
|
+static void pppol2tp_release_chan(struct ppp_channel *);
|
||||||
|
|
||||||
|
static const struct ppp_channel_ops pppol2tp_chan_ops = {
|
||||||
|
.start_xmit = pppol2tp_xmit,
|
||||||
|
+ .get_channel_protocol = pppol2tp_get_channel_protocol,
|
||||||
|
+ .hold = pppol2tp_hold_chan,
|
||||||
|
+ .release = pppol2tp_release_chan,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct proto_ops pppol2tp_ops;
|
||||||
|
@@ -328,6 +334,30 @@ error:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* 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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Transmit function called by generic PPP driver. Sends PPP frame
|
||||||
|
* over PPPoL2TP socket.
|
||||||
|
*
|
||||||
@@ -0,0 +1,608 @@
|
|||||||
|
From 16de3e75ec92f88a454725c2e33e22b501c1a873 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Murat Sezgin <quic_msezgin@quicinc.com>
|
||||||
|
Date: Wed, 10 May 2023 13:16:09 -0700
|
||||||
|
Subject: [PATCH 183/500] ppp: PPPoE acceleration support.
|
||||||
|
|
||||||
|
pppoe: Add return value to pppoe addressing get function
|
||||||
|
|
||||||
|
If the addressing doesn't have a netdevice, this should be
|
||||||
|
handled as a failure, so that the caller considers that
|
||||||
|
the get function failed.
|
||||||
|
|
||||||
|
Change-Id: Ia9a6b0e0f036a3434519d9f2194763486ca04583
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
|
||||||
|
Added some new APIs to the PPP/PPPoE kernel modules
|
||||||
|
for using from the hardware acceleration connection managers.
|
||||||
|
|
||||||
|
Change-Id: I2c16c6d6ccba8ffa14aec077c8dad1681535ae0b
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
|
||||||
|
net: ppp: rx/tx error and dropped pkt stats support
|
||||||
|
|
||||||
|
ppp_update_stats functions accepts rx/tx errors and dropped
|
||||||
|
pkt stats args.
|
||||||
|
|
||||||
|
Change-Id: Iba2f6ea2114d8a4678254332fec0ef7bc35bed2c
|
||||||
|
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
|
||||||
|
ppp: Update the last_recv and last_xmit times.
|
||||||
|
|
||||||
|
These need to be updated for accelerated connections, so that
|
||||||
|
on demand mode will recognize the active traffic.
|
||||||
|
|
||||||
|
Change-Id: I3c0ee4e8f4c3bc4c7ce221e6109bfd82046d11b4
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
|
||||||
|
ppp: Add channel connect/disconnect notifier.
|
||||||
|
|
||||||
|
When a channel is connected or disconnected to a PPP
|
||||||
|
unit, a notification will be sent to the kernel subsystems
|
||||||
|
which are registered to this notifier. Notifier sends
|
||||||
|
the event type (connect or disconnect) along with the
|
||||||
|
PPP netdevice pointer.
|
||||||
|
|
||||||
|
Change-Id: I0d592084744c86e1c114ac66da68b214ddff5b5a
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
Signed-off-by: Murat Sezgin <quic_msezgin@quicinc.com>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 220 ++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/net/ppp/pppoe.c | 83 ++++++++++++-
|
||||||
|
include/linux/if_pppox.h | 16 ++-
|
||||||
|
include/linux/ppp_channel.h | 52 ++++++++
|
||||||
|
net/l2tp/l2tp_core.c | 24 ++++
|
||||||
|
net/l2tp/l2tp_core.h | 2 +
|
||||||
|
6 files changed, 391 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
@@ -255,6 +255,24 @@ struct ppp_net {
|
||||||
|
#define seq_before(a, b) ((s32)((a) - (b)) < 0)
|
||||||
|
#define seq_after(a, b) ((s32)((a) - (b)) > 0)
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Registration/Unregistration methods
|
||||||
|
+ * for PPP channel connect and disconnect event notifications.
|
||||||
|
+ */
|
||||||
|
+RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list);
|
||||||
|
+
|
||||||
|
+void ppp_channel_connection_register_notify(struct notifier_block *nb)
|
||||||
|
+{
|
||||||
|
+ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify);
|
||||||
|
+
|
||||||
|
+void ppp_channel_connection_unregister_notify(struct notifier_block *nb)
|
||||||
|
+{
|
||||||
|
+ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify);
|
||||||
|
+
|
||||||
|
/* Prototypes. */
|
||||||
|
static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
|
||||||
|
struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
|
@@ -3468,6 +3486,7 @@ ppp_connect_channel(struct channel *pch,
|
||||||
|
struct ppp_net *pn;
|
||||||
|
int ret = -ENXIO;
|
||||||
|
int hdrlen;
|
||||||
|
+ int notify = 0;
|
||||||
|
|
||||||
|
pn = ppp_pernet(pch->chan_net);
|
||||||
|
|
||||||
|
@@ -3500,6 +3519,8 @@ ppp_connect_channel(struct channel *pch,
|
||||||
|
++ppp->n_channels;
|
||||||
|
pch->ppp = ppp;
|
||||||
|
refcount_inc(&ppp->file.refcnt);
|
||||||
|
+ notify = 1;
|
||||||
|
+
|
||||||
|
ppp_unlock(ppp);
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
@@ -3507,6 +3528,14 @@ ppp_connect_channel(struct channel *pch,
|
||||||
|
write_unlock_bh(&pch->upl);
|
||||||
|
out:
|
||||||
|
mutex_unlock(&pn->all_ppp_mutex);
|
||||||
|
+
|
||||||
|
+ if (notify && ppp && ppp->dev) {
|
||||||
|
+ dev_hold(ppp->dev);
|
||||||
|
+ raw_notifier_call_chain(&ppp_channel_connection_notifier_list,
|
||||||
|
+ PPP_CHANNEL_CONNECT, ppp->dev);
|
||||||
|
+ dev_put(ppp->dev);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3524,6 +3553,13 @@ ppp_disconnect_channel(struct channel *p
|
||||||
|
pch->ppp = NULL;
|
||||||
|
write_unlock_bh(&pch->upl);
|
||||||
|
if (ppp) {
|
||||||
|
+ if (ppp->dev) {
|
||||||
|
+ dev_hold(ppp->dev);
|
||||||
|
+ raw_notifier_call_chain(&ppp_channel_connection_notifier_list,
|
||||||
|
+ PPP_CHANNEL_DISCONNECT, ppp->dev);
|
||||||
|
+ dev_put(ppp->dev);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* remove it from the ppp unit's list */
|
||||||
|
ppp_lock(ppp);
|
||||||
|
list_del(&pch->clist);
|
||||||
|
@@ -3603,6 +3639,188 @@ static void *unit_find(struct idr *p, in
|
||||||
|
return idr_find(p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Updates the PPP interface statistics. */
|
||||||
|
+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)
|
||||||
|
+{
|
||||||
|
+ struct ppp *ppp;
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (dev->type != ARPHRD_PPP)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ppp = netdev_priv(dev);
|
||||||
|
+
|
||||||
|
+ ppp_xmit_lock(ppp);
|
||||||
|
+ ppp->stats64.tx_packets += tx_packets;
|
||||||
|
+ ppp->stats64.tx_bytes += tx_bytes;
|
||||||
|
+ ppp->dev->stats.tx_errors += tx_errors;
|
||||||
|
+ ppp->dev->stats.tx_dropped += tx_dropped;
|
||||||
|
+ if (tx_packets)
|
||||||
|
+ ppp->last_xmit = jiffies;
|
||||||
|
+ ppp_xmit_unlock(ppp);
|
||||||
|
+
|
||||||
|
+ ppp_recv_lock(ppp);
|
||||||
|
+ ppp->stats64.rx_packets += rx_packets;
|
||||||
|
+ ppp->stats64.rx_bytes += rx_bytes;
|
||||||
|
+ ppp->dev->stats.rx_errors += rx_errors;
|
||||||
|
+ ppp->dev->stats.rx_dropped += rx_dropped;
|
||||||
|
+ if (rx_packets)
|
||||||
|
+ ppp->last_recv = jiffies;
|
||||||
|
+ ppp_recv_unlock(ppp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if
|
||||||
|
+ * the device is not PPP.
|
||||||
|
+ */
|
||||||
|
+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);
|
||||||
|
+ ppp_lock(ppp);
|
||||||
|
+ flags = ppp->flags;
|
||||||
|
+ ppp_unlock(ppp);
|
||||||
|
+
|
||||||
|
+ 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
|
||||||
|
+ *
|
||||||
|
+ * NOTE: Some channels do not use PX sockets so the protocol value may be very
|
||||||
|
+ * different for them.
|
||||||
|
+ * NOTE: -1 indicates failure.
|
||||||
|
+ * NOTE: Once you know the channel protocol you may then either cast 'chan' to
|
||||||
|
+ * its sub-class or use the channel protocol specific API's as provided by that
|
||||||
|
+ * channel sub type.
|
||||||
|
+ */
|
||||||
|
+int ppp_channel_get_protocol(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ if (!chan->ops->get_channel_protocol)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ return chan->ops->get_channel_protocol(chan);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_channel_get_protocol);
|
||||||
|
+
|
||||||
|
+/* ppp_channel_hold()
|
||||||
|
+ * Call this to hold a channel.
|
||||||
|
+ *
|
||||||
|
+ * Returns true on success or false if the hold could not happen.
|
||||||
|
+ *
|
||||||
|
+ * NOTE: chan must be protected against destruction during this call -
|
||||||
|
+ * either by correct locking etc. or because you already have an implicit
|
||||||
|
+ * or explicit hold to the channel already and this is an additional hold.
|
||||||
|
+ */
|
||||||
|
+bool ppp_channel_hold(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ if (!chan->ops->hold)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ chan->ops->hold(chan);
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_channel_hold);
|
||||||
|
+
|
||||||
|
+/* ppp_channel_release()
|
||||||
|
+ * Call this to release a hold you have upon a channel
|
||||||
|
+ */
|
||||||
|
+void ppp_channel_release(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ chan->ops->release(chan);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_channel_release);
|
||||||
|
+
|
||||||
|
+/* 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;
|
||||||
|
+ ppp_lock(ppp);
|
||||||
|
+ 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 */
|
||||||
|
+ ppp_unlock(ppp);
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+ ppp_unlock(ppp);
|
||||||
|
+ return c;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_hold_channels);
|
||||||
|
+
|
||||||
|
+/* ppp_release_channels()
|
||||||
|
+ * Releases channels
|
||||||
|
+ */
|
||||||
|
+void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz)
|
||||||
|
+{
|
||||||
|
+ unsigned int c;
|
||||||
|
+
|
||||||
|
+ for (c = 0; c < chan_sz; ++c) {
|
||||||
|
+ struct ppp_channel *chan;
|
||||||
|
+
|
||||||
|
+ chan = channels[c];
|
||||||
|
+ chan->ops->release(chan);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_release_channels);
|
||||||
|
+
|
||||||
|
/* Module/initialization stuff */
|
||||||
|
|
||||||
|
module_init(ppp_init);
|
||||||
|
@@ -3619,6 +3837,8 @@ EXPORT_SYMBOL(ppp_input_error);
|
||||||
|
EXPORT_SYMBOL(ppp_output_wakeup);
|
||||||
|
EXPORT_SYMBOL(ppp_register_compressor);
|
||||||
|
EXPORT_SYMBOL(ppp_unregister_compressor);
|
||||||
|
+EXPORT_SYMBOL(ppp_update_stats);
|
||||||
|
+
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0);
|
||||||
|
MODULE_ALIAS_RTNL_LINK("ppp");
|
||||||
|
--- a/drivers/net/ppp/pppoe.c
|
||||||
|
+++ b/drivers/net/ppp/pppoe.c
|
||||||
|
@@ -62,6 +62,7 @@
|
||||||
|
#include <linux/inetdevice.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
+#include <linux/if_arp.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/if_pppox.h>
|
||||||
|
@@ -87,7 +88,7 @@
|
||||||
|
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
|
||||||
|
|
||||||
|
static const struct proto_ops pppoe_ops;
|
||||||
|
-static const struct ppp_channel_ops pppoe_chan_ops;
|
||||||
|
+static const struct pppoe_channel_ops pppoe_chan_ops;
|
||||||
|
|
||||||
|
/* per-net private data for this module */
|
||||||
|
static unsigned int pppoe_net_id __read_mostly;
|
||||||
|
@@ -645,6 +646,7 @@ static int pppoe_connect(struct socket *
|
||||||
|
if (stage_session(po->pppoe_pa.sid)) {
|
||||||
|
pppox_unbind_sock(sk);
|
||||||
|
pn = pppoe_pernet(sock_net(sk));
|
||||||
|
+
|
||||||
|
delete_item(pn, po->pppoe_pa.sid,
|
||||||
|
po->pppoe_pa.remote, po->pppoe_ifindex);
|
||||||
|
if (po->pppoe_dev) {
|
||||||
|
@@ -692,7 +694,7 @@ static int pppoe_connect(struct socket *
|
||||||
|
|
||||||
|
po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
|
||||||
|
po->chan.private = sk;
|
||||||
|
- po->chan.ops = &pppoe_chan_ops;
|
||||||
|
+ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops;
|
||||||
|
|
||||||
|
error = ppp_register_net_channel(dev_net(dev), &po->chan);
|
||||||
|
if (error) {
|
||||||
|
@@ -995,9 +997,80 @@ static int pppoe_fill_forward_path(struc
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const struct ppp_channel_ops pppoe_chan_ops = {
|
||||||
|
- .start_xmit = pppoe_xmit,
|
||||||
|
- .fill_forward_path = pppoe_fill_forward_path,
|
||||||
|
+/************************************************************************
|
||||||
|
+ *
|
||||||
|
+ * function called by generic PPP driver to hold channel
|
||||||
|
+ *
|
||||||
|
+ ***********************************************************************/
|
||||||
|
+static void pppoe_hold_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_hold(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/************************************************************************
|
||||||
|
+ *
|
||||||
|
+ * function called by generic PPP driver to release channel
|
||||||
|
+ *
|
||||||
|
+ ***********************************************************************/
|
||||||
|
+static void pppoe_release_chan(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+
|
||||||
|
+ sock_put(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/************************************************************************
|
||||||
|
+ *
|
||||||
|
+ * function called to get the channel protocol type
|
||||||
|
+ *
|
||||||
|
+ ***********************************************************************/
|
||||||
|
+static int pppoe_get_channel_protocol(struct ppp_channel *chan)
|
||||||
|
+{
|
||||||
|
+ return PX_PROTO_OE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/************************************************************************
|
||||||
|
+ *
|
||||||
|
+ * function called to get the PPPoE channel addressing
|
||||||
|
+ * NOTE: This function returns a HOLD to the netdevice
|
||||||
|
+ *
|
||||||
|
+ ***********************************************************************/
|
||||||
|
+static int pppoe_get_addressing(struct ppp_channel *chan,
|
||||||
|
+ struct pppoe_opt *addressing)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = (struct sock *)chan->private;
|
||||||
|
+ struct pppox_sock *po = pppox_sk(sk);
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ *addressing = po->proto.pppoe;
|
||||||
|
+ if (!addressing->dev)
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ dev_hold(addressing->dev);
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pppoe_channel_addressing_get()
|
||||||
|
+ * Return PPPoE channel specific addressing information.
|
||||||
|
+ */
|
||||||
|
+int pppoe_channel_addressing_get(struct ppp_channel *chan,
|
||||||
|
+ struct pppoe_opt *addressing)
|
||||||
|
+{
|
||||||
|
+ return pppoe_get_addressing(chan, addressing);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pppoe_channel_addressing_get);
|
||||||
|
+
|
||||||
|
+static const struct pppoe_channel_ops pppoe_chan_ops = {
|
||||||
|
+ /* PPPoE specific channel ops */
|
||||||
|
+ .get_addressing = pppoe_get_addressing,
|
||||||
|
+ /* General ppp channel ops */
|
||||||
|
+ .ops.start_xmit = pppoe_xmit,
|
||||||
|
+ .ops.fill_forward_path = pppoe_fill_forward_path,
|
||||||
|
+ .ops.get_channel_protocol = pppoe_get_channel_protocol,
|
||||||
|
+ .ops.hold = pppoe_hold_chan,
|
||||||
|
+ .ops.release = pppoe_release_chan,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
|
||||||
|
--- a/include/linux/if_pppox.h
|
||||||
|
+++ b/include/linux/if_pppox.h
|
||||||
|
@@ -1,11 +1,12 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
/***************************************************************************
|
||||||
|
* Linux PPP over X - Generic PPP transport layer sockets
|
||||||
|
- * Linux PPP over Ethernet (PPPoE) Socket Implementation (RFC 2516)
|
||||||
|
+ * Linux PPP over Ethernet (PPPoE) Socket Implementation (RFC 2516)
|
||||||
|
*
|
||||||
|
* This file supplies definitions required by the PPP over Ethernet driver
|
||||||
|
* (pppox.c). All version information wrt this file is located in pppox.c
|
||||||
|
*/
|
||||||
|
+
|
||||||
|
#ifndef __LINUX_IF_PPPOX_H
|
||||||
|
#define __LINUX_IF_PPPOX_H
|
||||||
|
|
||||||
|
@@ -91,4 +92,17 @@ enum {
|
||||||
|
PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/
|
||||||
|
};
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * PPPoE Channel specific operations
|
||||||
|
+ */
|
||||||
|
+struct pppoe_channel_ops {
|
||||||
|
+ /* Must be first - general to all PPP channels */
|
||||||
|
+ struct ppp_channel_ops ops;
|
||||||
|
+ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *);
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Return PPPoE channel specific addressing information */
|
||||||
|
+extern int pppoe_channel_addressing_get(struct ppp_channel *chan,
|
||||||
|
+ struct pppoe_opt *addressing);
|
||||||
|
+
|
||||||
|
#endif /* !(__LINUX_IF_PPPOX_H) */
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -19,6 +19,11 @@
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
#include <net/net_namespace.h>
|
||||||
|
+#include <linux/notifier.h>
|
||||||
|
+
|
||||||
|
+/* PPP channel connection event types */
|
||||||
|
+#define PPP_CHANNEL_DISCONNECT 0
|
||||||
|
+#define PPP_CHANNEL_CONNECT 1
|
||||||
|
|
||||||
|
struct net_device_path;
|
||||||
|
struct net_device_path_ctx;
|
||||||
|
@@ -33,6 +38,15 @@ struct ppp_channel_ops {
|
||||||
|
int (*fill_forward_path)(struct net_device_path_ctx *,
|
||||||
|
struct net_device_path *,
|
||||||
|
const struct ppp_channel *);
|
||||||
|
+
|
||||||
|
+ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to
|
||||||
|
+ * the channel subtype
|
||||||
|
+ */
|
||||||
|
+ int (*get_channel_protocol)(struct ppp_channel *);
|
||||||
|
+ /* Hold the channel from being destroyed */
|
||||||
|
+ void (*hold)(struct ppp_channel *);
|
||||||
|
+ /* Release hold on the channel */
|
||||||
|
+ void (*release)(struct ppp_channel *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ppp_channel {
|
||||||
|
@@ -47,6 +61,38 @@ 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);
|
||||||
|
+
|
||||||
|
+/* 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 *);
|
||||||
|
|
||||||
|
@@ -76,6 +122,12 @@ extern int ppp_unit_number(struct ppp_ch
|
||||||
|
/* Get the device name associated with a channel, or NULL if none */
|
||||||
|
extern char *ppp_dev_name(struct ppp_channel *);
|
||||||
|
|
||||||
|
+/* 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);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* SMP locking notes:
|
||||||
|
* The channel code must ensure that when it calls ppp_unregister_channel,
|
||||||
|
--- a/net/l2tp/l2tp_core.c
|
||||||
|
+++ b/net/l2tp/l2tp_core.c
|
||||||
|
@@ -403,6 +403,30 @@ err_tlock:
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(l2tp_session_register);
|
||||||
|
|
||||||
|
+void l2tp_stats_update(struct l2tp_tunnel *tunnel,
|
||||||
|
+ struct l2tp_session *session,
|
||||||
|
+ struct l2tp_stats *stats)
|
||||||
|
+{
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->rx_packets),
|
||||||
|
+ &tunnel->stats.rx_packets);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->rx_bytes),
|
||||||
|
+ &tunnel->stats.rx_bytes);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->tx_packets),
|
||||||
|
+ &tunnel->stats.tx_packets);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->tx_bytes),
|
||||||
|
+ &tunnel->stats.tx_bytes);
|
||||||
|
+
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->rx_packets),
|
||||||
|
+ &session->stats.rx_packets);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->rx_bytes),
|
||||||
|
+ &session->stats.rx_bytes);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->tx_packets),
|
||||||
|
+ &session->stats.tx_packets);
|
||||||
|
+ atomic_long_add(atomic_long_read(&stats->tx_bytes),
|
||||||
|
+ &session->stats.tx_bytes);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(l2tp_stats_update);
|
||||||
|
+
|
||||||
|
/*****************************************************************************
|
||||||
|
* Receive data handling
|
||||||
|
*****************************************************************************/
|
||||||
|
--- a/net/l2tp/l2tp_core.h
|
||||||
|
+++ b/net/l2tp/l2tp_core.h
|
||||||
|
@@ -231,6 +231,8 @@ struct l2tp_session *l2tp_session_get(co
|
||||||
|
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
|
||||||
|
struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
|
||||||
|
const char *ifname);
|
||||||
|
+void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session,
|
||||||
|
+ struct l2tp_stats *stats);
|
||||||
|
|
||||||
|
/* Tunnel and session lifetime management.
|
||||||
|
* Creation of a new instance is a two-step process: create, then register.
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
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) */
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
From fb2393132ddf7af47b6b5dd67b57048f4b914faa Mon Sep 17 00:00:00 2001
|
||||||
|
From: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
Date: Mon, 13 Nov 2017 15:10:10 +0530
|
||||||
|
Subject: [PATCH 298/500] net :gre : Set skb->skb_iif number
|
||||||
|
|
||||||
|
skb->skb_iif should be set to GRE netdevice to accelerate
|
||||||
|
packet
|
||||||
|
|
||||||
|
Change-Id: I0af542d2fa64b87c51b9bf3803bb874299299026
|
||||||
|
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
Signed-off-by: Subhash Kumar Katnpally <skatnapa@codeaurora.org>
|
||||||
|
Signed-off-by: Pavithra R <pavir@codeaurora.org>
|
||||||
|
---
|
||||||
|
net/ipv4/ip_gre.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
--- a/net/ipv4/ip_gre.c
|
||||||
|
+++ b/net/ipv4/ip_gre.c
|
||||||
|
@@ -687,6 +687,8 @@ static netdev_tx_t ipgre_xmit(struct sk_
|
||||||
|
if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
|
||||||
|
goto free_skb;
|
||||||
|
|
||||||
|
+ skb->skb_iif = dev->ifindex;
|
||||||
|
+
|
||||||
|
__gre_xmit(skb, dev, tnl_params, skb->protocol);
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
|
@@ -770,6 +772,8 @@ static netdev_tx_t gre_tap_xmit(struct s
|
||||||
|
if (skb_cow_head(skb, dev->needed_headroom))
|
||||||
|
goto free_skb;
|
||||||
|
|
||||||
|
+ skb->skb_iif = dev->ifindex;
|
||||||
|
+
|
||||||
|
__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
From cad2cc2ca7c6cb9b4428a0333c46713f82d2424d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ratheesh Kannoth <rkannoth@codeaurora.org>
|
||||||
|
Date: Fri, 6 Nov 2020 12:56:12 +0530
|
||||||
|
Subject: [PATCH 244/500] net: ppp: API to check compression enabled on PPP
|
||||||
|
device
|
||||||
|
|
||||||
|
Change-Id: I574c688a9299531263061534a51cc88fef5e069f
|
||||||
|
Signed-off-by: Ratheesh Kannoth <rkannoth@codeaurora.org>
|
||||||
|
Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 22 ++++++++++++++++++++++
|
||||||
|
include/linux/ppp_channel.h | 2 ++
|
||||||
|
2 files changed, 24 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
@@ -3675,6 +3675,28 @@ void ppp_update_stats(struct net_device
|
||||||
|
ppp_recv_unlock(ppp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Returns true if Compression is enabled on PPP device
|
||||||
|
+ */
|
||||||
|
+bool ppp_is_cp_enabled(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct ppp *ppp;
|
||||||
|
+ bool flag = false;
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (dev->type != ARPHRD_PPP)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ ppp = netdev_priv(dev);
|
||||||
|
+ ppp_lock(ppp);
|
||||||
|
+ flag = !!ppp->xcomp || !!ppp->rcomp;
|
||||||
|
+ ppp_unlock(ppp);
|
||||||
|
+
|
||||||
|
+ return flag;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ppp_is_cp_enabled);
|
||||||
|
+
|
||||||
|
/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if
|
||||||
|
* the device is not PPP.
|
||||||
|
*/
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -81,6 +81,8 @@ extern int ppp_hold_channels(struct net_
|
||||||
|
struct ppp_channel *channels[],
|
||||||
|
unsigned int chan_sz);
|
||||||
|
|
||||||
|
+bool ppp_is_cp_enabled(struct net_device *dev);
|
||||||
|
+
|
||||||
|
/* Test if the ppp device is a multi-link ppp device */
|
||||||
|
extern int ppp_is_multilink(struct net_device *dev);
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
From 74702bfe2627baa572303a4d4281bafa2cfa2464 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ratheesh Kannoth <rkannoth@codeaurora.org>
|
||||||
|
Date: Mon, 16 Nov 2020 17:34:25 +0530
|
||||||
|
Subject: [PATCH 264/500] net: ppp: Use flag to detect TX/RX compression
|
||||||
|
|
||||||
|
Change-Id: I3068377565fe172b2771b7878a6c933322f6c69e
|
||||||
|
Signed-off-by: Ratheesh Kannoth <rkannoth@codeaurora.org>
|
||||||
|
Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
@@ -3690,7 +3690,7 @@ bool ppp_is_cp_enabled(struct net_device
|
||||||
|
|
||||||
|
ppp = netdev_priv(dev);
|
||||||
|
ppp_lock(ppp);
|
||||||
|
- flag = !!ppp->xcomp || !!ppp->rcomp;
|
||||||
|
+ flag = !!(ppp->xstate & SC_COMP_RUN) || !!(ppp->rstate & SC_DECOMP_RUN);
|
||||||
|
ppp_unlock(ppp);
|
||||||
|
|
||||||
|
return flag;
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
From a7f74f20856f3076d57cb2a986cfbe1d26cead41 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
Date: Wed, 8 Jul 2015 11:13:57 +0530
|
||||||
|
Subject: [PATCH 306/500] net: l2tp: set skb->iif for pkt thru l2tp interface
|
||||||
|
|
||||||
|
Change-Id: I20eed270083ba9ac167d9672928483396e488133
|
||||||
|
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 15 +++++++++++++++
|
||||||
|
include/linux/ppp_channel.h | 4 ++++
|
||||||
|
net/l2tp/l2tp_ppp.c | 4 ++++
|
||||||
|
3 files changed, 23 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
@@ -2986,6 +2986,20 @@ char *ppp_dev_name(struct ppp_channel *c
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* 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;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disconnect a channel from the generic layer.
|
||||||
|
@@ -3854,6 +3868,7 @@ EXPORT_SYMBOL(ppp_unregister_channel);
|
||||||
|
EXPORT_SYMBOL(ppp_channel_index);
|
||||||
|
EXPORT_SYMBOL(ppp_unit_number);
|
||||||
|
EXPORT_SYMBOL(ppp_dev_name);
|
||||||
|
+EXPORT_SYMBOL(ppp_dev_index);
|
||||||
|
EXPORT_SYMBOL(ppp_input);
|
||||||
|
EXPORT_SYMBOL(ppp_input_error);
|
||||||
|
EXPORT_SYMBOL(ppp_output_wakeup);
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
#include <net/net_namespace.h>
|
||||||
|
+#include <linux/ppp_defs.h>
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
|
/* PPP channel connection event types */
|
||||||
|
@@ -118,6 +119,9 @@ extern void ppp_unregister_channel(struc
|
||||||
|
/* Get the channel number for a channel */
|
||||||
|
extern int ppp_channel_index(struct ppp_channel *);
|
||||||
|
|
||||||
|
+/* Get the device index associated with a channel, or 0, if none */
|
||||||
|
+extern int ppp_dev_index(struct ppp_channel *);
|
||||||
|
+
|
||||||
|
/* Get the unit number associated with a channel, or -1 if none */
|
||||||
|
extern int ppp_unit_number(struct ppp_channel *);
|
||||||
|
|
||||||
|
--- a/net/l2tp/l2tp_ppp.c
|
||||||
|
+++ b/net/l2tp/l2tp_ppp.c
|
||||||
|
@@ -243,6 +243,7 @@ static void pppol2tp_recv(struct l2tp_se
|
||||||
|
struct pppox_sock *po;
|
||||||
|
|
||||||
|
po = pppox_sk(sk);
|
||||||
|
+ skb->skb_iif = ppp_dev_index(&po->chan);
|
||||||
|
ppp_input(&po->chan, skb);
|
||||||
|
} else {
|
||||||
|
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
||||||
|
@@ -402,6 +403,9 @@ static int pppol2tp_xmit(struct ppp_chan
|
||||||
|
__skb_push(skb, 2);
|
||||||
|
skb->data[0] = PPP_ALLSTATIONS;
|
||||||
|
skb->data[1] = PPP_UI;
|
||||||
|
+ /* set incoming interface as the ppp interface */
|
||||||
|
+ if (skb->skb_iif)
|
||||||
|
+ skb->skb_iif = ppp_dev_index(chan);
|
||||||
|
|
||||||
|
local_bh_disable();
|
||||||
|
l2tp_xmit_skb(session, skb);
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
From 974e8f230c2294f54d5151fe0dbbc68a3aecb347 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
Date: Fri, 26 Feb 2016 15:18:08 -0800
|
||||||
|
Subject: [PATCH 307/500] net :l2tp: l2tp chan ops support get_addressing
|
||||||
|
|
||||||
|
l2tp channel ops support get_addressing() function. This
|
||||||
|
function can get l2tp tunnel/session/ip/port info.
|
||||||
|
|
||||||
|
Change-Id: Ica87438505c20376478092b95faaa3ecb8251596
|
||||||
|
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 79 +++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/if_pppol2tp.h | 23 ++++++++++
|
||||||
|
include/linux/ppp_channel.h | 7 ++++
|
||||||
|
net/l2tp/l2tp_ppp.c | 53 +++++++++++++++++++----
|
||||||
|
4 files changed, 155 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/ppp_generic.c
|
||||||
|
+++ b/drivers/net/ppp/ppp_generic.c
|
||||||
|
@@ -3737,6 +3737,32 @@ int ppp_is_multilink(struct net_device *
|
||||||
|
}
|
||||||
|
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
|
||||||
|
@@ -3841,6 +3867,59 @@ int ppp_hold_channels(struct net_device
|
||||||
|
}
|
||||||
|
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 acquire ppp_lock and 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/if_pppol2tp.h
|
||||||
|
+++ b/include/linux/if_pppol2tp.h
|
||||||
|
@@ -12,4 +12,27 @@
|
||||||
|
#include <linux/in6.h>
|
||||||
|
#include <uapi/linux/if_pppol2tp.h>
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * 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 *);
|
||||||
|
#endif
|
||||||
|
--- a/include/linux/ppp_channel.h
|
||||||
|
+++ b/include/linux/ppp_channel.h
|
||||||
|
@@ -83,10 +83,17 @@ extern int ppp_hold_channels(struct net_
|
||||||
|
unsigned int chan_sz);
|
||||||
|
|
||||||
|
bool ppp_is_cp_enabled(struct net_device *dev);
|
||||||
|
+/* 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);
|
||||||
|
|
||||||
|
+/* 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
|
||||||
|
*/
|
||||||
|
--- a/net/l2tp/l2tp_ppp.c
|
||||||
|
+++ b/net/l2tp/l2tp_ppp.c
|
||||||
|
@@ -126,12 +126,11 @@ static int pppol2tp_xmit(struct ppp_chan
|
||||||
|
static int pppol2tp_get_channel_protocol(struct ppp_channel *);
|
||||||
|
static void pppol2tp_hold_chan(struct ppp_channel *);
|
||||||
|
static void pppol2tp_release_chan(struct ppp_channel *);
|
||||||
|
-
|
||||||
|
-static const struct ppp_channel_ops pppol2tp_chan_ops = {
|
||||||
|
- .start_xmit = pppol2tp_xmit,
|
||||||
|
- .get_channel_protocol = pppol2tp_get_channel_protocol,
|
||||||
|
- .hold = pppol2tp_hold_chan,
|
||||||
|
- .release = pppol2tp_release_chan,
|
||||||
|
+static const struct pppol2tp_channel_ops pppol2tp_chan_ops = {
|
||||||
|
+ .ops.start_xmit = pppol2tp_xmit,
|
||||||
|
+ .ops.get_channel_protocol = pppol2tp_get_channel_protocol,
|
||||||
|
+ .ops.hold = pppol2tp_hold_chan,
|
||||||
|
+ .ops.release = pppol2tp_release_chan,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct proto_ops pppol2tp_ops;
|
||||||
|
@@ -359,6 +358,46 @@ static int pppol2tp_get_channel_protocol
|
||||||
|
return PX_PROTO_OL2TP;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* 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;
|
||||||
|
+ 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);
|
||||||
|
+
|
||||||
|
/* Transmit function called by generic PPP driver. Sends PPP frame
|
||||||
|
* over PPPoL2TP socket.
|
||||||
|
*
|
||||||
|
@@ -852,7 +891,7 @@ static int pppol2tp_connect(struct socke
|
||||||
|
po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
|
||||||
|
|
||||||
|
po->chan.private = sk;
|
||||||
|
- po->chan.ops = &pppol2tp_chan_ops;
|
||||||
|
+ po->chan.ops = &pppol2tp_chan_ops.ops;
|
||||||
|
po->chan.mtu = pppol2tp_tunnel_mtu(tunnel);
|
||||||
|
|
||||||
|
error = ppp_register_net_channel(sock_net(sk), &po->chan);
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
From 98f71e72955490c9a1dcdb0f290e4a874a92ae4e Mon Sep 17 00:00:00 2001
|
||||||
|
From: pavir <pavir@codeaurora.org>
|
||||||
|
Date: Mon, 26 Dec 2016 14:41:20 +0530
|
||||||
|
Subject: [PATCH 308/500] 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>
|
||||||
|
|
||||||
|
ppp: Fix ppp_connect_channel function's return value
|
||||||
|
|
||||||
|
The function should return 0 after all the successful
|
||||||
|
checks. The patch fixes failed PPPoE connections.
|
||||||
|
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
Change-Id: I6c4755b0b158ca9bd75403e01cb3c0dda193e9e0
|
||||||
|
Signed-off-by: Amruth S <quic_amrus@quicinc.com>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/ppp_generic.c | 61 +++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/netdevice.h | 1 -
|
||||||
|
include/linux/ppp_channel.h | 9 ++++++
|
||||||
|
net/l2tp/l2tp_ppp.c | 40 ++++++++++++++++++++++-
|
||||||
|
4 files changed, 109 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- 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>
|
||||||
|
@@ -3500,6 +3501,8 @@ ppp_connect_channel(struct channel *pch,
|
||||||
|
struct ppp_net *pn;
|
||||||
|
int ret = -ENXIO;
|
||||||
|
int hdrlen;
|
||||||
|
+ int ppp_proto;
|
||||||
|
+ int version;
|
||||||
|
int notify = 0;
|
||||||
|
|
||||||
|
pn = ppp_pernet(pch->chan_net);
|
||||||
|
@@ -3533,6 +3536,30 @@ ppp_connect_channel(struct channel *pch,
|
||||||
|
++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;
|
||||||
|
+ break;
|
||||||
|
+ case 3:
|
||||||
|
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case PX_PROTO_PPTP:
|
||||||
|
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
notify = 1;
|
||||||
|
|
||||||
|
ppp_unlock(ppp);
|
||||||
|
@@ -3783,6 +3810,18 @@ int ppp_channel_get_protocol(struct ppp_
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
@@ -3936,6 +3975,28 @@ void ppp_release_channels(struct ppp_cha
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
--- a/include/linux/netdevice.h
|
||||||
|
+++ b/include/linux/netdevice.h
|
||||||
|
@@ -2259,7 +2259,6 @@ struct net_device {
|
||||||
|
unsigned char nested_level;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-
|
||||||
|
/* Protocol-specific pointers */
|
||||||
|
|
||||||
|
struct in_device __rcu *ip_ptr;
|
||||||
|
--- 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_
|
||||||
|
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[],
|
||||||
|
--- 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
|
||||||
|
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_chan
|
||||||
|
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();
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
From 8b2fc28f1a1280663d30466c788ae80774fa1f29 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
Date: Fri, 24 Apr 2020 11:00:19 -0700
|
||||||
|
Subject: [PATCH 303/500] inet: pptp: Enable offload mode for PPTP GRE sequence
|
||||||
|
number handling
|
||||||
|
|
||||||
|
Changes in this patch will allow all PPTP Data and LCP packets
|
||||||
|
to go via packet acceleration hardware. The hardware will take
|
||||||
|
care of Seq/Ack numbers update.
|
||||||
|
|
||||||
|
Change-Id: Ia5cd7893d9fda180174f78c3468279678422794d
|
||||||
|
Signed-off-by: Shyam Sunder <ssunde@codeaurora.org>
|
||||||
|
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/ppp/pptp.c | 136 +++++++++++++++++++++++++++++++++++++--
|
||||||
|
include/linux/if_pppox.h | 21 ++++++
|
||||||
|
2 files changed, 153 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/pptp.c
|
||||||
|
+++ b/drivers/net/ppp/pptp.c
|
||||||
|
@@ -50,6 +50,8 @@ static struct proto pptp_sk_proto __read
|
||||||
|
static const struct ppp_channel_ops pptp_chan_ops;
|
||||||
|
static const struct proto_ops pptp_ops;
|
||||||
|
|
||||||
|
+static pptp_gre_seq_offload_callback_t __rcu pptp_gre_offload_xmit_cb;
|
||||||
|
+
|
||||||
|
static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr)
|
||||||
|
{
|
||||||
|
struct pppox_sock *sock;
|
||||||
|
@@ -116,6 +118,28 @@ static int lookup_session_dst(struct ppt
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* If offload mode set then this function sends all packets to
|
||||||
|
+ * offload module instead of network stack
|
||||||
|
+ */
|
||||||
|
+static int pptp_client_skb_xmit(struct sk_buff *skb,
|
||||||
|
+ struct net_device *pptp_dev)
|
||||||
|
+{
|
||||||
|
+ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ rcu_read_lock();
|
||||||
|
+ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb);
|
||||||
|
+
|
||||||
|
+ if (!pptp_gre_offload_cb_f) {
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = pptp_gre_offload_cb_f(skb, pptp_dev);
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int add_chan(struct pppox_sock *sock,
|
||||||
|
struct pptp_addr *sa)
|
||||||
|
{
|
||||||
|
@@ -188,8 +212,11 @@ static int pptp_xmit(struct ppp_channel
|
||||||
|
|
||||||
|
struct rtable *rt;
|
||||||
|
struct net_device *tdev;
|
||||||
|
+ struct net_device *pptp_dev;
|
||||||
|
struct iphdr *iph;
|
||||||
|
int max_headroom;
|
||||||
|
+ int pptp_ifindex;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
if (sk_pppox(po)->sk_state & PPPOX_DEAD)
|
||||||
|
goto tx_error;
|
||||||
|
@@ -283,14 +310,33 @@ static int pptp_xmit(struct ppp_channel
|
||||||
|
ip_select_ident(net, skb, NULL);
|
||||||
|
ip_send_check(iph);
|
||||||
|
|
||||||
|
+ pptp_ifindex = ppp_dev_index(chan);
|
||||||
|
+
|
||||||
|
/* set incoming interface as the ppp interface */
|
||||||
|
if (skb->skb_iif)
|
||||||
|
- skb->skb_iif = ppp_dev_index(chan);
|
||||||
|
+ skb->skb_iif = pptp_ifindex;
|
||||||
|
|
||||||
|
- ip_local_out(net, skb->sk, skb);
|
||||||
|
+ /* If the PPTP GRE seq number offload module is not enabled yet
|
||||||
|
+ * then sends all PPTP GRE packets through linux network stack
|
||||||
|
+ */
|
||||||
|
+ if (!opt->pptp_offload_mode) {
|
||||||
|
+ ip_local_out(net, skb->sk, skb);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return 1;
|
||||||
|
+ pptp_dev = dev_get_by_index(&init_net, pptp_ifindex);
|
||||||
|
+ if (!pptp_dev)
|
||||||
|
+ goto tx_error;
|
||||||
|
|
||||||
|
+ /* If PPTP offload module is enabled then forward all PPTP GRE
|
||||||
|
+ * packets to PPTP GRE offload module
|
||||||
|
+ */
|
||||||
|
+ ret = pptp_client_skb_xmit(skb, pptp_dev);
|
||||||
|
+ dev_put(pptp_dev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto tx_error;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
tx_error:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return 1;
|
||||||
|
@@ -344,6 +390,13 @@ static int pptp_rcv_core(struct sock *sk
|
||||||
|
goto drop;
|
||||||
|
|
||||||
|
payload = skb->data + headersize;
|
||||||
|
+
|
||||||
|
+ /* If offload is enabled, we expect the offload module
|
||||||
|
+ * to handle PPTP GRE sequence number checks
|
||||||
|
+ */
|
||||||
|
+ if (opt->pptp_offload_mode)
|
||||||
|
+ goto allow_packet;
|
||||||
|
+
|
||||||
|
/* check for expected sequence number */
|
||||||
|
if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) {
|
||||||
|
if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) &&
|
||||||
|
@@ -504,7 +557,7 @@ static int pptp_connect(struct socket *s
|
||||||
|
|
||||||
|
opt->dst_addr = sp->sa_addr.pptp;
|
||||||
|
sk->sk_state |= PPPOX_CONNECTED;
|
||||||
|
-
|
||||||
|
+ opt->pptp_offload_mode = false;
|
||||||
|
end:
|
||||||
|
release_sock(sk);
|
||||||
|
return error;
|
||||||
|
@@ -678,6 +731,81 @@ int pptp_session_find(struct pptp_opt *o
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(pptp_session_find);
|
||||||
|
|
||||||
|
+ /* Function to change the offload mode true/false for a PPTP session */
|
||||||
|
+static int pptp_set_offload_mode(bool accel_mode,
|
||||||
|
+ __be16 peer_call_id, __be32 peer_ip_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 == peer_call_id &&
|
||||||
|
+ sock->proto.pptp.dst_addr.sin_addr.s_addr == peer_ip_addr) {
|
||||||
|
+ sock_hold(sk_pppox(sock));
|
||||||
|
+ sock->proto.pptp.pptp_offload_mode = accel_mode;
|
||||||
|
+ sock_put(sk_pppox(sock));
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return -EINVAL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Enable the PPTP session offload flag */
|
||||||
|
+int pptp_session_enable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr)
|
||||||
|
+{
|
||||||
|
+ return pptp_set_offload_mode(true, peer_call_id, peer_ip_addr);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pptp_session_enable_offload_mode);
|
||||||
|
+
|
||||||
|
+/* Disable the PPTP session offload flag */
|
||||||
|
+int pptp_session_disable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr)
|
||||||
|
+{
|
||||||
|
+ return pptp_set_offload_mode(false, peer_call_id, peer_ip_addr);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pptp_session_disable_offload_mode);
|
||||||
|
+
|
||||||
|
+/* Register the offload callback function on behalf of the module which
|
||||||
|
+ * will own the sequence and acknowledgment number updates for all
|
||||||
|
+ * PPTP GRE packets. All PPTP GRE packets are then transmitted to this
|
||||||
|
+ * module after encapsulation in order to ensure the correct seq/ack
|
||||||
|
+ * fields are set in the packets before transmission. This is required
|
||||||
|
+ * when PPTP flows are offloaded to acceleration engines, in-order to
|
||||||
|
+ * ensure consistency in sequence and ack numbers between PPTP control
|
||||||
|
+ * (PPP LCP) and data packets
|
||||||
|
+ */
|
||||||
|
+int pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t
|
||||||
|
+ pptp_gre_offload_cb)
|
||||||
|
+{
|
||||||
|
+ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f;
|
||||||
|
+
|
||||||
|
+ rcu_read_lock();
|
||||||
|
+ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb);
|
||||||
|
+
|
||||||
|
+ if (pptp_gre_offload_cb_f) {
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rcu_assign_pointer(pptp_gre_offload_xmit_cb, pptp_gre_offload_cb);
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pptp_register_gre_seq_offload_callback);
|
||||||
|
+
|
||||||
|
+/* Unregister the PPTP GRE packets sequence number offload callback */
|
||||||
|
+void pptp_unregister_gre_seq_offload_callback(void)
|
||||||
|
+{
|
||||||
|
+ rcu_assign_pointer(pptp_gre_offload_xmit_cb, NULL);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(pptp_unregister_gre_seq_offload_callback);
|
||||||
|
+
|
||||||
|
/* pptp_hold_chan() */
|
||||||
|
static void pptp_hold_chan(struct ppp_channel *chan)
|
||||||
|
{
|
||||||
|
--- a/include/linux/if_pppox.h
|
||||||
|
+++ b/include/linux/if_pppox.h
|
||||||
|
@@ -37,6 +37,7 @@ struct pptp_opt {
|
||||||
|
u32 ack_sent, ack_recv;
|
||||||
|
u32 seq_sent, seq_recv;
|
||||||
|
int ppp_flags;
|
||||||
|
+ bool pptp_offload_mode;
|
||||||
|
};
|
||||||
|
#include <net/sock.h>
|
||||||
|
|
||||||
|
@@ -101,6 +102,10 @@ struct pppoe_channel_ops {
|
||||||
|
int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *);
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* PPTP client callback */
|
||||||
|
+typedef int (*pptp_gre_seq_offload_callback_t)(struct sk_buff *skb,
|
||||||
|
+ struct net_device *pptp_dev);
|
||||||
|
+
|
||||||
|
/* Return PPPoE channel specific addressing information */
|
||||||
|
extern int pppoe_channel_addressing_get(struct ppp_channel *chan,
|
||||||
|
struct pppoe_opt *addressing);
|
||||||
|
@@ -113,4 +118,20 @@ extern int pptp_session_find(struct pptp
|
||||||
|
extern void pptp_channel_addressing_get(struct pptp_opt *opt,
|
||||||
|
struct ppp_channel *chan);
|
||||||
|
|
||||||
|
+/* Enable the PPTP session offload flag */
|
||||||
|
+extern int pptp_session_enable_offload_mode(__be16 peer_call_id,
|
||||||
|
+ __be32 peer_ip_addr);
|
||||||
|
+
|
||||||
|
+/* Disable the PPTP session offload flag */
|
||||||
|
+extern int pptp_session_disable_offload_mode(__be16 peer_call_id,
|
||||||
|
+ __be32 peer_ip_addr);
|
||||||
|
+
|
||||||
|
+/* Register the PPTP GRE packets sequence number offload callback */
|
||||||
|
+extern int
|
||||||
|
+pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t
|
||||||
|
+ pptp_client_cb);
|
||||||
|
+
|
||||||
|
+/* Unregister the PPTP GRE packets sequence number offload callback */
|
||||||
|
+extern void pptp_unregister_gre_seq_offload_callback(void);
|
||||||
|
+
|
||||||
|
#endif /* !(__LINUX_IF_PPPOX_H) */
|
||||||
Reference in New Issue
Block a user