Merge branch 'master' of github.com:floodlight/loxigen
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index 9ea6d34..46aedda 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -403,6 +403,9 @@
if wire_version >= of_g.VERSION_1_3:
cls2 = parent + "_id" + cls[len(parent):]
type_maps.extension_action_id_subtype[wire_version][experimenter][cls2] = val
+ elif parent == 'of_instruction' and experimenter:
+ val = find_type_value(ofclass, 'subtype')
+ type_maps.extension_instruction_subtype[wire_version][experimenter][cls] = val
# Messages
for version, protocol in loxi_globals.ir.items():
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 1106f2d..e2bb467 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -2729,7 +2729,8 @@
# Some tlv16 types may be extensions requiring more work
if cls in ["of_action_bsn_mirror", "of_action_id_bsn_mirror",
"of_action_bsn_set_tunnel_dst", "of_action_id_bsn_set_tunnel_dst",
- "of_action_nicira_dec_ttl", "of_action_id_nicira_dec_ttl"]:
+ "of_action_nicira_dec_ttl", "of_action_id_nicira_dec_ttl",
+ "of_instruction_bsn_disable_src_mac_check"]:
out.write("""
/* Extended TLV obj; Call specific accessor */
of_extension_object_id_set(obj, %(enum)s);
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 30c73ac..a48bdf8 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -37,6 +37,9 @@
#include <loci/loci.h>
#include <loci/of_message.h>
+#define OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET 4
+#define OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET 8
+
/****************************************************************
* Top level OpenFlow message length functions
****************************************************************/
@@ -207,8 +210,6 @@
/**
* Set wire data for extension objects, not messages.
- *
- * Currently only handles BSN mirror; ignores all others
*/
void
@@ -235,6 +236,11 @@
OF_EXPERIMENTER_ID_NICIRA);
buf_u16_set(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, 18);
break;
+ case OF_INSTRUCTION_BSN_DISABLE_SRC_MAC_CHECK:
+ buf_u32_set(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET,
+ OF_EXPERIMENTER_ID_BSN);
+ buf_u32_set(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, 0);
+ break;
default:
break;
}
@@ -339,10 +345,26 @@
static int
extension_instruction_object_id_get(of_object_t *obj, of_object_id_t *id)
{
- (void)obj;
+ uint32_t exp_id;
+ uint8_t *buf;
*id = OF_INSTRUCTION_EXPERIMENTER;
+ buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
+
+ buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET, &exp_id);
+
+ switch (exp_id) {
+ case OF_EXPERIMENTER_ID_BSN: {
+ uint32_t subtype;
+ buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
+ switch (subtype) {
+ case 0: *id = OF_INSTRUCTION_BSN_DISABLE_SRC_MAC_CHECK; break;
+ }
+ break;
+ }
+ }
+
return OF_ERROR_NONE;
}
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index cf88e35..480eb29 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -156,7 +156,7 @@
if loxi_utils.class_is_list(cls):
return True
# TODO get this from the input file when we have virtual class syntax
- if cls in ["of_flow_mod", "of_stats_request", "of_stats_reply", "of_error_msg", "of_bsn_header", "of_nicira_header", "of_action_bsn", "of_action_nicira", "of_action_id_bsn", "of_action_id_nicira", "of_bsn_stats_request", "of_bsn_stats_reply", "of_experimenter_stats_request", "of_experimenter_stats_reply"]:
+ if cls in ["of_flow_mod", "of_stats_request", "of_stats_reply", "of_error_msg", "of_bsn_header", "of_nicira_header", "of_action_bsn", "of_action_nicira", "of_action_id_bsn", "of_action_id_nicira", "of_bsn_stats_request", "of_bsn_stats_reply", "of_experimenter_stats_request", "of_experimenter_stats_reply", "of_instruction_experimenter", "of_instruction_bsn"]:
return True
return False
@@ -597,7 +597,18 @@
}
# Set to empty dict if no extension instructions defined
-extension_instruction_subtype = {}
+extension_instruction_subtype = {
+ # version 1.0
+ of_g.VERSION_1_0:dict(),
+ of_g.VERSION_1_1:dict(),
+ of_g.VERSION_1_2:dict(),
+ of_g.VERSION_1_3:dict(
+ bsn = { # of_instruction_bsn_
+ },
+ nicira = { # of_instruction_nicira_
+ }
+ ),
+}
# Set to empty dict if no extension instructions defined
extension_queue_prop_subtype = {}
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index f90c1f2..8f5434e 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -65,7 +65,8 @@
OFExperimenter=set(('data','subtype')),
OFActionExperimenter=set(('data',)),
OFExperimenterStatsRequest=set(('data','subtype')),
- OFExperimenterStatsReply=set(('data','subtype')))
+ OFExperimenterStatsReply=set(('data','subtype')),
+ OFInstructionExperimenter=set(('data',)))
# map: $java_type -> set(java_name_property)
write_blacklist = defaultdict(lambda: set(), OFOxm=set(('typeLen',)), OFAction=set(('type',)), OFInstruction=set(('type',)), OFFlowMod=set(('command', )), OFExperimenter=set(('data','subtype')), OFActionExperimenter=set(('data',)))
# interfaces that are virtual
@@ -469,6 +470,13 @@
return ("action", "OFActionExperimenter", None)
else:
return ("action", "OFAction", None)
+ elif self.ir_class.is_instruction:
+ if self.ir_class.is_subclassof('of_instruction_bsn'):
+ return ("instruction", "OFInstructionBsn", None)
+ elif self.ir_class.is_subclassof('of_instruction_experimenter'):
+ return ("instruction", "OFInstructionExperimenter", None)
+ else:
+ return ("instruction", "OFInstruction", None)
elif re.match(r'OFBsnVport.+$', self.name):
return ("", "OFBsnVport", None)
elif self.name == "OFOxm":
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index d1a9e67..eca00e7 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -597,10 +597,10 @@
'of_action_push_mpls': { 'ethertype': eth_type },
'of_action_push_pbb': { 'ethertype': eth_type },
'of_action_push_vlan': { 'ethertype': eth_type },
+ 'of_action_pop_mpls': { 'ethertype': eth_type },
'of_action_set_nw_dst': { 'nw_addr': ipv4 },
'of_action_set_nw_ecn': { 'nw_ecn': ip_ecn },
'of_action_set_nw_src': { 'nw_addr': ipv4 },
- 'of_action_set_nw_dst': { 'tp_port': transport_port },
'of_action_set_tp_dst': { 'tp_port': transport_port },
'of_action_set_tp_src': { 'tp_port': transport_port },
'of_action_set_vlan_pcp': { 'vlan_pcp': vlan_pcp },
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index 9845e87..0cb42ac 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -46,6 +46,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-integration</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.9.Final</version>
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask128.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask128.java
index 051d573..93f5a2d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask128.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask128.java
@@ -22,7 +22,7 @@
this.raw2 = raw2;
}
- static OFBitMask128 of(long raw1, long raw2) {
+ public static OFBitMask128 of(long raw1, long raw2) {
if (raw1 == -1 && raw2 == -1)
return ALL;
if (raw1 == 0 && raw2 == 0)
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
index fc214e5..4db84f1 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
@@ -1,24 +1,18 @@
package org.projectfloodlight.openflow.types;
-import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertThat;
import junit.framework.TestCase;
import org.junit.Test;
-import com.google.common.collect.ImmutableList;
-
public class OFPortBitMapTest extends TestCase {
@Test
public void testCreateAndIterate() {
OFPortBitMap map = OFPortBitMap.ofPorts(OFPort.of(1), OFPort.of(2), OFPort.of(5));
- assertThat(
- ImmutableList.copyOf(map.getOnPorts()),
- equalTo(
- ImmutableList.of(OFPort.of(1), OFPort.of(2), OFPort.of(5))
- ));
+ assertThat(map.getOnPorts(), contains(OFPort.of(1), OFPort.of(2), OFPort.of(5)));
}
@Test
@@ -27,11 +21,7 @@
OFPortBitMap map = OFPortBitMap.of(bitmap);
- assertThat(
- ImmutableList.copyOf(map.getOnPorts()),
- equalTo(
- ImmutableList.of(OFPort.of(1), OFPort.of(2), OFPort.of(5))
- ));
+ assertThat(map.getOnPorts(), contains(OFPort.of(1), OFPort.of(2), OFPort.of(5)));
}
@Test
diff --git a/java_gen/templates/unit_test.java b/java_gen/templates/unit_test.java
index ad2c3b8..cf01429 100644
--- a/java_gen/templates/unit_test.java
+++ b/java_gen/templates/unit_test.java
@@ -46,7 +46,8 @@
//:: factory = java_model.model.factory_of(test.interface)
//:: var_type = msg.interface.name
//:: var_name = msg.interface.variable_name
- //:: builder_method = factory.method_name(msg.interface)
+ //:: use_builder = len(msg.data_members) > 0
+ //:: factory_method = factory.method_name(msg.interface, builder=use_builder)
//:: factory_impl = java_model.model.factory_of(test.interface).of_version(test.java_class.version).name
${factory.name if factory.name is not None else "OFFactory"} factory;
@@ -61,9 +62,13 @@
//:: if "java" in test_data:
@Test
public void testWrite() {
- ${var_type}.Builder builder = factory.${builder_method}();
+ //:: if use_builder:
+ ${var_type}.Builder builder = factory.${factory_method}();
${test_data["java"]};
${var_type} ${var_name} = builder.build();
+ //:: else:
+ ${var_type} ${var_name} = factory.${factory_method}();
+ //:: #endif
ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
${var_name}.writeTo(bb);
byte[] written = new byte[bb.readableBytes()];
@@ -74,9 +79,13 @@
@Test
public void testRead() throws Exception {
- ${var_type}.Builder builder = factory.${builder_method}();
+ //:: if use_builder:
+ ${var_type}.Builder builder = factory.${factory_method}();
${test_data["java"]};
${var_type} ${var_name}Built = builder.build();
+ //:: else:
+ ${var_type} ${var_name}Built = factory.${factory_method}();
+ //:: #endif
ChannelBuffer input = ChannelBuffers.copiedBuffer(${msg.constant_name}_SERIALIZED);
diff --git a/openflow_input/bsn-1.3 b/openflow_input/bsn-1.3
new file mode 100644
index 0000000..f9340b4
--- /dev/null
+++ b/openflow_input/bsn-1.3
@@ -0,0 +1,37 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+
+#version 4
+
+// BSN extension instruction
+struct of_instruction_bsn : of_instruction_experimenter {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == 0x5c16c7;
+ uint32_t subtype == ?;
+ pad(4);
+};
diff --git a/openflow_input/bsn_disable_src_mac_check b/openflow_input/bsn_disable_src_mac_check
new file mode 100644
index 0000000..f75c237
--- /dev/null
+++ b/openflow_input/bsn_disable_src_mac_check
@@ -0,0 +1,40 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 4
+
+struct of_instruction_bsn_disable_src_mac_check : of_instruction_bsn {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == 0x5c16c7;
+ uint32_t subtype == 0;
+ pad(4);
+};
diff --git a/py_gen/templates/instruction.py b/py_gen/templates/instruction.py
index 978e38b..2817625 100644
--- a/py_gen/templates/instruction.py
+++ b/py_gen/templates/instruction.py
@@ -54,16 +54,42 @@
:: #endfor
+def parse_experimenter(reader):
+ experimenter, = reader.peek("!4xL")
+ if experimenter == 0x005c16c7: # Big Switch Networks
+ subtype, = reader.peek("!8xL")
+ else:
+ raise loxi.ProtocolError("unexpected experimenter id %#x" % experimenter)
+
+ if subtype in experimenter_parsers[experimenter]:
+ return experimenter_parsers[experimenter][subtype](reader)
+ else:
+ raise loxi.ProtocolError("unexpected experimenter id %#x subtype %#x" % (experimenter, subtype))
+
parsers = {
:: sort_key = lambda x: x.type_members[0].value
:: msgtype_groups = itertools.groupby(sorted(ofclasses, key=sort_key), sort_key)
:: for (k, v) in msgtype_groups:
:: k = util.constant_for_value(version, "ofp_instruction_type", k)
:: v = list(v)
-:: if len(v) == 1:
+:: if len(v) == 1 and k != 'const.OFPIT_EXPERIMENTER':
${k} : ${v[0].pyname}.unpack,
:: else:
${k} : parse_${k[12:].lower()},
:: #endif
:: #endfor
}
+
+:: experimenter_ofclasses = [x for x in ofclasses if x.type_members[0].value == 0xffff]
+:: sort_key = lambda x: x.type_members[1].value
+:: experimenter_ofclasses.sort(key=sort_key)
+:: grouped = itertools.groupby(experimenter_ofclasses, sort_key)
+experimenter_parsers = {
+:: for (experimenter, v) in grouped:
+ ${experimenter} : {
+:: for ofclass in v:
+ ${ofclass.type_members[2].value}: ${ofclass.pyname}.unpack,
+:: #endfor
+ },
+:: #endfor
+}
diff --git a/test_data/of13/instruction_bsn_disable_src_mac_check.data b/test_data/of13/instruction_bsn_disable_src_mac_check.data
new file mode 100644
index 0000000..6001fde
--- /dev/null
+++ b/test_data/of13/instruction_bsn_disable_src_mac_check.data
@@ -0,0 +1,11 @@
+-- binary
+ff ff # type
+00 10 # length
+00 5c 16 c7 # experimenter
+00 00 00 00 # subtype
+00 00 00 00 # pad
+-- python
+ofp.instruction.bsn_disable_src_mac_check()
+-- java
+-- c
+obj = of_instruction_bsn_disable_src_mac_check_new(OF_VERSION_1_3);