Commit 58d6085c authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

l2tp: Remove UDP checksum verification

Validating the UDP checksum is now done in UDP before handing
packets to the encapsulation layer. Note that this also eliminates
the "feature" where L2TP can ignore a non-zero UDP checksum (doing
this was contrary to RFC 1122).
Signed-off-by: default avatarTom Herbert <therbert@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0a80966b
......@@ -495,52 +495,6 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
spin_unlock_bh(&session->reorder_q.lock);
}
static inline int l2tp_verify_udp_checksum(struct sock *sk,
struct sk_buff *skb)
{
struct udphdr *uh = udp_hdr(skb);
u16 ulen = ntohs(uh->len);
__wsum psum;
if (sk->sk_no_check || skb_csum_unnecessary(skb))
return 0;
#if IS_ENABLED(CONFIG_IPV6)
if (sk->sk_family == PF_INET6 && !l2tp_tunnel(sk)->v4mapped) {
if (!uh->check) {
LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n");
return 1;
}
if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
!csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr, ulen,
IPPROTO_UDP, skb->csum)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
return 0;
}
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr,
skb->len, IPPROTO_UDP,
0));
} else
#endif
{
struct inet_sock *inet;
if (!uh->check)
return 0;
inet = inet_sk(sk);
psum = csum_tcpudp_nofold(inet->inet_saddr, inet->inet_daddr,
ulen, IPPROTO_UDP, 0);
if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
!csum_fold(csum_add(psum, skb->csum)))
return 0;
skb->csum = psum;
}
return __skb_checksum_complete(skb);
}
static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr)
{
u32 nws;
......@@ -895,8 +849,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
u16 version;
int length;
if (tunnel->sock && l2tp_verify_udp_checksum(tunnel->sock, skb))
goto discard_bad_csum;
/* UDP has verifed checksum */
/* UDP always verifies the packet length. */
__skb_pull(skb, sizeof(struct udphdr));
......@@ -979,14 +932,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
return 0;
discard_bad_csum:
LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
UDP_INC_STATS_USER(tunnel->l2tp_net, UDP_MIB_INERRORS, 0);
atomic_long_inc(&tunnel->stats.rx_errors);
kfree_skb(skb);
return 0;
error:
/* Put UDP header back */
__skb_push(skb, sizeof(struct udphdr));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment