> On 22 Mar 2021, at 13:07, Faisal Mahmood <[email protected]> wrote:
>
> Thanks Jakub, I wasn't aware of the netaddr library but just gave it a play
> and it does seem very similar and I think it's very useful and completely
> valid.
>
> I think the subtle difference is also that my implementation allows you to
> specify the next prefix as well, so it won't just find the next prefix of the
> same size. This is a common use case when you are trying to find free
> address spaces, you will need to look for networks of different sizes
> depending on what you are doing.
>
> Currently, you could say that you were given a network of 10.200.20.0/24 and
> asked to split this network into a bunch of /26 networks, you can do this
> easily using the subnets method:
> >>> list(IPv4Network("10.200.20.0/24").subnets(prefixlen_diff=2))
> [IPv4Network('10.200.20.0/26'), IPv4Network('10.200.20.64/26'),
> IPv4Network('10.200.20.128/26'), IPv4Network('10.200.20.192/26')]
>
> That is very simple and effective, but not a very realistic example of how
> you would split networks up. Given how limited the IPv4 address space is,
> normally you may have to use that /24 block for multiple things, so can't
> just simply split it up into /26's, you may need to instead get two /30's,
> one /27 and one /25. Currently, I don't think there is any straightforward
> way to do this without a 'next_network' method that I have implemented.
>
> Example, given a network of 10.200.20.0/24, to get two /30's out of it, one
> /27 and one /25, I would do the following with my method:
> >>> first_network = IPv4Network("10.200.20.0/30")
> # first_network = IPv4Network("10.200.20.0/30")
>
> Then get the next one (note not specifying prefix just gives me another /30 -
> i.e. same prefix size):
> >>> second_network = first_network.next_network()
> # second_network = IPv4Network("10.200.20.4/30")
>
> Then I would need to get the /27, so do this:
> >>> third_network = second_network.next_network(new_prefixlen=27)
> # third_network = IPv4Network("10.200.20.32/27)
>
> Finally the /25:
> >>> fourth_network = third_network.next_network(new_prefixlen=25)
> # fourth_network = IPv4Network("10.200.20.128/25)
>
> When you are dealing with the same prefix size for each new network, I think
> it's just a simple case of adding 1 to the broadcast address each time, but
> when you have different prefix sizes it's a bit more complicated.
>
> On Sat, 20 Mar 2021 at 22:04, Jakub Stasiak <[email protected]> wrote:
>
>
>
> I don’t know if this is gonna support Faisal’s cause (“It’s used in a third
> party library in the wild, that means stdlib could use it!”) or the exact
> opposite (“it’s provided by a third party library, so may as well use third
> party library and stdlib doesn’t necessarily need this”) but the quite
> popular netaddr library that I’m a maintainer of does have IPNetwork.next()
> and IPNetwork.previous() methods[1][2]. The main difference is that in
> netaddr:
>
> * next() and previous() can produce networks arbitrary number of steps away,
> not just the first closest network forwards or backwards
> * going from a network to its supernetwork or subnetwork is done through a
> separate set of supernet() and subnet() methods[3][4]
>
> I can’t say how many library users actually consume this particular section
> of the API, of course, but I expect this API to be used and it seems rather
> useful.
>
> Best,
> Jakub
>
> [1] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.next
> [2]
> https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.previous
> [3] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.subnet
> [4]
> https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.supernet
Thank you for the explanation – now I understand better how that prefix
parameter is useful.
It’s not *that* difficult to emulate this using netaddr, there’s an extra
switch-to-supernet or switch-to-subnet step but that’s about it:
>>> from netaddr import IPNetwork
>>> first_network = IPNetwork("10.200.20.0/30")
>>> second_network = first_network.next()
>>> second_network
IPNetwork('10.200.20.4/30')
>>> third_network = second_network.supernet(27)[0].next()
>>> third_network
IPNetwork('10.200.20.32/27')
>>> fourth_network = third_network.supernet(25)[0].next()
>>> fourth_network
IPNetwork('10.200.20.128/25’)
That said, if merging this into the Python stdlib doesn’t work out I’m open to
improving netaddr’s interface to better serve this use case.
Best wishes,
Jakub
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/NA422HQIN232FSCHSO3QQMGOPVZ4QM6W/
Code of Conduct: http://python.org/psf/codeofconduct/