Merge into master from pull request #372:
In ports 512 - merge into master (https://github.com/floodlight/loxigen/pull/372)
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 5342a42..955f34f 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/java_gen/java_type.py b/java_gen/java_type.py
index 3f3a5f2..dbb87eb 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -449,10 +449,14 @@
table_stats_wildcards = JType("int") \
.op(read='bb.readInt()',
write='bb.writeInt($name)')
-port_bitmap = JType('OFBitMask128') \
+port_bitmap_128 = JType('OFBitMask128') \
.op(read='OFBitMask128.read16Bytes(bb)',
write='$name.write16Bytes(bb)',
default='OFBitMask128.NONE')
+port_bitmap_512 = JType('OFBitMask512') \
+ .op(read='OFBitMask512.read64Bytes(bb)',
+ write='$name.write64Bytes(bb)',
+ default='OFBitMask512.NONE')
table_id = JType("TableId") \
.op(read='TableId.readByte(bb)',
write='$name.writeByte(bb)',
@@ -573,7 +577,8 @@
'of_wc_bmap_t': flow_wildcards,
'of_oxm_t': oxm,
'of_meter_features_t': meter_features,
- 'of_bitmap_128_t': port_bitmap,
+ 'of_bitmap_128_t': port_bitmap_128,
+ 'of_bitmap_512_t': port_bitmap_512,
'of_checksum_128_t': u128,
'of_bsn_vport_t': bsn_vport,
'of_table_desc_t': table_desc,
@@ -637,8 +642,11 @@
'of_oxm_pbb_uca' : { 'value' : boolean_value },
'of_oxm_pbb_uca_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
- 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap },
- 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap, 'value_mask': port_bitmap },
+ 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap_128 },
+ 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap_128, 'value_mask': port_bitmap_128 },
+
+ 'of_oxm_bsn_in_ports_512' : { 'value': port_bitmap_512 },
+ 'of_oxm_bsn_in_ports_512_masked' : { 'value': port_bitmap_512, 'value_mask': port_bitmap_512 },
'of_oxm_bsn_lag_id' : { 'value' : lag_id },
'of_oxm_bsn_lag_id_masked' : { 'value' : lag_id, 'value_mask' : lag_id },
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index e956f78..931211f 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -14,6 +14,7 @@
import org.projectfloodlight.openflow.types.LagId;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.OFBitMask128;
+import org.projectfloodlight.openflow.types.OFBitMask512;
import org.projectfloodlight.openflow.types.OFBooleanValue;
import org.projectfloodlight.openflow.types.OFMetadata;
import org.projectfloodlight.openflow.types.OFPort;
@@ -182,7 +183,7 @@
new MatchField<OFBooleanValue>("mpls_bos", MatchFields.MPLS_BOS,
new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
- public final static MatchField<U64> TUNNEL_ID =
+ public final static MatchField<U64> TUNNEL_ID =
new MatchField<U64>("tunnel_id", MatchFields.TUNNEL_ID);
public final static MatchField<U16> IPV6_EXTHDR =
@@ -190,7 +191,7 @@
public final static MatchField<OFBooleanValue> PBB_UCA =
new MatchField<OFBooleanValue>("pbb_uca", MatchFields.PBB_UCA);
-
+
public final static MatchField<IPv4Address> TUNNEL_IPV4_SRC =
new MatchField<IPv4Address>("tunnel_ipv4_src", MatchFields.TUNNEL_IPV4_SRC,
new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.IPv4));
@@ -202,6 +203,9 @@
public final static MatchField<OFBitMask128> BSN_IN_PORTS_128 =
new MatchField<OFBitMask128>("bsn_in_ports_128", MatchFields.BSN_IN_PORTS_128);
+ public final static MatchField<OFBitMask512> BSN_IN_PORTS_512 =
+ new MatchField<OFBitMask512>("bsn_in_ports_512", MatchFields.BSN_IN_PORTS_512);
+
public final static MatchField<LagId> BSN_LAG_ID =
new MatchField<LagId>("bsn_lag_id", MatchFields.BSN_LAG_ID);
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index 28b6f8c..3a0ec89 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -45,6 +45,7 @@
TUNNEL_IPV4_SRC,
TUNNEL_IPV4_DST,
BSN_IN_PORTS_128,
+ BSN_IN_PORTS_512,
BSN_LAG_ID,
BSN_VRF,
BSN_GLOBAL_VRF_ALLOWED,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
new file mode 100644
index 0000000..3fe9b88
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
@@ -0,0 +1,205 @@
+package org.projectfloodlight.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import com.google.common.hash.PrimitiveSink;
+
+public class OFBitMask512 implements OFValueType<OFBitMask512> {
+
+ static final int LENGTH = 64;
+
+ private final long raw1;
+ private final long raw2;
+ private final long raw3;
+ private final long raw4;
+ private final long raw5;
+ private final long raw6;
+ private final long raw7;
+ private final long raw8;
+
+ public static final OFBitMask512 ALL = new OFBitMask512(-1, -1, -1, -1,
+ -1, -1, -1, -1);
+ public static final OFBitMask512 NONE = new OFBitMask512(0, 0, 0, 0,
+ 0, 0, 0, 0);
+
+ public static final OFBitMask512 NO_MASK = ALL;
+ public static final OFBitMask512 FULL_MASK = NONE;
+
+ private OFBitMask512(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8) {
+ this.raw1 = raw1;
+ this.raw2 = raw2;
+ this.raw3 = raw3;
+ this.raw4 = raw4;
+ this.raw5 = raw5;
+ this.raw6 = raw6;
+ this.raw7 = raw7;
+ this.raw8 = raw8;
+ }
+
+ public static OFBitMask512 of(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8) {
+ if (raw1 == -1 && raw2 == -1 && raw3 == -1 && raw4 == -1
+ && raw5 == -1 && raw6 == -1 && raw7 == -1 && raw8 == -1)
+ return ALL;
+ if (raw1 == 0 && raw2 == 0 && raw3 == 0 && raw4 == 0
+ && raw5 == 0 && raw6 == 0 && raw7 == 0 && raw8 == 0)
+ return NONE;
+ return new OFBitMask512(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+ @Override
+ public OFBitMask512 applyMask(OFBitMask512 mask) {
+ return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2,
+ this.raw3 & mask.raw3, this.raw4 & mask.raw4,
+ this.raw5 & mask.raw5, this.raw6 & mask.raw6,
+ this.raw7 & mask.raw7, this.raw8 & mask.raw8);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (raw1 ^ (raw1 >>> 32));
+ result = prime * result + (int) (raw2 ^ (raw2 >>> 32));
+ result = prime * result + (int) (raw3 ^ (raw3 >>> 32));
+ result = prime * result + (int) (raw4 ^ (raw4 >>> 32));
+ result = prime * result + (int) (raw5 ^ (raw5 >>> 32));
+ result = prime * result + (int) (raw6 ^ (raw6 >>> 32));
+ result = prime * result + (int) (raw7 ^ (raw7 >>> 32));
+ result = prime * result + (int) (raw8 ^ (raw8 >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ OFBitMask512 other = (OFBitMask512) obj;
+ if (raw1 != other.raw1) return false;
+ if (raw2 != other.raw2) return false;
+ if (raw3 != other.raw3) return false;
+ if (raw4 != other.raw4) return false;
+ if (raw5 != other.raw5) return false;
+ if (raw6 != other.raw6) return false;
+ if (raw7 != other.raw7) return false;
+ if (raw8 != other.raw8) return false;
+ return true;
+ }
+
+ protected static boolean isBitOn(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8, int bit) {
+ if (bit < 0 || bit >= 512)
+ throw new IndexOutOfBoundsException();
+ long word;
+ if (bit < 64) {
+ word = raw8;
+ } else if (bit < 128) {
+ word = raw7;
+ bit -= 64;
+ } else if (bit < 128) {
+ word = raw6;
+ bit -= 128;
+ } else if (bit < 128) {
+ word = raw5;
+ bit -= 192;
+ } else if (bit < 128) {
+ word = raw4;
+ bit -= 256;
+ } else if (bit < 128) {
+ word = raw3;
+ bit -= 320;
+ } else if (bit < 128) {
+ word = raw2;
+ bit -= 384;
+ } else {
+ word = raw1;
+ bit -= 448;
+ }
+ return (word & ((long)1 << bit)) != 0;
+ }
+
+ public void write64Bytes(ChannelBuffer cb) {
+ cb.writeLong(raw1);
+ cb.writeLong(raw2);
+ cb.writeLong(raw3);
+ cb.writeLong(raw4);
+ cb.writeLong(raw5);
+ cb.writeLong(raw6);
+ cb.writeLong(raw7);
+ cb.writeLong(raw8);
+ }
+
+ public static OFBitMask512 read64Bytes(ChannelBuffer cb) {
+ long raw1 = cb.readLong();
+ long raw2 = cb.readLong();
+ long raw3 = cb.readLong();
+ long raw4 = cb.readLong();
+ long raw5 = cb.readLong();
+ long raw6 = cb.readLong();
+ long raw7 = cb.readLong();
+ long raw8 = cb.readLong();
+ return of(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+ }
+
+ public boolean isOn(int bit) {
+ return isBitOn(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8, bit);
+ }
+
+ @Override
+ public String toString() {
+ return (String.format("%64s", Long.toBinaryString(raw8))
+ + String.format("%64s", Long.toBinaryString(raw7))
+ + String.format("%64s", Long.toBinaryString(raw6))
+ + String.format("%64s", Long.toBinaryString(raw5))
+ + String.format("%64s", Long.toBinaryString(raw4))
+ + String.format("%64s", Long.toBinaryString(raw3))
+ + String.format("%64s", Long.toBinaryString(raw2))
+ + String.format("%64s", Long.toBinaryString(raw1))).replaceAll(" ", "0");
+ }
+
+ @Override
+ public int compareTo(OFBitMask512 o) {
+ long c = this.raw1 - o.raw1;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw2 - o.raw2;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw3 - o.raw3;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw4 - o.raw4;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw5 - o.raw5;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw6 - o.raw6;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw7 - o.raw7;
+ if (c != 0)
+ return Long.signum(c);
+ return Long.signum(this.raw8 - o.raw8);
+ }
+
+ @Override
+ public void putTo(PrimitiveSink sink) {
+ sink.putLong(raw1);
+ sink.putLong(raw2);
+ sink.putLong(raw3);
+ sink.putLong(raw4);
+ sink.putLong(raw5);
+ sink.putLong(raw6);
+ sink.putLong(raw7);
+ sink.putLong(raw8);
+ }
+
+}
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