* [PATCH v2 0/1] UDP traceroute packets with no checksum
@ 2022-04-05 23:51 Kevin Mitchell
2022-04-05 23:51 ` [PATCH 1/1] netfilter: conntrack: skip verification of zero UDP checksum Kevin Mitchell
2022-05-04 10:06 ` [Bridge] [PATCH v2 0/1] UDP traceroute packets with no checksum Linus Lüssing
0 siblings, 2 replies; 3+ messages in thread
From: Kevin Mitchell @ 2022-04-05 23:51 UTC (permalink / raw)
Cc: kevmitch, gal, Pablo Neira Ayuso, Jozsef Kadlecsik,
Florian Westphal, David S. Miller, Jakub Kicinski, Roopa Prabhu,
Nikolay Aleksandrov, Alexey Kuznetsov, Hideaki YOSHIFUJI,
netfilter-devel, coreteam, netdev, linux-kernel, bridge
This is v2 of https://lkml.org/lkml/2022/1/14/1060
That patch was discovered to cause problems with UDP tunnels as
described here:
https://lore.kernel.org/netdev/7eed8111-42d7-63e1-d289-346a596fc933@nvidia.com/
This version addresses the issue by instead explicitly handling zero UDP
checksum in the nf_reject_verify_csum() helper function.
Unlike the previous patch, this one only allows zero UDP checksum in
IPv4. I discovered that the non-netfilter IPv6 path would indeed drop
zero UDP checksum packets, so it's probably best to remain consistent.
--
2.35.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] netfilter: conntrack: skip verification of zero UDP checksum
2022-04-05 23:51 [PATCH v2 0/1] UDP traceroute packets with no checksum Kevin Mitchell
@ 2022-04-05 23:51 ` Kevin Mitchell
2022-05-04 10:06 ` [Bridge] [PATCH v2 0/1] UDP traceroute packets with no checksum Linus Lüssing
1 sibling, 0 replies; 3+ messages in thread
From: Kevin Mitchell @ 2022-04-05 23:51 UTC (permalink / raw)
Cc: kevmitch, gal, Pablo Neira Ayuso, Jozsef Kadlecsik,
Florian Westphal, David S. Miller, Jakub Kicinski, Roopa Prabhu,
Nikolay Aleksandrov, Alexey Kuznetsov, Hideaki YOSHIFUJI,
netfilter-devel, coreteam, netdev, linux-kernel, bridge
The checksum is optional for UDP packets in IPv4. However nf_reject
would previously require a valid checksum to illicit a response such as
ICMP_DEST_UNREACH.
Add some logic to nf_reject_verify_csum to determine if a UDP packet has
a zero checksum and should therefore not be verified. Explicitly require
a valid checksum for IPv6 consistent RFC 2460 and with the non-netfilter
stack (see udp6_csum_zero_error).
Signed-off-by: Kevin Mitchell <kevmitch@arista.com>
---
include/net/netfilter/nf_reject.h | 27 ++++++++++++++++++++----
net/bridge/netfilter/nft_reject_bridge.c | 6 ++++--
net/ipv4/netfilter/nf_reject_ipv4.c | 6 ++++--
net/ipv6/netfilter/nf_reject_ipv6.c | 2 +-
4 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/include/net/netfilter/nf_reject.h b/include/net/netfilter/nf_reject.h
index 9051c3a0c8e7..f248c1ff8b22 100644
--- a/include/net/netfilter/nf_reject.h
+++ b/include/net/netfilter/nf_reject.h
@@ -5,12 +5,34 @@
#include <linux/types.h>
#include <uapi/linux/in.h>
-static inline bool nf_reject_verify_csum(__u8 proto)
+static inline bool nf_reject_verify_csum(struct sk_buff *skb, int dataoff,
+ __u8 proto)
{
/* Skip protocols that don't use 16-bit one's complement checksum
* of the entire payload.
*/
switch (proto) {
+ /* Protocols with optional checksums. */
+ case IPPROTO_UDP: {
+ const struct udphdr *udp_hdr;
+ struct udphdr _udp_hdr;
+
+ /* Checksum is required in IPv6
+ * see RFC 2460 section 8.1
+ */
+ if (skb->protocol == htons(ETH_P_IPV6))
+ return true;
+
+ udp_hdr = skb_header_pointer(skb, dataoff,
+ sizeof(_udp_hdr),
+ &_udp_hdr);
+ if (!udp_hdr || udp_hdr->check)
+ return true;
+
+ return false;
+ }
+ case IPPROTO_GRE:
+
/* Protocols with other integrity checks. */
case IPPROTO_AH:
case IPPROTO_ESP:
@@ -19,9 +41,6 @@ static inline bool nf_reject_verify_csum(__u8 proto)
/* Protocols with partial checksums. */
case IPPROTO_UDPLITE:
case IPPROTO_DCCP:
-
- /* Protocols with optional checksums. */
- case IPPROTO_GRE:
return false;
}
return true;
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index deae2c9a0f69..e6d62de95378 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -111,6 +111,7 @@ static void nft_reject_br_send_v4_unreach(struct net *net,
unsigned int len;
__wsum csum;
u8 proto;
+ int dataoff;
if (!nft_bridge_iphdr_validate(oldskb))
return;
@@ -129,9 +130,10 @@ static void nft_reject_br_send_v4_unreach(struct net *net,
return;
proto = ip_hdr(oldskb)->protocol;
+ dataoff = ip_hdrlen(oldskb);
if (!skb_csum_unnecessary(oldskb) &&
- nf_reject_verify_csum(proto) &&
+ nf_reject_verify_csum(oldskb, dataoff, proto) &&
nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), proto))
return;
@@ -234,7 +236,7 @@ static bool reject6_br_csum_ok(struct sk_buff *skb, int hook)
if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0)
return false;
- if (!nf_reject_verify_csum(proto))
+ if (!nf_reject_verify_csum(skb, thoff, proto))
return true;
return nf_ip6_checksum(skb, hook, thoff, proto) == 0;
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
index 93b07739807b..7a83fe1c2675 100644
--- a/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -189,6 +189,7 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
{
struct iphdr *iph = ip_hdr(skb_in);
u8 proto = iph->protocol;
+ int dataoff = ip_hdrlen(skb_in);
if (iph->frag_off & htons(IP_OFFSET))
return;
@@ -196,12 +197,13 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
if (hook == NF_INET_PRE_ROUTING && nf_reject_fill_skb_dst(skb_in))
return;
- if (skb_csum_unnecessary(skb_in) || !nf_reject_verify_csum(proto)) {
+ if (skb_csum_unnecessary(skb_in) ||
+ !nf_reject_verify_csum(skb_in, dataoff, proto)) {
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
return;
}
- if (nf_ip_checksum(skb_in, hook, ip_hdrlen(skb_in), proto) == 0)
+ if (nf_ip_checksum(skb_in, hook, dataoff, proto) == 0)
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
}
EXPORT_SYMBOL_GPL(nf_send_unreach);
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
index 4aef6baaa55e..ac9574c6068f 100644
--- a/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -253,7 +253,7 @@ static bool reject6_csum_ok(struct sk_buff *skb, int hook)
if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0)
return false;
- if (!nf_reject_verify_csum(proto))
+ if (!nf_reject_verify_csum(skb, thoff, proto))
return true;
return nf_ip6_checksum(skb, hook, thoff, proto) == 0;
--
2.35.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Bridge] [PATCH v2 0/1] UDP traceroute packets with no checksum
2022-04-05 23:51 [PATCH v2 0/1] UDP traceroute packets with no checksum Kevin Mitchell
2022-04-05 23:51 ` [PATCH 1/1] netfilter: conntrack: skip verification of zero UDP checksum Kevin Mitchell
@ 2022-05-04 10:06 ` Linus Lüssing
1 sibling, 0 replies; 3+ messages in thread
From: Linus Lüssing @ 2022-05-04 10:06 UTC (permalink / raw)
To: Kevin Mitchell
Cc: Matthias Schiffer, Hideaki YOSHIFUJI, netdev, gal, bridge,
Florian Westphal, linux-kernel, Jozsef Kadlecsik, coreteam,
netfilter-devel, Nikolay Aleksandrov, Roopa Prabhu,
Jakub Kicinski, Alexey Kuznetsov, David S. Miller,
Pablo Neira Ayuso
On Tue, Apr 05, 2022 at 04:51:15PM -0700, Kevin Mitchell via Bridge wrote:
> This is v2 of https://lkml.org/lkml/2022/1/14/1060
>
> That patch was discovered to cause problems with UDP tunnels as
> described here:
>
> https://lore.kernel.org/netdev/7eed8111-42d7-63e1-d289-346a596fc933@nvidia.com/
>
> This version addresses the issue by instead explicitly handling zero UDP
> checksum in the nf_reject_verify_csum() helper function.
>
> Unlike the previous patch, this one only allows zero UDP checksum in
> IPv4. I discovered that the non-netfilter IPv6 path would indeed drop
> zero UDP checksum packets, so it's probably best to remain consistent.
Are you sure that a UDP zero checksum is not working for IPv6
packets? We are using it here without any issues with VXLAN
tunnels.
Yes, the original RFC did not allow UDP zero checksums in IPv6
packets, but I believe this has changed:
https://www.rfc-editor.org/rfc/rfc6936
(https://www.ietf.org/archive/id/draft-ietf-6man-udpzero-01.html)
Regards, Linus
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-05-04 10:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-05 23:51 [PATCH v2 0/1] UDP traceroute packets with no checksum Kevin Mitchell
2022-04-05 23:51 ` [PATCH 1/1] netfilter: conntrack: skip verification of zero UDP checksum Kevin Mitchell
2022-05-04 10:06 ` [Bridge] [PATCH v2 0/1] UDP traceroute packets with no checksum Linus Lüssing
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).