Skip to content

"Mark utilized" not working as expected #8091

@candlerb

Description

@candlerb

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)

  1. create prefix 100.64.0.0/22 (Container) - don't check "mark utilized"
  2. create prefix 100.64.0.0/24 (Container) - don't check "mark utilized"
  3. create prefix 100.64.0.0/26 (Active) - don't check "mark utilized"
  4. create IP address 100.64.0.1/26
  5. 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, if mark_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, if mark_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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugA confirmed report of unexpected behavior in the application

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions