blob: f4cd95059b71824835a535b9789b26a465cfb4d3 [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.
"""
@brief Utilities involving LOXI naming conventions
Utility functions for OpenFlow class generation
These may need to be sorted out into language specific functions
"""
import re
import sys
import loxi_globals
from generic_utils import find, memoize
##
# Class types:
#
# Virtual
# A virtual class is one which does not have an explicit wire
# representation. For example, an inheritance super class
# or a list type.
#
# List
# A list of objects of some other type
#
# TLV16
# The wire represenation starts with 16-bit type and length fields
#
# OXM
# An extensible match object
#
# Message
# A top level OpenFlow message
#
#
class NoneClass(object):
def is_instanceof(self, x):
return False
none_item = NoneClass()
def _unified_by_name(cls):
c = loxi_globals.unified.class_by_name(cls)
return c if c is not None else none_item
@memoize
def class_is_message(cls):
"""
Return True if cls is a message object based on info in unified
"""
if cls == "of_header":
return False
else:
return _unified_by_name(cls).is_instanceof("of_header")
def class_is_tlv16(cls):
"""
Return True if cls_name is an object which uses uint16 for type and length
"""
if cls.find("of_action") == 0: # Includes of_action_id classes
return True
if cls.find("of_instruction") == 0:
return True
if cls.find("of_queue_prop") == 0:
return True
if cls.find("of_table_feature_prop") == 0:
return True
# *sigh*
if cls.find("of_meter_band_stats") == 0: # NOT A TLV
return False
if cls.find("of_meter_band") == 0:
return True
if cls.find("of_hello_elem") == 0:
return True
if cls == "of_match_v3":
return True
if cls == "of_match_v4":
return True
return False
def class_is_u16_len(cls):
"""
Return True if cls_name is an object which uses initial uint16 length
"""
return cls in ["of_group_desc_stats_entry", "of_group_stats_entry",
"of_flow_stats_entry", "of_bucket", "of_table_features"]
def class_is_oxm(cls):
"""
Return True if cls_name is an OXM object
"""
return _unified_by_name(cls).is_instanceof("of_oxm")
def class_is_action(cls):
"""
Return True if cls_name is an action object
Note that action_id is not an action object, though it has
the same header. It looks like an action header, but the type
is used to identify a kind of action, it does not indicate the
type of the object following.
"""
return _unified_by_name(cls).is_instanceof("of_action")
def class_is_action_id(cls):
"""
Return True if cls_name is an action object
Note that action_id is not an action object, though it has
the same header. It looks like an action header, but the type
is used to identify a kind of action, it does not indicate the
type of the object following.
"""
return _unified_by_name(cls).is_instanceof("of_action_id")
def class_is_instruction(cls):
"""
Return True if cls_name is an instruction object
"""
return _unified_by_name(cls).is_instanceof("of_instruction")
def class_is_meter_band(cls):
"""
Return True if cls_name is an instruction object
"""
return _unified_by_name(cls).is_instanceof("of_meter_band")
def class_is_hello_elem(cls):
"""
Return True if cls_name is an instruction object
"""
return _unified_by_name(cls).is_instanceof("of_hello_elem")
def class_is_queue_prop(cls):
"""
Return True if cls_name is a queue_prop object
"""
return _unified_by_name(cls).is_instanceof("of_queue_prop")
def class_is_table_feature_prop(cls):
"""
Return True if cls_name is a queue_prop object
"""
return _unified_by_name(cls).is_instanceof("of_table_feature_prop")
def class_is_stats_message(cls):
"""
Return True if cls_name is a message object based on info in unified
"""
u = _unified_by_name(cls)
return u.is_instanceof("of_stats_request") or u.ir_instanceof("of_stats_reply")
def class_is_list(cls):
"""
Return True if cls_name is a list object
"""
return (cls.find("of_list_") == 0)
def type_is_of_object(m_type):
"""
Return True if m_type is an OF object type
"""
# Remove _t from the type id and see if key for unified class
return _unified_by_name(re.sub(r'_t$', '', m_type)) != none_item
@memoize
def lookup_ir_wiretype(oftype, version):
""" if of is a reference to an enum in ir, resolve it to the wiretype
declared in that enum. Else return oftype """
enums = loxi_globals.ir[version].enums
enum = find(lambda e: e.name == oftype, enums)
if enum and 'wire_type' in enum.params:
return enum.params['wire_type']
else:
return oftype