In-progress changes in demo.py scripts for flow detection. 55/4755/1
authorSuchi Raman <suchi.raman@plexxi.com>
Sat, 25 Jan 2014 02:19:33 +0000 (21:19 -0500)
committerSuchi Raman <suchi.raman@plexxi.com>
Sat, 25 Jan 2014 02:19:33 +0000 (21:19 -0500)
License headers.

Signed-off-by: Suchi Raman <suchi.raman@plexxi.com>
21 files changed:
affinity/api/src/main/java/org/opendaylight/affinity/affinity/AffinityAttribute.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/AffinityAttributeType.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/AffinityGroup.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/AffinityIdentifier.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/AffinityLink.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/InetAddressMask.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/SetDeny.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/SetPathIsolate.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/SetPathRedirect.java
affinity/api/src/main/java/org/opendaylight/affinity/affinity/SetTap.java
affinity/api/src/test/java/org/opendaylight/affinity/affinity/AffinityGroupTest.java
affinity/integrationtest/src/test/java/org/opendaylight/affinity/affinity/internal/AffinityManagerIT.java
affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityGroupHosts.java
analytics/integrationtest/src/test/java/org/opendaylight/affinity/analytics/internal/AnalyticsManagerIT.java
flatl2/src/main/java/org/opendaylight/affinity/flatl2/Activator.java
scripts/affinity.py
scripts/affinity_control.py
scripts/analytics.py
scripts/demo.py
scripts/run.virt.sh [new file with mode: 0755]
scripts/stats.py

index 6ae7da86db8b217bcb89cd8750e2ec7c06e8561a..49a003fb67a3734bfe7a9aee6d295658e7242911 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import javax.xml.bind.annotation.XmlAccessType;
index bd55c80077b65a264865e67f694d613f69892dfb..f322d4ce9f99688c176e4016d74f372e43634546 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 /**
index 28101f072a3e5ac78daf3d851b85af91600c24e8..350a16ea33123b57bf3aff33261c971921e17525 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import org.opendaylight.controller.sal.utils.NetUtils;
index 9fb90163b2cf5ca67a44f37f6e4f8d3e90d49a42..ca409c8e49626c34b29a7f6c280b5251ab5d4dfb 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 import java.io.Serializable;
 
index 028127ad403e37a7208cabaac012b13eb289e51a..041bf2f5e951712745610472a382f7d80446aaf9 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import org.opendaylight.controller.sal.utils.NetUtils;
index a76e31d8dec3655b51955a02441ef1e29287e025..0a5d0fa730af8082052108a9862891cdea807f3e 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import javax.xml.bind.annotation.XmlAttribute;
index f5213e25ab004a0bc8602cf2793340a7f0f2397f..21d556600e0680412cf947f052c42d00ddc3f005 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import javax.xml.bind.annotation.XmlAccessType;
index c0378f096f0f7097d7d077da2bddb1f76c34f673..64e3e8fa06051f0be25d9d4366c4f310273c86b4 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import java.net.InetAddress;
index 3e5d15851b756950bac23902bf3a76a4254618eb..a91db3727988c25b9f94b940b5a72db9f9fef56e 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import java.net.InetAddress;
index 6a27446506200e9f9356610418827e2769ed5c9e..ac5d34e044c3fee8e3e55dafbc322512eb2a494d 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import java.net.InetAddress;
index 8de1105c05bdf2501161aa8f582f7555fa20b93f..8746677a9d0e432edc12ec7cb767126206a24220 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity;
 
 import java.net.Inet6Address;
index 865489bd75327f2521a5542a129910410291999f..4ac479c9f581ec7808c2ff6089007e679d01fa4a 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity.internal;
 
 import static org.junit.Assert.assertFalse;
index cc887dfd0d7e7a9a70acb6d007ad327d1d0a59ac..58d0ed90725557fcc7e23f3be9e3bfee230d1dd7 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.affinity.northbound;
 
 import org.opendaylight.controller.sal.utils.NetUtils;
index 01cae683fc2be02c58d2f7c5178c8dc1d5be91ad..13d8f7b502b67ed19072e9ff0e63817ccceee225 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.affinity.analytics.internal;
 
 import static org.junit.Assert.assertFalse;
index 965a1e4358cfecb6d7c0309e02cfc69a78187ae9..ad6e17888a64a83082200424739317ea111b2fcd 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013 Plexxi Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
index aee20d646be61969051975159cd5d5d3ebbb0733..4808e15f051ffb45567529608b58b1ece15d85c1 100644 (file)
@@ -89,6 +89,12 @@ def client_ws_example():
     put_url = 'http://localhost:8080/affinity/nb/v2/affinity/default/group/clients/add/ip/10.0.0.3'
     rest_method(put_url, "PUT")
 
+def repeat_add_link(): 
+    print "create link inflows"
+    put_url = 'http://localhost:8080/affinity/nb/v2/affinity/default/create/link/inflows/from/clients/to/webservers'
+    rest_method(put_url, "PUT")
+
+
 # Only one waypoint supported. 
 def set_waypoint_address(al, wp):
     put_url = 'http://localhost:8080/affinity/nb/v2/affinity/default/link/' + al + '/setwaypoint/' + wp
@@ -134,6 +140,7 @@ def main():
     # Create two affinity groups and a link between them. 
     # Assign attributes. 
     client_ws_example()
+    repeat_add_link()
 
     get_affinity_group('webservers')
     get_affinity_group('clients')
index 085d91bca3a606b5ec5dbdee7170433b0b211871..d1936288a1c99e2c02423fef2a451aa963ad677c 100644 (file)
@@ -54,7 +54,7 @@ class AffinityControl:
 
     # Add isolate to the link.
     def add_isolate(self, link_name):
-        resp, content = self.http.request(self.url_prefix + "link/%s/setisolate/%s" % (link_name), "PUT")
+        resp, content = self.http.request(self.url_prefix + "link/%s/setisolate" % (link_name), "PUT")
         if (resp.status != 201):
             print "Isolate could not be set for link %s" % (link_name)
             return
@@ -78,12 +78,20 @@ class AffinityControl:
 
     # Disable waypoint
     def disable_waypoint(self, link_name):
-        resp, content = self.http.request(self.url_prefix + "link/%s/disable" % link_name, "PUT")
+        resp, content = self.http.request(self.url_prefix + "link/%s/unsetwaypoint" % link_name, "PUT")
         if (resp.status != 201):
             print "Waypoint could not be disabled for link %s" % link_name
             return
         print "Waypoint disabled for link %s" % link_name
 
+    # Disable isolate 
+    def disable_isolate(self, link_name):
+        resp, content = self.http.request(self.url_prefix + "link/%s/unsetisolate" % link_name, "PUT")
+        if (resp.status != 201):
+            print "Isolate could not be disabled for link %s" % link_name
+            return
+        print "Isolate disabled for link %s" % link_name
+
     # Enable all affinity rules
     def enable_affinity(self):
         resp, content = self.http.request(self.flatl2url_prefix + "enableaffinity", "PUT")
index 1c6297c17caaeeb2db6f1f11dfcd932cb614213d..49b11d218776bb2e77d959f5ac5538f63c3dd13f 100644 (file)
@@ -68,6 +68,7 @@ def stats_hosts(src, dst, do_print=True):
     data = rest_method(url, "GET")
     if (do_print):
         print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+    print data
     return data
 
 def stats_hosts_protocol(src, dst, protocol, do_print=True):
@@ -75,6 +76,7 @@ def stats_hosts_protocol(src, dst, protocol, do_print=True):
     data = rest_method(url, "GET")
     if (do_print):
         print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+    print data
     return data
 
 def all_stats_hosts(src, dst, do_print=True):
@@ -89,6 +91,7 @@ def all_stats_hosts(src, dst, do_print=True):
     except:
         data = {}
     finally:
+        print data
         return data
 
 ### Affinity link statistics
@@ -98,6 +101,7 @@ def stats_link(al, do_print=True):
     data = rest_method(url, "GET")
     if (do_print):
         print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+    print data
     return data
 
 def stats_link_protocol(al, protocol, do_print=True):
@@ -105,6 +109,7 @@ def stats_link_protocol(al, protocol, do_print=True):
     data = rest_method(url, "GET")
     if (do_print):
         print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+    print data
     return data
 
 def all_stats_link(al, do_print=True):
@@ -119,6 +124,7 @@ def all_stats_link(al, do_print=True):
     except:
         data = {}
     finally:
+        print data
         return data
 
 ### Subnet statistics
@@ -128,6 +134,7 @@ def stats_subnet(src_sub, dst_sub, do_print=True):
     data = rest_method(url, "GET")
     if (do_print):
         print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+    print data
     return data
 
 def stats_subnet_protocol(src_sub, dst_sub, protocol, do_print=True):
index 60f239f66c18a1fa8fbdf8d7086240616ce79ec0..24bacf7a6d501d7ec4468cac0e9642ee2c162a06 100644 (file)
@@ -58,23 +58,27 @@ class WaypointMonitor(Thread):
         self.waypoint_address = waypoint_ip
         print "Registered waypoint for %s.  Any large flows will be redirected to %s." % (self.stat, waypoint_ip)
 
-    def set_large_flow_threshold(self, s):
-        self.stat.set_large_flow_threshold(s)
-        print "Set threshold for large flows to %d bytes" % s
+    def set_flow_thresholds(self, high, low):
+        self.stat.set_flow_thresholds(high, low)
+        print "Set threshold for large flows to %d, %d bytes" % (high,  low)
         print("-------------------------")
 
     def run(self):
         global sigint
         did_waypoint = False
         while not sigint:
-            _, is_big = self.stat.refresh()
+            print "**** Stat refresh ****"
+            _, is_big, is_small = self.stat.refresh()
+            print "is_big is ", is_big
+            print "is_small is ", is_small
+
             if is_big and not did_waypoint:
                 print "Large flow detected (%d bytes, %d packets, %3.3f bit/s)" % (self.stat.get_bytes(), self.stat.get_packets(), self.stat.get_bit_rate())
-                print "   ICMP: %d bytes, %d packets" % (self.stat.get_bytes(1), self.stat.get_packets(1))
-                print "   UDP: %d bytes, %d packets" % (self.stat.get_bytes(17), self.stat.get_packets(17))
-                print "   TCP: %d bytes, %d packets" % (self.stat.get_bytes(6), self.stat.get_packets(6))
-                print "   other: %d bytes, %d packets" % (self.stat.get_bytes(-1), self.stat.get_packets(-1))
-                print("-------------------------")
+#                print "   ICMP: %d bytes, %d packets" % (self.stat.get_bytes(1), self.stat.get_packets(1))
+#                print "   UDP: %d bytes, %d packets" % (self.stat.get_bytes(17), self.stat.get_packets(17))
+#                print "   TCP: %d bytes, %d packets" % (self.stat.get_bytes(6), self.stat.get_packets(6))
+#                print "   other (tbd): %d bytes, %d packets" % (self.stat.get_bytes(-1), self.stat.get_packets(-1))
+#                print("-------------------------")
                 ac = AffinityControl()
                 # First AG: Sources sending data into this subnet
                 src_ag_name = "sources"
@@ -98,10 +102,17 @@ class WaypointMonitor(Thread):
 #                ac.enable_waypoint(link_name)
                 ac.enable_affinity()
                 did_waypoint = True
-                raw_input("[Press Enter to disable affinity rules] ")
-                ac.disable_affinity()
-#                ac.disable_waypoint(link_name)
-            time.sleep(1)
+                time.sleep(30)
+            # Below low water mark. 
+            elif (is_small and did_waypoint): 
+                print "Disable affinity configuration."
+                ac = AffinityControl()
+                link_name = "inflows"
+                ac.disable_affinity() # Clear all openflow rules
+                ac.disable_waypoint(link_name) # Clear waypoint configuration
+                ac.disable_isolate(link_name)  # Clear isolate configuration
+                did_waypoint = False # Reset, so that we can detect again.
+            time.sleep(5)
 
 def main():
 
@@ -119,7 +130,7 @@ def main():
 
     m = WaypointMonitor(Stats.TYPE_SUBNET, subnet="10.0.0.0/31")
     m.set_waypoint("10.0.0.2")
-    m.set_large_flow_threshold(2000) # 2000 bytes
+    m.set_flow_thresholds(200, 50) # 2000 bytes
     m.start()
 
     # Register signal-handler to catch SIG_INT
diff --git a/scripts/run.virt.sh b/scripts/run.virt.sh
new file mode 100755 (executable)
index 0000000..053e96e
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+#copy this modified script to ./distributions/virtualization/src/assemble/resources/
+# Use same path for run.base.sh
+RUNSH_DIR=$(dirname $0)
+RUN_BASE_SH=${RUNSH_DIR}/run.base.sh
+
+function usage {
+    echo -e "You must select one of the 3 supported network virtualization technologies:\n\tovsdb | opendove | vtn"
+    echo "Usage: $0 -virt {ovsdb | opendove | vtn} [advanced options]"
+    echo "Advanced options: $($RUN_BASE_SH -help | sed "s;Usage: $RUN_BASE_SH ;;")"
+    exit 1
+}
+
+virtIndex=0
+while true ; do
+    (( i += 1 ))
+    case "${@:$i:1}" in
+        -virt) virtIndex=$i ;;
+        "") break ;;
+    esac
+done
+
+# Virtualization edition select
+if [ ${virtIndex} -eq 0 ]; then
+    usage
+fi
+
+virt=${@:$virtIndex+1:1}
+if [ "${virt}" == "" ]; then
+    usage
+else
+    if [ "${virt}" == "ovsdb" ]; then
+        ODL_VIRT_FILTER="opendove|vtn"
+    elif [ "${virt}" == "opendove" ]; then
+        ODL_VIRT_FILTER="ovsdb|vtn"
+    elif [ "${virt}" == "vtn" ]; then
+        ODL_VIRT_FILTER="affinity|opendove|ovsdb|controller.(arphandler|samples)"
+    elif [ "${virt}" == "cldemo" ]; then
+        ODL_VIRT_FILTER="vtn|opendove|ovsdb|controller.samples"
+    else
+        usage
+    fi
+fi
+
+$RUN_BASE_SH -bundlefilter "org.opendaylight.(${ODL_VIRT_FILTER})" "${@:1:$virtIndex-1}" "${@:virtIndex+2}"
index 096da966255752967a054b7fa0acd76171d2be16..d252c9aba11f382662f82b05969871ae66050db9 100644 (file)
@@ -25,8 +25,23 @@ class Stats:
 
         self.stats = {}
         self.protocol_stats = {}
+        self.last_value = {}
+        self.last_transfer = {}
+        
+        # Initialize last value read
+        self.last_value["None"] = 0
+        self.last_transfer["None"] = 0
+
+        protocols = [1, 6, 17] # ICMP, TCP, UDP
+        for protocol in protocols: 
+            self.last_value[protocol] = 0
+            self.last_transfer[protocol] = 0
+        
         self.rate_ewma = None
-        self.large_flow_threshold = 5 * 10**6 # in bytes
+        self.flow_high_threshold = 5 * 10**6 # in bytes
+        self.flow_low_threshold = 5 * 10**3 # in bytes
+
+        self.flow_bytes = 0 # Last value of bytes transferred for this flow. 
 
     def __str__(self):
         if (self.stat_type == Stats.TYPE_HOST):
@@ -50,14 +65,18 @@ class Stats:
             self.stats = analytics.stats_subnet("null/null", self.subnet, True)
             self.protocol_stats = analytics.all_stats_subnet("null/null", self.subnet, True)
         try:
+            self.reset_bytes()
             is_fast = self.handle_rate_ewma()
             is_big = self.check_large_flow()
-            return [is_fast, is_big]
+            is_small = self.check_small_flow()
+            return [is_fast, is_big, is_small]
         except:
-            return [False, False]
+            return [False, False, False]
 
-    def set_large_flow_threshold(self, s):
-        self.large_flow_threshold = s;
+            
+    def set_flow_thresholds(self, high, low):
+        self.flow_high_threshold = high;
+        self.flow_low_threshold = low;
 
     # Return all hosts that transferred a particular percentage of data into this entity.  Right now only supports subnets.
     def get_large_incoming_hosts(self):
@@ -96,7 +115,12 @@ class Stats:
 
     # Returns true if this is a large flow
     def check_large_flow(self):
-        if (self.get_bytes() > self.large_flow_threshold):
+        if (self.get_bytes() > self.flow_high_threshold):
+            return True
+        return False
+
+    def check_small_flow(self):
+        if (self.get_bytes() < self.flow_low_threshold):
             return True
         return False
 
@@ -104,13 +128,34 @@ class Stats:
     def get_bytes(self, protocol=None):
         try:
             if (protocol == None):
-                bytes = long(self.stats["byteCount"])
+                bytes = long(self.last_transfer["None"]) 
             else:
-                bytes = long(self.protocol_stats[protocol]["byteCount"])
+                bytes = long(self.last_transfer[protocol]) 
         except Exception as e:
             bytes = 0
+            print "get_bytes exception"
         return bytes
 
+    # Bytes
+    def reset_bytes(self, protocol=None):
+        try:
+            if (protocol == None):
+                bytes = long(self.stats["byteCount"]) 
+                lv = self.last_value["None"]
+                self.last_value["None"] = bytes
+                self.last_transfer["None"] = (bytes - lv)
+            else:
+                bytes = long(self.protocol_stats[protocol]["byteCount"]) 
+                lv = self.last_value[protocol]
+                self.last_value[protocol] = bytes
+                self.last_transfer[protocol] = (bytes - lv)
+        except Exception as e:
+            bytes = 0
+            lv = 0
+            print "reset_bytes exception"
+        print "*** lv = %d, bytes = %d" % (lv, bytes)
+        return (bytes - lv)
+
     # Packets
     def get_packets(self, protocol=None):
         try: