inetaf / netaddr

Network address types

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How does IPSet handle IPv6 zones?

danderson opened this issue · comments

In #126, the question came up of what the set complement of an IPSet containing a v6+zone address would be.

In strict math terms, the complement of a set with no IPv6 is the infinite set of all possible IPv6s in all possible zones. Obviously, we can't do that :)

@josharian suggested, for Complement specifically, to scan s.Ranges(), find all zones in use, and generate the complementary IPv6s for those zones only. So, if you have ::1%eth0 in the set, taking the complement would add (all IPs except ::1)%eth0. That feels a bit weird to me though, I'm unsure if that makes sense as an API user.

s.Ranges also doesn't deal with zones properly. Given s.AddPrefix("::/0%eth0"), s.Remove("::10"), s.Ranges currently will slice up ::/0%eth0, and some of those ranges won't preserve the zone.

Going even wider, IPRange also doesn't handle zones properly - more accurately, it ignores zones entirely, so you can have a range from ::1%eth0 to ::10%eno4, and that would compare unequal to ::1-::10, but behave like ::1-::10 in practice.

Options:

  1. Status quo: declare that IPRange and IPSet are zones-agnostic, and if you expect zones to make sense within them you're going to have a bad time.
  2. Declare IPRange and IPSet to not support zones. Make IPRanges with zones invalid, make IPSets containing zone-ful ranges equally invalid.
  3. Add zone support. Make IPRange valid only if To.Zone() == From.Zone(), make IPSet behave sensibly given valid IPRanges (including probably the Complement behavior @josharian suggested, but also correcting Range to be zone-aware, etc.)

Thoughts @bradfitz @josharian @mdlayher ?

Zones, the gift that keeps on giving.

Another option for complement is to force the caller to provide the universe (as another IPSet). Which is, I suppose, to eliminate complement and tell people to use difference instead. We could have some convenience functions to generate common universe sets, like AllIPv4, AllIPv6, AllIP.

I think we should either actively reject zones or completely support them. That is, I do not like option 1. I don't feel strongly between 2 and 3.

Providing the universe is an interesting idea. We could still keep Complement, but specify that its universe is AllIP, so if you're not doing whacky things, you get a handy helper. If you are doing whacky things, well, set difference is your friend.

Note I was wrong, #84 made IPRanges somewhat zone-aware, in that mixed-zone ranges are invalid. They still don't handle zones correctly in other areas (e.g. Contains() doesn't return the correct answers).

I think I'm lean toward option 3 assuming it can be done without immense complexity or corner cases. If the caller has zones in their addresses then I assume they know what they are doing with them (link-local IPv6 addresses being the primary use case).