blob: af3abd561b5a91184d09853dafe7dc77f137d70f [file] [log] [blame]
Yotam Harcholc742e202013-08-15 12:16:24 -07001import errno
Andreas Wundsam27303462013-07-16 12:52:35 -07002import os
Andreas Wundsam27303462013-07-16 12:52:35 -07003import re
4import subprocess
5import time
6
Andreas Wundsamc8912c12013-11-15 13:44:48 -08007import loxi_globals
Andreas Wundsam7cfeac32013-09-17 13:53:48 -07008from generic_utils import memoize
9import loxi_utils.loxi_utils as loxi_utils
Andreas Wundsam7cfeac32013-09-17 13:53:48 -070010
Andreas Wundsam2be7da52013-08-22 07:34:25 -070011def erase_type_annotation(class_name):
12 m=re.match(r'(.*)<.*>', class_name)
13 if m:
14 return m.group(1)
15 else:
16 return class_name
17
Andreas Wundsam27303462013-07-16 12:52:35 -070018def name_c_to_camel(name):
19 """ 'of_stats_reply' -> 'ofStatsReply' """
20 name = re.sub(r'^_','', name)
21 tokens = name.split('_')
22 for i in range(1, len(tokens)):
23 tokens[i] = tokens[i].title()
24 return "".join(tokens)
25
26def name_c_to_caps_camel(name):
27 """ 'of_stats_reply' to 'OFStatsReply' """
28 camel = name_c_to_camel(name.title())
Andreas Wundsam7cfeac32013-09-17 13:53:48 -070029 if camel.startswith('Ofp'):
30 return camel.replace('Ofp','OF',1)
31 elif camel.startswith('Of'):
Andreas Wundsam27303462013-07-16 12:52:35 -070032 return camel.replace('Of','OF',1)
33 else:
34 return camel
35
Rob Vaterlausfeee3712013-09-30 11:24:19 -070036java_primitive_types = set("boolean byte char short int long".split(" "))
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070037
38### info table about java primitive types, for casting literals in the source code
39# { name : (signed?, length_in_bits) }
Andreas Wundsam46d230f2013-08-02 22:24:06 -070040java_primitives_info = {
Andreas Wundsam438a9c32013-10-07 16:18:52 -070041 'boolean' : (False, 8, False),
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070042 'byte' : (True, 8, True),
43 'char' : (False, 16, True),
44 'short' : (True, 16, True),
45 'int' : (True, 32, False),
46 'long' : (True, 64, False),
Andreas Wundsam46d230f2013-08-02 22:24:06 -070047}
48
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070049def format_primitive_literal(t, value):
50 """ Format a primitive numeric literal for inclusion in the
51 java source code. Takes care of casting the literal
Rob Vaterlausfeee3712013-09-30 11:24:19 -070052 appropriately for correct representation despite Java's
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070053 signed-craziness
54 """
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070055 signed, bits, cast_needed = java_primitives_info[t]
Andreas Wundsamb1324402014-10-23 20:14:41 -070056 if t == 'boolean':
57 return "true" if bool(value) and value not in("False", "false") else "false"
58
Andreas Wundsam46d230f2013-08-02 22:24:06 -070059 max = (1 << bits)-1
60 if value > max:
Andreas Wundsamb1324402014-10-23 20:14:41 -070061 raise Exception("Value %s to large for type %s" % (value, t))
Andreas Wundsam46d230f2013-08-02 22:24:06 -070062
63 if signed:
64 max_pos = (1 << (bits-1)) - 1
65
66 if value > max_pos:
67 if t == "long":
68 return str((1 << bits) - value)
69 else:
70 return "(%s) 0x%x" % (t, value)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070071 return "%s0x%x%s" % ("(%s) " % t if cast_needed else "", value, "L" if t=="long" else "")
72
Yotam Harchold7b84202013-07-26 16:08:10 -070073
Andreas Wundsame916d6f2013-07-30 11:33:58 -070074ANY = 0xFFFFFFFFFFFFFFFF
Yotam Harchold7b84202013-07-26 16:08:10 -070075
76class VersionOp:
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070077 def __init__(self, version=ANY, read=None, write=None, default=None, funnel=None):
Yotam Harchold7b84202013-07-26 16:08:10 -070078 self.version = version
79 self.read = read
80 self.write = write
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -070081 self.default = default
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070082 self.funnel = funnel
Andreas Wundsame916d6f2013-07-30 11:33:58 -070083
Yotam Harchold7b84202013-07-26 16:08:10 -070084 def __str__(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070085 return "[Version: %d, Read: '%s', Write: '%s', Default: '%s', Funnel: '%s' ]" % (self.version, self.read, self.write, self.default, self.funnel )
Yotam Harchold7b84202013-07-26 16:08:10 -070086
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070087### FIXME: This class should really be cleaned up
Andreas Wundsam27303462013-07-16 12:52:35 -070088class JType(object):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070089 """ Wrapper class to hold C to Java type conversion information. JTypes can have a 'public'
90 and or 'private' java type associated with them and can define how those types can be
91 read from and written to ChannelBuffers.
92
93 """
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -070094 def __init__(self, pub_type, priv_type=None):
Andreas Wundsam27303462013-07-16 12:52:35 -070095 self.pub_type = pub_type # the type we expose externally, e.g. 'U8'
96 if priv_type is None:
97 priv_type = pub_type
98 self.priv_type = priv_type # the internal storage type
Yotam Harchold7b84202013-07-26 16:08:10 -070099 self.ops = {}
Yotam Harchold7b84202013-07-26 16:08:10 -0700100
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700101 def set_priv_type(self, priv_type):
102 self.priv_type = priv_type
103 return self
104
105 def op(self, version=ANY, read=None, write=None, default=None, funnel=None, pub_type=ANY):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700106 """
107 define operations to be performed for reading and writing this type
108 (when read_op, write_op is called). The operations 'read' and 'write'
109 can either be strings ($name, and $version and $length will be replaced),
110 or callables (name, version and length) will be passed.
111
112 @param version int OF version to define operation for, or ANY for all
113 @param pub_type boolean whether to define operations for the public type (True), the
114 private type(False) or both (ALL)
115 @param read read expression (either string or callable)s
116 @param write write expression (either string or callable)
117 """
118
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700119 pub_types = [ pub_type ] if pub_type is not ANY else [ False, True ]
120 for pub_type in pub_types:
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700121 self.ops[(version, pub_type)] = VersionOp(version, read, write, default, funnel)
Yotam Harchold7b84202013-07-26 16:08:10 -0700122 return self
Andreas Wundsam27303462013-07-16 12:52:35 -0700123
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700124 def format_value(self, value, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700125 # Format a constant value of this type, for inclusion in the java source code
126 # For primitive types, takes care of casting the value appropriately, to
127 # cope with java's signedness limitation
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700128 t = self.pub_type if pub_type else self.priv_type
129 if t in java_primitive_types:
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700130 return format_primitive_literal(t, value)
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700131 else:
132 return value
Andreas Wundsambf1dbbd2013-07-30 11:07:59 -0700133
Andreas Wundsam27303462013-07-16 12:52:35 -0700134 @property
135 def public_type(self):
136 """ return the public type """
137 return self.pub_type
138
139 def priv(self):
140 """ return the public type """
141 return self.priv_type
142
143 def has_priv(self):
144 """ Is the private type different from the public one?"""
145 return self.pub_type != self.priv_type
146
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700147 def get_op(self, op_type, version, pub_type, default_value, arguments):
148 ver = ANY if version is None else version.int_version
149
150 if not "version" in arguments:
Andreas Wundsamc8912c12013-11-15 13:44:48 -0800151 arguments["version"] = version.dotless_version
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700152
153 def lookup(ver, pub_type):
154 if (ver, pub_type) in self.ops:
155 return getattr(self.ops[(ver, pub_type)], op_type)
156 else:
157 return None
158
159 _op = lookup(ver, pub_type) or lookup(ANY, pub_type) or default_value
160 if callable(_op):
161 return _op(**arguments)
162 else:
163 return reduce(lambda a,repl: a.replace("$%s" % repl[0], str(repl[1])), arguments.items(), _op)
164
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700165 def read_op(self, version=None, length=None, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700166 """ return a Java stanza that reads a value of this JType from ChannelBuffer bb.
167 @param version int - OF wire version to generate expression for
168 @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
169 @param length string, for operations that need it (e.g., read a list of unknown length)
170 Java expression evaluating to the byte length to be read. Defaults to the remainig
171 length of the message.
172 @return string containing generated Java expression.
173 """
Andreas Wundsam27303462013-07-16 12:52:35 -0700174 if length is None:
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700175 # assumes that
176 # (1) length of the message has been read to 'length'
177 # (2) readerIndex at the start of the message has been stored in 'start'
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700178 length = "length - (bb.readerIndex() - start)"
Andreas Wundsam27303462013-07-16 12:52:35 -0700179
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700180 return self.get_op("read", version, pub_type,
181 default_value='ChannelUtilsVer$version.read%s(bb)' % self.pub_type,
182 arguments=dict(length=length)
183 )
Andreas Wundsam27303462013-07-16 12:52:35 -0700184
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700185 def write_op(self, version=None, name=None, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700186 """ return a Java stanza that writes a value of this JType contained in Java expression
187 'name' to ChannelBuffer bb.
188 @param name string containing Java expression that evaluations to the value to be written
189 @param version int - OF wire version to generate expression for
190 @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
191 @return string containing generated Java expression.
192 """
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700193
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700194 return self.get_op("write", version, pub_type,
195 default_value='ChannelUtilsVer$version.write%s(bb, $name)' % self.pub_type,
196 arguments=dict(name=name)
197 )
198
Andreas Wundsam27303462013-07-16 12:52:35 -0700199
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700200 def default_op(self, version=None, pub_type=True):
201 """ return a Java stanza that returns a default value of this JType.
202 @param version JavaOFVersion
203 @return string containing generated Java expression.
204 """
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700205 return self.get_op("default", version, pub_type,
206 arguments = dict(),
207 default_value = self.format_value(0) if self.is_primitive else "null"
208 )
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700209
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700210 def skip_op(self, version=None, length=None):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700211 """ return a java stanza that skips an instance of JType in the input ChannelBuffer 'bb'.
212 This is used in the Reader implementations for virtual classes (because after the
213 discriminator field, the concrete Reader instance will re-read all the fields)
214 Currently just delegates to read_op + throws away the result."""
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700215 return self.read_op(version, length)
216
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700217 def funnel_op(self, version=None, name=None, pub_type=True):
218 t = self.pub_type if pub_type else self.priv_type
219 return self.get_op("funnel", version, pub_type,
220 arguments = dict(name=name),
221 default_value = '$name.putTo(sink)' if not self._is_primitive(pub_type) else "sink.put{}($name)".format(t[0].upper() + t[1:])
222 )
223
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700224 @property
225 def is_primitive(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700226 return self._is_primitive()
227
228 def _is_primitive(self, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700229 """ return true if the pub_type is a java primitive type (and thus needs
230 special treatment, because it doesn't have methods)"""
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700231 t = self.pub_type if pub_type else self.priv_type
232 return t in java_primitive_types
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700233
234 @property
235 def is_array(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700236 return self._is_array()
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700237
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700238 def _is_array(self, pub_type=True):
239 t = self.pub_type if pub_type else self.priv_type
240 return t.endswith("[]")
241
242# Create a default mapping for a list type. Type defauls to List<${java_mapping_of_name}>
243def gen_enum_jtype(java_name, is_bitmask=False):
244 if is_bitmask:
245 java_type = "Set<{}>".format(java_name)
246 default_value = "ImmutableSet.<{}>of()".format(java_name)
247 else:
248 java_type = java_name
249 default_value = "null"
250
251 serializer = "{}SerializerVer$version".format(java_name)
252
253 return JType(java_type)\
254 .op(read="{}.readFrom(bb)".format(serializer),
255 write="{}.writeTo(bb, $name)".format(serializer),
256 default=default_value,
257 funnel="{}.putTo($name, sink)".format(serializer)
258 )
259
260def gen_list_jtype(java_base_name):
261 # read op assumes the class has a public final static field READER that implements
262 # OFMessageReader<$class> i.e., can deserialize an instance of class from a ChannelBuffer
263 # write op assumes class implements Writeable
264 return JType("List<{}>".format(java_base_name)) \
265 .op(
266 read= 'ChannelUtils.readList(bb, $length, {}Ver$version.READER)'.format(java_base_name), \
267 write='ChannelUtils.writeList(bb, $name)',
268 default="ImmutableList.<{}>of()".format(java_base_name),
269 funnel='FunnelUtils.putList($name, sink)'
270 )
271
272def gen_fixed_length_string_jtype(length):
273 return JType('String').op(
274 read='ChannelUtils.readFixedLengthString(bb, {})'.format(length),
275 write='ChannelUtils.writeFixedLengthString(bb, $name, {})'.format(length),
276 default='""',
277 funnel='sink.putUnencodedChars($name)'
278 )
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700279
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700280##### Predefined JType mappings
281# FIXME: This list needs to be pruned / cleaned up. Most of these are schematic.
282
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700283u8 = JType('short', 'byte') \
Andreas Wundsam83d877a2013-09-30 14:26:44 -0700284 .op(read='U8.f(bb.readByte())', write='bb.writeByte(U8.t($name))', pub_type=True) \
285 .op(read='bb.readByte()', write='bb.writeByte($name)', pub_type=False)
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700286u8_list = JType('List<U8>') \
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700287 .op(read='ChannelUtils.readList(bb, $length, U8.READER)',
288 write='ChannelUtils.writeList(bb, $name)',
289 default='ImmutableList.<U8>of()',
290 funnel='FunnelUtils.putList($name, sink)'
291 )
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700292u16 = JType('int', 'short') \
293 .op(read='U16.f(bb.readShort())', write='bb.writeShort(U16.t($name))', pub_type=True) \
294 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
295u32 = JType('long', 'int') \
296 .op(read='U32.f(bb.readInt())', write='bb.writeInt(U32.t($name))', pub_type=True) \
297 .op(read='bb.readInt()', write='bb.writeInt($name)', pub_type=False)
298u32_list = JType('List<U32>', 'int[]') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700299 .op(
300 read='ChannelUtils.readList(bb, $length, U32.READER)',
301 write='ChannelUtils.writeList(bb, $name)',
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700302 default="ImmutableList.<U32>of()",
303 funnel="FunnelUtils.putList($name, sink)")
xinwuf08ef682013-12-05 18:29:20 -0800304u64_list = JType('List<U64>', 'int[]') \
305 .op(
306 read='ChannelUtils.readList(bb, $length, U64.READER)',
307 write='ChannelUtils.writeList(bb, $name)',
308 default="ImmutableList.<U64>of()",
309 funnel="FunnelUtils.putList($name, sink)")
Yotam Harchol5804f772013-08-21 17:35:31 -0700310u8obj = JType('U8', 'U8') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700311 .op(read='U8.of(bb.readByte())', write='bb.writeByte($name.getRaw())', default="U8.ZERO")
Rich Lane9b178072014-05-19 15:31:55 -0700312u16obj = JType('U16', 'U16') \
Rich Lane99f1b432014-05-22 11:15:15 -0700313 .op(read='U16.of(bb.readShort())', write='bb.writeShort($name.getRaw())', default="U16.ZERO")
Yotam Harchol5804f772013-08-21 17:35:31 -0700314u32obj = JType('U32', 'U32') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700315 .op(read='U32.of(bb.readInt())', write='bb.writeInt($name.getRaw())', default="U32.ZERO")
Sovietaced3d42dbe2014-01-23 15:55:48 -0800316u64 = JType('U64', 'long') \
317 .op(read='U64.ofRaw(bb.readLong())', write='bb.writeLong($name.getValue())', default="U64.ZERO", pub_type=True) \
318 .op(read='bb.readLong()', write='bb.writeLong($name)', pub_type=False)
Andreas Wundsam7c15b172014-04-24 19:02:40 -0700319u128 = JType("U128") \
320 .op(read='U128.read16Bytes(bb)',
321 write='$name.write16Bytes(bb)',
322 default='U128.ZERO')
Yotam Harchold7b84202013-07-26 16:08:10 -0700323of_port = JType("OFPort") \
Andreas Wundsamad499c92013-09-28 18:56:49 -0700324 .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ANY") \
325 .op(version=ANY, read="OFPort.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFPort.ANY")
Andreas Wundsame962d372013-10-02 18:15:58 -0700326# the same OFPort, but with a default value of ZERO, only for OF10 match
327of_port_match_v1 = JType("OFPort") \
328 .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ZERO")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700329actions_list = gen_list_jtype("OFAction")
330instructions_list = gen_list_jtype("OFInstruction")
331buckets_list = gen_list_jtype("OFBucket")
332port_desc_list = gen_list_jtype("OFPortDesc")
333packet_queue_list = gen_list_jtype("OFPacketQueue")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700334port_desc = JType('OFPortDesc') \
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700335 .op(read='OFPortDescVer$version.READER.readFrom(bb)', \
Yotam Harchold7b84202013-07-26 16:08:10 -0700336 write='$name.writeTo(bb)')
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700337octets = JType('byte[]')\
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700338 .op(read='ChannelUtils.readBytes(bb, $length)', \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700339 write='bb.writeBytes($name)', \
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700340 default="new byte[0]",
341 funnel="sink.putBytes($name)"
342 );
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700343of_match = JType('Match') \
Andreas Wundsam951ada32013-08-01 22:05:38 -0700344 .op(read='ChannelUtilsVer$version.readOFMatch(bb)', \
Andreas Wundsame962d372013-10-02 18:15:58 -0700345 write='$name.writeTo(bb)',
346 default="OFFactoryVer$version.MATCH_WILDCARD_ALL");
Andreas Wundsam5812cf32013-11-15 13:51:24 -0800347group_mod_cmd = JType('OFGroupModCommand', 'short') \
348 .op(version=ANY, read="bb.readShort()", write="bb.writeShort($name)")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700349flow_mod_cmd = JType('OFFlowModCommand', 'short') \
Yotam Harchold7b84202013-07-26 16:08:10 -0700350 .op(version=1, read="bb.readShort()", write="bb.writeShort($name)") \
351 .op(version=ANY, read="bb.readByte()", write="bb.writeByte($name)")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700352mac_addr = JType('MacAddress') \
Yotam Harchold7b84202013-07-26 16:08:10 -0700353 .op(read="MacAddress.read6Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700354 write="$name.write6Bytes(bb)",
355 default="MacAddress.NONE")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700356
357port_name = gen_fixed_length_string_jtype(16)
Praseed Balakrishnan7f718782014-09-18 17:02:48 -0700358app_code = gen_fixed_length_string_jtype(15)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700359desc_str = gen_fixed_length_string_jtype(256)
360serial_num = gen_fixed_length_string_jtype(32)
361table_name = gen_fixed_length_string_jtype(32)
Rich Lanef8a3d002014-03-19 13:33:52 -0700362str64 = gen_fixed_length_string_jtype(64)
Brian O'Connor58a73e32015-05-28 11:51:27 -0700363str32 = gen_fixed_length_string_jtype(32)
364str6 = gen_fixed_length_string_jtype(6)
Yotam Harchola289d552013-09-16 10:10:40 -0700365ipv4 = JType("IPv4Address") \
366 .op(read="IPv4Address.read4Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700367 write="$name.write4Bytes(bb)",
368 default='IPv4Address.NONE')
Byungjoon Leeba92e292014-07-18 13:13:26 +0900369ipv4_list = JType('List<IPv4Address>') \
370 .op(read='ChannelUtils.readList(bb, $length, IPv4Address.READER)',
371 write='ChannelUtils.writeList(bb, $name)',
372 default='ImmutableList.<IPv4Address>of()',
373 funnel="FunnelUtils.putList($name, sink)")
Yotam Harchola289d552013-09-16 10:10:40 -0700374ipv6 = JType("IPv6Address") \
375 .op(read="IPv6Address.read16Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700376 write="$name.write16Bytes(bb)",
377 default='IPv6Address.NONE')
Byungjoon Leeba92e292014-07-18 13:13:26 +0900378ipv6_list = JType('List<IPv46ddress>') \
379 .op(read='ChannelUtils.readList(bb, $length, IPv6Address.READER)',
380 write='ChannelUtils.writeList(bb, $name)',
381 default='ImmutableList.<IPv6Address>of()',
382 funnel="FunnelUtils.putList($name, sink)")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700383packetin_reason = gen_enum_jtype("OFPacketInReason")
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700384transport_port = JType("TransportPort")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700385 .op(read="TransportPort.read2Bytes(bb)",
386 write="$name.write2Bytes(bb)",
387 default="TransportPort.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700388eth_type = JType("EthType")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700389 .op(read="EthType.read2Bytes(bb)",
390 write="$name.write2Bytes(bb)",
391 default="EthType.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700392vlan_vid = JType("VlanVid")\
Andreas Wundsam98a18632013-11-05 11:34:24 -0800393 .op(version=ANY, read="VlanVid.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="VlanVid.ZERO")
394vlan_vid_match = JType("OFVlanVidMatch")\
395 .op(version=1, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
396 .op(version=2, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
397 .op(version=ANY, read="OFVlanVidMatch.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFVlanVidMatch.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700398vlan_pcp = JType("VlanPcp")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700399 .op(read="VlanPcp.readByte(bb)",
400 write="$name.writeByte(bb)",
401 default="VlanPcp.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700402ip_dscp = JType("IpDscp")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700403 .op(read="IpDscp.readByte(bb)",
404 write="$name.writeByte(bb)",
405 default="IpDscp.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700406ip_ecn = JType("IpEcn")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700407 .op(read="IpEcn.readByte(bb)",
408 write="$name.writeByte(bb)",
409 default="IpEcn.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700410ip_proto = JType("IpProtocol")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700411 .op(read="IpProtocol.readByte(bb)",
412 write="$name.writeByte(bb)",
413 default="IpProtocol.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700414icmpv4_type = JType("ICMPv4Type")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700415 .op(read="ICMPv4Type.readByte(bb)",
416 write="$name.writeByte(bb)",
417 default="ICMPv4Type.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700418icmpv4_code = JType("ICMPv4Code")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700419 .op(read="ICMPv4Code.readByte(bb)",
420 write="$name.writeByte(bb)",
421 default="ICMPv4Code.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700422arp_op = JType("ArpOpcode")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700423 .op(read="ArpOpcode.read2Bytes(bb)",
424 write="$name.write2Bytes(bb)",
425 default="ArpOpcode.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700426ipv6_flabel = JType("IPv6FlowLabel")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700427 .op(read="IPv6FlowLabel.read4Bytes(bb)",
428 write="$name.write4Bytes(bb)",
429 default="IPv6FlowLabel.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700430metadata = JType("OFMetadata")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700431 .op(read="OFMetadata.read8Bytes(bb)",
432 write="$name.write8Bytes(bb)",
433 default="OFMetadata.NONE")
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700434oxm = JType("OFOxm<?>")\
435 .op( read="OFOxmVer$version.READER.readFrom(bb)",
436 write="$name.writeTo(bb)")
437oxm_list = JType("OFOxmList") \
438 .op(
439 read= 'OFOxmList.readFrom(bb, $length, OFOxmVer$version.READER)', \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700440 write='$name.writeTo(bb)',
441 default="OFOxmList.EMPTY")
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700442meter_features = JType("OFMeterFeatures")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700443 .op(read="OFMeterFeaturesVer$version.READER.readFrom(bb)",
444 write="$name.writeTo(bb)")
Wilson Ngd6181882014-04-14 16:28:35 -0700445bsn_vport = JType("OFBsnVport")\
446 .op(read="OFBsnVportVer$version.READER.readFrom(bb)",
Andreas Wundsam113d25b2014-01-22 20:17:37 -0800447 write="$name.writeTo(bb)")
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700448flow_wildcards = JType("int") \
449 .op(read='bb.readInt()',
450 write='bb.writeInt($name)',
451 default="OFFlowWildcardsSerializerVer$version.ALL_VAL")
452table_stats_wildcards = JType("int") \
453 .op(read='bb.readInt()',
454 write='bb.writeInt($name)')
Sovietaced25021ec2014-12-31 15:44:21 -0500455port_bitmap_128 = JType('OFBitMask128') \
Yotam Harchol2c535582013-10-01 15:50:20 -0700456 .op(read='OFBitMask128.read16Bytes(bb)',
Yotam Harchola11f38b2013-09-26 15:38:17 -0700457 write='$name.write16Bytes(bb)',
Yotam Harchol2c535582013-10-01 15:50:20 -0700458 default='OFBitMask128.NONE')
Jimmy Jin646d1222016-05-13 10:47:24 -0700459port_bitmap_256 = JType('OFBitMask256') \
460 .op(read='OFBitMask256.read32Bytes(bb)',
461 write='$name.write32Bytes(bb)',
462 default='OFBitMask256.NONE')
Sovietaced25021ec2014-12-31 15:44:21 -0500463port_bitmap_512 = JType('OFBitMask512') \
464 .op(read='OFBitMask512.read64Bytes(bb)',
465 write='$name.write64Bytes(bb)',
466 default='OFBitMask512.NONE')
Andreas Wundsam37e0fb12013-09-28 18:57:57 -0700467table_id = JType("TableId") \
468 .op(read='TableId.readByte(bb)',
469 write='$name.writeByte(bb)',
470 default='TableId.ALL')
Andreas Wundsam45c95f82013-10-08 15:04:23 -0700471table_id_default_zero = JType("TableId") \
472 .op(read='TableId.readByte(bb)',
473 write='$name.writeByte(bb)',
474 default='TableId.ZERO')
Sovietaced0f9dddf2014-01-28 19:45:07 -0800475of_aux_id = JType("OFAuxId") \
476 .op(read='OFAuxId.readByte(bb)',
Sovietaced92603b02014-01-28 18:23:24 -0800477 write='$name.writeByte(bb)',
Sovietaced0f9dddf2014-01-28 19:45:07 -0800478 default='OFAuxId.MAIN')
Andreas Wundsama0981022013-10-02 18:15:06 -0700479of_version = JType("OFVersion", 'byte') \
480 .op(read='bb.readByte()', write='bb.writeByte($name)')
Rob Vaterlausb10ae552013-09-23 14:39:39 -0700481
Andreas Wundsam8ec3bcc2013-09-16 19:44:00 -0700482port_speed = JType("PortSpeed")
Rob Vaterlaus4d311942013-09-24 13:41:44 -0700483error_type = JType("OFErrorType")
Andreas Wundsam73d7d672014-11-12 17:07:33 -0800484of_message = JType("OFMessage")\
485 .op(read="OFMessageVer$version.READER.readFrom(bb)",
486 write="$name.writeTo(bb)")
487
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700488of_type = JType("OFType", 'byte') \
489 .op(read='bb.readByte()', write='bb.writeByte($name)')
490action_type= gen_enum_jtype("OFActionType")\
491 .set_priv_type("short")\
492 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
493instruction_type = gen_enum_jtype("OFInstructionType")\
494 .set_priv_type('short') \
495 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
496buffer_id = JType("OFBufferId") \
497 .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER")
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700498boolean = JType("boolean", "byte") \
499 .op(read='(bb.readByte() != 0)',
500 write='bb.writeByte($name ? 1 : 0)',
501 default="false")
502datapath_id = JType("DatapathId") \
503 .op(read='DatapathId.of(bb.readLong())',
504 write='bb.writeLong($name.getLong())',
505 default='DatapathId.NONE')
Andreas Wundsam5ea1aca2013-10-07 17:00:24 -0700506action_type_set = JType("Set<OFActionType>") \
507 .op(read='ChannelUtilsVer10.readSupportedActions(bb)',
508 write='ChannelUtilsVer10.writeSupportedActions(bb, $name)',
509 default='ImmutableSet.<OFActionType>of()',
510 funnel='ChannelUtilsVer10.putSupportedActionsTo($name, sink)')
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700511of_group = JType("OFGroup") \
512 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ALL")
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800513of_group_default_any = JType("OFGroup") \
514 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ANY")
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700515# the outgroup field of of_flow_stats_request has a special default value
516of_group_default_any = JType("OFGroup") \
517 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ANY")
518buffer_id = JType("OFBufferId") \
519 .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER")
Rich Lane376cafe2013-10-27 21:49:14 -0700520lag_id = JType("LagId") \
521 .op(version=ANY, read="LagId.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="LagId.NONE")
Yafit Hadarf8caac02015-08-25 10:21:44 +0300522odu_sig_id = JType("OduSignalID") \
523 .op(read="OduSignalID.readFrom(bb)", \
524 write="$name.writeTo(bb)",
525 default='OduSignalID.DEFAULT')
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700526sig_id = JType("CircuitSignalID") \
527 .op(version=ANY, read="CircuitSignalID.read6Bytes(bb)", write="$name.write6Bytes(bb)", default="CircuitSignalID.NONE")
Rich Laneeb21c4f2013-10-28 17:34:41 -0700528vrf = JType("VRF") \
529 .op(version=ANY, read="VRF.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="VRF.ZERO")
530class_id = JType("ClassId") \
531 .op(version=ANY, read="ClassId.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="ClassId.NONE")
Rich Lane9c27b5d2013-10-30 17:14:32 -0700532boolean_value = JType('OFBooleanValue', 'OFBooleanValue') \
533 .op(read='OFBooleanValue.of(bb.readByte() != 0)', write='bb.writeByte($name.getInt())', default="OFBooleanValue.FALSE")
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800534gen_table_id = JType("GenTableId") \
535 .op(read='GenTableId.read2Bytes(bb)',
536 write='$name.write2Bytes(bb)',
537 )
Andreas Wundsam73d7d672014-11-12 17:07:33 -0800538bundle_id = JType("BundleId") \
539 .op(read='BundleId.read4Bytes(bb)',
540 write='$name.write4Bytes(bb)',
541 )
Rich Lane53ddf5c2014-03-20 15:24:08 -0700542udf = JType("UDF") \
543 .op(version=ANY, read="UDF.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="UDF.ZERO")
Andreas Wundsam62cbcff2014-05-09 16:35:00 -0700544error_cause_data = JType("OFErrorCauseData") \
Andreas Wundsam39efd1c2014-05-13 19:41:51 -0700545 .op(version=ANY, read="OFErrorCauseData.read(bb, $length, OFVersion.OF_$version)", write="$name.writeTo(bb)", default="OFErrorCauseData.NONE");
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700546
Andreas Wundsame2fd7ce2014-06-26 20:56:42 -0700547var_string = JType('String').op(
548 read='ChannelUtils.readFixedLengthString(bb, $length)',
549 write='ChannelUtils.writeFixedLengthString(bb, $name, $name.length())',
550 default='""',
551 funnel='sink.putUnencodedChars($name)'
552 )
553
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700554generic_t = JType("T")
555
Marc De Leenheer88c0bcb2015-07-24 15:49:19 -0700556calient_port_desc_stats_entry = JType('OFCalientPortDescStatsEntry').op(read='OFCalientPortDescStatsEntryVer$version.READER.readFrom(bb)', write='$name.writeTo(bb)')
557
Rich Lane0b1698d2014-10-17 18:35:37 -0700558table_desc = JType('OFTableDesc') \
559 .op(read='OFTableDescVer$version.READER.readFrom(bb)', \
560 write='$name.writeTo(bb)')
561
Andreas Wundsam27303462013-07-16 12:52:35 -0700562
563default_mtype_to_jtype_convert_map = {
564 'uint8_t' : u8,
565 'uint16_t' : u16,
566 'uint32_t' : u32,
567 'uint64_t' : u64,
Andreas Wundsam27303462013-07-16 12:52:35 -0700568 'of_port_no_t' : of_port,
569 'list(of_action_t)' : actions_list,
570 'list(of_instruction_t)' : instructions_list,
571 'list(of_bucket_t)': buckets_list,
572 'list(of_port_desc_t)' : port_desc_list,
573 'list(of_packet_queue_t)' : packet_queue_list,
xinwuf08ef682013-12-05 18:29:20 -0800574 'list(of_uint64_t)' : u64_list,
Andreas Wundsam27303462013-07-16 12:52:35 -0700575 'list(of_uint32_t)' : u32_list,
576 'list(of_uint8_t)' : u8_list,
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700577 'list(of_oxm_t)' : oxm_list,
Byungjoon Leeba92e292014-07-18 13:13:26 +0900578 'list(of_ipv4_t)' : ipv4_list,
579 'list(of_ipv6_t)' : ipv6_list,
Andreas Wundsam27303462013-07-16 12:52:35 -0700580 'of_octets_t' : octets,
581 'of_match_t': of_match,
582 'of_fm_cmd_t': flow_mod_cmd,
583 'of_mac_addr_t': mac_addr,
584 'of_port_desc_t': port_desc,
585 'of_desc_str_t': desc_str,
586 'of_serial_num_t': serial_num,
587 'of_port_name_t': port_name,
588 'of_table_name_t': table_name,
Rich Lanef8a3d002014-03-19 13:33:52 -0700589 'of_str64_t': str64,
Brian O'Connor58a73e32015-05-28 11:51:27 -0700590 'of_str32_t': str32,
591 'of_str6_t': str6,
Marc De Leenheer88c0bcb2015-07-24 15:49:19 -0700592 'of_calient_port_desc_stats_entry_t': calient_port_desc_stats_entry,
Andreas Wundsam27303462013-07-16 12:52:35 -0700593 'of_ipv4_t': ipv4,
594 'of_ipv6_t': ipv6,
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700595 'of_wc_bmap_t': flow_wildcards,
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700596 'of_oxm_t': oxm,
597 'of_meter_features_t': meter_features,
Sovietaced25021ec2014-12-31 15:44:21 -0500598 'of_bitmap_128_t': port_bitmap_128,
Jimmy Jin646d1222016-05-13 10:47:24 -0700599 'of_bitmap_256_t': port_bitmap_256,
Sovietaced25021ec2014-12-31 15:44:21 -0500600 'of_bitmap_512_t': port_bitmap_512,
Andreas Wundsam7c15b172014-04-24 19:02:40 -0700601 'of_checksum_128_t': u128,
Wilson Ngd6181882014-04-14 16:28:35 -0700602 'of_bsn_vport_t': bsn_vport,
Praseed Balakrishnan7f718782014-09-18 17:02:48 -0700603 'of_app_code_t': app_code,
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700604 'of_sig_id_t': sig_id,
Rich Lane0b1698d2014-10-17 18:35:37 -0700605 'of_table_desc_t': table_desc,
Yafit Hadarf8caac02015-08-25 10:21:44 +0300606 'of_odu_sig_id_t': odu_sig_id,
607 'of_och_sig_id_t' : sig_id,
Andreas Wundsam27303462013-07-16 12:52:35 -0700608 }
609
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700610## Map that defines exceptions from the standard loxi->java mapping scheme
611# map of {<loxi_class_name> : { <loxi_member_name> : <JType instance> } }
Andreas Wundsam27303462013-07-16 12:52:35 -0700612exceptions = {
Yotam Harcholc742e202013-08-15 12:16:24 -0700613 'of_packet_in': { 'data' : octets, 'reason': packetin_reason },
614 'of_oxm_tcp_src' : { 'value' : transport_port },
615 'of_oxm_tcp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
616 'of_oxm_tcp_dst' : { 'value' : transport_port },
617 'of_oxm_tcp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
618 'of_oxm_udp_src' : { 'value' : transport_port },
619 'of_oxm_udp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
620 'of_oxm_udp_dst' : { 'value' : transport_port },
621 'of_oxm_udp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
622 'of_oxm_sctp_src' : { 'value' : transport_port },
623 'of_oxm_sctp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
624 'of_oxm_sctp_dst' : { 'value' : transport_port },
625 'of_oxm_sctp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
626 'of_oxm_eth_type' : { 'value' : eth_type },
627 'of_oxm_eth_type_masked' : { 'value' : eth_type, 'value_mask' : eth_type },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800628 'of_oxm_vlan_vid' : { 'value' : vlan_vid_match },
629 'of_oxm_vlan_vid_masked' : { 'value' : vlan_vid_match, 'value_mask' : vlan_vid_match },
Yotam Harcholc742e202013-08-15 12:16:24 -0700630 'of_oxm_vlan_pcp' : { 'value' : vlan_pcp },
631 'of_oxm_vlan_pcp_masked' : { 'value' : vlan_pcp, 'value_mask' : vlan_pcp },
632 'of_oxm_ip_dscp' : { 'value' : ip_dscp },
633 'of_oxm_ip_dscp_masked' : { 'value' : ip_dscp, 'value_mask' : ip_dscp },
634 'of_oxm_ip_ecn' : { 'value' : ip_ecn },
635 'of_oxm_ip_ecn_masked' : { 'value' : ip_ecn, 'value_mask' : ip_ecn },
636 'of_oxm_ip_proto' : { 'value' : ip_proto },
637 'of_oxm_ip_proto_masked' : { 'value' : ip_proto, 'value_mask' : ip_proto },
638 'of_oxm_icmpv4_type' : { 'value' : icmpv4_type },
639 'of_oxm_icmpv4_type_masked' : { 'value' : icmpv4_type, 'value_mask' : icmpv4_type },
640 'of_oxm_icmpv4_code' : { 'value' : icmpv4_code },
641 'of_oxm_icmpv4_code_masked' : { 'value' : icmpv4_code, 'value_mask' : icmpv4_code },
642 'of_oxm_arp_op' : { 'value' : arp_op },
643 'of_oxm_arp_op_masked' : { 'value' : arp_op, 'value_mask' : arp_op },
644 'of_oxm_arp_spa' : { 'value' : ipv4 },
645 'of_oxm_arp_spa_masked' : { 'value' : ipv4, 'value_mask' : ipv4 },
646 'of_oxm_arp_tpa' : { 'value' : ipv4 },
647 'of_oxm_arp_tpa_masked' : { 'value' : ipv4, 'value_mask' : ipv4 },
648 'of_oxm_ipv6_flabel' : { 'value' : ipv6_flabel },
649 'of_oxm_ipv6_flabel_masked' : { 'value' : ipv6_flabel, 'value_mask' : ipv6_flabel },
650 'of_oxm_metadata' : { 'value' : metadata },
651 'of_oxm_metadata_masked' : { 'value' : metadata, 'value_mask' : metadata },
Yotam Harchol5804f772013-08-21 17:35:31 -0700652
653 'of_oxm_icmpv6_code' : { 'value' : u8obj },
654 'of_oxm_icmpv6_code_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
655 'of_oxm_icmpv6_type' : { 'value' : u8obj },
656 'of_oxm_icmpv6_type_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
657 'of_oxm_mpls_label' : { 'value' : u32obj },
658 'of_oxm_mpls_label_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
659 'of_oxm_mpls_tc' : { 'value' : u8obj },
660 'of_oxm_mpls_tc_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
Saurav Dasbc266742014-10-09 16:45:27 -0700661 'of_oxm_mpls_bos' : { 'value' : boolean_value },
662 'of_oxm_mpls_bos_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
Rich Lane9f595042014-10-31 15:56:34 -0700663 'of_oxm_ipv6_exthdr' : { 'value' : u16obj },
664 'of_oxm_ipv6_exthdr_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
665 'of_oxm_pbb_uca' : { 'value' : boolean_value },
666 'of_oxm_pbb_uca_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700667
Sovietaced25021ec2014-12-31 15:44:21 -0500668 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap_128 },
669 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap_128, 'value_mask': port_bitmap_128 },
Jimmy Jin646d1222016-05-13 10:47:24 -0700670
671 'of_oxm_bsn_in_ports_256' : { 'value': port_bitmap_256 },
672 'of_oxm_bsn_in_ports_256_masked' : { 'value': port_bitmap_256, 'value_mask': port_bitmap_256 },
Sovietaced25021ec2014-12-31 15:44:21 -0500673
674 'of_oxm_bsn_in_ports_512' : { 'value': port_bitmap_512 },
675 'of_oxm_bsn_in_ports_512_masked' : { 'value': port_bitmap_512, 'value_mask': port_bitmap_512 },
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700676
Rich Lane376cafe2013-10-27 21:49:14 -0700677 'of_oxm_bsn_lag_id' : { 'value' : lag_id },
678 'of_oxm_bsn_lag_id_masked' : { 'value' : lag_id, 'value_mask' : lag_id },
Rich Lane1424d0b2013-10-24 17:16:24 -0700679
Rich Laneeb21c4f2013-10-28 17:34:41 -0700680 'of_oxm_bsn_vrf' : { 'value' : vrf },
681 'of_oxm_bsn_vrf_masked' : { 'value' : vrf, 'value_mask' : vrf },
682
Rich Lane9c27b5d2013-10-30 17:14:32 -0700683 'of_oxm_bsn_global_vrf_allowed' : { 'value' : boolean_value },
684 'of_oxm_bsn_global_vrf_allowed_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
Rich Laneeb21c4f2013-10-28 17:34:41 -0700685
686 'of_oxm_bsn_l3_interface_class_id' : { 'value' : class_id },
687 'of_oxm_bsn_l3_interface_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
688
689 'of_oxm_bsn_l3_src_class_id' : { 'value' : class_id },
690 'of_oxm_bsn_l3_src_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
691
692 'of_oxm_bsn_l3_dst_class_id' : { 'value' : class_id },
693 'of_oxm_bsn_l3_dst_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
694
Rich Lane917bb9a2014-03-11 17:49:56 -0700695 'of_oxm_bsn_egr_port_group_id' : { 'value' : class_id },
696 'of_oxm_bsn_egr_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
697
Rich Lane75d235a2015-02-03 17:40:10 -0800698 'of_oxm_bsn_ingress_port_group_id' : { 'value' : class_id },
699 'of_oxm_bsn_ingress_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
700
Rich Lane53ddf5c2014-03-20 15:24:08 -0700701 'of_oxm_bsn_udf0' : { 'value' : udf },
702 'of_oxm_bsn_udf0_masked' : { 'value' : udf, 'value_mask' : udf },
703
704 'of_oxm_bsn_udf1' : { 'value' : udf },
705 'of_oxm_bsn_udf1_masked' : { 'value' : udf, 'value_mask' : udf },
706
707 'of_oxm_bsn_udf2' : { 'value' : udf },
708 'of_oxm_bsn_udf2_masked' : { 'value' : udf, 'value_mask' : udf },
709
710 'of_oxm_bsn_udf3' : { 'value' : udf },
711 'of_oxm_bsn_udf3_masked' : { 'value' : udf, 'value_mask' : udf },
712
713 'of_oxm_bsn_udf4' : { 'value' : udf },
714 'of_oxm_bsn_udf4_masked' : { 'value' : udf, 'value_mask' : udf },
715
716 'of_oxm_bsn_udf5' : { 'value' : udf },
717 'of_oxm_bsn_udf5_masked' : { 'value' : udf, 'value_mask' : udf },
718
719 'of_oxm_bsn_udf6' : { 'value' : udf },
720 'of_oxm_bsn_udf6_masked' : { 'value' : udf, 'value_mask' : udf },
721
722 'of_oxm_bsn_udf7' : { 'value' : udf },
723 'of_oxm_bsn_udf7_masked' : { 'value' : udf, 'value_mask' : udf },
724
Rich Lane9b178072014-05-19 15:31:55 -0700725 'of_oxm_bsn_tcp_flags' : { 'value' : u16obj },
726 'of_oxm_bsn_tcp_flags_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
727
Rich Lanea5eeae32014-06-26 19:59:04 -0700728 'of_oxm_bsn_vlan_xlate_port_group_id' : { 'value' : class_id },
729 'of_oxm_bsn_vlan_xlate_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
730
Wilson Ng15efef92014-11-05 14:27:35 -0800731 'of_oxm_bsn_l2_cache_hit' : { 'value' : boolean_value },
732 'of_oxm_bsn_l2_cache_hit_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
Wilson Nga3483d62014-11-05 13:50:37 -0800733
Ken Chiang8df4a112015-05-12 10:15:44 -0700734 'of_oxm_bsn_vxlan_network_id' : { 'value' : u32obj },
735 'of_oxm_bsn_vxlan_network_id_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
736
737 'of_oxm_bsn_inner_eth_dst' : { 'value' : mac_addr },
738 'of_oxm_bsn_inner_eth_dst_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
739
740 'of_oxm_bsn_inner_eth_src' : { 'value' : mac_addr },
741 'of_oxm_bsn_inner_eth_src_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
742
Wilson Ng95afd512015-07-13 14:31:00 -0700743 'of_oxm_bsn_inner_vlan_vid' : { 'value' : vlan_vid_match },
744 'of_oxm_bsn_inner_vlan_vid_masked' : { 'value' : vlan_vid_match, 'value_mask' : vlan_vid_match },
745
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700746 'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800747 'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700748 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
Andreas Wundsame962d372013-10-02 18:15:58 -0700749 'tcp_src': transport_port, 'tcp_dst': transport_port,
750 'in_port': of_port_match_v1
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700751 },
752 'of_bsn_set_l2_table_request': { 'l2_table_enable': boolean },
753 'of_bsn_set_l2_table_reply': { 'l2_table_enable': boolean },
Rob Vaterlause1b86842013-10-18 13:29:19 -0700754 'of_bsn_set_pktin_suppression_request': { 'enabled': boolean },
Sovietaced768c3e22014-04-04 16:46:48 -0700755 'of_bsn_controller_connection': { 'auxiliary_id' : of_aux_id},
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700756 'of_flow_stats_request': { 'out_group': of_group_default_any },
Andreas Wundsam384ccc12014-03-12 14:52:42 -0700757 'of_aggregate_stats_request': { 'out_group': of_group_default_any },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800758
759 'of_action_bsn_mirror': { 'dest_port': of_port },
760 'of_action_push_mpls': { 'ethertype': eth_type },
761 'of_action_push_pbb': { 'ethertype': eth_type },
762 'of_action_push_vlan': { 'ethertype': eth_type },
Ronald Li4fb8abb2013-11-21 19:53:02 -0800763 'of_action_pop_mpls': { 'ethertype': eth_type },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800764 'of_action_set_nw_dst': { 'nw_addr': ipv4 },
765 'of_action_set_nw_ecn': { 'nw_ecn': ip_ecn },
766 'of_action_set_nw_src': { 'nw_addr': ipv4 },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800767 'of_action_set_tp_dst': { 'tp_port': transport_port },
768 'of_action_set_tp_src': { 'tp_port': transport_port },
769 'of_action_set_vlan_pcp': { 'vlan_pcp': vlan_pcp },
770 'of_action_set_vlan_vid': { 'vlan_vid': vlan_vid },
Andreas Wundsam5812cf32013-11-15 13:51:24 -0800771
772 'of_group_mod' : { 'command' : group_mod_cmd },
773 'of_group_add' : { 'command' : group_mod_cmd },
774 'of_group_modify' : { 'command' : group_mod_cmd },
775 'of_group_delete' : { 'command' : group_mod_cmd },
776
777 'of_bucket' : { 'watch_group': of_group },
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800778
779 'of_bsn_tlv_vlan_vid' : { 'value' : vlan_vid },
Andreas Wundsamec1f6612014-06-25 15:48:12 -0700780 'of_bsn_table_set_buckets_size' : { 'table_id' : table_id },
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800781 'of_bsn_gentable_entry_add' : { 'table_id' : gen_table_id },
Andreas Wundsame2fd7ce2014-06-26 20:56:42 -0700782 'of_bsn_log': { 'data': var_string },
Sovietaced92603b02014-01-28 18:23:24 -0800783
Sovietaced0f9dddf2014-01-28 19:45:07 -0800784 'of_features_reply' : { 'auxiliary_id' : of_aux_id},
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700785 'of_oxm_och_sigtype' : { 'value' : u8obj },
786 'of_oxm_och_sigtype_basic' : { 'value' : u8obj },
alshabib78e24b92015-01-28 14:28:18 -0800787 'of_oxm_och_sigid' : {'value' : sig_id},
BitOhenry83b53232015-11-18 17:26:55 +0800788 'of_oxm_och_sigid_basic' : {'value' : sig_id},
Andreas Wundsam73d7d672014-11-12 17:07:33 -0800789
Jimmy Jin4fd39022016-01-15 12:39:01 -0800790 'of_oxm_och_sigatt' : { 'value' : u32obj },
791 'of_oxm_och_sigatt_basic' : { 'value' : u32obj },
792
Andreas Wundsam73d7d672014-11-12 17:07:33 -0800793 'of_bundle_add_msg' : { 'data' : of_message },
Yafit Hadarf8caac02015-08-25 10:21:44 +0300794
795 'of_oxm_exp_odu_sigtype' : { 'value' : u8obj },
BitOhenry83b53232015-11-18 17:26:55 +0800796 'of_oxm_exp_och_sigtype' : { 'value' : u8obj },
797
798 'of_oxm_reg0' : { 'value' : u32obj },
799 'of_oxm_reg0_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
800
801 'of_oxm_reg1' : { 'value' : u32obj },
802 'of_oxm_reg1_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
803
804 'of_oxm_reg2' : { 'value' : u32obj },
805 'of_oxm_reg2_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
806
807 'of_oxm_reg3' : { 'value' : u32obj },
808 'of_oxm_reg3_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
809
810 'of_oxm_reg4' : { 'value' : u32obj },
811 'of_oxm_reg4_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
812
813 'of_oxm_reg5' : { 'value' : u32obj },
814 'of_oxm_reg5_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
815
816 'of_oxm_reg6' : { 'value' : u32obj },
817 'of_oxm_reg6_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
818
819 'of_oxm_reg7' : { 'value' : u32obj },
820 'of_oxm_reg7_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530821
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530822 'of_oxm_nsp' : { 'value' : u32obj },
823 'of_oxm_nsp_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530824
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530825 'of_oxm_nsi' : { 'value' : u8obj },
826 'of_oxm_nsi_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530827
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530828 'of_oxm_nsh_c1' : { 'value' : u32obj },
829 'of_oxm_nsh_c1_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530830
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530831 'of_oxm_nsh_c2' : { 'value' : u32obj },
832 'of_oxm_nsh_c2_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530833
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530834 'of_oxm_nsh_c3' : { 'value' : u32obj },
835 'of_oxm_nsh_c3_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
Phanendra Manda4c728b32015-12-09 23:04:16 +0530836
Phaneendra Mandaadcb3e72016-05-12 21:53:48 +0530837 'of_oxm_nsh_c4' : { 'value' : u32obj },
838 'of_oxm_nsh_c4_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
839
840 'of_oxm_nsh_mdtype' : { 'value' : u8obj },
841 'of_oxm_nsh_mdtype_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
842
843 'of_oxm_nsh_np' : { 'value' : u8obj },
844 'of_oxm_nsh_np_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
845
846 'of_oxm_encap_eth_src' : { 'value' : mac_addr },
847 'of_oxm_encap_eth_src_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
848
849 'of_oxm_encap_eth_dst' : { 'value' : mac_addr },
850 'of_oxm_encap_eth_dst_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
851
852 'of_oxm_encap_eth_type' : { 'value' : u16obj },
853 'of_oxm_encap_eth_type_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
854
855 'of_oxm_tun_flags' : { 'value' : u16obj },
856 'of_oxm_tun_flags_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
857
858 'of_oxm_tun_gbp_id' : { 'value' : u16obj },
859 'of_oxm_tun_gbp_id_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
860
861 'of_oxm_tun_gbp_flags' : { 'value' : u8obj },
862 'of_oxm_tun_gbp_flags_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
863
864 'of_oxm_tun_gpe_np' : { 'value' : u8obj },
865 'of_oxm_tun_gpe_np_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
866
867 'of_oxm_tun_gpe_flags' : { 'value' : u8obj },
868 'of_oxm_tun_gpe_flags_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
Charles Chan339bfde2016-09-19 19:13:36 -0700869
870 'of_oxm_ofdpa_mpls_type': { 'value': u16obj },
Andreas Wundsam27303462013-07-16 12:52:35 -0700871}
872
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700873
874@memoize
875def enum_java_types():
876 enum_types = {}
Andreas Wundsamc8912c12013-11-15 13:44:48 -0800877 for enum in loxi_globals.unified.enums:
878 java_name = name_c_to_caps_camel(re.sub(r'_t$', "", enum.name))
879 enum_types[enum.name] = gen_enum_jtype(java_name, enum.is_bitmask)
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700880 return enum_types
881
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700882def make_match_field_jtype(sub_type_name="?"):
883 return JType("MatchField<{}>".format(sub_type_name))
884
Andreas Wundsam661a2222013-11-05 17:18:59 -0800885def make_oxm_jtype(sub_type_name="?"):
886 return JType("OFOxm<{}>".format(sub_type_name))
Andreas Wundsam27303462013-07-16 12:52:35 -0700887
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700888def list_cname_to_java_name(c_type):
Andreas Wundsam27303462013-07-16 12:52:35 -0700889 m = re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type)
890 if not m:
891 raise Exception("Not a recgonized standard list type declaration: %s" % c_type)
892 base_name = m.group(1)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700893 return "OF" + name_c_to_caps_camel(base_name)
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700894
895#### main entry point for conversion of LOXI types (c_types) Java types.
896# FIXME: This badly needs a refactoring
897
Andreas Wundsam27303462013-07-16 12:52:35 -0700898def convert_to_jtype(obj_name, field_name, c_type):
899 """ Convert from a C type ("uint_32") to a java type ("U32")
900 and return a JType object with the size, internal type, and marshalling functions"""
901 if obj_name in exceptions and field_name in exceptions[obj_name]:
902 return exceptions[obj_name][field_name]
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700903 elif ( obj_name == "of_header" or loxi_utils.class_is_message(obj_name)) and field_name == "type" and c_type == "uint8_t":
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700904 return of_type
Andreas Wundsam27303462013-07-16 12:52:35 -0700905 elif field_name == "type" and re.match(r'of_action.*', obj_name):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700906 return action_type
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700907 elif field_name == "err_type":
908 return JType("OFErrorType", 'short') \
909 .op(read='bb.readShort()', write='bb.writeShort($name)')
Andreas Wundsam62cbcff2014-05-09 16:35:00 -0700910 elif loxi_utils.class_is(obj_name, "of_error_msg") and field_name == "data":
911 return error_cause_data
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700912 elif field_name == "stats_type":
913 return JType("OFStatsType", 'short') \
914 .op(read='bb.readShort()', write='bb.writeShort($name)')
Andreas Wundsam999c0732013-10-01 19:29:16 -0700915 elif field_name == "type" and re.match(r'of_instruction.*', obj_name):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700916 return instruction_type
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800917 elif loxi_utils.class_is(obj_name, "of_flow_mod") and field_name == "table_id" and c_type == "uint8_t":
Andreas Wundsam45c95f82013-10-08 15:04:23 -0700918 return table_id_default_zero
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800919 elif loxi_utils.class_is(obj_name, "of_flow_mod") and field_name == "out_group" and c_type == "uint32_t":
920 return of_group_default_any
Andreas Wundsam37e0fb12013-09-28 18:57:57 -0700921 elif field_name == "table_id" and c_type == "uint8_t":
922 return table_id
Andreas Wundsam27303462013-07-16 12:52:35 -0700923 elif field_name == "version" and c_type == "uint8_t":
Andreas Wundsama0981022013-10-02 18:15:06 -0700924 return of_version
Rob Vaterlausb10ae552013-09-23 14:39:39 -0700925 elif field_name == "buffer_id" and c_type == "uint32_t":
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700926 return buffer_id
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700927 elif field_name == "group_id" and c_type == "uint32_t":
928 return of_group
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700929 elif field_name == 'datapath_id':
930 return datapath_id
931 elif field_name == 'actions' and obj_name == 'of_features_reply':
Andreas Wundsam5ea1aca2013-10-07 17:00:24 -0700932 return action_type_set
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800933 elif field_name == "table_id" and re.match(r'of_bsn_gentable.*', obj_name):
934 return gen_table_id
Andreas Wundsam73d7d672014-11-12 17:07:33 -0800935 elif field_name == "bundle_id" and re.match(r'of_bundle_.*', obj_name):
936 return bundle_id
Andreas Wundsam27303462013-07-16 12:52:35 -0700937 elif c_type in default_mtype_to_jtype_convert_map:
938 return default_mtype_to_jtype_convert_map[c_type]
939 elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700940 return gen_list_jtype(list_cname_to_java_name(c_type))
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700941 elif c_type in enum_java_types():
942 return enum_java_types()[c_type]
Andreas Wundsam27303462013-07-16 12:52:35 -0700943 else:
944 print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name)
945 jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type))
946 return JType(jtype)
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700947
948
949#### Enum specific wiretype definitions
950enum_wire_types = {
951 "uint8_t": JType("byte").op(read="bb.readByte()", write="bb.writeByte($name)"),
952 "uint16_t": JType("short").op(read="bb.readShort()", write="bb.writeShort($name)"),
953 "uint32_t": JType("int").op(read="bb.readInt()", write="bb.writeInt($name)"),
954 "uint64_t": JType("long").op(read="bb.readLong()", write="bb.writeLong($name)"),
955}
956
957def convert_enum_wire_type_to_jtype(wire_type):
958 return enum_wire_types[wire_type]