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

Reply via email to