loci: replace generated match more_specific/overlap code with simple loop
This removes the need to define more-specific/overlap macros for every type. We
can assume that any padding is initialized to zero.
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 */
}
""")