Source code for faucet.tfm_pipeline

"""Configure switch tables with TFM messages."""

from faucet import valve_of

REQUIRED_PROPERTIES = set(
    [
        valve_of.ofp.OFPTFPT_WRITE_ACTIONS,
        valve_of.ofp.OFPTFPT_WRITE_ACTIONS_MISS,
        valve_of.ofp.OFPTFPT_APPLY_ACTIONS,
        valve_of.ofp.OFPTFPT_APPLY_ACTIONS_MISS,
        valve_of.ofp.OFPTFPT_WRITE_SETFIELD,
        valve_of.ofp.OFPTFPT_WRITE_SETFIELD_MISS,
        valve_of.ofp.OFPTFPT_MATCH,
        valve_of.ofp.OFPTFPT_WILDCARDS,
        valve_of.ofp.OFPTFPT_APPLY_SETFIELD_MISS,
        valve_of.ofp.OFPTFPT_APPLY_SETFIELD,
        valve_of.ofp.OFPTFPT_NEXT_TABLES,
        valve_of.ofp.OFPTFPT_NEXT_TABLES_MISS,
        valve_of.ofp.OFPTFPT_APPLY_SETFIELD,
        valve_of.ofp.OFPTFPT_INSTRUCTIONS,
        valve_of.ofp.OFPTFPT_INSTRUCTIONS_MISS,
    ]
)


[docs] def fill_required_properties(new_table): """Ensure TFM has all required properties.""" configured_props = {prop.type for prop in new_table.properties} missing_props = REQUIRED_PROPERTIES - configured_props for prop in missing_props: new_table.properties.append(valve_of.parser.OFPTableFeaturePropOxm(type_=prop))
[docs] def init_table(table_id, name, max_entries, metadata_match, metadata_write): """Initialize a TFM.""" if not metadata_match: metadata_match = 0 if not metadata_write: metadata_write = 0 table_attr = { "config": 3, "max_entries": max_entries, "metadata_match": metadata_match, "metadata_write": metadata_write, "name": name.encode("utf-8"), "properties": [], "table_id": table_id, } return valve_of.parser.OFPTableFeaturesStats(**table_attr)
# pylint: disable=too-many-arguments # pylint: disable=too-many-locals
[docs] def load_tables(dp, valve_cl, max_table_id, min_max_flows, use_oxm_ids, fill_req): """Configure switch tables with TFM messages.""" table_array = [] active_table_ids = sorted( [valve_table.table_id for valve_table in dp.tables.values()] ) for table_id in active_table_ids: valve_table = dp.table_by_id(table_id) max_entries = max(min_max_flows, valve_table.table_config.size) new_table = init_table( table_id, valve_table.name, max_entries, valve_table.metadata_match, valve_table.metadata_write, ) # Match types if valve_table.match_types: oxm_ids = [] if use_oxm_ids: oxm_ids = [ valve_of.parser.OFPOxmId(type_=match_type, hasmask=hasmask) for match_type, hasmask in valve_table.match_types.items() ] new_table.properties.append( valve_of.parser.OFPTableFeaturePropOxm( oxm_ids=oxm_ids, type_=valve_of.ofp.OFPTFPT_MATCH ) ) # Not an exact match table, assume all fields wildcarded. if not valve_table.exact_match: new_table.properties.append( valve_of.parser.OFPTableFeaturePropOxm( oxm_ids=oxm_ids, type_=valve_of.ofp.OFPTFPT_WILDCARDS ) ) insts = set([valve_of.ofp.OFPIT_APPLY_ACTIONS]) # Next tables if valve_table.next_tables: new_table.properties.append( valve_of.parser.OFPTableFeaturePropNextTables( table_ids=valve_table.next_tables, type_=valve_of.ofp.OFPTFPT_NEXT_TABLES, ) ) insts.add(valve_of.ofp.OFPIT_GOTO_TABLE) # Instructions if valve_table.table_config.meter: insts.add(valve_of.ofp.OFPIT_METER) inst_ids = [valve_of.parser.OFPInstructionId(type_) for type_ in insts] new_table.properties.append( valve_of.parser.OFPTableFeaturePropInstructions( type_=valve_of.ofp.OFPTFPT_INSTRUCTIONS, instruction_ids=inst_ids ) ) apply_actions = set() if valve_table.table_config.dec_ttl and valve_cl.DEC_TTL: apply_actions.add(valve_of.ofp.OFPAT_DEC_NW_TTL) # Set fields and apply actions if valve_table.set_fields: apply_actions.add(valve_of.ofp.OFPAT_SET_FIELD) if "vlan_vid" in valve_table.set_fields: apply_actions.add(valve_of.ofp.OFPAT_PUSH_VLAN) oxm_ids = [] if use_oxm_ids: oxm_ids = [ valve_of.parser.OFPOxmId(type_=field, hasmask=False) for field in valve_table.set_fields ] new_table.properties.append( valve_of.parser.OFPTableFeaturePropOxm( oxm_ids=oxm_ids, type_=valve_of.ofp.OFPTFPT_APPLY_SETFIELD ) ) if valve_table.table_config.output: apply_actions.add(valve_of.ofp.OFPAT_OUTPUT) apply_actions.add(valve_of.ofp.OFPAT_POP_VLAN) if valve_cl.GROUPS: apply_actions.add(valve_of.ofp.OFPAT_GROUP) if apply_actions: action_ids = [valve_of.parser.OFPActionId(type_) for type_ in apply_actions] new_table.properties.append( valve_of.parser.OFPTableFeaturePropActions( type_=valve_of.ofp.OFPTFPT_APPLY_ACTIONS, action_ids=action_ids ) ) # Miss goto table option. if valve_table.table_config.miss_goto: miss_table_id = dp.tables[valve_table.table_config.miss_goto].table_id new_table.properties.append( valve_of.parser.OFPTableFeaturePropNextTables( table_ids=[miss_table_id], type_=valve_of.ofp.OFPTFPT_NEXT_TABLES_MISS, ) ) inst_ids = [valve_of.parser.OFPInstructionId(valve_of.ofp.OFPIT_GOTO_TABLE)] new_table.properties.append( valve_of.parser.OFPTableFeaturePropInstructions( type_=valve_of.ofp.OFPTFPT_INSTRUCTIONS_MISS, instruction_ids=inst_ids, ) ) if fill_req: fill_required_properties(new_table) table_array.append(new_table) tfm_table_ids = {table.table_id for table in table_array} for missing_table_id in set(range(max_table_id + 1)) - tfm_table_ids: new_table = init_table( missing_table_id, str(missing_table_id), min_max_flows, 0, 0 ) if fill_req: fill_required_properties(new_table) table_array.append(new_table) return table_array