Merge remote-tracking branch 'origin/master' into in_ports_masked2
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index df9d9da..798f5a4 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1007,6 +1007,11 @@
typedef char of_desc_str_t[OF_DESC_STR_LEN];
typedef char of_serial_num_t[OF_SERIAL_NUM_LEN];
+typedef struct of_bitmap_128_s {
+ uint64_t hi;
+ uint64_t lo;
+} of_bitmap_128_t;
+
/* These are types which change across versions. */
typedef uint32_t of_port_no_t;
typedef uint16_t of_fm_cmd_t;
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index 7353ae7..e15688e 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -286,6 +286,8 @@
OF_OXM_INDEX_IPV6_ND_TLL = 33, /* Target link-layer for ND. */
OF_OXM_INDEX_MPLS_LABEL = 34, /* MPLS label. */
OF_OXM_INDEX_MPLS_TC = 35, /* MPLS TC. */
+
+ OF_OXM_INDEX_BSN_IN_PORTS_128 = 36,
};
#define OF_OXM_BIT(index) (((uint64_t) 1) << (index))
@@ -1066,6 +1068,15 @@
#define OF_OVERLAP_MAC_ADDR(v1, v2, m1, m2) \\
of_overlap_mac_addr((v1), (v2), (m1), (m2))
+#define OF_MORE_SPECIFIC_BITMAP_128(v1, v2) \\
+ (OF_MORE_SPECIFIC_INT((v1)->lo, (v2)->lo) && OF_MORE_SPECIFIC_INT((v1)->hi, (v2)->hi))
+
+#define OF_RESTRICTED_MATCH_BITMAP_128(v1, v2, mask) \\
+ (OF_RESTRICTED_MATCH_INT((v1)->lo, (v2)->lo, (mask)->lo) && OF_RESTRICTED_MATCH_INT((v1)->hi, (v2)->hi, (mask)->hi))
+
+#define OF_OVERLAP_BITMAP_128(v1, v2, m1, m2) \\
+ (OF_OVERLAP_INT((v1)->lo, (v2)->lo, (m1)->lo, (m2)->lo) && OF_OVERLAP_INT((v1)->hi, (v2)->hi, (m1)->hi, (m2)->hi))
+
/**
* More-specific-than macro for integer types; see above
* @return true if v1 is equal to or more specific than v2
@@ -1136,6 +1147,9 @@
elif entry["m_type"] == "of_mac_addr_t":
comp = "OF_MORE_SPECIFIC_MAC_ADDR"
match_type = "OF_RESTRICTED_MATCH_MAC_ADDR"
+ elif entry["m_type"] == "of_bitmap_128_t":
+ comp = "OF_MORE_SPECIFIC_BITMAP_128"
+ match_type = "OF_RESTRICTED_MATCH_BITMAP_128"
else: # Integer
comp = "OF_MORE_SPECIFIC_INT"
match_type = "OF_RESTRICTED_MATCH_INT"
@@ -1190,6 +1204,8 @@
check = "OF_OVERLAP_IPV6"
elif entry["m_type"] == "of_mac_addr_t":
check = "OF_OVERLAP_MAC_ADDR"
+ elif entry["m_type"] == "of_bitmap_128_t":
+ check = "OF_OVERLAP_BITMAP_128"
else: # Integer
check = "OF_OVERLAP_INT"
m1 = "m1->%s" % key
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index fab9f96..d237cfe 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -98,6 +98,7 @@
of_match_t="match",
# BSN extensions
of_bsn_vport_q_in_q_t="vport",
+ of_bitmap_128_t="bitmap_128",
)
if m_type.find("of_list_") == 0:
@@ -111,7 +112,7 @@
"of_match_bmap_t", "of_ipv4_t"]
string_types = [ "of_port_name_t", "of_table_name_t",
"of_desc_str_t", "of_serial_num_t", "of_mac_addr_t",
- "of_ipv6_t"]
+ "of_ipv6_t", "of_bitmap_128_t"]
scalar_types = integer_types[:]
scalar_types.extend(string_types)
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index a0fec7e..3c523b4 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -507,6 +507,52 @@
}
"""
+ oxm_template = """
+/**
+ * oxm wire type to object ID array.
+ * Treat as private; use function accessor below
+ */
+
+extern const of_object_id_t *const of_oxm_type_to_id[OF_VERSION_ARRAY_MAX];
+
+#define OF_OXM_ITEM_COUNT %(ar_len)d\n
+
+/**
+ * Map an oxm wire value to an OF object
+ * @param oxm The oxm type wire value
+ * @param version The version associated with the check
+ * @return The oxm OF object type
+ * @return OF_OBJECT_INVALID if type does not map to an object
+ *
+ */
+static inline of_object_id_t
+of_oxm_to_object_id(uint32_t type_len, of_version_t version)
+{
+ if (!OF_VERSION_OKAY(version)) {
+ return OF_OBJECT_INVALID;
+ }
+
+ uint16_t class = (type_len >> 16) & 0xffff;
+ uint8_t masked_type = (type_len >> 8) & 0xff;
+
+ if (class == 0x8000) {
+ if (masked_type < 0 || masked_type >= OF_OXM_ITEM_COUNT) {
+ return OF_OBJECT_INVALID;
+ }
+
+ return of_oxm_type_to_id[version][masked_type];
+ } else if (class == 0x0003) {
+ switch (masked_type) {
+ case 0x00: return OF_OXM_BSN_IN_PORTS_128;
+ case 0x01: return OF_OXM_BSN_IN_PORTS_128_MASKED;
+ default: return OF_OBJECT_INVALID;
+ }
+ } else {
+ return OF_OBJECT_INVALID;
+ }
+}
+"""
+
# Action types array gen
ar_len = type_maps.type_array_len(type_maps.action_types, max_type_value)
out.write(map_with_experimenter_template %
@@ -561,13 +607,14 @@
out.write(map_template %
dict(name="flow_mod", u_name="FLOW_MOD", ar_len=ar_len))
+ # OXM
ar_len = type_maps.type_array_len(type_maps.oxm_types, max_type_value)
out.write("""
/* NOTE: We could optimize the OXM and only generate OF 1.2 versions. */
""")
- out.write(map_template %
- dict(name="oxm", u_name="OXM", ar_len=ar_len))
+ out.write(oxm_template % dict(ar_len=ar_len))
+ # Messages
out.write(experimenter_function)
# Must follow stats reply/request
ar_len = type_maps.type_array_len(type_maps.message_types, max_type_value)
@@ -1003,11 +1050,6 @@
extern void of_hello_elem_wire_object_id_get(of_object_t *obj,
of_object_id_t *id);
-/* XXX Hardcoded to the OpenFlow Basic OXM class */
-#define OF_OXM_MASKED_TYPE_GET(hdr) (((hdr) >> 8) & 0xff)
-#define OF_OXM_MASKED_TYPE_SET(hdr, val) \\
- (hdr) = ((hdr) & 0x000000ff) + 0x80000000 + (((val) & 0xff) << 8)
-
#define OF_OXM_LENGTH_GET(hdr) (((hdr) & 0xff) + 4)
#define OF_OXM_LENGTH_SET(hdr, val) \\
(hdr) = ((hdr) & 0xffffff00) + (((val) - 4) & 0xff)
diff --git a/c_gen/templates/loci_dump.h b/c_gen/templates/loci_dump.h
index c2fd53a..d44832a 100644
--- a/c_gen/templates/loci_dump.h
+++ b/c_gen/templates/loci_dump.h
@@ -94,6 +94,8 @@
int loci_dump_match(loci_writer_f writer, void* cookie, of_match_t *match);
#define LOCI_DUMP_match(writer, cookie, val) loci_dump_match(writer, cookie, &val)
+#define LOCI_DUMP_bitmap_128(writer, cookie, val) writer(cookie, "%" PRIx64 "%" PRIx64, (val).hi, (val).lo)
+
/**
* Generic version for any object
*/
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index 948ee92..d2ba8f4 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -162,6 +162,8 @@
int loci_show_match(loci_writer_f writer, void *cookie, of_match_t *match);
#define LOCI_SHOW_match(writer, cookie, val) loci_show_match(writer, cookie, &val)
+#define LOCI_SHOW_bitmap_128(writer, cookie, val) writer(cookie, "%" PRIx64 "%" PRIx64, (val).hi, (val).lo)
+
/**
* Generic version for any object
*/
@@ -337,6 +339,9 @@
#define LOCI_SHOW_ipv4_value_mask(writer, cookie, val) LOCI_SHOW_ipv4(writer, cookie, val)
#define LOCI_SHOW_u8_hybrid_enable(writer, cookie, val) LOCI_SHOW_u8(writer, cookie, val)
#define LOCI_SHOW_u16_hybrid_version(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
+#define LOCI_SHOW_bitmap_128_value(writer, cookie, val) LOCI_SHOW_bitmap_128(writer, cookie, val)
+#define LOCI_SHOW_bitmap_128_value_mask(writer, cookie, val) LOCI_SHOW_bitmap_128(writer, cookie, val)
+#define LOCI_SHOW_bitmap_128_bsn_in_ports_128(writer, cookie, val) LOCI_SHOW_bitmap_128(writer, cookie, val)
#endif /* _LOCI_SHOW_H_ */
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 2c1032d..67c3535 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -559,12 +559,10 @@
of_oxm_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
{
uint32_t type_len;
- int wire_type;
of_wire_buffer_t *wbuf;
_GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
- wire_type = OF_OXM_MASKED_TYPE_GET(type_len);
- *id = of_oxm_to_object_id(wire_type, obj->version);
+ *id = of_oxm_to_object_id(type_len, obj->version);
}
/**
@@ -584,9 +582,21 @@
/* Read-modify-write */
_GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
- wire_type = of_object_to_wire_type(id, obj->version);
- ASSERT(wire_type >= 0);
- OF_OXM_MASKED_TYPE_SET(type_len, wire_type);
+
+ switch (id) {
+ case OF_OXM_BSN_IN_PORTS_128:
+ type_len = 0x00030000 | (type_len & 0xff);
+ break;
+ case OF_OXM_BSN_IN_PORTS_128_MASKED:
+ type_len = 0x00030100 | (type_len & 0xff);
+ break;
+ default:
+ wire_type = of_object_to_wire_type(id, obj->version);
+ ASSERT(wire_type >= 0);
+ type_len = 0x80000000 | (wire_type << 8) | (type_len & 0xff);
+ break;
+ }
+
of_wire_buffer_u32_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), type_len);
}
diff --git a/c_gen/templates/of_wire_buf.h b/c_gen/templates/of_wire_buf.h
index 8750565..117332c 100644
--- a/c_gen/templates/of_wire_buf.h
+++ b/c_gen/templates/of_wire_buf.h
@@ -876,6 +876,30 @@
#define of_wire_buffer_ipv6_set(buf, offset, addr) \
_wbuf_octets_set(buf, offset, (uint8_t *)&addr, sizeof(of_ipv6_t))
+/**
+ * Get an bitmap_128 address from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param addr Pointer to where to store the bitmap_128 address
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_bitmap_128_get(buf, offset, addr) \
+ (of_wire_buffer_u64_get(buf, offset, &addr->hi), of_wire_buffer_u64_get(buf, offset+8, &addr->lo))
+
+/**
+ * Set an bitmap_128 address in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param addr The variable holding bitmap_128 address to store
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_bitmap_128_set(buf, offset, addr) \
+ (of_wire_buffer_u64_set(buf, offset, addr.hi), of_wire_buffer_u64_set(buf, offset+8, addr.lo))
+
/* Relocate data from start offset to the end of the buffer to a new position */
static inline void
of_wire_buffer_move_end(of_wire_buffer_t *wbuf, int start_offset, int new_offset)
diff --git a/loxi_front_end/match.py b/loxi_front_end/match.py
index 20d5030..c510477 100644
--- a/loxi_front_end/match.py
+++ b/loxi_front_end/match.py
@@ -394,6 +394,16 @@
takes_mask_in_spec=False,
order=501,
),
+
+ bsn_in_ports_128 = dict(
+ name="bsn_in_ports_128",
+ m_type="of_bitmap_128_t",
+ v2_wc_shift=9,
+ print_type="p",
+ conditions="",
+ takes_mask_in_spec=True,
+ order=1000,
+ ),
)
match_keys_sorted = of_match_members.keys()
diff --git a/of_g.py b/of_g.py
index 651ee64..c857e65 100644
--- a/of_g.py
+++ b/of_g.py
@@ -302,14 +302,15 @@
# of_match_v4_t = dict(bytes=-1, to_w="match_v4_hton",
# from_w="match_v4_ntoh",
# short_name="match_v4"),
- of_octets_t = dict(bytes=-1, short_name="octets")
+ of_octets_t = dict(bytes=-1, short_name="octets"),
+ of_bitmap_128_t = dict(bytes=16, short_name="bitmap_128"),
)
of_scalar_types = ["char", "uint8_t", "uint16_t", "uint32_t", "uint64_t",
"of_port_no_t", "of_fm_cmd_t", "of_wc_bmap_t",
"of_match_bmap_t", "of_port_name_t", "of_table_name_t",
"of_desc_str_t", "of_serial_num_t", "of_mac_addr_t",
- "of_ipv6_t", "of_ipv4_t"]
+ "of_ipv6_t", "of_ipv4_t", "of_bitmap_128_t"]
base_object_members = """\
/* The control block for the underlying data buffer */
diff --git a/openflow_input/bsn_in_ports b/openflow_input/bsn_in_ports
new file mode 100644
index 0000000..05003b9
--- /dev/null
+++ b/openflow_input/bsn_in_ports
@@ -0,0 +1,61 @@
+// 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 3
+#version 4
+
+/*
+ * Bitmap of input ports
+ *
+ * The representation is not straightforward, but it works with existing OXM
+ * semantics.
+ *
+ * The value should always be zero. The mask should be unset in every bit position
+ * where the corresponding input port is allowed, and set in all other bits.
+ * As a special case, the highest bit in the mask is reserved for higher port
+ * numbers than can be represented in the bitmap.
+ *
+ * The value1 and value_mask1 fields contain the most significant bits. value2
+ * and value_mask2 contain the least significant bits.
+ *
+ * Pseudocode for populating value or mask:
+ * bitmap |= in_port < 128 ? (1 << in_port) : (1 << 127)
+ */
+
+struct of_oxm_bsn_in_ports_128 : of_oxm {
+ uint32_t type_len == 0x00030020;
+ of_bitmap_128_t value;
+};
+
+struct of_oxm_bsn_in_ports_128_masked : of_oxm {
+ uint32_t type_len == 0x00030120;
+ of_bitmap_128_t value;
+ of_bitmap_128_t value_mask;
+};
diff --git a/py_gen/oftype.py b/py_gen/oftype.py
index a6620ab..c378cea 100644
--- a/py_gen/oftype.py
+++ b/py_gen/oftype.py
@@ -101,6 +101,11 @@
pack='%s',
unpack='str(%s.read_all())'),
+ 'of_bitmap_128_t': OFTypeData(
+ init='set()',
+ pack='util.pack_bitmap_128(%s)',
+ unpack="util.unpack_bitmap_128(%s)"),
+
# HACK need the match_v3 length field
'list(of_oxm_t)': OFTypeData(
init='[]',
diff --git a/py_gen/templates/util.py b/py_gen/templates/util.py
index c4de5a3..1566e82 100644
--- a/py_gen/templates/util.py
+++ b/py_gen/templates/util.py
@@ -142,3 +142,23 @@
def pack_list(values):
return "".join([x.pack() for x in values])
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+ x = 0l
+ for y in value:
+ x |= 1 << y
+ return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+ hi, lo = reader.read("!QQ")
+ x = (hi << 64) | lo
+ i = 0
+ value = set()
+ while x != 0:
+ if x & 1 == 1:
+ value.add(i)
+ i += 1
+ x >>= 1
+ return value
diff --git a/test_data/of13/oxm_bsn_in_ports_masked_128.data b/test_data/of13/oxm_bsn_in_ports_masked_128.data
new file mode 100644
index 0000000..0a8e70b
--- /dev/null
+++ b/test_data/of13/oxm_bsn_in_ports_masked_128.data
@@ -0,0 +1,20 @@
+-- binary
+00 03 # class
+01 # type/masked
+20 # length
+00 00 00 00 00 00 00 00 # value
+00 00 00 00 00 00 00 00 # ...
+80 00 00 01 00 00 00 00 # mask
+00 00 00 00 00 02 00 01 # ...
+-- python
+ofp.oxm.bsn_in_ports_128_masked(set(), set([0, 17, 96, 127]))
+-- c
+obj = of_oxm_bsn_in_ports_128_masked_new(OF_VERSION_1_3);
+{
+ of_bitmap_128_t bmap = { 0, 0 };
+ of_oxm_bsn_in_ports_128_masked_value_set(obj, bmap);
+}
+{
+ of_bitmap_128_t bmap = { 0x8000000100000000, 0x00000000020001 };
+ of_oxm_bsn_in_ports_128_masked_value_mask_set(obj, bmap);
+}