Signed-off-by: Takeshi <[email protected]>
---
ryu/topology/api.py | 7 +++++
ryu/topology/event.py | 23 +++++++++++++++++
ryu/topology/switches.py | 66
+++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/ryu/topology/api.py b/ryu/topology/api.py
index 7485a8e..aa8a09f 100644
--- a/ryu/topology/api.py
+++ b/ryu/topology/api.py
@@ -34,5 +34,12 @@ def get_link(app, dpid=None):
def get_all_link(app):
return get_link(app)
+def get_host(app, dpid=None):
+ rep = app.send_request(event.EventHostRequest(dpid))
+ return rep.hosts
+
+def get_all_hosts(app):
+ return get_host(app)
+
app_manager.require_app('ryu.topology.switches', api_style=True)
diff --git a/ryu/topology/event.py b/ryu/topology/event.py
index bd87ab0..17fcf94 100644
--- a/ryu/topology/event.py
+++ b/ryu/topology/event.py
@@ -126,3 +126,26 @@ class EventLinkReply(event.EventReplyBase):
def __str__(self):
return 'EventLinkReply<dst=%s, dpid=%s, links=%s>' % \
(self.dst, self.dpid, len(self.links))
+
+
+
+class EventHostRequest(event.EventRequestBase):
+ # If dpid is None, reply all list
+ def __init__(self, dpid=None):
+ super(EventHostRequest, self).__init__()
+ self.dst = 'switches'
+ self.dpid = dpid
+
+ def __str__(self):
+ return 'EventHostRequest<dpid=%s>' % \
+ (self.dpid)
+
+class EventHostReply(event.EventReplyBase):
+ def __init__(self, dst, dpid, hosts):
+ super(EventHostReply, self).__init__(dst)
+ self.dpid = dpid
+ self.hosts = hosts
+
+ def __str__(self):
+ return 'EventLinkReply<dpid=%s, hosts=%s>' % \
+ (self.dpid, self.hosts)
diff --git a/ryu/topology/switches.py b/ryu/topology/switches.py
index 63335f2..ab7f9f6 100644
--- a/ryu/topology/switches.py
+++ b/ryu/topology/switches.py
@@ -157,6 +157,35 @@ class Link(object):
def __str__(self):
return 'Link: %s to %s' % (self.src, self.dst)
+class Host(object):
+ # This is data class passed by EventHostXXXX
+ def __init__(self, dpid, port, mac):
+ super(Host, self).__init__()
+ self.dpid = dpid
+ self.port = port
+ self.mac = mac
+
+ def to_dict(self):
+ d = {
+ 'dpid': self.dpid,
+ 'port': self.port,
+ 'mac': self.mac
+ }
+ return d
+
+ # this type is used for key value of LinkState
+ def __eq__(self, other):
+ return self.mac == other.mac
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __hash__(self):
+ return hash(self.mac)
+
+ def __str__(self):
+ return 'Host<Mac address=%s>' % (self.mac, )
+
class PortState(dict):
# dict: int port_no -> OFPPort port
@@ -451,6 +480,7 @@ class Switches(app_manager.RyuApp):
self.port_state = {} # datapath_id => ports
self.ports = PortDataState() # Port class -> PortData class
self.links = LinkState() # Link class -> timestamp
+ self.hosts = {}
self.is_active = True
self.link_discovery = self.CONF.observe_links
@@ -689,7 +719,25 @@ class Switches(app_manager.RyuApp):
src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
except LLDPPacket.LLDPUnknownFormat as e:
# This handler can receive all the packtes which can be
- # not-LLDP packet. Ignore it silently
+ # not-LLDP packet.
+ # Check if it's new host
+
+ dpid = msg.datapath.id
+ port = -1
+
+ if msg.datapath.ofproto.OFP_VERSION ==
ofproto_v1_0.OFP_VERSION:
+ port = msg.in_port
+ elif msg.datapath.ofproto.OFP_VERSION >=
ofproto_v1_2.OFP_VERSION:
+ port = msg.match['in_port']
+
+ pkt = packet.Packet(msg.data)
+ eth = pkt.get_protocols(ethernet.ethernet)[0]
+ mac = eth.src
+
+ if mac not in self.hosts and port != -1:
+ LOG.debug('Found host(mac=%s) from dpid=%d, port=%d', mac,
dpid, port)
+ self.hosts[mac] = Host(dpid, port, mac)
+
return
dst_dpid = msg.datapath.id
@@ -862,3 +910,19 @@ class Switches(app_manager.RyuApp):
links = [link for link in self.links if link.src.dpid == dpid]
rep = event.EventLinkReply(req.src, dpid, links)
self.reply_to_request(req, rep)
+
+ @set_ev_cls(event.EventHostRequest)
+ def host_request_handler(self, req):
+ # LOG.debug(req)
+ dpid = req.dpid
+ hosts = []
+
+ if dpid is None:
+ hosts = [host for host in self.hosts.itervalues()]
+
+ else:
+ hosts = [host for host in self.hosts.itervalues() if host.dpid
== dpid]
+
+ rep = event.EventHostReply(req.src, dpid, hosts)
+ self.reply_to_request(req, rep)
+
--
2.3.2 (Apple Git-55)
--
Yi Tseng (a.k.a Takeshi)
Taiwan National Chiao Tung University
Department of Computer Science
W2CNLab
------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel