add csit tools 17/66617/3
authorSam Hague <shague@redhat.com>
Tue, 19 Dec 2017 15:42:19 +0000 (10:42 -0500)
committerSam Hague <shague@redhat.com>
Fri, 19 Jan 2018 16:13:36 +0000 (16:13 +0000)
Change-Id: I6d7df190633fef95ea3ed3b560933f96733409de
Signed-off-by: Sam Hague <shague@redhat.com>
19 files changed:
resources/tools/odl/csit/logfile.py [new file with mode: 0644]
resources/tools/odl/csit/robotfiles.py [new file with mode: 0644]
resources/tools/odl/csit/test_logfile.py [new file with mode: 0644]
resources/tools/odl/csit/test_robot_files.py [new file with mode: 0644]
resources/tools/odl/mdsal/__init__.py [new file with mode: 0644]
resources/tools/odl/mdsal/itm-state_dpn-endpoints.json [new file with mode: 0644]
resources/tools/odl/mdsal/itm_state.py [new file with mode: 0644]
resources/tools/odl/mdsal/models.py [new file with mode: 0644]
resources/tools/odl/mdsal/request.py [new file with mode: 0644]
resources/tools/odl/mdsal/test_itm_state.py [new file with mode: 0644]
resources/tools/odl/mdsal/test_request.py [new file with mode: 0644]
resources/tools/odl/ovs/__init__.py [new file with mode: 0644]
resources/tools/odl/ovs/flow_dumps.1.txt [new file with mode: 0644]
resources/tools/odl/ovs/flow_dumps.2.txt [new file with mode: 0644]
resources/tools/odl/ovs/flows.py [new file with mode: 0644]
resources/tools/odl/ovs/request.py [new file with mode: 0644]
resources/tools/odl/ovs/tables.py [new file with mode: 0644]
resources/tools/odl/ovs/test_flows.py [new file with mode: 0644]
resources/tools/odl/ovs/test_request.py [new file with mode: 0644]

diff --git a/resources/tools/odl/csit/logfile.py b/resources/tools/odl/csit/logfile.py
new file mode 100644 (file)
index 0000000..48fc8af
--- /dev/null
@@ -0,0 +1,54 @@
+import logging
+import os
+import re
+from subprocess import Popen
+
+
+LOG = logging.getLogger(__name__)
+
+
+class LogFile():
+    TMP = "/tmp"
+    LOGFILE = "log.html"
+
+    def __init__(self, logpath, jobpath, job):
+        if jobpath is None:
+            jobpath = self.TMP
+        self.jobpath = "{}/{}".format(jobpath, job)
+        self.logpath = logpath
+
+    def unzip_log_file0(self):
+        Popen("gunzip -fk {}".format(self.logpath), shell=True).wait()
+
+    def unzip_log_file1(self):
+        Popen("gunzip -kc {} > {}".format(self.logpath, self.jobpath + "/log.html"), shell=True).wait()
+
+    def unzip_log_file(self):
+        Popen("gunzip -cfk {} > {}".format(self.logpath, self.jobpath + "/" + self.LOGFILE), shell=True).wait()
+
+    def mkdir_job_path(self):
+        try:
+            os.makedirs(self.jobpath)
+        except OSError:
+            if not os.path.isdir(self.jobpath):
+                raise
+
+    def read_chunks(self, fp):
+        while True:
+            data = fp.read(64000)
+            if not data:
+                break
+            yield data
+
+    def parse_log(self, log):
+        # logfile = "/tmp/log.s2.html"
+        logfile = "/tmp/testjob/log.html"
+        # re_st = re.compile(r"ROBOT MESSAGE: Starting test")
+        re_st = re.compile(r"dump-flows")
+        cnt = 0
+        with open(logfile, 'rb') as fp:
+            for chunk in self.read_chunks(fp):
+                for m in re_st.finditer(chunk):
+                    print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
+                    cnt += 1
+        print "total matches: {}".format(cnt)
diff --git a/resources/tools/odl/csit/robotfiles.py b/resources/tools/odl/csit/robotfiles.py
new file mode 100644 (file)
index 0000000..00cb14f
--- /dev/null
@@ -0,0 +1,294 @@
+import argparse
+import logging
+import sys
+import os
+from os import path
+import re
+import xml.etree.cElementTree as ET
+from subprocess import Popen
+#sys.path.append('../')
+#sys.path.append('../ovs')
+#sys.path.append(path.dirname( path.dirname( path.abspath(__file__))))
+
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+class RobotFiles:
+    JOBTAG = "job"
+    TMP = "/tmp"
+    CHUNK_SIZE = 65536
+    DUMP_FLOWS = "sudo ovs-ofctl dump-flows br-int -OOpenFlow13"
+
+    def __init__(self, infile, outdir, jobtag):
+        if outdir is None:
+            outdir = RobotFiles.TMP
+        if jobtag is None:
+            jobtag = RobotFiles.JOBTAG
+        self.outdir = "{}/{}".format(outdir, jobtag)
+        self.datafilepath = infile
+        self.pdata = {}
+        self.re_normalize_text = re.compile(r"( \n)|(\[A\[C.*)")
+        self.re_uri = re.compile(r"uri=(?P<uri>.*),")
+        self.re_model = re.compile(r"uri=(?P<uri>.*),")
+
+    def set_log_level(self, level):
+        logger.setLevel(level)
+
+    def gunzip_output_file(self):
+        infile = self.datafilepath
+        basename = os.path.splitext(os.path.basename(self.datafilepath))[0]
+        self.datafilepath = "{}/{}".format(self.outdir, basename)
+        Popen("gunzip -cfk {} > {}".format(infile, self.datafilepath), shell=True).wait()
+
+    def mkdir(self, path):
+        try:
+            os.makedirs(path)
+        except OSError:
+            if not os.path.isdir(path):
+                raise
+
+    def mkdir_job_path(self):
+        self.mkdir(self.outdir)
+
+    def read_chunks(self, fp):
+        while True:
+            data = fp.read(RobotFiles.CHUNK_SIZE)
+            if not data:
+                break
+            yield data
+
+    def parse_data_file(self):
+        re_st = re.compile(r"dump-flows")
+        cnt = 0
+        with open(self.datafilepath, 'rb') as fp:
+            for chunk in self.read_chunks(fp):
+                for m in re_st.finditer(chunk):
+                    print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
+                    cnt += 1
+        print "total matches: {}".format(cnt)
+
+    class State:
+        def __init__(self):
+            self.state = "init"
+            self.pdata = {}
+            self.test_id = None
+            self.node = None
+            self.command = None
+            self.nodes = {}
+            self.models = {}
+
+        def reset(self):
+            self.state = "init"
+            self.pdata = {}
+            self.test_id = None
+            self.node = None
+            self.command = None
+            self.nodes = {}
+            self.models = {}
+
+    def normalize(self, intext):
+        outtext = self.re_normalize_text.sub("", intext)
+        return outtext
+
+    def print_config(self):
+        logger.info("datafilepath: %s, outdir: %s", self.datafilepath, self.outdir)
+
+    def process_element(self, state, event, element):
+        tag = element.tag
+        text = element.text
+        attribs = element.attrib
+        if logger.isEnabledFor(logging.DEBUG):
+            logger.debug("%s - %s - %s - %s - %s - %s", state.state, state.command, event, tag, (text is not None), attribs)
+        if event == "end":
+            if element.tag == "test":
+                state.pdata['nodes'] = state.nodes
+                state.pdata['models'] = state.models
+                self.pdata[state.test_id] = state.pdata
+                state.reset()
+                return
+            elif element.tag != "msg":
+                return
+
+        if event == "start" and state.state == "init":
+            # <test id="s1-s1-s1-t1" name="Create VLAN Network (l2_network_1)">
+            if element.tag == "test":
+                state.test_id = element.get("id")
+                state.pdata["name"] = element.get("name")
+                state.state = "test"
+        elif event == "start" and state.state == "test":
+            # <kw type="teardown" name="Get Test Teardown Debugs" library="OpenStackOperations">
+            if element.tag == "kw" and element.get("name") == "Get Test Teardown Debugs":
+                state.state = "debugs"
+        elif event == "start" and state.state == "debugs":
+            # <arg>Get DumpFlows And Ovsconfig</arg>
+            if element.tag == "arg" and element.text == "Get DumpFlows And Ovsconfig":
+                state.state = "nodes"
+            # <arg>Get Model Dump</arg>
+            if element.tag == "arg" and element.text == "Get Model Dump":
+                state.state = "models"
+        elif event == "start" and state.state == "nodes":
+            # <arg>${OS_CONTROL_NODE_IP}</arg>
+            if element.tag == "arg" and element.text is not None and "${OS_" in element.text:
+                state.node = element.text[element.text.find("{") + 1:element.text.find("}")]
+                state.nodes[state.node] = {}
+                state.state = "nodes2"
+        elif event == "start" and state.state == "nodes2":
+            # <kw name="Write Commands Until Expected Prompt" library="Utils">
+            if element.tag == "kw" and element.get("name") == "Write Commands Until Expected Prompt":
+                state.state = "kw"
+        elif event == "start" and state.state == "kw":
+            # <arg>ip -o link</arg>
+            if element.tag == "arg" and element.text is not None:
+                state.command = element.text
+                state.state = "command"
+                # only use the string before the ${...} since we don't know the ...
+                # <arg>sudo ip netns exec ${line} ip -o link</arg>
+                command_split = state.command.split("$")
+                if len(command_split) > 1:
+                    state.command = command_split[0]
+        elif event == "start" and state.state == "command":
+            # <msg timestamp="20170414 07:31:21.769" level="INFO">ip -o link</msg>
+            if element.tag == "msg" and element.text is not None:
+                text = self.normalize(element.text)
+                if text.find(state.command) != -1:
+                    # <msg timestamp="20170414 07:31:34.425" level="INFO">sudo ip netns exec
+                    # [jenkins@rele ^Mng-36618-350-devstack-newton-0 ~]&gt; ip -o link</msg>
+                    if text.find("jenkins") != -1:
+                        state.state = "nodes2"
+                    else:
+                        state.command = text
+                        state.state = "msg"
+        elif state.state == "msg":
+            # <msg timestamp="20170414 07:31:21.786" level="INFO">
+            if element.tag == "msg" and element.text is not None:
+                state.nodes[state.node][state.command] = element.text
+                # are we at the end of the debugs for the node?
+                # this command is the last one
+                if state.command == "sudo ovs-ofctl dump-group-stats br-int -OOpenFlow13":
+                    state.state = "debugs"
+                else:
+                    # still more debugs for this node
+                    state.state = "nodes2"
+        elif state.state == "models2":
+            # <msg timestamp="20170813 08:20:11.806" level="INFO">Get Request using : alias=model_dump_session,
+            # uri=restconf/config/interface-service-bindings:service-bindings, headers=None json=None</msg>
+            if element.tag == "msg" and element.text is not None and element.text.find("uri") != -1:
+                uri = self.re_uri.search(element.text)
+                if uri is not None and "uri" in uri.group():
+                    state.command = uri.group("uri")
+                    state.state = "uri"
+        elif event == "start" and state.state == "models":
+            # <kw type="foritem" name="${model} = config/neutronvpn:router-interfaces-map">
+            if element.tag == "kw" and "name" in element.attrib:
+                name_split = element.attrib["name"].split("${model} = ", 1)
+                model = None
+                if len(name_split) == 2:
+                    model = name_split[1]
+                if model is not None:
+                    state.command = model
+                    state.state = "uri"
+        elif state.state == "uri":
+            if element.tag == "msg" and element.text is not None and element.text.find("pretty_output") != -1:
+                state.state = "dump"
+        elif state.state == "dump":
+            if element.tag == "msg" and element.text is not None:
+                state.models[state.command] = element.text
+                if state.command == "restconf/operational/rendered-service-path:rendered-service-path":
+                    state.state = "done"
+                else:
+                    state.state = "models"
+
+    def parse_xml_data_file(self):
+        state = self.State()
+        with open(self.datafilepath, 'rb') as fp:
+            iterparser = ET.iterparse(fp, events=("start", "end"))
+            _, root = iterparser.next()
+            for event, element in iterparser:
+                self.process_element(state, event, element)
+                element.clear()
+                # if "s1-s1-s1-t1" in self.pdata:
+                #    break
+            root.clear()
+
+    def write_pdata(self):
+        for tindex, (testid, test) in enumerate(self.pdata.items()):
+            tdir = self.outdir + "/" + testid + "_" + test["name"].replace(" ", "_")
+            self.mkdir(tdir)
+            for nindex, (nodeid, node) in enumerate(test['nodes'].items()):
+                ndir = tdir + "/" + nodeid
+                self.mkdir(ndir)
+                for cindex, (cmdid, cmd) in enumerate(node.items()):
+                    filename = ndir + "/" + self.fix_command_names(cmdid) + ".txt"
+                    with open(filename, 'w') as fp:
+                        if cmd is not None:
+                            fp.writelines(cmd)
+            mdir = tdir + "/models"
+            self.mkdir(mdir)
+            for mindex, (model, mdata) in enumerate(test['models'].items()):
+                filename = mdir + "/" + self.fix_model_name(model) + ".txt"
+                with open(filename, 'w') as fp:
+                    if mdata is not None:
+                        fp.writelines(mdata)
+
+    def write_debug_pdata(self):
+        for tindex, (testid, test) in enumerate(self.pdata.items()):
+            tdir = self.outdir + "/" + testid + "_" + test["name"].replace(" ", "_")
+            for nindex, (nodeid, node) in enumerate(test['nodes'].items()):
+                ndir = tdir + "/" + nodeid
+                if RobotFiles.DUMP_FLOWS not in node:
+                    continue
+                filename = ndir + "/" + self.fix_command_names(RobotFiles.DUMP_FLOWS) + ".f.txt"
+                logger.info("Processing: %s", filename)
+                dump_flows = node[RobotFiles.DUMP_FLOWS]
+                flows = Flows(dump_flows, logging.DEBUG)
+                flows.write_fdata(filename)
+
+    def fix_command_names(self, cmd):
+        return cmd.replace(" ", "_")
+
+    def fix_model_name(self, model):
+        return model.replace("/", "_")
+
+
+def run(args):
+    robotfile = RobotFiles(args.infile, args.outdir, args.jobtag)
+    robotfile.print_config()
+    robotfile.parse_xml_data_file()
+    robotfile.mkdir_job_path()
+    robotfile.write_pdata()
+
+
+def create_parser():
+    parser = argparse.ArgumentParser(description="OpenStack CLI Mock")
+    parser.add_argument("-i", "--infile")
+    parser.add_argument("-o", "--outdir")
+    parser.add_argument("-j", "--jobtag")
+    parser.add_argument("-g", "--gunzip", action="store_true")
+    parser.set_defaults(func=run)
+
+    return parser
+
+
+def parse_args():
+    parser = create_parser()
+    args = parser.parse_args()
+
+    return args
+
+
+def main():
+    args = parse_args()
+    args.func(args)
+
+if __name__ == "__main__":
+    if __package__ is None:
+        import sys
+        from os import path
+
+        sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
+        from ovs.flows import Flows
+    else:
+        from ..ovs.flows import Flows
+    main()
diff --git a/resources/tools/odl/csit/test_logfile.py b/resources/tools/odl/csit/test_logfile.py
new file mode 100644 (file)
index 0000000..687e484
--- /dev/null
@@ -0,0 +1,28 @@
+import os
+import unittest
+from logfile import LogFile
+
+
+class TestLogFile(unittest.TestCase):
+    LOGPATH = "/tmp/log.html.gz"
+    JOBPATH = "/tmp"
+    JOB = "testjob"
+
+    def setUp(self):
+        self.logfile = LogFile(self.LOGPATH, self.JOBPATH, self.JOB)
+
+    def test_mkdir_log_path(self):
+        self.logfile.mkdir_job_path()
+        self.assertTrue(os.path.isdir(self.logfile.jobpath))
+
+    def test_unzip_log_file(self):
+        self.logfile.mkdir_job_path()
+        self.logfile.unzip_log_file()
+        fname = "{}/log.html".format(self.logfile.jobpath)
+        self.assertTrue(os.path.isfile(fname))
+
+    def test_parse_log(self):
+        self.logfile.parse_log(None)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/resources/tools/odl/csit/test_robot_files.py b/resources/tools/odl/csit/test_robot_files.py
new file mode 100644 (file)
index 0000000..f1d5c1f
--- /dev/null
@@ -0,0 +1,52 @@
+import os
+import unittest
+from robotfiles import RobotFiles
+
+
+# Requirements
+# - output.xml.gz in /tmp
+# - running tests will create job dir, unzip, parse and format output
+
+class TestRobotFiles(unittest.TestCase):
+    DATAPATH = "/tmp/output_l3.xml.gz"
+    JOBPATH = "/tmp"
+    JOBTAG = "testjob51"
+
+    def test_mkdir_job_path(self):
+        self.robotfile = RobotFiles(self.DATAPATH, self.JOBPATH, self.JOBTAG)
+        self.robotfile.mkdir_job_path()
+        self.assertTrue(os.path.isdir(self.robotfile.outdir))
+
+    def test_gunzip_xml_data_file(self):
+        self.robotfile = RobotFiles(self.DATAPATH, self.JOBPATH, self.JOBTAG)
+        self.robotfile.mkdir_job_path()
+        self.robotfile.gunzip_output_file()
+        self.assertTrue(os.path.isfile(self.robotfile.datafilepath))
+
+    def test_parse_xml_data_file(self):
+        self.robotfile = RobotFiles("/tmp/testjob51/output_l3.xml", self.JOBPATH, self.JOBTAG)
+        self.robotfile.print_config()
+        self.robotfile.parse_xml_data_file()
+
+        print "tests: {}".format(len(self.robotfile.pdata))
+        # test_id = "s1-s1-s4-t28"
+        test_id = "s1-t1"
+        if test_id not in self.robotfile.pdata:
+            self.fail("wrong test_id")
+        pdata = self.robotfile.pdata[test_id]
+        print "\n{} test id = {} - {}".format(1, test_id, pdata['name'])
+        if 1:
+            for nindex, (node, ndata) in enumerate(pdata['nodes'].items()):
+                print "{}: node = {}".format(nindex, node)
+                for cindex, (command, cdata) in enumerate(ndata.items()):
+                    print "{}: command = {}\n{}".format(cindex, command, cdata)
+        if 0:
+            for mindex, (model, mdata) in enumerate(sorted(pdata['models'].items())):
+                print "{}: model = {} - {}".format(mindex, model, mdata)
+
+        self.robotfile.mkdir_job_path()
+        self.robotfile.write_pdata()
+        # self.robotfile.write_debug_pdata()
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/resources/tools/odl/mdsal/__init__.py b/resources/tools/odl/mdsal/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/resources/tools/odl/mdsal/itm-state_dpn-endpoints.json b/resources/tools/odl/mdsal/itm-state_dpn-endpoints.json
new file mode 100644 (file)
index 0000000..cc518e5
--- /dev/null
@@ -0,0 +1,69 @@
+{
+  "dpn-endpoints": {
+    "DPN-TEPs-info": [
+      {
+        "DPN-ID": 13878168265586,
+        "tunnel-end-points": [
+          {
+            "VLAN-ID": 0,
+            "gw-ip-address": "0.0.0.0",
+            "interface-name": "13878168265586:tunnel_port:0",
+            "ip-address": "10.29.13.165",
+            "option-of-tunnel": false,
+            "option-tunnel-tos": "0",
+            "portname": "tunnel_port",
+            "subnet-mask": "0.0.0.0/0",
+            "tunnel-type": "odl-interface:tunnel-type-vxlan",
+            "tz-membership": [
+              {
+                "zone-name": "1032b8b4-5e9c-411b-a69b-2bba8f60aa67"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "DPN-ID": 61943686945521,
+        "tunnel-end-points": [
+          {
+            "VLAN-ID": 0,
+            "gw-ip-address": "0.0.0.0",
+            "interface-name": "61943686945521:tunnel_port:0",
+            "ip-address": "10.29.13.153",
+            "option-of-tunnel": false,
+            "option-tunnel-tos": "0",
+            "portname": "tunnel_port",
+            "subnet-mask": "0.0.0.0/0",
+            "tunnel-type": "odl-interface:tunnel-type-vxlan",
+            "tz-membership": [
+              {
+                "zone-name": "1032b8b4-5e9c-411b-a69b-2bba8f60aa67"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "DPN-ID": 224473964479867,
+        "tunnel-end-points": [
+          {
+            "VLAN-ID": 0,
+            "gw-ip-address": "0.0.0.0",
+            "interface-name": "224473964479867:tunnel_port:0",
+            "ip-address": "10.29.13.158",
+            "option-of-tunnel": false,
+            "option-tunnel-tos": "0",
+            "portname": "tunnel_port",
+            "subnet-mask": "0.0.0.0/0",
+            "tunnel-type": "odl-interface:tunnel-type-vxlan",
+            "tz-membership": [
+              {
+                "zone-name": "1032b8b4-5e9c-411b-a69b-2bba8f60aa67"
+              }
+            ]
+          }
+        ]
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/resources/tools/odl/mdsal/itm_state.py b/resources/tools/odl/mdsal/itm_state.py
new file mode 100644 (file)
index 0000000..8fd01c9
--- /dev/null
@@ -0,0 +1,51 @@
+from models import Model
+
+
+name = "itm-state"
+
+
+class DpnEndpoints(Model):
+    CONTAINER = "dpn-endpoints"
+    DPN_TEPS_INFO = "DPN-TEPs-info"
+    DPN_ID = "DPN-ID"
+    TUNNEL_END_POINTS = "tunnel-end-points"
+    IP_ADDRESS = "ip-address"
+
+    def item_generator(self, json_input, lookup_key):
+        if isinstance(json_input, dict):
+            for k, v in json_input.iteritems():
+                if k == lookup_key:
+                    yield v
+                else:
+                    for child_val in self.item_generator(v, lookup_key):
+                        yield child_val
+        elif isinstance(json_input, list):
+            for item in json_input:
+                for item_val in self.item_generator(item, lookup_key):
+                    yield item_val
+
+    def get_dpn_teps_infos(self):
+        return self.data[self.CONTAINER][self.DPN_TEPS_INFO]
+
+    def get_dpn_teps_info(self, dpn_id):
+        dpn_teps_infos = self.get_dpn_teps_infos()
+        for dpn_teps_info in dpn_teps_infos:
+            if dpn_teps_info[self.DPN_ID] == dpn_id:
+                return dpn_teps_info
+
+    def get_tunnel_endpoints(self, dpn_id):
+        dpn_teps_infos = self.get_dpn_teps_infos()
+        for dpn_teps_info in dpn_teps_infos:
+            if dpn_teps_info[self.DPN_ID] == dpn_id:
+                return dpn_teps_info[self.TUNNEL_END_POINTS]
+
+    def get_dpn_ids(self):
+        return self.get_kv(DpnEndpoints.DPN_ID, self.data, values=[])
+
+    def get_ip_address(self, dpn_id):
+        tunnel_endpoints = self.get_tunnel_endpoints(dpn_id)
+        return tunnel_endpoints[0][self.IP_ADDRESS]
+
+
+def dpn_endpoints(store, ip, port, debug=0):
+    return DpnEndpoints(name, DpnEndpoints.CONTAINER, store, ip, port, debug)
diff --git a/resources/tools/odl/mdsal/models.py b/resources/tools/odl/mdsal/models.py
new file mode 100644 (file)
index 0000000..34d6e8b
--- /dev/null
@@ -0,0 +1,57 @@
+import json
+import request
+
+
+class Model:
+    CONFIG = "config"
+    OPERATIONAL = "operational"
+    USER = "admin"
+    PW = "admin"
+
+    def __init__(self, name, container, store, ip, port, debug=0):
+        self.name = name
+        self.CONTAINER = container
+        self.store = store
+        self.ip = ip
+        self.port = port
+        self.debug = debug
+        self.data = None
+        self.url = self.make_url()
+
+    def set_debug(self, level):
+        self.debug = level
+
+    def set_odl_address(self, ip, port):
+        self.ip = ip
+        self.port = port
+
+    def make_url(self):
+        url = "http://{}:{}/restconf/{}/{}:{}".format(self.ip, self.port, self.store,
+                                                      self.name, self.CONTAINER)
+        return url
+
+    def get_from_odl(self):
+        self.data = request.get(self.url, self.USER, self.PW)
+        return self.data
+
+    def get_from_file(self, filename):
+        self.data = request.get_from_file(filename)
+        return self.data
+
+    def pretty_format(self, data=None):
+        if data is None:
+            data = self.data
+        return json.dumps(data, indent=4, separators=(',', ': '))
+
+    def get_kv(self, k, v, values):
+        if type(v) is dict:
+            for jsonkey in v:
+                if jsonkey == k:
+                    values.append(v[jsonkey])
+                elif type(v[jsonkey]) in (list, dict):
+                    self.get_kv(k, v[jsonkey], values)
+        elif type(v) is list:
+            for item in v:
+                if type(item) in (list, dict):
+                    self.get_kv(k, item, values)
+        return values
diff --git a/resources/tools/odl/mdsal/request.py b/resources/tools/odl/mdsal/request.py
new file mode 100644 (file)
index 0000000..69b2f06
--- /dev/null
@@ -0,0 +1,33 @@
+import json
+import logging
+import requests
+
+
+logging.basicConfig(format="%(levelname)-8s [%(module)s:%(lineno)d] %(message)s",
+                    level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def set_log_level(level):
+    logger.setLevel(level)
+
+
+def debug_print(text1, data):
+    logger.debug("request: %s", text1)
+    logger.debug("%s", json.dumps(data))
+    logger.debug("%s", json.dumps(data, indent=4, separators=(',', ': ')))
+
+
+def get(url, user, pw):
+    resp = requests.get(url, auth=(user, pw))
+    # TODO: add error checking of the response
+    data = resp.json()
+    debug_print(url, data)
+    return data
+
+
+def get_from_file(filename):
+    with open(filename) as json_file:
+        data = json.load(json_file)
+    debug_print(filename, data)
+    return data
diff --git a/resources/tools/odl/mdsal/test_itm_state.py b/resources/tools/odl/mdsal/test_itm_state.py
new file mode 100644 (file)
index 0000000..00f81c5
--- /dev/null
@@ -0,0 +1,49 @@
+import unittest
+import itm_state
+from models import Model
+from itm_state import DpnEndpoints
+
+
+ip = "127.0.0.1"
+port = "8080"
+
+
+class TestItmState(unittest.TestCase):
+    def setUp(self):
+        self.dpn_endpoints = itm_state.DpnEndpoints(self, DpnEndpoints.CONTAINER, Model.CONFIG, ip, port, 1)
+        self.data = self.dpn_endpoints.get_from_file("itm-state_dpn-endpoints.json")
+
+    def test_get_from_file(self):
+        print "dpn-endpoints: {}".format(self.data)
+        print "dpn-endpoints: \n{}".format(self.dpn_endpoints.pretty_format(self.data))
+
+    def test_get_ip_address(self):
+        dpn_ids = self.dpn_endpoints.get_dpn_ids()
+        dpn_id = dpn_ids[0]
+        ip_address = self.dpn_endpoints.get_ip_address(dpn_id)
+        print "dpn_id: {}, ip_address: {}".format(dpn_id, ip_address)
+
+    def test_get_all(self):
+        print "dpn-endpoints: {}".format(self.data)
+        print "dpn-endpoints: \n{}".format(self.dpn_endpoints.pretty_format(self.data))
+
+        dpn_ids = self.dpn_endpoints.get_dpn_ids()
+        dpn_id = dpn_ids[0]
+        dpn_teps_info = self.dpn_endpoints.get_dpn_teps_info(dpn_id)
+        print "dpn_teps_info for {}: {}".format(dpn_id, dpn_teps_info)
+
+        ip_address = self.dpn_endpoints.get_ip_address(dpn_id)
+        print "ip_address: {}".format(ip_address)
+
+        self.get_info(DpnEndpoints.CONTAINER)
+        self.get_info(DpnEndpoints.DPN_TEPS_INFO)
+        self.get_info(DpnEndpoints.TUNNEL_END_POINTS)
+        self.get_info(DpnEndpoints.DPN_ID)
+
+    def get_info(self, key):
+        info = self.dpn_endpoints.get_kv(key, self.data, values=[])
+        print "dpn info for {}: {}".format(key, info)
+        return info
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/resources/tools/odl/mdsal/test_request.py b/resources/tools/odl/mdsal/test_request.py
new file mode 100644 (file)
index 0000000..4614d84
--- /dev/null
@@ -0,0 +1,16 @@
+import logging
+import unittest
+import request
+
+
+class TestRequest(unittest.TestCase):
+    def setUp(self):
+        self.filename = "./itm-state_dpn-endpoints.json"
+
+    def test_get_from_file(self):
+        request.logger.setLevel(logging.DEBUG)
+        self.data = request.get_from_file(self.filename)
+        self.assertIsNotNone(self.data)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/resources/tools/odl/ovs/__init__.py b/resources/tools/odl/ovs/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/resources/tools/odl/ovs/flow_dumps.1.txt b/resources/tools/odl/ovs/flow_dumps.1.txt
new file mode 100644 (file)
index 0000000..b6da6b6
--- /dev/null
@@ -0,0 +1,76 @@
+OFPST_FLOW reply (OF1.3) (xid=0x2):
+ cookie=0x8000000, duration=235.254s, table=0, n_packets=237, n_bytes=24237, priority=4,in_port=2,vlan_tci=0x0000/0x1fff actions=write_metadata:0x10000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=234.432s, table=0, n_packets=94, n_bytes=10434, priority=4,in_port=1,vlan_tci=0x0000/0x1fff actions=write_metadata:0x30000000001/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=234.394s, table=0, n_packets=360, n_bytes=35472, priority=10,in_port=1,dl_vlan=1235 actions=pop_vlan,write_metadata:0x20000000001/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=230.969s, table=0, n_packets=237, n_bytes=24239, priority=4,in_port=3,vlan_tci=0x0000/0x1fff actions=write_metadata:0x40000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000001, duration=189.493s, table=0, n_packets=494, n_bytes=41194, priority=5,in_port=4 actions=write_metadata:0xe0000000001/0xfffff0000000001,goto_table:36
+ cookie=0x8000001, duration=185.987s, table=0, n_packets=371, n_bytes=29567, priority=5,in_port=5 actions=write_metadata:0x120000000001/0xfffff0000000001,goto_table:36
+ cookie=0x8040000, duration=234.275s, table=17, n_packets=234, n_bytes=23979, priority=10,metadata=0x10000000000/0xffffff0000000000 actions=load:0x1->NXM_NX_REG1[0..19],load:0x138a->NXM_NX_REG7[0..15],write_metadata:0xa00001138a000000/0xfffffffffffffffe,goto_table:48
+ cookie=0x8040000, duration=233.993s, table=17, n_packets=360, n_bytes=35472, priority=10,metadata=0x20000000000/0xffffff0000000000 actions=load:0x2->NXM_NX_REG1[0..19],load:0x138a->NXM_NX_REG7[0..15],write_metadata:0xa00002138a000000/0xfffffffffffffffe,goto_table:48
+ cookie=0x8040000, duration=230.023s, table=17, n_packets=235, n_bytes=24059, priority=10,metadata=0x40000000000/0xffffff0000000000 actions=load:0x4->NXM_NX_REG1[0..19],load:0x138b->NXM_NX_REG7[0..15],write_metadata:0xa00004138b000000/0xfffffffffffffffe,goto_table:48
+ cookie=0x8000000, duration=892.612s, table=17, n_packets=0, n_bytes=0, priority=0,metadata=0x8000000000000000/0xf000000000000000 actions=write_metadata:0x9000000000000000/0xf000000000000000,goto_table:80
+ cookie=0x6800000, duration=892.612s, table=18, n_packets=0, n_bytes=0, priority=0 actions=goto_table:38
+ cookie=0x1080000, duration=892.305s, table=19, n_packets=0, n_bytes=0, priority=100,arp,arp_op=1 actions=group:5000
+ cookie=0x1080000, duration=892.305s, table=19, n_packets=0, n_bytes=0, priority=100,arp,arp_op=2 actions=CONTROLLER:65535,resubmit(,17)
+ cookie=0x1080000, duration=892.305s, table=19, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x1030000, duration=892.305s, table=20, n_packets=0, n_bytes=0, priority=0 actions=goto_table:80
+ cookie=0x8000004, duration=892.305s, table=22, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:65535
+ cookie=0x1080000, duration=892.305s, table=23, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x900138b, duration=230.032s, table=36, n_packets=361, n_bytes=34122, priority=5,tun_id=0x29 actions=write_metadata:0x138b000000/0xfffffffff000000,goto_table:51
+ cookie=0x905138b, duration=230.963s, table=38, n_packets=0, n_bytes=0, priority=5,tun_id=0x29 actions=write_metadata:0x138b000000/0xfffffffff000000,goto_table:51
+ cookie=0x4000000, duration=892.612s, table=45, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x8500000, duration=892.612s, table=48, n_packets=829, n_bytes=83510, priority=0 actions=resubmit(,49),resubmit(,50)
+ cookie=0x805138a, duration=234.282s, table=50, n_packets=234, n_bytes=23979, priority=20,metadata=0x1138a000000/0xfffffffff000000,dl_src=fa:16:3e:45:bb:7e actions=goto_table:51
+ cookie=0x805138b, duration=230.032s, table=50, n_packets=235, n_bytes=24059, priority=20,metadata=0x4138b000000/0xfffffffff000000,dl_src=fa:16:3e:49:40:92 actions=goto_table:51
+ cookie=0x805138a, duration=193.107s, table=50, n_packets=119, n_bytes=11504, idle_timeout=300, send_flow_rem priority=20,metadata=0x2138a000000/0xfffffffff000000,dl_src=fa:16:3e:15:a8:66 actions=goto_table:51
+ cookie=0x805138a, duration=189.328s, table=50, n_packets=119, n_bytes=11710, idle_timeout=300, send_flow_rem priority=20,metadata=0x2138a000000/0xfffffffff000000,dl_src=fa:16:3e:40:3c:52 actions=goto_table:51
+ cookie=0x805138a, duration=186.748s, table=50, n_packets=119, n_bytes=11758, idle_timeout=300, send_flow_rem priority=20,metadata=0x2138a000000/0xfffffffff000000,dl_src=fa:16:3e:a6:83:5f actions=goto_table:51
+ cookie=0x8050001, duration=892.612s, table=50, n_packets=0, n_bytes=0, priority=10,reg4=0x1 actions=goto_table:51
+ cookie=0x8050000, duration=892.612s, table=50, n_packets=3, n_bytes=500, priority=0 actions=CONTROLLER:65535,learn(table=49,hard_timeout=10,priority=0,cookie=0x8600000,NXM_OF_ETH_SRC[],NXM_NX_REG1[0..19],load:0x1->NXM_NX_REG4[0..7]),goto_table:51
+ cookie=0x803138a, duration=234.287s, table=51, n_packets=310, n_bytes=30940, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:45:bb:7e actions=load:0x100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=230.032s, table=51, n_packets=310, n_bytes=29700, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:49:40:92 actions=load:0x400->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=193.107s, table=51, n_packets=72, n_bytes=7708, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:15:a8:66 actions=load:0x200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=189.458s, table=51, n_packets=72, n_bytes=7708, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:0d:3c:40 actions=set_field:0x29->tun_id,load:0xe00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=189.328s, table=51, n_packets=73, n_bytes=7753, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:40:3c:52 actions=load:0x200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=186.748s, table=51, n_packets=72, n_bytes=7708, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:a6:83:5f actions=load:0x200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=186.226s, table=51, n_packets=73, n_bytes=7753, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:56:2a:79 actions=set_field:0x29->tun_id,load:0x1200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=183.394s, table=51, n_packets=72, n_bytes=7710, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:22:f8:a6 actions=set_field:0x29->tun_id,load:0xe00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8030000, duration=892.612s, table=51, n_packets=0, n_bytes=0, priority=15,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
+ cookie=0x8030000, duration=892.612s, table=51, n_packets=136, n_bytes=10652, priority=0 actions=goto_table:52
+ cookie=0x870138a, duration=234.282s, table=52, n_packets=17, n_bytes=810, priority=5,metadata=0x138a000000/0xffff000001 actions=write_actions(group:210004)
+ cookie=0x870138a, duration=234.282s, table=52, n_packets=50, n_bytes=4532, priority=5,metadata=0x138a000001/0xffff000001 actions=write_actions(group:210003)
+ cookie=0x870138b, duration=230.032s, table=52, n_packets=51, n_bytes=4422, priority=5,metadata=0x138b000001/0xffff000001 actions=write_actions(group:210005)
+ cookie=0x870138b, duration=230.032s, table=52, n_packets=18, n_bytes=888, priority=5,metadata=0x138b000000/0xffff000001 actions=write_actions(group:210006)
+ cookie=0x8800001, duration=234.282s, table=55, n_packets=17, n_bytes=810, priority=10,tun_id=0x1,metadata=0x10000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800002, duration=233.996s, table=55, n_packets=0, n_bytes=0, priority=10,tun_id=0x2,metadata=0x20000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800004, duration=230.032s, table=55, n_packets=18, n_bytes=888, priority=10,tun_id=0x4,metadata=0x40000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800001, duration=234.282s, table=55, n_packets=50, n_bytes=4532, priority=9,tun_id=0x1 actions=load:0x100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8800002, duration=233.996s, table=55, n_packets=0, n_bytes=0, priority=9,tun_id=0x2 actions=load:0x200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8800004, duration=230.032s, table=55, n_packets=51, n_bytes=4422, priority=9,tun_id=0x4 actions=load:0x400->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x6800000, duration=892.612s, table=60, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x1030000, duration=892.305s, table=80, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x8220000, duration=892.305s, table=81, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x4000001, duration=892.612s, table=90, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=892.640s, table=211, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x6900000, duration=892.612s, table=212, n_packets=0, n_bytes=0, priority=0 actions=goto_table:213
+ cookie=0x6900000, duration=892.612s, table=213, n_packets=0, n_bytes=0, priority=62020,ct_state=-new+est-rel-inv+trk actions=resubmit(,17)
+ cookie=0x6900000, duration=892.612s, table=213, n_packets=0, n_bytes=0, priority=62020,ct_state=-new-est+rel-inv+trk actions=resubmit(,17)
+ cookie=0x6900000, duration=892.612s, table=213, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x8000007, duration=234.289s, table=220, n_packets=0, n_bytes=0, priority=10,reg6=0x200,metadata=0x1/0x1 actions=drop
+ cookie=0x8000007, duration=234.289s, table=220, n_packets=0, n_bytes=0, priority=10,reg6=0x300,metadata=0x1/0x1 actions=drop
+ cookie=0x8000007, duration=235.106s, table=220, n_packets=360, n_bytes=35472, priority=9,reg6=0x100 actions=output:2
+ cookie=0x8000007, duration=234.289s, table=220, n_packets=234, n_bytes=23979, priority=9,reg6=0x200 actions=push_vlan:0x8100,set_field:5331->vlan_vid,output:1
+ cookie=0x8000007, duration=234.289s, table=220, n_packets=0, n_bytes=0, priority=9,reg6=0x300 actions=output:1
+ cookie=0x8000007, duration=230.956s, table=220, n_packets=361, n_bytes=34122, priority=9,reg6=0x400 actions=output:3
+ cookie=0x8000007, duration=189.455s, table=220, n_packets=159, n_bytes=16048, priority=9,reg6=0x90000e00 actions=output:4
+ cookie=0x8000230, duration=189.455s, table=220, n_packets=159, n_bytes=16048, priority=6,reg6=0xe00 actions=load:0x90000e00->NXM_NX_REG6[],write_metadata:0/0xfffffffffe,goto_table:230
+ cookie=0x8000230, duration=186.232s, table=220, n_packets=88, n_bytes=8383, priority=6,reg6=0x1200 actions=load:0x90001200->NXM_NX_REG6[],write_metadata:0/0xfffffffffe,goto_table:230
+ cookie=0x8000007, duration=186.232s, table=220, n_packets=88, n_bytes=8383, priority=9,reg6=0x90001200 actions=output:5
+ cookie=0x8000230, duration=892.612s, table=230, n_packets=247, n_bytes=24431, priority=0 actions=resubmit(,220)
+ cookie=0x8000231, duration=892.612s, table=231, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=892.612s, table=241, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x6900000, duration=892.612s, table=242, n_packets=0, n_bytes=0, priority=0 actions=goto_table:243
+ cookie=0x6900000, duration=892.612s, table=243, n_packets=0, n_bytes=0, priority=62020,ct_state=-new+est-rel-inv+trk actions=resubmit(,220)
+ cookie=0x6900000, duration=892.612s, table=243, n_packets=0, n_bytes=0, priority=62020,ct_state=-new-est+rel-inv+trk actions=resubmit(,220)
+ cookie=0x6900000, duration=892.612s, table=243, n_packets=0, n_bytes=0, priority=0 actions=drop
+ [jenkins@releng-22320-97-2-devstack-ocata-0 ~]>
\ No newline at end of file
diff --git a/resources/tools/odl/ovs/flow_dumps.2.txt b/resources/tools/odl/ovs/flow_dumps.2.txt
new file mode 100644 (file)
index 0000000..699c1d5
--- /dev/null
@@ -0,0 +1,241 @@
+OFPST_FLOW reply (OF1.3) (xid=0x2):
+ cookie=0x8000000, duration=318.152s, table=0, n_packets=122, n_bytes=11492, priority=4,in_port=2,vlan_tci=0x0000/0x1fff actions=write_metadata:0x90000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=318.123s, table=0, n_packets=122, n_bytes=11492, priority=4,in_port=3,vlan_tci=0x0000/0x1fff actions=write_metadata:0xa0000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=318.091s, table=0, n_packets=128, n_bytes=14336, priority=4,in_port=1,vlan_tci=0x0000/0x1fff actions=write_metadata:0xc0000000001/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=318.068s, table=0, n_packets=194, n_bytes=19716, priority=10,in_port=1,dl_vlan=1235 actions=pop_vlan,write_metadata:0xb0000000001/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=310.235s, table=0, n_packets=122, n_bytes=11492, priority=4,in_port=4,vlan_tci=0x0000/0x1fff actions=write_metadata:0x110000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000000, duration=310.104s, table=0, n_packets=117, n_bytes=11114, priority=4,in_port=5,vlan_tci=0x0000/0x1fff actions=write_metadata:0x120000000000/0xffffff0000000001,goto_table:17
+ cookie=0x8000001, duration=309.236s, table=0, n_packets=569, n_bytes=45876, priority=5,in_port=6 actions=write_metadata:0x130000000001/0xfffff0000000001,goto_table:36
+ cookie=0x8000001, duration=308.726s, table=0, n_packets=447, n_bytes=32996, priority=5,in_port=7 actions=write_metadata:0x140000000001/0xfffff0000000001,goto_table:36
+ cookie=0x8040000, duration=317.500s, table=17, n_packets=121, n_bytes=11402, priority=10,metadata=0x90000a0000000000/0xffffff0000000000 actions=load:0xa->NXM_NX_REG1[0..19],load:0x138a->NXM_NX_REG7[0..15],write_metadata:0xa0000a138a000000/0xfffffffffffffffe,goto_table:43
+ cookie=0x6900000, duration=317.497s, table=17, n_packets=122, n_bytes=11492, priority=10,metadata=0xa0000000000/0xffffff0000000000 actions=write_metadata:0x90000a138a000000/0xfffffffffffffffe,goto_table:211
+ cookie=0x6900000, duration=317.496s, table=17, n_packets=122, n_bytes=11492, priority=10,metadata=0x90000000000/0xffffff0000000000 actions=write_metadata:0x900009138a000000/0xfffffffffffffffe,goto_table:211
+ cookie=0x8040000, duration=317.495s, table=17, n_packets=121, n_bytes=11402, priority=10,metadata=0x9000090000000000/0xffffff0000000000 actions=load:0x9->NXM_NX_REG1[0..19],load:0x138a->NXM_NX_REG7[0..15],write_metadata:0xa00009138a000000/0xfffffffffffffffe,goto_table:43
+ cookie=0x8040000, duration=317.180s, table=17, n_packets=194, n_bytes=19716, priority=10,metadata=0xb0000000000/0xffffff0000000000 actions=load:0xb->NXM_NX_REG1[0..19],load:0x138a->NXM_NX_REG7[0..15],write_metadata:0xa0000b138a000000/0xfffffffffffffffe,goto_table:43
+ cookie=0x8040000, duration=309.237s, table=17, n_packets=121, n_bytes=11402, priority=10,metadata=0x9000110000000000/0xffffff0000000000 actions=load:0x11->NXM_NX_REG1[0..19],load:0x138b->NXM_NX_REG7[0..15],write_metadata:0xa00011138b000000/0xfffffffffffffffe,goto_table:43
+ cookie=0x6900000, duration=309.237s, table=17, n_packets=122, n_bytes=11492, priority=10,metadata=0x110000000000/0xffffff0000000000 actions=write_metadata:0x900011138b000000/0xfffffffffffffffe,goto_table:211
+ cookie=0x6900000, duration=309.230s, table=17, n_packets=117, n_bytes=11114, priority=10,metadata=0x120000000000/0xffffff0000000000 actions=write_metadata:0x900012138b000000/0xfffffffffffffffe,goto_table:211
+ cookie=0x8040000, duration=309.230s, table=17, n_packets=116, n_bytes=11024, priority=10,metadata=0x9000120000000000/0xffffff0000000000 actions=load:0x12->NXM_NX_REG1[0..19],load:0x138b->NXM_NX_REG7[0..15],write_metadata:0xa00012138b000000/0xfffffffffffffffe,goto_table:43
+ cookie=0x8000000, duration=1686.215s, table=17, n_packets=0, n_bytes=0, priority=0,metadata=0x8000000000000000/0xf000000000000000 actions=write_metadata:0x9000000000000000/0xf000000000000000,goto_table:80
+ cookie=0x6800000, duration=1686.215s, table=18, n_packets=0, n_bytes=0, priority=0 actions=goto_table:38
+ cookie=0x8220015, duration=1686.215s, table=19, n_packets=0, n_bytes=0, priority=100,arp,arp_op=1 actions=resubmit(,17)
+ cookie=0x8220016, duration=1686.215s, table=19, n_packets=0, n_bytes=0, priority=100,arp,arp_op=2 actions=resubmit(,17)
+ cookie=0x1080000, duration=1686.215s, table=19, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x1030000, duration=1686.215s, table=20, n_packets=0, n_bytes=0, priority=0 actions=goto_table:80
+ cookie=0x8000004, duration=1686.215s, table=22, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:65535
+ cookie=0x1080000, duration=1686.215s, table=23, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x900138b, duration=309.237s, table=36, n_packets=190, n_bytes=18652, priority=5,tun_id=0x34 actions=write_metadata:0x138b000000/0xfffffffff000000,goto_table:51
+ cookie=0x905138b, duration=310.228s, table=38, n_packets=0, n_bytes=0, priority=5,tun_id=0x34 actions=write_metadata:0x138b000000/0xfffffffff000000,goto_table:51
+ cookie=0x822002d, duration=1685.424s, table=43, n_packets=81, n_bytes=3546, priority=100,arp,arp_op=1 actions=group:5000
+ cookie=0x822002e, duration=1685.424s, table=43, n_packets=6, n_bytes=272, priority=100,arp,arp_op=2 actions=CONTROLLER:65535,resubmit(,48)
+ cookie=0x8220000, duration=1685.712s, table=43, n_packets=586, n_bytes=61128, priority=0 actions=goto_table:48
+ cookie=0x4000000, duration=1686.215s, table=45, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x8500000, duration=1686.215s, table=48, n_packets=673, n_bytes=64946, priority=0 actions=resubmit(,49),resubmit(,50)
+ cookie=0x805138a, duration=317.503s, table=50, n_packets=121, n_bytes=11402, priority=20,metadata=0xa138a000000/0xfffffffff000000,dl_src=fa:16:3e:44:18:de actions=goto_table:51
+ cookie=0x805138a, duration=317.497s, table=50, n_packets=121, n_bytes=11402, priority=20,metadata=0x9138a000000/0xfffffffff000000,dl_src=fa:16:3e:1a:f1:a3 actions=goto_table:51
+ cookie=0x805138b, duration=309.237s, table=50, n_packets=121, n_bytes=11402, priority=20,metadata=0x11138b000000/0xfffffffff000000,dl_src=fa:16:3e:74:f5:c9 actions=goto_table:51
+ cookie=0x805138b, duration=309.235s, table=50, n_packets=116, n_bytes=11024, priority=20,metadata=0x12138b000000/0xfffffffff000000,dl_src=fa:16:3e:5a:a8:ab actions=goto_table:51
+ cookie=0x805138a, duration=297.357s, table=50, n_packets=15, n_bytes=1366, idle_timeout=300, send_flow_rem priority=20,metadata=0xb138a000000/0xfffffffff000000,dl_src=fa:16:3e:9c:62:1a actions=goto_table:51
+ cookie=0x805138a, duration=297.334s, table=50, n_packets=16, n_bytes=1206, idle_timeout=300, send_flow_rem priority=20,metadata=0xb138a000000/0xfffffffff000000,dl_src=fa:16:3e:42:ee:c0 actions=goto_table:51
+ cookie=0x805138a, duration=297.186s, table=50, n_packets=160, n_bytes=16352, idle_timeout=300, send_flow_rem priority=20,metadata=0xb138a000000/0xfffffffff000000,dl_src=fa:16:3e:73:73:40 actions=goto_table:51
+ cookie=0x8050001, duration=1685.847s, table=50, n_packets=0, n_bytes=0, priority=10,reg4=0x1 actions=goto_table:51
+ cookie=0x8050000, duration=1686.215s, table=50, n_packets=3, n_bytes=792, priority=0 actions=CONTROLLER:65535,learn(table=49,hard_timeout=10,priority=0,cookie=0x8600000,NXM_OF_ETH_SRC[],NXM_NX_REG1[0..19],load:0x1->NXM_NX_REG4[0..7]),goto_table:51
+ cookie=0x803138a, duration=317.503s, table=51, n_packets=73, n_bytes=8018, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:44:18:de actions=load:0xa00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=317.497s, table=51, n_packets=73, n_bytes=8018, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:1a:f1:a3 actions=load:0x900->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=309.237s, table=51, n_packets=73, n_bytes=7726, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:74:f5:c9 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=309.235s, table=51, n_packets=68, n_bytes=7348, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:5a:a8:ab actions=load:0x1200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=309.126s, table=51, n_packets=203, n_bytes=19478, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:13:c2:6a actions=set_field:0x34->tun_id,load:0x1300->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=308.604s, table=51, n_packets=0, n_bytes=0, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:c9:f6:37 actions=set_field:0x34->tun_id,load:0x1400->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138b, duration=308.604s, table=51, n_packets=0, n_bytes=0, priority=20,metadata=0x138b000000/0xffff000000,dl_dst=fa:16:3e:78:ae:5d actions=set_field:0x34->tun_id,load:0x1400->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=297.357s, table=51, n_packets=0, n_bytes=0, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:9c:62:1a actions=load:0xb00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=297.334s, table=51, n_packets=0, n_bytes=0, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:42:ee:c0 actions=load:0xb00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x803138a, duration=297.186s, table=51, n_packets=208, n_bytes=19856, priority=20,metadata=0x138a000000/0xffff000000,dl_dst=fa:16:3e:73:73:40 actions=load:0xb00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8030000, duration=1685.712s, table=51, n_packets=0, n_bytes=0, priority=15,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
+ cookie=0x8030000, duration=1685.847s, table=51, n_packets=165, n_bytes=13154, priority=0 actions=goto_table:52
+ cookie=0x870138a, duration=317.497s, table=52, n_packets=34, n_bytes=2948, priority=5,metadata=0x138a000000/0xffff000001 actions=write_actions(group:210004)
+ cookie=0x870138a, duration=317.497s, table=52, n_packets=48, n_bytes=3680, priority=5,metadata=0x138a000001/0xffff000001 actions=write_actions(group:210003)
+ cookie=0x870138b, duration=309.237s, table=52, n_packets=49, n_bytes=3578, priority=5,metadata=0x138b000001/0xffff000001 actions=write_actions(group:210005)
+ cookie=0x870138b, duration=309.237s, table=52, n_packets=34, n_bytes=2948, priority=5,metadata=0x138b000000/0xffff000001 actions=write_actions(group:210006)
+ cookie=0x880000a, duration=317.503s, table=55, n_packets=17, n_bytes=1474, priority=10,tun_id=0xa,metadata=0xa0000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800009, duration=317.497s, table=55, n_packets=17, n_bytes=1474, priority=10,tun_id=0x9,metadata=0x90000000000/0xfffff0000000000 actions=drop
+ cookie=0x880000b, duration=317.188s, table=55, n_packets=0, n_bytes=0, priority=10,tun_id=0xb,metadata=0xb0000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800011, duration=309.237s, table=55, n_packets=17, n_bytes=1474, priority=10,tun_id=0x11,metadata=0x110000000000/0xfffff0000000000 actions=drop
+ cookie=0x8800012, duration=309.235s, table=55, n_packets=17, n_bytes=1474, priority=10,tun_id=0x12,metadata=0x120000000000/0xfffff0000000000 actions=drop
+ cookie=0x880000a, duration=317.503s, table=55, n_packets=65, n_bytes=5154, priority=9,tun_id=0xa actions=load:0xa00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8800009, duration=317.497s, table=55, n_packets=65, n_bytes=5154, priority=9,tun_id=0x9 actions=load:0x900->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x880000b, duration=317.188s, table=55, n_packets=0, n_bytes=0, priority=9,tun_id=0xb actions=load:0xb00->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8800011, duration=309.237s, table=55, n_packets=66, n_bytes=5052, priority=9,tun_id=0x11 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x8800012, duration=309.235s, table=55, n_packets=66, n_bytes=5052, priority=9,tun_id=0x12 actions=load:0x1200->NXM_NX_REG6[],resubmit(,220)
+ cookie=0x6800000, duration=1686.215s, table=60, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x1030000, duration=1686.215s, table=80, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x8220000, duration=1685.712s, table=81, n_packets=81, n_bytes=3546, priority=0 actions=drop
+ cookie=0x4000001, duration=1686.215s, table=90, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=0, n_bytes=0, priority=63010,udp,metadata=0x90000000000/0xfffff0000000000,tp_src=67,tp_dst=68 actions=drop
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x90000000000/0xfffff0000000000,tp_src=547,tp_dst=546 actions=drop
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=0, n_bytes=0, priority=63020,icmp6,metadata=0x90000000000/0xfffff0000000000,icmp_type=134,icmp_code=0 actions=drop
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=3, n_bytes=210, priority=63010,icmp6,metadata=0x90000000000/0xfffff0000000000,icmp_type=133,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=1, n_bytes=78, priority=63010,icmp6,metadata=0x90000000000/0xfffff0000000000,icmp_type=135,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=0, n_bytes=0, priority=63010,icmp6,metadata=0x90000000000/0xfffff0000000000,icmp_type=136,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.828s, table=211, n_packets=0, n_bytes=0, priority=63010,udp,metadata=0xa0000000000/0xfffff0000000000,tp_src=67,tp_dst=68 actions=drop
+ cookie=0x6900000, duration=317.825s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0xa0000000000/0xfffff0000000000,tp_src=547,tp_dst=546 actions=drop
+ cookie=0x6900000, duration=317.823s, table=211, n_packets=0, n_bytes=0, priority=63020,icmp6,metadata=0xa0000000000/0xfffff0000000000,icmp_type=134,icmp_code=0 actions=drop
+ cookie=0x6900000, duration=317.819s, table=211, n_packets=3, n_bytes=210, priority=63010,icmp6,metadata=0xa0000000000/0xfffff0000000000,icmp_type=133,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.817s, table=211, n_packets=1, n_bytes=78, priority=63010,icmp6,metadata=0xa0000000000/0xfffff0000000000,icmp_type=135,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.814s, table=211, n_packets=0, n_bytes=0, priority=63010,icmp6,metadata=0xa0000000000/0xfffff0000000000,icmp_type=136,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.158s, table=211, n_packets=0, n_bytes=0, priority=63010,udp,metadata=0x110000000000/0xfffff0000000000,tp_src=67,tp_dst=68 actions=drop
+ cookie=0x6900000, duration=310.156s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x110000000000/0xfffff0000000000,tp_src=547,tp_dst=546 actions=drop
+ cookie=0x6900000, duration=310.152s, table=211, n_packets=0, n_bytes=0, priority=63020,icmp6,metadata=0x110000000000/0xfffff0000000000,icmp_type=134,icmp_code=0 actions=drop
+ cookie=0x6900000, duration=310.147s, table=211, n_packets=3, n_bytes=210, priority=63010,icmp6,metadata=0x110000000000/0xfffff0000000000,icmp_type=133,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.145s, table=211, n_packets=1, n_bytes=78, priority=63010,icmp6,metadata=0x110000000000/0xfffff0000000000,icmp_type=135,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.142s, table=211, n_packets=0, n_bytes=0, priority=63010,icmp6,metadata=0x110000000000/0xfffff0000000000,icmp_type=136,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=309.999s, table=211, n_packets=0, n_bytes=0, priority=63010,udp,metadata=0x120000000000/0xfffff0000000000,tp_src=67,tp_dst=68 actions=drop
+ cookie=0x6900000, duration=309.997s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x120000000000/0xfffff0000000000,tp_src=547,tp_dst=546 actions=drop
+ cookie=0x6900000, duration=309.995s, table=211, n_packets=0, n_bytes=0, priority=63020,icmp6,metadata=0x120000000000/0xfffff0000000000,icmp_type=134,icmp_code=0 actions=drop
+ cookie=0x6900000, duration=309.993s, table=211, n_packets=3, n_bytes=210, priority=63010,icmp6,metadata=0x120000000000/0xfffff0000000000,icmp_type=133,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=309.990s, table=211, n_packets=1, n_bytes=78, priority=63010,icmp6,metadata=0x120000000000/0xfffff0000000000,icmp_type=135,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=309.988s, table=211, n_packets=0, n_bytes=0, priority=63010,icmp6,metadata=0x120000000000/0xfffff0000000000,icmp_type=136,icmp_code=0 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=2, n_bytes=676, priority=63010,udp,metadata=0x90000000000/0xfffff0000000000,dl_src=fa:16:3e:1a:f1:a3,tp_src=68,tp_dst=67 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.937s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x90000000000/0xfffff0000000000,dl_src=fa:16:3e:1a:f1:a3,tp_src=546,tp_dst=547 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.835s, table=211, n_packets=2, n_bytes=676, priority=63010,udp,metadata=0xa0000000000/0xfffff0000000000,dl_src=fa:16:3e:44:18:de,tp_src=68,tp_dst=67 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.831s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0xa0000000000/0xfffff0000000000,dl_src=fa:16:3e:44:18:de,tp_src=546,tp_dst=547 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.163s, table=211, n_packets=2, n_bytes=676, priority=63010,udp,metadata=0x110000000000/0xfffff0000000000,dl_src=fa:16:3e:74:f5:c9,tp_src=68,tp_dst=67 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.160s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x110000000000/0xfffff0000000000,dl_src=fa:16:3e:74:f5:c9,tp_src=546,tp_dst=547 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.003s, table=211, n_packets=2, n_bytes=676, priority=63010,udp,metadata=0x120000000000/0xfffff0000000000,dl_src=fa:16:3e:5a:a8:ab,tp_src=68,tp_dst=67 actions=resubmit(,17)
+ cookie=0x6900000, duration=310.001s, table=211, n_packets=0, n_bytes=0, priority=63010,udp6,metadata=0x120000000000/0xfffff0000000000,dl_src=fa:16:3e:5a:a8:ab,tp_src=546,tp_dst=547 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.934s, table=211, n_packets=12, n_bytes=504, priority=63010,arp,metadata=0x90000000000/0xfffff0000000000,dl_src=fa:16:3e:1a:f1:a3,arp_spa=30.0.0.4,arp_sha=fa:16:3e:1a:f1:a3 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.810s, table=211, n_packets=12, n_bytes=504, priority=63010,arp,metadata=0xa0000000000/0xfffff0000000000,dl_src=fa:16:3e:44:18:de,arp_spa=30.0.0.8,arp_sha=fa:16:3e:44:18:de actions=resubmit(,17)
+ cookie=0x6900000, duration=310.139s, table=211, n_packets=12, n_bytes=504, priority=63010,arp,metadata=0x110000000000/0xfffff0000000000,dl_src=fa:16:3e:74:f5:c9,arp_spa=40.0.0.6,arp_sha=fa:16:3e:74:f5:c9 actions=resubmit(,17)
+ cookie=0x6900000, duration=309.984s, table=211, n_packets=10, n_bytes=420, priority=63010,arp,metadata=0x120000000000/0xfffff0000000000,dl_src=fa:16:3e:5a:a8:ab,arp_spa=40.0.0.8,arp_sha=fa:16:3e:5a:a8:ab actions=resubmit(,17)
+ cookie=0x6900000, duration=1685.712s, table=211, n_packets=0, n_bytes=0, priority=63009,arp actions=drop
+ cookie=0x6900000, duration=1685.712s, table=211, n_packets=0, n_bytes=0, priority=61009,ip actions=drop
+ cookie=0x6900000, duration=1685.712s, table=211, n_packets=4, n_bytes=360, priority=61009,ipv6 actions=drop
+ cookie=0x6900000, duration=317.923s, table=211, n_packets=1, n_bytes=90, priority=61010,ipv6,dl_src=fa:16:3e:1a:f1:a3,ipv6_src=fe80::f816:3eff:fe1a:f1a3 actions=ct(table=212,zone=5002)
+ cookie=0x6900000, duration=317.799s, table=211, n_packets=1, n_bytes=90, priority=61010,ipv6,dl_src=fa:16:3e:44:18:de,ipv6_src=fe80::f816:3eff:fe44:18de actions=ct(table=212,zone=5002)
+ cookie=0x6900000, duration=310.123s, table=211, n_packets=1, n_bytes=90, priority=61010,ipv6,dl_src=fa:16:3e:74:f5:c9,ipv6_src=fe80::f816:3eff:fe74:f5c9 actions=ct(table=212,zone=5003)
+ cookie=0x6900000, duration=309.976s, table=211, n_packets=1, n_bytes=90, priority=61010,ipv6,dl_src=fa:16:3e:5a:a8:ab,ipv6_src=fe80::f816:3eff:fe5a:a8ab actions=ct(table=212,zone=5003)
+ cookie=0x6900000, duration=317.920s, table=211, n_packets=102, n_bytes=9844, priority=61010,ip,dl_src=fa:16:3e:1a:f1:a3,nw_src=30.0.0.4 actions=ct(table=212,zone=5002)
+ cookie=0x6900000, duration=317.802s, table=211, n_packets=102, n_bytes=9844, priority=61010,ip,dl_src=fa:16:3e:44:18:de,nw_src=30.0.0.8 actions=ct(table=212,zone=5002)
+ cookie=0x6900000, duration=310.119s, table=211, n_packets=102, n_bytes=9844, priority=61010,ip,dl_src=fa:16:3e:74:f5:c9,nw_src=40.0.0.6 actions=ct(table=212,zone=5003)
+ cookie=0x6900000, duration=309.980s, table=211, n_packets=99, n_bytes=9550, priority=61010,ip,dl_src=fa:16:3e:5a:a8:ab,nw_src=40.0.0.8 actions=ct(table=212,zone=5003)
+ cookie=0x6900000, duration=317.927s, table=211, n_packets=0, n_bytes=0, priority=61005,metadata=0x90000000000/0xfffff0000000000,dl_src=fa:16:3e:1a:f1:a3 actions=resubmit(,17)
+ cookie=0x6900000, duration=317.804s, table=211, n_packets=0, n_bytes=0, priority=61005,metadata=0xa0000000000/0xfffff0000000000,dl_src=fa:16:3e:44:18:de actions=resubmit(,17)
+ cookie=0x6900000, duration=310.136s, table=211, n_packets=0, n_bytes=0, priority=61005,metadata=0x110000000000/0xfffff0000000000,dl_src=fa:16:3e:74:f5:c9 actions=resubmit(,17)
+ cookie=0x6900000, duration=309.982s, table=211, n_packets=0, n_bytes=0, priority=61005,metadata=0x120000000000/0xfffff0000000000,dl_src=fa:16:3e:5a:a8:ab actions=resubmit(,17)
+ cookie=0x6900000, duration=1686.215s, table=211, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x6900000, duration=1686.215s, table=212, n_packets=409, n_bytes=39442, priority=0 actions=goto_table:213
+ cookie=0x6900000, duration=1685.847s, table=213, n_packets=325, n_bytes=32890, priority=62020,ct_state=-new+est-rel-inv+trk actions=resubmit(,17)
+ cookie=0x6900000, duration=1685.847s, table=213, n_packets=0, n_bytes=0, priority=62020,ct_state=-new-est+rel-inv+trk actions=resubmit(,17)
+ cookie=0x6900001, duration=317.914s, table=213, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,metadata=0x90000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=317.792s, table=213, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,metadata=0xa0000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=310.100s, table=213, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,metadata=0x110000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=309.969s, table=213, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,metadata=0x120000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900000, duration=317.904s, table=213, n_packets=15, n_bytes=1110, priority=1002,ct_state=+new+trk,tcp,metadata=0x90000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.897s, table=213, n_packets=1, n_bytes=98, priority=1003,ct_state=+new+trk,icmp,metadata=0x90000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.894s, table=213, n_packets=4, n_bytes=340, priority=1004,ct_state=+new+trk,udp,metadata=0x90000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.782s, table=213, n_packets=15, n_bytes=1110, priority=1007,ct_state=+new+trk,tcp,metadata=0xa0000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.779s, table=213, n_packets=1, n_bytes=98, priority=1008,ct_state=+new+trk,icmp,metadata=0xa0000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.776s, table=213, n_packets=4, n_bytes=340, priority=1009,ct_state=+new+trk,udp,metadata=0xa0000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=310.067s, table=213, n_packets=15, n_bytes=1110, priority=1012,ct_state=+new+trk,tcp,metadata=0x110000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=310.062s, table=213, n_packets=1, n_bytes=98, priority=1013,ct_state=+new+trk,icmp,metadata=0x110000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=310.057s, table=213, n_packets=4, n_bytes=340, priority=1014,ct_state=+new+trk,udp,metadata=0x110000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=309.956s, table=213, n_packets=15, n_bytes=1110, priority=1017,ct_state=+new+trk,tcp,metadata=0x120000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=309.952s, table=213, n_packets=1, n_bytes=98, priority=1018,ct_state=+new+trk,icmp,metadata=0x120000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=309.949s, table=213, n_packets=4, n_bytes=340, priority=1019,ct_state=+new+trk,udp,metadata=0x120000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=317.910s, table=213, n_packets=1, n_bytes=90, priority=1000,ct_state=+new+trk,ipv6,metadata=0x90000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.908s, table=213, n_packets=0, n_bytes=0, priority=1001,ct_state=+new+trk,ip,metadata=0x90000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.787s, table=213, n_packets=1, n_bytes=90, priority=1005,ct_state=+new+trk,ipv6,metadata=0xa0000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=317.784s, table=213, n_packets=0, n_bytes=0, priority=1006,ct_state=+new+trk,ip,metadata=0xa0000000000/0xfffff0000000000 actions=ct(commit,zone=5002),resubmit(,17)
+ cookie=0x6900000, duration=310.084s, table=213, n_packets=1, n_bytes=90, priority=1010,ct_state=+new+trk,ipv6,metadata=0x110000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=310.075s, table=213, n_packets=0, n_bytes=0, priority=1011,ct_state=+new+trk,ip,metadata=0x110000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=309.964s, table=213, n_packets=1, n_bytes=90, priority=1015,ct_state=+new+trk,ipv6,metadata=0x120000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900000, duration=309.959s, table=213, n_packets=0, n_bytes=0, priority=1016,ct_state=+new+trk,ip,metadata=0x120000000000/0xfffff0000000000 actions=ct(commit,zone=5003),resubmit(,17)
+ cookie=0x6900001, duration=317.916s, table=213, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,metadata=0x90000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=317.796s, table=213, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,metadata=0xa0000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=310.111s, table=213, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,metadata=0x110000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900001, duration=309.973s, table=213, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,metadata=0x120000000000/0xfffff0000000000 actions=drop
+ cookie=0x6900000, duration=1686.215s, table=213, n_packets=0, n_bytes=0, priority=0 actions=drop
+ cookie=0x8000007, duration=318.041s, table=220, n_packets=0, n_bytes=0, priority=10,reg6=0xb00,metadata=0x1/0x1 actions=drop
+ cookie=0x8000007, duration=318.041s, table=220, n_packets=0, n_bytes=0, priority=10,reg6=0xc00,metadata=0x1/0x1 actions=drop
+ cookie=0x8000007, duration=318.069s, table=220, n_packets=121, n_bytes=10018, priority=9,reg6=0x90000900 actions=output:2
+ cookie=0x6900000, duration=318.069s, table=220, n_packets=138, n_bytes=13172, priority=6,reg6=0x900 actions=load:0x90000900->NXM_NX_REG6[],write_metadata:0x138a000000/0xfffffffffe,goto_table:239
+ cookie=0x8000007, duration=318.059s, table=220, n_packets=121, n_bytes=10018, priority=9,reg6=0x90000a00 actions=output:3
+ cookie=0x6900000, duration=318.059s, table=220, n_packets=138, n_bytes=13172, priority=6,reg6=0xa00 actions=load:0x90000a00->NXM_NX_REG6[],write_metadata:0x138a000000/0xfffffffffe,goto_table:239
+ cookie=0x8000007, duration=318.041s, table=220, n_packets=242, n_bytes=22804, priority=9,reg6=0xb00 actions=push_vlan:0x8100,set_field:5331->vlan_vid,output:1
+ cookie=0x8000007, duration=318.041s, table=220, n_packets=0, n_bytes=0, priority=9,reg6=0xc00 actions=output:1
+ cookie=0x6900000, duration=310.210s, table=220, n_packets=139, n_bytes=12778, priority=6,reg6=0x1100 actions=load:0x90001100->NXM_NX_REG6[],write_metadata:0x138b000000/0xfffffffffe,goto_table:239
+ cookie=0x8000007, duration=310.210s, table=220, n_packets=121, n_bytes=9850, priority=9,reg6=0x90001100 actions=output:4
+ cookie=0x8000007, duration=310.079s, table=220, n_packets=116, n_bytes=9472, priority=9,reg6=0x90001200 actions=output:5
+ cookie=0x6900000, duration=310.079s, table=220, n_packets=134, n_bytes=12400, priority=6,reg6=0x1200 actions=load:0x90001200->NXM_NX_REG6[],write_metadata:0x138b000000/0xfffffffffe,goto_table:239
+ cookie=0x8000007, duration=309.134s, table=220, n_packets=237, n_bytes=22426, priority=9,reg6=0x90001300 actions=output:6
+ cookie=0x8000230, duration=309.134s, table=220, n_packets=237, n_bytes=22426, priority=6,reg6=0x1300 actions=load:0x90001300->NXM_NX_REG6[],write_metadata:0/0xfffffffffe,goto_table:230
+ cookie=0x8000007, duration=308.621s, table=220, n_packets=34, n_bytes=2948, priority=9,reg6=0x90001400 actions=output:7
+ cookie=0x8000230, duration=308.621s, table=220, n_packets=34, n_bytes=2948, priority=6,reg6=0x1400 actions=load:0x90001400->NXM_NX_REG6[],write_metadata:0/0xfffffffffe,goto_table:230
+ cookie=0x8000230, duration=1686.215s, table=230, n_packets=271, n_bytes=25374, priority=0 actions=resubmit(,220)
+ cookie=0x8000231, duration=1686.215s, table=231, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=1685.712s, table=239, n_packets=0, n_bytes=0, priority=62020,ct_state=+trk,ip actions=ct(table=241)
+ cookie=0x6900000, duration=1685.712s, table=239, n_packets=4, n_bytes=360, priority=62020,ct_state=+trk,ipv6 actions=ct(table=241)
+ cookie=0x6900000, duration=1685.712s, table=239, n_packets=545, n_bytes=51162, priority=61010 actions=goto_table:241
+ cookie=0x6900000, duration=318.124s, table=241, n_packets=2, n_bytes=763, priority=63010,udp,reg6=0x900/0xfffff00,tp_src=67,tp_dst=68 actions=resubmit(,220)
+ cookie=0x6900000, duration=318.092s, table=241, n_packets=0, n_bytes=0, priority=63010,udp6,reg6=0x900/0xfffff00,tp_src=547,tp_dst=546 actions=resubmit(,220)
+ cookie=0x6900000, duration=318.069s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x900/0xfffff00,icmp_type=130,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=318.041s, table=241, n_packets=3, n_bytes=242, priority=63010,icmp6,reg6=0x900/0xfffff00,icmp_type=135,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=318.041s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x900/0xfffff00,icmp_type=136,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.888s, table=241, n_packets=2, n_bytes=763, priority=63010,udp,reg6=0xa00/0xfffff00,tp_src=67,tp_dst=68 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.885s, table=241, n_packets=0, n_bytes=0, priority=63010,udp6,reg6=0xa00/0xfffff00,tp_src=547,tp_dst=546 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.880s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0xa00/0xfffff00,icmp_type=130,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.876s, table=241, n_packets=3, n_bytes=242, priority=63010,icmp6,reg6=0xa00/0xfffff00,icmp_type=135,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.876s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0xa00/0xfffff00,icmp_type=136,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.228s, table=241, n_packets=2, n_bytes=755, priority=63010,udp,reg6=0x1100/0xfffff00,tp_src=67,tp_dst=68 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.220s, table=241, n_packets=0, n_bytes=0, priority=63010,udp6,reg6=0x1100/0xfffff00,tp_src=547,tp_dst=546 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.214s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x1100/0xfffff00,icmp_type=130,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.207s, table=241, n_packets=3, n_bytes=234, priority=63010,icmp6,reg6=0x1100/0xfffff00,icmp_type=135,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.202s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x1100/0xfffff00,icmp_type=136,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.052s, table=241, n_packets=2, n_bytes=755, priority=63010,udp,reg6=0x1200/0xfffff00,tp_src=67,tp_dst=68 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.050s, table=241, n_packets=0, n_bytes=0, priority=63010,udp6,reg6=0x1200/0xfffff00,tp_src=547,tp_dst=546 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.046s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x1200/0xfffff00,icmp_type=130,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.044s, table=241, n_packets=3, n_bytes=234, priority=63010,icmp6,reg6=0x1200/0xfffff00,icmp_type=135,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.041s, table=241, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x1200/0xfffff00,icmp_type=136,icmp_code=0 actions=resubmit(,220)
+ cookie=0x6900000, duration=318.035s, table=241, n_packets=48, n_bytes=2168, priority=63010,arp,reg6=0x900/0xfffff00 actions=resubmit(,220)
+ cookie=0x6900000, duration=317.872s, table=241, n_packets=48, n_bytes=2168, priority=63010,arp,reg6=0xa00/0xfffff00 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.196s, table=241, n_packets=48, n_bytes=2016, priority=63010,arp,reg6=0x1100/0xfffff00 actions=resubmit(,220)
+ cookie=0x6900000, duration=310.038s, table=241, n_packets=46, n_bytes=1932, priority=63010,arp,reg6=0x1200/0xfffff00 actions=resubmit(,220)
+ cookie=0x6900000, duration=1685.712s, table=241, n_packets=24, n_bytes=8144, priority=61010,ip,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=255.255.255.255 actions=goto_table:242
+ cookie=0x6900000, duration=318.013s, table=241, n_packets=68, n_bytes=7117, priority=61010,ip,dl_dst=fa:16:3e:1a:f1:a3,nw_dst=30.0.0.4 actions=ct(table=242,zone=5002)
+ cookie=0x6900000, duration=317.866s, table=241, n_packets=68, n_bytes=7117, priority=61010,ip,dl_dst=fa:16:3e:44:18:de,nw_dst=30.0.0.8 actions=ct(table=242,zone=5002)
+ cookie=0x6900000, duration=310.173s, table=241, n_packets=68, n_bytes=6845, priority=61010,ip,dl_dst=fa:16:3e:74:f5:c9,nw_dst=40.0.0.6 actions=ct(table=242,zone=5003)
+ cookie=0x6900000, duration=310.032s, table=241, n_packets=65, n_bytes=6551, priority=61010,ip,dl_dst=fa:16:3e:5a:a8:ab,nw_dst=40.0.0.8 actions=ct(table=242,zone=5003)
+ cookie=0x6900000, duration=318.028s, table=241, n_packets=0, n_bytes=0, priority=61010,ip,reg6=0x900/0xfffff00,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=30.0.0.255 actions=goto_table:242
+ cookie=0x6900000, duration=317.869s, table=241, n_packets=0, n_bytes=0, priority=61010,ip,reg6=0xa00/0xfffff00,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=30.0.0.255 actions=goto_table:242
+ cookie=0x6900000, duration=310.191s, table=241, n_packets=0, n_bytes=0, priority=61010,ip,reg6=0x1100/0xfffff00,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=40.0.0.255 actions=goto_table:242
+ cookie=0x6900000, duration=310.035s, table=241, n_packets=0, n_bytes=0, priority=61010,ip,reg6=0x1200/0xfffff00,dl_dst=ff:ff:ff:ff:ff:ff,nw_dst=40.0.0.255 actions=goto_table:242
+ cookie=0x6900000, duration=318.018s, table=241, n_packets=0, n_bytes=0, priority=61010,ipv6,dl_dst=fa:16:3e:1a:f1:a3,ipv6_dst=fe80::f816:3eff:fe1a:f1a3 actions=ct(table=242,zone=5002)
+ cookie=0x6900000, duration=317.864s, table=241, n_packets=0, n_bytes=0, priority=61010,ipv6,dl_dst=fa:16:3e:44:18:de,ipv6_dst=fe80::f816:3eff:fe44:18de actions=ct(table=242,zone=5002)
+ cookie=0x6900000, duration=310.189s, table=241, n_packets=0, n_bytes=0, priority=61010,ipv6,dl_dst=fa:16:3e:74:f5:c9,ipv6_dst=fe80::f816:3eff:fe74:f5c9 actions=ct(table=242,zone=5003)
+ cookie=0x6900000, duration=310.029s, table=241, n_packets=0, n_bytes=0, priority=61010,ipv6,dl_dst=fa:16:3e:5a:a8:ab,ipv6_dst=fe80::f816:3eff:fe5a:a8ab actions=ct(table=242,zone=5003)
+ cookie=0x6900000, duration=1685.712s, table=241, n_packets=0, n_bytes=0, priority=61005,dl_dst=ff:ff:ff:ff:ff:ff actions=resubmit(,220)
+ cookie=0x6900000, duration=1685.712s, table=241, n_packets=46, n_bytes=3476, priority=0 actions=drop
+ cookie=0x6900000, duration=1685.712s, table=242, n_packets=293, n_bytes=35230, priority=0 actions=goto_table:243
+ cookie=0x6900000, duration=1685.712s, table=243, n_packets=266, n_bytes=26792, priority=62020,ct_state=-new+est-rel-inv+trk actions=resubmit(,220)
+ cookie=0x6900000, duration=1685.712s, table=243, n_packets=0, n_bytes=0, priority=62020,ct_state=-new-est+rel-inv+trk actions=resubmit(,220)
+ cookie=0x6900001, duration=317.995s, table=243, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,reg6=0x900/0xfffff00 actions=drop
+ cookie=0x6900001, duration=317.851s, table=243, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,reg6=0xa00/0xfffff00 actions=drop
+ cookie=0x6900001, duration=310.173s, table=243, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,reg6=0x1100/0xfffff00 actions=drop
+ cookie=0x6900001, duration=310.012s, table=243, n_packets=0, n_bytes=0, priority=62015,ct_state=+inv+trk,reg6=0x1200/0xfffff00 actions=drop
+ cookie=0x6900000, duration=317.987s, table=243, n_packets=0, n_bytes=0, priority=1000,ct_state=+new+trk,tcp,reg6=0x900/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=317.937s, table=243, n_packets=1, n_bytes=98, priority=1001,ct_state=+new+trk,icmp,reg6=0x900/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=317.937s, table=243, n_packets=0, n_bytes=0, priority=1002,ct_state=+new+trk,udp,reg6=0x900/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=317.847s, table=243, n_packets=0, n_bytes=0, priority=1003,ct_state=+new+trk,tcp,reg6=0xa00/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=317.844s, table=243, n_packets=1, n_bytes=98, priority=1004,ct_state=+new+trk,icmp,reg6=0xa00/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=317.836s, table=243, n_packets=0, n_bytes=0, priority=1005,ct_state=+new+trk,udp,reg6=0xa00/0xfffff00 actions=ct(commit,zone=5002),resubmit(,220)
+ cookie=0x6900000, duration=310.173s, table=243, n_packets=0, n_bytes=0, priority=1006,ct_state=+new+trk,tcp,reg6=0x1100/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900000, duration=310.168s, table=243, n_packets=1, n_bytes=98, priority=1007,ct_state=+new+trk,icmp,reg6=0x1100/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900000, duration=310.163s, table=243, n_packets=0, n_bytes=0, priority=1008,ct_state=+new+trk,udp,reg6=0x1100/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900000, duration=310.012s, table=243, n_packets=0, n_bytes=0, priority=1009,ct_state=+new+trk,tcp,reg6=0x1200/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900000, duration=310.006s, table=243, n_packets=0, n_bytes=0, priority=1010,ct_state=+new+trk,icmp,reg6=0x1200/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900000, duration=310.006s, table=243, n_packets=0, n_bytes=0, priority=1011,ct_state=+new+trk,udp,reg6=0x1200/0xfffff00 actions=ct(commit,zone=5003),resubmit(,220)
+ cookie=0x6900001, duration=318.004s, table=243, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,reg6=0x900/0xfffff00 actions=drop
+ cookie=0x6900001, duration=317.858s, table=243, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,reg6=0xa00/0xfffff00 actions=drop
+ cookie=0x6900001, duration=310.173s, table=243, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,reg6=0x1100/0xfffff00 actions=drop
+ cookie=0x6900001, duration=310.022s, table=243, n_packets=0, n_bytes=0, priority=50,ct_state=+new+trk,reg6=0x1200/0xfffff00 actions=drop
+ cookie=0x6900000, duration=1685.712s, table=243, n_packets=24, n_bytes=8144, priority=0 actions=drop
+[jenkins@releng-22320-97-2-devstack-ocata-0 ~]>
\ No newline at end of file
diff --git a/resources/tools/odl/ovs/flows.py b/resources/tools/odl/ovs/flows.py
new file mode 100644 (file)
index 0000000..506ac1f
--- /dev/null
@@ -0,0 +1,155 @@
+import logging
+from pprint import pformat
+import re
+
+import tables
+import request
+
+
+logging.basicConfig(format="%(levelname)-8s []%(name)s] [%(module)s:%(lineno)d] %(message)s",
+                    level=logging.DEBUG)
+logger = logging.getLogger(__name__)
+
+
+# TODO:
+# metadata decoder
+# mac to port
+# REG6 decoder
+# group decoder
+# curl -s -u admin:admin -X GET 127.0.0.1:8080/restconf/operational/odl-l3vpn:learnt-vpn-vip-to-port-data
+# - check if external ip is resolved, devstack uses port 8087
+
+class Flows:
+    COOKIE = "cookie"
+    DURATION = "duration"
+    TABLE = "table"
+    N_PACKETS = "n_packets"
+    N_BYTES = "n_bytes"
+    MATCHES = "matches"
+    ACTIONS = "actions"
+    IDLE_TIMEOUT = "idle_timeout"
+    SEND_FLOW_REMOVED = "send_flow_rem"
+    PRIORITY = "priority"
+    GOTO = "goto"
+    RESUBMIT = "resubmit"
+
+    def __init__(self, data, level=logging.INFO):
+        self.pdata = []
+        self.fdata = []
+        self.data = data
+        print "level: {}".format(level)
+        logger.setLevel(level)
+        if level is not logging.INFO:
+            logger.info("effective: %d", logger.getEffectiveLevel())
+        self.process_data()
+        self.format_data()
+        logger.info("data has been processed and parsed")
+
+    def set_log_level(self, level):
+        logger.setLevel(level)
+        logger.info("effective: %d", logger.getEffectiveLevel())
+
+    def process_data(self):
+        """
+        Process the dump-flows data into a map.
+
+        The processing will tokenize the parts in each line of the flow dump.
+
+        :return: A list of dictionaries of parsed tokens per line
+        """
+        # cookie=0x805138a, duration=193.107s, table=50, n_packets=119, n_bytes=11504, idle_timeout=300,
+        #  send_flow_rem priority=20,metadata=0x2138a000000/0xfffffffff000000,dl_src=fa:16:3e:15:a8:66
+        #  actions=goto_table:51
+
+        self.pdata = []
+        if len(self.data) == 0:
+            logger.warn("There is no data to process")
+            return self.pdata
+
+        # skip the header if present
+        if "OFPST_FLOW" in self.data[0]:
+            start = 1
+        else:
+            start = 0
+        if "jenkins" in self.data[-1]:
+            end = len(self.data) - 2
+        else:
+            end = len(self.data) - 1
+
+        # Parse each line of the data. Create a dictionary of all tokens and append to a list.
+        for line in self.data[start:end]:
+            pline = {}
+            tokens = line.split(" ")
+            for token in tokens:
+                # most lines are key=value so look for that pattern
+                splits = token.split("=", 1)
+                if len(splits) == 2:
+                    pline[splits[0]] = splits[1].rstrip(",")
+                elif token == Flows.SEND_FLOW_REMOVED:
+                    # send_flow_rem is a single token without a value
+                    pline[token] = token
+            self.pdata.append(pline)
+        logger.info("Processed %d lines, skipped %d", len(self.pdata), start)
+        logger.debug("Processed data: %s", pformat(self.pdata))
+        return self.pdata
+
+    def re_table(self, match):
+        """
+        regex function to add the table name to table lines
+
+        :param match: The regex match
+        :return: The new line with table name
+        :rtype: str
+        """
+        if match.group(Flows.GOTO) is not None:
+            table_id = int(match.group(Flows.GOTO))
+        elif match.group(Flows.RESUBMIT) is not None:
+            table_id = int(match.group(Flows.RESUBMIT))
+        else:
+            table_id = 256
+
+        rep = "{}({})".format(match.group(), tables.get_table_name(table_id))
+        return rep
+
+    def format_data(self):
+        if len(self.pdata) == 0:
+            self.logger.warn("There is no data to process")
+            return self.pdata
+        header = "{:9} {:8} {:13}     {:6} {:12} {}... {}... {} {}\n" \
+            .format(Flows.COOKIE, Flows.DURATION, Flows.TABLE, "n_pack", Flows.N_BYTES, Flows.MATCHES, Flows.ACTIONS,
+                    Flows.IDLE_TIMEOUT, Flows.DURATION)
+        header_under = "--------- -------- -------------     ------ ------------ ---------- ---------- --------" \
+                       "---- --------\n"
+
+        # Match goto_table: nnn or resubmit(,nnn) and return as goto or resubmit match group
+        re_gt = re.compile(r"goto_table:(?P<goto>\d{1,3})|"
+                           r"resubmit\(,(?P<resubmit>\d{1,3})\)")
+        self.fdata = [header, header_under]
+        for line in self.pdata:
+            if Flows.SEND_FLOW_REMOVED in line:
+                send_flow_rem = " {} ".format(line[Flows.SEND_FLOW_REMOVED])
+            else:
+                send_flow_rem = ""
+            if Flows.IDLE_TIMEOUT in line:
+                idle_timeo = " {}={}".format(Flows.IDLE_TIMEOUT, line[Flows.IDLE_TIMEOUT])
+            else:
+                idle_timeo = ""
+            if Flows.ACTIONS in line:
+                nactions = re_gt.sub(self.re_table, line[Flows.ACTIONS])
+            else:
+                logger.warn("Missing actions in %s", line)
+                nactions = ""
+
+            logger.debug("line: %s", line)
+
+            fline = "{:9} {:8} {:3} {:13} {:6} {:12} priority={} actions={}{}{}" \
+                .format(line[Flows.COOKIE], line[Flows.DURATION],
+                        line[Flows.TABLE], tables.get_table_name(int(line[Flows.TABLE])),
+                        line[Flows.N_PACKETS], line[Flows.N_BYTES],
+                        line[Flows.PRIORITY], nactions,
+                        idle_timeo, send_flow_rem, )
+            self.fdata.append(fline)
+        return self.fdata
+
+    def write_fdata(self, filename):
+        request.write_file(filename, self.fdata)
diff --git a/resources/tools/odl/ovs/request.py b/resources/tools/odl/ovs/request.py
new file mode 100644 (file)
index 0000000..21d16a5
--- /dev/null
@@ -0,0 +1,32 @@
+import logging
+# from pprint import pformat
+
+
+# TODO:
+# - requests to get flow dumps via ovs-vsctl, ssh
+# - group processing
+
+logging.basicConfig(format="%(levelname)-8s [%(module)s:%(lineno)d] %(message)s",
+                    level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def set_log_level(level):
+    logger.setLevel(level)
+
+
+def get_from_file(filename):
+    lines = []
+    with open(filename, 'r') as fp:
+        for line in fp:
+            # strip leading spaces; by default every flow line has a leading space: " cookie=..."
+            lines.append(line.lstrip())
+    logger.info("File: %s: processed %d lines", filename, len(lines))
+    logger.debug("\n%s", "".join(lines))
+    # logger.debug("\n%s", pformat(lines))
+    return lines
+
+
+def write_file(filename, lines):
+    with open(filename, 'w') as fp:
+        fp.writelines(lines)
diff --git a/resources/tools/odl/ovs/tables.py b/resources/tools/odl/ovs/tables.py
new file mode 100644 (file)
index 0000000..4eab261
--- /dev/null
@@ -0,0 +1,37 @@
+tables = {
+    0: "INGRESS",
+    17: "DISPATCHER",
+    18: "DHCP_EXT_TUN",
+    19: "L3_GW_MAC",
+    20: "L3_LFIB",
+    22: "L3_SUBNET_RT",
+    23: "L3VNI_EXT_TUN",
+    36: "INT_TUN",
+    38: "EXT_TUN",
+    45: "IPV6",
+    48: "ELAN_BASE",
+    50: "ELAN_SMAC",
+    51: "ELAN_DMAC",
+    52: "ELAN_UNK_DMAC",
+    55: "ELAN_FILTER",
+    60: "DHCP",
+    80: "L3_INTF",
+    81: "ARP_RESPONDER",
+    90: "QOS_DSCP",
+    211: "IN_ACL",
+    212: "IN_ACL_REM",
+    213: "IN_ACL_FILTER",
+    220: "EG_LPORT_DISP",
+    230: "EG_POL_CLASS",
+    231: "EG_POL_RT",
+    241: "EG_ACL",
+    242: "EG_ACL_REM",
+    243: "EG_LEARN_REM"
+}
+
+
+def get_table_name(table_id):
+    if table_id in tables:
+        return tables[table_id]
+    else:
+        return "unknown:{}".format(table_id)
diff --git a/resources/tools/odl/ovs/test_flows.py b/resources/tools/odl/ovs/test_flows.py
new file mode 100644 (file)
index 0000000..899dac4
--- /dev/null
@@ -0,0 +1,31 @@
+import logging
+from pprint import pformat
+import unittest
+import flows
+from flows import Flows
+import request
+import tables
+
+
+class TestFlows(unittest.TestCase):
+    def setUp(self):
+        self.filename = "./flow_dumps.1.txt"
+        self.data = request.get_from_file(self.filename)
+        self.flows = Flows(self.data, logging.DEBUG)
+
+    def test_process_data(self):
+        pdata = self.flows.process_data()
+        # print "parsed data:\n{}".format(pformat(pdata))
+
+    def test_format_data(self):
+        fdata = self.flows.format_data()
+        # print "parsed data:\n{}".format(pformat(fdata))
+
+    def test_write_file(self):
+        self.flows.write_fdata("/tmp/flow_dumps.out.txt")
+
+    def test_get_table_name(self):
+        print "table: {} is the {} table".format(17, tables.get_table_name(17))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/resources/tools/odl/ovs/test_request.py b/resources/tools/odl/ovs/test_request.py
new file mode 100644 (file)
index 0000000..98c301b
--- /dev/null
@@ -0,0 +1,16 @@
+import logging
+import unittest
+import request
+
+
+class TestRequest(unittest.TestCase):
+    def setUp(self):
+        self.filename = "./flow_dumps.1.txt"
+
+    def test_get_from_file(self):
+        request.logger.setLevel(logging.DEBUG)
+        self.data = request.get_from_file(self.filename)
+        self.assertEquals(len(self.data), 76)
+
+if __name__ == '__main__':
+    unittest.main()