Bug 226421 - v6 address truncated and socket type shows "tcp46" when IPv4 mapping enabled
Summary: v6 address truncated and socket type shows "tcp46" when IPv4 mapping enabled
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 11.1-STABLE
Hardware: Any Any
: --- Affects Only Me
Assignee: Michael Tuexen
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-03-07 15:10 UTC by Dan McGregor
Modified: 2018-04-08 13:57 UTC (History)
2 users (show)

See Also:
tuexen: mfc-stable11+


Attachments
Proposed patch to correct IPv6 vs IPv4 check in receive path (640 bytes, patch)
2018-03-07 15:10 UTC, Dan McGregor
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dan McGregor 2018-03-07 15:10:39 UTC
Created attachment 191279 [details]
Proposed patch to correct IPv6 vs IPv4 check in receive path

Since bug 221385's been closed, with net.inet6.ip6.v6only=0, a socket listening on an IPv6 address accepts a connection from another IPv6 host, the accepted socket shows type "tcp46" and has its address truncated to the lower 32 bits:

USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
dan      sshd       711   3  tcp46  254.11.122.185:22     0.0.0.2:47615
root     sshd       708   3  tcp46  254.11.122.185:22     0.0.0.2:47615

The addresses are the lower 32 bits of the IPv6 addresses in question, 2001:470:1f17:273:2a0:98ff:fe0b:7ab9 and 2001:470:1c:4df::2.

The expected result would be:

USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
dan      sshd       40475 3  tcp6   2001:470:30f3:1:ca60:ff:fe5f:c1f3:22 2001:470:30f3:1:922b:34ff:fe5d:d4b3:33558
root     sshd       35424 3  tcp6   2001:470:30f3:1:ca60:ff:fe5f:c1f3:22 2001:470:30f3:1:922b:34ff:fe5d:d4b3:33558

This appears to be due to the kernel assuming any socket whose inp_vflag includes IPv4 is an IPv4 socket. The accepted socket inherits that value from the parent socket. It should only have tcp46 for listening sockets, and in accept check that only INP_IPV4 is set.
Comment 1 Conrad Meyer freebsd_committer freebsd_triage 2018-03-07 18:38:06 UTC
Michael, CCing you as you addressed the previous issue in a similar area and probably have some experience with this code.
Comment 2 Michael Tuexen freebsd_committer freebsd_triage 2018-03-07 18:58:31 UTC
Hi Conrad,

thanks for adding me. I'm aware of the problem and have a fix under review D13514.
Can you test the patch under reiew D13514?

Best regards
Michael
Comment 3 Conrad Meyer freebsd_committer freebsd_triage 2018-03-07 18:59:53 UTC
Dan, can you test Michael's patch?  I'm afraid I don't have any ipv6 networking on any of my FreeBSD machines (nor time to test).
Comment 4 Dan McGregor 2018-03-12 16:20:25 UTC
(In reply to Conrad Meyer from comment #3)

Yes, it looks like Michael's review D13514 fixes the issue for me too.
Comment 5 commit-hook freebsd_committer freebsd_triage 2018-03-16 15:26:47 UTC
A commit references this bug:

Author: tuexen
Date: Fri Mar 16 15:26:08 UTC 2018
New revision: 331061
URL: https://svnweb.freebsd.org/changeset/base/331061

Log:
  Set the inp_vflag consistently for accepted TCP/IPv6 connections when
  net.inet6.ip6.v6only=0.

  Without this patch, the inp_vflag would have INP_IPV4 and the
  INP_IPV6 flags for accepted TCP/IPv6 connections if the sysctl
  variable net.inet6.ip6.v6only is 0. This resulted in netstat
  to report the source and destination addresses as IPv4 addresses,
  even they are IPv6 addresses.

  PR:			226421
  Reviewed by:		bz, hiren, kib
  MFC after:		3 days
  Sponsored by:		Netflix, Inc.
  Differential Revision:	https://reviews.freebsd.org/D13514

Changes:
  head/sys/netinet/tcp_syncache.c
Comment 6 commit-hook freebsd_committer freebsd_triage 2018-04-07 20:47:39 UTC
A commit references this bug:

Author: tuexen
Date: Sat Apr  7 20:47:25 UTC 2018
New revision: 332238
URL: https://svnweb.freebsd.org/changeset/base/332238

Log:
  MFC r331061:

  Set the inp_vflag consistently for accepted TCP/IPv6 connections when
  net.inet6.ip6.v6only=0.

  Without this patch, the inp_vflag would have INP_IPV4 and the
  INP_IPV6 flags for accepted TCP/IPv6 connections if the sysctl
  variable net.inet6.ip6.v6only is 0. This resulted in netstat
  to report the source and destination addresses as IPv4 addresses,
  even they are IPv6 addresses.

  PR:			226421
  Reviewed by:		bz, hiren, kib
  Sponsored by:		Netflix, Inc.
  Differential Revision:	https://reviews.freebsd.org/D13514

Changes:
_U  stable/11/
  stable/11/sys/netinet/tcp_syncache.c
Comment 7 Michael Tuexen freebsd_committer freebsd_triage 2018-04-08 13:57:47 UTC
This is now fixed in head and stable/11. So I'm closing this bug.