Skip to content

Commit

Permalink
net: l2tp: reduce log level of messages in receive path, add counter …
Browse files Browse the repository at this point in the history
…instead

commit 3e59e88 upstream.

Commit 5ee759c ("l2tp: use standard API for warning log messages")
changed a number of warnings about invalid packets in the receive path
so that they are always shown, instead of only when a special L2TP debug
flag is set. Even with rate limiting these warnings can easily cause
significant log spam - potentially triggered by a malicious party
sending invalid packets on purpose.

In addition these warnings were noticed by projects like Tunneldigger [1],
which uses L2TP for its data path, but implements its own control
protocol (which is sufficiently different from L2TP data packets that it
would always be passed up to userspace even with future extensions of
L2TP).

Some of the warnings were already redundant, as l2tp_stats has a counter
for these packets. This commit adds one additional counter for invalid
packets that are passed up to userspace. Packets with unknown session are
not counted as invalid, as there is nothing wrong with the format of
these packets.

With the additional counter, all of these messages are either redundant
or benign, so we reduce them to pr_debug_ratelimited().

[1] wlanslovenija/tunneldigger#160

Fixes: 5ee759c ("l2tp: use standard API for warning log messages")
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
neocturne authored and gregkh committed Mar 17, 2021
1 parent edb24de commit 9144b0c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 19 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/l2tp.h
Expand Up @@ -145,6 +145,7 @@ enum {
L2TP_ATTR_RX_ERRORS, /* u64 */
L2TP_ATTR_STATS_PAD,
L2TP_ATTR_RX_COOKIE_DISCARDS, /* u64 */
L2TP_ATTR_RX_INVALID, /* u64 */
__L2TP_ATTR_STATS_MAX,
};

Expand Down
41 changes: 22 additions & 19 deletions net/l2tp/l2tp_core.c
Expand Up @@ -649,9 +649,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
/* Parse and check optional cookie */
if (session->peer_cookie_len > 0) {
if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
tunnel->name, tunnel->tunnel_id,
session->session_id);
pr_debug_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
tunnel->name, tunnel->tunnel_id,
session->session_id);
atomic_long_inc(&session->stats.rx_cookie_discards);
goto discard;
}
Expand Down Expand Up @@ -702,8 +702,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
* If user has configured mandatory sequence numbers, discard.
*/
if (session->recv_seq) {
pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
session->name);
pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
session->name);
atomic_long_inc(&session->stats.rx_seq_discards);
goto discard;
}
Expand All @@ -718,8 +718,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
session->send_seq = 0;
l2tp_session_set_header_len(session, tunnel->version);
} else if (session->send_seq) {
pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
session->name);
pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
session->name);
atomic_long_inc(&session->stats.rx_seq_discards);
goto discard;
}
Expand Down Expand Up @@ -809,9 +809,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)

/* Short packet? */
if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) {
pr_warn_ratelimited("%s: recv short packet (len=%d)\n",
tunnel->name, skb->len);
goto error;
pr_debug_ratelimited("%s: recv short packet (len=%d)\n",
tunnel->name, skb->len);
goto invalid;
}

/* Point to L2TP header */
Expand All @@ -824,17 +824,17 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
/* Check protocol version */
version = hdrflags & L2TP_HDR_VER_MASK;
if (version != tunnel->version) {
pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
tunnel->name, version, tunnel->version);
goto error;
pr_debug_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
tunnel->name, version, tunnel->version);
goto invalid;
}

/* Get length of L2TP packet */
length = skb->len;

/* If type is control packet, it is handled by userspace. */
if (hdrflags & L2TP_HDRFLAG_T)
goto error;
goto pass;

/* Skip flags */
ptr += 2;
Expand Down Expand Up @@ -863,21 +863,24 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
l2tp_session_dec_refcount(session);

/* Not found? Pass to userspace to deal with */
pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n",
tunnel->name, tunnel_id, session_id);
goto error;
pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n",
tunnel->name, tunnel_id, session_id);
goto pass;
}

if (tunnel->version == L2TP_HDR_VER_3 &&
l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
goto error;
goto invalid;

l2tp_recv_common(session, skb, ptr, optr, hdrflags, length);
l2tp_session_dec_refcount(session);

return 0;

error:
invalid:
atomic_long_inc(&tunnel->stats.rx_invalid);

pass:
/* Put UDP header back */
__skb_push(skb, sizeof(struct udphdr));

Expand Down
1 change: 1 addition & 0 deletions net/l2tp/l2tp_core.h
Expand Up @@ -39,6 +39,7 @@ struct l2tp_stats {
atomic_long_t rx_oos_packets;
atomic_long_t rx_errors;
atomic_long_t rx_cookie_discards;
atomic_long_t rx_invalid;
};

struct l2tp_tunnel;
Expand Down
6 changes: 6 additions & 0 deletions net/l2tp/l2tp_netlink.c
Expand Up @@ -428,6 +428,9 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
L2TP_ATTR_STATS_PAD) ||
nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
atomic_long_read(&tunnel->stats.rx_errors),
L2TP_ATTR_STATS_PAD) ||
nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
atomic_long_read(&tunnel->stats.rx_invalid),
L2TP_ATTR_STATS_PAD))
goto nla_put_failure;
nla_nest_end(skb, nest);
Expand Down Expand Up @@ -771,6 +774,9 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
L2TP_ATTR_STATS_PAD) ||
nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
atomic_long_read(&session->stats.rx_errors),
L2TP_ATTR_STATS_PAD) ||
nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
atomic_long_read(&session->stats.rx_invalid),
L2TP_ATTR_STATS_PAD))
goto nla_put_failure;
nla_nest_end(skb, nest);
Expand Down

0 comments on commit 9144b0c

Please sign in to comment.