def setUp(self): self.n0 = Node("n0") self.n1 = Node("n1") self.r0 = Node("r0") self.r1 = Node("r1") self.r0.enable_ip_forwarding() self.r1.enable_ip_forwarding() ### Create interfaces and connect nodes and routers ### (eth_p1r1, eth_r1p1) = connect(self.n0, self.r0, "eth-n1r1-0", "eth-r1n1-0") (eth_r1r2, eth_r2r1) = connect(self.r0, self.r1, "eth-r1r2-0", "eth-r2r1-0") (eth_r2p2, eth_p2r2) = connect(self.r1, self.n1, "eth-r2n2-0", "eth-n2r2-0") ### Assign addresses to interfaces ### eth_p1r1.set_address("10.0.1.1/24") eth_r1p1.set_address("10.0.1.2/24") eth_r1r2.set_address("10.0.2.2/24") eth_r2r1.set_address("10.0.2.3/24") eth_r2p2.set_address("10.0.3.3/24") eth_p2r2.set_address("10.0.3.4/24") config.set_value("routing_suite", "quagga") # Use quagga
def setUp(self): self.assertTrue(isfile("/usr/lib/frr/zebra"), "Frrouting is not installed") self.n0 = Node("n0") self.n1 = Node("n1") self.r0 = Node("r0") self.r1 = Node("r1") self.r0.enable_ip_forwarding() self.r1.enable_ip_forwarding() ### Create interfaces and connect nodes and routers ### (eth_p1r1, eth_r1p1) = connect(self.n0, self.r0, "eth-n1r1-0", "eth-r1n1-0") (eth_r1r2, eth_r2r1) = connect(self.r0, self.r1, "eth-r1r2-0", "eth-r2r1-0") (eth_r2p2, eth_p2r2) = connect(self.r1, self.n1, "eth-r2n2-0", "eth-n2r2-0") ### Assign addresses to interfaces ### eth_p1r1.set_address("10.0.1.1/24") eth_r1p1.set_address("10.0.1.2/24") eth_r1r2.set_address("10.0.2.2/24") eth_r2r1.set_address("10.0.2.3/24") eth_r2p2.set_address("10.0.3.3/24") eth_p2r2.set_address("10.0.3.4/24") config.set_value("routing_suite", "frr") # Use frr
def setUp(self): self.n0 = Node("n0") self.n1 = Node("n1") self.r0 = Node("r0") self.r1 = Node("r1") self.r0.enable_ip_forwarding() self.r1.enable_ip_forwarding() ### Create interfaces and connect nodes and routers ### (eth_p1r1, eth_r1p1) = connect(self.n0, self.r0, "eth-n1r1-0", "eth-r1n1-0") (eth_r1r2, eth_r2r1) = connect(self.r0, self.r1, "eth-r1r2-0", "eth-r2r1-0") (eth_r2p2, eth_p2r2) = connect(self.r1, self.n1, "eth-r2n2-0", "eth-n2r2-0") ### Assign addresses to interfaces ### eth_p1r1.set_address("10::1:1/122") eth_r1p1.set_address("10::1:2/122") eth_r1r2.set_address("10::2:2/122") eth_r2r1.set_address("10::2:3/122") eth_r2p2.set_address("10::3:3/122") eth_p2r2.set_address("10::3:4/122") config.set_value("routing_suite", "frr") # Use frr
def test_experiment_ipv6_dad(self): # Test IPv6 with Duplicate Address Detection (DAD) enabled config.set_value("disable_dad", False) n0 = Node("n0") n1 = Node("n1") r = Node("r") r.enable_ip_forwarding() (n0_r, r_n0) = connect(n0, r) (r_n1, n1_r) = connect(r, n1) n0_r.set_address("10::1:1/122") r_n0.set_address("10::1:2/122") r_n1.set_address("10::2:2/122") n1_r.set_address("10::2:1/122") n0.add_route("DEFAULT", n0_r) n1.add_route("DEFAULT", n1_r) n0_r.set_attributes("100mbit", "5ms") r_n0.set_attributes("100mbit", "5ms") r_n1.set_attributes("10mbit", "40ms", "pie") n1_r.set_attributes("10mbit", "40ms") exp = Experiment("test-experiment-ipv6-dad") flow = Flow(n0, n1, n1_r.address, 0, 5, 2) exp.add_tcp_flow(flow) exp.run() # Resetting disable_dad in config config.set_value("disable_dad", True)
def test_logs(self): config.set_value("routing_logs", True) RoutingHelper("rip").populate_routing_tables() self.assertTrue( len(glob(f"{config.get_value('routing_suite')}-logs_*")) > 0) config.set_value("routing_logs", False)
def test_logs(self): config.set_value("routing_logs", True) RoutingHelper("rip").populate_routing_tables() self.assertTrue( os.path.isdir( f"{config.get_value('routing_suite')}-logs_{IdGen.topology_id}" )) config.set_value("routing_logs", False)
def test_invalid_veth_name(self): # Disable topology map config.set_value("assign_random_names", False) node0 = Node("longname0") node1 = Node("longname1") with self.assertRaises(ValueError) as cm: connect(node0, node1) err = cm.exception self.assertEqual( str(err), "Auto-generated device name longname0-longname1-0 is " "too long. The length of name should not exceed 15 characters.", ) # Enable topology map config.set_value("assign_random_names", True)
def test_invalid_ifb_interface_name(self): # Disable topology map config.set_value("assign_random_names", False) node0 = Node("node0") node1 = Node("node1") eth0, _ = connect(node0, node1) with self.assertRaises(ValueError) as cm: eth0.set_attributes("10mbit", "10ms", "codel") err = cm.exception self.assertEqual( str(err), "Device name ifb-node0-node1-0 is too " "long. Device names should not exceed 15 characters", ) # Enable topology map config.set_value("assign_random_names", True)
def test_invalid_interface_name(self): # Disable topology map config.set_value("assign_random_names", False) # Valid interface name Interface("namewith15chars") # Invalid interface name with self.assertRaises(ValueError) as cm: Interface("looonginvalidname") err = cm.exception self.assertEqual( str(err), "Device name looonginvalidname is too long. Device names " "should not exceed 15 characters", ) # Enable topology map config.set_value("assign_random_names", True)
# IMPORTANT: Quagga module is not installed by default in Linux. Hence, before # running this program, install the Quagga module as explained in the README # file in the same directory as this program. Ignore, if Quagga is installed. ########################################################## # Network Topology # # # # 5mbit, 5ms --> 5mbit, 5ms --> # # h1 -------------------- r1 -------------------- h2 # # <-- 10mbit, 100ms <-- 10mbit, 100ms # # # ########################################################## # Configure the program to use Quagga routing suite and enable routing logs. # Routing logs are written to files in a dedicated `logs` directory. config.set_value("routing_suite", "quagga") # `quagga` is default in NeST. config.set_value("routing_logs", True) # By default, this is False. # Create two hosts `h1` and `h2`, and one router `r1` h1 = Node("h1") h2 = Node("h2") r1 = Router("r1") # Internally, `Router` API enables IP forwarding in `r1` # Set the IPv4 address for the networks, and not the interfaces. # We will use the `AddressHelper` later to assign addresses to the interfaces. # Note: this example has two networks, one each on either side of `r1`. n1 = Network("192.168.1.0/24") # network on the left side of `r1` n2 = Network("192.168.2.0/24") # network on the right side of `r1` # Connect `h1` to `r1` (left side), and then `r1` (right side) to `h2`. # `eth1` and `eth2` are the interfaces at `h1` and `h2`, respectively.
################################################################################### # Network Topology # # # # Labels are auto-assigned using LDP -> # # | # # 50mbit, 5ms -> 10mbit, 10ms -> 10mbit, 10ms -> 50mbit, 5ms -> # # ce1 -------------- pe1 --------------- p --------------- pe2 -------------- ce2 # # <- 50mbit, 5ms <- 10mbit, 10ms <- 10mbit, 10ms <- 50mbit, 5ms # # | # # <- Labels are auto-assigned using LDP # # # ################################################################################### # Configure the program to use FRR suite (for LDP). config.set_value("routing_suite", "frr") # Create two `ce` routers, two `pe` routers and one `p` router ce1 = Router("ce1") ce2 = Router("ce2") pe1 = Router("pe1") pe2 = Router("pe2") p = Router("p") # Set the IPv4 address for the networks. # This example has four networks: one on the left of `pe1`, second between # `pe1` and `p`, third between `p` and `pe2`, and fourth on the right of `pe2`. n1 = Network("192.168.1.0/24") # network on the left of `pe1` n2 = Network("192.168.2.0/24") # network between `pe1` and `p` n3 = Network("192.168.3.0/24") # network between `p` and `pe2` n4 = Network("192.168.4.0/24") # network on the right of `pe2`
# Network Topology # # # # 5mbit, 5ms --> # # h1 ------------------- h2 # # <-- 10mbit, 100ms # # # ################################# # NeST supports different levels of logging by using Python's logging levels. # By default, the logging is enabled at INFO level. Other levels supported are: # NOTSET, TRACE, DEBUG, WARNING, ERROR and CRITICAL. # The following line configures the NeST to log at ERROR level. When this # program is run, it does not print INFO statements on the console as done in # some of the other examples in NeST. Only errors are printed to the console. config.set_value("log_level", "ERROR") # Create two hosts `h1` and `h2`. h1 = Node("h1") h2 = Node("h2") # Connect the above two hosts using a veth (virtual Ethernet) pair. (eth1, eth2) = connect(h1, h2) # Assign IPv4 address to both the interfaces. # We assume that the IPv4 address of this network is `192.168.1.0/24`. eth1.set_address("192.168.1.1/24") eth2.set_address("192.168.1.2/24") # Set the link attributes: `h1` --> `h2` and `h2` --> `h1` eth1.set_attributes("5mbit", "5ms")
# `config` option in NeST is to avoid giving random names to the namespaces. # Since NeST allows multiple programs to run in parallel on the same machine, # it internally assigns random names to the namespaces by default. However, # when random names are disabled, node names cannot be longer than three # characters. We use names `h1` and `h2` in this example. # The following two lines ensure that NeST does not delete namespaces during # the termination of this experiment, and does not assign random names to the # namespaces. After running this program, use `ip netns` command to see the # namespaces created by NeST. IMPORTANT: Do not forget to delete the namespaces # manually before re-running this program. You can delete namespaces one-by-one # by using `sudo ip netns del h1` command (similarly for `h2`) or delete all # namespaces at once by using `sudo ip --all netns del`. Be careful if you # choose to delete all namespaces because this command will delete all the # namespaces in your system (even the ones that were not created by NeST). config.set_value("delete_namespaces_on_termination", False) config.set_value("assign_random_names", False) # Create two hosts `h1` and `h2`. h1 = Node("h1") h2 = Node("h2") # Connect the above two hosts using a veth (virtual Ethernet) pair. (eth1, eth2) = connect(h1, h2) # Assign IPv4 address to both the interfaces. # We assume that the IPv4 address of this network is `192.168.1.0/24`. eth1.set_address("192.168.1.1/24") eth2.set_address("192.168.1.2/24") # Set the link attributes: `h1` --> `h2` and `h2` --> `h1`