-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
NetBox version
v3.1.1
Python version
3.8
Steps to Reproduce
(Maybe this is a documentation issue; maybe this will lead to a FR for more flexible calculation)
- create prefix 100.64.0.0/22 (Container) - don't check "mark utilized"
- create prefix 100.64.0.0/24 (Container) - don't check "mark utilized"
- create prefix 100.64.0.0/26 (Active) - don't check "mark utilized"
- create IP address 100.64.0.1/26
- browse to prefix 100.64.0.0/22
Expected Behavior
Utilization to be about 0.1% (1/1024)
Observed Behavior
The /22 prefix shows as 25% utilized; therefore the /24 prefix (container within the container) is apparently treated as fully utilized for the purposes of this calculation. However, mark_utilized
was not set on any prefix.
Usage calculation (from source)
The current logic of Prefix.get_utilization
is (roughly) as follows:
- If this prefix has
mark_utilized
then return 100 - if this prefix status is "container", then count all descendant prefixes (of any status) as 100% used
- otherwise, count all descendant IP addresses or ranges (of any status) as used, ignoring descendant prefixes
This behaviour is I think correct for the use case of 'container' as 'manual allocation block': any child container or child active prefix is considered used, so that the "unused" space within the container is therefore how much space you have left for allocating further child prefixes within the container.
Use case
Where this causes a problem: you create a container prefix object to represent an aggregate route announcement, possibly multiple levels of this. This doesn't change how the prefixes and IPs within it are used, but it causes the utilization of an outer (parent) prefix to shoot up as if all addresses within the aggregate are allocated.
Hence I'd like to be able to add a prefix, which doesn't affect the usage of the parent prefix.
(Setting the parent prefix to "Reserved" does give a different calculation, although it doesn't make use of "mark_utilized" either)
Purpose of mark_utilized?
The effect of the mark_utilized
flag doesn't appear to be documented. Going through the source code, I can't find any unit tests for prefix utilization calculation which depend on mark_utilized (only tests for filtering on mark_utilized = true or false). Actually that's reasonable, because it has almost no effect on this calculation.
I can only find two places where mark_utilized
is used:
- in
Prefix.get_available_ips
, ifmark_utilized
is set then an empty list is returned (OK, it means "don't allocate any more addresses out of this prefix") - in
Prefix.get_utilization
, ifmark_utilized
is set then 100 (%) is returned. However, when counting child prefixes it doesn't take notice of the flag (only the size) of those prefixes.
The func get_utilization
for aggregate doesn't make use of the mark_utilized flag either.
For discussion
One alternative would be to count prefix utilization recursively, where each prefix counts as 100% used if "mark utilized" is set, and as child prefixes/addresses/ranges if it is not set. However this would conflict with the use of "mark utilized" as "do not allocate any more addresses from this range".
Another option is to add a new prefix type, say "Aggregate". Then when calculating the utilization of a container, you would only select child prefixes whose status is not Aggregate (i.e. "Container", "Active", "Reserved" and "Deprecated" would be treated as 100% used).