Merge branch 'l2tp-replace-custom-logging-code-with-tracepoints'
Tom Parkin says: ==================== l2tp: replace custom logging code with tracepoints The l2tp subsystem implemented custom logging macros for debugging purposes which were controlled using a set of debugging flags in each tunnel and session structure. A more standard and easier-to-use approach is to use tracepoints. This patchset refactors l2tp to: * remove excessive logging * tweak useful log messages to use the standard pr_* calls for logging rather than the l2tp wrappers * replace debug-level logging with tracepoints * add tracepoints for capturing tunnel and session lifetime events I note that checkpatch.pl warns about the layout of code in the newly-added file net/l2tp/trace.h. When adding this file I followed the example(s) of other tracepoint files in the net/ subtree since it seemed preferable to adhere to the prevailing style rather than follow checkpatch.pl's advice in this instance. If that's the wrong approach please let me know. v1 -> v2 * Fix up a build warning found by the kernel test robot ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d7223aa586
13 changed files with 302 additions and 287 deletions
|
@ -455,31 +455,16 @@ l2tp help`` for more information.
|
||||||
Debugging
|
Debugging
|
||||||
---------
|
---------
|
||||||
|
|
||||||
The L2TP subsystem offers a debug scheme where kernel trace messages
|
The L2TP subsystem offers a range of debugging interfaces through the
|
||||||
may be optionally enabled per tunnel and per session. Care is needed
|
debugfs filesystem.
|
||||||
when debugging a live system since the messages are not rate-limited
|
|
||||||
and a busy system could be swamped. Userspace uses setsockopt on the
|
|
||||||
PPPoX socket to set a debug mask, or ``L2TP_ATTR_DEBUG`` in netlink
|
|
||||||
Create and Modify commands.
|
|
||||||
|
|
||||||
The following debug mask bits are defined:-
|
To access these interfaces, the debugfs filesystem must first be mounted::
|
||||||
|
|
||||||
================ ==============================
|
|
||||||
L2TP_MSG_DEBUG verbose debug (if compiled in)
|
|
||||||
L2TP_MSG_CONTROL userspace - kernel interface
|
|
||||||
L2TP_MSG_SEQ sequence numbers handling
|
|
||||||
L2TP_MSG_DATA data packets
|
|
||||||
================ ==============================
|
|
||||||
|
|
||||||
Sessions inherit default debug flags from the parent tunnel.
|
|
||||||
|
|
||||||
If enabled, files under a l2tp debugfs directory can be used to dump
|
|
||||||
kernel state about L2TP tunnels and sessions. To access it, the
|
|
||||||
debugfs filesystem must first be mounted::
|
|
||||||
|
|
||||||
# mount -t debugfs debugfs /debug
|
# mount -t debugfs debugfs /debug
|
||||||
|
|
||||||
Files under the l2tp directory can then be accessed::
|
Files under the l2tp directory can then be accessed, providing a summary
|
||||||
|
of the current population of tunnel and session contexts existing in the
|
||||||
|
kernel::
|
||||||
|
|
||||||
# cat /debug/l2tp/tunnels
|
# cat /debug/l2tp/tunnels
|
||||||
|
|
||||||
|
@ -488,8 +473,14 @@ state information because the file format is subject to change. It is
|
||||||
implemented to provide extra debug information to help diagnose
|
implemented to provide extra debug information to help diagnose
|
||||||
problems. Applications should instead use the netlink API.
|
problems. Applications should instead use the netlink API.
|
||||||
|
|
||||||
/proc/net/pppol2tp is also provided for backwards compatibility with
|
In addition the L2TP subsystem implements tracepoints using the standard
|
||||||
the original pppol2tp code. It lists information about L2TPv2
|
kernel event tracing API. The available L2TP events can be reviewed as
|
||||||
|
follows::
|
||||||
|
|
||||||
|
# find /debug/tracing/events/l2tp
|
||||||
|
|
||||||
|
Finally, /proc/net/pppol2tp is also provided for backwards compatibility
|
||||||
|
with the original pppol2tp code. It lists information about L2TPv2
|
||||||
tunnels and sessions only. Its use is discouraged.
|
tunnels and sessions only. Its use is discouraged.
|
||||||
|
|
||||||
Internal Implementation
|
Internal Implementation
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct pppol2tpv3in6_addr {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Socket options:
|
/* Socket options:
|
||||||
* DEBUG - bitmask of debug message categories
|
* DEBUG - bitmask of debug message categories (not used)
|
||||||
* SENDSEQ - 0 => don't send packets with sequence numbers
|
* SENDSEQ - 0 => don't send packets with sequence numbers
|
||||||
* 1 => send packets with sequence numbers
|
* 1 => send packets with sequence numbers
|
||||||
* RECVSEQ - 0 => receive packet sequence numbers are optional
|
* RECVSEQ - 0 => receive packet sequence numbers are optional
|
||||||
|
|
|
@ -108,7 +108,7 @@ enum {
|
||||||
L2TP_ATTR_VLAN_ID, /* u16 (not used) */
|
L2TP_ATTR_VLAN_ID, /* u16 (not used) */
|
||||||
L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
|
L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
|
||||||
L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
|
L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
|
||||||
L2TP_ATTR_DEBUG, /* u32, enum l2tp_debug_flags */
|
L2TP_ATTR_DEBUG, /* u32, enum l2tp_debug_flags (not used) */
|
||||||
L2TP_ATTR_RECV_SEQ, /* u8 */
|
L2TP_ATTR_RECV_SEQ, /* u8 */
|
||||||
L2TP_ATTR_SEND_SEQ, /* u8 */
|
L2TP_ATTR_SEND_SEQ, /* u8 */
|
||||||
L2TP_ATTR_LNS_MODE, /* u8 */
|
L2TP_ATTR_LNS_MODE, /* u8 */
|
||||||
|
@ -177,7 +177,9 @@ enum l2tp_seqmode {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum l2tp_debug_flags - debug message categories for L2TP tunnels/sessions
|
* enum l2tp_debug_flags - debug message categories for L2TP tunnels/sessions.
|
||||||
|
*
|
||||||
|
* Unused.
|
||||||
*
|
*
|
||||||
* @L2TP_MSG_DEBUG: verbose debug (if compiled in)
|
* @L2TP_MSG_DEBUG: verbose debug (if compiled in)
|
||||||
* @L2TP_MSG_CONTROL: userspace - kernel interface
|
* @L2TP_MSG_CONTROL: userspace - kernel interface
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
obj-$(CONFIG_L2TP) += l2tp_core.o
|
obj-$(CONFIG_L2TP) += l2tp_core.o
|
||||||
|
|
||||||
|
CFLAGS_l2tp_core.o += -I$(src)
|
||||||
|
|
||||||
# Build l2tp as modules if L2TP is M
|
# Build l2tp as modules if L2TP is M
|
||||||
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
|
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
|
||||||
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
|
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
|
||||||
|
|
|
@ -61,6 +61,10 @@
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
|
|
||||||
#include "l2tp_core.h"
|
#include "l2tp_core.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#define CREATE_TRACE_POINTS
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
#define L2TP_DRV_VERSION "V2.0"
|
#define L2TP_DRV_VERSION "V2.0"
|
||||||
|
|
||||||
|
@ -151,6 +155,7 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id)
|
||||||
|
|
||||||
static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
|
static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
|
||||||
{
|
{
|
||||||
|
trace_free_tunnel(tunnel);
|
||||||
sock_put(tunnel->sock);
|
sock_put(tunnel->sock);
|
||||||
/* the tunnel is freed in the socket destructor */
|
/* the tunnel is freed in the socket destructor */
|
||||||
}
|
}
|
||||||
|
@ -159,6 +164,8 @@ static void l2tp_session_free(struct l2tp_session *session)
|
||||||
{
|
{
|
||||||
struct l2tp_tunnel *tunnel = session->tunnel;
|
struct l2tp_tunnel *tunnel = session->tunnel;
|
||||||
|
|
||||||
|
trace_free_session(session);
|
||||||
|
|
||||||
if (tunnel) {
|
if (tunnel) {
|
||||||
if (WARN_ON(tunnel->magic != L2TP_TUNNEL_MAGIC))
|
if (WARN_ON(tunnel->magic != L2TP_TUNNEL_MAGIC))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -381,6 +388,8 @@ int l2tp_session_register(struct l2tp_session *session,
|
||||||
hlist_add_head(&session->hlist, head);
|
hlist_add_head(&session->hlist, head);
|
||||||
write_unlock_bh(&tunnel->hlist_lock);
|
write_unlock_bh(&tunnel->hlist_lock);
|
||||||
|
|
||||||
|
trace_register_session(session);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_tlock_pnlock:
|
err_tlock_pnlock:
|
||||||
|
@ -409,10 +418,6 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk
|
||||||
skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
|
skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
|
||||||
if (L2TP_SKB_CB(skbp)->ns > ns) {
|
if (L2TP_SKB_CB(skbp)->ns > ns) {
|
||||||
__skb_queue_before(&session->reorder_q, skbp, skb);
|
__skb_queue_before(&session->reorder_q, skbp, skb);
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
|
|
||||||
session->name, ns, L2TP_SKB_CB(skbp)->ns,
|
|
||||||
skb_queue_len(&session->reorder_q));
|
|
||||||
atomic_long_inc(&session->stats.rx_oos_packets);
|
atomic_long_inc(&session->stats.rx_oos_packets);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -445,9 +450,7 @@ static void l2tp_recv_dequeue_skb(struct l2tp_session *session, struct sk_buff *
|
||||||
/* Bump our Nr */
|
/* Bump our Nr */
|
||||||
session->nr++;
|
session->nr++;
|
||||||
session->nr &= session->nr_max;
|
session->nr &= session->nr_max;
|
||||||
|
trace_session_seqnum_update(session);
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated nr to %hu\n",
|
|
||||||
session->name, session->nr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call private receive handler */
|
/* call private receive handler */
|
||||||
|
@ -472,37 +475,27 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
|
||||||
start:
|
start:
|
||||||
spin_lock_bh(&session->reorder_q.lock);
|
spin_lock_bh(&session->reorder_q.lock);
|
||||||
skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
|
skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
|
||||||
if (time_after(jiffies, L2TP_SKB_CB(skb)->expires)) {
|
struct l2tp_skb_cb *cb = L2TP_SKB_CB(skb);
|
||||||
|
|
||||||
|
/* If the packet has been pending on the queue for too long, discard it */
|
||||||
|
if (time_after(jiffies, cb->expires)) {
|
||||||
atomic_long_inc(&session->stats.rx_seq_discards);
|
atomic_long_inc(&session->stats.rx_seq_discards);
|
||||||
atomic_long_inc(&session->stats.rx_errors);
|
atomic_long_inc(&session->stats.rx_errors);
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
trace_session_pkt_expired(session, cb->ns);
|
||||||
"%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n",
|
|
||||||
session->name, L2TP_SKB_CB(skb)->ns,
|
|
||||||
L2TP_SKB_CB(skb)->length, session->nr,
|
|
||||||
skb_queue_len(&session->reorder_q));
|
|
||||||
session->reorder_skip = 1;
|
session->reorder_skip = 1;
|
||||||
__skb_unlink(skb, &session->reorder_q);
|
__skb_unlink(skb, &session->reorder_q);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (L2TP_SKB_CB(skb)->has_seq) {
|
if (cb->has_seq) {
|
||||||
if (session->reorder_skip) {
|
if (session->reorder_skip) {
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: advancing nr to next pkt: %u -> %u",
|
|
||||||
session->name, session->nr,
|
|
||||||
L2TP_SKB_CB(skb)->ns);
|
|
||||||
session->reorder_skip = 0;
|
session->reorder_skip = 0;
|
||||||
session->nr = L2TP_SKB_CB(skb)->ns;
|
session->nr = cb->ns;
|
||||||
|
trace_session_seqnum_reset(session);
|
||||||
}
|
}
|
||||||
if (L2TP_SKB_CB(skb)->ns != session->nr) {
|
if (cb->ns != session->nr)
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: holding oos pkt %u len %d, waiting for %u, reorder_q_len=%d\n",
|
|
||||||
session->name, L2TP_SKB_CB(skb)->ns,
|
|
||||||
L2TP_SKB_CB(skb)->length, session->nr,
|
|
||||||
skb_queue_len(&session->reorder_q));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
__skb_unlink(skb, &session->reorder_q);
|
__skb_unlink(skb, &session->reorder_q);
|
||||||
|
|
||||||
|
@ -535,14 +528,13 @@ static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr)
|
||||||
*/
|
*/
|
||||||
static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb)
|
static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (!l2tp_seq_check_rx_window(session, L2TP_SKB_CB(skb)->ns)) {
|
struct l2tp_skb_cb *cb = L2TP_SKB_CB(skb);
|
||||||
|
|
||||||
|
if (!l2tp_seq_check_rx_window(session, cb->ns)) {
|
||||||
/* Packet sequence number is outside allowed window.
|
/* Packet sequence number is outside allowed window.
|
||||||
* Discard it.
|
* Discard it.
|
||||||
*/
|
*/
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
trace_session_pkt_outside_rx_window(session, cb->ns);
|
||||||
"%s: pkt %u len %d discarded, outside window, nr=%u\n",
|
|
||||||
session->name, L2TP_SKB_CB(skb)->ns,
|
|
||||||
L2TP_SKB_CB(skb)->length, session->nr);
|
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,10 +551,10 @@ static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb)
|
||||||
* is seen. After nr_oos_count_max in-sequence packets, reset the
|
* is seen. After nr_oos_count_max in-sequence packets, reset the
|
||||||
* sequence number to re-enable packet reception.
|
* sequence number to re-enable packet reception.
|
||||||
*/
|
*/
|
||||||
if (L2TP_SKB_CB(skb)->ns == session->nr) {
|
if (cb->ns == session->nr) {
|
||||||
skb_queue_tail(&session->reorder_q, skb);
|
skb_queue_tail(&session->reorder_q, skb);
|
||||||
} else {
|
} else {
|
||||||
u32 nr_oos = L2TP_SKB_CB(skb)->ns;
|
u32 nr_oos = cb->ns;
|
||||||
u32 nr_next = (session->nr_oos + 1) & session->nr_max;
|
u32 nr_next = (session->nr_oos + 1) & session->nr_max;
|
||||||
|
|
||||||
if (nr_oos == nr_next)
|
if (nr_oos == nr_next)
|
||||||
|
@ -573,17 +565,10 @@ static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb)
|
||||||
session->nr_oos = nr_oos;
|
session->nr_oos = nr_oos;
|
||||||
if (session->nr_oos_count > session->nr_oos_count_max) {
|
if (session->nr_oos_count > session->nr_oos_count_max) {
|
||||||
session->reorder_skip = 1;
|
session->reorder_skip = 1;
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: %d oos packets received. Resetting sequence numbers\n",
|
|
||||||
session->name, session->nr_oos_count);
|
|
||||||
}
|
}
|
||||||
if (!session->reorder_skip) {
|
if (!session->reorder_skip) {
|
||||||
atomic_long_inc(&session->stats.rx_seq_discards);
|
atomic_long_inc(&session->stats.rx_seq_discards);
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
trace_session_pkt_oos(session, cb->ns);
|
||||||
"%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n",
|
|
||||||
session->name, L2TP_SKB_CB(skb)->ns,
|
|
||||||
L2TP_SKB_CB(skb)->length, session->nr,
|
|
||||||
skb_queue_len(&session->reorder_q));
|
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
skb_queue_tail(&session->reorder_q, skb);
|
skb_queue_tail(&session->reorder_q, skb);
|
||||||
|
@ -660,16 +645,14 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
int length)
|
int length)
|
||||||
{
|
{
|
||||||
struct l2tp_tunnel *tunnel = session->tunnel;
|
struct l2tp_tunnel *tunnel = session->tunnel;
|
||||||
u32 ns = 0, nr = 0;
|
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
/* Parse and check optional cookie */
|
/* Parse and check optional cookie */
|
||||||
if (session->peer_cookie_len > 0) {
|
if (session->peer_cookie_len > 0) {
|
||||||
if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
|
if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
|
||||||
l2tp_info(tunnel, L2TP_MSG_DATA,
|
pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
|
||||||
"%s: cookie mismatch (%u/%u). Discarding.\n",
|
tunnel->name, tunnel->tunnel_id,
|
||||||
tunnel->name, tunnel->tunnel_id,
|
session->session_id);
|
||||||
session->session_id);
|
|
||||||
atomic_long_inc(&session->stats.rx_cookie_discards);
|
atomic_long_inc(&session->stats.rx_cookie_discards);
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
@ -686,32 +669,21 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
L2TP_SKB_CB(skb)->has_seq = 0;
|
L2TP_SKB_CB(skb)->has_seq = 0;
|
||||||
if (tunnel->version == L2TP_HDR_VER_2) {
|
if (tunnel->version == L2TP_HDR_VER_2) {
|
||||||
if (hdrflags & L2TP_HDRFLAG_S) {
|
if (hdrflags & L2TP_HDRFLAG_S) {
|
||||||
ns = ntohs(*(__be16 *)ptr);
|
|
||||||
ptr += 2;
|
|
||||||
nr = ntohs(*(__be16 *)ptr);
|
|
||||||
ptr += 2;
|
|
||||||
|
|
||||||
/* Store L2TP info in the skb */
|
/* Store L2TP info in the skb */
|
||||||
L2TP_SKB_CB(skb)->ns = ns;
|
L2TP_SKB_CB(skb)->ns = ntohs(*(__be16 *)ptr);
|
||||||
L2TP_SKB_CB(skb)->has_seq = 1;
|
L2TP_SKB_CB(skb)->has_seq = 1;
|
||||||
|
ptr += 2;
|
||||||
|
/* Skip past nr in the header */
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: recv data ns=%u, nr=%u, session nr=%u\n",
|
|
||||||
session->name, ns, nr, session->nr);
|
|
||||||
}
|
}
|
||||||
} else if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
|
} else if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
|
||||||
u32 l2h = ntohl(*(__be32 *)ptr);
|
u32 l2h = ntohl(*(__be32 *)ptr);
|
||||||
|
|
||||||
if (l2h & 0x40000000) {
|
if (l2h & 0x40000000) {
|
||||||
ns = l2h & 0x00ffffff;
|
|
||||||
|
|
||||||
/* Store L2TP info in the skb */
|
/* Store L2TP info in the skb */
|
||||||
L2TP_SKB_CB(skb)->ns = ns;
|
L2TP_SKB_CB(skb)->ns = l2h & 0x00ffffff;
|
||||||
L2TP_SKB_CB(skb)->has_seq = 1;
|
L2TP_SKB_CB(skb)->has_seq = 1;
|
||||||
|
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
|
||||||
"%s: recv data ns=%u, session nr=%u\n",
|
|
||||||
session->name, ns, session->nr);
|
|
||||||
}
|
}
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
|
@ -722,9 +694,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
* configure it so.
|
* configure it so.
|
||||||
*/
|
*/
|
||||||
if (!session->lns_mode && !session->send_seq) {
|
if (!session->lns_mode && !session->send_seq) {
|
||||||
l2tp_info(session, L2TP_MSG_SEQ,
|
trace_session_seqnum_lns_enable(session);
|
||||||
"%s: requested to enable seq numbers by LNS\n",
|
|
||||||
session->name);
|
|
||||||
session->send_seq = 1;
|
session->send_seq = 1;
|
||||||
l2tp_session_set_header_len(session, tunnel->version);
|
l2tp_session_set_header_len(session, tunnel->version);
|
||||||
}
|
}
|
||||||
|
@ -733,9 +703,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
* If user has configured mandatory sequence numbers, discard.
|
* If user has configured mandatory sequence numbers, discard.
|
||||||
*/
|
*/
|
||||||
if (session->recv_seq) {
|
if (session->recv_seq) {
|
||||||
l2tp_warn(session, L2TP_MSG_SEQ,
|
pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
|
||||||
"%s: recv data has no seq numbers when required. Discarding.\n",
|
session->name);
|
||||||
session->name);
|
|
||||||
atomic_long_inc(&session->stats.rx_seq_discards);
|
atomic_long_inc(&session->stats.rx_seq_discards);
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
@ -746,15 +715,12 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
* LAC is broken. Discard the frame.
|
* LAC is broken. Discard the frame.
|
||||||
*/
|
*/
|
||||||
if (!session->lns_mode && session->send_seq) {
|
if (!session->lns_mode && session->send_seq) {
|
||||||
l2tp_info(session, L2TP_MSG_SEQ,
|
trace_session_seqnum_lns_disable(session);
|
||||||
"%s: requested to disable seq numbers by LNS\n",
|
|
||||||
session->name);
|
|
||||||
session->send_seq = 0;
|
session->send_seq = 0;
|
||||||
l2tp_session_set_header_len(session, tunnel->version);
|
l2tp_session_set_header_len(session, tunnel->version);
|
||||||
} else if (session->send_seq) {
|
} else if (session->send_seq) {
|
||||||
l2tp_warn(session, L2TP_MSG_SEQ,
|
pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
|
||||||
"%s: recv data has no seq numbers when required. Discarding.\n",
|
session->name);
|
||||||
session->name);
|
|
||||||
atomic_long_inc(&session->stats.rx_seq_discards);
|
atomic_long_inc(&session->stats.rx_seq_discards);
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
@ -847,22 +813,11 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
|
||||||
|
|
||||||
/* Short packet? */
|
/* Short packet? */
|
||||||
if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) {
|
if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) {
|
||||||
l2tp_info(tunnel, L2TP_MSG_DATA,
|
pr_warn_ratelimited("%s: recv short packet (len=%d)\n",
|
||||||
"%s: recv short packet (len=%d)\n",
|
tunnel->name, skb->len);
|
||||||
tunnel->name, skb->len);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trace packet contents, if enabled */
|
|
||||||
if (tunnel->debug & L2TP_MSG_DATA) {
|
|
||||||
length = min(32u, skb->len);
|
|
||||||
if (!pskb_may_pull(skb, length))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
pr_debug("%s: recv\n", tunnel->name);
|
|
||||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point to L2TP header */
|
/* Point to L2TP header */
|
||||||
optr = skb->data;
|
optr = skb->data;
|
||||||
ptr = skb->data;
|
ptr = skb->data;
|
||||||
|
@ -873,9 +828,8 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
|
||||||
/* Check protocol version */
|
/* Check protocol version */
|
||||||
version = hdrflags & L2TP_HDR_VER_MASK;
|
version = hdrflags & L2TP_HDR_VER_MASK;
|
||||||
if (version != tunnel->version) {
|
if (version != tunnel->version) {
|
||||||
l2tp_info(tunnel, L2TP_MSG_DATA,
|
pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
|
||||||
"%s: recv protocol version mismatch: got %d expected %d\n",
|
tunnel->name, version, tunnel->version);
|
||||||
tunnel->name, version, tunnel->version);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,12 +837,8 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
|
||||||
length = skb->len;
|
length = skb->len;
|
||||||
|
|
||||||
/* If type is control packet, it is handled by userspace. */
|
/* If type is control packet, it is handled by userspace. */
|
||||||
if (hdrflags & L2TP_HDRFLAG_T) {
|
if (hdrflags & L2TP_HDRFLAG_T)
|
||||||
l2tp_dbg(tunnel, L2TP_MSG_DATA,
|
|
||||||
"%s: recv control packet, len=%d\n",
|
|
||||||
tunnel->name, length);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip flags */
|
/* Skip flags */
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
|
@ -917,9 +867,8 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
|
||||||
l2tp_session_dec_refcount(session);
|
l2tp_session_dec_refcount(session);
|
||||||
|
|
||||||
/* Not found? Pass to userspace to deal with */
|
/* Not found? Pass to userspace to deal with */
|
||||||
l2tp_info(tunnel, L2TP_MSG_DATA,
|
pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n",
|
||||||
"%s: no session found (%u/%u). Passing up.\n",
|
tunnel->name, tunnel_id, session_id);
|
||||||
tunnel->name, tunnel_id, session_id);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,9 +902,6 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||||
if (!tunnel)
|
if (!tunnel)
|
||||||
goto pass_up;
|
goto pass_up;
|
||||||
|
|
||||||
l2tp_dbg(tunnel, L2TP_MSG_DATA, "%s: received %d bytes\n",
|
|
||||||
tunnel->name, skb->len);
|
|
||||||
|
|
||||||
if (l2tp_udp_recv_core(tunnel, skb))
|
if (l2tp_udp_recv_core(tunnel, skb))
|
||||||
goto pass_up;
|
goto pass_up;
|
||||||
|
|
||||||
|
@ -993,8 +939,7 @@ static int l2tp_build_l2tpv2_header(struct l2tp_session *session, void *buf)
|
||||||
*bufp++ = 0;
|
*bufp++ = 0;
|
||||||
session->ns++;
|
session->ns++;
|
||||||
session->ns &= 0xffff;
|
session->ns &= 0xffff;
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated ns to %u\n",
|
trace_session_seqnum_update(session);
|
||||||
session->name, session->ns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bufp - optr;
|
return bufp - optr;
|
||||||
|
@ -1030,9 +975,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
|
||||||
l2h = 0x40000000 | session->ns;
|
l2h = 0x40000000 | session->ns;
|
||||||
session->ns++;
|
session->ns++;
|
||||||
session->ns &= 0xffffff;
|
session->ns &= 0xffffff;
|
||||||
l2tp_dbg(session, L2TP_MSG_SEQ,
|
trace_session_seqnum_update(session);
|
||||||
"%s: updated ns to %u\n",
|
|
||||||
session->name, session->ns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*((__be32 *)bufp) = htonl(l2h);
|
*((__be32 *)bufp) = htonl(l2h);
|
||||||
|
@ -1049,23 +992,6 @@ static void l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
unsigned int len = skb->len;
|
unsigned int len = skb->len;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Debug */
|
|
||||||
if (session->send_seq)
|
|
||||||
l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %zd bytes, ns=%u\n",
|
|
||||||
session->name, data_len, session->ns - 1);
|
|
||||||
else
|
|
||||||
l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %zd bytes\n",
|
|
||||||
session->name, data_len);
|
|
||||||
|
|
||||||
if (session->debug & L2TP_MSG_DATA) {
|
|
||||||
int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
|
||||||
unsigned char *datap = skb->data + uhlen;
|
|
||||||
|
|
||||||
pr_debug("%s: xmit\n", session->name);
|
|
||||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
|
|
||||||
datap, min_t(size_t, 32, len - uhlen));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Queue the packet to IP for output */
|
/* Queue the packet to IP for output */
|
||||||
skb->ignore_df = 1;
|
skb->ignore_df = 1;
|
||||||
skb_dst_drop(skb);
|
skb_dst_drop(skb);
|
||||||
|
@ -1195,8 +1121,6 @@ static void l2tp_tunnel_destruct(struct sock *sk)
|
||||||
if (!tunnel)
|
if (!tunnel)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing...\n", tunnel->name);
|
|
||||||
|
|
||||||
/* Disable udp encapsulation */
|
/* Disable udp encapsulation */
|
||||||
switch (tunnel->encap) {
|
switch (tunnel->encap) {
|
||||||
case L2TP_ENCAPTYPE_UDP:
|
case L2TP_ENCAPTYPE_UDP:
|
||||||
|
@ -1255,9 +1179,6 @@ static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
|
||||||
struct hlist_node *tmp;
|
struct hlist_node *tmp;
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
|
|
||||||
l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing all sessions...\n",
|
|
||||||
tunnel->name);
|
|
||||||
|
|
||||||
write_lock_bh(&tunnel->hlist_lock);
|
write_lock_bh(&tunnel->hlist_lock);
|
||||||
tunnel->acpt_newsess = false;
|
tunnel->acpt_newsess = false;
|
||||||
for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
|
for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
|
||||||
|
@ -1265,9 +1186,6 @@ static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
|
||||||
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
|
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
|
||||||
session = hlist_entry(walk, struct l2tp_session, hlist);
|
session = hlist_entry(walk, struct l2tp_session, hlist);
|
||||||
|
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: closing session\n", session->name);
|
|
||||||
|
|
||||||
hlist_del_init(&session->hlist);
|
hlist_del_init(&session->hlist);
|
||||||
|
|
||||||
if (test_and_set_bit(0, &session->dead))
|
if (test_and_set_bit(0, &session->dead))
|
||||||
|
@ -1483,16 +1401,12 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
|
||||||
tunnel->version = version;
|
tunnel->version = version;
|
||||||
tunnel->tunnel_id = tunnel_id;
|
tunnel->tunnel_id = tunnel_id;
|
||||||
tunnel->peer_tunnel_id = peer_tunnel_id;
|
tunnel->peer_tunnel_id = peer_tunnel_id;
|
||||||
tunnel->debug = L2TP_DEFAULT_DEBUG_FLAGS;
|
|
||||||
|
|
||||||
tunnel->magic = L2TP_TUNNEL_MAGIC;
|
tunnel->magic = L2TP_TUNNEL_MAGIC;
|
||||||
sprintf(&tunnel->name[0], "tunl %u", tunnel_id);
|
sprintf(&tunnel->name[0], "tunl %u", tunnel_id);
|
||||||
rwlock_init(&tunnel->hlist_lock);
|
rwlock_init(&tunnel->hlist_lock);
|
||||||
tunnel->acpt_newsess = true;
|
tunnel->acpt_newsess = true;
|
||||||
|
|
||||||
if (cfg)
|
|
||||||
tunnel->debug = cfg->debug;
|
|
||||||
|
|
||||||
tunnel->encap = encap;
|
tunnel->encap = encap;
|
||||||
|
|
||||||
refcount_set(&tunnel->ref_count, 1);
|
refcount_set(&tunnel->ref_count, 1);
|
||||||
|
@ -1597,6 +1511,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
|
||||||
"l2tp_sock");
|
"l2tp_sock");
|
||||||
sk->sk_allocation = GFP_ATOMIC;
|
sk->sk_allocation = GFP_ATOMIC;
|
||||||
|
|
||||||
|
trace_register_tunnel(tunnel);
|
||||||
|
|
||||||
if (tunnel->fd >= 0)
|
if (tunnel->fd >= 0)
|
||||||
sockfd_put(sock);
|
sockfd_put(sock);
|
||||||
|
|
||||||
|
@ -1617,6 +1533,7 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_register);
|
||||||
void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
|
void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
|
||||||
{
|
{
|
||||||
if (!test_and_set_bit(0, &tunnel->dead)) {
|
if (!test_and_set_bit(0, &tunnel->dead)) {
|
||||||
|
trace_delete_tunnel(tunnel);
|
||||||
l2tp_tunnel_inc_refcount(tunnel);
|
l2tp_tunnel_inc_refcount(tunnel);
|
||||||
queue_work(l2tp_wq, &tunnel->del_work);
|
queue_work(l2tp_wq, &tunnel->del_work);
|
||||||
}
|
}
|
||||||
|
@ -1628,6 +1545,7 @@ void l2tp_session_delete(struct l2tp_session *session)
|
||||||
if (test_and_set_bit(0, &session->dead))
|
if (test_and_set_bit(0, &session->dead))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
trace_delete_session(session);
|
||||||
l2tp_session_unhash(session);
|
l2tp_session_unhash(session);
|
||||||
l2tp_session_queue_purge(session);
|
l2tp_session_queue_purge(session);
|
||||||
if (session->session_close)
|
if (session->session_close)
|
||||||
|
@ -1686,12 +1604,8 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
|
||||||
INIT_HLIST_NODE(&session->hlist);
|
INIT_HLIST_NODE(&session->hlist);
|
||||||
INIT_HLIST_NODE(&session->global_hlist);
|
INIT_HLIST_NODE(&session->global_hlist);
|
||||||
|
|
||||||
/* Inherit debug options from tunnel */
|
|
||||||
session->debug = tunnel->debug;
|
|
||||||
|
|
||||||
if (cfg) {
|
if (cfg) {
|
||||||
session->pwtype = cfg->pw_type;
|
session->pwtype = cfg->pw_type;
|
||||||
session->debug = cfg->debug;
|
|
||||||
session->send_seq = cfg->send_seq;
|
session->send_seq = cfg->send_seq;
|
||||||
session->recv_seq = cfg->recv_seq;
|
session->recv_seq = cfg->recv_seq;
|
||||||
session->lns_mode = cfg->lns_mode;
|
session->lns_mode = cfg->lns_mode;
|
||||||
|
|
|
@ -51,7 +51,6 @@ struct l2tp_session_cfg {
|
||||||
unsigned int lns_mode:1; /* behave as LNS?
|
unsigned int lns_mode:1; /* behave as LNS?
|
||||||
* LAC enables sequence numbers under LNS control.
|
* LAC enables sequence numbers under LNS control.
|
||||||
*/
|
*/
|
||||||
int debug; /* bitmask of debug message categories */
|
|
||||||
u16 l2specific_type; /* Layer 2 specific type */
|
u16 l2specific_type; /* Layer 2 specific type */
|
||||||
u8 cookie[8]; /* optional cookie */
|
u8 cookie[8]; /* optional cookie */
|
||||||
int cookie_len; /* 0, 4 or 8 bytes */
|
int cookie_len; /* 0, 4 or 8 bytes */
|
||||||
|
@ -66,6 +65,7 @@ struct l2tp_session_cfg {
|
||||||
* Is linked into a per-tunnel session hashlist; and in the case of an L2TPv3 session into
|
* Is linked into a per-tunnel session hashlist; and in the case of an L2TPv3 session into
|
||||||
* an additional per-net ("global") hashlist.
|
* an additional per-net ("global") hashlist.
|
||||||
*/
|
*/
|
||||||
|
#define L2TP_SESSION_NAME_MAX 32
|
||||||
struct l2tp_session {
|
struct l2tp_session {
|
||||||
int magic; /* should be L2TP_SESSION_MAGIC */
|
int magic; /* should be L2TP_SESSION_MAGIC */
|
||||||
long dead;
|
long dead;
|
||||||
|
@ -90,14 +90,13 @@ struct l2tp_session {
|
||||||
struct hlist_node hlist; /* hash list node */
|
struct hlist_node hlist; /* hash list node */
|
||||||
refcount_t ref_count;
|
refcount_t ref_count;
|
||||||
|
|
||||||
char name[32]; /* for logging */
|
char name[L2TP_SESSION_NAME_MAX]; /* for logging */
|
||||||
char ifname[IFNAMSIZ];
|
char ifname[IFNAMSIZ];
|
||||||
unsigned int recv_seq:1; /* expect receive packets with sequence numbers? */
|
unsigned int recv_seq:1; /* expect receive packets with sequence numbers? */
|
||||||
unsigned int send_seq:1; /* send packets with sequence numbers? */
|
unsigned int send_seq:1; /* send packets with sequence numbers? */
|
||||||
unsigned int lns_mode:1; /* behave as LNS?
|
unsigned int lns_mode:1; /* behave as LNS?
|
||||||
* LAC enables sequence numbers under LNS control.
|
* LAC enables sequence numbers under LNS control.
|
||||||
*/
|
*/
|
||||||
int debug; /* bitmask of debug message categories */
|
|
||||||
int reorder_timeout; /* configured reorder timeout (in jiffies) */
|
int reorder_timeout; /* configured reorder timeout (in jiffies) */
|
||||||
int reorder_skip; /* set if skip to next nr */
|
int reorder_skip; /* set if skip to next nr */
|
||||||
enum l2tp_pwtype pwtype;
|
enum l2tp_pwtype pwtype;
|
||||||
|
@ -131,7 +130,6 @@ struct l2tp_session {
|
||||||
|
|
||||||
/* L2TP tunnel configuration */
|
/* L2TP tunnel configuration */
|
||||||
struct l2tp_tunnel_cfg {
|
struct l2tp_tunnel_cfg {
|
||||||
int debug; /* bitmask of debug message categories */
|
|
||||||
enum l2tp_encap_type encap;
|
enum l2tp_encap_type encap;
|
||||||
|
|
||||||
/* Used only for kernel-created sockets */
|
/* Used only for kernel-created sockets */
|
||||||
|
@ -154,6 +152,7 @@ struct l2tp_tunnel_cfg {
|
||||||
* Maintains a hashlist of sessions belonging to the tunnel instance.
|
* Maintains a hashlist of sessions belonging to the tunnel instance.
|
||||||
* Is linked into a per-net list of tunnels.
|
* Is linked into a per-net list of tunnels.
|
||||||
*/
|
*/
|
||||||
|
#define L2TP_TUNNEL_NAME_MAX 20
|
||||||
struct l2tp_tunnel {
|
struct l2tp_tunnel {
|
||||||
int magic; /* Should be L2TP_TUNNEL_MAGIC */
|
int magic; /* Should be L2TP_TUNNEL_MAGIC */
|
||||||
|
|
||||||
|
@ -170,8 +169,7 @@ struct l2tp_tunnel {
|
||||||
u32 peer_tunnel_id;
|
u32 peer_tunnel_id;
|
||||||
int version; /* 2=>L2TPv2, 3=>L2TPv3 */
|
int version; /* 2=>L2TPv2, 3=>L2TPv3 */
|
||||||
|
|
||||||
char name[20]; /* for logging */
|
char name[L2TP_TUNNEL_NAME_MAX]; /* for logging */
|
||||||
int debug; /* bitmask of debug message categories */
|
|
||||||
enum l2tp_encap_type encap;
|
enum l2tp_encap_type encap;
|
||||||
struct l2tp_stats stats;
|
struct l2tp_stats stats;
|
||||||
|
|
||||||
|
@ -337,19 +335,6 @@ static inline int l2tp_v3_ensure_opt_in_linear(struct l2tp_session *session, str
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define l2tp_printk(ptr, type, func, fmt, ...) \
|
|
||||||
do { \
|
|
||||||
if (((ptr)->debug) & (type)) \
|
|
||||||
func(fmt, ##__VA_ARGS__); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define l2tp_warn(ptr, type, fmt, ...) \
|
|
||||||
l2tp_printk(ptr, type, pr_warn, fmt, ##__VA_ARGS__)
|
|
||||||
#define l2tp_info(ptr, type, fmt, ...) \
|
|
||||||
l2tp_printk(ptr, type, pr_info, fmt, ##__VA_ARGS__)
|
|
||||||
#define l2tp_dbg(ptr, type, fmt, ...) \
|
|
||||||
l2tp_printk(ptr, type, pr_debug, fmt, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
#define MODULE_ALIAS_L2TP_PWTYPE(type) \
|
#define MODULE_ALIAS_L2TP_PWTYPE(type) \
|
||||||
MODULE_ALIAS("net-l2tp-type-" __stringify(type))
|
MODULE_ALIAS("net-l2tp-type-" __stringify(type))
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
|
||||||
tunnel->sock ? refcount_read(&tunnel->sock->sk_refcnt) : 0,
|
tunnel->sock ? refcount_read(&tunnel->sock->sk_refcnt) : 0,
|
||||||
refcount_read(&tunnel->ref_count));
|
refcount_read(&tunnel->ref_count));
|
||||||
seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
|
seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
|
||||||
tunnel->debug,
|
0,
|
||||||
atomic_long_read(&tunnel->stats.tx_packets),
|
atomic_long_read(&tunnel->stats.tx_packets),
|
||||||
atomic_long_read(&tunnel->stats.tx_bytes),
|
atomic_long_read(&tunnel->stats.tx_bytes),
|
||||||
atomic_long_read(&tunnel->stats.tx_errors),
|
atomic_long_read(&tunnel->stats.tx_errors),
|
||||||
|
@ -192,7 +192,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
|
||||||
session->recv_seq ? 'R' : '-',
|
session->recv_seq ? 'R' : '-',
|
||||||
session->send_seq ? 'S' : '-',
|
session->send_seq ? 'S' : '-',
|
||||||
session->lns_mode ? "LNS" : "LAC",
|
session->lns_mode ? "LNS" : "LAC",
|
||||||
session->debug,
|
0,
|
||||||
jiffies_to_msecs(session->reorder_timeout));
|
jiffies_to_msecs(session->reorder_timeout));
|
||||||
seq_printf(m, " offset 0 l2specific %hu/%hu\n",
|
seq_printf(m, " offset 0 l2specific %hu/%hu\n",
|
||||||
session->l2specific_type, l2tp_get_l2specific_len(session));
|
session->l2specific_type, l2tp_get_l2specific_len(session));
|
||||||
|
|
|
@ -128,17 +128,6 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct l2tp_eth *priv;
|
struct l2tp_eth *priv;
|
||||||
|
|
||||||
if (session->debug & L2TP_MSG_DATA) {
|
|
||||||
unsigned int length;
|
|
||||||
|
|
||||||
length = min(32u, skb->len);
|
|
||||||
if (!pskb_may_pull(skb, length))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
pr_debug("%s: eth recv\n", session->name);
|
|
||||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, ETH_HLEN))
|
if (!pskb_may_pull(skb, ETH_HLEN))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,6 @@ static int l2tp_ip_recv(struct sk_buff *skb)
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel = NULL;
|
struct l2tp_tunnel *tunnel = NULL;
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
int length;
|
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, 4))
|
if (!pskb_may_pull(skb, 4))
|
||||||
goto discard;
|
goto discard;
|
||||||
|
@ -147,20 +146,6 @@ static int l2tp_ip_recv(struct sk_buff *skb)
|
||||||
if (!tunnel)
|
if (!tunnel)
|
||||||
goto discard_sess;
|
goto discard_sess;
|
||||||
|
|
||||||
/* Trace packet contents, if enabled */
|
|
||||||
if (tunnel->debug & L2TP_MSG_DATA) {
|
|
||||||
length = min(32u, skb->len);
|
|
||||||
if (!pskb_may_pull(skb, length))
|
|
||||||
goto discard_sess;
|
|
||||||
|
|
||||||
/* Point to L2TP header */
|
|
||||||
optr = skb->data;
|
|
||||||
ptr = skb->data;
|
|
||||||
ptr += 4;
|
|
||||||
pr_debug("%s: ip recv\n", tunnel->name);
|
|
||||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
|
if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
|
||||||
goto discard_sess;
|
goto discard_sess;
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,6 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel = NULL;
|
struct l2tp_tunnel *tunnel = NULL;
|
||||||
struct ipv6hdr *iph;
|
struct ipv6hdr *iph;
|
||||||
int length;
|
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, 4))
|
if (!pskb_may_pull(skb, 4))
|
||||||
goto discard;
|
goto discard;
|
||||||
|
@ -160,20 +159,6 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
|
||||||
if (!tunnel)
|
if (!tunnel)
|
||||||
goto discard_sess;
|
goto discard_sess;
|
||||||
|
|
||||||
/* Trace packet contents, if enabled */
|
|
||||||
if (tunnel->debug & L2TP_MSG_DATA) {
|
|
||||||
length = min(32u, skb->len);
|
|
||||||
if (!pskb_may_pull(skb, length))
|
|
||||||
goto discard_sess;
|
|
||||||
|
|
||||||
/* Point to L2TP header */
|
|
||||||
optr = skb->data;
|
|
||||||
ptr = skb->data;
|
|
||||||
ptr += 4;
|
|
||||||
pr_debug("%s: ip recv\n", tunnel->name);
|
|
||||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
|
if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
|
||||||
goto discard_sess;
|
goto discard_sess;
|
||||||
|
|
||||||
|
|
|
@ -229,9 +229,6 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs[L2TP_ATTR_DEBUG])
|
|
||||||
cfg.debug = nla_get_u32(attrs[L2TP_ATTR_DEBUG]);
|
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
switch (cfg.encap) {
|
switch (cfg.encap) {
|
||||||
case L2TP_ENCAPTYPE_UDP:
|
case L2TP_ENCAPTYPE_UDP:
|
||||||
|
@ -307,9 +304,6 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[L2TP_ATTR_DEBUG])
|
|
||||||
tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
|
|
||||||
|
|
||||||
ret = l2tp_tunnel_notify(&l2tp_nl_family, info,
|
ret = l2tp_tunnel_notify(&l2tp_nl_family, info,
|
||||||
tunnel, L2TP_CMD_TUNNEL_MODIFY);
|
tunnel, L2TP_CMD_TUNNEL_MODIFY);
|
||||||
|
|
||||||
|
@ -400,7 +394,7 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
|
||||||
if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) ||
|
if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
|
nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
|
nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_DEBUG, tunnel->debug) ||
|
nla_put_u32(skb, L2TP_ATTR_DEBUG, 0) ||
|
||||||
nla_put_u16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap))
|
nla_put_u16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
@ -605,9 +599,6 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
||||||
cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
|
cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[L2TP_ATTR_DEBUG])
|
|
||||||
cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
|
|
||||||
|
|
||||||
if (info->attrs[L2TP_ATTR_RECV_SEQ])
|
if (info->attrs[L2TP_ATTR_RECV_SEQ])
|
||||||
cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
|
cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
|
||||||
|
|
||||||
|
@ -689,9 +680,6 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[L2TP_ATTR_DEBUG])
|
|
||||||
session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
|
|
||||||
|
|
||||||
if (info->attrs[L2TP_ATTR_RECV_SEQ])
|
if (info->attrs[L2TP_ATTR_RECV_SEQ])
|
||||||
session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
|
session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
|
||||||
|
|
||||||
|
@ -730,7 +718,7 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
|
||||||
nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) ||
|
nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
|
nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id) ||
|
nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id) ||
|
||||||
nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) ||
|
nla_put_u32(skb, L2TP_ATTR_DEBUG, 0) ||
|
||||||
nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype))
|
nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
|
|
@ -237,17 +237,9 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int
|
||||||
if (sk->sk_state & PPPOX_BOUND) {
|
if (sk->sk_state & PPPOX_BOUND) {
|
||||||
struct pppox_sock *po;
|
struct pppox_sock *po;
|
||||||
|
|
||||||
l2tp_dbg(session, L2TP_MSG_DATA,
|
|
||||||
"%s: recv %d byte data frame, passing to ppp\n",
|
|
||||||
session->name, data_len);
|
|
||||||
|
|
||||||
po = pppox_sk(sk);
|
po = pppox_sk(sk);
|
||||||
ppp_input(&po->chan, skb);
|
ppp_input(&po->chan, skb);
|
||||||
} else {
|
} else {
|
||||||
l2tp_dbg(session, L2TP_MSG_DATA,
|
|
||||||
"%s: recv %d byte data frame, passing to L2TP socket\n",
|
|
||||||
session->name, data_len);
|
|
||||||
|
|
||||||
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
||||||
atomic_long_inc(&session->stats.rx_errors);
|
atomic_long_inc(&session->stats.rx_errors);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -259,7 +251,7 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int
|
||||||
|
|
||||||
no_sock:
|
no_sock:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
l2tp_info(session, L2TP_MSG_DATA, "%s: no socket\n", session->name);
|
pr_warn_ratelimited("%s: no socket in recv\n", session->name);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +702,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
||||||
if (!tunnel) {
|
if (!tunnel) {
|
||||||
struct l2tp_tunnel_cfg tcfg = {
|
struct l2tp_tunnel_cfg tcfg = {
|
||||||
.encap = L2TP_ENCAPTYPE_UDP,
|
.encap = L2TP_ENCAPTYPE_UDP,
|
||||||
.debug = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Prevent l2tp_tunnel_register() from trying to set up
|
/* Prevent l2tp_tunnel_register() from trying to set up
|
||||||
|
@ -840,8 +831,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
||||||
drop_refcnt = false;
|
drop_refcnt = false;
|
||||||
|
|
||||||
sk->sk_state = PPPOX_CONNECTED;
|
sk->sk_state = PPPOX_CONNECTED;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n",
|
|
||||||
session->name);
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -1157,9 +1146,7 @@ static int pppol2tp_tunnel_setsockopt(struct sock *sk,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case PPPOL2TP_SO_DEBUG:
|
case PPPOL2TP_SO_DEBUG:
|
||||||
tunnel->debug = val;
|
/* Tunnel debug flags option is deprecated */
|
||||||
l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: set debug=%x\n",
|
|
||||||
tunnel->name, tunnel->debug);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1185,9 +1172,6 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
session->recv_seq = !!val;
|
session->recv_seq = !!val;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: set recv_seq=%d\n",
|
|
||||||
session->name, session->recv_seq);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_SENDSEQ:
|
case PPPOL2TP_SO_SENDSEQ:
|
||||||
|
@ -1203,9 +1187,6 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
|
||||||
PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
|
PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
|
||||||
}
|
}
|
||||||
l2tp_session_set_header_len(session, session->tunnel->version);
|
l2tp_session_set_header_len(session, session->tunnel->version);
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: set send_seq=%d\n",
|
|
||||||
session->name, session->send_seq);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_LNSMODE:
|
case PPPOL2TP_SO_LNSMODE:
|
||||||
|
@ -1214,22 +1195,14 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
session->lns_mode = !!val;
|
session->lns_mode = !!val;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: set lns_mode=%d\n",
|
|
||||||
session->name, session->lns_mode);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_DEBUG:
|
case PPPOL2TP_SO_DEBUG:
|
||||||
session->debug = val;
|
/* Session debug flags option is deprecated */
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL, "%s: set debug=%x\n",
|
|
||||||
session->name, session->debug);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_REORDERTO:
|
case PPPOL2TP_SO_REORDERTO:
|
||||||
session->reorder_timeout = msecs_to_jiffies(val);
|
session->reorder_timeout = msecs_to_jiffies(val);
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: set reorder_timeout=%d\n",
|
|
||||||
session->name, session->reorder_timeout);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1297,9 +1270,8 @@ static int pppol2tp_tunnel_getsockopt(struct sock *sk,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case PPPOL2TP_SO_DEBUG:
|
case PPPOL2TP_SO_DEBUG:
|
||||||
*val = tunnel->debug;
|
/* Tunnel debug flags option is deprecated */
|
||||||
l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: get debug=%x\n",
|
*val = 0;
|
||||||
tunnel->name, tunnel->debug);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1321,32 +1293,23 @@ static int pppol2tp_session_getsockopt(struct sock *sk,
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case PPPOL2TP_SO_RECVSEQ:
|
case PPPOL2TP_SO_RECVSEQ:
|
||||||
*val = session->recv_seq;
|
*val = session->recv_seq;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: get recv_seq=%d\n", session->name, *val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_SENDSEQ:
|
case PPPOL2TP_SO_SENDSEQ:
|
||||||
*val = session->send_seq;
|
*val = session->send_seq;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: get send_seq=%d\n", session->name, *val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_LNSMODE:
|
case PPPOL2TP_SO_LNSMODE:
|
||||||
*val = session->lns_mode;
|
*val = session->lns_mode;
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: get lns_mode=%d\n", session->name, *val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_DEBUG:
|
case PPPOL2TP_SO_DEBUG:
|
||||||
*val = session->debug;
|
/* Session debug flags option is deprecated */
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL, "%s: get debug=%d\n",
|
*val = 0;
|
||||||
session->name, *val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPOL2TP_SO_REORDERTO:
|
case PPPOL2TP_SO_REORDERTO:
|
||||||
*val = (int)jiffies_to_msecs(session->reorder_timeout);
|
*val = (int)jiffies_to_msecs(session->reorder_timeout);
|
||||||
l2tp_info(session, L2TP_MSG_CONTROL,
|
|
||||||
"%s: get reorder_timeout=%d\n", session->name, *val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1534,7 +1497,7 @@ static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
|
||||||
(tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N',
|
(tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N',
|
||||||
refcount_read(&tunnel->ref_count) - 1);
|
refcount_read(&tunnel->ref_count) - 1);
|
||||||
seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n",
|
seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n",
|
||||||
tunnel->debug,
|
0,
|
||||||
atomic_long_read(&tunnel->stats.tx_packets),
|
atomic_long_read(&tunnel->stats.tx_packets),
|
||||||
atomic_long_read(&tunnel->stats.tx_bytes),
|
atomic_long_read(&tunnel->stats.tx_bytes),
|
||||||
atomic_long_read(&tunnel->stats.tx_errors),
|
atomic_long_read(&tunnel->stats.tx_errors),
|
||||||
|
@ -1580,7 +1543,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
|
||||||
session->recv_seq ? 'R' : '-',
|
session->recv_seq ? 'R' : '-',
|
||||||
session->send_seq ? 'S' : '-',
|
session->send_seq ? 'S' : '-',
|
||||||
session->lns_mode ? "LNS" : "LAC",
|
session->lns_mode ? "LNS" : "LAC",
|
||||||
session->debug,
|
0,
|
||||||
jiffies_to_msecs(session->reorder_timeout));
|
jiffies_to_msecs(session->reorder_timeout));
|
||||||
seq_printf(m, " %hu/%hu %ld/%ld/%ld %ld/%ld/%ld\n",
|
seq_printf(m, " %hu/%hu %ld/%ld/%ld %ld/%ld/%ld\n",
|
||||||
session->nr, session->ns,
|
session->nr, session->ns,
|
||||||
|
|
211
net/l2tp/trace.h
Normal file
211
net/l2tp/trace.h
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#undef TRACE_SYSTEM
|
||||||
|
#define TRACE_SYSTEM l2tp
|
||||||
|
|
||||||
|
#if !defined(_TRACE_L2TP_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
|
#define _TRACE_L2TP_H
|
||||||
|
|
||||||
|
#include <linux/tracepoint.h>
|
||||||
|
#include <linux/l2tp.h>
|
||||||
|
#include "l2tp_core.h"
|
||||||
|
|
||||||
|
#define encap_type_name(e) { L2TP_ENCAPTYPE_##e, #e }
|
||||||
|
#define show_encap_type_name(val) \
|
||||||
|
__print_symbolic(val, \
|
||||||
|
encap_type_name(UDP), \
|
||||||
|
encap_type_name(IP))
|
||||||
|
|
||||||
|
#define pw_type_name(p) { L2TP_PWTYPE_##p, #p }
|
||||||
|
#define show_pw_type_name(val) \
|
||||||
|
__print_symbolic(val, \
|
||||||
|
pw_type_name(ETH_VLAN), \
|
||||||
|
pw_type_name(ETH), \
|
||||||
|
pw_type_name(PPP), \
|
||||||
|
pw_type_name(PPP_AC), \
|
||||||
|
pw_type_name(IP))
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(tunnel_only_evt,
|
||||||
|
TP_PROTO(struct l2tp_tunnel *tunnel),
|
||||||
|
TP_ARGS(tunnel),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_TUNNEL_NAME_MAX)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, tunnel->name, L2TP_TUNNEL_NAME_MAX);
|
||||||
|
),
|
||||||
|
TP_printk("%s", __entry->name)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(session_only_evt,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_SESSION_NAME_MAX)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, session->name, L2TP_SESSION_NAME_MAX);
|
||||||
|
),
|
||||||
|
TP_printk("%s", __entry->name)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(register_tunnel,
|
||||||
|
TP_PROTO(struct l2tp_tunnel *tunnel),
|
||||||
|
TP_ARGS(tunnel),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_TUNNEL_NAME_MAX)
|
||||||
|
__field(int, fd)
|
||||||
|
__field(u32, tid)
|
||||||
|
__field(u32, ptid)
|
||||||
|
__field(int, version)
|
||||||
|
__field(enum l2tp_encap_type, encap)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, tunnel->name, L2TP_TUNNEL_NAME_MAX);
|
||||||
|
__entry->fd = tunnel->fd;
|
||||||
|
__entry->tid = tunnel->tunnel_id;
|
||||||
|
__entry->ptid = tunnel->peer_tunnel_id;
|
||||||
|
__entry->version = tunnel->version;
|
||||||
|
__entry->encap = tunnel->encap;
|
||||||
|
),
|
||||||
|
TP_printk("%s: type=%s encap=%s version=L2TPv%d tid=%u ptid=%u fd=%d",
|
||||||
|
__entry->name,
|
||||||
|
__entry->fd > 0 ? "managed" : "unmanaged",
|
||||||
|
show_encap_type_name(__entry->encap),
|
||||||
|
__entry->version,
|
||||||
|
__entry->tid,
|
||||||
|
__entry->ptid,
|
||||||
|
__entry->fd)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(tunnel_only_evt, delete_tunnel,
|
||||||
|
TP_PROTO(struct l2tp_tunnel *tunnel),
|
||||||
|
TP_ARGS(tunnel)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(tunnel_only_evt, free_tunnel,
|
||||||
|
TP_PROTO(struct l2tp_tunnel *tunnel),
|
||||||
|
TP_ARGS(tunnel)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(register_session,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_SESSION_NAME_MAX)
|
||||||
|
__field(u32, tid)
|
||||||
|
__field(u32, ptid)
|
||||||
|
__field(u32, sid)
|
||||||
|
__field(u32, psid)
|
||||||
|
__field(enum l2tp_pwtype, pwtype)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, session->name, L2TP_SESSION_NAME_MAX);
|
||||||
|
__entry->tid = session->tunnel ? session->tunnel->tunnel_id : 0;
|
||||||
|
__entry->ptid = session->tunnel ? session->tunnel->peer_tunnel_id : 0;
|
||||||
|
__entry->sid = session->session_id;
|
||||||
|
__entry->psid = session->peer_session_id;
|
||||||
|
__entry->pwtype = session->pwtype;
|
||||||
|
),
|
||||||
|
TP_printk("%s: pseudowire=%s sid=%u psid=%u tid=%u ptid=%u",
|
||||||
|
__entry->name,
|
||||||
|
show_pw_type_name(__entry->pwtype),
|
||||||
|
__entry->sid,
|
||||||
|
__entry->psid,
|
||||||
|
__entry->sid,
|
||||||
|
__entry->psid)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_only_evt, delete_session,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_only_evt, free_session,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_only_evt, session_seqnum_lns_enable,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_only_evt, session_seqnum_lns_disable,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(session_seqnum_evt,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_SESSION_NAME_MAX)
|
||||||
|
__field(u32, ns)
|
||||||
|
__field(u32, nr)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, session->name, L2TP_SESSION_NAME_MAX);
|
||||||
|
__entry->ns = session->ns;
|
||||||
|
__entry->nr = session->nr;
|
||||||
|
),
|
||||||
|
TP_printk("%s: ns=%u nr=%u",
|
||||||
|
__entry->name,
|
||||||
|
__entry->ns,
|
||||||
|
__entry->nr)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_seqnum_evt, session_seqnum_update,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_seqnum_evt, session_seqnum_reset,
|
||||||
|
TP_PROTO(struct l2tp_session *session),
|
||||||
|
TP_ARGS(session)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(session_pkt_discard_evt,
|
||||||
|
TP_PROTO(struct l2tp_session *session, u32 pkt_ns),
|
||||||
|
TP_ARGS(session, pkt_ns),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__array(char, name, L2TP_SESSION_NAME_MAX)
|
||||||
|
__field(u32, pkt_ns)
|
||||||
|
__field(u32, my_nr)
|
||||||
|
__field(u32, reorder_q_len)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
memcpy(__entry->name, session->name, L2TP_SESSION_NAME_MAX);
|
||||||
|
__entry->pkt_ns = pkt_ns,
|
||||||
|
__entry->my_nr = session->nr;
|
||||||
|
__entry->reorder_q_len = skb_queue_len(&session->reorder_q);
|
||||||
|
),
|
||||||
|
TP_printk("%s: pkt_ns=%u my_nr=%u reorder_q_len=%u",
|
||||||
|
__entry->name,
|
||||||
|
__entry->pkt_ns,
|
||||||
|
__entry->my_nr,
|
||||||
|
__entry->reorder_q_len)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_pkt_discard_evt, session_pkt_expired,
|
||||||
|
TP_PROTO(struct l2tp_session *session, u32 pkt_ns),
|
||||||
|
TP_ARGS(session, pkt_ns)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_pkt_discard_evt, session_pkt_outside_rx_window,
|
||||||
|
TP_PROTO(struct l2tp_session *session, u32 pkt_ns),
|
||||||
|
TP_ARGS(session, pkt_ns)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(session_pkt_discard_evt, session_pkt_oos,
|
||||||
|
TP_PROTO(struct l2tp_session *session, u32 pkt_ns),
|
||||||
|
TP_ARGS(session, pkt_ns)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* _TRACE_L2TP_H */
|
||||||
|
|
||||||
|
/* This part must be outside protection */
|
||||||
|
#undef TRACE_INCLUDE_PATH
|
||||||
|
#define TRACE_INCLUDE_PATH .
|
||||||
|
#undef TRACE_INCLUDE_FILE
|
||||||
|
#define TRACE_INCLUDE_FILE trace
|
||||||
|
#include <trace/define_trace.h>
|
Loading…
Reference in a new issue