"""Parse JSON for TFM based table config."""
import json
import os
from faucet import valve_of
[docs]class LoadRyuTables(object):
_CLASS_NAME_TO_NAME_IDS = {
'OFPTableFeaturePropInstructions': 'instruction_ids',
'OFPTableFeaturePropNextTables': 'table_ids',
'OFPTableFeaturePropActions': 'action_ids',
'OFPTableFeaturePropOxm': 'oxm_ids'}
def __init__(self, cfgpath, pipeline_conf):
self.ryu_table_translator = OpenflowToRyuTranslator(
cfgpath, pipeline_conf)
[docs] def load_tables(self):
try:
tables = self.ryu_table_translator.create_ryu_structure()
return self._create_tables(tables)
except (ValueError, IOError) as err:
print(err)
return []
def _create_tables(self, tables_information):
table_array = []
for table in tables_information:
for table_class_name, table_attr in list(table.items()):
table_class = getattr(valve_of.parser, table_class_name,)
properties = self._create_features(table_attr['properties'])
table_attr['properties'] = properties
table_attr['name'] = table_attr['name'].encode('utf-8')
new_table = table_class(**table_attr)
table_array.append(new_table)
return table_array
def _create_features(self, table_features_information):
features_array = []
for feature in table_features_information:
for feature_class_name, feature_attr in list(feature.items()):
name_id = self._CLASS_NAME_TO_NAME_IDS[feature_class_name]
feature_class = getattr(valve_of.parser, feature_class_name)
instruction_ids = self._create_instructions(feature_attr[name_id])
feature_attr[name_id] = instruction_ids
feature_attr['type_'] = feature_attr.pop('type')
new_feature = feature_class(**feature_attr)
features_array.append(new_feature)
return features_array
@staticmethod
def _create_instructions(instruction_ids_information):
instruction_array = []
for instruction in instruction_ids_information:
if isinstance(instruction, dict):
for instruction_class_name, instruction_attr in list(instruction.items()):
instruction_class = getattr(valve_of.parser, instruction_class_name)
instruction_attr['type_'] = instruction_attr.pop('type')
new_instruction = instruction_class(**instruction_attr)
instruction_array.append(new_instruction)
else:
instruction_array = instruction_ids_information
break
return instruction_array
[docs]class OpenflowToRyuTranslator(object):
def __init__(self, cfgpath, pipeline_conf):
self.openflow_to_ryu = json.loads(
open(os.path.join(cfgpath, 'ofproto_to_ryu.json')).read())
self.pipeline_conf = json.loads(
open(os.path.join(cfgpath, pipeline_conf)).read())
[docs] def create_ryu_structure(self):
tables = []
for openflow_table in self.pipeline_conf:
table_properties = []
for property_item in openflow_table['properties']:
fields_tag = self.openflow_to_ryu['tables'][property_item['name']]['action_tag']
actions_ids = property_item[fields_tag]
table_properties.append(
self._create_table_feature(
property_item['name'],
actions_ids,
property_item['type']))
tables.append(
self._create_table(
table_id=openflow_table['table_id'],
name=openflow_table['name'],
config=3,
max_entries=openflow_table['max_entries'],
metadata_match=0,
metadata_write=0,
properties=table_properties))
return tables
def _create_table(self, table_id, name, config, max_entries,
metadata_match, metadata_write, properties):
return {
self.openflow_to_ryu['table_tag']: {
'config': config,
'max_entries': max_entries,
'metadata_match': metadata_match,
'metadata_write': metadata_write,
'name': name,
'properties': properties,
'table_id': table_id}}
def _create_table_feature(self, name, actions, type_id):
table_feature_name = self.openflow_to_ryu['tables'][name]['name']
instruction_id_name = self.openflow_to_ryu['tables'][name]['action_tag']
action_id_name = self.openflow_to_ryu['content'][instruction_id_name]
if action_id_name:
new_array_instructions = []
for action in actions:
if 'name' in action:
action.pop('name')
new_array_instructions.append({action_id_name: action})
else:
new_array_instructions = actions
new_table_feature = {
table_feature_name: {
instruction_id_name: new_array_instructions,
'type': type_id}}
return new_table_feature