3

I understand that IP colisions are incredibly rare under IPv6. Most subnets are at least 64bit, meaning that the risk of true random collision is neglegable.

However there are circumstances where sources of real entropy are so limited (or broken) that the risk can rise significantly.

I read somewhere that on assigning an IP address, the host is supposed to use the neighbour discovery protocol to check whether the address exists and if so refuse to use it.

So my question is what does Linux do in this situation? If I have some software that wants to add an IP to the host, how could that software discover that the IP is taken? E.g. using the ip CLI?


There are two angles of this question that are not obvious to me and lead me to shy away from "works on my machine" approaches to discover an answer:

  1. Syntax stability and parsing the output.
  2. Timing and knowing how long to wait.

2 Answers 2

5

The kernel automatically performs Duplicate Address Detection any time an IPv6 address is added to an interface. There is nothing special that the program needs to do in order to activate DAD.

If I have some software that wants to add an IP to the host, how could that software discover that the IP is taken. Eg using the ip CLI?

The same way it adds the IP address:

  • If the program uses Netlink (rtnl) as most Linux networking tools do, then after adding the rtnl_addr object it can get (RTM_GETADDR) the same object and check its IFA_FLAGS:

    • having IFA_F_TENTATIVE means it is still undergoing Duplicate Address Detection (and in fact the kernel won't allow you to use it, unless Optimistic DAD is enabled),
    • IFA_F_DADFAILED means DAD finished and found a collision (the tentative flag may remain set as well),
    • absence of both flags means DAD finished and no collisions were found.

    The program doesn't need to wait for a specific time. The kernel's DAD code already has the necessary timers (which may vary depending on whether the kernel has optimistic_dad or enhanced_dad enabled). The program only needs to keep checking (e.g. every second) until either the 'tentative' flag disappears or 'dadfailed' appears, whichever happens first.

    Netlink also provides change notifications (like in ip monitor addr) so the program will automatically keep receiving the address object every time its flags change, without needing any poll interval.

  • If the program uses the ip CLI, then to begin with, it should stop using the ip CLI and start using interfaces meant for machine use, namely Netlink. But if that's not possible then the program should use ip -json to query the addresses, parsing the output as JSON and using the same logic as for Netlink (i.e. wait until .tentative has disappeared and/or .dadfailed has appeared).

    ip -j -6 addr ls mlx0 | jq '.[].addr_info[] | {local, tentative, dadfailed}' 

    The iproute2 ip CLI itself uses Netlink, so it is not problematic in itself – it has access to all of the same information, and you can run it manually to check the same flags. But it is an interface for human consumption first and foremost.

  • If the program uses the ip CLI on a platform where there's no -json option (either because it's an ancient iproute2 version or because it's the Busybox imitation), then sorry but that's already in the "works on my computer" territory.

  • And if the program uses the old Linux 2.4 era IPv6-specific ioctl and /proc/net interfaces, then AFAIK it has no way to obtain this information, and it should be ported to Netlink – although even ip -json would already be an upgrade.

    (This specifically includes the net-tools ifconfig, as nobody has ported it to the modern Linux 2.6 ways yet. Avoid net-tools.)

0
1

I read somewhere that on assigning an IP, the host is supposed to use the neighbour discovery protocol to check if the IP exists and refuse to use it.

Yep, IPv6 Duplicate Address Detection. Basically, you send an ICMPv6 packet to a special address, putting the :: IPv6 as source address, and you'll get information that you can later query (e.g. via ip neighbor).

But: common connection establishment tools do that for you; for example, if you add an address with ip address add, your system will perform DAD and if that detects a collision, assignment would fail. (You can disable that manually, though.) ip addr add --help is your friend :)

5
  • Could you be a bit more specific. When you say "IP address assignment will fail" will the command return non-zero / error output or will I need to check back with another command. That was really the point of the question. Commented yesterday
  • have you tried? This is really riskless to try on your machine, an interface can have any number of IP addresses, and you can just try to add the ip address of an existing neighbor). Check the contents of ip addr show after you tried to add the conflicting address! Commented 20 hours ago
  • These days I'm very cautious around "works on my machine" solutions. The point of this question to ask how it can be detected. Commented 19 hours ago
  • 1
    as said, you let Linux DAD run on it and check the output of ip addr show. That's how you'd do it. (you can also read the interface address properties with other userland tools than ip, but that's not any better than reading ip) Commented 19 hours ago
  • (DAD is, as far as I read RFC 2462 right now, not idempotent: the pure sending of the request packets changes the available addresses that other nodes might consider. As such, there's no "harmless probing". You really ought to use the address you asked for afterwards Commented 18 hours ago

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.