def _setup_wire_index(self, wire_index_data): self.wire_index = {} # all wire for name, data in wire_index_data.items(): try: if data['mode'] == 'shared': self.wire_index[name] = patch_wire.SharedWire(name, data, self.ofp_version) elif data['mode'] == 'exclusive': self.wire_index[name] = patch_wire.ExclusiveWire(name, data, self.ofp_version) else: msg = "Wire:%s have invalid 'mode'" % name raise patch_error.PatchDefinitionError(msg) except KeyError: msg = "Wire:%s does not have 'mode'" % name raise patch_error.PatchDefinitionError(msg)
def _generate_wire_rule_by_path(self, forward, flow_rule, path_elm_pairs, test_host_port, dut_host_port): match_eth = 'eth_src' if forward else 'eth_dst' host_mac = test_host_port.mac_addr for path_elm_pair in path_elm_pairs: rule = { # 'dpid': path_elm_pair.in_elm.node, # 'inport': path_elm_pair.in_elm.port, # 'outport': path_elm_pair.out_elm.port, 'dpid': path_elm_pair.in_elm.node_entity.datapath_id, 'inport': path_elm_pair.in_elm.port_entity.number, 'outport': path_elm_pair.out_elm.port_entity.number, match_eth: host_mac, 'priority': 32767 } # select action at dut-edge by direction: push/pop vlan if self.__use_vlan(path_elm_pair, dut_host_port, forward): # print "## %s, %s, %s" % (path_elm_pair, dut_host_port, forward) if forward: if self.ofp_version == "OpenFlow13": rule['push_vlan'] = dut_host_port.vlan_id elif self.ofp_version == "OpenFlow10": rule['set_vlan'] = dut_host_port.vlan_id else: msg = "OpenFlow version unknown for generation wire flow rule." raise patch_error.PatchDefinitionError(msg) else: rule['vlan_vid'] = dut_host_port.vlan_id rule['pop_vlan'] = "true" # merge self._merge_flow_rule(path_elm_pair.in_elm.node, flow_rule, rule)
def _setup_dut_hosts(self): try: dut_hosts_data = self.node_data['dut-hosts'] except KeyError: msg = "Could not find 'dut-hosts' data in node info" raise patch_error.PatchDefinitionError(msg) for dut_name, dut_data in dut_hosts_data.items(): self.dut_host_index[dut_name] = DUTHost(dut_name, dut_data)
def _setup_dispatchers(self): try: dispatcher_data = self.node_data['dispatchers'] except KeyError: msg = "Could not find 'dispatcher' data in node info" raise patch_error.PatchDefinitionError(msg) for di_name, di_data in dispatcher_data.items(): self.dispatcher_index[di_name] = Dispatcher(di_name, di_data)
def _setup_test_hosts(self): try: test_hosts_data = self.node_data['test-hosts'] except KeyError: msg = "Could not find 'test-hosts' data in node info" raise patch_error.PatchDefinitionError(msg) for th_name, th_data in test_hosts_data.items(): self.test_host_index[th_name] = TestHost(th_name, th_data)
def __create_dut_host_port(self, host, host_name, port_name): cp_role = self.__counterpart_node_role(host_name, port_name) port_data = host.port_index[port_name].data if cp_role == 'switch': host.port_index[port_name]\ = patch_port.DUTHostPort(port_name, port_data) else: msg = "DUT-Host,Port=%s,%s does not connect switch" % (host_name, port_name) raise patch_error.PatchDefinitionError(msg)
def __counterpart_node_role(self, node_name, port_name): link = self.linkmgr.find_link_by_name(node_name, port_name) if link: counterpart_port = link.counterpart_by_name(node_name, port_name) counterpart_node = self.node_by_name(counterpart_port.node) return counterpart_node.role else: msg = "Cound not find link counterpart of Node,Port=%s,%s" % (node_name, port_name) raise patch_error.PatchDefinitionError(msg)
def __init__(self, name, wire_group_data, ofp_version="OpenFlow10"): self.name = name self.wire_group_data = wire_group_data self.ofp_version = ofp_version try: self.id = self.wire_group_data['id'] self.wires = self.wire_group_data['wires'] except KeyError as err: msg = "Wire group:%s does not have key:%s" % (self.name, err.message) raise patch_error.PatchDefinitionError(msg)
def dut_to_host_port_pair(self): head_port = self.path[0].port_entity tail_port = self.path[-1].port_entity if head_port.is_host_edge_port() and tail_port.is_dut_edge_port(): return self._forward_path_port_pair(list(reversed(self.path))) elif head_port.is_dut_edge_port() and tail_port.is_host_edge_port(): return self._forward_path_port_pair(self.path) else: msg = "wire head/tail is same type: dut-edge or host-edge" raise patch_error.PatchDefinitionError(msg)
def generate_bcast_rule_by_wire_group(self, bcast_wire, out_ports): # wire group id (use as mpls label) wire_group_id = self.id # path of broadcast (DUT edge -> host edge) path_elm_pairs = bcast_wire.dut_to_host_port_pair() # switch: [rules] dictionary flow_rule = {} for path_elm_pair in path_elm_pairs: rule = { # 'dpid': path_elm_pair.in_elm.node, # 'inport': path_elm_pair.in_elm.port, # 'outport': path_elm_pair.out_elm.port 'dpid': path_elm_pair.in_elm.node_entity.datapath_id, 'inport': path_elm_pair.in_elm.port_entity.number, 'outport': path_elm_pair.out_elm.port_entity.number, 'eth_dst': 'ff:ff:ff:ff:ff:ff', 'priority': 16535 } if path_elm_pair.in_elm.port_entity.is_dut_edge_port(): # at DUT edge switch dut_host_port = bcast_wire.dut_host_elm.port_entity if dut_host_port.has_vlan(): # if DUT port is vlan-trunk rule.update({ 'vlan_vid': dut_host_port.vlan_id, 'set_vlan': wire_group_id }) else: # if DUT port is vlan-access if self.ofp_version == "OpenFlow13": rule['push_vlan'] = wire_group_id elif self.ofp_version == "OpenFlow10": rule['set_vlan'] = wire_group_id else: msg = "OpenFlow version unknown for generation wire flow rule." raise patch_error.PatchDefinitionError(msg) elif path_elm_pair.out_elm.port_entity.is_host_edge_port(): # at HOST edge switch rule.update({ 'vlan_vid': wire_group_id, 'pop_vlan': "true", 'outports': out_ports # multiple outport }) # remove(replace to 'outports' added as default) rule.pop('outport') else: # at inter-switch rule.update({ 'vlan_vid': wire_group_id }) flow_rule[path_elm_pair.in_elm.node] = [rule] return flow_rule
def _forward_path_port_pair(path): elm_pairs = [] for i in xrange(len(path) - 1): in_elm = path[i] out_elm = path[i + 1] if in_elm.node == out_elm.node: elm_pairs.append(patch_link.NodeLink(in_elm, out_elm)) if len(elm_pairs) == 0: msg = "Path element pairs not found for path:%s" % path raise patch_error.PatchDefinitionError(msg) return elm_pairs
def __init__(self, wire_data): ################################## self.ofp_version = "OpenFlow10" # TODO: ofp version selection ################################## try: self._setup_wire_index(wire_data['wire-index']) self._setup_wire_group_index(wire_data['wire-group-index']) except KeyError as err: msg = "Could not find key:%s in wire info" % err.message raise patch_error.PatchDefinitionError(msg) self._setup_exclusive_wires()
def gen_wire_manager_by_file(file_name): try: wire_data_file = open(file_name, 'r') wire_data = json.load(wire_data_file) wire_data_file.close() return patch_wire_group.WireManager(wire_data) except ValueError as err: msg = "Wire info file, %s: json parse error.\n%s" % (file_name, err) raise patch_error.PatchDefinitionError(msg) except IOError as err: msg = "Cannot open wire info file: %s.\n%s" % (file_name, err) raise patch_error.PatchError(msg)
def gen_node_manager_by_file(file_name): try: node_data_file = open(file_name, 'r') node_data = json.load(node_data_file) node_data_file.close() return patch_node.NodeManager(node_data) except ValueError as err: msg = "Node info file, %s: json parse error.\n%s" % (file_name, err) raise patch_error.PatchDefinitionError(msg) except IOError as err: msg = "Cannot open node info file: %s.\n%s" % (file_name, err) raise patch_error.PatchError(msg)
def __init__(self, name, wire_data, ofp_version="OpenFlow10"): self.name = name self.path = [] self.ofp_version = ofp_version try: self.mode = wire_data['mode'] self._setup_wire_elms(wire_data['path']) # end points of wire self.test_host_elm = patch_link.NodeLinkElement( *wire_data['test-host-port']) self.dut_host_elm = patch_link.NodeLinkElement( *wire_data['dut-host-port']) except KeyError as err: msg = "Wire:%s does not have key:%s" % (self.name, err.message) raise patch_error.PatchDefinitionError(msg)
def __create_dispatcher_port(self, dispatcher, dispatcher_name, port_name): cp_role = self.__counterpart_node_role(dispatcher_name, port_name) # print "// switch:%s, port:%s, role:%s" % (dispatcher_name, port_name, cp_role) port_data = dispatcher.port_index[port_name].data if cp_role == 'test-host': dispatcher.port_index[port_name]\ = patch_port.HostEdgePort(port_name, port_data) elif cp_role == 'dut-host': dispatcher.port_index[port_name]\ = patch_port.DUTEdgePort(port_name, port_data) elif cp_role == 'switch': dispatcher.port_index[port_name]\ = patch_port.InterSwitchPort(port_name, port_data) else: msg = "Dispatcher,Port=%s,%s connected unknown host/port" raise patch_error.PatchDefinitionError(msg)
def _generate_wire_rule_by_path(self, forward, flow_rule, path_elm_pairs, test_host_port, dut_host_port): for path_elm_pair in path_elm_pairs: try: rule = { # 'dpid': path_elm_pair.in_elm.node, # 'inport': path_elm_pair.in_elm.port, # 'outport': path_elm_pair.out_elm.port 'dpid': path_elm_pair.in_elm.node_entity.datapath_id, 'inport': path_elm_pair.in_elm.port_entity.number, 'outport': path_elm_pair.out_elm.port_entity.number, 'priority': 65535 } # merge self._merge_flow_rule(path_elm_pair.in_elm.node, flow_rule, rule) except AttributeError as err: msg = "Node or Port definition missing in path_elm:%s" % path_elm_pair raise patch_error.PatchDefinitionError(msg)