Merge pull request #357 from rlane/in_ports_512
bsn_in_ports_512 OXM
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 968d939..a9a0576 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -616,19 +616,26 @@
uint8_t addr[OF_IPV6_BYTES];
} of_ipv6_t;
+typedef struct of_bitmap_512_s {
+ uint64_t words[8];
+} of_bitmap_512_t;
+
extern const of_mac_addr_t of_mac_addr_all_ones;
-extern const of_mac_addr_t of_mac_addr_all_zeros;
+extern const of_mac_addr_t of_mac_addr_all_zeroes;
extern const of_ipv6_t of_ipv6_all_ones;
extern const of_ipv6_t of_ipv6_all_zeros;
+extern const of_bitmap_512_t of_bitmap_512_all_ones;
+extern const of_bitmap_512_t of_bitmap_512_all_zeroes;
+
/**
* Generic zero and all-ones values of size 16 bytes.
*
- * IPv6 is longest data type we worry about for comparisons
+ * bitmap_512 is longest data type we worry about for comparisons
*/
-#define of_all_zero_value of_ipv6_all_zeros
-#define of_all_ones_value of_ipv6_all_ones
+#define of_all_zero_value of_bitmap_512_all_zeroes
+#define of_all_ones_value of_bitmap_512_all_ones
/**
* Non-zero/all ones check for arbitrary type of size <= 16 bytes
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index a703e4f..ccc503d 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -963,55 +963,31 @@
*/
static inline int
-of_match_more_specific(of_match_t *entry, of_match_t *query)
+of_match_more_specific(const of_match_t *entry, const of_match_t *query)
{
- of_match_fields_t *q_m, *e_m; /* Short hand for masks, fields */
- of_match_fields_t *q_f, *e_f;
+ LOCI_ASSERT(sizeof(of_match_fields_t) % sizeof(uint8_t) == 0);
- q_m = &query->masks;
- e_m = &entry->masks;
- q_f = &query->fields;
- e_f = &entry->fields;
-""")
- for key, entry in match.of_match_members.items():
- q_m = "&q_m->%s" % key
- e_m = "&e_m->%s" % key
- q_f = "&q_f->%s" % key
- e_f = "&e_f->%s" % key
- if entry["m_type"] == "of_ipv6_t":
- comp = "OF_MORE_SPECIFIC_IPV6"
- match_type = "OF_RESTRICTED_MATCH_IPV6"
- 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"
- q_m = "q_m->%s" % key
- e_m = "e_m->%s" % key
- q_f = "q_f->%s" % key
- e_f = "e_f->%s" % key
- out.write("""
- /* Mask and values for %(key)s */
- if (!%(comp)s(%(e_m)s, %(q_m)s)) {
- return 0;
- }
- if (!%(match_type)s(%(e_f)s, %(q_f)s,
- %(q_m)s)) {
- return 0;
- }
-""" % dict(match_type=match_type, comp=comp, q_f=q_f, e_f=e_f,
- q_m=q_m, e_m=e_m, key=key))
+ /* Short hand for masks, fields */
+ const uint8_t *qm = (const uint8_t *)&query->masks;
+ const uint8_t *em = (const uint8_t *)&entry->masks;
+ const uint8_t *qf = (const uint8_t *)&query->fields;
+ const uint8_t *ef = (const uint8_t *)&entry->fields;
- out.write("""
+ int i;
+ for (i = 0; i < sizeof(of_match_fields_t)/sizeof(uint8_t); i++) {
+ if (qm[i] & ~em[i]) {
+ /* Query mask has a bit set that isn't set in the entry mask */
+ return 0;
+ }
+
+ if ((qf[i] ^ ef[i]) & qm[i]) {
+ /* Query and entry disagree on a field bit */
+ return 0;
+ }
+ }
+
return 1;
}
-""")
-
- out.write("""
/**
* Do two entries overlap?
@@ -1022,42 +998,24 @@
*/
static inline int
-of_match_overlap(of_match_t *match1, of_match_t *match2)
+of_match_overlap(const of_match_t *match1, const of_match_t *match2)
{
- of_match_fields_t *m1, *m2; /* Short hand for masks, fields */
- of_match_fields_t *f1, *f2;
+ LOCI_ASSERT(sizeof(of_match_fields_t) % sizeof(uint8_t) == 0);
- m1 = &match1->masks;
- m2 = &match2->masks;
- f1 = &match1->fields;
- f2 = &match2->fields;
-""")
- for key, entry in match.of_match_members.items():
- m1 = "&m1->%s" % key
- m2 = "&m2->%s" % key
- f1 = "&f1->%s" % key
- f2 = "&f2->%s" % key
- if entry["m_type"] == "of_ipv6_t":
- 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
- m2 = "m2->%s" % key
- f1 = "f1->%s" % key
- f2 = "f2->%s" % key
- out.write("""
- /* Check overlap for %(key)s */
- if (!%(check)s(%(f1)s, %(f2)s,
- %(m2)s, %(m1)s)) {
- return 0; /* This field differentiates; all done */
+ /* Short hand for masks, fields */
+ const uint8_t *m1 = (const uint8_t *)&match1->masks;
+ const uint8_t *m2 = (const uint8_t *)&match2->masks;
+ const uint8_t *f1 = (const uint8_t *)&match1->fields;
+ const uint8_t *f2 = (const uint8_t *)&match2->fields;
+
+ int i;
+ for (i = 0; i < sizeof(of_match_fields_t)/sizeof(uint8_t); i++) {
+ if ((f1[i] ^ f2[i]) & (m1[i] & m2[i])) {
+ /* Matches disagree on a field bit they both qualify on */
+ return 0;
+ }
}
-""" % dict(check=check, f1=f1, f2=f2, m1=m1, m2=m2, key=key))
- out.write("""
return 1; /* No field differentiates matches */
}
""")
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 109ab9b..6e88d6d 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -105,6 +105,7 @@
# BSN extensions
of_bsn_vport_q_in_q_t="vport",
of_bitmap_128_t="bitmap_128",
+ of_bitmap_512_t="bitmap_512",
of_checksum_128_t="checksum_128",
)
@@ -120,7 +121,7 @@
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_bitmap_128_t", "of_checksum_128_t",
- "of_str64_t"]
+ "of_str64_t", "of_bitmap_512_t"]
scalar_types = integer_types[:]
scalar_types.extend(string_types)
diff --git a/c_gen/of_g_legacy.py b/c_gen/of_g_legacy.py
index 87e0680..9c0722c 100644
--- a/c_gen/of_g_legacy.py
+++ b/c_gen/of_g_legacy.py
@@ -213,6 +213,7 @@
# short_name="match_v4"),
of_octets_t = dict(bytes=-1, short_name="octets"),
of_bitmap_128_t = dict(bytes=16, short_name="bitmap_128"),
+ of_bitmap_512_t = dict(bytes=64, short_name="bitmap_512"),
of_checksum_128_t = dict(bytes=16, short_name="checksum_128"),
)
@@ -221,7 +222,7 @@
"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_bitmap_128_t", "of_checksum_128_t",
- "of_str64_t"]
+ "of_str64_t", "of_bitmap_512_t"]
##
# LOXI identifiers
diff --git a/c_gen/templates/loci_dump.h b/c_gen/templates/loci_dump.h
index 1344565..89c5f2a 100644
--- a/c_gen/templates/loci_dump.h
+++ b/c_gen/templates/loci_dump.h
@@ -99,6 +99,8 @@
#define LOCI_DUMP_checksum_128(writer, cookie, val) writer(cookie, "%016" PRIx64 "%016" PRIx64, (val).hi, (val).lo)
+#define LOCI_DUMP_bitmap_512(writer, cookie, val) writer(cookie, "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64, (val).words[7], (val).words[6], (val).words[5], (val).words[4], (val).words[3], (val).words[2], (val).words[1], (val).words[0])
+
/**
* Generic version for any object
*/
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index a227645..dc35959 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -113,6 +113,8 @@
#define LOCI_SHOW_checksum_128(writer, cookie, val) writer(cookie, "%016" PRIx64 "%016" PRIx64, (val).hi, (val).lo)
+#define LOCI_SHOW_bitmap_512(writer, cookie, val) writer(cookie, "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64 "%" PRIx64, (val).words[7], (val).words[6], (val).words[5], (val).words[4], (val).words[3], (val).words[2], (val).words[1], (val).words[0])
+
/**
* Generic version for any object
*/
diff --git a/c_gen/templates/loci_strings.c b/c_gen/templates/loci_strings.c
index f546e12..165bf56 100644
--- a/c_gen/templates/loci_strings.c
+++ b/c_gen/templates/loci_strings.c
@@ -69,6 +69,12 @@
}
};
+const of_bitmap_512_t of_bitmap_512_all_ones = {
+ { -1, -1, -1, -1, -1, -1, -1, -1, }
+};
+
+const of_bitmap_512_t of_bitmap_512_all_zeroes;
+
/** @var of_error_strings
* The error string map; use abs value to index
*/
diff --git a/c_gen/templates/of_wire_buf.h b/c_gen/templates/of_wire_buf.h
index 3d38f53..9ade2c4 100644
--- a/c_gen/templates/of_wire_buf.h
+++ b/c_gen/templates/of_wire_buf.h
@@ -888,6 +888,45 @@
#define of_wire_buffer_checksum_128_set(buf, offset, checksum) \
(of_wire_buffer_u64_set(buf, offset, checksum.hi), of_wire_buffer_u64_set(buf, offset+8, checksum.lo))
+
+/**
+ * Get a bitmap_512 from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_bitmap_512_get(of_wire_buffer_t *wbuf, int offset, of_bitmap_512_t *value)
+{
+ OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(of_bitmap_512_t));
+ int i;
+ for (i = 0; i < 8; i++) {
+ buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset+i*8), &value->words[i]);
+ }
+}
+
+/**
+ * Set a bitmap_512 in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_bitmap_512_set(of_wire_buffer_t *wbuf, int offset, of_bitmap_512_t value)
+{
+ OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(of_bitmap_512_t));
+ int i;
+ for (i = 0; i < 8; i++) {
+ buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset+i*8), value.words[i]);
+ }
+}
+
/* 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_ir/ir_offset.py b/loxi_ir/ir_offset.py
index db55f24..5eff8e0 100644
--- a/loxi_ir/ir_offset.py
+++ b/loxi_ir/ir_offset.py
@@ -109,6 +109,7 @@
of_octets_t = (0, False),
of_bitmap_128_t = (16, True),
of_checksum_128_t = (16, True),
+ of_bitmap_512_t = (64, True),
)
def type_dec_to_count_base(m_type):
diff --git a/openflow_input/bsn_in_ports b/openflow_input/bsn_in_ports
index 819bdde..bb4c030 100644
--- a/openflow_input/bsn_in_ports
+++ b/openflow_input/bsn_in_ports
@@ -60,3 +60,14 @@
of_bitmap_128_t value;
of_bitmap_128_t value_mask;
};
+
+struct of_oxm_bsn_in_ports_512 : of_oxm {
+ uint32_t type_len == 0x00032640;
+ of_bitmap_512_t value;
+};
+
+struct of_oxm_bsn_in_ports_512_masked : of_oxm {
+ uint32_t type_len == 0x00032780;
+ of_bitmap_512_t value;
+ of_bitmap_512_t value_mask;
+};
diff --git a/py_gen/oftype.py b/py_gen/oftype.py
index 51b8e13..3893865 100644
--- a/py_gen/oftype.py
+++ b/py_gen/oftype.py
@@ -116,6 +116,11 @@
init='0',
pack='util.pack_checksum_128(%s)',
unpack="util.unpack_checksum_128(%s)"),
+
+ 'of_bitmap_512_t': OFTypeData(
+ init='set()',
+ pack='util.pack_bitmap_512(%s)',
+ unpack="util.unpack_bitmap_512(%s)"),
}
## Fixed length strings
diff --git a/py_gen/templates/util.py b/py_gen/templates/util.py
index 85181dc..7558576 100644
--- a/py_gen/templates/util.py
+++ b/py_gen/templates/util.py
@@ -173,6 +173,28 @@
x >>= 1
return value
+def pack_bitmap_512(value):
+ words = [0] * 8
+ for v in value:
+ assert v < 512
+ words[7-v/64] |= 1 << (v % 64)
+ return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+ words = reader.read("!8Q")
+ x = 0l
+ for word in words:
+ x <<= 64
+ x |= word
+ i = 0
+ value = set()
+ while x != 0:
+ if x & 1 == 1:
+ value.add(i)
+ i += 1
+ x >>= 1
+ return value
+
def pack_checksum_128(value):
return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
diff --git a/py_gen/tests/of13.py b/py_gen/tests/of13.py
index c5a16b2..c99ee34 100644
--- a/py_gen/tests/of13.py
+++ b/py_gen/tests/of13.py
@@ -126,5 +126,18 @@
else:
fn()
+class TestUtils(unittest.TestCase):
+ def check_bitmap_512(self, value, data):
+ self.assertEquals(data, ofp.util.pack_bitmap_512(set(value)))
+ self.assertEquals(ofp.util.unpack_bitmap_512(OFReader(data)), set(value))
+
+ def test_bitmap_512(self):
+ self.check_bitmap_512([0], "\x00" * 63 + "\x01")
+ self.check_bitmap_512([8], "\x00" * 62 + "\x01\x00")
+ self.check_bitmap_512([63], "\x00" * 56 + "\x80" + "\x00" * 7)
+ self.check_bitmap_512([64], "\x00" * 55 + "\x01" + "\x00" * 8)
+ self.check_bitmap_512([511], "\x80" + "\x00" * 63)
+ self.check_bitmap_512([5, 67, 90], "\x00" * 52 + "\x04\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x20")
+
if __name__ == '__main__':
unittest.main()
diff --git a/test_data/of13/oxm_bsn_in_ports_masked_512.data b/test_data/of13/oxm_bsn_in_ports_masked_512.data
new file mode 100644
index 0000000..82cc45c
--- /dev/null
+++ b/test_data/of13/oxm_bsn_in_ports_masked_512.data
@@ -0,0 +1,36 @@
+-- binary
+00 03 # class
+27 # type/masked
+80 # length
+00 00 00 00 00 00 00 00 # value
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+00 00 00 00 00 00 00 00 # ...
+7f ff ff ff ff ff ff ff # mask - Only ports 0, 17, 96, 511 are selected (and thus are zero)
+ff ff ff ff ff ff ff ff # ...
+ff ff ff ff ff ff ff ff # ...
+ff ff ff ff ff ff ff ff # ...
+ff ff ff ff ff ff ff ff # ...
+ff ff ff ff ff ff ff ff # ...
+ff ff ff fe ff ff ff ff # ...
+ff ff ff ff ff fd ff fe # ...
+-- python
+ofp.oxm.bsn_in_ports_512_masked(set(), set(range(0,512)) - set((0, 17, 96, 511)))
+-- c
+obj = of_oxm_bsn_in_ports_512_masked_new(OF_VERSION_1_3);
+{
+ of_bitmap_512_t bmap = { { 0, 0, 0, 0, 0, 0, 0, 0 } };
+ of_oxm_bsn_in_ports_512_masked_value_set(obj, bmap);
+}
+{
+ of_bitmap_512_t bmap = { { 0x7fffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffeffffffff, 0xfffffffffffdfffe } };
+ of_oxm_bsn_in_ports_512_masked_value_mask_set(obj, bmap);
+}
+-- java
+OFPortMap portmap = OFPortMap.ofPorts(OFPort.of(0), OFPort.of(17), OFPort.of(96));
+builder.setValue(portmap.getValue());
+builder.setMask(portmap.getMask());
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index 48cb447..ad0f0c2 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -49,6 +49,10 @@
read_scalar(reader, subtree, field_name, 16)
end
+function read_of_bitmap_512_t(reader, version, subtree, field_name)
+ read_scalar(reader, subtree, field_name, 64)
+end
+
function read_of_checksum_128_t(reader, version, subtree, field_name)
read_scalar(reader, subtree, field_name, 16)
end