Merge into master from pull request #183:
update pyloxi to floodlight/loxigen-artifacts @ 6fb4ac9fe79ec8730ae34928df12cdf671f3ba75 (https://github.com/floodlight/oftest/pull/183)
diff --git a/src/python/loxi/connection.py b/src/python/loxi/connection.py
new file mode 100644
index 0000000..af8bf84
--- /dev/null
+++ b/src/python/loxi/connection.py
@@ -0,0 +1,237 @@
+# Copyright 2015, Big Switch Networks, Inc.
+
+"""
+OpenFlow connection class
+
+This class creates a thread which continually parses OpenFlow messages off the
+supplied socket and places them in a queue. The class has methods for reading messages
+from the RX queue, sending messages, and higher level operations like request-response
+and multipart transactions.
+"""
+
+import loxi
+import loxi.of14
+import logging
+import time
+import socket
+import errno
+import os
+import select
+from threading import Condition, Lock, Thread
+
+DEFAULT_TIMEOUT = 1
+
+class TransactionError(Exception):
+ def __str__(self):
+ return self.args[0]
+
+ @property
+ def msg(self):
+ return self.args[1]
+
+class Connection(Thread):
+ def __init__(self, sock):
+ Thread.__init__(self)
+ self.sock = sock
+ self.logger = logging.getLogger("connection")
+ self.rx = []
+ self.rx_cv = Condition()
+ self.tx_lock = Lock()
+ self.next_xid = 1
+ self.wakeup_rd, self.wakeup_wr = os.pipe()
+ self.finished = False
+ self.read_buffer = None
+
+ def run(self):
+ while not self.finished:
+ rd, wr, err = select.select([self.sock, self.wakeup_rd], [], [])
+ if self.sock in rd:
+ self.process_read()
+ if self.wakeup_rd in rd:
+ os.read(self.wakeup_rd, 1)
+ self.logger.debug("Exited event loop")
+
+ def process_read(self):
+ recvd = self.sock.recv(4096)
+
+ self.logger.debug("Received %d bytes", len(recvd))
+
+ buf = self.read_buffer
+ if buf:
+ buf += recvd
+ else:
+ buf = recvd
+
+ offset = 0
+ while offset < len(buf):
+ if offset + 8 > len(buf):
+ # Not enough data for the OpenFlow header
+ break
+
+ # Parse the header to get type
+ hdr_version, hdr_type, hdr_msglen, hdr_xid = loxi.of14.message.parse_header(buf[offset:])
+
+ # Use loxi to resolve ofp of matching version
+ ofp = loxi.protocol(hdr_version)
+
+ # Extract the raw message bytes
+ if (offset + hdr_msglen) > len(buf):
+ # Not enough data for the body
+ break
+ rawmsg = buf[offset : offset + hdr_msglen]
+ offset += hdr_msglen
+
+ msg = ofp.message.parse_message(rawmsg)
+ if not msg:
+ self.logger.warn("Could not parse message")
+ continue
+
+ self.logger.debug("Received message %s.%s xid %d length %d",
+ type(msg).__module__, type(msg).__name__, hdr_xid, hdr_msglen)
+
+ with self.rx_cv:
+ self.rx.append(msg)
+ self.rx_cv.notify_all()
+
+ if offset == len(buf):
+ self.read_buffer = None
+ else:
+ self.read_buffer = buf[offset:]
+ self.logger.debug("%d bytes remaining", len(self.read_buffer))
+
+ def recv(self, predicate, timeout=DEFAULT_TIMEOUT):
+ """
+ Remove and return the first message in the RX queue for
+ which 'predicate' returns true
+ """
+ assert self.is_alive()
+
+ deadline = time.time() + timeout
+ while True:
+ with self.rx_cv:
+ for i, msg in enumerate(self.rx):
+ if predicate(msg):
+ return self.rx.pop(i)
+
+ now = time.time()
+ if now > deadline:
+ return None
+ else:
+ self.rx_cv.wait(deadline - now)
+
+ def recv_any(self, timeout=DEFAULT_TIMEOUT):
+ """
+ Return the first message in the RX queue
+ """
+ return self.recv(lambda msg: True, timeout)
+
+ def recv_xid(self, xid, timeout=DEFAULT_TIMEOUT):
+ """
+ Return the first message in the RX queue with XID 'xid'
+ """
+ return self.recv(lambda msg: msg.xid == xid, timeout)
+
+ def recv_class(self, klass, timeout=DEFAULT_TIMEOUT):
+ """
+ Return the first message in the RX queue which is an instance of 'klass'
+ """
+ return self.recv(lambda msg: isinstance(msg, klass), timeout)
+
+ def send_raw(self, buf):
+ """
+ Send raw bytes on the socket
+ """
+ assert self.is_alive()
+ self.logger.debug("Sending raw message length %d", len(buf))
+ with self.tx_lock:
+ if self.sock.sendall(buf) is not None:
+ raise RuntimeError("failed to send message to switch")
+
+ def send(self, msg):
+ """
+ Send a message
+ """
+ assert self.is_alive()
+
+ if msg.xid is None:
+ msg.xid = self._gen_xid()
+ buf = msg.pack()
+ self.logger.debug("Sending message %s.%s xid %d length %d",
+ type(msg).__module__, type(msg).__name__, msg.xid, len(buf))
+ with self.tx_lock:
+ if self.sock.sendall(buf) is not None:
+ raise RuntimeError("failed to send message to switch")
+
+ def transact(self, msg, timeout=DEFAULT_TIMEOUT):
+ """
+ Send a message and return the reply
+ """
+ self.send(msg)
+ reply = self.recv_xid(msg.xid, timeout)
+ if reply is None:
+ raise TransactionError("no reply for %s" % type(msg).__name__, None)
+ elif isinstance(reply, loxi.protocol(reply.version).message.error_msg):
+ raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+ return reply
+
+ def transact_multipart_generator(self, msg, timeout=DEFAULT_TIMEOUT):
+ """
+ Send a multipart request and yield each entry from the replies
+ """
+ self.send(msg)
+ finished = False
+ while not finished:
+ reply = self.recv_xid(msg.xid, timeout)
+ if reply is None:
+ raise TransactionError("no reply for %s" % type(msg).__name__, None)
+ elif not isinstance(reply, loxi.protocol(reply.version).message.stats_reply):
+ raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+ for entry in reply.entries:
+ yield entry
+ finished = reply.flags & loxi.protocol(reply.version).OFPSF_REPLY_MORE == 0
+
+ def transact_multipart(self, msg, timeout=DEFAULT_TIMEOUT):
+ """
+ Send a multipart request and return all entries from the replies
+ """
+ entries = []
+ for entry in self.transact_multipart_generator(msg, timeout):
+ entries.append(entry)
+ return entries
+
+ def stop(self):
+ """
+ Signal the thread to exit and wait for it
+ """
+ assert not self.finished
+ self.logger.debug("Stopping connection")
+ self.finished = True
+ os.write(self.wakeup_wr, "x")
+ self.join()
+ self.sock.close()
+ os.close(self.wakeup_rd)
+ os.close(self.wakeup_wr)
+ self.logger.debug("Stopped connection")
+
+ def _gen_xid(self):
+ xid = self.next_xid
+ self.next_xid += 1
+ return xid
+
+def connect(ip, port=6653, daemon=True, ofp=loxi.of14):
+ """
+ Actively connect to a switch
+ """
+ soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ soc.connect((ip, port))
+ soc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+ cxn = Connection(soc)
+ cxn.daemon = daemon
+ cxn.logger.debug("Connected to %s:%d", ip, port)
+ cxn.start()
+
+ cxn.send(ofp.message.hello())
+ if not cxn.recv(lambda msg: msg.type == ofp.OFPT_HELLO):
+ raise Exception("Did not receive HELLO")
+
+ return cxn
diff --git a/src/python/loxi/of13/bsn_tlv.py b/src/python/loxi/of13/bsn_tlv.py
index 66a4839..3559248 100644
--- a/src/python/loxi/of13/bsn_tlv.py
+++ b/src/python/loxi/of13/bsn_tlv.py
@@ -3551,6 +3551,53 @@
bsn_tlv.subtypes[6] = vlan_vid
+class vlan_vid_mask(bsn_tlv):
+ type = 77
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ 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("!H", self.value))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = vlan_vid_mask()
+ _type = reader.read("!H")[0]
+ assert(_type == 77)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length, 4)
+ obj.value = reader.read("!H")[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("vlan_vid_mask {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
class vrf(bsn_tlv):
type = 19
diff --git a/src/python/loxi/of13/common.py b/src/python/loxi/of13/common.py
index 450c9bb..73011a4 100644
--- a/src/python/loxi/of13/common.py
+++ b/src/python/loxi/of13/common.py
@@ -2951,6 +2951,7 @@
packed.append(loxi.generic_util.pack_list(self.action_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -2962,6 +2963,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -2998,6 +3000,7 @@
packed.append(loxi.generic_util.pack_list(self.action_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3009,6 +3012,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3045,6 +3049,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3056,6 +3061,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3092,6 +3098,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3103,6 +3110,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3151,6 +3159,7 @@
packed.append(self.experimenter_data)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3169,6 +3178,7 @@
obj.experimenter = reader.read("!L")[0]
obj.subtype = reader.read("!L")[0]
obj.experimenter_data = str(reader.read_all())
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3222,6 +3232,7 @@
packed.append(self.experimenter_data)
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3240,6 +3251,7 @@
obj.experimenter = reader.read("!L")[0]
obj.subtype = reader.read("!L")[0]
obj.experimenter_data = str(reader.read_all())
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3281,6 +3293,7 @@
packed.append(loxi.generic_util.pack_list(self.instruction_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3292,6 +3305,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3328,6 +3342,7 @@
packed.append(loxi.generic_util.pack_list(self.instruction_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3339,6 +3354,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3375,6 +3391,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3386,6 +3403,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3422,6 +3440,7 @@
packed.append(loxi.generic_util.pack_list(self.next_table_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3433,6 +3452,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3469,6 +3489,7 @@
packed.append(loxi.generic_util.pack_list(self.next_table_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3480,6 +3501,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3516,6 +3538,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3527,6 +3550,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3563,6 +3587,7 @@
packed.append(loxi.generic_util.pack_list(self.action_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3574,6 +3599,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3610,6 +3636,7 @@
packed.append(loxi.generic_util.pack_list(self.action_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3621,6 +3648,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3657,6 +3685,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3668,6 +3697,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
@@ -3704,6 +3734,7 @@
packed.append(loxi.generic_util.pack_list(self.oxm_ids))
length = sum([len(x) for x in packed])
packed[1] = struct.pack("!H", length)
+ packed.append(loxi.generic_util.pad_to(8, length))
return ''.join(packed)
@staticmethod
@@ -3715,6 +3746,7 @@
orig_reader = reader
reader = orig_reader.slice(_length, 4)
obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+ orig_reader.skip_align()
return obj
def __eq__(self, other):
diff --git a/src/python/loxi/of13/const.py b/src/python/loxi/of13/const.py
index fc0fd7b..35df7f0 100644
--- a/src/python/loxi/of13/const.py
+++ b/src/python/loxi/of13/const.py
@@ -354,6 +354,7 @@
OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
ofp_bsn_port_counter_map = {
0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
@@ -383,6 +384,7 @@
24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+ 27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
}
# Identifiers from group ofp_bsn_tcp_flag
diff --git a/src/python/loxi/of13/oxm.py b/src/python/loxi/of13/oxm.py
index 603afc3..51b1a73 100644
--- a/src/python/loxi/of13/oxm.py
+++ b/src/python/loxi/of13/oxm.py
@@ -975,6 +975,190 @@
oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+class bsn_inner_eth_dst(oxm):
+ type_len = 207878
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_dst()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207878)
+ obj.value = list(reader.read('!6B'))
+ 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_inner_eth_dst {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+ type_len = 208140
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ packed.append(struct.pack("!6B", *self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_dst_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208140)
+ obj.value = list(reader.read('!6B'))
+ obj.value_mask = list(reader.read('!6B'))
+ 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_inner_eth_dst_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text(util.pretty_mac(self.value_mask))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+ type_len = 208390
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_src()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208390)
+ obj.value = list(reader.read('!6B'))
+ 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_inner_eth_src {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+ type_len = 208652
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ packed.append(struct.pack("!6B", *self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_src_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208652)
+ obj.value = list(reader.read('!6B'))
+ obj.value_mask = list(reader.read('!6B'))
+ 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_inner_eth_src_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text(util.pretty_mac(self.value_mask))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
class bsn_l2_cache_hit(oxm):
type_len = 205825
@@ -2447,6 +2631,98 @@
oxm.subtypes[197896] = bsn_vrf_masked
+class bsn_vxlan_network_id(oxm):
+ type_len = 207364
+
+ 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_vxlan_network_id()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207364)
+ 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_vxlan_network_id {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+ type_len = 207624
+
+ 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_vxlan_network_id_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207624)
+ 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_vxlan_network_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[207624] = bsn_vxlan_network_id_masked
+
class eth_dst(oxm):
type_len = 2147485190
diff --git a/src/python/loxi/of14/bsn_tlv.py b/src/python/loxi/of14/bsn_tlv.py
index 97a1619..0211226 100644
--- a/src/python/loxi/of14/bsn_tlv.py
+++ b/src/python/loxi/of14/bsn_tlv.py
@@ -3551,6 +3551,53 @@
bsn_tlv.subtypes[6] = vlan_vid
+class vlan_vid_mask(bsn_tlv):
+ type = 77
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = 0
+ 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("!H", self.value))
+ length = sum([len(x) for x in packed])
+ packed[1] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = vlan_vid_mask()
+ _type = reader.read("!H")[0]
+ assert(_type == 77)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length, 4)
+ obj.value = reader.read("!H")[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("vlan_vid_mask {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
class vrf(bsn_tlv):
type = 19
diff --git a/src/python/loxi/of14/const.py b/src/python/loxi/of14/const.py
index 89a293d..8b2ad1e 100644
--- a/src/python/loxi/of14/const.py
+++ b/src/python/loxi/of14/const.py
@@ -383,6 +383,7 @@
OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
ofp_bsn_port_counter_map = {
0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
@@ -412,6 +413,7 @@
24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+ 27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
}
# Identifiers from group ofp_bsn_tcp_flag
diff --git a/src/python/loxi/of14/message.py b/src/python/loxi/of14/message.py
index e1962ee..ae86367 100644
--- a/src/python/loxi/of14/message.py
+++ b/src/python/loxi/of14/message.py
@@ -3373,6 +3373,88 @@
bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
+class bsn_generic_async(bsn_header):
+ version = 5
+ type = 4
+ experimenter = 6035143
+ subtype = 68
+
+ def __init__(self, xid=None, name=None, tlvs=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ if name != None:
+ self.name = name
+ else:
+ self.name = ""
+ if tlvs != None:
+ self.tlvs = tlvs
+ else:
+ self.tlvs = []
+ 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("!64s", self.name))
+ packed.append(loxi.generic_util.pack_list(self.tlvs))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_generic_async()
+ _version = reader.read("!B")[0]
+ assert(_version == 5)
+ _type = reader.read("!B")[0]
+ assert(_type == 4)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length, 4)
+ obj.xid = reader.read("!L")[0]
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 68)
+ obj.name = reader.read("!64s")[0].rstrip("\x00")
+ obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ if self.name != other.name: return False
+ if self.tlvs != other.tlvs: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_generic_async {")
+ 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("name = ");
+ q.pp(self.name)
+ q.text(","); q.breakable()
+ q.text("tlvs = ");
+ q.pp(self.tlvs)
+ q.breakable()
+ q.text('}')
+
+bsn_header.subtypes[68] = bsn_generic_async
+
class bsn_generic_stats_reply(bsn_stats_reply):
version = 5
type = 19
@@ -8096,6 +8178,68 @@
bsn_header.subtypes[61] = bsn_table_set_buckets_size
+class bsn_takeover(bsn_header):
+ version = 5
+ type = 4
+ experimenter = 6035143
+ subtype = 69
+
+ def __init__(self, xid=None):
+ if xid != None:
+ self.xid = xid
+ else:
+ self.xid = None
+ 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))
+ length = sum([len(x) for x in packed])
+ packed[2] = struct.pack("!H", length)
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_takeover()
+ _version = reader.read("!B")[0]
+ assert(_version == 5)
+ _type = reader.read("!B")[0]
+ assert(_type == 4)
+ _length = reader.read("!H")[0]
+ orig_reader = reader
+ reader = orig_reader.slice(_length, 4)
+ obj.xid = reader.read("!L")[0]
+ _experimenter = reader.read("!L")[0]
+ assert(_experimenter == 6035143)
+ _subtype = reader.read("!L")[0]
+ assert(_subtype == 69)
+ return obj
+
+ def __eq__(self, other):
+ if type(self) != type(other): return False
+ if self.xid != other.xid: return False
+ return True
+
+ def pretty_print(self, q):
+ q.text("bsn_takeover {")
+ 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.breakable()
+ q.text('}')
+
+bsn_header.subtypes[69] = bsn_takeover
+
class bsn_time_reply(bsn_header):
version = 5
type = 4
diff --git a/src/python/loxi/of14/oxm.py b/src/python/loxi/of14/oxm.py
index e6964a1..9abd97f 100644
--- a/src/python/loxi/of14/oxm.py
+++ b/src/python/loxi/of14/oxm.py
@@ -883,6 +883,190 @@
oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+class bsn_inner_eth_dst(oxm):
+ type_len = 207878
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_dst()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207878)
+ obj.value = list(reader.read('!6B'))
+ 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_inner_eth_dst {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+ type_len = 208140
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ packed.append(struct.pack("!6B", *self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_dst_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208140)
+ obj.value = list(reader.read('!6B'))
+ obj.value_mask = list(reader.read('!6B'))
+ 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_inner_eth_dst_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text(util.pretty_mac(self.value_mask))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+ type_len = 208390
+
+ def __init__(self, value=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_src()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208390)
+ obj.value = list(reader.read('!6B'))
+ 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_inner_eth_src {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+ type_len = 208652
+
+ def __init__(self, value=None, value_mask=None):
+ if value != None:
+ self.value = value
+ else:
+ self.value = [0,0,0,0,0,0]
+ if value_mask != None:
+ self.value_mask = value_mask
+ else:
+ self.value_mask = [0,0,0,0,0,0]
+ return
+
+ def pack(self):
+ packed = []
+ packed.append(struct.pack("!L", self.type_len))
+ packed.append(struct.pack("!6B", *self.value))
+ packed.append(struct.pack("!6B", *self.value_mask))
+ return ''.join(packed)
+
+ @staticmethod
+ def unpack(reader):
+ obj = bsn_inner_eth_src_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 208652)
+ obj.value = list(reader.read('!6B'))
+ obj.value_mask = list(reader.read('!6B'))
+ 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_inner_eth_src_masked {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text(util.pretty_mac(self.value))
+ q.text(","); q.breakable()
+ q.text("value_mask = ");
+ q.text(util.pretty_mac(self.value_mask))
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
class bsn_l3_interface_class_id(oxm):
type_len = 198660
@@ -2171,6 +2355,98 @@
oxm.subtypes[197896] = bsn_vrf_masked
+class bsn_vxlan_network_id(oxm):
+ type_len = 207364
+
+ 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_vxlan_network_id()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207364)
+ 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_vxlan_network_id {")
+ with q.group():
+ with q.indent(2):
+ q.breakable()
+ q.text("value = ");
+ q.text("%#x" % self.value)
+ q.breakable()
+ q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+ type_len = 207624
+
+ 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_vxlan_network_id_masked()
+ _type_len = reader.read("!L")[0]
+ assert(_type_len == 207624)
+ 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_vxlan_network_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[207624] = bsn_vxlan_network_id_masked
+
class eth_dst(oxm):
type_len = 2147485190