Understanding IP addressing and routing is not difficult, but there are some subtleties you need to be aware of.
This is a good place to start.
IP V4 addressing
An IP V4 address is like 18.104.22.168, where each number is between 0 and 255 inclusive (8 bits). You see routing statements like 22.214.171.124/24 which means the left 24 bits are significant for routing. 126.96.36.199/24 is routed the same as 188.8.131.52/24 because 192.6.24.n/24 refers to the range 184.108.40.206 to 220.127.116.11.
IP V6 addressing
IP V6 addresses are like abcd:efgh:ijkl:mnop:qrst:uvwx:yzab:cdef – or 8 groups of 4 hex digits.
Within each group leading zeros can be dropped.
The longest sequence of consecutive all-zero fields is replaced with two colons (::).
fe80:0000:0000:0000:11ad:b884:0000:0084 can be written fe80:0:0:0:11ad:b884:0:84 which can be written fe80::11ad:b884:0:84, which is a more manageable number to use.
I tend to use addresses like fe00::4 because they are short!
IP V6 prefixes
An Internet Service Provider (ISP) provides connectivity to its users. Each enterprise customer, or end user, is allocated a prefix, usually 48 digits long, and you have 16 digits for routers (the subnet) within your organisation. Normally the total prefix length is 64.
At home with a wireless router, my laptops address is 2a00:dddd:ffff:1111:65fa:229:f923:84b8. 2a00:dddd:ffff from my ISP and my subnet is 1111 within my organisation.
An address like 2001:db8::/64 is the range 2001:db8:0:0:0:0:0:0 to 2001:db8:0:0:ffff:ffff:ffff:ffff.
An address like 2001:db8::9/128 is the single address 2001:db8:0:0:0:0:0:9, because all digits are significant.
There are different levels of IP V6 addresses
- Addresses starting with fe80::, called link-local addresses, are assigned to interfaces for communication on the attached link. If you think of lots of machines on an Ethernet connection, they have a fe80… address. They tend to be used internally by Dynamic Routing. I haven’t explicitly used one.
- “global” addresses – or not on an Ethernet cable.
- fc00::/7 Unique Local Addresses (ULA) – also known as “Private” IPv6 addresses. They are only valid within an enterprise.
- 2…::/16 Global Unique Addresses (GUA) – Routable IPv6 addresses. These addresses allow you to access resources, such as web sites, outside of your domain. My ISP provides me with an address 2a00:abcd:….
Some addresses are reserved, for example
- 2001:db8::/32 is reserved for documentation, these addresses do not leave your enterprise.
- fe80::/10 Addresses in the link-local prefix. These are allocated to the “cable” or connection between two nodes. Two different “network cables” can have the same fe80… address because they are on different cables.
- fc00/12 are addresses which are within your enterprise. Routers will not send these addresses out of its domain.
- ff02::1 Multicast, all nodes in the link-local
- ff02::2 Muticast, all routers in the link-local
- ff05::2 All routers in the site-local (in your machine)
See here for a more complete list.
Defining an address
If I define an address for connection (on Linux) I can use
- sudo ip -6 addr add 2001::99 dev tap1, this is one address. When displayed this gives 2001::99/128
- sudo ip -6 addr add 2001::999/64 dev tap1, this is an address, and when used in routing, use the left 64 bits. When displayed this gives 2001::999/64
It is important to understand how the prefix affects the routing behaviour.
If I have two Ethernet connections(interfaces) into my laptop. I want traffic for 2001::a:0:0:0 to go via interface A, and traffic for 2001::b:0:0:0 to go via interface B.
If I use
sudo ip -6 route add 2001::a:0:0:0/64 dev A sudo ip -6 route add 2001::b:0:0:0/64 dev B
then this will not always work. With 2001::a:0:0:0/64 the prefix is 2001:0:0:0:a:0:0:0/64. When comparing a packet with address 2001::b:0:0:0 with each route; both routes are available, because 2001:0:0:0 matches both, and if the packet gets sent to 2001::b:0:0:0 it will be lost.
You either need to move the a/b to make them significant, 2001:0:0:a::/64 and 2001:0:0:b::/64 or use 2001:0:0:0:a::/80 and 2001:0:0:0:b::/80 in the routing statements.
The system needs to be able to route traffic to the correct interface, so you need to be careful how you set up the routing.
Does this make sense?
sudo ip -6 route add 2001:db8::99/64 dev eno1 metric 1024 pref medium
is the same as
sudo ip -6 route add 2001:db8::/64 dev eno1 metric 1024 pref medium
because the routing only looks at the left 64 bits. The ::99 is ignored.
Having the :99 makes it a bit more confusing for those stumbling about trying to understand this topic. I’ve had to rewrite some of my blog posts where I use 2001:db8::99/64 in the routing.
In the case of
sudo ip -6 route add 2001:db8::99/128 dev eno1 metric 1024 pref medium
the ::99 is relevant. A packet for 2001:db8::98 would not be routed down this definition because all 128 bits of the route definition are relevant.