License headers.
Signed-off-by: Suchi Raman <suchi.raman@plexxi.com>
+/*
+ * 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;
+/*
+ * 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;
/**
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
+/*
+ * 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;
/*
- * 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,
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
# 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')
# 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
# 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")
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):
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):
except:
data = {}
finally:
+ print data
return data
### Affinity link statistics
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):
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):
except:
data = {}
finally:
+ print data
return data
### Subnet statistics
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):
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"
# 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():
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
--- /dev/null
+#!/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}"
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):
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):
# 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
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: