Skip to content

Commit

Permalink
Closes netbox-community#946: Disregard mask length when filtering IP …
Browse files Browse the repository at this point in the history
…addresses by a parent prefix
  • Loading branch information
jeremystretch committed Mar 8, 2017
1 parent a4aad8f commit 0e9a83c
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 5 deletions.
4 changes: 2 additions & 2 deletions netbox/ipam/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .formfields import IPFormField
from .lookups import (
EndsWith, IEndsWith, IRegex, IStartsWith, NetContained, NetContainedOrEqual, NetContains, NetContainsOrEquals,
NetHost, NetMaskLength, Regex, StartsWith,
NetHost, NetHostContained, NetMaskLength, Regex, StartsWith,
)


Expand Down Expand Up @@ -66,7 +66,6 @@ def db_type(self, connection):
IPNetworkField.register_lookup(NetContainedOrEqual)
IPNetworkField.register_lookup(NetContains)
IPNetworkField.register_lookup(NetContainsOrEquals)
IPNetworkField.register_lookup(NetHost)
IPNetworkField.register_lookup(NetMaskLength)


Expand All @@ -91,4 +90,5 @@ def db_type(self, connection):
IPAddressField.register_lookup(NetContains)
IPAddressField.register_lookup(NetContainsOrEquals)
IPAddressField.register_lookup(NetHost)
IPAddressField.register_lookup(NetHostContained)
IPAddressField.register_lookup(NetMaskLength)
2 changes: 1 addition & 1 deletion netbox/ipam/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def search_by_parent(self, queryset, name, value):
return queryset
try:
query = str(IPNetwork(value.strip()).cidr)
return queryset.filter(address__net_contained_or_equal=query)
return queryset.filter(address__net_host_contained=query)
except AddrFormatError:
return queryset.none()

Expand Down
14 changes: 14 additions & 0 deletions netbox/ipam/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ def as_sql(self, qn, connection):
return 'HOST(%s) = %s' % (lhs, rhs), params


class NetHostContained(Lookup):
"""
Check for the host portion of an IP address without regard to its mask. This allows us to find e.g. 192.0.2.1/24
when specifying a parent prefix of 192.0.2.0/26.
"""
lookup_name = 'net_host_contained'

def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return 'CAST(HOST(%s) AS INET) << %s' % (lhs, rhs), params


class NetMaskLength(Transform):
lookup_name = 'net_mask_length'
function = 'MASKLEN'
Expand Down
4 changes: 2 additions & 2 deletions netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ def prefix(request, pk):
aggregate = None

# Count child IP addresses
ipaddress_count = IPAddress.objects.filter(vrf=prefix.vrf, address__net_contained_or_equal=str(prefix.prefix))\
ipaddress_count = IPAddress.objects.filter(vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix))\
.count()

# Parent prefixes table
Expand Down Expand Up @@ -499,7 +499,7 @@ def prefix_ipaddresses(request, pk):
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)

# Find all IPAddresses belonging to this Prefix
ipaddresses = IPAddress.objects.filter(vrf=prefix.vrf, address__net_contained_or_equal=str(prefix.prefix))\
ipaddresses = IPAddress.objects.filter(vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix))\
.select_related('vrf', 'interface__device', 'primary_ip4_for', 'primary_ip6_for')
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)

Expand Down

0 comments on commit 0e9a83c

Please sign in to comment.