blob: c86c503af2fd0ef4e27d5d5839d8b6306f9c189c [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28"""
29@brief Utilities involving LOXI naming conventions
30
Andreas Wundsam53256162013-05-02 14:05:53 -070031Utility functions for OpenFlow class generation
Rich Lanea06d0c32013-03-25 08:52:03 -070032
33These may need to be sorted out into language specific functions
34"""
35
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080036import re
Rich Lanec3405172013-02-20 18:18:57 -080037import sys
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080038
39import loxi_globals
Andreas Wundsam37c7bc22013-09-17 13:48:35 -070040from generic_utils import find, memoize
Rich Lanea06d0c32013-03-25 08:52:03 -070041
Rich Lanea06d0c32013-03-25 08:52:03 -070042##
43# Class types:
44#
45# Virtual
46# A virtual class is one which does not have an explicit wire
47# representation. For example, an inheritance super class
48# or a list type.
49#
50# List
51# A list of objects of some other type
52#
53# TLV16
54# The wire represenation starts with 16-bit type and length fields
55#
56# OXM
57# An extensible match object
58#
59# Message
60# A top level OpenFlow message
61#
62#
63
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080064class NoneClass(object):
65 def is_instanceof(self, x):
66 return False
67none_item = NoneClass()
68
69def _unified_by_name(cls):
70 c = loxi_globals.unified.class_by_name(cls)
71 return c if c is not None else none_item
72
73@memoize
Rich Lanea06d0c32013-03-25 08:52:03 -070074def class_is_message(cls):
75 """
76 Return True if cls is a message object based on info in unified
77 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080078 if cls == "of_header":
79 return False
80 else:
81 return _unified_by_name(cls).is_instanceof("of_header")
Rich Lanea06d0c32013-03-25 08:52:03 -070082
Rich Lanea06d0c32013-03-25 08:52:03 -070083def class_is_oxm(cls):
84 """
85 Return True if cls_name is an OXM object
86 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080087 return _unified_by_name(cls).is_instanceof("of_oxm")
Rich Lanea06d0c32013-03-25 08:52:03 -070088
89def class_is_action(cls):
90 """
91 Return True if cls_name is an action object
92
93 Note that action_id is not an action object, though it has
94 the same header. It looks like an action header, but the type
95 is used to identify a kind of action, it does not indicate the
96 type of the object following.
97 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080098 return _unified_by_name(cls).is_instanceof("of_action")
Rich Lanea06d0c32013-03-25 08:52:03 -070099
100def class_is_action_id(cls):
101 """
102 Return True if cls_name is an action object
103
104 Note that action_id is not an action object, though it has
105 the same header. It looks like an action header, but the type
106 is used to identify a kind of action, it does not indicate the
107 type of the object following.
108 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800109 return _unified_by_name(cls).is_instanceof("of_action_id")
Rich Lanea06d0c32013-03-25 08:52:03 -0700110
111def class_is_instruction(cls):
112 """
113 Return True if cls_name is an instruction object
114 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800115 return _unified_by_name(cls).is_instanceof("of_instruction")
Rich Lanea06d0c32013-03-25 08:52:03 -0700116
117def class_is_meter_band(cls):
118 """
119 Return True if cls_name is an instruction object
120 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800121 return _unified_by_name(cls).is_instanceof("of_meter_band")
Rich Lanea06d0c32013-03-25 08:52:03 -0700122
123def class_is_hello_elem(cls):
124 """
125 Return True if cls_name is an instruction object
126 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800127 return _unified_by_name(cls).is_instanceof("of_hello_elem")
Rich Lanea06d0c32013-03-25 08:52:03 -0700128
129def class_is_queue_prop(cls):
130 """
131 Return True if cls_name is a queue_prop object
132 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800133 return _unified_by_name(cls).is_instanceof("of_queue_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700134
135def class_is_table_feature_prop(cls):
136 """
137 Return True if cls_name is a queue_prop object
138 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800139 return _unified_by_name(cls).is_instanceof("of_table_feature_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700140
141def class_is_stats_message(cls):
142 """
143 Return True if cls_name is a message object based on info in unified
144 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800145 u = _unified_by_name(cls)
146 return u.is_instanceof("of_stats_request") or u.ir_instanceof("of_stats_reply")
Rich Lanea06d0c32013-03-25 08:52:03 -0700147
Rich Lane13730732013-12-03 13:05:19 -0800148def class_is_bsn_tlv(cls):
149 """
150 Return True if cls_name is a bsn_tlv object
151 """
152 return _unified_by_name(cls).is_instanceof("of_bsn_tlv")
153
Rich Lanea06d0c32013-03-25 08:52:03 -0700154def class_is_list(cls):
155 """
156 Return True if cls_name is a list object
157 """
158 return (cls.find("of_list_") == 0)
159
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800160def class_is(cls, cand_name):
161 return _unified_by_name(cls).is_instanceof(cand_name)
162
Rich Lanea06d0c32013-03-25 08:52:03 -0700163def type_is_of_object(m_type):
164 """
165 Return True if m_type is an OF object type
166 """
167 # Remove _t from the type id and see if key for unified class
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800168 return _unified_by_name(re.sub(r'_t$', '', m_type)) != none_item
Rich Lanec3405172013-02-20 18:18:57 -0800169
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700170@memoize
171def lookup_ir_wiretype(oftype, version):
172 """ if of is a reference to an enum in ir, resolve it to the wiretype
173 declared in that enum. Else return oftype """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800174 enums = loxi_globals.ir[version].enums
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700175 enum = find(lambda e: e.name == oftype, enums)
176 if enum and 'wire_type' in enum.params:
177 return enum.params['wire_type']
178 else:
179 return oftype
Rich Lane2cc2b862014-06-13 14:50:17 -0700180
181def oftype_is_list(oftype):
182 return (oftype.find("list(") == 0)
183
184# Converts "list(of_flow_stats_entry_t)" to "of_flow_stats_entry"
185def oftype_list_elem(oftype):
186 assert oftype.find("list(") == 0
187 return oftype[5:-3]