Bug 247718

Summary: FreeBSD incorrectly drops IPv6 packets looping back to the same p2p interface
Product: Base System Reporter: Mira Ressel <aranea>
Component: kernAssignee: Alexander V. Chernikov <melifaro>
Status: Closed FIXED    
Severity: Affects Only Me CC: donner, kevans, melifaro, moviuro+freebsd
Priority: --- Keywords: patch
Version: UnspecifiedFlags: kevans: mfc-stable12+
kevans: mfc-stable11-
Hardware: Any   
OS: Any   
Attachments:
Description Flags
suggested patch for sys/netinet6/ip6_forward.c none

Description Mira Ressel 2020-07-02 15:06:00 UTC
FreeBSD's IPv6 stack explicitly drops packets which were received on an
IFF_POINTOPOINT interface and are then looped back to the same interface [1].

This piece of code originated in the KAME project, and was controversial even
when it was enabled there by default back in 2001 [2]. Notably, there is no
equivalent logic in FreeBSD's IPv4 stack -- it also generates ICMP Redirect
messages under these circumstances, but doesn't drop any packets.

While this logic may arguably make sense for true point-to-point links, not all
interfaces with the IFF_POINTOPOINT flag are such links. In particular, tun
interfaces are always marked with this flag, even though the userland
application behind a tun interface might well be forwarding packets to multiple
peers.

One example for an application that uses tun interfaces to present a
point-to-multipoint/NBMA link rather than a point-to-point link is wireguard-go,
the userland implementation of the wireguard protocol [3]. In this case, the
aforementioned logic causes packet drops in a perfectly valid network topology,
as reported in [4].

Therefore, I would suggest removing the entire "if ((nh->nh_ifp->if_flags &
IFF_POINTOPOINT) != 0) { ... }" block that drops these packets. Even in the case
of true point-to-point links, its only function is to avoid transient looping of
packets sent my misconfigured applications or attackers. This is a well-known
problem [5] that can be easily avoided by proper route configuration, rather
than by hardcoded kernel logic to drop packets.


[1] https://svnweb.freebsd.org/base/head/sys/netinet6/ip6_forward.c?view=markup&pathrev=362338#l265
[2] lengthy ML thread archived at
    https://www.ietf.org/mail-archive/text/ipngwg/2001-04.mail and -05,
    subject "nonexisting destination on p2p link"
[3] https://www.wireguard.com/
[4] https://forums.freebsd.org/threads/wireguard-peers-cant-reach-each-other-on-ipv6.75991/
[5] https://tools.ietf.org/html/rfc6164#section-5.1
Comment 1 Mira Ressel 2020-07-02 15:15:40 UTC
Created attachment 216144 [details]
suggested patch for sys/netinet6/ip6_forward.c
Comment 2 Lutz Donnerhacke freebsd_committer freebsd_triage 2020-07-05 12:44:16 UTC
Open an internal Code review: https://reviews.freebsd.org/D25567
Comment 3 commit-hook freebsd_committer freebsd_triage 2020-08-31 01:46:48 UTC
A commit references this bug:

Author: kevans
Date: Mon Aug 31 01:45:49 UTC 2020
New revision: 364982
URL: https://svnweb.freebsd.org/changeset/base/364982

Log:
  ipv6: quit dropping packets looping back on p2p interfaces

  To paraphrase the below-referenced PR:

  This logic originated in the KAME project, and was even controversial when
  it was enabled there by default in 2001. No such equivalent logic exists in
  the IPv4 stack, and it turns out that this leads to us dropping valid
  traffic when the "point to point" interface is actually a 1:many tun
  interface, e.g. with the wireguard userland stack.

  Even in the case of true point-to-point links, this logic only avoids
  transient looping of packets sent by misconfigured applications or
  attackers, which can be subverted by proper route configuration rather than
  hardcoded logic in the kernel to drop packets.

  In the review, melifaro goes on to note that the kernel can't fix it, so it
  perhaps shouldn't try to be 'smart' about it. Additionally, that TTL will
  still kick in even with incorrect route configuration.

  PR:		247718
  Reviewed by:	melifaro, rgrimes
  MFC after:	1 week
  Differential Revision:	https://reviews.freebsd.org/D25567

Changes:
  head/sys/netinet6/ip6_forward.c
Comment 4 Kyle Evans freebsd_committer freebsd_triage 2020-08-31 01:47:08 UTC
Oh, I noticed a little too late that melifaro@ had already 'taken' this PR. Sorry =(
Comment 5 commit-hook freebsd_committer freebsd_triage 2020-09-07 23:20:58 UTC
A commit references this bug:

Author: kevans
Date: Mon Sep  7 23:20:02 UTC 2020
New revision: 365434
URL: https://svnweb.freebsd.org/changeset/base/365434

Log:
  MFC r364982: ipv6: quit dropping packets looping back on p2p interfaces

  PR:		247718

Changes:
_U  stable/12/
  stable/12/sys/netinet6/ip6_forward.c
Comment 6 Kyle Evans freebsd_committer freebsd_triage 2020-09-07 23:21:23 UTC
Will appear in 12.2; thanks!