Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic prefix length for individual IP addresses #800

Closed
candlerb opened this issue Jan 16, 2017 · 6 comments
Closed

Automatic prefix length for individual IP addresses #800

candlerb opened this issue Jan 16, 2017 · 6 comments

Comments

@candlerb
Copy link
Contributor

candlerb commented Jan 16, 2017

According to the documentation:

An IP address comprises a single address (either IPv4 or IPv6) and its mask. Its mask should match exactly how the IP address is configured on an interface in the real world.

It would save time and errors if when allocating an "IP Address" I could enter just the IP address without the prefix length (mask).

Use cases

  1. I type "1.2.3.4" and get told it's an error. I have to remember that this is on a /26 subnet and retype "1.2.3.4/26". I grumble.

    image

  2. Someone else types "1.2.3.5" and gets told it's an error. So they enter either "1.2.3.5/32" (because it's a single IP) or a made-up prefix which does not match reality, e.g. "1.2.3.5/24", because they don't know enough about the network topology.

    Note that it's very easy to enter nonsense here. For example you can enter IP address 10.0.99.99/16 whose parent prefix is 10.0.99.0/24 !

  3. I am importing addresses from a spreadsheet. It is tedious to work out which subnet each prefix is within and append the right prefix length - I may have to write a program to do this. If I am lazy I will just add "/32" to every IPv4 address.

    image

Possible improvements

I can think of two ways this could be improved.

Option 1

When you enter an IP address without a prefix, automatically append the prefix length of the nearest enclosing prefix object, i.e. what is picked as the "parent prefix"

This works fine if you've been good and have pre-entered all your prefixes. It also involves no change to the data model.

However if you change your prefixes later (e.g. you originally only put in prefix 10.0.0.0/16 and later you add prefix 10.0.99.0/24) then the IP addresses all need updating.

I think you would probably also need a tool which reports on all the inconsistencies (i.e. where the IP Address prefix length does not match the parent IP Prefix prefix length), and optionally can update them to be consistent.

Option 2

Change the data model to record only the address

Netbox already has a distinction between an "IP Address" and a "Prefix". An "IP Address" only ever represents a single IP Address.

So: don't store any prefix length against the IP Address object (or equivalently: store them all as /32 or /128).

This avoids all duplication and the resulting inconsistencies. If you ever want to know the correct value to use, go look at its parent prefix. From the point of view of IPAM, the only thing which matters is that a single IP address has been allocated.

Discussion

Option 2 would be my preference (I hate duplication of data), but what problems might this give?

SNMP data collection

If you were collecting interface configs from SNMP, you might want to record somewhere that the seen interface configuration was 10.0.99.99/255.255.255.0 = 10.0.99.99/24; then later run a query to highlight if there are inconsistent prefixes between multiple devices on the subnet.

But equally, at the time you collect the data you could see if there is a matching parent prefix, and warn if not. In any case, Netbox is a human-driven tool for what the network should look like, not a collection of how it has been configured.

Intentionally mismatched netmasks

There are a few cases where you might intentionally configure devices with a different prefix length on the same subnet. But again, I don't think it's the job of IPAM to record that, only which addresses have actually been allocated.

For example: you can have a /24 prefix which overlays two /25 prefixes. You could, in a strange situation, configure one device with 255.255.255.0 and another device with 255.255.255.128 netmask. But the IP address is just the IP address, 1.2.3.4.

Indeed, you would not want to record 1.2.3.4/24 and 1.2.3.4/25 as two different IP allocations, because they are the same address. The mismatched netmasks are an artefact of the way the two different devices are configured, not of the IP address itself.

However, I do expect that the decision to record prefix length with individual IP addresses was made for a good reason, and that such a fundamental change may be rejected.

@jeremystretch
Copy link
Member

jeremystretch commented Jan 17, 2017

Thanks for your feedback, but as the quoted portion of the documentation says, the mask is part of the IP address. You simply cannot configure an IP address on an interface in the real world without also specifying its mask. Omitting the mask would severely reduce the functionality of the IPAM component. Maybe that's not ideal for your use case, but it is crucial to the way NetBox functions and isn't going to change.

@candlerb
Copy link
Contributor Author

the mask is part of the IP address

OK, so how about my option 1: if the user doesn't enter a prefix length, then take the prefix length from the nearest enclosing Prefix object? (Maybe only if its state is 'Active')

It saves typing, and it reduces data entry errors, without any change to the conceptual model.

You simply cannot configure an IP address on an interface in the real world without also specifying its mask

Of course. But the mask on all addresses within that prefix is going to be the same; effectively it's a property of the prefix, not the individual IP address.

If you store it against every individual IP address, then that's duplication of data.

Omitting the mask would severely reduce the functionality of the IPAM component

Can you give a specific example of the reduction in functionality? I can't see anywhere in Netbox where the prefix length makes any difference. I can enter an address as 1.2.3.4/24 or 1.2.3.4/32 and as far as I can tell, it works the same.

One other idea you might consider.

Option 3

(This functionality to be enabled by a global config option)

  • If you enter an IP address without a prefix length, then default to /32 (IPv4) or /128 (IPv6)
  • When displaying an IP address, hide the prefix length if it's /32 (IPv4) or /128 (IPv6)

This would work for me. Individual IP addresses are entered (and appear) as individual IP addresses, and there's no multiple entry of prefix lengths. The data model is arguably "abused", as you'd be storing all IP addresses as if they were loopbacks.

I can't see what functionality would break. If you extract data from the Netbox database and want to know the prefix length for an address, you'd make the query search for the enclosing Prefix object.

@jeremystretch
Copy link
Member

OK, so how about my option 1: if the user doesn't enter a prefix length, then take the prefix length from the nearest enclosing Prefix object? (Maybe only if its state is 'Active')

This would require the user to define every prefix for which they have an IP address assigned anywhere in their network, including prefixes they likely don't care about (for example, WAN IP assignments on Internet access devices). Another example is dealing with a very large number of point-to-point prefixes: a user might not care to define each prefix, instead relying on the mask of the IP address to determine its peer.

It would also introduce the potential for conflict when modeling overlapping addresses within a shared number space. (Overlapping IP space is of course undesirable, but nonetheless something we sometimes have to deal with, so NetBox supports it.)

And finally, omitting the mask from an IP address would make it impossible to distinguish loopback IPs (/32s and /128s). If all you have is the IP 192.0.2.123 and a parent prefix of 192.0.2.0/24, you have no way of inferring whether it should be 192.0.2.123/32 or 192.0.2.123/24.

Can you give a specific example of the reduction in functionality?

Let's say I want to validate all the IP addresses assigned to every device in my network against my source of truth (NetBox). As the model is currently defined, this is an extremely efficient process. If you were to omit the mask, every single IP address would have to be looked up to find its nearest matching prefix (and you would still run into the problems listed above).

For all these reasons, the mask is stored along with the IP address in the database. If this does not suit your needs, NetBox probably isn't a good fit for you.

@candlerb
Copy link
Contributor Author

Another example is dealing with a very large number of point-to-point prefixes: a user might not care to define each prefix, instead relying on the mask of the IP address to determine its peer.

OK, that's a valid use case: an environment where you have many more WAN links than you have internal devices (e.g. a large ISP). The idea is that you can save effort entering just the IP/mask rather than IP plus prefix/mask.

However I would note that if you don't allocate the Prefix objects, then you will have a hard time allocating a new prefix for the next customer's WAN link. That is, suppose you have only these IP address objects:

  • 1.2.3.1/29
  • 1.2.3.9/30

inside a container 1.2.3.0/24, but no prefix objects. Then you want to assign the next available /29. You'll need to expand the IP addresses to prefixes to do the calculation.

It would also introduce the potential for conflict when modeling overlapping addresses within a shared number space. (Overlapping IP space is of course undesirable, but nonetheless something we sometimes have to deal with, so NetBox supports it.)

But Netbox supports overlapping address space properly, via the concept of VRFs.

Saying that 1.2.3.4/29 and 1.2.3.4/27 are on two different networks (by implication, because of the different netmasks) is icky at best. And what if you happened to use the same netmask in both locations? Then you'll have 1.2.3.4/29 and 1.2.3.4/29 and no way to distinguish them.

Furthermore, if you enable uniqueness checking, Netbox (correctly) says that 1.2.3.4/29 and 1.2.3.4/27 are conflicting because they're the same address.

For all these reasons, the mask is stored along with the IP address in the database. If this does not suit your needs, NetBox probably isn't a good fit for you.

It makes me sad that every time I enter an IP address, I also have to determine which prefix length goes with that address (which involves an additional query, or knowledge of the network), and I have to type it in, when the system knows all this information already.

I think my workaround will be to use /32 for all IPv4 addresses and /128 for all IPv6 addresses. This means no opportunity for errors or inconsistencies.

Thanks for taking the time to discuss.

@jeremystretch
Copy link
Member

But Netbox supports overlapping address space properly, via the concept of VRFs.

NetBox also supports it "improperly." That is, you can create duplicate prefixes and IP addresses within the global table (unless ENFORCE_GLOBAL_UNIQUE has been set to True). Ideally, this shouldn't be necessary, but sometimes it is. A good example is tracking a set of overlapping link-local addresses.

Saying that 1.2.3.4/29 and 1.2.3.4/27 are on two different networks (by implication, because of the different netmasks) is icky at best. And what if you happened to use the same netmask in both locations? Then you'll have 1.2.3.4/29 and 1.2.3.4/29 and no way to distinguish them.

Right, this is an example of overlapping IP space. It's not ideal, but it is possible (and in a few corner cases even reasonable) to employ in the real world, so NetBox does its best to support it. Additional data, such as site or VLAN assignment, would be needed to differentiate between them. (An example: A set of branch offices, each of which uses 192.168.1.0/24 for its isolated guest wireless network. Each prefix can be assigned to its respective site to allow for differentiation.)

It makes me sad that every time I enter an IP address, I also have to determine which prefix length goes with that address (which involves an additional query, or knowledge of the network), and I have to type it in, when the system knows all this information already.

Think of it as an investment. You enter complete information from day one, and NetBox saves it forever. The alternative is repeating the same dangerous inferences based on parent prefixes each and every time an IP is retrieved, over a long period of time during which many changes are likely to be made.

I think my workaround will be to use /32 for all IPv4 addresses and /128 for all IPv6 addresses.

I would strongly advise against this, but of course you're free to use NetBox however you'd like.

@candlerb
Copy link
Contributor Author

In case it's useful to anyone else, I have put a small patch here which lets you omit the prefix length when entering or importing an IP address (defaulting to /32 or /128), and hides the prefixlen when rendering a /32 or /128 address.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants