Rack of Ethernet switches.

Linux IPv6 on Comcast

Linux and IPv6

IPv6 or Internet Protocol version 6 is the modern network-layer protocol. In many parts of the world including East Asia and South Asia, IPv6 is the dominant protocol and IPv4 is used only in small islands in an IPv6 sea.

About a year ago I had to replace my cable modem. I checked first to verify that the one I planned to buy at the local "big box" store supported IPv6. However, I couldn't get IPv6 working, at least not at first.

Here is how to get IPv6 working with a Motorola / Arris Surfboard SB6121 on a Comcast connection. This involved some unexpected changes in the ifcfg-* interface configuration file, and modifications to one of the network control scripts.

My main Linux system is connected to the cable modem, so its exterior interface gets a publicly reachable address. Network services are locked down with their configurations plus iptables (and now, ip6tables) rules.

I am doing this on Comcast, but I don't think there is anything really Comcast-specific beyond the routing we see in the traceroute6 output at the end.

I am running my own DNS server using BIND. I have noticed some erratic behavior from Comcast's DNS servers, but their routing is pretty reliable and so my DNS server can generally get me what I need.

I am using a Mageia distribution. Mandrake Linux was derived from Red Hat Linux version 5.1 back in 1998. There was a lawsuit from Hearst Corporation complaining about their trademarked character Mandrake the Magician in 2004, and then the acquisition of the Brazilian company Conectiva in early 2005, and so in April 2005 the Mandrake distribution became Mandriva Linux.

The last stable version was Mandriva Linux 2011, then the commercial Mandrake/Mandriva operation ended. Most of the laid-off developers joined the Mageia project.

Mageia remains somewhat Red-Hat-like, although not as similar as Oracle Linux or Scientific Linux, let alone CentOS.

Mageia uses RPM packages, although it uses the URPMI suite of commands — urpmi, urpme, urpmf, and urpmq, — rather than the yum high-level package management tool used on most RPM-based distributions.

However, the service control in general and the network configuration details will be familiar to users of non Debian/Ubuntu distributions. Service control itself with systemctl, configuration in /etc/sysconfig/, network details and scripts in /etc/sysconfig/network-scripts/.

The Kernel Detects the Interfaces

The traditional network interface names eth0, eth1, wlan0, and so on were replaced starting with v197 systemd. The names are now based on hardware details, making them consistent from one boot session to the next.

Linux
Interface
Names

Interfaces on the motherboard may get names eno1, eno2, and so on, or maybe em1, em2, and so on. Their names may encode their PCI bus addresses, such as enp2s0 for an Ethernet device at PCI bus address 02:00.0. They may get something like p3p1 for a port on a PCI card, that would be for slot 3 and port 1.

My experience is that I cannot predict in advance what a given platform's interfaces will be named. But once we've seen it boot once, those names will always be the same.

The kernel detects the devices in whatever order its drivers load and probe the buses, and assigns initial names eth0, eth1, etc.

Then the interfaces are renamed.

The end result on my system is that p7p1 is the exterior Ethernet port, connected to the cable modem, and p3p1 and em1 are on interior LANs. (em1 is on the motherboard, p3p1 and p7p1 are on a dual-interface PCIe card) A WLAN interface on a USB stick is wlp10s0u1, encoding its USB device number plus the USB controller's PCI bus address.

$ egrep 'p[0-9][ps][0-9]|e[mn][0-9]|eth[0-9]|wlan' /var/log/dmesg
[    4.791236] r8169 0000:06:00.0 eth0: RTL8168evl/8111evl at 0xffffc90000f96000, 00:13:3b:12:6f:a9, XID 0c900800 IRQ 44
[    4.791238] r8169 0000:06:00.0 eth0: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[    4.791727] r8169 0000:07:00.0 eth1: RTL8168evl/8111evl at 0xffffc90000f98000, 00:13:3b:12:6f:aa, XID 0c900800 IRQ 45
[    4.791728] r8169 0000:07:00.0 eth1: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[    4.792413] r8169 0000:0c:00.0 eth2: RTL8168f/8111f at 0xffffc90000f9c000, 08:62:66:2c:ab:1c, XID 08000800 IRQ 46
[    4.792414] r8169 0000:0c:00.0 eth2: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[    4.992382] r8169 0000:06:00.0 p3p1: renamed from eth0
[    5.077048] r8169 0000:0c:00.0 em1: renamed from eth2
[    5.085507] r8169 0000:07:00.0 p7p1: renamed from eth1
[    6.268971] rt2800usb 2-1:1.0 wlp10s0u1: renamed from wlan0

Network Configuration and Scripts

General network settings go in /etc/sysconfig/network — hostname and whether to enable networking or not.

Individual network interfaces are configured in files name ifcfg-* in the directory /etc/sysconfig/network-scripts/. In the following, p3p1 is on the interior LAN, wlp10s0u1 is a USB-connected WLAN interface using WPA/2 PSK with a key based on the passphrase "PassPhraseHere", and p7p1 is plugged into the cable modem leading out to Comcast.

$ cat /etc/sysconfig/network
HOSTNAME=thishost.example.com
NETWORKING=yes

$ cat /etc/sysconfig/network-scripts/ifcfg-p3p1
DEVICE=p3p1
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.1.1.100
NETMASK=255.255.255.0

IPV6INIT=yes

$ cat /etc/sysconfig/network-scripts/ifcfg-wlp10s0u1
DEVICE=wlp10s0u1
ONBOOT=yes
BOOTPROTO=dhcp
DHCP_CLIENT=dhclient
METRIC=35
WIRELESS_MODE=Managed
WIRELESS_ESSID=FBI_van4
WIRELESS_ENC_KEY="s:PassPhraseHere"
WIRELESS_WPA_DRIVER=wext
WIRELESS_WPA_REASSOCIATE=no

IPV6INIT=yes

$ cat /etc/sysconfig/network-scripts/ifcfg-p7p1
DEVICE=p7p1
ONBOOT=yes
BOOTPROTO=dhcp
DHCP_CLIENT=dhclient
NEEDHOSTNAME=no
DEFROUTE=yes

IPV6INIT=yes

The interior interface p3p1 brought up IPv6 and gave itself a link-local auto-configured address fe80::213:3bff:fe12:6fa9/64 (based on its Ethernet MAC address 00:13:3b:12:6f:a9).

However, the exterior interface p7p1 did not start IPv6, and attempts to manually assign an IPv6 address failed with a distinctive error:

# ip -6 addr add 2600:2600::1/64 dev p7p1
RTNETLINK answers: No buffer space available

That interface is ineligible for IPv6. The reasons are shown here, if you know what to look for:

$ cat /proc/net/if_inet6
00000000000000000000000000000001 01 80 10 80       lo
fe80000000000000ca3a35fffecf3bb9 05 40 20 80 wlp10s0u1
fe8000000000000002133bfffe126fa9 02 40 20 80     p3p1
$ cat cat /sys/class/net/p7p1/mtu
576

The fields in if_inet6 are shown in hexadecimal and list the:
• IPv6 address
• Netlink device number
• Prefix length
• Scope value
• Interface flags
Then the interface name. But notice that p7p1 doesn't show up at all. The reason is the MTU value. IPv6 requires a minimum MTU of 1280 bytes as per RFC 2460. (versus the IPv4 minimum of 576)

Enabling IPv6 on the Cable Modem Interface

Increase the IPv6-specific MTU setting. You must use IPV6_MTU and not MTU, at least with the Mageia boot scripts.

$ cat /etc/sysconfig/network-scripts/ifcfg-p7p1
DEVICE=p7p1
ONBOOT=yes
BOOTPROTO=dhcp
DHCP_CLIENT=dhclient
NEEDHOSTNAME=no
DEFROUTE=yes

IPV6INIT=yes
IPV6_MTU=1500

We attempt to restart the network service. We don't get a global IPv6 address from the provider, but at least it brings up IPv6 and auto-configures a link-local address:

$ cat /proc/net/if_inet6
00000000000000000000000000000001 01 80 10 80       lo
fe8000000000000002133bfffe126faa 03 40 20 80     p7p1
fe80000000000000ca3a35fffecf3bb9 05 40 20 80 wlp10s0u1
fe8000000000000002133bfffe126fa9 02 40 20 80     p3p1

Modifying the Boot Script

Now the service control scripts are trying to get an IPv6 address, but they fail. You run:
systemctl, which calls
   ↪ /etc/sysconfig/network-scripts/ifup, which calls
     ↪ /etc/sysconfig/network-scripts/ifup-ipv6 and
     ↪ /etc/sysconfig/network-scripts/ifup-eth

The last of those, ifup-eth, ends with a block where it attempts to bring up IPv6 and then tests the result. The corresponding script in RHEL ends with an almost identical block:

[ ... many lines not shown ... ]

# IPv6 initialisation?
/etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG}
if [[ "${DHCPV6C}"  = [Yy1]* ]] && [ -x /sbin/dhclient ]; then
    generate_config_file_name 6
    generate_lease_file_name 6
    echo
    echo -n $"Determining IPv6 information for ${DEVICE}..."
    if /sbin/dhclient -6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient6-${DEVICE}.pid -H ${DHCP_HOSTNAME:-${HOSTNAME%%.*}} ${DEVICE} ; then
        echo $" done."
    else
        echo $" failed."
        if [ "${dhcpipv4}" = "good" -o -n "${IPADDR}" ]; then
            net_log "Unable to obtain IPv6 DHCP address ${DEVICE}." warning
        else
            exit 1
        fi
    fi
fi

exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2}

The ifup-eth script tries to pass a host name with the -H flag, but the dhclient program doesn't recognize that option. It worked with dhclient version 4.1.1 but it no longer works with version 4.3.3, see its documentation for details.

Additionally, it seems to always fail when it's called too soon after the first instance ran to get the IPv4 configuration.

I need to modify the script. Copy the original to ifup-eth-ORIGINAL and make some changes. The line marked * was changed, The lines marked + were added, replacing what was there.

[ ... many lines not shown ... ]

# IPv6 initialisation?
/etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG}
if [[ "${DHCPV6C}"  = [Yy1]* ]] && [ -x /sbin/dhclient ]; then
    generate_config_file_name 6
    generate_lease_file_name 6
    echo
    echo -n $"Determining IPv6 information for ${DEVICE}..."
    attempts=1
*   /sbin/dhclient -6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}
+   success=$?
+   while [ $success != 0 ]
+   do
+        echo ""
+        attempts=$(( $attempts + 1 ))
+        sleep 1
+        echo "attempt $attempts"
+        /sbin/dhclient -6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}
+        success=$?
+        if [ $attempts -gt 10 ]
+        then
+            success=0
+        fi
+   done
fi

exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2}

It Works!

Let's see the configuration:

$ ip link show p7p1
3: p7p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:13:3b:12:6f:aa brd ff:ff:ff:ff:ff:ff

$ ip addr show p7p1
3: p7p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:13:3b:12:6f:aa brd ff:ff:ff:ff:ff:ff
    inet 24.15.60.156/23 brd 255.255.255.255 scope global p7p1
       valid_lft forever preferred_lft forever
    inet6 2001:558:600d:16:12d:1ee2:8012:6869/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::213:3bff:fe12:6faa/64 scope link 
       valid_lft forever preferred_lft forever

$ cat /proc/net/if_inet6
00000000000000000000000000000001 01 80 10 80       lo
fe8000000000000002133bfffe126faa 03 40 20 80     p7p1
fe80000000000000ca3a35fffecf3bb9 05 40 20 80 wlp10s0u1
20010558600d0016012d1ee280126869 03 40 00 80     p7p1
fe8000000000000002133bfffe126fa9 02 40 20 80     p3p1

The fe80 address is auto-configured with a link-local unicast address as before, while the 2001:558::/31 IPv6 address block is assigned to Comcast:

$ whois 2001:558:600d:16:12d:1ee2:8012:6869
[...]

NetRange:       2001:558:: - 2001:559:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
CIDR:           2001:558::/31
NetName:        COMCAST6NET
NetHandle:      NET6-2001-558-1
Parent:         ARIN-001 (NET6-2001-400-0)
NetType:        Direct Allocation
OriginAS:       AS7922
Organization:   Comcast Cable Communications, LLC (CCCS)
[...]

Let's see the IPv4 and IPv6 routing tables:

$ ip route
default via 24.15.60.1 dev p7p1  metric 5 
10.1.1.0/24 dev p3p1  proto kernel  scope link  src 10.1.1.100 
24.15.60.0/23 dev p7p1  proto kernel  scope link  src 24.15.60.156  metric 5 
169.254.0.0/16 dev p7p1  scope link  metric 5 
169.254.0.0/16 dev wlp10s0u1  scope link  metric 35 
169.254.0.0/16 dev p3p1  scope link  metric 1002 
192.168.1.0/24 dev wlp10s0u1  proto kernel  scope link  src 192.168.1.101  metric 35 
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 linkdown 

$ ip -6 route
unreachable ::/96 dev lo  metric 1024  error -113 pref medium
unreachable ::ffff:0.0.0.0/96 dev lo  metric 1024  error -113 pref medium
2001:558:600d:16::/64 dev p7p1  proto kernel  metric 256  pref medium
unreachable 2002:a00::/24 dev lo  metric 1024  error -113 pref medium
unreachable 2002:7f00::/24 dev lo  metric 1024  error -113 pref medium
unreachable 2002:a9fe::/32 dev lo  metric 1024  error -113 pref medium
unreachable 2002:ac10::/28 dev lo  metric 1024  error -113 pref medium
unreachable 2002:c0a8::/32 dev lo  metric 1024  error -113 pref medium
unreachable 2002:e000::/19 dev lo  metric 1024  error -113 pref medium
unreachable 3ffe:ffff::/32 dev lo  metric 1024  error -113 pref medium
fe80::/64 dev wlp10s0u1  proto kernel  metric 256  pref medium
fe80::/64 dev p3p1  proto kernel  metric 256  pref medium
fe80::/64 dev p7p1  proto kernel  metric 256  pref medium
default via fe80::201:5cff:fe79:1446 dev p7p1  proto ra  metric 1024  expires 1798sec pref medium

The 2001:558:600d:16::/64 subnet is directly connected via p7p1. The default route is the IPv6 next hop via Comcast's router. The unreachable 2002::/16 routes are the 6to4 tunnel addresses for localhost, the RFC 1918 private IPv4 blocks (10/8, 172.16/12, and 192.168/16), and the ZeroConf or Bonjour 169.254/16 block. See RFC 5735 for the special-use IPv4 addresses. The unreachable 3ffe::/16 address block was used for the second 6bone experimental network.

Now let's see the ARP (IPv4) and NDP (IPv6) caches, with the Comcast router listed under its IPv4 and IPv6 addresses.

$ ip neigh show
24.15.60.1 dev p7p1 lladdr 00:01:5c:79:14:46 REACHABLE
10.1.1.234 dev p3p1 lladdr 00:30:c1:8b:d2:94 REACHABLE
10.1.1.231 dev p3p1 lladdr 00:1c:50:ac:72:1e DELAY
10.1.1.232 dev p3p1 lladdr b8:27:eb:69:be:bb REACHABLE
10.1.1.230 dev p3p1 lladdr 2c:27:d7:c5:d3:7b REACHABLE
192.168.1.100 dev wlp10s0u1 lladdr 00:37:6d:a9:b9:35 DELAY
10.1.1.252 dev p3p1 lladdr 00:1d:7e:2e:97:85 STALE
10.1.1.233 dev p3p1 lladdr b8:27:eb:01:d3:20 REACHABLE
fe80::201:5cff:fe79:1446 dev p7p1 lladdr 00:01:5c:79:14:46 router REACHABLE

Finally, let's do some functional tests:

$ ping6 -n -c 5 www.google.com
PING www.google.com(2607:f8b0:4009:80a::2004) 56 data bytes
64 bytes from 2607:f8b0:4009:80a::2004: icmp_seq=1 ttl=45 time=26.5 ms
64 bytes from 2607:f8b0:4009:80a::2004: icmp_seq=2 ttl=45 time=26.2 ms
64 bytes from 2607:f8b0:4009:80a::2004: icmp_seq=3 ttl=45 time=26.1 ms
64 bytes from 2607:f8b0:4009:80a::2004: icmp_seq=4 ttl=45 time=26.1 ms
64 bytes from 2607:f8b0:4009:80a::2004: icmp_seq=5 ttl=45 time=26.5 ms

--- www.google.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 26.104/26.317/26.575/0.201 ms

$ traceroute6 www.google.com
traceroute to www.google.com (2607:f8b0:4009:80a::2004) from 2001:558:600d:16:12d:1ee2:8012:6869, 30 hops max, 24 byte packets
 1  2001:558:600d:16::1 (2001:558:600d:16::1)  8.132 ms  8.575 ms  8.777 ms
 2  te-5-4-ur01.lafayette.in.indiana.comcast.net (2001:558:322:ff89::1)  8.697 ms  8.278 ms  9.099 ms
 3  te-9-2-ur02.lafayette.in.indiana.comcast.net (2001:558:300:40a::2)  8.603 ms  8.66 ms  10.193 ms
 4  te-1-9-0-9-ar01.indianapolis.in.indiana.comcast.net (2001:558:300:40c::1)  18.756 ms  18.788 ms  15.965 ms
 5  hu-1-13-0-0-ar01.area4.il.chicago.comcast.net (2001:558:300:25d::1)  27.876 ms 27.442 27.549
 6  be-33491-cr02.350ecermak.il.ibone.comcast.net (2001:558:0:f6e9::1)  28.628 ms  27.001 ms  34.741 ms
 7  hu-0-13-0-1-pe04.350ecermak.il.ibone.comcast.net (2001:558:0:f5df::2)  27.211 28.110 27.488 ms
 8  as15169-7-c.350ecermak.il.ibone.comcast.net (2001:559::562)  28.239 ms  34.473 ms  26.295 ms
 9  2001:4860::1:0:cb7d (2001:4860::1:0:cb7d)  27.782 ms  26.948 ms  36.19 ms
10  2001:4860:0:1::957 (2001:4860:0:1::957)  27.038 ms  26.581 ms  26.883 ms
11  ord30s21-in-x04.1e100.net (2607:f8b0:4009:80a::2004)  29.295 ms  27.844 ms  26.299 ms

That's 8-9 msec and 3 hops across West Lafayette and Lafayette, another 10 msec and one hop to Indianapolis, another 10 msec and 1 hop back past Lafayette to Chicago, 3 hops around the Chicago area, then into a Google data center.

Hops 9 and 10 are within the 2001:4860::/32 IPv6 address block assigned to Google but there aren't pointer records mapping those back to host names.

Cisco EZXS88W Ethernet switch, Cisco WRT54G wireless router and Ethernet switch, Harris SB621 'Surfboard' cable modem, MFJ-1278 multi-mode data controller.

Cisco EZXS88W 8-port Ethernet switch, Cisco WRT54G wireless router and Ethernet switch, MFJ-1278 multi-mode data controller, and Harris SB6121 "SURFboard" cable modem.

Forwarding IPv6 to the World

The next step was to get IPv6 forwarding working between my interior LAN and the outside world. A shell script /etc/rc.d/rc.firewall runs from /etc/rc.local at the end of the booting process. It uses iptables and ip6tables to set up filtering rules.

[ ... many lines not shown ... ]

echo "  Finding interfaces..."
EXT_INT="p7p1"
EXT_IPV4="$( ip -4 addr show ${EXT_INT} |
	awk '/inet/ {print $2}' | sed 's@/.*@@' )"
EXT_IPV6="$( ip -6 addr show ${EXT_INT} |
	awk '/inet6/ {print $2}' | sed 's@/.*@@' | grep -v '^fe80' )"

[ ... many lines not shown ... ]

echo " Turning on SNAT masqueraded forwarding..."
# Turning on IPv6 forwarding will remove the IPv6 default route.
# Record it first.
DEFGW_IPV6=$(ip -6 route show | awk '/default/ {print $3}')
# Now turn on forwarding and fix the IPv6 default route.
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
if [ "$DEFGW_IPV6" != "" ]
then
	ip route add default via $DEFGW_IPV6 dev p7p1
fi
iptables  -t nat -F
ip6tables -t nat -F
echo "  Masq to ${EXT_INT}"
iptables  -t nat -A POSTROUTING -o ${EXT_INT} -j SNAT --to-source ${EXT_IPV4}
ip6tables -t nat -A POSTROUTING -o ${EXT_INT} -j SNAT --to-source ${EXT_IPV6}

[ ... many lines not shown ... ]

I need to run the the IPv6 Router Advertisement Daemon. It is configured in /etc/radvd.conf and /etc/sysconfig/radvd and controlled as service radvd. My /etc/radvd.conf contains:

interface p3p1
{
        AdvSendAdvert on;
	# IPv6 routers will not forward (including with NAT) packets
	# with link-local source addresses.  So I advertise a
	# fc00::/7 IPv6 block as per RFC 4193.
	# https://tools.ietf.org/html/rfc4193
	prefix fc00::/64
	{
                AdvOnLink on;
                AdvAutonomous on;
		AdvRouterAddr on;
        };
};

I restart the Linux system and notice that a new IPv6 address is in use on the interior interface:

$ ip addr show p3p1
2: p3p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:13:3b:12:6f:a9 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.100/24 brd 10.1.1.255 scope global p3p1
       valid_lft forever preferred_lft forever
    inet6 fc00::213:3bff:fe12:6fa9/64 scope global mngtmpaddr dynamic 
       valid_lft 86157sec preferred_lft 14157sec
    inet6 fe80::213:3bff:fe12:6fa9/64 scope link 
       valid_lft forever preferred_lft forever

When I restart an OpenBSD system on the interior LAN I now see and can do this:

$ cat /etc/hostname.re0
rtsol
dhcp

$ ifconfig re0
re0: flags=218843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,MPSAFE,AUTOCONF6> mtu 1500
	lladdr 2c:27:d7:c5:d3:7b
	priority: 0
	groups: egress
	media: Ethernet autoselect (100baseTX full-duplex)
	status: active
	inet 10.1.1.230 netmask 0xffffff00 broadcast 10.1.1.255
	inet6 fe80::2e27:d7ff:fec5:d37b%re0 prefixlen 64 scopeid 0x1
	inet6 fc00::2e27:d7ff:fec5:d37b prefixlen 64 autoconf pltime 14389 vltime 86389
	inet6 fc00::38e3:cbcc:16ff:dd07 prefixlen 64 autoconf autoconfprivacy pltime 14269 vltime 86269

$ route show
Routing tables

Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
default            10.1.1.100         UGS        4       10     -     8 re0  
10.1.1/24          10.1.1.230         UC         1        2     -     4 re0  
10.1.1.100         00:13:3b:12:6f:a9  UHLc       2      132     -     4 re0  
10.1.1.230         2c:27:d7:c5:d3:7b  UHLl       0       41     -     1 re0  
10.1.1.255         10.1.1.230         UHb        0        0     -     1 re0  
loopback           localhost          UGRS       0        0 32768     8 lo0  
localhost          localhost          UHl        2     3921 32768     1 lo0  
BASE-ADDRESS.MCAST localhost          URS        0        0 32768     8 lo0  

Internet6:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
::/104             localhost          UGRS       0        0 32768     8 lo0  
::/96              localhost          UGRS       0        0 32768     8 lo0  
default            fe80::213:3bff:fe1 UG         0        3     -    56 re0  
localhost          localhost          UHl        3        3 32768     1 lo0  
::127.0.0.0/104    localhost          UGRS       0        0 32768     8 lo0  
::224.0.0.0/100    localhost          UGRS       0        0 32768     8 lo0  
::255.0.0.0/104    localhost          UGRS       0        0 32768     8 lo0  
::ffff:0.0.0.0/96  localhost          UGRS       0        0 32768     8 lo0  
2002::/24          localhost          UGRS       0        0 32768     8 lo0  
2002:7f00::/24     localhost          UGRS       0        0 32768     8 lo0  
2002:e000::/20     localhost          UGRS       0        0 32768     8 lo0  
2002:ff00::/24     localhost          UGRS       0        0 32768     8 lo0  
fc00::/64          fc00::2e27:d7ff:fe UC         0        0     -     4 re0  
fc00::2e27:d7ff:fe 2c:27:d7:c5:d3:7b  UHLl       0        0     -     1 re0  
fc00::38e3:cbcc:16 2c:27:d7:c5:d3:7b  UHLl       0        2     -     1 re0  
fe80::/10          localhost          UGRS       0        1 32768     8 lo0  
fe80::%re0/64      fe80::2e27:d7ff:fe UC         1        5     -     4 re0  
fe80::213:3bff:fe1 00:13:3b:12:6f:a9  UHLc       1       37     -     4 re0
fe80::2e27:d7ff:fe 2c:27:d7:c5:d3:7b  UHLl       0        2     -     1 re0  
fe80::1%lo0        fe80::1%lo0        UHl        0        0 32768     1 lo0  
fec0::/10          localhost          UGRS       0        0 32768     8 lo0  
ff01::/16          localhost          UGRS       0        1 32768     8 lo0  
ff01::%re0/32      fe80::2e27:d7ff:fe UC         0        2     -     4 re0  
ff01::%lo0/32      localhost          UC         0        1 32768     4 lo0  
ff02::/16          localhost          UGRS       0        1 32768     8 lo0  
ff02::%re0/32      fe80::2e27:d7ff:fe UC         0        2     -     4 re0  
ff02::%lo0/32      localhost          UC         0        1 32768     4 lo0  

$ traceroute6 www.google.com
traceroute6 to www.google.com (2607:f8b0:4002:c0c::93), 64 hops max, 60 byte packets
 1  fc00::213:3bff:fe12:6fa9 (fc00::213:3bff:fe12:6fa9)  0.252 ms  0.189 ms  0.182 ms
 2  2001:558:600d:16::1 (2001:558:600d:16::1)  16.989 ms  8.714 ms  8.407 ms
 3  te-5-4-ur01.lafayette.in.indiana.comcast.net (2001:558:322:ff89::1)  40.658 ms  208.868 ms  207.967 ms
 4  te-3-2-ur02.lafayette.in.indiana.comcast.net (2001:558:300:13f::2)  8.445 ms  8.243 ms  8.854 ms
 5  te-0-7-0-4-ar01.indianapolis.in.indiana.comcast.net (2001:558:300:140::1)  17.06 ms  18.779 ms  16.809 ms
 6  he-4-9-0-0-ar01.area4.il.chicago.comcast.net (2001:558:300:7::1)  27.611 ms  28.539 ms  27.51 ms
[...]

And, from an interior Linux system:

$ ssh raspberrypi ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:69:be:bb brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.232/24 brd 10.1.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fc00::9fec:ef7f:c7d9:4ae3/64 scope global noprefixroute dynamic 
       valid_lft 86368sec preferred_lft 14368sec
    inet6 fe80::ce3f:fcf6:59a6:7a08/64 scope link 
       valid_lft forever preferred_lft forever

$ ssh raspberrypi ip -6 route
fc00::/64 dev eth0  proto kernel  metric 202 
fe80::/64 dev eth0  proto kernel  metric 256 
default via fe80::213:3bff:fe12:6fa9 dev eth0  metric 202 

$ ssh raspberrypi traceroute6 -m 6 www.google.com
traceroute to www.google.com (2607:f8b0:4002:c0c::93), 7 hops max, 80 byte packets
 1  fc00::213:3bff:fe12:6fa9 (fc00::213:3bff:fe12:6fa9)  0.891 ms  0.309 ms  0.274 ms
 2  2001:558:600d:16::1 (2001:558:600d:16::1)  8.422 ms  13.388 ms  14.183 ms
 3  te-5-4-ur01.lafayette.in.indiana.comcast.net (2001:558:322:ff89::1)  14.858 ms  14.563 ms  14.266 ms
 4  te-3-2-ur02.lafayette.in.indiana.comcast.net (2001:558:300:13f::2)  17.363 ms  18.034 ms  17.742 ms
 5  te-0-7-0-4-ar01.indianapolis.in.indiana.comcast.net (2001:558:300:140::1)  19.396 ms  20.197 ms  19.876 ms
 6  he-4-9-0-0-ar01.area4.il.chicago.comcast.net (2001:558:300:7::1)  28.450 ms  29.431 ms  33.517 ms