IP address ranges #654

Closed
opened 2025-12-29 16:24:21 +01:00 by adam · 37 comments
Owner

Originally created by @candlerb on GitHub (Jan 23, 2017).

Originally assigned to: @jeremystretch on GitHub.

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

  • 10.10.2.151 - 10.10.2.160 : Tester range
  • 10.10.2.180 - 10.10.2.253 : Admin/Developer range

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

  • ::0 to ::fff - reserved for infrastructure
  • ::1000 to ::ffff - available for assignment

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"

Originally created by @candlerb on GitHub (Jan 23, 2017). Originally assigned to: @jeremystretch on GitHub. 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 * 10.10.2.151 - 10.10.2.160 : Tester range * 10.10.2.180 - 10.10.2.253 : Admin/Developer range 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 * ::0 to ::fff - reserved for infrastructure * ::1000 to ::ffff - available for assignment 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"
adam added the status: acceptedtype: feature labels 2025-12-29 16:24:21 +01:00
adam closed this issue 2025-12-29 16:24:21 +01:00
Author
Owner

@jeremystretch commented on GitHub (Jan 23, 2017):

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.

@jeremystretch commented on GitHub (Jan 23, 2017): 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](https://netaddr.readthedocs.io/en/latest/tutorial_03.html#convert-an-ip-set-to-an-ip-range).
Author
Owner

@candlerb commented on GitHub (Jan 23, 2017):

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.

  1. 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]

  2. 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:

  • 192.0.2.100 to 192.0.2.122
  • 192.0.2.124 to 192.0.2.149
  • 192.0.2.151 to 192.0.2.199

The only difference between this and the current model is:

  • In the current model you create all addresses from 192.0.2.100 to 192.0.2.199 with status "DHCP Pool", and then change .123 and .150 to status "Active"
  • In the range model, you create a range from 192.0.2.100 to 192.0.2.199, and create .123 and .150 with status "Active", or a new status like "DHCP Excluded"

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.

@candlerb commented on GitHub (Jan 23, 2017): > 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. 1. 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] 2. 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: * 192.0.2.100 to 192.0.2.122 * 192.0.2.124 to 192.0.2.149 * 192.0.2.151 to 192.0.2.199 The only difference between this and the current model is: * In the current model you create all addresses from 192.0.2.100 to 192.0.2.199 with status "DHCP Pool", and then change .123 and .150 to status "Active" * In the range model, you create a range from 192.0.2.100 to 192.0.2.199, and create .123 and .150 with status "Active", or a new status like "DHCP Excluded" > > 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](https://linux.die.net/man/5/dhcpd.conf) 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.
Author
Owner

@candlerb commented on GitHub (Jan 23, 2017):

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')]
@candlerb commented on GitHub (Jan 23, 2017): > 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')] ~~~
Author
Owner

@jeremystretch commented on GitHub (Jan 23, 2017):

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.

@jeremystretch commented on GitHub (Jan 23, 2017): > 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.
Author
Owner

@candlerb commented on GitHub (Jan 23, 2017):

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.

@candlerb commented on GitHub (Jan 23, 2017): > 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.
Author
Owner

@explody commented on GitHub (Dec 15, 2017):

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:

  • Status (includes one "DHCP" option)
  • Whether it's assigned to an interface or not
  • Role (not useful in this context unless it were expanded to more roles)

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:,

  • Tagging could_almost_ achieve the same thing while being entirely freeform, and still pushing most logic out to the consumer (e.g. "Status: DHCP Tags: Dynamic" or "Status: Reserved Tags: Infrastructure").
  • Make Statuses and Roles user-extensible - perhaps combos of customizable fields would obviate needing additional constructs (and would be way faster than custom fields)

If any of these approaches are appealing, I'm happy to invest work on them.

@explody commented on GitHub (Dec 15, 2017): 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: * Status (includes one "DHCP" option) * Whether it's assigned to an interface or not * Role (not useful in this context unless it were expanded to more roles) 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:, * Tagging could_almost_ achieve the same thing while being entirely freeform, and still pushing most logic out to the consumer (e.g. "Status: DHCP Tags: Dynamic" or "Status: Reserved Tags: Infrastructure"). * Make Statuses and Roles user-extensible - perhaps combos of customizable fields would obviate needing additional constructs (and would be way faster than custom fields) If any of these approaches are appealing, I'm happy to invest work on them.
Author
Owner

@Wouter0100 commented on GitHub (Mar 12, 2018):

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..

@Wouter0100 commented on GitHub (Mar 12, 2018): 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..
Author
Owner

@sajaltiwari commented on GitHub (Oct 9, 2018):

+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.

@sajaltiwari commented on GitHub (Oct 9, 2018): +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.
Author
Owner

@candlerb commented on GitHub (Oct 9, 2018):

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?

@candlerb commented on GitHub (Oct 9, 2018): 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?
Author
Owner

@athompson-merlin commented on GitHub (Mar 29, 2020):

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.

@athompson-merlin commented on GitHub (Mar 29, 2020): 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.
Author
Owner

@bluikko commented on GitHub (Apr 5, 2020):

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.

@bluikko commented on GitHub (Apr 5, 2020): 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.
Author
Owner

@bluikko commented on GitHub (Jun 19, 2020):

The "range" functionality would be useful for VLANs also.

@bluikko commented on GitHub (Jun 19, 2020): The "range" functionality would be useful for VLANs also.
Author
Owner

@jscmenezes commented on GitHub (Dec 8, 2020):

This feature is necessary to represent DHCP. Create DHCP Pools, independently of the Prefix is a common task for network admins.

@jscmenezes commented on GitHub (Dec 8, 2020): This feature is necessary to represent DHCP. Create DHCP Pools, independently of the Prefix is a common task for network admins.
Author
Owner

@jeremystretch commented on GitHub (Dec 8, 2020):

@jscmenezes DHCP pools can already be represented by creating the appropriate set of individual IP addresses and setting their status to DHCP.

@jeremystretch commented on GitHub (Dec 8, 2020): @jscmenezes DHCP pools can already be represented by creating the appropriate set of individual IP addresses and setting their status to DHCP.
Author
Owner

@jeremystretch commented on GitHub (Dec 21, 2020):

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.

@jeremystretch commented on GitHub (Dec 21, 2020): 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.
Author
Owner

@bluikko commented on GitHub (Dec 22, 2020):

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?

@bluikko commented on GitHub (Dec 22, 2020): 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?
Author
Owner

@candlerb commented on GitHub (Dec 22, 2020):

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:

  • Add a new object class which appears as IPAM > Ranges. Existing IPAM > IP Addresses and IPAM > Prefixes remain unchanged.
  • Its attributes would be similar to 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.
  • In addition, it would have 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?)
  • custom fields need to be supported
  • there should be an API endpoint to allocate the next available IP address from a given Range, and possibly also the next available prefix of a given size from a given Range.

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:

  • viewing a Range should have a tab to show its Child IP Addresses (i.e. those between start and end, and with same VRF); ideally also any child Ranges or child Prefixes, which overlap with the range (i.e. start or end is within the range)
    • Thinking again, perhaps it's saner if a Range is only a child of another range if both start and end are within the Range. Otherwise there's a circular child relationship between Ranges
  • 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, i.e. you see "Child Prefixes", "Child Ranges", "Child IP Addresses". Again, a Range could be defined as a "child" of a Prefix if either its start address or end address is contained within the Prefix, or if both are contained within the Prefix.
  • global search on a single IP address should find ranges whose start or end matches (and ideally, ranges which contain the given address)

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:

  1. Nonsense ranges like "1.1.1.1 - 8.8.8.8" are harder to create; you need a container Prefix which coves the whole Range
  2. If you change a Prefix then its child Range(s) move with it
  3. It simplifies the UI, because Ranges can be hidden under Prefixes without having to create a new top-level entity.

The disadvantages are:

  1. This is inconsistent with how IPAddresses work in Netbox: each IPAddress is an independent entity which knows its full address and netmask, and has no explicit link to a Prefix object.
  2. Ranges which use offsets to parent prefix would be much harder to search for by address. This is probably the biggest practical issue.
  3. Harder to maintain invariants, e.g. if you make a prefix smaller and it now contains ranges which are outside its bounds

For these reasons, I think Ranges which know their VRF and have absolute start and end addresses make more sense.

@candlerb commented on GitHub (Dec 22, 2020): > 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: * Add a new object class which appears as `IPAM > Ranges`. Existing `IPAM > IP Addresses` and `IPAM > Prefixes` remain unchanged. * Its attributes would be similar to `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. * In addition, it would have `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?) * custom fields need to be supported * there should be an API endpoint to allocate the next available IP address from a given Range, and possibly also the next available prefix of a given size from a given Range. 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: * viewing a Range should have a tab to show its Child IP Addresses (i.e. those between start and end, and with same VRF); ideally also any child Ranges or child Prefixes, which overlap with the range (i.e. start or end is within the range) * Thinking again, perhaps it's saner if a Range is only a child of another range if *both* start and end are within the Range. Otherwise there's a circular child relationship between Ranges * 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, i.e. you see "Child Prefixes", "Child Ranges", "Child IP Addresses". Again, a Range could be defined as a "child" of a Prefix if either its start address or end address is contained within the Prefix, or if both are contained within the Prefix. * global search on a single IP address should find ranges whose start or end matches (and ideally, ranges which contain the given address) ----- 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: 1. Nonsense ranges like "1.1.1.1 - 8.8.8.8" are harder to create; you need a container Prefix which coves the whole Range 2. If you change a Prefix then its child Range(s) move with it 3. It simplifies the UI, because Ranges can be hidden under Prefixes without having to create a new top-level entity. The disadvantages are: 1. This is inconsistent with how IPAddresses work in Netbox: each IPAddress is an independent entity which knows its full address and netmask, and has no explicit link to a Prefix object. 2. Ranges which use offsets to parent prefix would be much harder to search for by address. This is probably the biggest practical issue. 3. Harder to maintain invariants, e.g. if you make a prefix smaller and it now contains ranges which are outside its bounds For these reasons, I think Ranges which know their VRF and have absolute start and end addresses make more sense.
Author
Owner

@jeremystretch commented on GitHub (Dec 22, 2020):

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.

@jeremystretch commented on GitHub (Dec 22, 2020): > 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.
Author
Owner

@jeremystretch commented on GitHub (Dec 22, 2020):

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.

@jeremystretch commented on GitHub (Dec 22, 2020): 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.
Author
Owner

@candlerb commented on GitHub (Dec 22, 2020):

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.

  • 1.2.3.1
  • 1.2.3.2
  • 5 IPs available
  • 1.2.3.8 - 1.2.3.20 << this is a Range
    • 13 IPs available
  • 10 IPs available
  • 1.2.3.31
    ...

If a range contains IP allocations, then they can be nested underneath and/or colored differently:

  • 1.2.3.1
  • 1.2.3.2
  • 5 IPs available
  • 1.2.3.8 - 1.2.3.20
    • 4 IPs available
    • 1.2.3.12
    • 1.2.3.13
    • 7 IPs available
  • 10 IPs available
  • 1.2.3.31
    ...

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.

image

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:

  • DHCP pool
    • perhaps no individual allocations are allowed within it...
    • ...but you still might want to make static allocations within a pool, e.g. to allocate address X to device Y
  • As a range to allocate addresses from, and/or documentation that a certain range is reserved for a certain purpose
    • clearly, individual allocations must be allowed within this range
  • To mark a range of addresses not to be used, e.g. to reserve .1 to .9 at the start of a subnet for infrastructure purposes
    • I still want to be able to make allocations within this range manually - e.g. to add a switch at .2 and later a new switch at .3

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:

  • disable API allocation within the range
  • disable the link on the UI for allocating within a range

What I mean is, with "Allocation enabled" the UI would look like this:

  • 1.2.3.8 - 1.2.3.20
    • 4 IPs available << clicking here creates 1.2.3.8
    • 1.2.3.12
    • 1.2.3.13
    • 7 IPs available << clicking here creates 1.2.3.14
  • 1.2.3.21

With "Allocation disabled" it looks like this:

  • 1.2.3.8 - 1.2.3.20
    • 1.2.3.12
    • 1.2.3.13
  • 1.2.3.21

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.

@candlerb commented on GitHub (Dec 22, 2020): > 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. * 1.2.3.1 * 1.2.3.2 * 5 IPs available * 1.2.3.8 - 1.2.3.20 *<< this is a Range* * 13 IPs available * 10 IPs available * 1.2.3.31 ... If a range contains IP allocations, then they can be nested underneath and/or colored differently: * 1.2.3.1 * 1.2.3.2 * 5 IPs available * 1.2.3.8 - 1.2.3.20 * 4 IPs available * 1.2.3.12 * 1.2.3.13 * 7 IPs available * 10 IPs available * 1.2.3.31 ... 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. ![image](https://user-images.githubusercontent.com/44789/102899794-63b21b80-4463-11eb-81cd-b54cd9b74e5b.png) 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: * DHCP pool * perhaps no individual allocations are allowed within it... * ...but you still might want to make static allocations within a pool, e.g. to allocate address X to device Y * As a range to allocate addresses from, and/or documentation that a certain range is reserved for a certain purpose * clearly, individual allocations must be allowed within this range * To mark a range of addresses *not* to be used, e.g. to reserve .1 to .9 at the start of a subnet for infrastructure purposes * I still want to be able to make allocations within this range manually - e.g. to add a switch at .2 and later a new switch at .3 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: - disable API allocation within the range - disable the link on the UI for allocating within a range What I mean is, with "Allocation enabled" the UI would look like this: * 1.2.3.8 - 1.2.3.20 * 4 IPs available *<< clicking here creates 1.2.3.8* * 1.2.3.12 * 1.2.3.13 * 7 IPs available *<< clicking here creates 1.2.3.14* * 1.2.3.21 With "Allocation disabled" it looks like this: * 1.2.3.8 - 1.2.3.20 * 1.2.3.12 * 1.2.3.13 * 1.2.3.21 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*.
Author
Owner

@jeremystretch commented on GitHub (Dec 22, 2020):

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.

@jeremystretch commented on GitHub (Dec 22, 2020): > 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.
Author
Owner

@jscmenezes commented on GitHub (Dec 22, 2020):

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 <
notifications@github.com> 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
.

@jscmenezes commented on GitHub (Dec 22, 2020): 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 < notifications@github.com> 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> > . >
Author
Owner

@teepox commented on GitHub (Jan 8, 2021):

Chiming in as someone who's looking for an alternative to our current IPAM. Here's how ranges are implemented in what we have now:

  • Child objects of prefixes (i.e. not possible to span beyond a single prefix)
  • Included in the same view with IPs, similar to how @candlerb suggested.
  • No overlaps (personally I think this is good, as it simplifies things. Maybe allow range inside a range, but partial overlap sounds like asking for trouble).
  • Ranges are considered as allocated space, but they have their own allocation meters too. I'm not entirely sold on this idea, though. It has both pros and cons, some of which have been discussed above.
  • It is possible to reserve IPs from inside the range, but you need to specifically choose to do so. In both GUI and API you need to point your allocate-action to the range in question, or select a separate "include ranges" option. The reasons why you should be able to reserve addresses from inside the range have been stated alreay.

With regards to using individual IP addresses with status or a tag to represent "ranges", most of our IPAM data was created/imported before ranges were implemented in the product we use. As a result we have plenty of ranges like these which haven't been converted to real ranges. In a large deployment used to manage office networks it becomes a performance issue, though. Looks like we have more than 24000 IPs marked as "DHCP", which is about 1/4 of all addresses.

@teepox commented on GitHub (Jan 8, 2021): Chiming in as someone who's looking for an alternative to our current IPAM. Here's how ranges are implemented in what we have now: - Child objects of prefixes (i.e. not possible to span beyond a single prefix) - Included in the same view with IPs, similar to how @candlerb suggested. - No overlaps (personally I think this is good, as it simplifies things. Maybe allow range inside a range, but partial overlap sounds like asking for trouble). - Ranges are considered as allocated space, but they have their own allocation meters too. I'm not entirely sold on this idea, though. It has both pros and cons, some of which have been discussed above. - It is possible to reserve IPs from inside the range, but you need to specifically choose to do so. In both GUI and API you need to point your allocate-action to the range in question, or select a separate "include ranges" option. The reasons why you should be able to reserve addresses from inside the range have been stated alreay. With regards to using individual IP addresses with status or a tag to represent "ranges", most of our IPAM data was created/imported before ranges were implemented in the product we use. As a result we have plenty of ranges like these which haven't been converted to real ranges. In a large deployment used to manage office networks it becomes a performance issue, though. Looks like we have more than 24000 IPs marked as "DHCP", which is about 1/4 of all addresses.
Author
Owner

@stale[bot] commented on GitHub (Feb 22, 2021):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our contributing guide.

@stale[bot] commented on GitHub (Feb 22, 2021): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@stale[bot] commented on GitHub (Mar 19, 2021):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@stale[bot] commented on GitHub (Mar 19, 2021): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Author
Owner

@th0mcat commented on GitHub (Apr 8, 2021):

I think child pools and subnets should be nested under a parent subnet as "types" of a range. For example, once you're viewing the Prefixes page, clicking on an arrow beside 10.134.204.0/22 would open a pull down and display information about ranges .

10.134.204.0/22 
        Type Range Status Utilization ...
	Pool 10.134.204.2-32 Active 75%
	Pool 10.134.204.33-64 Active 15%
	Pool 10.134.204.65-127 Active 85%
	Subnet 10.134.204.128/25
	Pool 10.134.205.3-75 Active 75%
	Pool 10.134.205.76-108 Active 75%
	Unused 10.134.205.109-10.134.206.3 0%
	Pool 10.134.206.4-111 Active 75%
	Pool 10.134.206.112-254 Active 75%
	Pool 10.134.206.255-10.134.207.126 Active 75%
	Pool 10.134.207.127-150 Active 75%
	Pool 10.134.207.151-254 Active 75%

Clicking on the range would then send you to https:///ipam/prefixes/<#>/ip-addresses/ where you can see individual IP usage.

@th0mcat commented on GitHub (Apr 8, 2021): I think child pools and subnets should be nested under a parent subnet as "types" of a range. For example, once you're viewing the Prefixes page, clicking on an arrow beside 10.134.204.0/22 would open a pull down and display information about ranges . ``` 10.134.204.0/22 Type Range Status Utilization ... Pool 10.134.204.2-32 Active 75% Pool 10.134.204.33-64 Active 15% Pool 10.134.204.65-127 Active 85% Subnet 10.134.204.128/25 Pool 10.134.205.3-75 Active 75% Pool 10.134.205.76-108 Active 75% Unused 10.134.205.109-10.134.206.3 0% Pool 10.134.206.4-111 Active 75% Pool 10.134.206.112-254 Active 75% Pool 10.134.206.255-10.134.207.126 Active 75% Pool 10.134.207.127-150 Active 75% Pool 10.134.207.151-254 Active 75% ``` Clicking on the range would then send you to https://<url>/ipam/prefixes/<#>/ip-addresses/ where you can see individual IP usage.
Author
Owner

@marioland commented on GitHub (Jun 2, 2021):

Being a IPAM tool this feature to support IP ranges is needed to get a more complete picture in this sense.

@marioland commented on GitHub (Jun 2, 2021): Being a IPAM tool this feature to support IP ranges is needed to get a more complete picture in this sense.
Author
Owner

@jeremystretch commented on GitHub (Jun 4, 2021):

I'd like to revisit the ideas here. It would be a great addition to the IPAM component, however we need to devise a workable model.

@jeremystretch commented on GitHub (Jun 4, 2021): I'd like to revisit the ideas here. It would be a great addition to the IPAM component, however we need to devise a workable model.
Author
Owner

@athompson-merlin commented on GitHub (Jun 4, 2021):

I see two options:

  1. make ranges an object subsidiary to subnets, that can overlap with hosts but don't have to, or
  2. make ranges a sort of UI syntactic sugar, where they really exist as a set of n host objects but there's an "annotation" (in Java terms) to cause the UI to display the range by default as a collapsed... um... range. object that isn't really an object. Or better yet, make it a sparse thing, along these same UI lines. So the range isn't really part of the core data model at all here, but it does need to be tracked.

I have clients who have assigned ranges 192.168.10-19, .20-29, .30-39, .40-49 etc. for each site. There's no sane way to represent that in most IPAM tools other than a set of (usually) three subnets of different length. Or 10x /24s, which is a PITA and doesn't help me understand the allocation philosophy (*cough*) when I look at it in an IPAM tool.

@athompson-merlin commented on GitHub (Jun 4, 2021): I see two options: 1. make ranges an object subsidiary to subnets, that *can* overlap with hosts but don't have to, or 2. make ranges a sort of UI syntactic sugar, where they really exist as a set of _n_ host objects but there's an "annotation" (in Java terms) to cause the UI to display the range by default as a collapsed... um... range. object that isn't really an object. Or better yet, make it a sparse thing, along these same UI lines. So the range isn't really part of the core data model at all here, but it does need to be tracked. I have clients who have assigned ranges 192.168.10-19, .20-29, .30-39, .40-49 etc. for each site. There's no sane way to represent that in most IPAM tools other than a set of (usually) three subnets of different length. Or 10x /24s, which is a PITA and doesn't help me understand the allocation philosophy (\*cough\*) when I look at it in an IPAM tool.
Author
Owner

@candlerb commented on GitHub (Jun 4, 2021):

From a data model point of view, I think it's just:

  • start address
  • end address (inclusive, i.e. closed interval)
  • basic fields like IPAddress: VRF, description, status
  • name/slug (optional)
  • custom fields

This would be equivalent to netaddr.IPRange, and would require the same internal model validation: i.e. end >= start, same address family.

I also think that the range should have an "allocatable" flag which, if enabled, gives the option to click to allocate an address within the range - in the same way as you can already click on a synthetic range of non-existent addresses in the UI. In that way, you can mark a range as being for a particular allocation purpose (e.g. "IP Phones"), whilst having other ranges which are reserved/DHCP. However that wouldn't prevent you from explicitly creating an IP address within the range. (At the end of the day, Netbox requires you to know what you're doing).

Open questions include:

  • What the UI looks like
  • Validation with respect to other ranges: can ranges overlap partially or totally? If such overlaps are completely disallowed then it most likely simplifies the UI logic
  • How and if ranges are counted towards prefix utilization (maybe that's also a flag on the range, otherwise certain status values like 'Reserved' or 'DHCP' can be treated as utilized)
  • Any API changes: e.g. it would be a nice-to-have feature to be able to request allocation of an IP from within a named range. But this doesn't need to be implemented on day one.
@candlerb commented on GitHub (Jun 4, 2021): From a [data model](https://github.com/netbox-community/netbox/issues/834#issuecomment-749527901) point of view, I think it's just: * start address * end address (inclusive, i.e. closed interval) * basic fields like IPAddress: VRF, description, status * name/slug (optional) * custom fields This would be equivalent to [netaddr.IPRange](https://netaddr.readthedocs.io/en/latest/api.html#arbitrary-ip-address-ranges), and would require the same internal model validation: i.e. end >= start, same address family. I also think that the range should have an "allocatable" flag which, if enabled, gives the option to click to allocate an address within the range - in the same way as you can already click on a synthetic range of non-existent addresses in the UI. In that way, you can mark a range as being for a particular allocation purpose (e.g. "IP Phones"), whilst having other ranges which are reserved/DHCP. However that wouldn't prevent you from explicitly creating an IP address within the range. (At the end of the day, Netbox requires you to know what you're doing). Open questions include: * What the UI looks like * Validation with respect to other ranges: can ranges overlap partially or totally? If such overlaps are completely disallowed then it most likely simplifies the UI logic * How and if ranges are counted towards prefix utilization (maybe that's also a flag on the range, otherwise certain status values like 'Reserved' or 'DHCP' can be treated as utilized) * Any API changes: e.g. it would be a nice-to-have feature to be able to request allocation of an IP from within a named range. But this doesn't need to be implemented on day one.
Author
Owner

@marioland commented on GitHub (Jun 7, 2021):

From what I came in contact with IP ranges I saw 2 use cases:

  1. DHCP ranges
  2. In Firewall to select only the servers and exclude gateway and broadcast addresses

Data model-wise I would have to comments:

  • An IP range should have a relation to the prefix it is part of
  • No VRF on the IP range as the VRF should be inherited from the prefix
@marioland commented on GitHub (Jun 7, 2021): From what I came in contact with IP ranges I saw 2 use cases: 1. DHCP ranges 2. In Firewall to select only the servers and exclude gateway and broadcast addresses Data model-wise I would have to comments: - An IP range should have a relation to the prefix it is part of - No VRF on the IP range as the VRF should be inherited from the prefix
Author
Owner

@candlerb commented on GitHub (Jun 7, 2021):

I disagree with that. In the Netbox data model there is no explicit linkage between IPAddress and Prefix, so I think it would be consistent to treat IPRanges the same way.

@candlerb commented on GitHub (Jun 7, 2021): I disagree with that. In the Netbox data model there is no explicit linkage between IPAddress and Prefix, so I think it would be consistent to treat IPRanges the same way.
Author
Owner

@marioland commented on GitHub (Jun 8, 2021):

Your are right. IPAddress is only possibly linked via the VRF to each other. In order to be consistent we should do it the same way for the IPRange.

I am just wondering do you know the reason to this design decision?
It seems to me a logical relation that an IP can be directly part of a prefix. These OSI layer 3 objects do have a relation in its nature.
In larger environments were we need to manage overlapping IP scopes it is good to be able to separate the environments. E.g. overlay/underlay/K8S-internal networks etc.
There we have the 2 options of VRFs or tenants as far as I know.

@marioland commented on GitHub (Jun 8, 2021): Your are right. IPAddress is only possibly linked via the VRF to each other. In order to be consistent we should do it the same way for the IPRange. I am just wondering do you know the reason to this design decision? It seems to me a logical relation that an IP can be directly part of a prefix. These OSI layer 3 objects do have a relation in its nature. In larger environments were we need to manage overlapping IP scopes it is good to be able to separate the environments. E.g. overlay/underlay/K8S-internal networks etc. There we have the 2 options of VRFs or tenants as far as I know.
Author
Owner

@jeremystretch commented on GitHub (Jun 28, 2021):

I think @candlerb's rough proposal above is spot on. As for the open questions:

What the UI looks like

Something I've been stuck on for a long time is how to integrate IP ranges with individual addresses e.g. in a prefix's child IPs list. But maybe I'm overthinking it. Just having the IP range model in place, even without any especially convenient integration with individual IPs, is pretty valuable.

Validation with respect to other ranges: can ranges overlap partially or totally? If such overlaps are completely disallowed then it most likely simplifies the UI logic

I think we should disallow overlaps within a VRF entirely, since I expect that to be almost always the desired behavior, and as you mention it greatly simplifies validation.

How and if ranges are counted towards prefix utilization

I suggest that they follow the same rules as individual IPs.

Any API changes: e.g. it would be a nice-to-have feature to be able to request allocation of an IP from within a named range. But this doesn't need to be implemented on day one.

The basic REST API functionality should be pretty straightforward; I don't see us trying to integrate with the IPAddress or Prefix endpoints directly at all. We should be able to provide a "next available" feature as exists for prefixes today.

If we accept the introduction of IPRange as a new model separate from the Prefix and IPAddress models, with its own parallel views and API endpoints, this becomes very straightforward to implement, and I'd be open to tackling it for v3.0.

@jeremystretch commented on GitHub (Jun 28, 2021): I think @candlerb's rough proposal [above](https://github.com/netbox-community/netbox/issues/834#issuecomment-854925129) is spot on. As for the open questions: > What the UI looks like Something I've been stuck on for a long time is how to integrate IP ranges with individual addresses e.g. in a prefix's child IPs list. But maybe I'm overthinking it. Just having the IP range model in place, even without any especially convenient integration with individual IPs, is pretty valuable. > Validation with respect to other ranges: can ranges overlap partially or totally? If such overlaps are completely disallowed then it most likely simplifies the UI logic I think we should disallow overlaps within a VRF entirely, since I expect that to be almost always the desired behavior, and as you mention it greatly simplifies validation. > How and if ranges are counted towards prefix utilization I suggest that they follow the same rules as individual IPs. > Any API changes: e.g. it would be a nice-to-have feature to be able to request allocation of an IP from within a named range. But this doesn't need to be implemented on day one. The basic REST API functionality should be pretty straightforward; I don't see us trying to integrate with the IPAddress or Prefix endpoints directly at all. We should be able to provide a "next available" feature as exists for prefixes today. If we accept the introduction of IPRange as a new model separate from the Prefix and IPAddress models, with its own parallel views and API endpoints, this becomes very straightforward to implement, and I'd be open to tackling it for v3.0.
Author
Owner

@candlerb commented on GitHub (Jun 28, 2021):

How and if ranges are counted towards prefix utilization

I suggest that they follow the same rules as individual IPs.

I can think of use cases for both:

  • If a range is a "DHCP range", then you'd certainly want it to be counted towards utilization
  • If a range is a range from which other IPs are manually allocated (say "switches" or "printers") then you arguably might not want it to count towards total utilization.

But in practice, I think that counting it towards utilization is fine. If your subnet is 95% used, but that's because you've reserved a bunch of address for switches and for printers, then that's an accurate view (i.e. only 5% is available for general allocation).

And equally: even if your prefix is only 50% used, you might have reached 100% within your switches range, or 100% within your printers range; then actually you're "full" for those purposes.

This makes me think of a couple of things:

  1. When viewing a range, it would be helpful to see its utilization figure (i.e. IPs within that range)
  2. I think that there should be no enforcement of name uniqueness. Being able to create multiple ranges with the same name is equivalent to creating "disjoint ranges". Application: say you have .100-.109 reserved for printers, and you use it all up, you might want to add a second range for printers.

From the API point of view, I think it's desiriable to scope requests within a prefix, so you can say "allocate me an IP from the 'printers' range within prefix 10.11.12.0/24". The server would filter the matching ranges to exclude any outside the given prefix.

@candlerb commented on GitHub (Jun 28, 2021): > > How and if ranges are counted towards prefix utilization > > I suggest that they follow the same rules as individual IPs. I can think of use cases for both: * If a range is a "DHCP range", then you'd certainly want it to be counted towards utilization * If a range is a range from which other IPs are manually allocated (say "switches" or "printers") then you arguably *might* not want it to count towards total utilization. But in practice, I think that counting it towards utilization is fine. If your subnet is 95% used, but that's because you've reserved a bunch of address for switches and for printers, then that's an accurate view (i.e. only 5% is available for general allocation). And equally: even if your prefix is only 50% used, you might have reached 100% within your switches range, or 100% within your printers range; then actually you're "full" for those purposes. This makes me think of a couple of things: 1. When viewing a range, it would be helpful to see its utilization figure (i.e. IPs within that range) 2. I think that there should be no enforcement of name uniqueness. Being able to create multiple ranges with the same name is equivalent to creating "disjoint ranges". Application: say you have .100-.109 reserved for printers, and you use it all up, you might want to add a second range for printers. From the API point of view, I think it's desiriable to scope requests within a prefix, so you can say "allocate me an IP from the 'printers' range within prefix 10.11.12.0/24". The server would filter the matching ranges to exclude any outside the given prefix.
Author
Owner

@jeremystretch commented on GitHub (Jun 28, 2021):

We could always punt the problem to the user by including a "counts as utilized space" boolean on the IPRange model.

I think that there should be no enforcement of name uniqueness.

How about sticking with an (optional) description instead of a name, like we do with prefixes and IP addresses?

@jeremystretch commented on GitHub (Jun 28, 2021): We could always punt the problem to the user by including a "counts as utilized space" boolean on the IPRange model. > I think that there should be no enforcement of name uniqueness. How about sticking with an (optional) description instead of a name, like we do with prefixes and IP addresses?
Author
Owner

@candlerb commented on GitHub (Jun 28, 2021):

We could always punt the problem to the user by including a "counts as utilized space" boolean on the IPRange model.

That'll work too.

I think that there should be no enforcement of name uniqueness.

How about sticking with an (optional) description instead of a name, like we do with prefixes and IP addresses?

I think ranges need a name, so you can make an API request which is "assign me an IP address from range Foo". slug would work too, except that would have to be unique.

@candlerb commented on GitHub (Jun 28, 2021): > We could always punt the problem to the user by including a "counts as utilized space" boolean on the IPRange model. That'll work too. > > I think that there should be no enforcement of name uniqueness. > > How about sticking with an (optional) description instead of a name, like we do with prefixes and IP addresses? I think ranges need a name, so you can make an API request which is "assign me an IP address from range Foo". slug would work too, except that *would* have to be unique.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#654