def port_mod(switch, msg, rawmsg): """ Process a port_mod message from the controller @param switch The main switch object @param msg The parsed message object of type port_mod @param rawmsg The actual packet received as a string """ switch.logger.debug("Received port_mod from controller") err = None try: port = switch.ports[msg.port_no] if port.hw_addr == msg.hw_addr: port.config = (port.config & ~msg.mask) | (msg.config & msg.mask) if msg.advertise != 0: port.advertise = msg.advertise #@todo check to see if requested features is valid #@todo throw an error if invalid : # http://www.openflow.org/bugs/openflow/ticket/249 port.curr = port.advertise #@todo update port.curr and call to ioctl() to actually change #the port's speed else: err = ofutils.of_error_msg_make(ofp.OFPET_PORT_MOD_FAILED, ofp.OFPPMFC_BAD_HW_ADDR, msg) except IndexError: switch.logger.error( "port_mod from controller tried to access non-existent" + " port %d %x:%x:%x:%x%x:%x" % ((msg.port) + msg.hw_addr)) err = ofutils.of_error_msg_make(ofp.OFPET_PORT_MOD_FAILED, ofp.OFPPMFC_BAD_PORT, msg) if err: switch.controller.message_send(err)
def port_mod(switch, msg, rawmsg): """ Process a port_mod message from the controller @param switch The main switch object @param msg The parsed message object of type port_mod @param rawmsg The actual packet received as a string """ switch.logger.debug("Received port_mod from controller") err = None try: port = switch.ports[msg.port_no] if port.hw_addr == msg.hw_addr: port.config = (port.config& ~msg.mask) | (msg.config & msg.mask) if msg.advertise != 0 : port.advertise = msg.advertise #@todo check to see if requested features is valid #@todo throw an error if invalid : # http://www.openflow.org/bugs/openflow/ticket/249 port.curr = port.advertise #@todo update port.curr and call to ioctl() to actually change #the port's speed else: err = ofutils.of_error_msg_make(ofp.OFPET_PORT_MOD_FAILED, ofp.OFPPMFC_BAD_HW_ADDR, msg) except IndexError: switch.logger.error("port_mod from controller tried to access non-existent" + " port %d %x:%x:%x:%x%x:%x" % ((msg.port) + msg.hw_addr )) err = ofutils.of_error_msg_make(ofp.OFPET_PORT_MOD_FAILED, ofp.OFPPMFC_BAD_PORT, msg) if err: switch.controller.message_send(err)
def table_mod_process(self, table_mod): """ Apply the config changes specified in a table_mod to one or more tables in the pipeline @param table_mod a fully instantiated table_mod class @return None on success, an ofp_error message on error """ if table_mod.table_id >= self.n_tables and table_mod.table_id != 0xFF: return ofutils.of_error_msg_make(ofp.OFPET_TABLE_MOD_FAILED, ofp.OFPTMFC_BAD_TABLE, table_mod) if table_mod.config not in [ ofp.OFPTC_TABLE_MISS_CONTROLLER, ofp.OFPTC_TABLE_MISS_CONTINUE, ofp.OFPTC_TABLE_MISS_DROP, ]: return ofutils.of_error_msg_make(ofp.OFPET_TABLE_MOD_FAILED, ofp.OFPTMFC_BAD_CONFIG, table_mod) update_list = None if table_mod.table_id == 0xFF: update_list = self.tables else: update_list = [self.tables[table_mod.table_id]] for table in update_list: self.logger.debug( "table_mod: " + "setting table %d " % table.table_id + "to miss_policy %d" % table_mod.config ) table.miss_policy = table_mod.config return None
def table_mod_process(self, table_mod): """ Apply the config changes specified in a table_mod to one or more tables in the pipeline @param table_mod a fully instantiated table_mod class @return None on success, an ofp_error message on error """ if (table_mod.table_id >= self.n_tables and table_mod.table_id != 0xff): return ofutils.of_error_msg_make(ofp.OFPET_TABLE_MOD_FAILED, ofp.OFPTMFC_BAD_TABLE, table_mod) if table_mod.config not in [ ofp.OFPTC_TABLE_MISS_CONTROLLER, ofp.OFPTC_TABLE_MISS_CONTINUE, ofp.OFPTC_TABLE_MISS_DROP]: return ofutils.of_error_msg_make(ofp.OFPET_TABLE_MOD_FAILED, ofp.OFPTMFC_BAD_CONFIG, table_mod) update_list = None if table_mod.table_id == 0xff: update_list = self.tables else: update_list = [ self.tables[table_mod.table_id]] for table in update_list: self.logger.debug("table_mod: " + "setting table %d " % table.table_id + "to miss_policy %d" % table_mod.config) table.miss_policy = table_mod.config return None
def _validate_match_mpls(match, flow_mod, logger): mpls_label_specified = (match.wildcards & ofp.OFPFMF_MPLS_LABEL) == 0 if ( mpls_label_specified and not _test_mpls_label(match.mpls_label)): logger.error( "rejecting broken match: bad mpls label: %x %d" % (match.wildcards, match.mpls_label)) raise MatchException( ofutils.of_error_msg_make( ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) # We only care about the tc value: # IF it's not wildcarded and # if mpls_label is wildcarded or not NONE # because if there is no mpls_label, there is no tc tc_needs_test = ( (match.wildcards & ofp.OFPFMF_MPLS_TC) == 0 and ( not mpls_label_specified or match.mpls_label != ofp.OFPML_NONE )) if ( tc_needs_test and not _test_mpls_tc(match.mpls_tc)): logger.error("rejecting broken match: bad mpls tc") raise MatchException( ofutils.of_error_msg_make( ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) return None
def _validate_match_vlan(match, flow_mod, logger): vlan_specified = (match.wildcards & ofp.OFPFMF_DL_VLAN) == 0 if (vlan_specified and not _test_vlan_vid(match.dl_vlan)): logger.error("rejecting broken match: bad vlan: %d" % match.dl_vlan) raise MatchException( ofutils.of_error_msg_make(ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) pcp_needs_test = ((match.wildcards & ofp.OFPFMF_DL_VLAN_PCP) == 0 and (not vlan_specified or match.dl_vlan != ofp.OFPVID_NONE)) if (pcp_needs_test and not _test_vlan_pcp(match.dl_vlan_pcp)): logger.error("rejecting broken match: bad vlan_pcp") raise MatchException( ofutils.of_error_msg_make(ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) return None
def _validate_action_set_mpls_tc(action, switch, flow_mod, logger): if _test_mpls_tc(action.mpls_tc): return None else: return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_instruction_goto_table(instruction, switch, flow_mod, logger): table_id = instruction.table_id if table_id >= 0 and table_id < switch.pipeline.n_tables: return None else: return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_action_push_mpls(action, switch, flow_mod, logger): if (action.ethertype == packet.ETHERTYPE_MPLS or action.ethertype == packet.ETHERTYPE_MPLS_MCAST): return None else: return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_instruction_goto_table(instruction, switch, flow_mod, logger): table_id = instruction.table_id if table_id >= 0 and table_id < switch.pipeline.n_tables : return None else: return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_action_output(action, switch, flow_mod, logger): if action.port >= ofp.OFPP_MAX or action.port in switch.ports: return None # port is valid else: logger.error("invalid port %d (0x%x) in action_output" % (action.port, action.port)) return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_OUT_PORT, flow_mod)
def _validate_action_push_vlan(action, switch, flow_mod, logger): if (action.ethertype == packet.ETHERTYPE_VLAN or action.ethertype == packet.ETHERTYPE_VLAN_QinQ): return None else: logger.error("invalid ethertype 0x%x in action_push_vlan" % action.ethertype) return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_action_push_vlan(action, switch, flow_mod, logger): if (action.ethertype == packet.ETHERTYPE_VLAN or action.ethertype == packet.ETHERTYPE_VLAN_QinQ): return None else: logger.error("invalid ethertype 0x%x in action_push_vlan" % action.ethertype ) return ofutils.of_error_msg_make(ofp.OFPET_BAD_ACTION, ofp.OFPBAC_BAD_ARGUMENT, flow_mod)
def _validate_match_vlan(match, flow_mod, logger): vlan_specified = (match.wildcards & ofp.OFPFMF_DL_VLAN) == 0 if ( vlan_specified and not _test_vlan_vid(match.dl_vlan)): logger.error("rejecting broken match: bad vlan: %d" % match.dl_vlan) raise MatchException( ofutils.of_error_msg_make( ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) pcp_needs_test = ( (match.wildcards & ofp.OFPFMF_DL_VLAN_PCP) == 0 and (not vlan_specified or match.dl_vlan != ofp.OFPVID_NONE)) if ( pcp_needs_test and not _test_vlan_pcp(match.dl_vlan_pcp)): logger.error("rejecting broken match: bad vlan_pcp") raise MatchException( ofutils.of_error_msg_make( ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) return None
def _validate_match_mpls(match, flow_mod, logger): mpls_label_specified = (match.wildcards & ofp.OFPFMF_MPLS_LABEL) == 0 if (mpls_label_specified and not _test_mpls_label(match.mpls_label)): logger.error("rejecting broken match: bad mpls label: %x %d" % (match.wildcards, match.mpls_label)) raise MatchException( ofutils.of_error_msg_make(ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) # We only care about the tc value: # IF it's not wildcarded and # if mpls_label is wildcarded or not NONE # because if there is no mpls_label, there is no tc tc_needs_test = ((match.wildcards & ofp.OFPFMF_MPLS_TC) == 0 and (not mpls_label_specified or match.mpls_label != ofp.OFPML_NONE)) if (tc_needs_test and not _test_mpls_tc(match.mpls_tc)): logger.error("rejecting broken match: bad mpls tc") raise MatchException( ofutils.of_error_msg_make(ofp.OFPET_FLOW_MOD_FAILED, ofp.OFPFMFC_BAD_MATCH, flow_mod)) return None