netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] ipv6/netfilter: Drop Packet Too Big with invalid payload
@ 2021-06-24  9:01 Georg Kohmann
  2021-06-24  9:05 ` Florian Westphal
  0 siblings, 1 reply; 3+ messages in thread
From: Georg Kohmann @ 2021-06-24  9:01 UTC (permalink / raw)
  To: netdev
  Cc: coreteam, netfilter-devel, kuba, davem, fw, kadlec, pablo,
	Georg Kohmann

PMTU is updated even though received ICMPv6 PTB do not match any
transmitted traffic. This breaks TAHI IPv6 Core Conformance Test
Revision 5.0.1, v6LC.4.1.12 Validate Packet Too Big[1].

Referring to RFC8201 IPv6 Path MTU Discovery, section 4: "Nodes should
appropriately validate the payload of ICMPv6 PTB messages to ensure
these are received in response to transmitted traffic (i.e., a reported
error condition that corresponds to an IPv6 packet actually sent by the
application) per [ICMPv6]."

nf_conntrack_inet_error() return -NF_ACCEPT if the inner header of
ICMPv6 error packet is not related to an existing connection. Drop PTB
packet when this occur. This will prevent ipv6 from handling the packet
and update the PMTU.

The included test script below use ICMPv6 echo requests and PTB with an
invalid ICMPv6 identifier to check whether the host under test will
ignore the PTB or not. The host should not fragment the last echo
response.

[1] https://www.ipv6ready.org/docs/Core_Conformance_5_0_1.pdf
===== SCRIPT FOR SIMULATING TEST v6LC.4.1.12. =====

from scapy.all import *

def send_packet_too_big(addr, reply, mtu, id):
    reply[ICMPv6EchoReply].id = id
    I=IPv6(dst=addr)
    PacketTooBig=ICMPv6PacketTooBig(mtu=mtu, code=255)
    reply.data = reply.data[:mtu-len(I/PacketTooBig/reply)]
    reply[IPv6].fl = 0
    packet = I/PacketTooBig/reply
    del packet.cksum
    send(packet)

def send_echo_request(addr, payload, id=0, wait=True):
    I=IPv6(dst=addr)
    EchoRequest=ICMPv6EchoRequest(data=payload)
    EchoRequest.id = id
    if wait:
        return sr1(I/EchoRequest, timeout=5)
    else:
        return send(I/EchoRequest)

def validate_packets(addr):
    packets = sniff(filter = "ip6 and host {}".format(addr), timeout=2)
    for packet in packets:
        if IPv6ExtHdrFragment in packet[IPv6]:
            if ICMPv6EchoReply in packet[IPv6][IPv6ExtHdrFragment]:
                print("Fail - Received a fragmented echo")
                return
    print("Success - No fragmented echo reply received")

if __name__ == '__main__':
    print("Simulating IPv6 Core Conformance Test v6LC4.1.12")
    addr = sys.argv[1]
    thread = threading.Thread(target=validate_packets, args=(addr,))
    thread.start()
    echo_reply = send_echo_request(addr, 'A'*1400, id=0)
    if echo_reply:
        send_packet_too_big(addr, echo_reply, mtu=1300, id=1)
        send_echo_request(addr, 'A'*1400, id=0, wait=False)

===== END OF SCRIPT =====

Signed-off-by: Georg Kohmann <geokohma@cisco.com>
---
 net/netfilter/nf_conntrack_proto_icmpv6.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_icmpv6.c b/net/netfilter/nf_conntrack_proto_icmpv6.c
index facd8c6..797cd42 100644
--- a/net/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/netfilter/nf_conntrack_proto_icmpv6.c
@@ -139,6 +139,7 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
 	const struct icmp6hdr *icmp6h;
 	struct icmp6hdr _ih;
 	int type;
+	int ret;
 
 	icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
 	if (icmp6h == NULL) {
@@ -167,8 +168,12 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
 	memcpy(&outer_daddr.ip6, &ipv6_hdr(skb)->daddr,
 	       sizeof(outer_daddr.ip6));
 	dataoff += sizeof(*icmp6h);
-	return nf_conntrack_inet_error(tmpl, skb, dataoff, state,
-				       IPPROTO_ICMPV6, &outer_daddr);
+	ret = nf_conntrack_inet_error(tmpl, skb, dataoff, state,
+				      IPPROTO_ICMPV6, &outer_daddr);
+	if (icmp6h->icmp6_type == ICMPV6_PKT_TOOBIG &&
+	    ret == -NF_ACCEPT)
+		return -NF_DROP;
+	return ret;
 }
 
 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ipv6/netfilter: Drop Packet Too Big with invalid payload
  2021-06-24  9:01 [PATCH net] ipv6/netfilter: Drop Packet Too Big with invalid payload Georg Kohmann
@ 2021-06-24  9:05 ` Florian Westphal
  2021-06-24  9:27   ` Georg Kohmann (geokohma)
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Westphal @ 2021-06-24  9:05 UTC (permalink / raw)
  To: Georg Kohmann
  Cc: netdev, coreteam, netfilter-devel, kuba, davem, fw, kadlec, pablo

Georg Kohmann <geokohma@cisco.com> wrote:
> PMTU is updated even though received ICMPv6 PTB do not match any
> transmitted traffic. This breaks TAHI IPv6 Core Conformance Test
> Revision 5.0.1, v6LC.4.1.12 Validate Packet Too Big[1].
> 
> Referring to RFC8201 IPv6 Path MTU Discovery, section 4: "Nodes should
> appropriately validate the payload of ICMPv6 PTB messages to ensure
> these are received in response to transmitted traffic (i.e., a reported
> error condition that corresponds to an IPv6 packet actually sent by the
> application) per [ICMPv6]."
> 
> nf_conntrack_inet_error() return -NF_ACCEPT if the inner header of
> ICMPv6 error packet is not related to an existing connection. Drop PTB
> packet when this occur. This will prevent ipv6 from handling the packet
> and update the PMTU.

This is intentional. We try to not auto-drop packets in conntrack.

Packet is marked as invalid, users can add nft/iptables rules to discard
such packets if they want to do so.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ipv6/netfilter: Drop Packet Too Big with invalid payload
  2021-06-24  9:05 ` Florian Westphal
@ 2021-06-24  9:27   ` Georg Kohmann (geokohma)
  0 siblings, 0 replies; 3+ messages in thread
From: Georg Kohmann (geokohma) @ 2021-06-24  9:27 UTC (permalink / raw)
  To: Florian Westphal
  Cc: netdev@vger.kernel.org, coreteam@netfilter.org,
	netfilter-devel@vger.kernel.org, kuba@kernel.org,
	davem@davemloft.net, kadlec@netfilter.org, pablo@netfilter.org

On 24.06.2021 11:05, Florian Westphal wrote:
> Georg Kohmann <geokohma@cisco.com> wrote:
>> PMTU is updated even though received ICMPv6 PTB do not match any
>> transmitted traffic. This breaks TAHI IPv6 Core Conformance Test
>> Revision 5.0.1, v6LC.4.1.12 Validate Packet Too Big[1].
>>
>> Referring to RFC8201 IPv6 Path MTU Discovery, section 4: "Nodes should
>> appropriately validate the payload of ICMPv6 PTB messages to ensure
>> these are received in response to transmitted traffic (i.e., a reported
>> error condition that corresponds to an IPv6 packet actually sent by the
>> application) per [ICMPv6]."
>>
>> nf_conntrack_inet_error() return -NF_ACCEPT if the inner header of
>> ICMPv6 error packet is not related to an existing connection. Drop PTB
>> packet when this occur. This will prevent ipv6 from handling the packet
>> and update the PMTU.
> This is intentional. We try to not auto-drop packets in conntrack.
>
> Packet is marked as invalid, users can add nft/iptables rules to discard
> such packets if they want to do so.
Ah, dropping patch then, thank you.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-06-24  9:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-06-24  9:01 [PATCH net] ipv6/netfilter: Drop Packet Too Big with invalid payload Georg Kohmann
2021-06-24  9:05 ` Florian Westphal
2021-06-24  9:27   ` Georg Kohmann (geokohma)

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).