def runTest(self): mirror_ports = test_param_get("mirror_ports") ports = [p for p in config["port_map"].keys() if p not in mirror_ports] pkt = simple_tcp_packet() match = packet_to_flow_match(self, pkt) match.in_port = ports[0] match.wildcards &= ~ofp.OFPFW_IN_PORT logging.info("Checking that mirror ports are not reported") self.assertEqual(bool(self.bsn_get_mirroring()), False) m, r = self.controller.transact(message.features_request(), 2) p = dict([(pt.port_no, pt) for pt in m.ports]) self.assertFalse(mirror_ports[0] in p or mirror_ports[1] in p, "Mirror port in features reply") logging.info("Enabling mirror port reporting") self.bsn_set_mirroring(True) logging.info("Checking that mirror ports are reported") self.assertEqual(bool(self.bsn_get_mirroring()), True) m, r = self.controller.transact(message.features_request(), 2) p = dict([(pt.port_no, pt) for pt in m.ports]) self.assertTrue(mirror_ports[0] in p and mirror_ports[1] in p, "Mirror port not in features reply") self.assertTrue(p[mirror_ports[0]].config & (1 << 31), "Mirror port config flag not set in features reply") self.assertTrue(p[mirror_ports[1]].config & (1 << 31), "Mirror port config flag not set in features reply") act1 = bsn_action_mirror() act1.dest_port = mirror_ports[0] act1.copy_stage = 0 act2 = bsn_action_mirror() act2.dest_port = mirror_ports[1] act2.copy_stage = 0 act3 = action.action_output() act3.port = ports[1] flow_mod = message.flow_mod() flow_mod.match = match self.assertTrue(flow_mod.actions.add(act1), "Could not add mirror action") self.assertTrue(flow_mod.actions.add(act2), "Could not add mirror action") self.assertTrue(flow_mod.actions.add(act3), "Could not add output action") self.assertEqual(delete_all_flows(self.controller), 0, "Failed to delete all flows") self.assertNotEqual(self.controller.message_send(flow_mod), -1, "Error installing flow mod") self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") logging.info("Sending packet to port %s" % ports[0]) self.dataplane.send(ports[0], str(pkt)) logging.info("Checking that packet was received from output port %s, " "mirror ports %s and %s" % ( ports[1], mirror_ports[0], mirror_ports[1])) receive_pkt_check(self.dataplane, pkt, [ports[1], mirror_ports[0], mirror_ports[1]], [], self)
def setUp(self): logging.info("** START TEST CASE " + str(self)) self.controller = controller.Controller( switch=config["switch_ip"], host=config["controller_host"], port=config["controller_port"]) # clean_shutdown should be set to False to force quit app self.clean_shutdown = True self.controller.start() #@todo Add an option to wait for a pkt transaction to ensure version # compatibilty? self.controller.connect(timeout=20) # By default, respond to echo requests self.controller.keep_alive = True if not self.controller.active: raise Exception("Controller startup failed") if self.controller.switch_addr is None: raise Exception("Controller startup failed (no switch addr)") logging.info("Connected " + str(self.controller.switch_addr)) request = message.features_request() reply, pkt = self.controller.transact(request) self.assertTrue(reply is not None, "Did not complete features_request for handshake") self.supported_actions = reply.actions logging.info("Supported actions: " + hex(self.supported_actions))
def port_config_set(controller, port_no, config, mask): """ Set the port configuration according the given parameters Gets the switch feature configuration and updates one port's configuration value according to config and mask """ logging.info("Setting port " + str(port_no) + " to config " + str(config)) request = message.features_request() reply, pkt = controller.transact(request) if reply is None: return -1 logging.debug(reply.show()) for idx in range(len(reply.ports)): if reply.ports[idx].port_no == port_no: break if idx >= len(reply.ports): return -1 mod = message.port_mod() mod.port_no = port_no mod.hw_addr = reply.ports[idx].hw_addr mod.config = config mod.mask = mask mod.advertise = reply.ports[idx].advertised rv = controller.message_send(mod) return rv
def setUp(self): oflog.start_logging(self) logging.info("** START TEST CASE " + str(self)) self.controller = controller.Controller(host=config["controller_host"], port=config["controller_port"]) # clean_shutdown should be set to False to force quit app self.clean_shutdown = True self.controller.start() #@todo Add an option to wait for a pkt transaction to ensure version # compatibilty? time_out = config["controller_timeout"] self.controller.connect(timeout=time_out) # By default, respond to echo requests self.controller.keep_alive = True if not self.controller.active: raise Exception("Controller startup failed") if self.controller.switch_addr is None: self.controller.shutdown() raise Exception("Controller startup failed (no switch addr)") logging.info("Connected " + str(self.controller.switch_addr)) request = message.features_request() reply, pkt = self.controller.transact(request) self.assertTrue(reply is not None, "Did not complete features_request for handshake") self.supported_actions = reply.actions logging.info("Supported actions: " + hex(self.supported_actions))
def controllerSetup(self, host, port): self.controller = controller.Controller(host=host,port=port) # clean_shutdown should be set to False to force quit app self.clean_shutdown = True self.controller.start() #@todo Add an option to wait for a pkt transaction to ensure version # compatibilty? self.controller.connect(timeout=10) self.assertTrue(self.controller.active, "Controller startup failed, not active") self.assertTrue(self.controller.switch_addr is not None, "Controller startup failed, no switch addr") request = message.features_request() reply, pkt = self.controller.transact(request, timeout=20) self.assertTrue(reply is not None, "Did not complete features_request for handshake") serial_failover_logger.info("Connected " + str(self.controller.switch_addr)) # send echo request and wait for reply request = message.echo_request() response, pkt = self.controller.transact(request) self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY, 'response is not echo_reply') self.assertEqual(request.header.xid, response.header.xid, 'response xid != request xid') self.assertEqual(len(response.data), 0, 'response data non-empty')
def controllerSetup(self, host, port): self.controller = controller.Controller(host=host, port=port) # clean_shutdown should be set to False to force quit app self.clean_shutdown = True self.controller.start() #@todo Add an option to wait for a pkt transaction to ensure version # compatibilty? self.controller.connect(timeout=10) self.assertTrue(self.controller.active, "Controller startup failed, not active") self.assertTrue(self.controller.switch_addr is not None, "Controller startup failed, no switch addr") request = message.features_request() reply, pkt = self.controller.transact(request, timeout=20) self.assertTrue(reply is not None, "Did not complete features_request for handshake") serial_failover_logger.info("Connected " + str(self.controller.switch_addr)) # send echo request and wait for reply request = message.echo_request() response, pkt = self.controller.transact(request) self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY, 'response is not echo_reply') self.assertEqual(request.header.xid, response.header.xid, 'response xid != request xid') self.assertEqual(len(response.data), 0, 'response data non-empty')
def port_config_set(controller, port_no, config, mask, logger): """ Set the port configuration according the given parameters Gets the switch feature configuration and updates one port's configuration value according to config and mask """ logger.info("Setting port " + str(port_no) + " to config " + str(config)) request = message.features_request() reply, pkt = controller.transact(request, timeout=2) if reply is None: return -1 logger.debug(reply.show()) for idx in range(len(reply.ports)): if reply.ports[idx].port_no == port_no: break if idx >= len(reply.ports): return -1 mod = message.port_mod() mod.port_no = port_no mod.hw_addr = reply.ports[idx].hw_addr mod.config = config mod.mask = mask mod.advertise = reply.ports[idx].advertised rv = controller.message_send(mod) return rv
def runTest(self): logging = get_logger() logging.info("Running PortModFailedBadHwAdd Grp100No270 test") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 1, "Not enough ports for test") #Send features request request = message.features_request() reply, pkt = self.controller.transact(request, timeout=2) self.assertTrue(reply is not None, "Features Reply not recieved") for idx in range(len(reply.ports)): if reply.ports[idx].port_no == of_ports[0]: break self.assertTrue(idx <= len(reply.ports), "Error in the ports information") logging.info("Sending port_mod request ..") mod = message.port_mod() mod.port_no = of_ports[0] mod.hw_addr = [0,0,0,0,0,0] mod.config = ofp.OFPPC_NO_FLOOD mod.mask = ofp.OFPPC_NO_FLOOD mod.advertise = reply.ports[idx].advertised rv = self.controller.message_send(mod) self.assertTrue(rv != -1,"Unable to send the message") logging.info("Waiting for OFPT_ERROR message...") (response, raw) = self.controller.poll(ofp.OFPT_ERROR, timeout=10) self.assertTrue(response is not None,"Did not receive an error") self.assertTrue(response.type==ofp.OFPET_PORT_MOD_FAILED,"Unexpected Error type. Expected OFPET_PORT_MOD_FAILED error type") self.assertTrue(response.code==ofp.OFPPMFC_BAD_HW_ADDR," Unexpected error code, Expected OFPPMFC_BAD_HW_ADDR error code")
def runTest(self): request = message.features_request() response,_ = self.controller.transact(request) self.assertTrue(response,"Got no features_reply to features_request") self.assertEqual(response.header.type, ofp.OFPT_FEATURES_REPLY, 'response is not echo_reply') self.assertTrue(len(response) >= 32, "features_reply too short: %d < 32 " % len(response))
def runTest(self): request = message.features_request() response, _ = self.controller.transact(request) self.assertTrue(response, "Got no features_reply to features_request") self.assertEqual(response.header.type, ofp.OFPT_FEATURES_REPLY, 'response is not echo_reply') self.assertTrue( len(response) >= 32, "features_reply too short: %d < 32 " % len(response))
def sw_supported_actions(parent,use_cache=False): #Returns the switch's supported actions cache_supported_actions = None if cache_supported_actions is None or not use_cache: request = message.features_request() (reply, pkt) = parent.controller.transact(request) parent.assertTrue(reply is not None, "Did not get response to ftr req") cache_supported_actions = reply.actions return cache_supported_actions
def sw_supported_actions(parent, use_cache=False): #Returns the switch's supported actions cache_supported_actions = None if cache_supported_actions is None or not use_cache: request = message.features_request() (reply, pkt) = parent.controller.transact(request) parent.assertTrue(reply is not None, "Did not get response to ftr req") cache_supported_actions = reply.actions return cache_supported_actions
def runTest(self): self.num_controllers = test_param_get('num_controllers', default=1) self.controller_timeout = test_param_get('controller_timeout', default=-1) for i in range(self.num_controllers): self.controllerSetup(config["controller_host"], config["controller_port"] + i) for i in range(self.num_controllers): self.controllers[i].handshake_done = False # try to maintain switch connections for specified timeout # -1 means forever while True: for con in self.controllers: if con.switch_socket and con.handshake_done: if (self.controller_timeout < 0 or con.count < self.controller_timeout): logging.info(con.host + ":" + str(con.port) + ": maintaining connection to " + str(con.switch_addr)) con.count = con.count + 1 else: logging.info(con.host + ":" + str(con.port) + ": disconnecting from " + str(con.switch_addr)) con.disconnect() con.handshake_done = False con.count = 0 time.sleep(1) else: #@todo Add an option to wait for a pkt transaction to # ensure version compatibilty? con.connect(self.default_timeout) if not con.switch_socket: logging.info("Did not connect to switch") continue logging.info("TCP Connected " + str(con.switch_addr)) logging.info("Sending hello") con.message_send(message.hello()) request = message.features_request() reply, pkt = con.transact(request, timeout=self.default_timeout) if reply: logging.info("Handshake complete with " + str(con.switch_addr)) con.handshake_done = True con.keep_alive = True con.count = 0 else: logging.info("Did not complete features_request " + "for handshake") con.disconnect() con.handshake_done = False con.count = 0
def runTest(self): self.num_controllers = test_param_get('num_controllers', default=1) self.controller_timeout = test_param_get('controller_timeout', default=-1) for i in range(self.num_controllers): self.controllerSetup(config["controller_host"], config["controller_port"]+i) for i in range(self.num_controllers): self.controllers[i].handshake_done = False # try to maintain switch connections for specified timeout # -1 means forever while True: for con in self.controllers: if con.switch_socket and con.handshake_done: if (self.controller_timeout < 0 or con.count < self.controller_timeout): logging.info(con.host + ":" + str(con.port) + ": maintaining connection to " + str(con.switch_addr)) con.count = con.count + 1 else: logging.info(con.host + ":" + str(con.port) + ": disconnecting from " + str(con.switch_addr)) con.disconnect() con.handshake_done = False con.count = 0 time.sleep(1) else: #@todo Add an option to wait for a pkt transaction to # ensure version compatibilty? con.connect(self.default_timeout) if not con.switch_socket: logging.info("Did not connect to switch") continue logging.info("TCP Connected " + str(con.switch_addr)) logging.info("Sending hello") con.message_send(message.hello()) request = message.features_request() reply, pkt = con.transact(request, timeout=self.default_timeout) if reply: logging.info("Handshake complete with " + str(con.switch_addr)) con.handshake_done = True con.keep_alive = True con.count = 0 else: logging.info("Did not complete features_request " + "for handshake") con.disconnect() con.handshake_done = False con.count = 0
def supported_actions_get(parent, use_cache=True): """ Get the bitmap of supported actions from the switch If use_cache is false, the cached value will be updated """ global cached_supported_actions if cached_supported_actions is None or not use_cache: request = message.features_request() (reply, pkt) = parent.controller.transact(request, timeout=2) parent.assertTrue(reply is not None, "Did not get response to ftr req") cached_supported_actions = reply.actions pa_logger.info("Supported actions: " + hex(cached_supported_actions)) return cached_supported_actions
def runTest(self): logging = get_logger() logging.info("Running Grp80No60: Features Request-Reply") logging.info("Sending features_request.") req = message.features_request() (res, pkt) = self.controller.transact(req) self.assertIsNotNone(res, "Did not receive response to features_request.") logging.info("Verifying response's essential fields.") self.assertEqual(res.header.type, ofp.OFPT_FEATURES_REPLY, "Response type was %d, but expected %d." % (res.header.type, ofp.OFPT_FEATURES_REPLY)) self.assertEqual(res.header.xid,req.header.xid, ("Transaction ID of response did not match the " "transaction ID of the request."))
def runTest(self): logging = get_logger() logging.info("Running Grp80No60: Features Request-Reply") logging.info("Sending features_request.") req = message.features_request() (res, pkt) = self.controller.transact(req) self.assertIsNotNone(res, "Did not receive response to features_request.") logging.info("Verifying response's essential fields.") self.assertEqual( res.header.type, ofp.OFPT_FEATURES_REPLY, "Response type was %d, but expected %d." % (res.header.type, ofp.OFPT_FEATURES_REPLY)) self.assertEqual(res.header.xid, req.header.xid, ("Transaction ID of response did not match the " "transaction ID of the request."))
class SimpleProtocol(unittest.TestCase): """ Root class for setting up the controller """ def sig_handler(self, v1, v2): basic_logger.critical("Received interrupt signal; exiting") print "Received interrupt signal; exiting" self.clean_shutdown = False self.tearDown() raise KeyboardInterrupt def setUp(self): self.logger = basic_logger self.config = basic_config #@todo Test cases shouldn't monkey with signals; move SIGINT handler # to top-level oft try: signal.signal(signal.SIGINT, self.sig_handler) except ValueError, e: basic_logger.info("Could not set SIGINT handler: %s" % e) basic_logger.info("** START TEST CASE " + str(self)) self.controller = controller.Controller( host=basic_config["controller_host"], port=basic_config["controller_port"]) # clean_shutdown should be set to False to force quit app self.clean_shutdown = True self.controller.start() #@todo Add an option to wait for a pkt transaction to ensure version # compatibilty? self.controller.connect(timeout=20) # By default, respond to echo requests self.controller.keep_alive = True if not self.controller.active: raise Exception("Controller startup failed") if self.controller.switch_addr is None: raise Exception("Controller startup failed (no switch addr)") basic_logger.info("Connected " + str(self.controller.switch_addr)) request = message.features_request() reply, pkt = self.controller.transact(request, timeout=10) self.assertTrue(reply is not None, "Did not complete features_request for handshake") self.supported_actions = reply.actions basic_logger.info("Supported actions: " + hex(self.supported_actions))
def runTest(self): logging.info("Running PortModFailedBadHwAdd Grp100No280 test") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 1, "Not enough ports for test") # Send features request request = message.features_request() reply, pkt = self.controller.transact(request, timeout=2) self.assertTrue(reply is not None, "Features Reply not recieved") for idx in range(len(reply.ports)): if reply.ports[idx].port_no == of_ports[0]: break self.assertTrue(idx <= len(reply.ports), "Error in the ports information") logging.info("Sending port_mod request ..") mod = message.port_mod() mod.port_no = of_ports[0] mod.hw_addr = [0, 0, 0, 0, 0, 0] mod.config = ofp.OFPPC_NO_FLOOD mod.mask = ofp.OFPPC_NO_FLOOD mod.advertise = reply.ports[idx].advertised rv = self.controller.message_send(mod) self.assertTrue(rv != -1, "Unable to send the message") logging.info("Waiting for OFPT_ERROR message...") count = 0 while True: (response, raw) = self.controller.poll(ofp.OFPT_ERROR) if not response: # Timeout break if not response.type == ofp.OFPET_PORT_MOD_FAILED: logging.info("Error type is not as expected") break if not response.code == ofp.OFPPMFC_BAD_HW_ADDR: logging.info("Error Code is not as expected") break if not config["relax"]: # Only one attempt to match break count += 1 if count > 10: # Too many tries break
def runTest(self): self.controllerSetup(cxn_config["controller_host"], cxn_config["controller_port"]) cxn_logger.info("TCP Connected " + str(self.controller.switch_addr)) cxn_logger.info("Sending hello") self.controller.message_send(message.hello()) request = message.features_request() reply, pkt = self.controller.transact(request, timeout=20) self.assertTrue(reply is not None, "Did not complete features_request for handshake") cxn_logger.info("Handshake complete with " + str(self.controller.switch_addr)) self.controller.keep_alive = True # keep controller up forever while self.controller.active: time.sleep(1) self.assertTrue(not self.controller.active, "Expected controller disconnect, but still active")
def runTest(self): logging.info("Running Features_Request test") of_ports = config["port_map"].keys() of_ports.sort() #Clear switch state delete_all_flows(self.controller) logging.info("Sending Features_Request") logging.info("Expecting Features_Reply") request = message.features_request() self.controller.message_send(request) (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY, timeout=2) self.assertTrue(response is not None, 'Did not receive Features Reply')
def runTest(self): logging.info("Running Grp20No10 Features_Request test") of_ports = config["port_map"].keys() of_ports.sort() # Clear switch state rc = delete_all_flows(self.controller) self.assertEqual(rc, 0, "Failed to delete all flows") logging.info("Sending Features_Request") logging.info("Expecting Features_Reply") request = message.features_request() rv = self.controller.message_send(request) self.assertTrue(rv != -1, "Not able to send features request.") (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY, timeout=2) self.assertTrue(response is not None, "Did not receive Features Reply")
def runTest(self): logging = get_logger() logging.info("Running Grp70No20 Announcement test") logging.info("Sending Features_Request") logging.info("Expecting Features Reply with supported actions") # Sending Features_Request request = message.features_request() (reply, pkt) = self.controller.transact(request) self.assertTrue(reply is not None, "Failed to get any reply") self.assertEqual(reply.header.type, ofp.OFPT_FEATURES_REPLY, 'Response is not Features_reply') supported_actions = [] if (reply.actions & 1 << ofp.OFPAT_OUTPUT): supported_actions.append('OFPAT_OUTPUT') if (reply.actions & 1 << ofp.OFPAT_SET_VLAN_VID): supported_actions.append('OFPAT_SET_VLAN_VID') if (reply.actions & 1 << ofp.OFPAT_SET_VLAN_PCP): supported_actions.append('OFPAT_SET_VLAN_PCP') if (reply.actions & 1 << ofp.OFPAT_STRIP_VLAN): supported_actions.append('OFPAT_STRIP_VLAN') if (reply.actions & 1 << ofp.OFPAT_SET_DL_SRC): supported_actions.append('OFPAT_SET_DL_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_DL_DST): supported_actions.append('OFPAT_SET_NW_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_NW_DST): supported_actions.append('OFPAT_SET_NW_DST') if (reply.actions & 1 << ofp.OFPAT_SET_NW_TOS): supported_actions.append('OFPAT_SET_NW_TOS') if (reply.actions & 1 << ofp.OFPAT_SET_TP_SRC): supported_actions.append('OFPAT_SET_TP_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_TP_DST): supported_actions.append('OFPAT_SET_TP_DST') if (reply.actions & 1 << ofp.OFPAT_VENDOR): supported_actions.append('OFPAT_VENDOR') if (reply.actions & 1 << ofp.OFPAT_ENQUEUE): supported_actions.append('OFPAT_ENQUEUE') logging.info(supported_actions)
def runTest(self): of_logger.info("Running Features_Request test") of_ports = of_port_map.keys() of_ports.sort() #Clear switch state rc = delete_all_flows(self.controller, of_logger) self.assertEqual(rc, 0, "Failed to delete all flows") of_logger.info("Sending Features_Request") of_logger.info("Expecting Features_Reply") request = message.features_request() rv = self.controller.message_send(request) self.assertTrue(rv != -1, "Not able to send features request.") (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY, timeout=2) self.assertTrue(response is not None, 'Did not receive Features Reply')
def runTest(self): logging = get_logger() logging.info("Running Grp70No20 Announcement test") logging.info("Sending Features_Request") logging.info("Expecting Features Reply with supported actions") # Sending Features_Request request = message.features_request() (reply, pkt) = self.controller.transact(request) self.assertTrue(reply is not None, "Failed to get any reply") self.assertEqual(reply.header.type, ofp.OFPT_FEATURES_REPLY,'Response is not Features_reply') supported_actions =[] if(reply.actions &1<<ofp.OFPAT_OUTPUT): supported_actions.append('OFPAT_OUTPUT') if(reply.actions &1<<ofp.OFPAT_SET_VLAN_VID): supported_actions.append('OFPAT_SET_VLAN_VID') if(reply.actions &1<<ofp.OFPAT_SET_VLAN_PCP): supported_actions.append('OFPAT_SET_VLAN_PCP') if(reply.actions &1<<ofp.OFPAT_STRIP_VLAN): supported_actions.append('OFPAT_STRIP_VLAN') if(reply.actions &1<<ofp.OFPAT_SET_DL_SRC): supported_actions.append('OFPAT_SET_DL_SRC') if(reply.actions &1<<ofp.OFPAT_SET_DL_DST): supported_actions.append('OFPAT_SET_NW_SRC') if(reply.actions &1<<ofp.OFPAT_SET_NW_DST): supported_actions.append('OFPAT_SET_NW_DST') if(reply.actions &1<<ofp.OFPAT_SET_NW_TOS): supported_actions.append('OFPAT_SET_NW_TOS') if(reply.actions &1<<ofp.OFPAT_SET_TP_SRC): supported_actions.append('OFPAT_SET_TP_SRC') if(reply.actions &1<<ofp.OFPAT_SET_TP_DST): supported_actions.append('OFPAT_SET_TP_DST') if(reply.actions &1<<ofp.OFPAT_VENDOR): supported_actions.append('OFPAT_VENDOR') if(reply.actions &1<<ofp.OFPAT_ENQUEUE): supported_actions.append('OFPAT_ENQUEUE') logging.info(supported_actions)
def port_config_get(controller, port_no): """ Get a port's configuration Gets the switch feature configuration and grabs one port's configuration @returns (hwaddr, config, advert) The hwaddress, configuration and advertised values """ request = message.features_request() reply, pkt = controller.transact(request) logging.debug(reply.show()) if reply is None: logging.warn("Get feature request failed") return None, None, None for idx in range(len(reply.ports)): if reply.ports[idx].port_no == port_no: return (reply.ports[idx].hw_addr, reply.ports[idx].config, reply.ports[idx].advertised) logging.warn("Did not find port number for port config") return None, None, None
def runTest(self): self.controllerSetup(config["controller_host"], config["controller_port"]) logging.info("TCP Connected " + str(self.controller.switch_addr)) logging.info("Sending hello") self.controller.message_send(message.hello()) request = message.features_request() reply, pkt = self.controller.transact(request, timeout=20) self.assertTrue(reply is not None, "Did not complete features_request for handshake") logging.info("Handshake complete with " + str(self.controller.switch_addr)) self.controller.keep_alive = True # keep controller up forever while self.controller.active: time.sleep(1) self.assertTrue(not self.controller.active, "Expected controller disconnect, but still active")
def runTest(self): logging = get_logger() logging.info("Running Grp20No10 Features_Request test") of_ports = config["port_map"].keys() of_ports.sort() #Clear switch state rc = delete_all_flows(self.controller) self.assertEqual(rc, 0, "Failed to delete all flows") logging.info("Sending OFPT_FEATURES_REQUEST") request = message.features_request() rv = self.controller.message_send(request) self.assertTrue(rv != -1, "Not able to send features request.") logging.info("Expecting OFPT_FEATURES_REPLY") (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY, timeout=2) self.assertTrue(response is not None, 'Did not receive OFPT_FEATURES_REPLY') logging.info("Received OFPT_FEATURES_REPLY")
def runTest(self): logging = get_logger() logging.info("Running Grp10No110 test ") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 0, "Not enough ports for test") #Clear switch state rv = delete_all_flows(self.controller) self.assertEqual(rv, 0, "Failed to delete all flows") rc = delete_all_flows_emer(self.controller) self.assertEqual(rc, 0, "Failed to send delete-emergency flow") response, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue( response is None, "Emergency flow cannot be deleted: Check if the Switch supports Emergency Mode" ) #Insert an emergency flow entry test_packet = simple_tcp_packet() match = parse.packet_to_flow_match(test_packet) e_flow_mod = message.flow_mod() match = parse.packet_to_flow_match(test_packet) e_flow_mod.match = match e_flow_mod.flags = e_flow_mod.flags | ofp.OFPFF_EMERG e_flow_mod.match.in_port = of_ports[0] act = action.action_output() act.port = of_ports[1] self.assertTrue(e_flow_mod.actions.add(act), "Failed to add action") rv = self.controller.message_send(e_flow_mod) response = None response, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue(response is None, "Unable to add emergency flows") self.assertTrue(rv != -1, "Unable to send a flow_mod") self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") # Assert matching dataplane packet isn't forwarded. self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should not be forwarded yes_ports = [] no_ports = set(of_ports) receive_pkt_check(self.dataplane, test_packet, yes_ports, no_ports, self) #Shutdown the controller self.controller.initial_hello = False self.controller.disconnect() #waiting for the switch to recognize the connection drop. sleep(2) assertionerr = False pkt = simple_tcp_packet() logging.info("checking for control channel status") try: for x in range(15): logging.info("Sending an unmatched packet") self.dataplane.send(of_ports[1], str(pkt)) (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, timeout=10) self.assertTrue( response is not None, 'PacketIn is not generated--Control plane is down') except AssertionError: #Send a simple tcp packet on ingress_port logging.info("Control channel is down") logging.info("Sending simple tcp packet ...") logging.info( "Checking for Emergency flows status after controller shutdown" ) self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should be forwarded yes_ports = [of_ports[1]] no_ports = set(of_ports).difference(yes_ports) receive_pkt_check(self.dataplane, test_packet, yes_ports, no_ports, self) logging.info( "Emergency flows are active after control channel is disconnected" ) assertionerr = True else: self.assertTrue(assertionerr is True, "Failed to shutdown the control plane") self.controller.initial_hello = True self.controller.connect() sleep(3) features = message.features_request() rv = self.controller.message_send(features) # for i in range(10): # sleep(2) (response, raw) = self.controller.poll(ofp.OFPT_FEATURES_REPLY, timeout=5) self.assertTrue(response is not None, "Control channel connection could not be established") logging.info("Control channel is up") logging.info("Sending simple tcp packet ...") logging.info( "Checking for Emergency flows status after controller reconnection" ) self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should be forwarded yes_ports = [of_ports[1]] no_ports = set(of_ports).difference(yes_ports) receive_pkt_check(self.dataplane, test_packet, yes_ports, no_ports, self) logging.info( "Emergency flows are active after control channel is reconnected") logging.info("Cleaning up emergency flows") rc = delete_all_flows_emer(self.controller) self.assertEqual(rc, 0, "Failed to send delete-emergency flow") res, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue(res is None, "Emergency flows could not be deleted.")
def runTest(self): logging = get_logger() logging.info("Running Grp80No70 Features Reply Body test") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 1, "Not enough ports for test") # Sending Features_Request logging.info("Sending Features_Request...") request = message.features_request() (reply, pkt) = self.controller.transact(request) self.assertTrue(reply is not None, "Failed to get any reply") self.assertEqual(reply.header.type, ofp.OFPT_FEATURES_REPLY, 'Response is not Features_reply') self.assertEqual(reply.header.xid, request.header.xid, 'Transaction id does not match') supported_actions = [] #Grp80No180 if (reply.actions & 1 << ofp.OFPAT_OUTPUT): supported_actions.append('OFPAT_OUTPUT') if (reply.actions & 1 << ofp.OFPAT_SET_VLAN_VID): supported_actions.append('OFPAT_SET_VLAN_VID') if (reply.actions & 1 << ofp.OFPAT_SET_VLAN_PCP): supported_actions.append('OFPAT_SET_VLAN_PCP') if (reply.actions & 1 << ofp.OFPAT_STRIP_VLAN): supported_actions.append('OFPAT_STRIP_VLAN') if (reply.actions & 1 << ofp.OFPAT_SET_DL_SRC): supported_actions.append('OFPAT_SET_DL_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_DL_DST): supported_actions.append('OFPAT_SET_DL_DST') if (reply.actions & 1 << ofp.OFPAT_SET_NW_SRC): supported_actions.append('OFPAT_SET_NW_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_NW_DST): supported_actions.append('OFPAT_SET_NW_DST') if (reply.actions & 1 << ofp.OFPAT_SET_NW_TOS): supported_actions.append('OFPAT_SET_NW_TOS') if (reply.actions & 1 << ofp.OFPAT_SET_TP_SRC): supported_actions.append('OFPAT_SET_TP_SRC') if (reply.actions & 1 << ofp.OFPAT_SET_TP_DST): supported_actions.append('OFPAT_SET_TP_DST') if (reply.actions & 1 << ofp.OFPAT_VENDOR): supported_actions.append('OFPAT_VENDOR') if (reply.actions & 1 << ofp.OFPAT_ENQUEUE): supported_actions.append('OFPAT_ENQUEUE') self.assertTrue( len(supported_actions) != 0, "Features Reply did not contain actions supported by sw") #Verify switch supports the Required Actions i.e Forward self.assertTrue('OFPAT_OUTPUT' in supported_actions, "Required Action--Forward is not supported ") logging.info("Supported Actions: " + str(supported_actions)) logging.info("Capabilities bitmap: {0}".format(bin( reply.capabilities))) supported_capabilities = [] mandatory = 0 #Grp80No110 if (reply.capabilities & ofp.OFPC_FLOW_STATS): supported_capabilities.append('OFPC_FLOW_STATS') else: mandatory = 1 #Grp80No120 if (reply.capabilities & ofp.OFPC_TABLE_STATS): supported_capabilities.append('OFPC_TABLE_STATS') else: mandatory = 1 #Grp80No130 if (reply.capabilities & ofp.OFPC_PORT_STATS): supported_capabilities.append('OFPC_PORT_STATS') else: mandatory = 1 #Grp80No140 if (reply.capabilities & ofp.OFPC_STP): supported_capabilities.append('OFPC_STP') #Grp80N0150 - Reserved, must be Zero if (reply.capabilities & ofp.OFPC_RESERVED): mandatory = 1 #Grp80No160 if (reply.capabilities & ofp.OFPC_IP_REASM): supported_capabilities.append('OFPC_IP_REASM') if (reply.capabilities & ofp.OFPC_QUEUE_STATS): supported_capabilities.append('OFPC_QUEUE_STATS') #Grp80No170 - Match on IP src and IP dst are Optional if (reply.capabilities & ofp.OFPC_ARP_MATCH_IP): supported_capabilities.append('OFPC_ARP_MATCH_IP') logging.info("Supported Capabilities: " + str(supported_capabilities)) self.assertTrue(mandatory == 0, "Switch does not support all mandatory capabilities") #Grp80No80 self.assertTrue(reply.datapath_id != 0, "Features Reply did not contain datapath of the sw") logging.info("Datapath Id: " + str(reply.datapath_id)) #Grp80No90 logging.info("Buffer Size: " + str(reply.n_buffers)) #Grp80No100 self.assertTrue( reply.n_tables != 0, "Features Reply does not contain no. of tables supported by datapath" ) logging.info("No of tables: " + str(reply.n_tables)) #Grp80No190 ports = 0 ports = len(reply.ports) self.assertTrue( ports != 0, "Features Reply does not contain no. of ports and their ports definitions" ) self.assertTrue( ports >= len(of_ports), "No. of openflow ports in the features Reply is incorrect") logging.info("No. of openflow ports: " + str(ports))
def runTest(self): logging.info("Running Features Reply Body test") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 1, "Not enough ports for test") # Sending Features_Request logging.info("Sending Features_Request...") request = message.features_request() (reply, pkt) = self.controller.transact(request) self.assertTrue(reply is not None, "Failed to get any reply") self.assertEqual(reply.header.type, ofp.OFPT_FEATURES_REPLY,'Response is not Features_reply') self.assertEqual(reply.header.xid,request.header.xid,'Transaction id does not match') supported_actions =[] if(reply.actions &1<<ofp.OFPAT_OUTPUT): supported_actions.append('OFPAT_OUTPUT') if(reply.actions &1<<ofp.OFPAT_SET_VLAN_VID): supported_actions.append('OFPAT_SET_VLAN_VID') if(reply.actions &1<<ofp.OFPAT_SET_VLAN_PCP): supported_actions.append('OFPAT_SET_VLAN_PCP') if(reply.actions &1<<ofp.OFPAT_STRIP_VLAN): supported_actions.append('OFPAT_STRIP_VLAN') if(reply.actions &1<<ofp.OFPAT_SET_DL_SRC): supported_actions.append('OFPAT_SET_DL_SRC') if(reply.actions &1<<ofp.OFPAT_SET_DL_DST): supported_actions.append('OFPAT_SET_NW_SRC') if(reply.actions &1<<ofp.OFPAT_SET_NW_DST): supported_actions.append('OFPAT_SET_NW_DST') if(reply.actions &1<<ofp.OFPAT_SET_NW_TOS): supported_actions.append('OFPAT_SET_NW_TOS') if(reply.actions &1<<ofp.OFPAT_SET_TP_SRC): supported_actions.append('OFPAT_SET_TP_SRC') if(reply.actions &1<<ofp.OFPAT_SET_TP_DST): supported_actions.append('OFPAT_SET_TP_DST') if(reply.actions &1<<ofp.OFPAT_VENDOR): supported_actions.append('OFPAT_VENDOR') if(reply.actions &1<<ofp.OFPAT_ENQUEUE): supported_actions.append('OFPAT_ENQUEUE') self.assertTrue(len(supported_actions) != 0,"Features Reply did not contain actions supported by sw") #Verify switch supports the Required Actions i.e Forward self.assertTrue('OFPAT_OUTPUT' in supported_actions,"Required Action--Forward is not supported ") logging.info("Supported Actions: " + str(supported_actions)) supported_capabilities = [] if(reply.capabilities &1<<ofp.OFPC_FLOW_STATS): supported_capabilities.append('OFPC_FLOW_STATS') if(reply.capabilities &1<<ofp.OFPC_TABLE_STATS): supported_capabilities.append('OFPC_TABLE_STATS') if(reply.capabilities &1<<ofp.OFPC_PORT_STATS): supported_capabilities.append('OFPC_PORT_STATS') if(reply.capabilities &1<<ofp.OFPC_STP): supported_capabilities.append('OFPC_STP') if(reply.capabilities &1<<ofp.OFPC_RESERVED): supported_capabilities.append('OFPC_RESERVED') if(reply.capabilities &1<<ofp.OFPC_IP_REASM): supported_capabilities.append('OFPC_IP_REASM') if(reply.capabilities &1<<ofp.OFPC_QUEUE_STATS): supported_capabilities.append('OFPC_QUEUE_STATS') if(reply.capabilities &1<<ofp.OFPC_ARP_MATCH_IP): supported_capabilities.append('OFPC_ARP_MATCH_IP') logging.info("Supported Capabilities: " + str(supported_capabilities)) self.assertTrue(reply.datapath_id != 0 , "Features Reply did not contain datapath of the sw") logging.info("Datapath Id: " + str(reply.datapath_id)) logging.info("Buffer Size: " + str(reply.n_buffers)) self.assertTrue(reply.n_tables != 0 , "Features Reply does not contain no. of tables supported by datapath") logging.info("No of tables: " + str(reply.n_tables)) ports=0 ports = len(reply.ports) self.assertTrue(ports != 0, "Features Reply does not contain no. of ports and their ports definitions") self.assertTrue(ports >= len(of_ports),"No. of openflow ports in the features Reply is incorrect") logging.info("No. of openflow ports: " + str(ports))
def runTest(self): request = message.features_request() response, _ = self.controller.transact(request) #print(response.show()) self.logger.info(response.show())
def runTest(self): request = message.features_request() response,_ = self.controller.transact(request) #print(response.show()) self.logger.info(response.show())
def runTest(self): for conspec in self.controller_list: self.controllerSetup(conspec[0], conspec[1]) for i in range(len(self.controller_list)): self.controllers[i].cstate = 0 self.controllers[i].keep_alive = self.keep_alive self.controllers[i].saved_switch_addr = None tick = 0.1 # time period in seconds at which controllers are handled disconnected_count = 0 cycle = 0 while True: states = [] for con in self.controllers: condesc = con.host + ":" + str(con.port) + ": " logging.debug("Checking " + condesc) if con.switch_socket: if con.switch_addr != con.saved_switch_addr: con.saved_switch_addr = con.switch_addr con.cstate = 0 if con.cstate == 0: logging.info(condesc + "Sending hello to " + str(con.switch_addr)) con.message_send(message.hello()) con.cstate = 1 con.count = 0 elif con.cstate == 1: reply, pkt = con.poll(exp_msg=ofp.OFPT_HELLO, timeout=0) if reply is not None: logging.info(condesc + "Hello received from " + str(con.switch_addr)) con.cstate = 2 else: con.count = con.count + 1 # fall back to previous state on timeout if con.count >= self.hello_timeout/tick: logging.info(condesc + "Timeout hello from " + str(con.switch_addr)) con.cstate = 0 elif con.cstate == 2: logging.info(condesc + "Sending features request to " + str(con.switch_addr)) con.message_send(message.features_request()) con.cstate = 3 con.count = 0 elif con.cstate == 3: reply, pkt = con.poll(exp_msg=ofp.OFPT_FEATURES_REPLY, timeout=0) if reply is not None: logging.info(condesc + "Features request received from " + str(con.switch_addr)) con.cstate = 4 con.count = 0 cycle = cycle + 1 logging.info("Cycle " + str(cycle)) else: con.count = con.count + 1 # fall back to previous state on timeout if con.count >= self.features_req_timeout/tick: logging.info(condesc + "Timeout features request from " + str(con.switch_addr)) con.cstate = 2 elif con.cstate == 4: if (self.controller_timeout < 0 or con.count < self.controller_timeout/tick): logging.debug(condesc + "Maintaining connection to " + str(con.switch_addr)) con.count = con.count + 1 else: logging.info(condesc + "Disconnecting from " + str(con.switch_addr)) con.disconnect() con.cstate = 0 else: con.cstate = 0 states.append(con.cstate) logging.debug("Cycle " + str(cycle) + ", states " + str(states) + ", disconnected_count " + str(disconnected_count)) if 4 in states: disconnected_count = 0 else: disconnected_count = disconnected_count + 1 if cycle != 0: self.assertTrue(disconnected_count < self.disconnected_timeout/tick, "Timeout expired connecting to controller") else: # on first cycle, allow more time for initial connect self.assertTrue(disconnected_count < 2*self.disconnected_timeout/tick, "Timeout expired connecting to controller on init") if cycle > self.cxn_cycles: break time.sleep(tick)
def runTest(self): logging = get_logger() logging.info("Running Grp10No110 test ") of_ports = config["port_map"].keys() of_ports.sort() self.assertTrue(len(of_ports) > 0, "Not enough ports for test") #Clear switch state rv = delete_all_flows(self.controller) self.assertEqual(rv, 0, "Failed to delete all flows") rc = delete_all_flows_emer(self.controller) self.assertEqual(rc, 0, "Failed to send delete-emergency flow") response, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue(response is None, "Emergency flow cannot be deleted: Check if the Switch supports Emergency Mode") #Insert an emergency flow entry test_packet = simple_tcp_packet() match = parse.packet_to_flow_match(test_packet) e_flow_mod = message.flow_mod() match = parse.packet_to_flow_match(test_packet) e_flow_mod.match = match e_flow_mod.flags = e_flow_mod.flags | ofp.OFPFF_EMERG e_flow_mod.match.in_port = of_ports[0] act = action.action_output() act.port = of_ports[1] self.assertTrue(e_flow_mod.actions.add(act), "Failed to add action") rv = self.controller.message_send(e_flow_mod) response=None response, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue(response is None, "Unable to add emergency flows") self.assertTrue(rv != -1, "Unable to send a flow_mod") self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") # Assert matching dataplane packet isn't forwarded. self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should not be forwarded yes_ports=[] no_ports = set(of_ports) receive_pkt_check(self.dataplane,test_packet,yes_ports,no_ports,self) #Shutdown the controller self.controller.initial_hello = False self.controller.disconnect() #waiting for the switch to recognize the connection drop. sleep(2) assertionerr=False pkt=simple_tcp_packet() logging.info("checking for control channel status") try : for x in range(15): logging.info("Sending an unmatched packet") self.dataplane.send(of_ports[1], str(pkt)) (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, timeout=10) self.assertTrue(response is not None, 'PacketIn is not generated--Control plane is down') except AssertionError : #Send a simple tcp packet on ingress_port logging.info("Control channel is down") logging.info("Sending simple tcp packet ...") logging.info("Checking for Emergency flows status after controller shutdown") self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should be forwarded yes_ports=[of_ports[1]] no_ports = set(of_ports).difference(yes_ports) receive_pkt_check(self.dataplane,test_packet,yes_ports,no_ports,self) logging.info("Emergency flows are active after control channel is disconnected") assertionerr = True else : self.assertTrue(assertionerr is True, "Failed to shutdown the control plane") self.controller.initial_hello=True self.controller.connect() sleep(3) features = message.features_request() rv = self.controller.message_send(features) # for i in range(10): # sleep(2) (response, raw) = self.controller.poll(ofp.OFPT_FEATURES_REPLY, timeout=5) self.assertTrue(response is not None, "Control channel connection could not be established") logging.info("Control channel is up") logging.info("Sending simple tcp packet ...") logging.info("Checking for Emergency flows status after controller reconnection") self.dataplane.send(of_ports[0], str(test_packet)) #Verify dataplane packet should be forwarded yes_ports=[of_ports[1]] no_ports = set(of_ports).difference(yes_ports) receive_pkt_check(self.dataplane,test_packet,yes_ports,no_ports,self) logging.info("Emergency flows are active after control channel is reconnected") logging.info("Cleaning up emergency flows") rc = delete_all_flows_emer(self.controller) self.assertEqual(rc, 0, "Failed to send delete-emergency flow") res, pkt = self.controller.poll(ofp.OFPT_ERROR, timeout=5) self.assertTrue(res is None, "Emergency flows could not be deleted.")