Feature idea: support for explicit "IP ranges"
An IP range would have a start address and an end address attribute, a name, and a VRF. It would be independent from IP prefixes.
Use case 1: documentation of ranges within a prefix. For example, in our current dumb spreadsheet we have assigned logical ranges for user assignment
and I prefer not to lose that information when moving to Netbox.
Use case 2 (related to #761): a cleaner way of defining IP pools, rather than enumerating all addresses within a range and setting their status individually to "DHCP Pool". The current model wouldn't work very well if you wanted a large IPv6 pool. Also, generating a DHCP config from this involves iterating over all the addresses and collecting adjacent ones together to form a single range, which is messy.
Use case 2a: for redundancy you have two DHCP servers on a subnet with separate ranges, e.g. DHCP1 has pool .50-.149 and DHCP2 has pool .150-.249
Use case 3 (related to #665): be able to automatically assign the next available address from within a specific range. For example: suppose your address plan for a /24 reserves .1-.9 and .250-.254 for infrastructure. So you define a named range .10-.249 and then on demand assign the next available address from within that range. This would be particularly helpful for automatic assignment via an API.
This last case can also be handled by marking addresses unused addresses in the .1-.9 and .250-.254 ranges as status "reserved". That may be reasonable for IPv4, but might not work well for IPv6, e.g. if your plan had
It also doesn't let you assign from two or more ranges within the same prefix - e.g. going back to use case 1, "assign next Tester address" or "assign next Admin/Developer address"
Let's assume have defined 192.0.2.100 through 192.0.2.199 (inclusive) as a DHCP pool. How would you handle a scenario where 192.0.2.123 has become statically assigned and needs to be removed from the pool?
The current model wouldn't work very well if you wanted a large IPv6 pool.
Why wouldn't it work? (I've never used DHCPv6.)
Also, generating a DHCP config from this involves iterating over all the addresses and collecting adjacent ones together to form a single range, which is messy.
The netaddr library (which NetBox uses for IP calculations) makes this super easy.
Let's assume have defined 192.0.2.100 through 192.0.2.199 (inclusive) as a DHCP pool. How would you handle a scenario where 192.0.2.123 has become statically assigned and needs to be removed from the pool?
Well, I can think of two scenarios.
The statically assigned address is already known to the DHCP server (e.g. via a fixed MAC address to IP address mapping). In this case there is no need to shrink the pool, it can still span the assigned address [^1]
The statically assigned address was was someone stupidly putting a statically-assigned piece of equipment in the middle of a DHCP pool. In this case your options are:
2a. Same as 1: tell the DHCP server about the static allocation. It should be fine to skip it.
2b. At worst, split the pool into two pools:
~
range 192.0.2.100 192.0.2.122;
range 192.0.2.124 192.0.2.199;
~
But this doesn't mean you need to create two separate "IP Range" objects in the database.
Let's assume the worst case, and your DHCP server does not support reserving individual addresses. Then, when generating the config, you read out an IP Range object from the database, covering the range 192.0.2.100 to 192.0.2.199
You then also query the database for all Active IP objects which sit within the range. Suppose you find 192.0.2.123 and 192.0.2.150. Then you can easily output the broken-up ranges:
The only difference between this and the current model is:
The current model wouldn't work very well if you wanted a large IPv6 pool.
Why wouldn't it work? (I've never used DHCPv6.)
If you want a pool from 2001:db8::1000 to 2001:db8::1fff, you need to add 4,096 separate entries into your database. If you want a pool from 2001:db8::1000 to 2001:db8::ffff, you need to add 64,512 database records.
This is an inefficient way to represent a pool, and will badly clutter the user interface.
Also, generating a DHCP config from this involves iterating over all the addresses and collecting adjacent ones together to form a single range, which is messy.
The netaddr library (which NetBox uses for IP calculations) makes this super easy.
It still involves a large database query to read all the addresses where status = DHCP Pool.
[^1] At least, I'm pretty sure this works for sane DHCP servers like ISC dhcpd.
The documentation says:
Any IPv6 addresses given to hosts with fixed-address6 are excluded from the range6, as are IPv6 addresses on the server itself.
Admittedly, I can't see an equivalent statement for an ipv4 range, but I very much doubt it allocates a fixed-address to any random device. I've not tested it though. I use static mappings for DHCP all the time, but I pick addresses outside of the pool for clarity.
You then also query the database for all Active IP objects which sit within the range. Suppose you find 192.0.2.123 and 192.0.2.150. Then you can easily output the broken-up ranges
Oh, and this is super-easy too :-)
~~~
s = netaddr.IPSet(netaddr.IPRange('192.0.2.100','192.0.2.199'))
list((s - netaddr.IPSet(['192.0.2.123','192.0.2.150'])).iter_ipranges())
[IPRange('192.0.2.100', '192.0.2.122'), IPRange('192.0.2.124', '192.0.2.149'), IPRange('192.0.2.151', '192.0.2.199')]
~~~
Same as 1: tell the DHCP server about the static allocation.
NetBox is responsible for telling the DHCP server about the allocation. It should be possible to generate a DHCP server configuration from scratch using only the information available in NetBox (at least, that's the philosophy).
The implementation of IP ranges boils down to incurring additional processing logic at read time versus additional storage in the database. At the moment, I don't think the trade-off is worth it for IPv4 alone: It's usually going to be safer and more efficient to store discrete IPs directly, rather than storing a range, converting it to discrete IPs, and coalescing it with other ranges and/or sets of IPs. It may be worthwhile given the potentially overwhelming size of IPv6 pools, but that doesn't seem like it'd be a very common use case. Specifically, we're talking about a scenario wherein a) DHCPv6 is in use rather than SLAAC, and b) pools much larger than their IPv4 equivalents are required.
a) DHCPv6 is in use rather than SLAAC
SLAAC is an operational nightmare, due to constantly-changing privacy addresses. DHCPv6 addresses stick with the client for as long as it has a lease. Hence I disable SLAAC everywhere and use DHCPv6 exclusively.
b) pools much larger than their IPv4 equivalents are required.
In a campus network, an IPv4 pool of /22 (of private IPs) is fairly reasonable for a wifi network where users are constantly walking in and out of range, and you don't want to use a ridiculously low lease time. You might have a subnet like that per building.
For IPv6, a pool from ::1000 to ::1fff is a reasonable minimum to avoid any risk of pool exhaustion.
I'll chime in that I don't think this is purely a v4 vs v6 (i.e. quantity of IPs) issue. IMHO, it's about manageability of IPs inside of subnet boundaries.
Let's assume have defined 192.0.2.100 through 192.0.2.199 (inclusive) as a DHCP pool. How would you handle a scenario where 192.0.2.123 has become statically assigned and needs to be removed from the pool?
Tell whichever engineer not to allocate IPs from a DHCP range ;)
At some point though, one can't wholly protect a system from someone who can write to it. More realistically though, you could disallow assignment of IPs from a defined range.
The netaddr library (which NetBox uses for IP calculations) makes this super easy.
Regarding this - netaddr is great, but consider @candlerb's example of multiple assignments inside a range of IPs one is trying to build into a DHCP range - there's no beginning or end to the range, so how do you validate if the assignment is supposed to be inside the "range"? As shown, one ends up with N DHCP pools, fractured against the "rogue" assigned IPs, instead of one well-defined, construct with contiguous member IPs. Generating and managing configs from data like this is what scares me - not IP calculations. ( also, how do you know the clients are even python? ;) )
All this being said, I'm not 100% sure that we _must have_ ranges as described, but I am certain that there isn't enough metadata about addresses, by default, to work around their absence. For example, we can derive this about an address:
In our case, to at least distinguish between DHCP reservation ranges and dynamic ranges, we have modified the Status options so we can represent IPs in more states than currently available. So now, we have "DHCP dynamic" and "DHCP reservation" and I rely on trout-slapping my engineers if they hand out IPs with the wrong status - it solves one problem for our case but monkeypatching isn't a great pattern.
Ranges, in contrast, would be multifunction - they can define series of IPs that should or should not be used for any particular purpose, and could potentially affect behavior (read-only ranges) or hold more data about their member IPs without cluttering the Address model. I'd envision them as many-to-one from address to range - no nesting, no membership in multiple ranges, no range overlaps, keep the queries low and keep changes to the address model to a minimum.
For some completely different angles:,
If any of these approaches are appealing, I'm happy to invest work on them.
I'm also in search for such a feature, where I'm able to easily assign a range of IP adresses to machines without creating all of them (especially for IPv6).
For example, when a customer leases an additional IP subnet, I'd like to assign all those IP's to his interface (except the gateway) so they show up as "reserved" or "active" and count towards my utilization.
Currently I use the import feature to import a handcrafted CSV list, which adds the IPv4 addresses and links it with the interface - but for IPv6 this isn't really an option..
+1
We need this feature for reserving some ip for ex: broadcast ip and Network IP.
If we reserve an IP, other user can change it by mistake.
As a separate issue, I wonder if Netbox ought to avoid letting users create network or broadcast IP, unless the prefix is /31 or /32 or the role is special like anycast?
Adding my $0.02 - ranges are necessary to document existing configuration/behaviour where the DHCP (in particular) range does not fall on any bit boundary, e.g. our convention is to have x.x.x.100-x.x.x.199 handed out via DHCP. I don't care what's in there, but I do care that it's DHCP. I also care, when using Netbox' IPAM features to find the next available address, that the user doesn't think .100 is available for use!
N.b. I'm not generating configs using Netbox, I'm just using it for documentation.
Found this issue while pondering how to model our IPAM case.
"Ranges" would be useful for documenting "parts" of a subnet for many things other than DHCP. Subnets may be logically split into different purposes, say inside a /24 the lower /25 would be used for x and upper /25 used for y.
Currently I have created dummy subnets (/25s continuing the above example), but this actually breaks when starting to use the Netbox API for automation. I guess I could somehow mark those dummy subnets and filter them out but I am clearly not alone in needing a proper way to do it.
In short, I would also need this feature for creating logical "ranges" inside subnets for strictly documentation purposes (that's what Netbox is for after all?).
Edit: I ended up putting the dummy subnets into a special VRF in Netbox. That is obviously not optimal and the dummy subnets have other problems.
The "range" functionality would be useful for VLANs also.
This feature is necessary to represent DHCP. Create DHCP Pools, independently of the Prefix is a common task for network admins.
@jscmenezes DHCP pools can already be represented by creating the appropriate set of individual IP addresses and setting their status to DHCP.
It looks like this feature request needs to be revisited, as a concrete database model for representing IP ranges has not yet been proposed. I get the feeling different people have different ideas of what this entails. Happy to continue the discussion here, or reboot the discussion in a new issue. Either way, we'll need to nail down exactly what changes are being proposed before work can commence.
To me the range would be an additional field similar to description that would apply to several IP addresses with a beginning and an end IP address (or a prefix).
It would be used as a note about the intended usage of the IP addresses.
For example it would be used to tell that a lower half of a /20 is for servers located in Row A and upper half in Row B. Or that the first 20 IP addresses are reserved for web servers, second 20 is for caches, and so on. Any of those addresses could be in use or free.
How should it be shown in the web interface? Should there be an additional entry under IPAM menu?
Then the range(s) could be visible in IP address lists in their own column, and when viewing an individual IP address with links to those ranges?
It looks like this feature request needs to be revisited, as a concrete database model for representing IP ranges has not yet been proposed.
My proposal is:
IPAM > Ranges. Existing IPAM > IP Addresses and IPAM > Prefixes remain unchanged.class IPAddress. Instead of address there would be start_address and end_address, which would be plain IP addresses (without mask). It would not have the assigned_object*, nat_inside or dns_name attributes.name and/or slug attributes.status choices are limited to "Active", "Reserved", "Deprecated"role choices could be limited to "DHCP Pool", "Assignment Pool" initially. (Or perhaps they should use Prefix/VLAN roles, which are user-defined?)I think in general it's OK if Ranges are allowed to overlap, and/or to wholly contain other ranges. But you probably shouldn't be allowed to create a second range with identical start and end and VRF.
It would be helpful to have a migration which changes all IP addresses with status "DHCP" into Ranges. This could be done automatically if there is a contiguous range of IP addresses which have identical attributes; they would be replaced with a single Range. (To avoid forcing this change unexpectedly, it could be provided as an extra script which is run when a user requests, in which case the "DHCP" status for IP Addresses can be retained for now but deprecated)
In the UI:
Aside: I did consider making Range an explicit child of Prefix - i.e. has a foreign key to a parent Prefix. Instead of start_address and end_address there would be start_offset and end_offset, which are validated to be between 0 and the parent prefix size minus 1. VRF field is not required, as this is implicitly the same as its parent prefix.
The advantages of this approach are:
The disadvantages are:
For these reasons, I think Ranges which know their VRF and have absolute start and end addresses make more sense.
viewing a Prefix should show its child Ranges as well as its child IP Addresses. This would most simply be done as an extra tab
That doesn't seem like it would be an acceptable solution. As a user, I expect to see _all_ allocated IP space within a prefix in a consistent, ordered list, including both individual IPs and ranges. Simply viewing one type or the other would not provide an complete representation of available space within the prefix.
Consider a user looking at a prefix 192.168.0.0/23, which is used as a pool for loopback IPs. To allocate a new address, I shouldn't need to check the existing IPs and then go check for any declared ranges within the prefix before creating a new IP address.
This means we need a solution for collating both individual addresses and ranges in the same view (both in the UI and the REST API), including enforcing permissions for both. I think this is the major blocker for this FR. There is no pattern for such a solution in NetBox today, but I'm open to reasonable suggestions.
I think in general it's OK if Ranges are allowed to overlap, and/or to wholly contain other ranges. But you probably shouldn't be allowed to create a second range with identical start and end and VRF.
That seems inconsistent IMO. If two ranges can partially overlap, why not permit them to fully overlap? Additionally, we would need to honor the VRF's enforce_unique attribute (as well as ENFORCE_GLOBAL_UNIQUE for the global table), allowing overlap only when it's permitted. So that's an extra layer of validation needed, to check for overlapping ranges.
Something else I wanted to mention: I've noticed some people seem to discuss IP ranges as a substitute for defining individual IP addresses. For example, you might create a range of .100 - .200 within an IPv4 /24 prefix to convey that those IP addresses are used, and users would not be able to create any individual IPs captured by the range. However, they way @candlerb describes it above, a range would be more of a subset of a prefix, from which individual IPs could still be allocated.
I think there's a use case for either approach, but wanted to call out the subtle distinction.
As a user, I expect to see all allocated IP space within a prefix in a consistent, ordered list, including both individual IPs and ranges. Simply viewing one type or the other would not provide an complete representation of available space within the prefix.
Certainly: the UI I proposed was minimal viable product, and it doesn't affect the data model.
It agree that normally it would be more user-friendly to show ranges in-line with IP addresses. Already the unused gaps between IP addresses are merged into implicit ranges, and shown in a different colour with a description, and are clickable to create a new IP address from the bottom of the available range.
I am sure this could be extended to view explicit ranges. e.g.
If a range contains IP allocations, then they can be nested underneath and/or colored differently:
Having said that, sometimes I'd like to be able to see just the ranges (e.g. show me just the DHCP pools), so it would be nice to collapse to just the ranges.
If two ranges can partially overlap, why not permit them to fully overlap?
I thought that in order to be consistent with Prefixes: you can't create 1.0.0.0/24 twice, but you can created child prefixes.

In practice, I don't expect ranges-within-ranges will be very useful, and it wouldn't be a major limitation if they could not overlap at all (which is easy to enforce: ensure no range contains either the start or end address of any other range).
Disallowing overlapping ranges would probably be required for the merged IP+range view shown above, so I'd accept it for that reason alone.
For example, you might create a range of .100 - .200 within an IPv4 /24 prefix to convey that those IP addresses are used, and users would not be able to create any individual IPs captured by the range. However, they way @candlerb describes it above, a range would be more of a subset of a prefix, from which individual IPs could still be allocated.
This goes back to the original use cases:
I think the solution here is to add a flag to the Range saying whether allocations are permitted. This would be similar to the flag on Prefix which says "is a pool". What this should do is:
What I mean is, with "Allocation enabled" the UI would look like this:
With "Allocation disabled" it looks like this:
There's nowhere to click to auto-allocate within a range. But this doesn't prevent you from creating (say) 1.2.3.9 manually.
If someone does create 1.2.3.9 manually, it might be reasonable to pop up a warning dialog ("Warning: you are creating an IP address within range FOO").
There is one other issue I can think of, which is allocation of prefixes rather than individual IP addresses.
One IPAM use case is "allocate me the next available /28 prefix from range FOO". Doing that in the GUI, you'd want to be able to see all the prefixes contained within range FOO. In practice, it may be sufficient to allocate prefixes from a parent prefix, rather than prefixes from a range.
Already the unused gaps between IP addresses are merged into implicit ranges, and shown in a different colour with a description, and are clickable to create a new IP address from the bottom of the available range. I am sure this could be extended to view explicit ranges. e.g.
The difference is that unallocated space is calculated dynamically as a function of the prefixes that have already been retrieved from the database; no other information is necessary to display these "filler" objects. IP ranges, however, are discrete objects that would also need to be retrieved from the database and collated with individual IP addresses. This is rather complex, particularly when you consider the need to support arbitrary pagination through the queryset.
I thought that in order to be consistent with Prefixes: you can't create 1.0.0.0/24 twice, but you can created child prefixes.
The creation of duplicate prefixes is configurable, by toggling the parent VRF's enforce_unique attribute and (for the global table) the ENFORCE_GLOBAL_UNIQUE configuration parameter. When ENFORCE_GLOBAL_UNIQUE is set to False, NetBox will permit the creation of multiple duplicate prefixes and/or IP addresses in the global table. We want to ensure that this behavior carries forward to IP ranges.
I think the solution here is to add a flag to the Range saying whether allocations are permitted.
Maybe, but this would complicate validation even further. We would need to check for ranges whenever creating or modifying an IP address, and check for IP addresses whenever creating or modifying a range. I'm not saying it isn't feasible, but the more conditional logic we pile into a solution, the more fragile it becomes.
Hi Netbox-Community,
here is the ideia of IP Ranges in the University where I work.
Users MUST register their device at first attempt to connect to our
network. At this time, we reserve an IP address to that device/user and
then DHCP always OFFER the same address.
The problem is with users's permission. We need, many times, small ranges
to offer to a University's department.
For example, we assigned 192.168.1.0/24 to our Physical Institute. Then we
need to reserve 10 first IPs to infrastructure, 5 IPs to printers and 10
IPs for Access Points. All this ranges are excluded from the DHCP scope.
Furthermore, many ranges (pools) with specific user permission inside the
original /24 prefix, e. g., 192.168.1.50-65 (Quantic Departament),
192.168.1.66-70(Mechanical Physics Departament)...
I do this model for a django prototype app: https://pastebin.com/97bxQW60
I am a begginer with django.
Regards,
Jerônimo
Em ter., 22 de dez. de 2020 Ã s 12:42, Jeremy Stretch <
[email protected]> escreveu:
Already the unused gaps between IP addresses are merged into implicit
ranges, and shown in a different colour with a description, and are
clickable to create a new IP address from the bottom of the available
range. I am sure this could be extended to view explicit ranges. e.g.The difference is that unallocated space is calculated dynamically as a
function of the prefixes that have already been retrieved from the
database; no other information is necessary to display these "filler"
objects. IP ranges, however, are discrete objects that would also need to
be retrieved from the database and collated with individual IP addresses.
This is rather complex, particularly when you consider the need to support
arbitrary pagination through the queryset.I thought that in order to be consistent with Prefixes: you can't create
1.0.0.0/24 twice, but you can created child prefixes.The creation of duplicate prefixes is configurable, by toggling the parent
VRF's enforce_unique attribute and (for the global table) the
ENFORCE_GLOBAL_UNIQUE configuration parameter. When ENFORCE_GLOBAL_UNIQUE
is set to False, NetBox will permit the creation of multiple duplicate
prefixes and/or IP addresses in the global table. We want to ensure that
this behavior carries forward to IP ranges.I think the solution here is to add a flag to the Range saying whether
allocations are permitted.Maybe, but this would complicate validation even further. We would need to
check for ranges whenever creating or modifying an IP address, and check
for IP addresses whenever creating or modifying a range. I'm not saying it
isn't feasible, but the more conditional logic we pile into a solution, the
more fragile it becomes.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/netbox-community/netbox/issues/834#issuecomment-749607211,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AC4DSVR6YSLUXHN6WH4U3R3SWC455ANCNFSM4C5LYEKQ
.
Most helpful comment
Adding my $0.02 - ranges are necessary to document existing configuration/behaviour where the DHCP (in particular) range does not fall on any bit boundary, e.g. our convention is to have x.x.x.100-x.x.x.199 handed out via DHCP. I don't care what's in there, but I do care that it's DHCP. I also care, when using Netbox' IPAM features to find the next available address, that the user doesn't think .100 is available for use!
N.b. I'm not generating configs using Netbox, I'm just using it for documentation.