Thanks for the new feature!

This assumes that if something sends non lldp packets, then it is a
'host', rigth? One concern is that a host, for example, windows, can
be configured to send lldp packets. Thought?

Even if the above false identificatoin could happen, I'm ok with the
patches. There is no way to identify hosts correctly in any
environments, I guess.


On Thu, 11 Jun 2015 02:30:40 +0800
Yi Tseng <[email protected]> wrote:

> 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