blob: f4cd95059b71824835a535b9789b26a465cfb4d3 [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
83def class_is_tlv16(cls):
84 """
85 Return True if cls_name is an object which uses uint16 for type and length
86 """
87 if cls.find("of_action") == 0: # Includes of_action_id classes
88 return True
89 if cls.find("of_instruction") == 0:
90 return True
91 if cls.find("of_queue_prop") == 0:
92 return True
93 if cls.find("of_table_feature_prop") == 0:
94 return True
95 # *sigh*
96 if cls.find("of_meter_band_stats") == 0: # NOT A TLV
97 return False
98 if cls.find("of_meter_band") == 0:
99 return True
100 if cls.find("of_hello_elem") == 0:
101 return True
102 if cls == "of_match_v3":
103 return True
104 if cls == "of_match_v4":
105 return True
106 return False
107
108def class_is_u16_len(cls):
109 """
110 Return True if cls_name is an object which uses initial uint16 length
111 """
112 return cls in ["of_group_desc_stats_entry", "of_group_stats_entry",
113 "of_flow_stats_entry", "of_bucket", "of_table_features"]
114
115def class_is_oxm(cls):
116 """
117 Return True if cls_name is an OXM object
118 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800119 return _unified_by_name(cls).is_instanceof("of_oxm")
Rich Lanea06d0c32013-03-25 08:52:03 -0700120
121def class_is_action(cls):
122 """
123 Return True if cls_name is an action object
124
125 Note that action_id is not an action object, though it has
126 the same header. It looks like an action header, but the type
127 is used to identify a kind of action, it does not indicate the
128 type of the object following.
129 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800130 return _unified_by_name(cls).is_instanceof("of_action")
Rich Lanea06d0c32013-03-25 08:52:03 -0700131
132def class_is_action_id(cls):
133 """
134 Return True if cls_name is an action object
135
136 Note that action_id is not an action object, though it has
137 the same header. It looks like an action header, but the type
138 is used to identify a kind of action, it does not indicate the
139 type of the object following.
140 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800141 return _unified_by_name(cls).is_instanceof("of_action_id")
Rich Lanea06d0c32013-03-25 08:52:03 -0700142
143def class_is_instruction(cls):
144 """
145 Return True if cls_name is an instruction object
146 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800147 return _unified_by_name(cls).is_instanceof("of_instruction")
Rich Lanea06d0c32013-03-25 08:52:03 -0700148
149def class_is_meter_band(cls):
150 """
151 Return True if cls_name is an instruction object
152 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800153 return _unified_by_name(cls).is_instanceof("of_meter_band")
Rich Lanea06d0c32013-03-25 08:52:03 -0700154
155def class_is_hello_elem(cls):
156 """
157 Return True if cls_name is an instruction object
158 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800159 return _unified_by_name(cls).is_instanceof("of_hello_elem")
Rich Lanea06d0c32013-03-25 08:52:03 -0700160
161def class_is_queue_prop(cls):
162 """
163 Return True if cls_name is a queue_prop object
164 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800165 return _unified_by_name(cls).is_instanceof("of_queue_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700166
167def class_is_table_feature_prop(cls):
168 """
169 Return True if cls_name is a queue_prop object
170 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800171 return _unified_by_name(cls).is_instanceof("of_table_feature_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700172
173def class_is_stats_message(cls):
174 """
175 Return True if cls_name is a message object based on info in unified
176 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800177 u = _unified_by_name(cls)
178 return u.is_instanceof("of_stats_request") or u.ir_instanceof("of_stats_reply")
Rich Lanea06d0c32013-03-25 08:52:03 -0700179
180def class_is_list(cls):
181 """
182 Return True if cls_name is a list object
183 """
184 return (cls.find("of_list_") == 0)
185
186def type_is_of_object(m_type):
187 """
188 Return True if m_type is an OF object type
189 """
190 # Remove _t from the type id and see if key for unified class
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800191 return _unified_by_name(re.sub(r'_t$', '', m_type)) != none_item
Rich Lanec3405172013-02-20 18:18:57 -0800192
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700193@memoize
194def lookup_ir_wiretype(oftype, version):
195 """ if of is a reference to an enum in ir, resolve it to the wiretype
196 declared in that enum. Else return oftype """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800197 enums = loxi_globals.ir[version].enums
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700198 enum = find(lambda e: e.name == oftype, enums)
199 if enum and 'wire_type' in enum.params:
200 return enum.params['wire_type']
201 else:
202 return oftype