blob: c7382bbd4532df1d5f472edf943631b05f3e83f7 [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#
Murat Parlakisikf95672c2016-12-05 00:53:17 -080059# OXS
60# Extensible Stats Object
61#
Rich Lanea06d0c32013-03-25 08:52:03 -070062# Message
63# A top level OpenFlow message
64#
65#
66
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080067class NoneClass(object):
68 def is_instanceof(self, x):
69 return False
70none_item = NoneClass()
71
72def _unified_by_name(cls):
73 c = loxi_globals.unified.class_by_name(cls)
74 return c if c is not None else none_item
75
76@memoize
Rich Lanea06d0c32013-03-25 08:52:03 -070077def class_is_message(cls):
78 """
79 Return True if cls is a message object based on info in unified
80 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080081 if cls == "of_header":
82 return False
83 else:
84 return _unified_by_name(cls).is_instanceof("of_header")
Rich Lanea06d0c32013-03-25 08:52:03 -070085
Rich Lanea06d0c32013-03-25 08:52:03 -070086def class_is_oxm(cls):
87 """
88 Return True if cls_name is an OXM object
89 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -080090 return _unified_by_name(cls).is_instanceof("of_oxm")
Rich Lanea06d0c32013-03-25 08:52:03 -070091
Murat Parlakisikf95672c2016-12-05 00:53:17 -080092def class_is_oxs(cls):
93 """
94 Return True if cls_name is an OXS object
95 """
96 return _unified_by_name(cls).is_instanceof("of_oxs")
97
Rich Lanea06d0c32013-03-25 08:52:03 -070098def class_is_action(cls):
99 """
100 Return True if cls_name is an action object
101
102 Note that action_id is not an action object, though it has
103 the same header. It looks like an action header, but the type
104 is used to identify a kind of action, it does not indicate the
105 type of the object following.
106 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800107 return _unified_by_name(cls).is_instanceof("of_action")
Rich Lanea06d0c32013-03-25 08:52:03 -0700108
109def class_is_action_id(cls):
110 """
111 Return True if cls_name is an action object
112
113 Note that action_id is not an action object, though it has
114 the same header. It looks like an action header, but the type
115 is used to identify a kind of action, it does not indicate the
116 type of the object following.
117 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800118 return _unified_by_name(cls).is_instanceof("of_action_id")
Rich Lanea06d0c32013-03-25 08:52:03 -0700119
120def class_is_instruction(cls):
121 """
122 Return True if cls_name is an instruction object
123 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800124 return _unified_by_name(cls).is_instanceof("of_instruction")
Rich Lanea06d0c32013-03-25 08:52:03 -0700125
126def class_is_meter_band(cls):
127 """
128 Return True if cls_name is an instruction object
129 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800130 return _unified_by_name(cls).is_instanceof("of_meter_band")
Rich Lanea06d0c32013-03-25 08:52:03 -0700131
132def class_is_hello_elem(cls):
133 """
134 Return True if cls_name is an instruction object
135 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800136 return _unified_by_name(cls).is_instanceof("of_hello_elem")
Rich Lanea06d0c32013-03-25 08:52:03 -0700137
138def class_is_queue_prop(cls):
139 """
140 Return True if cls_name is a queue_prop object
141 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800142 return _unified_by_name(cls).is_instanceof("of_queue_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700143
144def class_is_table_feature_prop(cls):
145 """
146 Return True if cls_name is a queue_prop object
147 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800148 return _unified_by_name(cls).is_instanceof("of_table_feature_prop")
Rich Lanea06d0c32013-03-25 08:52:03 -0700149
150def class_is_stats_message(cls):
151 """
152 Return True if cls_name is a message object based on info in unified
153 """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800154 u = _unified_by_name(cls)
155 return u.is_instanceof("of_stats_request") or u.ir_instanceof("of_stats_reply")
Rich Lanea06d0c32013-03-25 08:52:03 -0700156
Rich Lane13730732013-12-03 13:05:19 -0800157def class_is_bsn_tlv(cls):
158 """
159 Return True if cls_name is a bsn_tlv object
160 """
161 return _unified_by_name(cls).is_instanceof("of_bsn_tlv")
162
Rich Lanea06d0c32013-03-25 08:52:03 -0700163def class_is_list(cls):
164 """
165 Return True if cls_name is a list object
166 """
167 return (cls.find("of_list_") == 0)
168
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800169def class_is(cls, cand_name):
170 return _unified_by_name(cls).is_instanceof(cand_name)
171
Rich Lanea06d0c32013-03-25 08:52:03 -0700172def type_is_of_object(m_type):
173 """
174 Return True if m_type is an OF object type
175 """
176 # Remove _t from the type id and see if key for unified class
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800177 return _unified_by_name(re.sub(r'_t$', '', m_type)) != none_item
Rich Lanec3405172013-02-20 18:18:57 -0800178
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700179@memoize
180def lookup_ir_wiretype(oftype, version):
181 """ if of is a reference to an enum in ir, resolve it to the wiretype
182 declared in that enum. Else return oftype """
Andreas Wundsamc94e08c2013-11-15 13:37:59 -0800183 enums = loxi_globals.ir[version].enums
Andreas Wundsam37c7bc22013-09-17 13:48:35 -0700184 enum = find(lambda e: e.name == oftype, enums)
185 if enum and 'wire_type' in enum.params:
186 return enum.params['wire_type']
187 else:
188 return oftype
Rich Lane2cc2b862014-06-13 14:50:17 -0700189
190def oftype_is_list(oftype):
191 return (oftype.find("list(") == 0)
192
193# Converts "list(of_flow_stats_entry_t)" to "of_flow_stats_entry"
194def oftype_list_elem(oftype):
195 assert oftype.find("list(") == 0
196 return oftype[5:-3]