blob: 9d249d401032f5f05ae0b52612a69ff20e5de440 [file] [log] [blame]
# Copyright 2013, Big Switch Networks, Inc.
#
# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
# the following special exception:
#
# LOXI Exception
#
# As a special exception to the terms of the EPL, you may distribute libraries
# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
# that copyright and licensing notices generated by LoxiGen are not altered or removed
# from the LoxiGen Libraries and the notice provided below is (i) included in
# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
# documentation for the LoxiGen Libraries, if distributed in binary form.
#
# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
#
# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
# a copy of the EPL at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# 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
# EPL for the specific language governing permissions and limitations
# under the EPL.
from collections import namedtuple
OFTypeData = namedtuple("OFTypeData", ["init", "pack", "unpack"])
type_data = {
## Primitives
'char': OFTypeData(
init='0',
pack='struct.pack("!B", %s)',
unpack='%s.read("!B")[0]'),
'uint8_t': OFTypeData(
init='0',
pack='struct.pack("!B", %s)',
unpack='%s.read("!B")[0]'),
'uint16_t': OFTypeData(
init='0',
pack='struct.pack("!H", %s)',
unpack='%s.read("!H")[0]'),
'uint32_t': OFTypeData(
init='0',
pack='struct.pack("!L", %s)',
unpack='%s.read("!L")[0]'),
'uint64_t': OFTypeData(
init='0',
pack='struct.pack("!Q", %s)',
unpack='%s.read("!Q")[0]'),
'of_port_no_t': OFTypeData(
init='0',
pack='util.pack_port_no(%s)',
unpack='util.unpack_port_no(%s)'),
'of_fm_cmd_t': OFTypeData(
init='0',
pack='util.pack_fm_cmd(%s)',
unpack='util.unpack_fm_cmd(%s)'),
'of_wc_bmap_t': OFTypeData(
init='util.init_wc_bmap()',
pack='util.pack_wc_bmap(%s)',
unpack='util.unpack_wc_bmap(%s)'),
'of_match_bmap_t': OFTypeData(
init='util.init_match_bmap()',
pack='util.pack_match_bmap(%s)',
unpack='util.unpack_match_bmap(%s)'),
'of_ipv6_t': OFTypeData(
init="'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'",
pack='struct.pack("!16s", %s)',
unpack="%s.read('!16s')[0]"),
'of_mac_addr_t': OFTypeData(
init='[0,0,0,0,0,0]',
pack='struct.pack("!6B", *%s)',
unpack="list(%s.read('!6B'))"),
'of_octets_t': OFTypeData(
init="''",
pack='%s',
unpack='str(%s.read_all())'),
## Strings
'of_port_name_t': OFTypeData(
init="''",
pack='struct.pack("!16s", %s)',
unpack='%s.read("!16s")[0].rstrip("\\x00")'),
'of_table_name_t': OFTypeData(
init="''",
pack='struct.pack("!32s", %s)',
unpack='%s.read("!32s")[0].rstrip("\\x00")'),
'of_serial_num_t': OFTypeData(
init="''",
pack='struct.pack("!32s", %s)',
unpack='%s.read("!32s")[0].rstrip("\\x00")'),
'of_desc_str_t': OFTypeData(
init="''",
pack='struct.pack("!256s", %s)',
unpack='%s.read("!256s")[0].rstrip("\\x00")'),
## Embedded structs
# TODO add helper to generate these
'of_match_t': OFTypeData(
init='common.match()',
pack='%s.pack()',
unpack='common.match.unpack(%s)'),
'of_port_desc_t': OFTypeData(
init='common.port_desc()',
pack='%s.pack()',
unpack='common.port_desc.unpack(%s)'),
'of_meter_features_t': OFTypeData(
init='common.meter_features()',
pack='%s.pack()',
unpack='common.meter_features.unpack(%s)'),
'of_bsn_vport_q_in_q_t': OFTypeData(
init='common.bsn_vport_q_in_q()',
pack='%s.pack()',
unpack='common.bsn_vport_q_in_q.unpack(%s)'),
## TLV Lists
'list(of_action_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='action.unpack_list(%s)'),
'list(of_table_features_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack=None),
'list(of_flow_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_flow_stats_entry(%s)'),
'list(of_bucket_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_bucket(%s)'),
'list(of_packet_queue_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_packet_queue(%s)'),
'list(of_meter_stats_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_meter_stats(%s)'),
# HACK need the match_v3 length field
'list(of_oxm_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='oxm.unpack_list(%s.slice(_length-4))'),
'list(of_group_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_group_stats_entry(%s)'),
'list(of_hello_elem_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_hello_elem(%s)'),
'list(of_action_id_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack=None),
'list(of_group_desc_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_group_desc_stats_entry(%s)'),
'list(of_queue_prop_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='common.unpack_list_queue_prop(%s)'),
'list(of_instruction_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='instruction.unpack_list(%s)'),
'list(of_table_feature_prop_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack=None),
'list(of_meter_band_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='meter_band.unpack_list(%s)'),
## Lists with fixed-length elements
'list(of_bucket_counter_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.bucket_counter.unpack)'),
'list(of_uint32_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.uint32.unpack)'),
'list(of_queue_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.queue_stats_entry.unpack)'),
'list(of_table_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.table_stats_entry.unpack)'),
'list(of_uint8_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.uint8.unpack)'),
'list(of_port_stats_entry_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.port_stats_entry.unpack)'),
'list(of_bsn_interface_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.bsn_interface.unpack)'),
'list(of_meter_band_stats_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.meter_band_stats.unpack)'),
'list(of_port_desc_t)': OFTypeData(
init='[]',
pack='util.pack_list(%s)',
unpack='loxi.generic_util.unpack_list(%s, common.port_desc.unpack)'),
}
class OFType(object):
"""
Encapsulates knowledge about the OpenFlow type system.
"""
version = None
base = None
def __init__(self, string, version):
self.version = version
self.base = string
self.type_data = type_data.get(self.base)
def gen_init_expr(self):
if self.type_data and self.type_data.init:
return self.type_data.init
else:
return "loxi.unimplemented('init %s')" % self.base
def gen_pack_expr(self, value_expr):
if self.type_data and self.type_data.pack:
return self.type_data.pack % value_expr
else:
"loxi.unimplemented('pack %s')" % self.base
def gen_unpack_expr(self, reader_expr):
if self.type_data and self.type_data.unpack:
return self.type_data.unpack % reader_expr
else:
"loxi.unimplemented('unpack %s')" % self.base