Ryu controller - simple_switch_13_stp does not recalculate the Tree after a failure? - openflow

I am using mininet with a Ryu controller.
For the Ryu controller I am using the command:
ryu-manager simple_switch_stp_13.py
Concerning mininet I use the topology defined in the file Topo1.py:
from mininet.topo import Topo
class Project( Topo ):
def __init__( self ):
# Initialize topology
Topo.__init__( self )
# Add hosts
h1 = self.addHost('h1')
h2 = self.addHost('h2')
# Add switches
s1 = self.addSwitch('s1')
s2 = self.addSwitch('s2')
s3 = self.addSwitch('s3')
s4 = self.addSwitch('s4')
# Add links
self.addLink(h1,s1)
self.addLink(s1,s2)
self.addLink(s2,s4)
self.addLink(s3,s1)
self.addLink(s3,s4)
self.addLink(h2,s4)
topos = { 'myTopo': ( lambda: Project() )}
Then I run mininet with the command:
sudo mn --custom Topo1.py --topo=myTopo --switch ovsk --controller=remote --mac
The connection between them is perfect; I succeed to run a ping from host 1 to host 2. What I want to do is to cut the link with s1 and s2 (without stopping the ping between h1 and h2).
Secondly, the issues I have :
According to https://osrg.github.io/ryu-book/en/Ryubook.pdf page 65 I used the command:
link s1 s2 down.
But, I can observe using wireshark that the controller sends Port_Mod, in reaction to the Port_Status, which asks to the switch to put the interface up again.
The switch does it so the ping repass by the interface between s1 and s2. I'm not understanding why the controller sends this Port_Mod?
In https://osrg.github.io/ryu-book/en/Ryubook.pdf page 65 they do not have this issue.
Then, I tried the command:
py net.delLinkBetween(s1, s2)
The link is totally deleted, the controller is notified by a Port Status but the root, the cost to the root ... do not evolved at all. Then, the ping does not restart and does not pass by s3. I also do not get why ?
Do you know if the two observations I did are normal ? And if yes, do you know how to correct my experiment in order to have the expected behavior ?

Related

How to iteratively call duarouter algorithm in a traCI simulation?

I defined the flow by giving the from and to edges. When testing some traffic signal algorithm, I found the network would easily come to a gridlock,partially because vehicles cannot find the dynamic user equilibrium route. Thus my goal is to make those defined flow (vehicle) find dynamic user equilibrium route in every simulation time step. I know the duarouter should be the solution. But how can I call duarouter in every simulation time step, how where should I incorporate duarouter in my code?
I followed the example code provided by SUMO website. Basically I defined a run() function which defines my signal control algorithm. Then I call run() in the main function.
Where should I inset the duarouter?
How should I call it in my simulation loop for make sure in every time step, the vehicles in the network can find its user equilibrium route.
dua-iterate.py -n <PATH_TO_SUMO_NET> -t <PATH_TO_TRIPS>
def run():
"""execute the TraCI control loop"""
step = 0
NSphase = 0
EWphase = 2
while traci.simulation.getMinExpectedNumber() > 0:
traci.simulationStep() # this means let the simulation go forward for one step
step += 1
{signal control algorithm}
traci.close()
sys.stdout.flush()
if __name__ == "__main__":
traci.start(["/home/hao/sumo_binaries/bin/sumo-gui", "-c", "/home/hao/Documents/traci_test/randomnet4/random.sumo.cfg",
"--tripinfo-output", "tripinfo.xml"])
run()
Traci is a control interface to sumo. So the basic idea is that you can start a sumo server and connect Traci to the server. Traci will generate the routes based on your network and trips files, statically or dynamically.
In the SUE case, your code
traci.start(["/home/hao/sumo_binaries/bin/sumo-gui", "-c", "/home/hao/Documents/traci_test/randomnet4/random.sumo.cfg", "--tripinfo-output", "tripinfo.xml"])
actually
starts the sumo-gui server,
and connects Traci (SUE) to the server.
To use DUE with Traci, you should use the duaIterate.py in tools/assign folder. But
traci.start(["python", <PATH TO duaIterate.py>, "-n", <NETWORK FILE>, "-t", <TRIPS FILE>])
only tries to connect Traci (DUE) to a sumo/sumo-gui server. So you should first start the server manually:
sumo-gui -n suedstadt.net.xml --remote-port <PORT NUMBER>
The remote-port option here starts sumo-gui in the server mode. Now you can connect Traci to the server with the port option.
traci.start(["python", <PATH TO duaIterate.py>, "-n", <NETWORK FILE>, "-t", <TRIPS FILE>], port=<PORT NUMBER>)

How to send a packet to all switches using ryu controller?

I need to measure link delay in Ryu controller. I want to send a packet-out message for all switches by the controller and calculate the time between the sent packet-out message and received the packet-in message. I am a beginner in Ryu and don't know how to send a packet with specific EtherType such as 0x8fc to all switches. I have obtained the MAC of all switches and build a packet. how I can send a packet with specific EtherType to all switches? I don't know what is the db parameter for every switch?
def send_packet(self, dp, port, pkt):
ofproto = dp.ofproto
parser = dp.ofproto_parser
pkt.serialize()
data = pkt.data
action = [parser.OFPActionOutput(port=port)]
out = parser.OFPPacketOut(
datapath=dp, buffer_id=ofproto.OFP_NO_BUFFER,
in_port=ofproto.OFPP_CONTROLLER,
actions=action, data=data)
dp.send_msg(out)
def create_packet(self):
i=l=0
for l in range(1,len(self.adjacency)+1):
#print("\n")
for i in self.adjacency[l]:
ethertype = 0x8fc
dst = self.macaddr(i)
src = self.macaddr(l)
e = ethernet.ethernet(dst, src, ethertype)
p = packet.Packet()
p.add_protocol(e)
p.add_protocol(time.time())
p.serialize()
port=self.adjacency[l][i]
send_packet(self, dp **??????** , port, p):
DP is the abbreviation for DataPathID that is kind of Uniq ID for an OpenFlow switch in your network.
According to the OpenFlow specification:
“The datapath_id field uniquely identifies a datapath. The lower 48
bits are intended for the switch MAC address, while the top 16 bits
are up to the implementer. An example use of the top 16 bits would be
a VLAN ID to distinguish multiple virtual switch instances on a single
physical switch.”
If you're using Mininet and for example, you run linear topology:
mn --controller remote --topo linear,3
Your topology will be:
s1 -- s2 -- s3
| | |
h1 h2 h3
DataPathID's will be:
s1: 0x0000000000000001
s2: 0x0000000000000002
s3: 0x0000000000000003
Pay attention that in other testbeds this numbers may be different but they're alway 16 digit hex.

lxc container can't use nfc usb device

I have been trying to use libnfc in a lxc container running debian wheezy.
Having tried several things and libraries, thus justifying the lxc way, I finally reached a point where I don't know where to look.
The problem is that the hosts sees my usb device, but not the container.
I added the following in the container's lxc config file:
lxc.cgroup.devices.allow = c 189:* rwm
When I try lsusb on the container I get:
root#nfc:~/libnfc# lsusb
unable to initialize libusb: -99
Whereas the host gives:
Bus 006 Device 003: ID 072f:2200 Advanced Card Systems, Ltd
Which is the device I'm looking for.
Surprisingly the container can see the device:
root#nfc:~/libnfc# usb-devices
[...]
T: Bus=06 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=072f ProdID=2200 Rev=02.14
S: Manufacturer=ACS
S: Product=ACR122U PICC Interface
C: #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=200mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=0b(scard) Sub=00 Prot=00 Driver=(none)
I have checked libusb versions, kernel modules, dependencies, but being quite ignorant there I'm a bit lost.
Any ideas ?
Adding:
lxc.mount.entry = /dev/bus/usb dev/bus/usb none bind,optional,create=dir
To the container configuration file in addition to lxc.cgroup.devices.allow = c 189:* rwm
worked for me.

How to monitor GlassFish thread pool via asadmin interface

I'm trying to use the asadmin interface to monitor a thread-pool on GlassFish 3.1.1. I'm executing the following command:
asadmin get -m server.network.my-listener.thread-pool.*
and I'm getting data back, but most of it has lastsampletime = -1 (so the related data is zero; and is worthless).
Note: I've also tried the REST interface, which I believe asadmin delegates to, and the JMX interface. Same problem: much of the data has lastsampletime = -1.
I've already turned monitoring to HIGH for all modules. What am I missing?
It seems like redeploying my application was necessary for the monitoring to actually get values. Perhaps I interpreted the manual incorrectly but it seems to suggest that a restart/redeploy wouldn't be required:
Oracle GlassFish Server 3.1 Administration Guide
Also, it is weird that the following shows there is no monitoring data:
asadmin get -m server.thread-pools.thread-pool.http-thread-pool.*
Instead you must go through a specific network listener like:
asadmin get -m server.network.http-listener-2.thread-pool.*
It also took me by surprise that enabling thread-pool monitoring IS NOT enough to see thread pool statistics. You must also enable http-service monitoring:
asadmin enable-monitoring
asadmin set server.monitoring-service.module-monitoring-levels.thread-pool=HIGH
asadmin set server.monitoring-service.module-monitoring-levels.http-service=HIGH
That's all you should need to do.
Enable monitoring, set to HIGH, for the http-service module on the DAS, stand-alone instance, or cluster you want to monitor.
Deploy an app to the DAS, stand-alone instance, or cluster and make http-requests.
asadmin get -m *instancename*.network.*listener*.thread-pool.*
Looks like you are monitoring DAS, since you are using asadmin get -m server.network.my-listener.thread-pool.*.
I deployed a simple war to DAS and made a bunch of http requests. I see the corethreads-count and maxthreads-count have last sample time as -1. And the remaining statistics have actual last sample times.
asadmin get -m "server.network.http-listener-1.thread-pool.*"
server.network.http-listener-1.thread-pool.corethreads-count = 0
server.network.http-listener-1.thread-pool.corethreads-description = Core number of threads in the thread pool
server.network.http-listener-1.thread-pool.corethreads-lastsampletime = -1
server.network.http-listener-1.thread-pool.corethreads-name = CoreThreads
server.network.http-listener-1.thread-pool.corethreads-starttime = 1320764890444
server.network.http-listener-1.thread-pool.corethreads-unit = count
server.network.http-listener-1.thread-pool.currentthreadcount-count = 5
server.network.http-listener-1.thread-pool.currentthreadcount-description = Provides the number of request processing threads currently in the listener thread pool
server.network.http-listener-1.thread-pool.currentthreadcount-lastsampletime = 1320765351708
server.network.http-listener-1.thread-pool.currentthreadcount-name = CurrentThreadCount
server.network.http-listener-1.thread-pool.currentthreadcount-starttime = 1320764890445
server.network.http-listener-1.thread-pool.currentthreadcount-unit = count
server.network.http-listener-1.thread-pool.currentthreadsbusy-count = 0
server.network.http-listener-1.thread-pool.currentthreadsbusy-description = Provides the number of request processing threads currently in use in the listener thread pool serving requests
server.network.http-listener-1.thread-pool.currentthreadsbusy-lastsampletime = 1320765772814
server.network.http-listener-1.thread-pool.currentthreadsbusy-name = CurrentThreadsBusy
server.network.http-listener-1.thread-pool.currentthreadsbusy-starttime = 1320764890445
server.network.http-listener-1.thread-pool.currentthreadsbusy-unit = count
server.network.http-listener-1.thread-pool.dotted-name = server.network.http-listener-1.thread-pool
server.network.http-listener-1.thread-pool.maxthreads-count = 0
server.network.http-listener-1.thread-pool.maxthreads-description = Maximum number of threads allowed in the thread pool
server.network.http-listener-1.thread-pool.maxthreads-lastsampletime = -1
server.network.http-listener-1.thread-pool.maxthreads-name = MaxThreads
server.network.http-listener-1.thread-pool.maxthreads-starttime = 1320764890443
server.network.http-listener-1.thread-pool.maxthreads-unit = count
server.network.http-listener-1.thread-pool.totalexecutedtasks-count = 31
server.network.http-listener-1.thread-pool.totalexecutedtasks-description = Provides the total number of tasks, which were executed by the thread pool
server.network.http-listener-1.thread-pool.totalexecutedtasks-lastsampletime = 1320765772814
server.network.http-listener-1.thread-pool.totalexecutedtasks-name = TotalExecutedTasksCount
server.network.http-listener-1.thread-pool.totalexecutedtasks-starttime = 1320764890444
server.network.http-listener-1.thread-pool.totalexecutedtasks-unit = count
Command get executed successfully.
To instantly enable monitoring without restart use enable-monitoring command
enable-monitoring
enable-monitoring --modules jvm=LOW
enable-monitoring --modules thread-pool=HIGH
enable-monitoring --modules http-service=HIGH
enable-monitoring --modules jdbc-connection-pool=HIGH
The trick is that thread-pool and http-service modules must have high level to get monitoring info.
For more info refer https://docs.oracle.com/cd/E26576_01/doc.312/e24928/monitoring.htm#GSADG00558

Extend existing Twisted Service with another Socket/TCP/RPC Service to get Service informations

I'm implementing a Twisted-based Heartbeat Client/Server combo, based on this example. It is my first Twisted project.
Basically it consists of a UDP Listener (Receiver), who calls a listener method (DetectorService.update) on receiving packages. The DetectorService always holds a list of currently active/inactive clients (I extended the example a lot, but the core is still the same), making it possible to react on clients which seem disconnected for a specified timeout.
This is the source taken from the site:
UDP_PORT = 43278; CHECK_PERIOD = 20; CHECK_TIMEOUT = 15
import time
from twisted.application import internet, service
from twisted.internet import protocol
from twisted.python import log
class Receiver(protocol.DatagramProtocol):
"""Receive UDP packets and log them in the clients dictionary"""
def datagramReceived(self, data, (ip, port)):
if data == 'PyHB':
self.callback(ip)
class DetectorService(internet.TimerService):
"""Detect clients not sending heartbeats for too long"""
def __init__(self):
internet.TimerService.__init__(self, CHECK_PERIOD, self.detect)
self.beats = {}
def update(self, ip):
self.beats[ip] = time.time()
def detect(self):
"""Log a list of clients with heartbeat older than CHECK_TIMEOUT"""
limit = time.time() - CHECK_TIMEOUT
silent = [ip for (ip, ipTime) in self.beats.items() if ipTime < limit]
log.msg('Silent clients: %s' % silent)
application = service.Application('Heartbeat')
# define and link the silent clients' detector service
detectorSvc = DetectorService()
detectorSvc.setServiceParent(application)
# create an instance of the Receiver protocol, and give it the callback
receiver = Receiver()
receiver.callback = detectorSvc.update
# define and link the UDP server service, passing the receiver in
udpServer = internet.UDPServer(UDP_PORT, receiver)
udpServer.setServiceParent(application)
# each service is started automatically by Twisted at launch time
log.msg('Asynchronous heartbeat server listening on port %d\n'
'press Ctrl-C to stop\n' % UDP_PORT)
This heartbeat server runs as a daemon in background.
Now my Problem:
I need to be able to run a script "externally" to print the number of offline/online clients on the console, which the Receiver gathers during his lifetime (self.beats). Like this:
$ pyhb showactiveclients
3 clients online
$ pyhb showofflineclients
1 client offline
So I need to add some kind of additional server (Socket, Tcp, RPC - it doesn't matter. the main point is that i'm able to build a client-script with the above behavior) to my DetectorService, which allows to connect to it from outside. It should just give a response to a request.
This server needs to have access to the internal variables of the running detectorservice instance, so my guess is that I have to extend the DetectorService with some kind of additionalservice.
After some hours of trying to combine the detectorservice with several other services, I still don't have an idea what's the best way to realize that behavior. So I hope that somebody can give me at least the essential hint how to start to solve this problem.
Thanks in advance!!!
I think you already have the general idea of the solution here, since you already applied it to an interaction between Receiver and DetectorService. The idea is for your objects to have references to other objects which let them do what they need to do.
So, consider a web service that responds to requests with a result based on the beats data:
from twisted.web.resource import Resource
class BeatsResource(Resource):
# It has no children, let it respond to the / URL for brevity.
isLeaf = True
def __init__(self, detector):
Resource.__init__(self)
# This is the idea - BeatsResource has a reference to the detector,
# which has the data needed to compute responses.
self._detector = detector
def render_GET(self, request):
limit = time.time() - CHECK_TIMEOUT
# Here, use that data.
beats = self._detector.beats
silent = [ip for (ip, ipTime) in beats.items() if ipTime < limit]
request.setHeader('content-type', 'text/plain')
return "%d silent clients" % (len(silent),)
# Integrate this into the existing application
application = service.Application('Heartbeat')
detectorSvc = DetectorService()
detectorSvc.setServiceParent(application)
.
.
.
from twisted.web.server import Site
from twisted.application.internet import TCPServer
# The other half of the idea - make sure to give the resource that reference
# it needs.
root = BeatsResource(detectorSvc)
TCPServer(8080, Site(root)).setServiceParent(application)