Pfx.minimize
You're seeing just the function
minimize
, go back to Pfx module for more information.
Specs
Returns a minimized list of prefixes covering the same address space.
The list of, possibly mixed types of prefixes, is first grouped by their maxlen
property,
then each sublist is minimized by:
- sorting such that, possibly, adjacent/overlapping prefixes are next to each other
- recursively combine neighboring prefixes into their parent prefix
The prefixes can be any format understood by Pfx.new/1
or be straight up
Pfx.t/0
structs, and the result mimics the format of the first prefix.
Notes:
- to use the list as an acl, apply
Enum.sort({:desc, Pfx})
afterwards - that uses
Pfx.compare/2
, so when using mixed prefix types, group_by maxlen first and sort the sub-lists
Examples
iex> acl = ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4", "1.1.1.5", "1.1.1.6/31"]
iex> minimize(acl) |> Enum.sort({:desc, Pfx})
["1.1.1.4/30", "1.1.1.2/31", "1.1.1.1"]
# list of 255 hosts (ip 1.1.1.128 is excluded)
iex> hosts = for ip <- hosts("1.1.1.0/24"), ip != "1.1.1.128", do: ip
iex> Enum.member?(hosts, "1.1.1.128")
false
iex> Enum.count(hosts)
255
iex> acl = minimize(hosts)
iex> Enum.sort(acl, {:desc, Pfx})
[
"1.1.1.0/25",
"1.1.1.192/26",
"1.1.1.160/27",
"1.1.1.144/28",
"1.1.1.136/29",
"1.1.1.132/30",
"1.1.1.130/31",
"1.1.1.129"
]
#
# reverse back to list of hosts
#
iex> acl_hosts = (for pfx <- acl, do: hosts(pfx)) |> List.flatten()
iex> Enum.count(acl_hosts)
255
iex> Enum.member?(acl_hosts, "1.1.1.128")
false
# minimize list of different types of prefixes
iex> list = ["1.1.0.0/24", "1.1.1.0/24", "acdc:0::/17", "acdc:8000::/17"]
iex> minimize(list)
["acdc::/16", "1.1.0.0/23"]
# mimics format of first prefix in the list
iex> minimize([{1, 2, 3, 4}, {{1, 2, 3, 0}, 25}, "1.2.3.128/26", "1.2.3.192/26"])
[{{1, 2, 3, 0}, 24}]
# mixed prefixes
iex> ["10.10.10.0/24", "10.10.11.0/24", "100.100.100.0/25", "100.100.100.128/25", "acdc::1"]
...> |> minimize()
["acdc::1", "100.100.100.0/24", "10.10.10.0/23"]
# minimize & sort mixed prefixes more to less specific (per type)
iex> ["10.10.10.0/24", "10.10.11.0/24", "100.100.100.0/25", "100.100.100.128/25", "acdc::1"]
...> |> minimize()
...> |> Enum.sort({:desc, Pfx})
["acdc::1", "10.10.10.0/23", "100.100.100.0/24"]
# to avoid excessive conversions due to mimicking, do:
iex> ["10.10.10.0/24", "10.10.11.0/24", "100.100.100.0/25", "100.100.100.128/25", "acdc::1"]
...> |> Enum.map(fn pfx -> new(pfx) end)
...> |> minimize()
...> |> Enum.sort({:desc, Pfx})
...> |> Enum.map(&format/1)
["acdc::1", "10.10.10.0/23", "100.100.100.0/24"]