[docs]classRouterTree(AbstractPlugin):"""This creates a router high-degree tree running OSPF and BGP. Following is an example of a 3 degree tree:: <host> -- <OSPF> -- <BGP> ------------------------- | | | <BGP 0> <BGP 1> <BGP 2> | | | <OSPF 0> <OSPF 1> <OSPF 2> | | | <host 0> <host 1> <host 2> """
[docs]defrun(self,size):""" Create the router tree topology. Args: size (str): The degree of the router tree. This must be castable to an :obj:`int`. """# Convert the size to an int.# Note that all parameters to Plugins will be strings as they are passed# in via the command line. They have to be converted to the requested type.size=int(size)# Create two networks where the control nets can be used for communication# between routers and the host_nets are used to communicate amongst hosts.control_nets=netaddr.IPNetwork("192.168.0.0/16").subnet(30)host_nets=netaddr.IPNetwork("10.0.0.0/8").subnet(24)# Create an iterator with AS numbers which can be used with the BGP routers.# Start with AS number 1000 because there were topologies connected with# router_tree that used the same AS numbers.start_as_number=1000as_nums=iter(range(start_as_number,start_as_number+size+1))# First, make the root pair.root=self._make_router_pair("root.net",control_nets,host_nets,as_nums)# The root BGP router needs lots of memory if the topology is largetry:root.vm["mem"]=4096exceptAttributeError:root.vm={"mem":4096}# Next, create all of the leaves and link them to the root.foriinrange(size):# Create the leaf nodes and return the BGP routerleaf=self._make_router_pair(f"leaf-{i}.net",control_nets,host_nets,as_nums)# Create a switch to connect the leaf to the root routerswitch=Vertex(self.g,f"root-leaf{i}.switch")switch.decorate(Switch)# Get the next subnetbgp_net=next(control_nets)bgp_ips=bgp_net.iter_hosts()# Connect both the root BGP router and the leaf BGP routerleaf.connect(switch,next(bgp_ips),bgp_net.netmask)root.connect(switch,next(bgp_ips),bgp_net.netmask)# Make sure that the routers peer with each other via BGProot.link_bgp(leaf,switch,switch)# Sanity check that everything was created correctly# i.e. make sure interfaces were created.assertlen(root.interfaces.interfaces)!=0assertlen(leaf.interfaces.interfaces)!=0
[docs]def_make_router_pair(self,name,control_nets,host_nets,as_nums):"""Internal function to create the host, OSPF, BGP sequence. Args: name (str): The name of the router/host sequence (e.g. 'leaf-1.net'). control_nets (netaddr.IPNetwork): The network to use between routers. host_nets (netaddr.IPNetwork): The network to use between hosts. as_nums (range_iterator): An iterator for the AS numbering of the BGP routers. Returns: generic_vm_objects.GenericRouter: The BGP router for the pairing. """# Get the next subnet in the `host_nets` IP block# Then get an iter of IPs for that subnethost_net=next(host_nets)host_ips=host_net.iter_hosts()# Create a hosthost=Vertex(self.g,f"host.{name}")host.decorate(LinuxHost)# Create an OSFF Routerospf=Vertex(self.g,f"ospf.{name}")ospf.decorate(GenericRouter)# Create a switch to connect the Host and OSPF routerswitch_host_to_ospf=Vertex(self.g,f"switch-host-ospf.{name}")switch_host_to_ospf.decorate(Switch)# Connect the OSPF router and Host to the Switch.# Use the `host_nets` IP network as the IP address for the VMsospf.connect(switch_host_to_ospf,next(host_ips),host_net.netmask)host.connect(switch_host_to_ospf,next(host_ips),host_net.netmask)# Get the next subnet in the `control_nets` IP block# Then get an iter of IPs for that subnetospf_net=next(control_nets)ospf_ips=ospf_net.iter_hosts()# Create a BGP Routerbgp=Vertex(self.g,f"bgp.{name}")bgp.decorate(GenericRouter)# Set the AS number of the BGP routeras_num=next(as_nums)bgp.set_bgp_as(as_num)# Create a switch to connect the OSPF router and the BGP routerswitch_ospf_to_bgp=Vertex(self.g,f"switch-ospf-bgp.{name}")switch_ospf_to_bgp.decorate(Switch)# Connect the OSPF and BGP routers to the Switch.# We use the ospf_connect method which enables us to define the connection# as an OSPF connection.# Use the `control_nets` IP network as the IP address for the VMsospf.ospf_connect(switch_ospf_to_bgp,next(ospf_ips),ospf_net.netmask)bgp.ospf_connect(switch_ospf_to_bgp,next(ospf_ips),ospf_net.netmask)# Redistribute routes for directly connected subnets to OSPF peers.ospf.redistribute_ospf_connected()# Enable redistributing routes from BGP peers to OSPF peers.bgp.redistribute_bgp_into_ospf()# Enable redistributing routes from OSPF peers to BGP peers.bgp.redistribute_ospf_into_bgp()# Return the BGP routerreturnbgp