A magical new legacy free Internet where every device automatically gets a link local fe80::/64 and a publicly routable address.
In IPv6 world every network interface will have multiple addresses defined. Old ifconfig
might not show them, its better to use commands from iproute2. package. IP aadress management is done using ip address command.
ip address show
Or you can shorten it to just
ip a
That will list all of the currently configured IP addresses.
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet 193.40.103.202/32 brd 193.40.103.202 scope global lo:202
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether c2:bf:b2:8b:4f:37 brd ff:ff:ff:ff:ff:ff
inet 172.20.20.102/16 brd 172.20.255.255 scope global ens18
valid_lft forever preferred_lft forever
inet6 2001:bb8:4008:20:c0bf:b2ff:fe8b:4f37/64 scope global dynamic mngtmpaddr
valid_lft 2591858sec preferred_lft 604658sec
inet6 fe80::c0bf:b2ff:fe8b:4f37/64 scope link
valid_lft forever preferred_lft forever
Iproute2 information density is quite high, running
ip -c a
adds color to the output and makes it easier to read. I usually create an alias for italias ip='ip -c'
.ip -6 -c a
is even better – it removes all legacy (IPv4) clutter from the output.
Every interface should by default have an Link-local address
inet6 fe80::abcd/64
And because every IPv6 host also subscribes ff02::1
address, you can ping every single host in local LAN. By default ping
does not know that interface to use for the ping, so we have to tell by appending zone index to the IPv6 address.
ping ff02::1%ens18
PING ff02::1%ens18(ff02::1%ens18) 56 data bytes
64 bytes from fe80::c0bf:b2ff:fe8b:4f37%ens18: icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from fe80::1ec1:deff:fe1c:2ab2%ens18: icmp_seq=1 ttl=64 time=0.333 ms (DUP!)
64 bytes from fe80::242e:89ff:fea0:2981%ens18: icmp_seq=1 ttl=64 time=0.353 ms (DUP!)
...
64 bytes from fe80::3858:47ff:fe9a:53c6%ens18: icmp_seq=1 ttl=64 time=4.91 ms (DUP!)
64 bytes from fe80::648c:5eff:fe74:ce4%ens18: icmp_seq=1 ttl=64 time=5.03 ms (DUP!)
^C
--- ff02::1%ens18 ping statistics ---
1 packets transmitted, 1 received, +105 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.080/2.692/5.026/0.981 ms
After you can check local neighbours cache to see those same hosts
ip -6 neigh
You can also use the same Link-Local address for ssh
ssh arti@fe80::e422:deff:fefa:612b%ens18
Link-Local addresses can't be routed over the Internet and work only on local LAN. For routing to the public Internet, an IPv6 has to figure out
Where a are the local routers
Configure an publicly routable IP address using
This whole process is called Stateless address autoconfiguration.
Local routers are discovered by listening for ICMPv6 Neighbor Discovery Protocol. Router Advertisement packets on multicast or any of the Link-Local addresses. To speed up the router discovery, host can also send Router Solicitation packets to ff02::2
.
Router Advertisement (RA) packets contain what public IPv6 subnets are routed through that router. RA packets can also contain DNS server info or have a bit set that tells the host to obtain DNS server info via DHCPv6.
rdisc6
from ndisc6 project can be used to test if Router Advertisment packets are working and contain correct information.
sudo rdisc6 ens18
[sudo] password for arti:
Soliciting ff02::2 (ff02::2) on ens18...
Hop limit : undefined ( 0x00)
Stateful address conf. : No
Stateful other conf. : Yes
Mobile home agent : No
Router preference : medium
Neighbor discovery proxy : No
Router lifetime : 1800 (0x00000708) seconds
Reachable time : unspecified (0x00000000)
Retransmit time : unspecified (0x00000000)
Source link-layer address: 90:E2:BA:82:8D:51
Prefix : 2001:bb8:4008:20::/64
On-link : Yes
Autonomous address conf.: Yes
Valid time : 2592000 (0x00278d00) seconds
Pref. time : 604800 (0x00093a80) seconds
from fe80::92e2:baff:fe82:8d51
Now that our host knows that ens18
interface has an router on address fe80::92e2:baff:fe82:8d51
that routes subnet 2001:bb8:4008:20::/64
, we can start generating a publicly routable IPv6 address in that prefix subnet. This is done automatically by Linux kernel or by systemd-networkd.
I theory you can use any address in side 2001:bb8:4008:20::/64
subnet but by default the address is generated based on interface MAC aadress using Modified EUI-64. For example systemd-networkd has a config option called IPv6Token= that is used to configure the generated suffix. This can be useful if you want to generate interesting vanity addresses.
ip -6 addr show br-zoo
8: br-zoo: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 state UP qlen 1000
inet6 2001:bb8:4008:20::bad:c0de/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 2591932sec preferred_lft 604732sec
inet6 fe80::e422:deff:fefa:612b/64 scope link
valid_lft forever preferred_lft forever
You can view it by using ip route command.
ip -6 route show
or shorter
ip -6 r
::1 dev lo proto kernel metric 256 pref medium
2001:bb8:4008:20::/64 dev ens18 proto kernel metric 256 expires 2591714sec pref medium
fe80::/64 dev ens18 proto kernel metric 256 pref medium
default via fe80::92e2:baff:fe82:8d51 dev ens18 proto ra metric 1024 expires 1514sec pref medium
If you added -c
alias to your .bashrc
then you can also get pretty colors here.
IPv6 subnet delegation
https://wiki.archlinux.org/index.php/IPv6
http://www.policyrouting.org/iproute2.doc.html