blob: 5ff987d48670b7510455db62dfdd87ec5838bca1 [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 Wundsam46d230f2013-08-02 22:24:06 -070056 max = (1 << bits)-1
57 if value > max:
58 raise Exception("Value %d to large for type %s" % (value, t))
59
60 if signed:
61 max_pos = (1 << (bits-1)) - 1
62
63 if value > max_pos:
64 if t == "long":
65 return str((1 << bits) - value)
66 else:
67 return "(%s) 0x%x" % (t, value)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070068 return "%s0x%x%s" % ("(%s) " % t if cast_needed else "", value, "L" if t=="long" else "")
69
Yotam Harchold7b84202013-07-26 16:08:10 -070070
Andreas Wundsame916d6f2013-07-30 11:33:58 -070071ANY = 0xFFFFFFFFFFFFFFFF
Yotam Harchold7b84202013-07-26 16:08:10 -070072
73class VersionOp:
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070074 def __init__(self, version=ANY, read=None, write=None, default=None, funnel=None):
Yotam Harchold7b84202013-07-26 16:08:10 -070075 self.version = version
76 self.read = read
77 self.write = write
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -070078 self.default = default
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070079 self.funnel = funnel
Andreas Wundsame916d6f2013-07-30 11:33:58 -070080
Yotam Harchold7b84202013-07-26 16:08:10 -070081 def __str__(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070082 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 -070083
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070084### FIXME: This class should really be cleaned up
Andreas Wundsam27303462013-07-16 12:52:35 -070085class JType(object):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -070086 """ Wrapper class to hold C to Java type conversion information. JTypes can have a 'public'
87 and or 'private' java type associated with them and can define how those types can be
88 read from and written to ChannelBuffers.
89
90 """
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -070091 def __init__(self, pub_type, priv_type=None):
Andreas Wundsam27303462013-07-16 12:52:35 -070092 self.pub_type = pub_type # the type we expose externally, e.g. 'U8'
93 if priv_type is None:
94 priv_type = pub_type
95 self.priv_type = priv_type # the internal storage type
Yotam Harchold7b84202013-07-26 16:08:10 -070096 self.ops = {}
Yotam Harchold7b84202013-07-26 16:08:10 -070097
Andreas Wundsam22ba3af2013-10-04 16:00:30 -070098 def set_priv_type(self, priv_type):
99 self.priv_type = priv_type
100 return self
101
102 def op(self, version=ANY, read=None, write=None, default=None, funnel=None, pub_type=ANY):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700103 """
104 define operations to be performed for reading and writing this type
105 (when read_op, write_op is called). The operations 'read' and 'write'
106 can either be strings ($name, and $version and $length will be replaced),
107 or callables (name, version and length) will be passed.
108
109 @param version int OF version to define operation for, or ANY for all
110 @param pub_type boolean whether to define operations for the public type (True), the
111 private type(False) or both (ALL)
112 @param read read expression (either string or callable)s
113 @param write write expression (either string or callable)
114 """
115
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700116 pub_types = [ pub_type ] if pub_type is not ANY else [ False, True ]
117 for pub_type in pub_types:
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700118 self.ops[(version, pub_type)] = VersionOp(version, read, write, default, funnel)
Yotam Harchold7b84202013-07-26 16:08:10 -0700119 return self
Andreas Wundsam27303462013-07-16 12:52:35 -0700120
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700121 def format_value(self, value, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700122 # Format a constant value of this type, for inclusion in the java source code
123 # For primitive types, takes care of casting the value appropriately, to
124 # cope with java's signedness limitation
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700125 t = self.pub_type if pub_type else self.priv_type
126 if t in java_primitive_types:
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700127 return format_primitive_literal(t, value)
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700128 else:
129 return value
Andreas Wundsambf1dbbd2013-07-30 11:07:59 -0700130
Andreas Wundsam27303462013-07-16 12:52:35 -0700131 @property
132 def public_type(self):
133 """ return the public type """
134 return self.pub_type
135
136 def priv(self):
137 """ return the public type """
138 return self.priv_type
139
140 def has_priv(self):
141 """ Is the private type different from the public one?"""
142 return self.pub_type != self.priv_type
143
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700144 def get_op(self, op_type, version, pub_type, default_value, arguments):
145 ver = ANY if version is None else version.int_version
146
147 if not "version" in arguments:
Andreas Wundsamc8912c12013-11-15 13:44:48 -0800148 arguments["version"] = version.dotless_version
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700149
150 def lookup(ver, pub_type):
151 if (ver, pub_type) in self.ops:
152 return getattr(self.ops[(ver, pub_type)], op_type)
153 else:
154 return None
155
156 _op = lookup(ver, pub_type) or lookup(ANY, pub_type) or default_value
157 if callable(_op):
158 return _op(**arguments)
159 else:
160 return reduce(lambda a,repl: a.replace("$%s" % repl[0], str(repl[1])), arguments.items(), _op)
161
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700162 def read_op(self, version=None, length=None, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700163 """ return a Java stanza that reads a value of this JType from ChannelBuffer bb.
164 @param version int - OF wire version to generate expression for
165 @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
166 @param length string, for operations that need it (e.g., read a list of unknown length)
167 Java expression evaluating to the byte length to be read. Defaults to the remainig
168 length of the message.
169 @return string containing generated Java expression.
170 """
Andreas Wundsam27303462013-07-16 12:52:35 -0700171 if length is None:
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700172 # assumes that
173 # (1) length of the message has been read to 'length'
174 # (2) readerIndex at the start of the message has been stored in 'start'
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700175 length = "length - (bb.readerIndex() - start)"
Andreas Wundsam27303462013-07-16 12:52:35 -0700176
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700177 return self.get_op("read", version, pub_type,
178 default_value='ChannelUtilsVer$version.read%s(bb)' % self.pub_type,
179 arguments=dict(length=length)
180 )
Andreas Wundsam27303462013-07-16 12:52:35 -0700181
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700182 def write_op(self, version=None, name=None, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700183 """ return a Java stanza that writes a value of this JType contained in Java expression
184 'name' to ChannelBuffer bb.
185 @param name string containing Java expression that evaluations to the value to be written
186 @param version int - OF wire version to generate expression for
187 @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
188 @return string containing generated Java expression.
189 """
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700190
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700191 return self.get_op("write", version, pub_type,
192 default_value='ChannelUtilsVer$version.write%s(bb, $name)' % self.pub_type,
193 arguments=dict(name=name)
194 )
195
Andreas Wundsam27303462013-07-16 12:52:35 -0700196
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700197 def default_op(self, version=None, pub_type=True):
198 """ return a Java stanza that returns a default value of this JType.
199 @param version JavaOFVersion
200 @return string containing generated Java expression.
201 """
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700202 return self.get_op("default", version, pub_type,
203 arguments = dict(),
204 default_value = self.format_value(0) if self.is_primitive else "null"
205 )
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700206
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700207 def skip_op(self, version=None, length=None):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700208 """ return a java stanza that skips an instance of JType in the input ChannelBuffer 'bb'.
209 This is used in the Reader implementations for virtual classes (because after the
210 discriminator field, the concrete Reader instance will re-read all the fields)
211 Currently just delegates to read_op + throws away the result."""
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700212 return self.read_op(version, length)
213
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700214 def funnel_op(self, version=None, name=None, pub_type=True):
215 t = self.pub_type if pub_type else self.priv_type
216 return self.get_op("funnel", version, pub_type,
217 arguments = dict(name=name),
218 default_value = '$name.putTo(sink)' if not self._is_primitive(pub_type) else "sink.put{}($name)".format(t[0].upper() + t[1:])
219 )
220
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700221 @property
222 def is_primitive(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700223 return self._is_primitive()
224
225 def _is_primitive(self, pub_type=True):
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700226 """ return true if the pub_type is a java primitive type (and thus needs
227 special treatment, because it doesn't have methods)"""
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700228 t = self.pub_type if pub_type else self.priv_type
229 return t in java_primitive_types
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700230
231 @property
232 def is_array(self):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700233 return self._is_array()
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700234
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700235 def _is_array(self, pub_type=True):
236 t = self.pub_type if pub_type else self.priv_type
237 return t.endswith("[]")
238
239# Create a default mapping for a list type. Type defauls to List<${java_mapping_of_name}>
240def gen_enum_jtype(java_name, is_bitmask=False):
241 if is_bitmask:
242 java_type = "Set<{}>".format(java_name)
243 default_value = "ImmutableSet.<{}>of()".format(java_name)
244 else:
245 java_type = java_name
246 default_value = "null"
247
248 serializer = "{}SerializerVer$version".format(java_name)
249
250 return JType(java_type)\
251 .op(read="{}.readFrom(bb)".format(serializer),
252 write="{}.writeTo(bb, $name)".format(serializer),
253 default=default_value,
254 funnel="{}.putTo($name, sink)".format(serializer)
255 )
256
257def gen_list_jtype(java_base_name):
258 # read op assumes the class has a public final static field READER that implements
259 # OFMessageReader<$class> i.e., can deserialize an instance of class from a ChannelBuffer
260 # write op assumes class implements Writeable
261 return JType("List<{}>".format(java_base_name)) \
262 .op(
263 read= 'ChannelUtils.readList(bb, $length, {}Ver$version.READER)'.format(java_base_name), \
264 write='ChannelUtils.writeList(bb, $name)',
265 default="ImmutableList.<{}>of()".format(java_base_name),
266 funnel='FunnelUtils.putList($name, sink)'
267 )
268
269def gen_fixed_length_string_jtype(length):
270 return JType('String').op(
271 read='ChannelUtils.readFixedLengthString(bb, {})'.format(length),
272 write='ChannelUtils.writeFixedLengthString(bb, $name, {})'.format(length),
273 default='""',
274 funnel='sink.putUnencodedChars($name)'
275 )
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700276
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700277##### Predefined JType mappings
278# FIXME: This list needs to be pruned / cleaned up. Most of these are schematic.
279
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700280u8 = JType('short', 'byte') \
Andreas Wundsam83d877a2013-09-30 14:26:44 -0700281 .op(read='U8.f(bb.readByte())', write='bb.writeByte(U8.t($name))', pub_type=True) \
282 .op(read='bb.readByte()', write='bb.writeByte($name)', pub_type=False)
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700283u8_list = JType('List<U8>') \
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700284 .op(read='ChannelUtils.readList(bb, $length, U8.READER)',
285 write='ChannelUtils.writeList(bb, $name)',
286 default='ImmutableList.<U8>of()',
287 funnel='FunnelUtils.putList($name, sink)'
288 )
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700289u16 = JType('int', 'short') \
290 .op(read='U16.f(bb.readShort())', write='bb.writeShort(U16.t($name))', pub_type=True) \
291 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
292u32 = JType('long', 'int') \
293 .op(read='U32.f(bb.readInt())', write='bb.writeInt(U32.t($name))', pub_type=True) \
294 .op(read='bb.readInt()', write='bb.writeInt($name)', pub_type=False)
295u32_list = JType('List<U32>', 'int[]') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700296 .op(
297 read='ChannelUtils.readList(bb, $length, U32.READER)',
298 write='ChannelUtils.writeList(bb, $name)',
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700299 default="ImmutableList.<U32>of()",
300 funnel="FunnelUtils.putList($name, sink)")
xinwuf08ef682013-12-05 18:29:20 -0800301u64_list = JType('List<U64>', 'int[]') \
302 .op(
303 read='ChannelUtils.readList(bb, $length, U64.READER)',
304 write='ChannelUtils.writeList(bb, $name)',
305 default="ImmutableList.<U64>of()",
306 funnel="FunnelUtils.putList($name, sink)")
Yotam Harchol5804f772013-08-21 17:35:31 -0700307u8obj = JType('U8', 'U8') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700308 .op(read='U8.of(bb.readByte())', write='bb.writeByte($name.getRaw())', default="U8.ZERO")
Rich Lane9b178072014-05-19 15:31:55 -0700309u16obj = JType('U16', 'U16') \
Rich Lane99f1b432014-05-22 11:15:15 -0700310 .op(read='U16.of(bb.readShort())', write='bb.writeShort($name.getRaw())', default="U16.ZERO")
Yotam Harchol5804f772013-08-21 17:35:31 -0700311u32obj = JType('U32', 'U32') \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700312 .op(read='U32.of(bb.readInt())', write='bb.writeInt($name.getRaw())', default="U32.ZERO")
Sovietaced3d42dbe2014-01-23 15:55:48 -0800313u64 = JType('U64', 'long') \
314 .op(read='U64.ofRaw(bb.readLong())', write='bb.writeLong($name.getValue())', default="U64.ZERO", pub_type=True) \
315 .op(read='bb.readLong()', write='bb.writeLong($name)', pub_type=False)
Andreas Wundsam7c15b172014-04-24 19:02:40 -0700316u128 = JType("U128") \
317 .op(read='U128.read16Bytes(bb)',
318 write='$name.write16Bytes(bb)',
319 default='U128.ZERO')
Yotam Harchold7b84202013-07-26 16:08:10 -0700320of_port = JType("OFPort") \
Andreas Wundsamad499c92013-09-28 18:56:49 -0700321 .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ANY") \
322 .op(version=ANY, read="OFPort.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFPort.ANY")
Andreas Wundsame962d372013-10-02 18:15:58 -0700323# the same OFPort, but with a default value of ZERO, only for OF10 match
324of_port_match_v1 = JType("OFPort") \
325 .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ZERO")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700326actions_list = gen_list_jtype("OFAction")
327instructions_list = gen_list_jtype("OFInstruction")
328buckets_list = gen_list_jtype("OFBucket")
329port_desc_list = gen_list_jtype("OFPortDesc")
330packet_queue_list = gen_list_jtype("OFPacketQueue")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700331port_desc = JType('OFPortDesc') \
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700332 .op(read='OFPortDescVer$version.READER.readFrom(bb)', \
Yotam Harchold7b84202013-07-26 16:08:10 -0700333 write='$name.writeTo(bb)')
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700334octets = JType('byte[]')\
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700335 .op(read='ChannelUtils.readBytes(bb, $length)', \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700336 write='bb.writeBytes($name)', \
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700337 default="new byte[0]",
338 funnel="sink.putBytes($name)"
339 );
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700340of_match = JType('Match') \
Andreas Wundsam951ada32013-08-01 22:05:38 -0700341 .op(read='ChannelUtilsVer$version.readOFMatch(bb)', \
Andreas Wundsame962d372013-10-02 18:15:58 -0700342 write='$name.writeTo(bb)',
343 default="OFFactoryVer$version.MATCH_WILDCARD_ALL");
Andreas Wundsam5812cf32013-11-15 13:51:24 -0800344group_mod_cmd = JType('OFGroupModCommand', 'short') \
345 .op(version=ANY, read="bb.readShort()", write="bb.writeShort($name)")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700346flow_mod_cmd = JType('OFFlowModCommand', 'short') \
Yotam Harchold7b84202013-07-26 16:08:10 -0700347 .op(version=1, read="bb.readShort()", write="bb.writeShort($name)") \
348 .op(version=ANY, read="bb.readByte()", write="bb.writeByte($name)")
Andreas Wundsam2bf357c2013-08-03 22:50:40 -0700349mac_addr = JType('MacAddress') \
Yotam Harchold7b84202013-07-26 16:08:10 -0700350 .op(read="MacAddress.read6Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700351 write="$name.write6Bytes(bb)",
352 default="MacAddress.NONE")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700353
354port_name = gen_fixed_length_string_jtype(16)
Praseed Balakrishnan7f718782014-09-18 17:02:48 -0700355app_code = gen_fixed_length_string_jtype(15)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700356desc_str = gen_fixed_length_string_jtype(256)
357serial_num = gen_fixed_length_string_jtype(32)
358table_name = gen_fixed_length_string_jtype(32)
Rich Lanef8a3d002014-03-19 13:33:52 -0700359str64 = gen_fixed_length_string_jtype(64)
Yotam Harchola289d552013-09-16 10:10:40 -0700360ipv4 = JType("IPv4Address") \
361 .op(read="IPv4Address.read4Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700362 write="$name.write4Bytes(bb)",
363 default='IPv4Address.NONE')
Yotam Harchola289d552013-09-16 10:10:40 -0700364ipv6 = JType("IPv6Address") \
365 .op(read="IPv6Address.read16Bytes(bb)", \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700366 write="$name.write16Bytes(bb)",
367 default='IPv6Address.NONE')
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700368packetin_reason = gen_enum_jtype("OFPacketInReason")
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700369transport_port = JType("TransportPort")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700370 .op(read="TransportPort.read2Bytes(bb)",
371 write="$name.write2Bytes(bb)",
372 default="TransportPort.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700373eth_type = JType("EthType")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700374 .op(read="EthType.read2Bytes(bb)",
375 write="$name.write2Bytes(bb)",
376 default="EthType.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700377vlan_vid = JType("VlanVid")\
Andreas Wundsam98a18632013-11-05 11:34:24 -0800378 .op(version=ANY, read="VlanVid.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="VlanVid.ZERO")
379vlan_vid_match = JType("OFVlanVidMatch")\
380 .op(version=1, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
381 .op(version=2, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
382 .op(version=ANY, read="OFVlanVidMatch.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFVlanVidMatch.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700383vlan_pcp = JType("VlanPcp")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700384 .op(read="VlanPcp.readByte(bb)",
385 write="$name.writeByte(bb)",
386 default="VlanPcp.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700387ip_dscp = JType("IpDscp")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700388 .op(read="IpDscp.readByte(bb)",
389 write="$name.writeByte(bb)",
390 default="IpDscp.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700391ip_ecn = JType("IpEcn")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700392 .op(read="IpEcn.readByte(bb)",
393 write="$name.writeByte(bb)",
394 default="IpEcn.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700395ip_proto = JType("IpProtocol")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700396 .op(read="IpProtocol.readByte(bb)",
397 write="$name.writeByte(bb)",
398 default="IpProtocol.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700399icmpv4_type = JType("ICMPv4Type")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700400 .op(read="ICMPv4Type.readByte(bb)",
401 write="$name.writeByte(bb)",
402 default="ICMPv4Type.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700403icmpv4_code = JType("ICMPv4Code")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700404 .op(read="ICMPv4Code.readByte(bb)",
405 write="$name.writeByte(bb)",
406 default="ICMPv4Code.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700407arp_op = JType("ArpOpcode")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700408 .op(read="ArpOpcode.read2Bytes(bb)",
409 write="$name.write2Bytes(bb)",
410 default="ArpOpcode.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700411ipv6_flabel = JType("IPv6FlowLabel")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700412 .op(read="IPv6FlowLabel.read4Bytes(bb)",
413 write="$name.write4Bytes(bb)",
414 default="IPv6FlowLabel.NONE")
Yotam Harcholc742e202013-08-15 12:16:24 -0700415metadata = JType("OFMetadata")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700416 .op(read="OFMetadata.read8Bytes(bb)",
417 write="$name.write8Bytes(bb)",
418 default="OFMetadata.NONE")
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700419oxm = JType("OFOxm<?>")\
420 .op( read="OFOxmVer$version.READER.readFrom(bb)",
421 write="$name.writeTo(bb)")
422oxm_list = JType("OFOxmList") \
423 .op(
424 read= 'OFOxmList.readFrom(bb, $length, OFOxmVer$version.READER)', \
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700425 write='$name.writeTo(bb)',
426 default="OFOxmList.EMPTY")
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700427meter_features = JType("OFMeterFeatures")\
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700428 .op(read="OFMeterFeaturesVer$version.READER.readFrom(bb)",
429 write="$name.writeTo(bb)")
Wilson Ngd6181882014-04-14 16:28:35 -0700430bsn_vport = JType("OFBsnVport")\
431 .op(read="OFBsnVportVer$version.READER.readFrom(bb)",
Andreas Wundsam113d25b2014-01-22 20:17:37 -0800432 write="$name.writeTo(bb)")
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700433flow_wildcards = JType("int") \
434 .op(read='bb.readInt()',
435 write='bb.writeInt($name)',
436 default="OFFlowWildcardsSerializerVer$version.ALL_VAL")
437table_stats_wildcards = JType("int") \
438 .op(read='bb.readInt()',
439 write='bb.writeInt($name)')
Yotam Harchol2c535582013-10-01 15:50:20 -0700440port_bitmap = JType('OFBitMask128') \
441 .op(read='OFBitMask128.read16Bytes(bb)',
Yotam Harchola11f38b2013-09-26 15:38:17 -0700442 write='$name.write16Bytes(bb)',
Yotam Harchol2c535582013-10-01 15:50:20 -0700443 default='OFBitMask128.NONE')
Andreas Wundsam37e0fb12013-09-28 18:57:57 -0700444table_id = JType("TableId") \
445 .op(read='TableId.readByte(bb)',
446 write='$name.writeByte(bb)',
447 default='TableId.ALL')
Andreas Wundsam45c95f82013-10-08 15:04:23 -0700448table_id_default_zero = JType("TableId") \
449 .op(read='TableId.readByte(bb)',
450 write='$name.writeByte(bb)',
451 default='TableId.ZERO')
Sovietaced0f9dddf2014-01-28 19:45:07 -0800452of_aux_id = JType("OFAuxId") \
453 .op(read='OFAuxId.readByte(bb)',
Sovietaced92603b02014-01-28 18:23:24 -0800454 write='$name.writeByte(bb)',
Sovietaced0f9dddf2014-01-28 19:45:07 -0800455 default='OFAuxId.MAIN')
Andreas Wundsama0981022013-10-02 18:15:06 -0700456of_version = JType("OFVersion", 'byte') \
457 .op(read='bb.readByte()', write='bb.writeByte($name)')
Rob Vaterlausb10ae552013-09-23 14:39:39 -0700458
Andreas Wundsam8ec3bcc2013-09-16 19:44:00 -0700459port_speed = JType("PortSpeed")
Rob Vaterlaus4d311942013-09-24 13:41:44 -0700460error_type = JType("OFErrorType")
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700461of_type = JType("OFType", 'byte') \
462 .op(read='bb.readByte()', write='bb.writeByte($name)')
463action_type= gen_enum_jtype("OFActionType")\
464 .set_priv_type("short")\
465 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
466instruction_type = gen_enum_jtype("OFInstructionType")\
467 .set_priv_type('short') \
468 .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)
469buffer_id = JType("OFBufferId") \
470 .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER")
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700471boolean = JType("boolean", "byte") \
472 .op(read='(bb.readByte() != 0)',
473 write='bb.writeByte($name ? 1 : 0)',
474 default="false")
475datapath_id = JType("DatapathId") \
476 .op(read='DatapathId.of(bb.readLong())',
477 write='bb.writeLong($name.getLong())',
478 default='DatapathId.NONE')
Andreas Wundsam5ea1aca2013-10-07 17:00:24 -0700479action_type_set = JType("Set<OFActionType>") \
480 .op(read='ChannelUtilsVer10.readSupportedActions(bb)',
481 write='ChannelUtilsVer10.writeSupportedActions(bb, $name)',
482 default='ImmutableSet.<OFActionType>of()',
483 funnel='ChannelUtilsVer10.putSupportedActionsTo($name, sink)')
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700484of_group = JType("OFGroup") \
485 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ALL")
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800486of_group_default_any = JType("OFGroup") \
487 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ANY")
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700488# the outgroup field of of_flow_stats_request has a special default value
489of_group_default_any = JType("OFGroup") \
490 .op(version=ANY, read="OFGroup.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFGroup.ANY")
491buffer_id = JType("OFBufferId") \
492 .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER")
Rich Lane376cafe2013-10-27 21:49:14 -0700493lag_id = JType("LagId") \
494 .op(version=ANY, read="LagId.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="LagId.NONE")
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700495
496sig_id = JType("CircuitSignalID") \
497 .op(version=ANY, read="CircuitSignalID.read6Bytes(bb)", write="$name.write6Bytes(bb)", default="CircuitSignalID.NONE")
Rich Laneeb21c4f2013-10-28 17:34:41 -0700498vrf = JType("VRF") \
499 .op(version=ANY, read="VRF.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="VRF.ZERO")
500class_id = JType("ClassId") \
501 .op(version=ANY, read="ClassId.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="ClassId.NONE")
Rich Lane9c27b5d2013-10-30 17:14:32 -0700502boolean_value = JType('OFBooleanValue', 'OFBooleanValue') \
503 .op(read='OFBooleanValue.of(bb.readByte() != 0)', write='bb.writeByte($name.getInt())', default="OFBooleanValue.FALSE")
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800504gen_table_id = JType("GenTableId") \
505 .op(read='GenTableId.read2Bytes(bb)',
506 write='$name.write2Bytes(bb)',
507 )
Rich Lane53ddf5c2014-03-20 15:24:08 -0700508udf = JType("UDF") \
509 .op(version=ANY, read="UDF.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="UDF.ZERO")
Andreas Wundsam62cbcff2014-05-09 16:35:00 -0700510error_cause_data = JType("OFErrorCauseData") \
Andreas Wundsam39efd1c2014-05-13 19:41:51 -0700511 .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 -0700512
Andreas Wundsame2fd7ce2014-06-26 20:56:42 -0700513var_string = JType('String').op(
514 read='ChannelUtils.readFixedLengthString(bb, $length)',
515 write='ChannelUtils.writeFixedLengthString(bb, $name, $name.length())',
516 default='""',
517 funnel='sink.putUnencodedChars($name)'
518 )
519
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700520generic_t = JType("T")
521
Andreas Wundsam27303462013-07-16 12:52:35 -0700522
523default_mtype_to_jtype_convert_map = {
524 'uint8_t' : u8,
525 'uint16_t' : u16,
526 'uint32_t' : u32,
527 'uint64_t' : u64,
Andreas Wundsam27303462013-07-16 12:52:35 -0700528 'of_port_no_t' : of_port,
529 'list(of_action_t)' : actions_list,
530 'list(of_instruction_t)' : instructions_list,
531 'list(of_bucket_t)': buckets_list,
532 'list(of_port_desc_t)' : port_desc_list,
533 'list(of_packet_queue_t)' : packet_queue_list,
xinwuf08ef682013-12-05 18:29:20 -0800534 'list(of_uint64_t)' : u64_list,
Andreas Wundsam27303462013-07-16 12:52:35 -0700535 'list(of_uint32_t)' : u32_list,
536 'list(of_uint8_t)' : u8_list,
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700537 'list(of_oxm_t)' : oxm_list,
Andreas Wundsam27303462013-07-16 12:52:35 -0700538 'of_octets_t' : octets,
539 'of_match_t': of_match,
540 'of_fm_cmd_t': flow_mod_cmd,
541 'of_mac_addr_t': mac_addr,
542 'of_port_desc_t': port_desc,
543 'of_desc_str_t': desc_str,
544 'of_serial_num_t': serial_num,
545 'of_port_name_t': port_name,
546 'of_table_name_t': table_name,
Rich Lanef8a3d002014-03-19 13:33:52 -0700547 'of_str64_t': str64,
Andreas Wundsam27303462013-07-16 12:52:35 -0700548 'of_ipv4_t': ipv4,
549 'of_ipv6_t': ipv6,
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700550 'of_wc_bmap_t': flow_wildcards,
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700551 'of_oxm_t': oxm,
552 'of_meter_features_t': meter_features,
Rich Lane2d1c5c72013-12-03 13:02:10 -0800553 'of_bitmap_128_t': port_bitmap,
Andreas Wundsam7c15b172014-04-24 19:02:40 -0700554 'of_checksum_128_t': u128,
Wilson Ngd6181882014-04-14 16:28:35 -0700555 'of_bsn_vport_t': bsn_vport,
Praseed Balakrishnan7f718782014-09-18 17:02:48 -0700556 'of_app_code_t': app_code,
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700557 'of_sig_id_t': sig_id,
Andreas Wundsam27303462013-07-16 12:52:35 -0700558 }
559
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700560## Map that defines exceptions from the standard loxi->java mapping scheme
561# map of {<loxi_class_name> : { <loxi_member_name> : <JType instance> } }
Andreas Wundsam27303462013-07-16 12:52:35 -0700562exceptions = {
Yotam Harcholc742e202013-08-15 12:16:24 -0700563 'of_packet_in': { 'data' : octets, 'reason': packetin_reason },
564 'of_oxm_tcp_src' : { 'value' : transport_port },
565 'of_oxm_tcp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
566 'of_oxm_tcp_dst' : { 'value' : transport_port },
567 'of_oxm_tcp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
568 'of_oxm_udp_src' : { 'value' : transport_port },
569 'of_oxm_udp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
570 'of_oxm_udp_dst' : { 'value' : transport_port },
571 'of_oxm_udp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
572 'of_oxm_sctp_src' : { 'value' : transport_port },
573 'of_oxm_sctp_src_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
574 'of_oxm_sctp_dst' : { 'value' : transport_port },
575 'of_oxm_sctp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
576 'of_oxm_eth_type' : { 'value' : eth_type },
577 'of_oxm_eth_type_masked' : { 'value' : eth_type, 'value_mask' : eth_type },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800578 'of_oxm_vlan_vid' : { 'value' : vlan_vid_match },
579 'of_oxm_vlan_vid_masked' : { 'value' : vlan_vid_match, 'value_mask' : vlan_vid_match },
Yotam Harcholc742e202013-08-15 12:16:24 -0700580 'of_oxm_vlan_pcp' : { 'value' : vlan_pcp },
581 'of_oxm_vlan_pcp_masked' : { 'value' : vlan_pcp, 'value_mask' : vlan_pcp },
582 'of_oxm_ip_dscp' : { 'value' : ip_dscp },
583 'of_oxm_ip_dscp_masked' : { 'value' : ip_dscp, 'value_mask' : ip_dscp },
584 'of_oxm_ip_ecn' : { 'value' : ip_ecn },
585 'of_oxm_ip_ecn_masked' : { 'value' : ip_ecn, 'value_mask' : ip_ecn },
586 'of_oxm_ip_proto' : { 'value' : ip_proto },
587 'of_oxm_ip_proto_masked' : { 'value' : ip_proto, 'value_mask' : ip_proto },
588 'of_oxm_icmpv4_type' : { 'value' : icmpv4_type },
589 'of_oxm_icmpv4_type_masked' : { 'value' : icmpv4_type, 'value_mask' : icmpv4_type },
590 'of_oxm_icmpv4_code' : { 'value' : icmpv4_code },
591 'of_oxm_icmpv4_code_masked' : { 'value' : icmpv4_code, 'value_mask' : icmpv4_code },
592 'of_oxm_arp_op' : { 'value' : arp_op },
593 'of_oxm_arp_op_masked' : { 'value' : arp_op, 'value_mask' : arp_op },
594 'of_oxm_arp_spa' : { 'value' : ipv4 },
595 'of_oxm_arp_spa_masked' : { 'value' : ipv4, 'value_mask' : ipv4 },
596 'of_oxm_arp_tpa' : { 'value' : ipv4 },
597 'of_oxm_arp_tpa_masked' : { 'value' : ipv4, 'value_mask' : ipv4 },
598 'of_oxm_ipv6_flabel' : { 'value' : ipv6_flabel },
599 'of_oxm_ipv6_flabel_masked' : { 'value' : ipv6_flabel, 'value_mask' : ipv6_flabel },
600 'of_oxm_metadata' : { 'value' : metadata },
601 'of_oxm_metadata_masked' : { 'value' : metadata, 'value_mask' : metadata },
Yotam Harchol5804f772013-08-21 17:35:31 -0700602
603 'of_oxm_icmpv6_code' : { 'value' : u8obj },
604 'of_oxm_icmpv6_code_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
605 'of_oxm_icmpv6_type' : { 'value' : u8obj },
606 'of_oxm_icmpv6_type_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
607 'of_oxm_mpls_label' : { 'value' : u32obj },
608 'of_oxm_mpls_label_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
609 'of_oxm_mpls_tc' : { 'value' : u8obj },
610 'of_oxm_mpls_tc_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700611
Yotam Harchol595c6442013-09-27 16:29:08 -0700612 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap },
613 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap, 'value_mask': port_bitmap },
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700614
Rich Lane376cafe2013-10-27 21:49:14 -0700615 'of_oxm_bsn_lag_id' : { 'value' : lag_id },
616 'of_oxm_bsn_lag_id_masked' : { 'value' : lag_id, 'value_mask' : lag_id },
Rich Lane1424d0b2013-10-24 17:16:24 -0700617
Rich Laneeb21c4f2013-10-28 17:34:41 -0700618 'of_oxm_bsn_vrf' : { 'value' : vrf },
619 'of_oxm_bsn_vrf_masked' : { 'value' : vrf, 'value_mask' : vrf },
620
Rich Lane9c27b5d2013-10-30 17:14:32 -0700621 'of_oxm_bsn_global_vrf_allowed' : { 'value' : boolean_value },
622 'of_oxm_bsn_global_vrf_allowed_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
Rich Laneeb21c4f2013-10-28 17:34:41 -0700623
624 'of_oxm_bsn_l3_interface_class_id' : { 'value' : class_id },
625 'of_oxm_bsn_l3_interface_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
626
627 'of_oxm_bsn_l3_src_class_id' : { 'value' : class_id },
628 'of_oxm_bsn_l3_src_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
629
630 'of_oxm_bsn_l3_dst_class_id' : { 'value' : class_id },
631 'of_oxm_bsn_l3_dst_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
632
Rich Lane917bb9a2014-03-11 17:49:56 -0700633 'of_oxm_bsn_egr_port_group_id' : { 'value' : class_id },
634 'of_oxm_bsn_egr_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
635
Rich Lane53ddf5c2014-03-20 15:24:08 -0700636 'of_oxm_bsn_udf0' : { 'value' : udf },
637 'of_oxm_bsn_udf0_masked' : { 'value' : udf, 'value_mask' : udf },
638
639 'of_oxm_bsn_udf1' : { 'value' : udf },
640 'of_oxm_bsn_udf1_masked' : { 'value' : udf, 'value_mask' : udf },
641
642 'of_oxm_bsn_udf2' : { 'value' : udf },
643 'of_oxm_bsn_udf2_masked' : { 'value' : udf, 'value_mask' : udf },
644
645 'of_oxm_bsn_udf3' : { 'value' : udf },
646 'of_oxm_bsn_udf3_masked' : { 'value' : udf, 'value_mask' : udf },
647
648 'of_oxm_bsn_udf4' : { 'value' : udf },
649 'of_oxm_bsn_udf4_masked' : { 'value' : udf, 'value_mask' : udf },
650
651 'of_oxm_bsn_udf5' : { 'value' : udf },
652 'of_oxm_bsn_udf5_masked' : { 'value' : udf, 'value_mask' : udf },
653
654 'of_oxm_bsn_udf6' : { 'value' : udf },
655 'of_oxm_bsn_udf6_masked' : { 'value' : udf, 'value_mask' : udf },
656
657 'of_oxm_bsn_udf7' : { 'value' : udf },
658 'of_oxm_bsn_udf7_masked' : { 'value' : udf, 'value_mask' : udf },
659
Rich Lane9b178072014-05-19 15:31:55 -0700660 'of_oxm_bsn_tcp_flags' : { 'value' : u16obj },
661 'of_oxm_bsn_tcp_flags_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
662
Rich Lanea5eeae32014-06-26 19:59:04 -0700663 'of_oxm_bsn_vlan_xlate_port_group_id' : { 'value' : class_id },
664 'of_oxm_bsn_vlan_xlate_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
665
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700666 'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800667 'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
Andreas Wundsamb3ed3ff2013-09-23 14:46:29 -0700668 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
Andreas Wundsame962d372013-10-02 18:15:58 -0700669 'tcp_src': transport_port, 'tcp_dst': transport_port,
670 'in_port': of_port_match_v1
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700671 },
672 'of_bsn_set_l2_table_request': { 'l2_table_enable': boolean },
673 'of_bsn_set_l2_table_reply': { 'l2_table_enable': boolean },
Rob Vaterlause1b86842013-10-18 13:29:19 -0700674 'of_bsn_set_pktin_suppression_request': { 'enabled': boolean },
Sovietaced768c3e22014-04-04 16:46:48 -0700675 'of_bsn_controller_connection': { 'auxiliary_id' : of_aux_id},
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700676 'of_flow_stats_request': { 'out_group': of_group_default_any },
Andreas Wundsam384ccc12014-03-12 14:52:42 -0700677 'of_aggregate_stats_request': { 'out_group': of_group_default_any },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800678
679 'of_action_bsn_mirror': { 'dest_port': of_port },
680 'of_action_push_mpls': { 'ethertype': eth_type },
681 'of_action_push_pbb': { 'ethertype': eth_type },
682 'of_action_push_vlan': { 'ethertype': eth_type },
Ronald Li4fb8abb2013-11-21 19:53:02 -0800683 'of_action_pop_mpls': { 'ethertype': eth_type },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800684 'of_action_set_nw_dst': { 'nw_addr': ipv4 },
685 'of_action_set_nw_ecn': { 'nw_ecn': ip_ecn },
686 'of_action_set_nw_src': { 'nw_addr': ipv4 },
Andreas Wundsam98a18632013-11-05 11:34:24 -0800687 'of_action_set_tp_dst': { 'tp_port': transport_port },
688 'of_action_set_tp_src': { 'tp_port': transport_port },
689 'of_action_set_vlan_pcp': { 'vlan_pcp': vlan_pcp },
690 'of_action_set_vlan_vid': { 'vlan_vid': vlan_vid },
Andreas Wundsam5812cf32013-11-15 13:51:24 -0800691
692 'of_group_mod' : { 'command' : group_mod_cmd },
693 'of_group_add' : { 'command' : group_mod_cmd },
694 'of_group_modify' : { 'command' : group_mod_cmd },
695 'of_group_delete' : { 'command' : group_mod_cmd },
696
697 'of_bucket' : { 'watch_group': of_group },
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800698
699 'of_bsn_tlv_vlan_vid' : { 'value' : vlan_vid },
Andreas Wundsamec1f6612014-06-25 15:48:12 -0700700 'of_bsn_table_set_buckets_size' : { 'table_id' : table_id },
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800701 'of_bsn_gentable_entry_add' : { 'table_id' : gen_table_id },
Andreas Wundsame2fd7ce2014-06-26 20:56:42 -0700702 'of_bsn_log': { 'data': var_string },
Sovietaced92603b02014-01-28 18:23:24 -0800703
Sovietaced0f9dddf2014-01-28 19:45:07 -0800704 'of_features_reply' : { 'auxiliary_id' : of_aux_id},
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700705 'of_oxm_och_sigtype' : { 'value' : u8obj },
706 'of_oxm_och_sigtype_basic' : { 'value' : u8obj },
707 'of_oxm_och_sigid' : {'value' : sig_id},
708 'of_oxm_och_sigid_basic' : {'value' : sig_id},
Andreas Wundsam27303462013-07-16 12:52:35 -0700709}
710
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700711
712@memoize
713def enum_java_types():
714 enum_types = {}
Andreas Wundsamc8912c12013-11-15 13:44:48 -0800715 for enum in loxi_globals.unified.enums:
716 java_name = name_c_to_caps_camel(re.sub(r'_t$', "", enum.name))
717 enum_types[enum.name] = gen_enum_jtype(java_name, enum.is_bitmask)
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700718 return enum_types
719
Andreas Wundsam2be7da52013-08-22 07:34:25 -0700720def make_match_field_jtype(sub_type_name="?"):
721 return JType("MatchField<{}>".format(sub_type_name))
722
Andreas Wundsam661a2222013-11-05 17:18:59 -0800723def make_oxm_jtype(sub_type_name="?"):
724 return JType("OFOxm<{}>".format(sub_type_name))
Andreas Wundsam27303462013-07-16 12:52:35 -0700725
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700726def list_cname_to_java_name(c_type):
Andreas Wundsam27303462013-07-16 12:52:35 -0700727 m = re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type)
728 if not m:
729 raise Exception("Not a recgonized standard list type declaration: %s" % c_type)
730 base_name = m.group(1)
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700731 return "OF" + name_c_to_caps_camel(base_name)
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700732
733#### main entry point for conversion of LOXI types (c_types) Java types.
734# FIXME: This badly needs a refactoring
735
Andreas Wundsam27303462013-07-16 12:52:35 -0700736def convert_to_jtype(obj_name, field_name, c_type):
737 """ Convert from a C type ("uint_32") to a java type ("U32")
738 and return a JType object with the size, internal type, and marshalling functions"""
739 if obj_name in exceptions and field_name in exceptions[obj_name]:
740 return exceptions[obj_name][field_name]
Andreas Wundsam46d230f2013-08-02 22:24:06 -0700741 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 -0700742 return of_type
Andreas Wundsam27303462013-07-16 12:52:35 -0700743 elif field_name == "type" and re.match(r'of_action.*', obj_name):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700744 return action_type
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700745 elif field_name == "err_type":
746 return JType("OFErrorType", 'short') \
747 .op(read='bb.readShort()', write='bb.writeShort($name)')
Andreas Wundsam62cbcff2014-05-09 16:35:00 -0700748 elif loxi_utils.class_is(obj_name, "of_error_msg") and field_name == "data":
749 return error_cause_data
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700750 elif field_name == "stats_type":
751 return JType("OFStatsType", 'short') \
752 .op(read='bb.readShort()', write='bb.writeShort($name)')
Andreas Wundsam999c0732013-10-01 19:29:16 -0700753 elif field_name == "type" and re.match(r'of_instruction.*', obj_name):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700754 return instruction_type
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800755 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 -0700756 return table_id_default_zero
Andreas Wundsamee8b42c2014-01-24 17:38:19 -0800757 elif loxi_utils.class_is(obj_name, "of_flow_mod") and field_name == "out_group" and c_type == "uint32_t":
758 return of_group_default_any
Andreas Wundsam37e0fb12013-09-28 18:57:57 -0700759 elif field_name == "table_id" and c_type == "uint8_t":
760 return table_id
Andreas Wundsam27303462013-07-16 12:52:35 -0700761 elif field_name == "version" and c_type == "uint8_t":
Andreas Wundsama0981022013-10-02 18:15:06 -0700762 return of_version
Rob Vaterlausb10ae552013-09-23 14:39:39 -0700763 elif field_name == "buffer_id" and c_type == "uint32_t":
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700764 return buffer_id
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700765 elif field_name == "group_id" and c_type == "uint32_t":
766 return of_group
Rob Vaterlausfeee3712013-09-30 11:24:19 -0700767 elif field_name == 'datapath_id':
768 return datapath_id
769 elif field_name == 'actions' and obj_name == 'of_features_reply':
Andreas Wundsam5ea1aca2013-10-07 17:00:24 -0700770 return action_type_set
Andreas Wundsamd4b22692014-01-14 14:17:26 -0800771 elif field_name == "table_id" and re.match(r'of_bsn_gentable.*', obj_name):
772 return gen_table_id
Andreas Wundsam27303462013-07-16 12:52:35 -0700773 elif c_type in default_mtype_to_jtype_convert_map:
774 return default_mtype_to_jtype_convert_map[c_type]
775 elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type):
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700776 return gen_list_jtype(list_cname_to_java_name(c_type))
Andreas Wundsam7cfeac32013-09-17 13:53:48 -0700777 elif c_type in enum_java_types():
778 return enum_java_types()[c_type]
Andreas Wundsam27303462013-07-16 12:52:35 -0700779 else:
780 print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name)
781 jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type))
782 return JType(jtype)
Andreas Wundsamd8bcedf2013-08-03 21:23:37 -0700783
784
785#### Enum specific wiretype definitions
786enum_wire_types = {
787 "uint8_t": JType("byte").op(read="bb.readByte()", write="bb.writeByte($name)"),
788 "uint16_t": JType("short").op(read="bb.readShort()", write="bb.writeShort($name)"),
789 "uint32_t": JType("int").op(read="bb.readInt()", write="bb.writeInt($name)"),
790 "uint64_t": JType("long").op(read="bb.readLong()", write="bb.writeLong($name)"),
791}
792
793def convert_enum_wire_type_to_jtype(wire_type):
794 return enum_wire_types[wire_type]