# Copyright (C) 2016 Rackspace US, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import base64 import logging from os_ken.ofproto import nicira_ext LOG = logging.getLogger(__name__) def action_to_str(act, ofctl_action_to_str): sub_type = act.subtype if sub_type == nicira_ext.NXAST_RESUBMIT: return 'NX_RESUBMIT: {port: %s, table: %s}' % (act.in_port, act.table_id) elif sub_type == nicira_ext.NXAST_REG_MOVE: src_start = act.src_ofs dst_start = act.dst_ofs src_end = src_start + act.n_bits dst_end = dst_start + act.n_bits return 'NX_MOVE: {%s[%s..%s]: %s[%s..%s]}' % (act.dst_field, dst_start, dst_end, act.src_field, src_start, src_end) elif sub_type == nicira_ext.NXAST_REG_LOAD: start = act.ofs end = start + act.nbits return 'NX_LOAD: {%s[%s..%s]: %x}' % (act.dst, start, end, act.value) elif sub_type == nicira_ext.NXAST_LEARN: specs = [] add_spec = specs.append for spec in act.specs: dst_type = spec._dst_type if dst_type == 0: # match if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits start_end = '%s..%s' % (start, end) else: src = spec.src start_end = '[]' add_spec('%s[%s]' % (src, start_end)) elif dst_type == 1: # load if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits src_start_end = '[%s..%s]' % (start, end) else: src = spec.src src_start_end = '[]' if isinstance(spec.dst, (tuple, list)): dst = spec.dst[0] start = spec.dst[1] end = start + spec.n_bits dst_start_end = '[%s..%s]' % (start, end) else: dst = spec.dst dst_start_end = '[]' add_spec('NX_LOAD {%s%s: %s%s}' % (dst, dst_start_end, src, src_start_end)) elif dst_type == 2: # output if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits start_end = '%s..%s' % (start, end) else: src = spec.src start_end = '[]' add_spec('output:%s%s' % (src, start_end)) return ('NX_LEARN: {idle_timeout: %s, ' 'hard_timeouts: %s, ' 'priority: %s, ' 'cookie: %s, ' 'flags: %s, ' 'table_id: %s, ' 'fin_idle_timeout: %s, ' 'fin_hard_timeout: %s, ' 'specs: %s}' % (act.idle_timeout, act.hard_timeout, act.priority, act.cookie, act.flags, act.table_id, act.fin_idle_timeout, act.self.fin_hard_timeout, specs)) elif sub_type == nicira_ext.NXAST_CONJUNCTION: return ('NX_CONJUNCTION: {clause: %s, number_of_clauses: %s, id: %s}' % (act.clause, act.n_clauses, act.id)) elif sub_type == nicira_ext.NXAST_CT: if act.zone_ofs_nbits != 0: start = act.zone_ofs_nbits end = start + 16 zone = act.zone_src + ('[%s..%s]' % (start, end)) else: zone = act.zone_src actions = [ofctl_action_to_str(action) for action in act.actions] return ('NX_CT: {flags: %s, ' 'zone: %s, ' 'table: %s, ' 'alg: %s, ' 'actions: %s}' % (act.flags, zone, act.recirc_table, act.alg, actions)) elif sub_type == nicira_ext.NXAST_NAT: return ('NX_NAT: {flags: %s, ' 'range_ipv4_min: %s, ' 'range_ipv4_max: %s, ' 'range_ipv6_min: %s, ' 'range_ipv6_max: %s, ' 'range_proto_min: %s, ' 'range_proto_max: %s}' % (act.flags, act.range_ipv4_min, act.range_ipv4_max, act.range_ipv6_min, act.range_ipv6_max, act.range_proto_min, act.range_proto_max)) data_str = base64.b64encode(act.data) return 'NX_UNKNOWN: {subtype: %s, data: %s}' % (sub_type, data_str.decode('utf-8'))