Coder Social home page Coder Social logo

Comments (9)

bluemonk avatar bluemonk commented on June 9, 2024

Hello,

thanks for your compliments.

I didn't fully understand your example here, would you please go deeper into it? I feel it's an interesting function to add to the library.

Best would be to also have some tests to import directly in the code, so I will be sure to meet what you're expecting.

Best regards,
Marco

from ipaddress.

bilco105 avatar bilco105 commented on June 9, 2024

Hi Marco,

Basically the above RFC is designed to allow you to slice up your supernets (/21, /20, /19 etc) effectively within an ISP.

A few examples of how it works are..;

ruby-1.9.2-p180 :001 > require 'netaddr'
 => true 
ruby-1.9.2-p180 :002 > cidr = NetAddr::CIDR.create('192.168.0.0/24')
 => 192.168.0.0/24 
ruby-1.9.2-p180 :003 > cidr.allocate_rfc3531(25).sort
 => ["192.168.0.0/25", "192.168.0.128/25"] 
ruby-1.9.2-p180 :004 > cidr.allocate_rfc3531(26).sort
 => ["192.168.0.0/26", "192.168.0.128/26", "192.168.0.192/26", "192.168.0.64/26"] 
ruby-1.9.2-p180 :005 > cidr.allocate_rfc3531(27).sort
 => ["192.168.0.0/27", "192.168.0.128/27", "192.168.0.160/27", "192.168.0.192/27", "192.168.0.224/27", "192.168.0.32/27", "192.168.0.64/27", "192.168.0.96/27"] 
ruby-1.9.2-p180 :006 > ruby-1.9.2-p180 :006 > cidr.allocate_rfc3531(28).count
 => 16 
ruby-1.9.2-p180 :007 > cidr.allocate_rfc3531(29).count
 => 32 
ruby-1.9.2-p180 :008 >

from ipaddress.

bilco105 avatar bilco105 commented on June 9, 2024

NetAddr::CIDR#cmp would also be a great feature to implement: http://netaddr.rubyforge.org/classes/NetAddr/CIDR.html#M000062

These are the features we use the most in NetAddr

from ipaddress.

bluemonk avatar bluemonk commented on June 9, 2024

Hello Rob,
I understand better now, thank you.

I think you may have a look at IPv4#subnet, as it does quite the same with a different interface. You need to specify the number of subnets rather than the new prefix, but the result is the same:

IPAddress("192.168.0.0/24").subnet(4).map {|i| i.to_string}
=> ["192.168.0.0/26", "192.168.0.64/26", "192.168.0.128/26", "192.168.0.192/26"]

If you want, you can still specify the new subnet with a workaround

irb(main):003:0> a = IPAddress("192.168.0.0/24")
=> #<IPAddress::IPv4:0xb768362c @address="192.168.0.0", @octets=[192, 168, 0, 0], @prefix=24, @u32=3232235520>
irb(main):004:0> a.subnet(2**(26-a.prefix.to_i)).map {|i| i.to_string}
=> ["192.168.0.0/26", "192.168.0.64/26", "192.168.0.128/26", "192.168.0.192/26"]

I will maybe include a new method in the next release to be able to specify the new prefix without the workaround.

from ipaddress.

bilco105 avatar bilco105 commented on June 9, 2024

Hi Marco,

The reason we need to do it the way NetADDR does it, is because we only know what size subnet someone wants (i.e. /29). We therefore take each of our supernets, make as many /29s out of them and loop through the individual subnets until we find one that's free, and then allocate that to the customer.

None of the work arounds really do the above functionality.

from ipaddress.

bluemonk avatar bluemonk commented on June 9, 2024

Hi Rob,
there are some things that are not clear to me.

When you say "we", you mean the library (NetADDR) or your application using the library? And again, when you say "until we find one that's free", what does that mean?

Thanks for helping me understand better, I'm always interested in adding some nice functionality to IPAddress :)

Maybe, if you want, you can provide me with some unit tests that I can integrate in the library. It would me much clearer in this way.

Best regards,
Marco

from ipaddress.

bilco105 avatar bilco105 commented on June 9, 2024

Hi Marco,

Sorry, I'll clarify.

We have an application which is responsible for allocating subnets to customers. To do this, we assign supernets (/19, /20 etc) to the application. An administrator then selects a customers VLAN, and selects 'Allocate subnet' and requests a paticular size of subnet, i.e. a /29.

The code we use for this is as follows..

## Create a new subnet allocation of the desired size
def allocate_subnet(size)
  return false unless size.is_a?(Integer)

  Supernet.all.each do |supernet|
    allocated_subnets = supernet.subnets.all.map(&:cidr_object) ## Returns an array of NetADDR::CIDR object for each allocated subnet
    NetAddr::CIDR.create(supernet.to_s).allocate_rfc3531(size, :Objectify => true).sort.each do |potential_subnet|
      free_subnet = true
      allocated_subnets.each do |allocated_subnet|
        free_subnet = false unless potential_subnet.cmp(allocated_subnet).nil?
      end
      if free_subnet
        return self.subnets.create!(:network => potential_subnet.network, :cidr => size, :supernet => supernet)
      end
    end
  end
  return nil
end

This basically loops through each Supernet, making as many /29s or whatever subnet size was requested out of it. It then loops through each created subnet and checks whether the network IP address has been used in another subnet. If not, then we deem that subnet to be free and allocate it to the customer.

I'm intending to write tests for our application this afternoon, so should be able to provide tests which show the functionality we're after.

from ipaddress.

bluemonk avatar bluemonk commented on June 9, 2024

Hello Rob,
I've installed NetAddr and played a little with it.

It seems to me that NetAddr::CIDR#allocate_rfc3531 and IPAddress::IPv4#subnet do exactly the same thing.

If you want the same interface, you can do

module IPAddress
  class IPv4
    def allocate_rfc3531(new_prefix)
      subnet(2**(new_prefix-prefix.to_i))
    end
  end
end

Then you can call it like you used to do

> a = IPAddress("192.168.0.0/24")
 => 192.168.0.0 
> a.allocate_rfc3531(26)
 => [192.168.0.0, 192.168.0.64, 192.168.0.128, 192.168.0.192] 

from ipaddress.

bilco105 avatar bilco105 commented on June 9, 2024

Yep, it's pretty much just a different API, without needing to know how many subnets you want, which is ideal for us. Is this something you'd look to add into your library, or should we just extend it?

We'd also like something the same as NetAddr::CIDR#cmp if at all possible, as we use that widely too.

from ipaddress.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.