Merge into master from pull request #107:
Verifiy configuration flag (https://github.com/floodlight/oftest/pull/107)
diff --git a/oft b/oft
index 8a7272b..9d5df6a 100755
--- a/oft
+++ b/oft
@@ -77,14 +77,17 @@
"log_file" : "oft.log",
"log_dir" : None,
"debug" : "verbose",
+ "profile" : False,
# Test behavior options
"relax" : False,
"test_params" : "None",
"fail_skipped" : False,
- "default_timeout" : 2,
+ "default_timeout" : 2.0,
+ "default_negative_timeout" : 0.01,
"minsize" : 0,
"random_seed" : None,
+ "disable_ipv6" : False,
# Other configuration
"port_map" : {},
@@ -178,6 +181,7 @@
const="verbose", help="Shortcut for --debug=verbose")
group.add_option("-q", "--quiet", action="store_const", dest="debug",
const="warning", help="Shortcut for --debug=warning")
+ group.add_option("--profile", action="store_true", help="Write Python profile to profile.out")
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "Test behavior options")
@@ -188,12 +192,16 @@
group.add_option("-t", "--test-params", help=test_params_help)
group.add_option("--fail-skipped", action="store_true",
help="Return failure if any test was skipped")
- group.add_option("--default-timeout", type="int",
+ group.add_option("--default-timeout", type=float,
help="Timeout in seconds for most operations")
+ group.add_option("--default-negative-timeout", type=float,
+ help="Timeout in seconds for negative checks")
group.add_option("--minsize", type="int",
help="Minimum allowable packet size on the dataplane.")
group.add_option("--random-seed", type="int",
help="Random number generator seed")
+ group.add_option("--disable-ipv6", action="store_true",
+ help="Disable IPv6 tests")
parser.add_option_group(group)
# Might need this if other parsers want command line
@@ -488,6 +496,7 @@
logging.info("OF port map: " + str(config["port_map"]))
oftest.ofutils.default_timeout = config["default_timeout"]
+oftest.ofutils.default_negative_timeout = config["default_negative_timeout"]
oftest.testutils.MINSIZE = config['minsize']
if os.getuid() != 0 and not config["allow_user"]:
@@ -509,6 +518,11 @@
signal.signal(signal.SIGINT, signal.SIG_DFL)
if __name__ == "__main__":
+ if config["profile"]:
+ import cProfile
+ profiler = cProfile.Profile()
+ profiler.enable()
+
# Set up the dataplane
oftest.dataplane_instance = oftest.dataplane.DataPlane(config)
pcap_setup(config)
@@ -529,6 +543,10 @@
oftest.dataplane_instance.kill()
oftest.dataplane_instance = None
+ if config["profile"]:
+ profiler.disable()
+ profiler.dump_stats("profile.out")
+
if result.failures or result.errors:
# exit(1) hangs sometimes
os._exit(1)
diff --git a/src/python/loxi/of12/oxm.py b/src/python/loxi/of12/oxm.py
index f116d1a..9f12fc9 100644
--- a/src/python/loxi/of12/oxm.py
+++ b/src/python/loxi/of12/oxm.py
@@ -517,6 +517,98 @@
oxm.subtypes[2147495688] = arp_tpa_masked
+class bsn_egr_port_group_id(oxm):
+ type_len = 200196
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!L", self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_egr_port_group_id()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 200196)
+ obj.value = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.value != other.value: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_egr_port_group_id {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+ type_len = 200456
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!L", self.value))
+ packed.append(struct.pack("!L", self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_egr_port_group_id_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 200456)
+ obj.value = reader.read("!L")[0]
+ obj.value_mask = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.value != other.value: return False
+ if self.value_mask != other.value_mask: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_egr_port_group_id_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text("%#x" % self.value_mask)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
class bsn_global_vrf_allowed(oxm):
type_len = 198145
diff --git a/src/python/loxi/of13/action_id.py b/src/python/loxi/of13/action_id.py
index e0e495e..b1519f0 100644
--- a/src/python/loxi/of13/action_id.py
+++ b/src/python/loxi/of13/action_id.py
@@ -35,7 +35,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -52,7 +51,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -140,7 +138,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!L", self.subtype))
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -161,7 +158,6 @@
_experimenter = reader.read("!L")[0]
assert(_experimenter == 6035143)
obj.subtype = reader.read("!L")[0]
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -193,7 +189,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!L", self.subtype))
- packed.append('\x00' * 3)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -210,7 +205,6 @@
assert(_experimenter == 6035143)
_subtype = reader.read("!L")[0]
assert(_subtype == 1)
- reader.skip(3)
return obj
def __eq__(self, other):
@@ -283,7 +277,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -296,7 +289,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -323,7 +315,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -336,7 +327,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -363,7 +353,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -376,7 +365,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -403,7 +391,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -416,7 +403,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -490,8 +476,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!H", self.subtype))
- packed.append('\x00' * 2)
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -512,8 +496,6 @@
_experimenter = reader.read("!L")[0]
assert(_experimenter == 8992)
obj.subtype = reader.read("!H")[0]
- reader.skip(2)
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -545,8 +527,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!H", self.subtype))
- packed.append('\x00' * 2)
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -563,8 +543,6 @@
assert(_experimenter == 8992)
_subtype = reader.read("!H")[0]
assert(_subtype == 18)
- reader.skip(2)
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -591,7 +569,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 6)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -604,7 +581,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(6)
return obj
def __eq__(self, other):
@@ -631,7 +607,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 2)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -644,7 +619,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(2)
return obj
def __eq__(self, other):
@@ -671,7 +645,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -684,7 +657,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -711,7 +683,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -724,7 +695,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -751,7 +721,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 2)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -764,7 +733,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(2)
return obj
def __eq__(self, other):
@@ -791,7 +759,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 2)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -804,7 +771,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(2)
return obj
def __eq__(self, other):
@@ -831,7 +797,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 2)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -844,7 +809,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(2)
return obj
def __eq__(self, other):
@@ -909,7 +873,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 3)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -922,7 +885,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(3)
return obj
def __eq__(self, other):
@@ -949,7 +911,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 3)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -962,7 +923,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(3)
return obj
def __eq__(self, other):
diff --git a/src/python/loxi/of13/bsn_tlv.py b/src/python/loxi/of13/bsn_tlv.py
index dd3eced..f169a6d 100644
--- a/src/python/loxi/of13/bsn_tlv.py
+++ b/src/python/loxi/of13/bsn_tlv.py
@@ -114,6 +114,53 @@
bsn_tlv.subtypes[10] = broadcast_query_timeout
+class circuit_id(bsn_tlv):
+ type = 14
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = ''
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+ packed.append(self.value)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = circuit_id()
+ _type = reader.read("!H")[0]
+ assert(_type == 14)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.value = str(reader.read_all())
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.value != other.value: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("circuit_id {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.pp(self.value)
+ q.breakable()
+ q.text('}')
+
+bsn_tlv.subtypes[14] = circuit_id
+
class idle_notification(bsn_tlv):
type = 7
diff --git a/src/python/loxi/of13/common.py b/src/python/loxi/of13/common.py
index be5f8cd..c206d24 100644
--- a/src/python/loxi/of13/common.py
+++ b/src/python/loxi/of13/common.py
@@ -88,6 +88,42 @@
q.text('}')
+class bsn_flow_checksum_bucket_stats_entry(loxi.OFObject):
+
+ def __init__(self, checksum=None):
+ if checksum != None:
+ self.checksum = checksum
+ else:
+ self.checksum = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!Q", self.checksum))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_flow_checksum_bucket_stats_entry()
+ obj.checksum = reader.read("!Q")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.checksum != other.checksum: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_flow_checksum_bucket_stats_entry {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("checksum = ");
+ q.text("%#x" % self.checksum)
+ q.breakable()
+ q.text('}')
+
+
class bsn_gentable_bucket_stats_entry(loxi.OFObject):
def __init__(self, checksum=None):
@@ -684,6 +720,52 @@
q.text('}')
+class bsn_table_checksum_stats_entry(loxi.OFObject):
+
+ def __init__(self, table_id=None, checksum=None):
+ if table_id != None:
+ self.table_id = table_id
+ else:
+ self.table_id = 0
+ if checksum != None:
+ self.checksum = checksum
+ else:
+ self.checksum = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.table_id))
+ packed.append(struct.pack("!Q", self.checksum))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_table_checksum_stats_entry()
+ obj.table_id = reader.read("!B")[0]
+ obj.checksum = reader.read("!Q")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.table_id != other.table_id: return False
+ if self.checksum != other.checksum: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_table_checksum_stats_entry {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("table_id = ");
+ q.text("%#x" % self.table_id)
+ q.text(","); q.breakable()
+ q.text("checksum = ");
+ q.text("%#x" % self.checksum)
+ q.breakable()
+ q.text('}')
+
+
class bsn_vport(loxi.OFObject):
subtypes = {}
@@ -1002,56 +1084,6 @@
q.text('}')
-class experimenter_stats_header(loxi.OFObject):
- subtypes = {}
-
-
- def __init__(self, experimenter=None, subtype=None):
- if experimenter != None:
- self.experimenter = experimenter
- else:
- self.experimenter = 0
- if subtype != None:
- self.subtype = subtype
- else:
- self.subtype = 0
- return
-
- def pack(self):
- packed = []
- packed.append(struct.pack("!L", self.experimenter))
- packed.append(struct.pack("!L", self.subtype))
- return ''.join(packed)
-
- @staticmethod
- def unpack(reader):
- subtype, = reader.peek('!L', 0)
- subclass = experimenter_stats_header.subtypes.get(subtype)
- if subclass:
- return subclass.unpack(reader)
-
- obj = experimenter_stats_header()
- obj.experimenter = reader.read("!L")[0]
- obj.subtype = reader.read("!L")[0]
- return obj
-
- def __eq__(self, other):
- if type(self) != type(other): return False
- if self.experimenter != other.experimenter: return False
- if self.subtype != other.subtype: return False
- return True
-
- def pretty_print(self, q):
- q.text("experimenter_stats_header {")
- with q.group():
- with q.indent(2):
- q.breakable()
- q.text("subtype = ");
- q.text("%#x" % self.subtype)
- q.breakable()
- q.text('}')
-
-
class flow_stats_entry(loxi.OFObject):
def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
@@ -2740,7 +2772,7 @@
table_feature_prop.subtypes[15] = table_feature_prop_apply_setfield_miss
class table_feature_prop_experimenter(table_feature_prop):
- type = 65535
+ type = 65534
def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
if experimenter != None:
@@ -2772,7 +2804,7 @@
def unpack(reader):
obj = table_feature_prop_experimenter()
_type = reader.read("!H")[0]
- assert(_type == 65535)
+ assert(_type == 65534)
_length = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_length - (2 + 2))
@@ -2804,7 +2836,74 @@
q.breakable()
q.text('}')
-table_feature_prop.subtypes[65535] = table_feature_prop_experimenter
+table_feature_prop.subtypes[65534] = table_feature_prop_experimenter
+
+class table_feature_prop_experimenter_miss(table_feature_prop):
+ type = 65535
+
+ def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+ if experimenter != None:
+ self.experimenter = experimenter
+ else:
+ self.experimenter = 0
+ if subtype != None:
+ self.subtype = subtype
+ else:
+ self.subtype = 0
+ if experimenter_data != None:
+ self.experimenter_data = experimenter_data
+ else:
+ self.experimenter_data = ''
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append(self.experimenter_data)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = table_feature_prop_experimenter_miss()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.experimenter = reader.read("!L")[0]
+ obj.subtype = reader.read("!L")[0]
+ obj.experimenter_data = str(reader.read_all())
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.experimenter != other.experimenter: return False
+ if self.subtype != other.subtype: return False
+ if self.experimenter_data != other.experimenter_data: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("table_feature_prop_experimenter_miss {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("experimenter = ");
+ q.text("%#x" % self.experimenter)
+ q.text(","); q.breakable()
+ q.text("subtype = ");
+ q.text("%#x" % self.subtype)
+ q.text(","); q.breakable()
+ q.text("experimenter_data = ");
+ q.pp(self.experimenter_data)
+ q.breakable()
+ q.text('}')
+
+table_feature_prop.subtypes[65535] = table_feature_prop_experimenter_miss
class table_feature_prop_instructions(table_feature_prop):
type = 0
@@ -2833,7 +2932,7 @@
_length = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_length - (2 + 2))
- obj.instruction_ids = loxi.generic_util.unpack_list(reader, instruction.instruction.unpack)
+ obj.instruction_ids = loxi.generic_util.unpack_list(reader, instruction_id.instruction_id.unpack)
return obj
def __eq__(self, other):
@@ -2880,7 +2979,7 @@
_length = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_length - (2 + 2))
- obj.instruction_ids = loxi.generic_util.unpack_list(reader, instruction.instruction.unpack)
+ obj.instruction_ids = loxi.generic_util.unpack_list(reader, instruction_id.instruction_id.unpack)
return obj
def __eq__(self, other):
diff --git a/src/python/loxi/of13/const.py b/src/python/loxi/of13/const.py
index 404d582..cae3396 100644
--- a/src/python/loxi/of13/const.py
+++ b/src/python/loxi/of13/const.py
@@ -692,6 +692,9 @@
OFPR_BSN_DEST_PORT_UNREACHABLE = 136
OFPR_BSN_FRAGMENTATION_REQUIRED = 137
OFPR_BSN_ARP = 139
+OFPR_BSN_DHCP = 140
+OFPR_BSN_DEBUG = 141
+OFPR_BSN_PACKET_OF_DEATH = 142
ofp_packet_in_reason_map = {
0: 'OFPR_NO_MATCH',
@@ -708,6 +711,9 @@
136: 'OFPR_BSN_DEST_PORT_UNREACHABLE',
137: 'OFPR_BSN_FRAGMENTATION_REQUIRED',
139: 'OFPR_BSN_ARP',
+ 140: 'OFPR_BSN_DHCP',
+ 141: 'OFPR_BSN_DEBUG',
+ 142: 'OFPR_BSN_PACKET_OF_DEATH',
}
# Identifiers from group ofp_port
diff --git a/src/python/loxi/of13/instruction.py b/src/python/loxi/of13/instruction.py
index 5d36bda..bc06252 100644
--- a/src/python/loxi/of13/instruction.py
+++ b/src/python/loxi/of13/instruction.py
@@ -283,6 +283,150 @@
bsn.subtypes[1] = bsn_arp_offload
+class bsn_deny(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 5
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append('\x00' * 4)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_deny()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 5)
+ reader.skip(4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_deny {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 2
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append('\x00' * 4)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_dhcp_offload()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 2)
+ reader.skip(4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_dhcp_offload {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_split_horizon_check(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 3
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append('\x00' * 4)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_disable_split_horizon_check()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 3)
+ reader.skip(4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_disable_split_horizon_check {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
class bsn_disable_src_mac_check(bsn):
type = 65535
experimenter = 6035143
@@ -331,6 +475,102 @@
bsn.subtypes[0] = bsn_disable_src_mac_check
+class bsn_packet_of_death(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 6
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append('\x00' * 4)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_packet_of_death()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 6)
+ reader.skip(4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_packet_of_death {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 4
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append('\x00' * 4)
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_permit()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 4)
+ reader.skip(4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_permit {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
class clear_actions(instruction):
type = 5
diff --git a/src/python/loxi/of13/instruction_id.py b/src/python/loxi/of13/instruction_id.py
index 2c101a1..7d64a9a 100644
--- a/src/python/loxi/of13/instruction_id.py
+++ b/src/python/loxi/of13/instruction_id.py
@@ -77,7 +77,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -90,7 +89,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -178,7 +176,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!L", self.subtype))
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -199,7 +196,6 @@
_experimenter = reader.read("!L")[0]
assert(_experimenter == 6035143)
obj.subtype = reader.read("!L")[0]
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -231,7 +227,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!L", self.subtype))
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -248,7 +243,6 @@
assert(_experimenter == 6035143)
_subtype = reader.read("!L")[0]
assert(_subtype == 1)
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -265,6 +259,144 @@
bsn.subtypes[1] = bsn_arp_offload
+class bsn_deny(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 5
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_deny()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 5)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_deny {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 2
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_dhcp_offload()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 2)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_dhcp_offload {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_split_horizon_check(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 3
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_disable_split_horizon_check()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 3)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_disable_split_horizon_check {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
class bsn_disable_src_mac_check(bsn):
type = 65535
experimenter = 6035143
@@ -279,7 +411,6 @@
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
packed.append(struct.pack("!L", self.experimenter))
packed.append(struct.pack("!L", self.subtype))
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -296,7 +427,6 @@
assert(_experimenter == 6035143)
_subtype = reader.read("!L")[0]
assert(_subtype == 0)
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -313,6 +443,98 @@
bsn.subtypes[0] = bsn_disable_src_mac_check
+class bsn_packet_of_death(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 6
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_packet_of_death()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 6)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_packet_of_death {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+ type = 65535
+ experimenter = 6035143
+ subtype = 4
+
+ def __init__(self):
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!H", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_permit()
+ _type = reader.read("!H")[0]
+ assert(_type == 65535)
+ _len = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_len - (2 + 2))
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 4)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_permit {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.breakable()
+ q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
class clear_actions(instruction_id):
type = 5
@@ -323,7 +545,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -336,7 +557,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -363,7 +583,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 3)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -376,7 +595,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(3)
return obj
def __eq__(self, other):
@@ -441,7 +659,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -454,7 +671,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
@@ -481,7 +697,6 @@
packed = []
packed.append(struct.pack("!H", self.type))
packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
- packed.append('\x00' * 4)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
return ''.join(packed)
@@ -494,7 +709,6 @@
_len = reader.read("!H")[0]
orig_reader = reader
reader = orig_reader.slice(_len - (2 + 2))
- reader.skip(4)
return obj
def __eq__(self, other):
diff --git a/src/python/loxi/of13/message.py b/src/python/loxi/of13/message.py
index f4716fc..0aaeec6 100644
--- a/src/python/loxi/of13/message.py
+++ b/src/python/loxi/of13/message.py
@@ -2109,6 +2109,546 @@
bsn_header.subtypes[56] = bsn_controller_connections_request
+class experimenter_stats_reply(stats_reply):
+ subtypes = {}
+
+ version = 4
+ type = 19
+ stats_type = 65535
+
+ def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if experimenter != None:
+ self.experimenter = experimenter
+ else:
+ self.experimenter = 0
+ if subtype != None:
+ self.subtype = subtype
+ else:
+ self.subtype = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ subtype, = reader.peek('!L', 16)
+ subclass = experimenter_stats_reply.subtypes.get(subtype)
+ if subclass:
+ return subclass.unpack(reader)
+
+ obj = experimenter_stats_reply()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 19)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ obj.experimenter = reader.read("!L")[0]
+ obj.subtype = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.experimenter != other.experimenter: return False
+ if self.subtype != other.subtype: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("experimenter_stats_reply {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.text(","); q.breakable()
+ q.text("subtype = ");
+ q.text("%#x" % self.subtype)
+ q.breakable()
+ q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+ subtypes = {}
+
+ version = 4
+ type = 19
+ stats_type = 65535
+ experimenter = 6035143
+
+ def __init__(self, xid=None, flags=None, subtype=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if subtype != None:
+ self.subtype = subtype
+ else:
+ self.subtype = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ subtype, = reader.peek('!L', 20)
+ subclass = bsn_stats_reply.subtypes.get(subtype)
+ if subclass:
+ return subclass.unpack(reader)
+
+ obj = bsn_stats_reply()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 19)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ obj.subtype = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.subtype != other.subtype: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_stats_reply {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.breakable()
+ q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class bsn_flow_checksum_bucket_stats_reply(bsn_stats_reply):
+ version = 4
+ type = 19
+ stats_type = 65535
+ experimenter = 6035143
+ subtype = 10
+
+ def __init__(self, xid=None, flags=None, entries=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if entries != None:
+ self.entries = entries
+ else:
+ self.entries = []
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append(loxi.generic_util.pack_list(self.entries))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_flow_checksum_bucket_stats_reply()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 19)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 10)
+ obj.entries = loxi.generic_util.unpack_list(reader, common.bsn_flow_checksum_bucket_stats_entry.unpack)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.entries != other.entries: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_flow_checksum_bucket_stats_reply {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.text(","); q.breakable()
+ q.text("entries = ");
+ q.pp(self.entries)
+ q.breakable()
+ q.text('}')
+
+bsn_stats_reply.subtypes[10] = bsn_flow_checksum_bucket_stats_reply
+
+class experimenter_stats_request(stats_request):
+ subtypes = {}
+
+ version = 4
+ type = 18
+ stats_type = 65535
+
+ def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if experimenter != None:
+ self.experimenter = experimenter
+ else:
+ self.experimenter = 0
+ if subtype != None:
+ self.subtype = subtype
+ else:
+ self.subtype = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ subtype, = reader.peek('!L', 16)
+ subclass = experimenter_stats_request.subtypes.get(subtype)
+ if subclass:
+ return subclass.unpack(reader)
+
+ obj = experimenter_stats_request()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 18)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ obj.experimenter = reader.read("!L")[0]
+ obj.subtype = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.experimenter != other.experimenter: return False
+ if self.subtype != other.subtype: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("experimenter_stats_request {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.text(","); q.breakable()
+ q.text("subtype = ");
+ q.text("%#x" % self.subtype)
+ q.breakable()
+ q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+ subtypes = {}
+
+ version = 4
+ type = 18
+ stats_type = 65535
+ experimenter = 6035143
+
+ def __init__(self, xid=None, flags=None, subtype=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if subtype != None:
+ self.subtype = subtype
+ else:
+ self.subtype = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ subtype, = reader.peek('!L', 20)
+ subclass = bsn_stats_request.subtypes.get(subtype)
+ if subclass:
+ return subclass.unpack(reader)
+
+ obj = bsn_stats_request()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 18)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ obj.subtype = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.subtype != other.subtype: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_stats_request {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.breakable()
+ q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_flow_checksum_bucket_stats_request(bsn_stats_request):
+ version = 4
+ type = 18
+ stats_type = 65535
+ experimenter = 6035143
+ subtype = 10
+
+ def __init__(self, xid=None, flags=None, table_id=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if table_id != None:
+ self.table_id = table_id
+ else:
+ self.table_id = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append(struct.pack("!B", self.table_id))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_flow_checksum_bucket_stats_request()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 18)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 10)
+ obj.table_id = reader.read("!B")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.table_id != other.table_id: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_flow_checksum_bucket_stats_request {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.text(","); q.breakable()
+ q.text("table_id = ");
+ q.text("%#x" % self.table_id)
+ q.breakable()
+ q.text('}')
+
+bsn_stats_request.subtypes[10] = bsn_flow_checksum_bucket_stats_request
+
class bsn_flow_idle(bsn_header):
version = 4
type = 4
@@ -2501,188 +3041,6 @@
bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
-class experimenter_stats_reply(stats_reply):
- subtypes = {}
-
- version = 4
- type = 19
- stats_type = 65535
-
- def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
- if xid != None:
- self.xid = xid
- else:
- self.xid = None
- if flags != None:
- self.flags = flags
- else:
- self.flags = 0
- if experimenter != None:
- self.experimenter = experimenter
- else:
- self.experimenter = 0
- if subtype != None:
- self.subtype = subtype
- else:
- self.subtype = 0
- return
-
- def pack(self):
- packed = []
- packed.append(struct.pack("!B", self.version))
- packed.append(struct.pack("!B", self.type))
- packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
- packed.append(struct.pack("!L", self.xid))
- packed.append(struct.pack("!H", self.stats_type))
- packed.append(struct.pack("!H", self.flags))
- packed.append('\x00' * 4)
- packed.append(struct.pack("!L", self.experimenter))
- packed.append(struct.pack("!L", self.subtype))
- length = sum([len(x) for x in packed])
- packed[2] = struct.pack("!H", length)
- return ''.join(packed)
-
- @staticmethod
- def unpack(reader):
- subtype, = reader.peek('!L', 16)
- subclass = experimenter_stats_reply.subtypes.get(subtype)
- if subclass:
- return subclass.unpack(reader)
-
- obj = experimenter_stats_reply()
- _version = reader.read("!B")[0]
- assert(_version == 4)
- _type = reader.read("!B")[0]
- assert(_type == 19)
- _length = reader.read("!H")[0]
- orig_reader = reader
- reader = orig_reader.slice(_length - (2 + 2))
- obj.xid = reader.read("!L")[0]
- _stats_type = reader.read("!H")[0]
- assert(_stats_type == 65535)
- obj.flags = reader.read("!H")[0]
- reader.skip(4)
- obj.experimenter = reader.read("!L")[0]
- obj.subtype = reader.read("!L")[0]
- return obj
-
- def __eq__(self, other):
- if type(self) != type(other): return False
- if self.xid != other.xid: return False
- if self.flags != other.flags: return False
- if self.experimenter != other.experimenter: return False
- if self.subtype != other.subtype: return False
- return True
-
- def pretty_print(self, q):
- q.text("experimenter_stats_reply {")
- with q.group():
- with q.indent(2):
- q.breakable()
- q.text("xid = ");
- if self.xid != None:
- q.text("%#x" % self.xid)
- else:
- q.text('None')
- q.text(","); q.breakable()
- q.text("flags = ");
- q.text("%#x" % self.flags)
- q.text(","); q.breakable()
- q.text("subtype = ");
- q.text("%#x" % self.subtype)
- q.breakable()
- q.text('}')
-
-stats_reply.subtypes[65535] = experimenter_stats_reply
-
-class bsn_stats_reply(experimenter_stats_reply):
- subtypes = {}
-
- version = 4
- type = 19
- stats_type = 65535
- experimenter = 6035143
-
- def __init__(self, xid=None, flags=None, subtype=None):
- if xid != None:
- self.xid = xid
- else:
- self.xid = None
- if flags != None:
- self.flags = flags
- else:
- self.flags = 0
- if subtype != None:
- self.subtype = subtype
- else:
- self.subtype = 0
- return
-
- def pack(self):
- packed = []
- packed.append(struct.pack("!B", self.version))
- packed.append(struct.pack("!B", self.type))
- packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
- packed.append(struct.pack("!L", self.xid))
- packed.append(struct.pack("!H", self.stats_type))
- packed.append(struct.pack("!H", self.flags))
- packed.append('\x00' * 4)
- packed.append(struct.pack("!L", self.experimenter))
- packed.append(struct.pack("!L", self.subtype))
- length = sum([len(x) for x in packed])
- packed[2] = struct.pack("!H", length)
- return ''.join(packed)
-
- @staticmethod
- def unpack(reader):
- subtype, = reader.peek('!L', 20)
- subclass = bsn_stats_reply.subtypes.get(subtype)
- if subclass:
- return subclass.unpack(reader)
-
- obj = bsn_stats_reply()
- _version = reader.read("!B")[0]
- assert(_version == 4)
- _type = reader.read("!B")[0]
- assert(_type == 19)
- _length = reader.read("!H")[0]
- orig_reader = reader
- reader = orig_reader.slice(_length - (2 + 2))
- obj.xid = reader.read("!L")[0]
- _stats_type = reader.read("!H")[0]
- assert(_stats_type == 65535)
- obj.flags = reader.read("!H")[0]
- reader.skip(4)
- _experimenter = reader.read("!L")[0]
- assert(_experimenter == 6035143)
- obj.subtype = reader.read("!L")[0]
- return obj
-
- def __eq__(self, other):
- if type(self) != type(other): return False
- if self.xid != other.xid: return False
- if self.flags != other.flags: return False
- if self.subtype != other.subtype: return False
- return True
-
- def pretty_print(self, q):
- q.text("bsn_stats_reply {")
- with q.group():
- with q.indent(2):
- q.breakable()
- q.text("xid = ");
- if self.xid != None:
- q.text("%#x" % self.xid)
- else:
- q.text('None')
- q.text(","); q.breakable()
- q.text("flags = ");
- q.text("%#x" % self.flags)
- q.breakable()
- q.text('}')
-
-experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
-
class bsn_gentable_bucket_stats_reply(bsn_stats_reply):
version = 4
type = 19
@@ -2771,188 +3129,6 @@
bsn_stats_reply.subtypes[5] = bsn_gentable_bucket_stats_reply
-class experimenter_stats_request(stats_request):
- subtypes = {}
-
- version = 4
- type = 18
- stats_type = 65535
-
- def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
- if xid != None:
- self.xid = xid
- else:
- self.xid = None
- if flags != None:
- self.flags = flags
- else:
- self.flags = 0
- if experimenter != None:
- self.experimenter = experimenter
- else:
- self.experimenter = 0
- if subtype != None:
- self.subtype = subtype
- else:
- self.subtype = 0
- return
-
- def pack(self):
- packed = []
- packed.append(struct.pack("!B", self.version))
- packed.append(struct.pack("!B", self.type))
- packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
- packed.append(struct.pack("!L", self.xid))
- packed.append(struct.pack("!H", self.stats_type))
- packed.append(struct.pack("!H", self.flags))
- packed.append('\x00' * 4)
- packed.append(struct.pack("!L", self.experimenter))
- packed.append(struct.pack("!L", self.subtype))
- length = sum([len(x) for x in packed])
- packed[2] = struct.pack("!H", length)
- return ''.join(packed)
-
- @staticmethod
- def unpack(reader):
- subtype, = reader.peek('!L', 16)
- subclass = experimenter_stats_request.subtypes.get(subtype)
- if subclass:
- return subclass.unpack(reader)
-
- obj = experimenter_stats_request()
- _version = reader.read("!B")[0]
- assert(_version == 4)
- _type = reader.read("!B")[0]
- assert(_type == 18)
- _length = reader.read("!H")[0]
- orig_reader = reader
- reader = orig_reader.slice(_length - (2 + 2))
- obj.xid = reader.read("!L")[0]
- _stats_type = reader.read("!H")[0]
- assert(_stats_type == 65535)
- obj.flags = reader.read("!H")[0]
- reader.skip(4)
- obj.experimenter = reader.read("!L")[0]
- obj.subtype = reader.read("!L")[0]
- return obj
-
- def __eq__(self, other):
- if type(self) != type(other): return False
- if self.xid != other.xid: return False
- if self.flags != other.flags: return False
- if self.experimenter != other.experimenter: return False
- if self.subtype != other.subtype: return False
- return True
-
- def pretty_print(self, q):
- q.text("experimenter_stats_request {")
- with q.group():
- with q.indent(2):
- q.breakable()
- q.text("xid = ");
- if self.xid != None:
- q.text("%#x" % self.xid)
- else:
- q.text('None')
- q.text(","); q.breakable()
- q.text("flags = ");
- q.text("%#x" % self.flags)
- q.text(","); q.breakable()
- q.text("subtype = ");
- q.text("%#x" % self.subtype)
- q.breakable()
- q.text('}')
-
-stats_request.subtypes[65535] = experimenter_stats_request
-
-class bsn_stats_request(experimenter_stats_request):
- subtypes = {}
-
- version = 4
- type = 18
- stats_type = 65535
- experimenter = 6035143
-
- def __init__(self, xid=None, flags=None, subtype=None):
- if xid != None:
- self.xid = xid
- else:
- self.xid = None
- if flags != None:
- self.flags = flags
- else:
- self.flags = 0
- if subtype != None:
- self.subtype = subtype
- else:
- self.subtype = 0
- return
-
- def pack(self):
- packed = []
- packed.append(struct.pack("!B", self.version))
- packed.append(struct.pack("!B", self.type))
- packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
- packed.append(struct.pack("!L", self.xid))
- packed.append(struct.pack("!H", self.stats_type))
- packed.append(struct.pack("!H", self.flags))
- packed.append('\x00' * 4)
- packed.append(struct.pack("!L", self.experimenter))
- packed.append(struct.pack("!L", self.subtype))
- length = sum([len(x) for x in packed])
- packed[2] = struct.pack("!H", length)
- return ''.join(packed)
-
- @staticmethod
- def unpack(reader):
- subtype, = reader.peek('!L', 20)
- subclass = bsn_stats_request.subtypes.get(subtype)
- if subclass:
- return subclass.unpack(reader)
-
- obj = bsn_stats_request()
- _version = reader.read("!B")[0]
- assert(_version == 4)
- _type = reader.read("!B")[0]
- assert(_type == 18)
- _length = reader.read("!H")[0]
- orig_reader = reader
- reader = orig_reader.slice(_length - (2 + 2))
- obj.xid = reader.read("!L")[0]
- _stats_type = reader.read("!H")[0]
- assert(_stats_type == 65535)
- obj.flags = reader.read("!H")[0]
- reader.skip(4)
- _experimenter = reader.read("!L")[0]
- assert(_experimenter == 6035143)
- obj.subtype = reader.read("!L")[0]
- return obj
-
- def __eq__(self, other):
- if type(self) != type(other): return False
- if self.xid != other.xid: return False
- if self.flags != other.flags: return False
- if self.subtype != other.subtype: return False
- return True
-
- def pretty_print(self, q):
- q.text("bsn_stats_request {")
- with q.group():
- with q.indent(2):
- q.breakable()
- q.text("xid = ");
- if self.xid != None:
- q.text("%#x" % self.xid)
- else:
- q.text('None')
- q.text(","); q.breakable()
- q.text("flags = ");
- q.text("%#x" % self.flags)
- q.breakable()
- q.text('}')
-
-experimenter_stats_request.subtypes[6035143] = bsn_stats_request
-
class bsn_gentable_bucket_stats_request(bsn_stats_request):
version = 4
type = 18
@@ -6678,6 +6854,256 @@
bsn_stats_request.subtypes[6] = bsn_switch_pipeline_stats_request
+class bsn_table_checksum_stats_reply(bsn_stats_reply):
+ version = 4
+ type = 19
+ stats_type = 65535
+ experimenter = 6035143
+ subtype = 11
+
+ def __init__(self, xid=None, flags=None, entries=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ if entries != None:
+ self.entries = entries
+ else:
+ self.entries = []
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append(loxi.generic_util.pack_list(self.entries))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_table_checksum_stats_reply()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 19)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 11)
+ obj.entries = loxi.generic_util.unpack_list(reader, common.bsn_table_checksum_stats_entry.unpack)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ if self.entries != other.entries: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_table_checksum_stats_reply {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.text(","); q.breakable()
+ q.text("entries = ");
+ q.pp(self.entries)
+ q.breakable()
+ q.text('}')
+
+bsn_stats_reply.subtypes[11] = bsn_table_checksum_stats_reply
+
+class bsn_table_checksum_stats_request(bsn_stats_request):
+ version = 4
+ type = 18
+ stats_type = 65535
+ experimenter = 6035143
+ subtype = 11
+
+ def __init__(self, xid=None, flags=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if flags != None:
+ self.flags = flags
+ else:
+ self.flags = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!H", self.stats_type))
+ packed.append(struct.pack("!H", self.flags))
+ packed.append('\x00' * 4)
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_table_checksum_stats_request()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 18)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _stats_type = reader.read("!H")[0]
+ assert(_stats_type == 65535)
+ obj.flags = reader.read("!H")[0]
+ reader.skip(4)
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 11)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.flags != other.flags: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_table_checksum_stats_request {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("flags = ");
+ q.text("%#x" % self.flags)
+ q.breakable()
+ q.text('}')
+
+bsn_stats_request.subtypes[11] = bsn_table_checksum_stats_request
+
+class bsn_table_set_buckets_size(bsn_header):
+ version = 4
+ type = 4
+ experimenter = 6035143
+ subtype = 61
+
+ def __init__(self, xid=None, table_id=None, buckets_size=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if table_id != None:
+ self.table_id = table_id
+ else:
+ self.table_id = 0
+ if buckets_size != None:
+ self.buckets_size = buckets_size
+ else:
+ self.buckets_size = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!B", self.version))
+ packed.append(struct.pack("!B", self.type))
+ packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+ packed.append(struct.pack("!L", self.xid))
+ packed.append(struct.pack("!L", self.experimenter))
+ packed.append(struct.pack("!L", self.subtype))
+ packed.append(struct.pack("!H", self.table_id))
+ packed.append('\x00' * 2)
+ packed.append(struct.pack("!L", self.buckets_size))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_table_set_buckets_size()
+ _version = reader.read("!B")[0]
+ assert(_version == 4)
+ _type = reader.read("!B")[0]
+ assert(_type == 4)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length - (2 + 2))
+ obj.xid = reader.read("!L")[0]
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 61)
+ obj.table_id = reader.read("!H")[0]
+ reader.skip(2)
+ obj.buckets_size = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.table_id != other.table_id: return False
+ if self.buckets_size != other.buckets_size: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_table_set_buckets_size {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("xid = ");
+ if self.xid != None:
+ q.text("%#x" % self.xid)
+ else:
+ q.text('None')
+ q.text(","); q.breakable()
+ q.text("table_id = ");
+ q.text("%#x" % self.table_id)
+ q.text(","); q.breakable()
+ q.text("buckets_size = ");
+ q.text("%#x" % self.buckets_size)
+ q.breakable()
+ q.text('}')
+
+bsn_header.subtypes[61] = bsn_table_set_buckets_size
+
class bsn_time_reply(bsn_header):
version = 4
type = 4
diff --git a/src/python/loxi/of13/oxm.py b/src/python/loxi/of13/oxm.py
index a2f5053..65536e8 100644
--- a/src/python/loxi/of13/oxm.py
+++ b/src/python/loxi/of13/oxm.py
@@ -521,6 +521,98 @@
oxm.subtypes[2147495688] = arp_tpa_masked
+class bsn_egr_port_group_id(oxm):
+ type_len = 200196
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!L", self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_egr_port_group_id()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 200196)
+ obj.value = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.value != other.value: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_egr_port_group_id {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+ type_len = 200456
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = 0
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!L", self.value))
+ packed.append(struct.pack("!L", self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_egr_port_group_id_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 200456)
+ obj.value = reader.read("!L")[0]
+ obj.value_mask = reader.read("!L")[0]
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.value != other.value: return False
+ if self.value_mask != other.value_mask: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_egr_port_group_id_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text("%#x" % self.value_mask)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
class bsn_global_vrf_allowed(oxm):
type_len = 198145
diff --git a/src/python/oftest/dataplane.py b/src/python/oftest/dataplane.py
index 12dcfce..740e6aa 100644
--- a/src/python/oftest/dataplane.py
+++ b/src/python/oftest/dataplane.py
@@ -126,7 +126,7 @@
def recv(self):
(timestamp, pkt) = next(self.pcap)
- return (pkt, timestamp)
+ return (pkt[:], timestamp)
def send(self, packet):
return self.pcap.inject(packet, len(packet))
diff --git a/src/python/oftest/ofutils.py b/src/python/oftest/ofutils.py
index 8cf2ae0..f81a2f5 100644
--- a/src/python/oftest/ofutils.py
+++ b/src/python/oftest/ofutils.py
@@ -10,6 +10,7 @@
import logging
default_timeout = None # set by oft
+default_negative_timeout = None # set by oft
def gen_xid():
return random.randrange(1,0xffffffff)
@@ -19,11 +20,9 @@
The condition variable must already be acquired.
The timeout value -1 means use the default timeout.
There is deliberately no support for an infinite timeout.
-TODO: get the default timeout from configuration
"""
def timed_wait(cv, fn, timeout=-1):
if timeout == -1:
- # TODO make this configurable
timeout = default_timeout
end_time = time.time() + timeout
diff --git a/src/python/oftest/packet.py b/src/python/oftest/packet.py
index 9631e02..1ed100f 100644
--- a/src/python/oftest/packet.py
+++ b/src/python/oftest/packet.py
@@ -4,15 +4,17 @@
"""
Wrap scapy to satisfy pylint
"""
+from oftest import config
import sys
try:
import scapy.config
import scapy.route
- import scapy.route6
import scapy.layers.l2
import scapy.layers.inet
- import scapy.layers.inet6
+ if not config["disable_ipv6"]:
+ import scapy.route6
+ import scapy.layers.inet6
except ImportError:
sys.exit("Need to install scapy for packet parsing")
@@ -22,10 +24,12 @@
Dot1Q = scapy.layers.l2.Dot1Q
IP = scapy.layers.inet.IP
IPOption = scapy.layers.inet.IPOption
-IPv6 = scapy.layers.inet6.IPv6
ARP = scapy.layers.inet.ARP
TCP = scapy.layers.inet.TCP
UDP = scapy.layers.inet.UDP
ICMP = scapy.layers.inet.ICMP
-ICMPv6Unknown = scapy.layers.inet6.ICMPv6Unknown
-ICMPv6EchoRequest = scapy.layers.inet6.ICMPv6EchoRequest
+
+if not config["disable_ipv6"]:
+ IPv6 = scapy.layers.inet6.IPv6
+ ICMPv6Unknown = scapy.layers.inet6.ICMPv6Unknown
+ ICMPv6EchoRequest = scapy.layers.inet6.ICMPv6EchoRequest
diff --git a/src/python/oftest/testutils.py b/src/python/oftest/testutils.py
index d47f81f..57201ce 100644
--- a/src/python/oftest/testutils.py
+++ b/src/python/oftest/testutils.py
@@ -292,9 +292,10 @@
ip_dst='192.168.0.2',
ip_tos=0,
ip_ttl=64,
+ ip_id=1,
icmp_type=8,
- icmp_code=0
- ):
+ icmp_code=0,
+ icmp_data=''):
"""
Return a simple ICMP packet
@@ -309,8 +310,10 @@
@param ip_dst IP destination
@param ip_tos IP ToS
@param ip_ttl IP TTL
+ @param ip_id IP Identification
@param icmp_type ICMP type
@param icmp_code ICMP code
+ @param icmp_data ICMP data
Generates a simple ICMP ECHO REQUEST. Users
shouldn't assume anything about this packet other than that
@@ -323,12 +326,12 @@
if (dl_vlan_enable):
pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
scapy.Dot1Q(prio=vlan_pcp, id=0, vlan=vlan_vid)/ \
- scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos)/ \
- scapy.ICMP(type=icmp_type, code=icmp_code)
+ scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+ scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
else:
pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
- scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos)/ \
- scapy.ICMP(type=icmp_type, code=icmp_code)
+ scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+ scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
pkt = pkt/("0" * (pktlen - len(pkt)))
@@ -573,11 +576,6 @@
DEPRECATED in favor in verify_packets
"""
- # Wait this long for packets that we don't expect to receive.
- # 100ms is (rarely) too short for positive tests on slow
- # switches but is definitely not too short for a negative test.
- negative_timeout = 0.1
-
exp_pkt_arg = None
if oftest.config["relax"]:
exp_pkt_arg = pkt
@@ -595,7 +593,7 @@
"Received packet does not match expected packet " +
"on port " + str(ofport))
if len(no_ports) > 0:
- time.sleep(negative_timeout)
+ time.sleep(oftest.ofutils.default_negative_timeout)
for ofport in no_ports:
logging.debug("Negative check for pkt on port " + str(ofport))
(rcv_port, rcv_pkt, pkt_time) = dp.poll(
@@ -1379,7 +1377,6 @@
return get_stats(test, req)
def verify_flow_stats(test, match, table_id=0xff,
- out_port=None,
initial=[],
pkts=None, bytes=None):
"""
@@ -1389,8 +1386,6 @@
get_flow_stats(). If 'initial' is not given the counters are assumed to
begin at 0.
"""
- if out_port == None:
- out_port = ofp.OFPP_NONE
def accumulate(stats):
pkts_acc = bytes_acc = 0
@@ -1404,7 +1399,7 @@
# Wait 10s for counters to update
pkt_diff = byte_diff = None
for i in range(0, 100):
- stats = get_flow_stats(test, match, table_id=table_id, out_port=out_port)
+ stats = get_flow_stats(test, match, table_id=table_id)
pkts_after, bytes_after = accumulate(stats)
pkt_diff = pkts_after - pkts_before
byte_diff = bytes_after - bytes_before
@@ -1602,7 +1597,7 @@
# Negative test, need to wait a short amount of time before checking we
# didn't receive the message.
- time.sleep(0.5)
+ time.sleep(oftest.ofutils.default_negative_timeout)
# Check every packet_in queued in the controller
while True:
@@ -1645,7 +1640,10 @@
Check that a particular packet is not received
"""
logging.debug("Negative check for pkt on port %r", ofport)
- (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(port_number=ofport, exp_pkt=str(pkt), timeout=0.01)
+ (rcv_port, rcv_pkt, pkt_time) = \
+ test.dataplane.poll(
+ port_number=ofport, exp_pkt=str(pkt),
+ timeout=oftest.ofutils.default_negative_timeout)
test.assertTrue(rcv_pkt == None, "Received packet on %r" % ofport)
def verify_no_other_packets(test):
@@ -1657,7 +1655,7 @@
if oftest.config["relax"]:
return
logging.debug("Checking for unexpected packets on all ports")
- (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(timeout=0.01)
+ (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(timeout=oftest.ofutils.default_negative_timeout)
if rcv_pkt != None:
logging.debug("Received unexpected packet on port %r: %s", rcv_port, format_packet(rcv_pkt))
test.assertTrue(rcv_pkt == None, "Unexpected packet on port %r" % rcv_port)
@@ -1689,7 +1687,7 @@
def verify_capability(test, capability):
"""
- Assert that the DUT supports the specified capability.
+ Return True if DUT supports the specified capability.
@param test Instance of base_tests.SimpleProtocol
@param capability One of ofp_capabilities.
@@ -1707,14 +1705,16 @@
test.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
("Unexpected packet type %d received in response to "
"OFPT_FEATURES_REQUEST") % res.type)
- logging.info("Received features_request.")
+ logging.info("Received features_reply.")
- logging.info("Verifying %s bit is set.", capability_str)
- test.assertTrue((res.capabilities & capability) > 0,
- ("Capabilities bitmask does not support "
- "%s.") % capability_str)
- logging.info(("Switch capabilities bitmask claims to support "
- "%s."), capability_str)
+ if (res.capabilities & capability) > 0:
+ logging.info("Switch capabilities bitmask claims to support %s",
+ capability_str)
+ return True, res.capabilities
+ else:
+ logging.info("Capabilities bitmask does not support %s.",
+ capability_str)
+ return False, res.capabilities
def verify_configuration_flag(test, flag):
"""
diff --git a/tests-1.3/bsn_controller_connections.py b/tests-1.3/bsn_controller_connections.py
new file mode 100644
index 0000000..ba58596
--- /dev/null
+++ b/tests-1.3/bsn_controller_connections.py
@@ -0,0 +1,24 @@
+"""
+Test the BSN controller connections request
+"""
+import struct
+import unittest
+import logging
+
+import oftest
+from oftest import config
+import oftest.controller as controller
+import ofp
+import oftest.base_tests as base_tests
+
+from oftest.testutils import *
+
+class BsnControllerConnectionsRequest(base_tests.SimpleProtocol):
+ """
+ Verify that the switch sends a bsn_controller_connections_reply in response
+ to the request
+ """
+ def runTest(self):
+ request = ofp.message.bsn_controller_connections_request()
+ response, _ = self.controller.transact(request)
+ self.assertIsInstance(response, ofp.message.bsn_controller_connections_reply)
diff --git a/tests-1.3/bsn_flow_checksum.py b/tests-1.3/bsn_flow_checksum.py
new file mode 100644
index 0000000..11bbedc
--- /dev/null
+++ b/tests-1.3/bsn_flow_checksum.py
@@ -0,0 +1,252 @@
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2014 Big Switch Networks, Inc.
+"""
+BSN flow checksum extension test cases
+"""
+
+import logging
+import math
+import random
+
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+
+from oftest.testutils import *
+
+TABLE_ID = 0
+
+def make_checksum(hi, lo):
+ """
+ Place 'hi' in the upper 8 bits and 'lo' in the lower bits.
+ """
+ return ((hi & 0xff) << 56) | lo
+
+assert make_checksum(0xab, 0xcd) == 0xab000000000000cd
+
+def shuffled(seq):
+ l = list(seq)[:]
+ random.shuffle(l)
+ return l
+
+class FlowChecksumBase(base_tests.SimpleProtocol):
+ """
+ Base class that maintains the expected table and bucket checksums
+ """
+ checksum_buckets = None
+ table_checksum = None
+ all_checksums = []
+
+ def get_table_checksum(self):
+ for entry in get_stats(self, ofp.message.bsn_table_checksum_stats_request()):
+ if entry.table_id == TABLE_ID:
+ return entry.checksum
+ return None
+
+ def get_checksum_buckets(self):
+ stats = get_stats(self,
+ ofp.message.bsn_flow_checksum_bucket_stats_request(table_id=TABLE_ID))
+ return [x.checksum for x in stats]
+
+ def verify_checksums(self):
+ self.assertEquals(self.get_table_checksum(), self.table_checksum)
+ self.assertEquals(self.get_checksum_buckets(), self.checksum_buckets)
+
+ def update_checksums(self, checksum):
+ self.table_checksum ^= checksum
+ checksum_shift = 64 - int(math.log(len(self.checksum_buckets), 2))
+ self.checksum_buckets[checksum >> checksum_shift] ^= checksum
+
+ def insert_checksum(self, checksum):
+ self.update_checksums(checksum)
+ self.all_checksums.append(checksum)
+
+ def remove_checksum(self, checksum):
+ self.update_checksums(checksum)
+ self.all_checksums.remove(checksum)
+
+ def set_buckets_size(self, buckets_size):
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=buckets_size))
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+
+ self.checksum_buckets = [0] * buckets_size
+ self.table_checksum = 0
+ for checksum in self.all_checksums:
+ self.update_checksums(checksum)
+
+class FlowChecksum(FlowChecksumBase):
+ """
+ Test flow checksum buckets and table checksums
+ """
+ def runTest(self):
+ delete_all_flows(self.controller)
+
+ # Deleted all flows, table checksum should be 0
+ self.assertEquals(self.get_table_checksum(), 0)
+
+ self.set_buckets_size(8)
+ self.verify_checksums()
+
+ # Interesting checksums
+ checksums = [
+ make_checksum(0, 1),
+ make_checksum(0, 2),
+ make_checksum(1, 0xab),
+ make_checksum(1, 0xab),
+ make_checksum(7, 0xff),
+ make_checksum(7, 0xaa),
+ ]
+
+ # Random checksums
+ for _ in xrange(0, 8):
+ checksums.append(random.randint(0, 2**64-1))
+
+ # Add flows in random order
+ for i, checksum in shuffled(enumerate(checksums)):
+ self.insert_checksum(checksum)
+ request = ofp.message.flow_add(
+ table_id=TABLE_ID,
+ cookie=checksum,
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=i)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ # Delete flows in random order
+ for i, checksum in shuffled(enumerate(checksums)):
+ self.remove_checksum(checksum)
+ request = ofp.message.flow_delete_strict(
+ table_id=TABLE_ID,
+ priority=i,
+ out_port=ofp.OFPP_ANY,
+ out_group=ofp.OFPG_ANY)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ # Deleted all flows, table checksum should be 0
+ self.assertEquals(self.get_table_checksum(), 0)
+
+class Resize(FlowChecksumBase):
+ """
+ Resize the checksum buckets, checking limits and redistribution
+ """
+ def runTest(self):
+ delete_all_flows(self.controller)
+
+ self.assertEquals(self.get_table_checksum(), 0)
+
+ self.set_buckets_size(128)
+ self.verify_checksums()
+
+ checksums = [random.randint(0, 2**64-1) for _ in xrange(0, 128)]
+
+ # Add flows
+ for i, checksum in enumerate(checksums):
+ self.insert_checksum(checksum)
+ request = ofp.message.flow_add(
+ table_id=TABLE_ID,
+ cookie=checksum,
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=i)
+ self.controller.message_send(request)
+ if i % 17 == 0:
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ # Shrink checksum buckets
+ self.set_buckets_size(64)
+ self.verify_checksums()
+
+ # Shrink checksum buckets to minimum
+ self.set_buckets_size(1)
+ self.verify_checksums()
+
+ # Grow checksum buckets
+ self.set_buckets_size(2)
+ self.verify_checksums()
+
+ # Grow checksum buckets
+ self.set_buckets_size(256)
+ self.verify_checksums()
+
+ # Grow checksum buckets to maximum
+ self.set_buckets_size(65536)
+ self.verify_checksums()
+
+ # Delete flows
+ for i, checksum in enumerate(checksums):
+ self.remove_checksum(checksum)
+ request = ofp.message.flow_delete_strict(
+ table_id=TABLE_ID,
+ priority=i,
+ out_port=ofp.OFPP_ANY,
+ out_group=ofp.OFPG_ANY)
+ self.controller.message_send(request)
+ if i % 17 == 0:
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+ self.verify_checksums()
+
+ # Deleted all flows, table checksum should be 0
+ self.assertEquals(self.get_table_checksum(), 0)
+
+class ResizeError(FlowChecksumBase):
+ """
+ Check that the switch rejects invalid checksum buckets sizes
+ """
+ def runTest(self):
+ # buckets_size = 0
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=0))
+ do_barrier(self.controller)
+ error, _ = self.controller.poll(ofp.OFPT_ERROR)
+ self.assertIsInstance(error, ofp.message.error_msg)
+
+ # buckets_size = 3
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=3))
+ do_barrier(self.controller)
+ error, _ = self.controller.poll(ofp.OFPT_ERROR)
+ self.assertIsInstance(error, ofp.message.error_msg)
+
+ # buckets_size = 100
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=100))
+ do_barrier(self.controller)
+ error, _ = self.controller.poll(ofp.OFPT_ERROR)
+ self.assertIsInstance(error, ofp.message.error_msg)
+
+ # buckets_size = 2**32 - 1
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=2**32-1))
+ do_barrier(self.controller)
+ error, _ = self.controller.poll(ofp.OFPT_ERROR)
+ self.assertIsInstance(error, ofp.message.error_msg)
+
+ # buckets_size = 2**31
+ self.controller.message_send(
+ ofp.message.bsn_table_set_buckets_size(
+ table_id=TABLE_ID, buckets_size=2**31))
+ do_barrier(self.controller)
+ error, _ = self.controller.poll(ofp.OFPT_ERROR)
+ self.assertIsInstance(error, ofp.message.error_msg)
diff --git a/tests-1.3/bsn_gentable.py b/tests-1.3/bsn_gentable.py
index e9f3145..915729c 100644
--- a/tests-1.3/bsn_gentable.py
+++ b/tests-1.3/bsn_gentable.py
@@ -702,8 +702,7 @@
do_barrier(self.controller)
error, _ = self.controller.poll(ofp.OFPT_ERROR, 0)
- self.assertIsInstance(error, ofp.message.bad_request_error_msg)
- self.assertEquals(error.code, ofp.OFPBRC_EPERM)
+ self.assertEquals(error, None)
class DeleteFailureError(BaseGenTableTest):
"""
diff --git a/tests-1.3/bsn_role_status.py b/tests-1.3/bsn_role_status.py
new file mode 100644
index 0000000..957738a
--- /dev/null
+++ b/tests-1.3/bsn_role_status.py
@@ -0,0 +1,92 @@
+"""
+Test the BSN role status message
+
+This is a backport of the OpenFlow 1.4 functionality.
+"""
+import struct
+import unittest
+import logging
+
+import oftest
+from oftest import config
+import oftest.controller as controller
+import ofp
+import oftest.base_tests as base_tests
+
+from oftest.testutils import *
+
+def simple_role_request(test, role, gen=None, con=None):
+ """
+ Send a role request we expect to succeed
+ """
+ if con == None:
+ con = test.controller
+ request = ofp.message.role_request(role=role, generation_id=gen)
+ response, _ = con.transact(request)
+ test.assertTrue(isinstance(response, ofp.message.role_reply), "Expected a role reply")
+ if role != ofp.OFPCR_ROLE_NOCHANGE:
+ test.assertEquals(response.role, role)
+ if gen != None:
+ test.assertEquals(response.generation_id, gen)
+ return response.role, response.generation_id
+
+@disabled
+@nonstandard
+class RoleStatus(unittest.TestCase):
+ """
+ Verify that when a connection becomes a master the existing master is
+ downgraded to slave and receives a role-status message.
+
+ Requires the switch to attempt to connect in parallel to ports 6653
+ and 6753 on the configured IP.
+ """
+
+ def setUp(self):
+ host = config["controller_host"]
+ self.controllers = [
+ controller.Controller(host=host,port=6653),
+ controller.Controller(host=host,port=6753)
+ ]
+
+ def runTest(self):
+ # Connect and handshake with both controllers
+ for con in self.controllers:
+ con.start()
+ if not con.connect():
+ raise AssertionError("failed to connect controller %s" % str(con))
+ reply, _ = con.transact(ofp.message.features_request())
+ self.assertTrue(isinstance(reply, ofp.message.features_reply))
+
+ # Assert initial role and get generation IDs
+ role, gen0 = simple_role_request(self, ofp.OFPCR_ROLE_NOCHANGE, con=self.controllers[0])
+ self.assertEqual(role, ofp.OFPCR_ROLE_EQUAL)
+ role, gen1 = simple_role_request(self, ofp.OFPCR_ROLE_NOCHANGE, con=self.controllers[1])
+ self.assertEqual(role, ofp.OFPCR_ROLE_EQUAL)
+
+ # Initial role assignment: controller 0 is master, controller 1 is slave
+ simple_role_request(self, ofp.OFPCR_ROLE_MASTER, gen0, con=self.controllers[0])
+ simple_role_request(self, ofp.OFPCR_ROLE_SLAVE, gen1, con=self.controllers[1])
+ self.verify_role(self.controllers[0], ofp.OFPCR_ROLE_MASTER)
+ self.verify_role(self.controllers[1], ofp.OFPCR_ROLE_SLAVE)
+
+ # Controller 1 requests master
+ # Controller 0 becomes slave
+ simple_role_request(self, ofp.OFPCR_ROLE_MASTER, gen1, con=self.controllers[1])
+ self.verify_role(self.controllers[0], ofp.OFPCR_ROLE_SLAVE)
+ self.verify_role(self.controllers[1], ofp.OFPCR_ROLE_MASTER)
+
+ # Controller 0 should receive a bsn_role_status message
+ msg, _ = self.controllers[0].poll(ofp.OFPT_EXPERIMENTER)
+ self.assertIsInstance(msg, ofp.message.bsn_role_status)
+ self.assertEqual(msg.role, ofp.OFPCR_ROLE_SLAVE)
+ self.assertEqual(msg.reason, ofp.OFP_BSN_CONTROLLER_ROLE_REASON_MASTER_REQUEST)
+ self.assertEqual(msg.generation_id, gen1)
+
+ def verify_role(self, con, role):
+ rcv_role, _ = simple_role_request(self, ofp.OFPCR_ROLE_NOCHANGE, con=con)
+ self.assertEqual(rcv_role, role)
+
+ def tearDown(self):
+ for con in self.controllers:
+ con.shutdown()
+
diff --git a/tests-1.3/flow_mod.py b/tests-1.3/flow_mod.py
new file mode 100644
index 0000000..2f0e711
--- /dev/null
+++ b/tests-1.3/flow_mod.py
@@ -0,0 +1,88 @@
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2014 Big Switch Networks, Inc.
+"""
+Flow-mod test cases
+"""
+
+import logging
+
+import oftest
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+from loxi.pp import pp
+
+from oftest.testutils import *
+from oftest.parse import parse_ipv6
+
+class Overwrite(base_tests.SimpleDataPlane):
+ """
+ Verify that overwriting a flow changes most fields but preserves stats
+ """
+ def runTest(self):
+ in_port, out_port1, out_port2 = openflow_ports(3)
+
+ delete_all_flows(self.controller)
+
+ table_id = test_param_get("table", 0)
+ match = ofp.match([
+ ofp.oxm.in_port(in_port),
+ ])
+ priority = 1000
+
+ logging.info("Inserting flow")
+ request = ofp.message.flow_add(
+ table_id=table_id,
+ match=match,
+ instructions=[
+ ofp.instruction.apply_actions([ofp.action.output(out_port1)]),
+ ],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=priority,
+ flags=ofp.OFPFF_SEND_FLOW_REM,
+ cookie=0x1234,
+ hard_timeout=1000,
+ idle_timeout=2000)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ # Send a packet through so that we can check stats were preserved
+ self.dataplane.send(in_port, str(simple_tcp_packet(pktlen=100)))
+ verify_flow_stats(self, ofp.match(), table_id=table_id, pkts=1)
+
+ # Send a flow-add with the same table_id, match, and priority, causing
+ # an overwrite
+ logging.info("Overwriting flow")
+ request = ofp.message.flow_add(
+ table_id=table_id,
+ match=match,
+ instructions=[
+ ofp.instruction.apply_actions([ofp.action.output(out_port2)]),
+ ],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=priority,
+ flags=0,
+ cookie=0xabcd,
+ hard_timeout=3000,
+ idle_timeout=4000)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ # Should not get a flow-removed message
+ msg, _ = self.controller.poll(exp_msg=ofp.message.flow_removed,
+ timeout=oftest.ofutils.default_negative_timeout)
+ self.assertEquals(msg, None)
+
+ # Check that the fields in the flow stats entry match the second flow-add
+ stats = get_flow_stats(self, ofp.match())
+ self.assertEquals(len(stats), 1)
+ entry = stats[0]
+ logging.debug(entry.show())
+ self.assertEquals(entry.instructions, request.instructions)
+ self.assertEquals(entry.flags, request.flags)
+ self.assertEquals(entry.cookie, request.cookie)
+ self.assertEquals(entry.hard_timeout, request.hard_timeout)
+ self.assertEquals(entry.idle_timeout, request.idle_timeout)
+
+ # Flow stats should have been preserved
+ verify_flow_stats(self, ofp.match(), table_id=table_id, pkts=1)
diff --git a/tests/latency.py b/tests/latency.py
new file mode 100644
index 0000000..3cf8c5d
--- /dev/null
+++ b/tests/latency.py
@@ -0,0 +1,107 @@
+"""
+Latency tests
+
+These tests are mostly helpful for finding an optimal value for the
+--default-negative-timeout option. If this value is too large it will
+unnecessarily some down testing, but if it is too small then tests
+may pass when they should have failed.
+
+Most of this latency is caused by OFTest. Actual switch latency should be just
+a few microseconds, but OFTest can add milliseconds on top of that.
+"""
+
+import logging
+import unittest
+import time
+
+from oftest import config
+import ofp
+import oftest.base_tests as base_tests
+
+from oftest.testutils import *
+
+class DataplaneLatency(base_tests.SimpleDataPlane):
+ """
+ Measure and assert dataplane latency
+
+ All packets must arrive within the default timeout, and 90% must
+ arrive within the default negative timeout.
+ """
+ def runTest(self):
+ in_port, out_port = openflow_ports(2)
+
+ delete_all_flows(self.controller)
+
+ pkt = str(simple_tcp_packet())
+
+ request = ofp.message.flow_add(
+ match=ofp.match(wildcards=ofp.OFPFW_ALL),
+ buffer_id=0xffffffff,
+ actions=[ofp.action.output(out_port)])
+
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ latencies = []
+ for i in xrange(0, 1000):
+ start_time = time.time()
+ self.dataplane.send(in_port, pkt)
+ verify_packet(self, pkt, out_port)
+ end_time = time.time()
+ latencies.append(end_time - start_time)
+
+ latencies.sort()
+
+ latency_min = latencies[0]
+ latency_90 = latencies[int(len(latencies)*0.9)]
+ latency_max = latencies[-1]
+
+ logging.debug("Minimum latency: %f ms", latency_min * 1000.0)
+ logging.debug("90%% latency: %f ms", latency_90 * 1000.0)
+ logging.debug("Maximum latency: %f ms", latency_max * 1000.0)
+
+ self.assertGreater(config["default_timeout"], latency_max)
+ self.assertGreater(config["default_negative_timeout"], latency_90)
+
+class PktinLatency(base_tests.SimpleDataPlane):
+ """
+ Measure and assert packet-in latency
+
+ All packet-ins must arrive within the default timeout, and 90% must
+ arrive within the default negative timeout.
+ """
+ def runTest(self):
+ in_port, = openflow_ports(1)
+
+ delete_all_flows(self.controller)
+
+ pkt = str(simple_tcp_packet())
+
+ request = ofp.message.flow_add(
+ match=ofp.match(wildcards=ofp.OFPFW_ALL),
+ buffer_id=0xffffffff,
+ actions=[ofp.action.output(ofp.OFPP_CONTROLLER)])
+
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ latencies = []
+ for i in xrange(0, 1000):
+ start_time = time.time()
+ self.dataplane.send(in_port, pkt)
+ verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
+ end_time = time.time()
+ latencies.append(end_time - start_time)
+
+ latencies.sort()
+
+ latency_min = latencies[0]
+ latency_90 = latencies[int(len(latencies)*0.9)]
+ latency_max = latencies[-1]
+
+ logging.debug("Minimum latency: %f ms", latency_min * 1000.0)
+ logging.debug("90%% latency: %f ms", latency_90 * 1000.0)
+ logging.debug("Maximum latency: %f ms", latency_max * 1000.0)
+
+ self.assertGreater(config["default_timeout"], latency_max)
+ self.assertGreater(config["default_negative_timeout"], latency_90)
diff --git a/tests/openflow_protocol_messages.py b/tests/openflow_protocol_messages.py
index 50c7eae..ded727e 100644
--- a/tests/openflow_protocol_messages.py
+++ b/tests/openflow_protocol_messages.py
@@ -278,30 +278,6 @@
verify_packet_in(self, str(pkt), ingress_port, ofp.OFPR_NO_MATCH)
-class Hello(base_tests.SimpleDataPlane):
-
- """Test Hello messages are implemented
- a) Create Hello messages from controller
- b) Verify switch also exchanges hello message -- (Poll the control plane)
- d) Verify the version field in the hello messages is openflow 1.0.0 """
-
- def runTest(self):
-
- logging.info("Running Hello test")
-
- logging.info("Sending Hello")
- logging.info("Expecting a Hello on the control plane with version--1.0.0")
-
- #Send Hello message
- request = ofp.message.hello()
- (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_HELLO,
- timeout=1)
- self.assertTrue(response is not None,
- 'Switch did not exchange hello message in return')
- self.assertTrue(response.version == 0x01, 'switch openflow-version field is not 1.0.0')
-
-
-
class EchoWithoutBody(base_tests.SimpleProtocol):
"""Test basic echo-reply is implemented