Hello Attached files are my patch.
Thanks . 2015-06-14 21:47 GMT+08:00 FUJITA Tomonori <[email protected]>: > On Thu, 11 Jun 2015 15:19:53 +0800 > Yi Tseng <[email protected]> wrote: > > > Please ignore previous patch, because I forgot to check coding style with > > pep8, here is the new patch > > > > Signed-off-by: Takeshi <[email protected]> > > --- > > ryu/topology/api.py | 9 +++++++ > > ryu/topology/event.py | 23 ++++++++++++++++ > > ryu/topology/switches.py | 69 > > ++++++++++++++++++++++++++++++++++++++++++++++-- > > 3 files changed, 99 insertions(+), 2 deletions(-) > > Thanks but I got the following error: > > FUJITA-no-MacBook-Pro:ryu fujita$ patch -p1 < 1 > patching file ryu/topology/api.py > patching file ryu/topology/event.py > patching file ryu/topology/switches.py > patch: **** malformed patch at line 246: ofproto_v1_0.OFP_VERSION: > -- Yi Tseng (a.k.a Takeshi) Taiwan National Chiao Tung University Department of Computer Science W2CNLab
From c8be39932ea9873b08531fb6b5f625495043cb4e Mon Sep 17 00:00:00 2001 From: Takeshi <[email protected]> Date: Mon, 15 Jun 2015 01:06:04 +0800 Subject: [PATCH 1/2] Implement host discovery in ryu.topology Signed-off-by: Takeshi <[email protected]> --- ryu/topology/api.py | 9 +++++++ ryu/topology/event.py | 23 ++++++++++++++++ ryu/topology/switches.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/ryu/topology/api.py b/ryu/topology/api.py index 7485a8e..0a61c1b 100644 --- a/ryu/topology/api.py +++ b/ryu/topology/api.py @@ -35,4 +35,13 @@ 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..ea9d8ce 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..3f69f7c 100644 --- a/ryu/topology/switches.py +++ b/ryu/topology/switches.py @@ -46,6 +46,8 @@ CONF = cfg.CONF CONF.register_cli_opts([ cfg.BoolOpt('observe-links', default=False, help='observe link discovery events.'), + cfg.BoolOpt('observe-hosts', default=False, + help='observe host discovery events.'), cfg.BoolOpt('install-lldp-flow', default=True, help='link discovery: explicitly install flow entry ' 'to send lldp packet to controller'), @@ -158,6 +160,33 @@ class Link(object): 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 + + 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 # OFPPort is defined in ryu.ofproto.ofproto_v1_X_parser @@ -451,9 +480,12 @@ 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 + self.host_discovery = self.CONF.observe_hosts + if self.link_discovery: self.install_flow = self.CONF.install_lldp_flow self.explicit_drop = self.CONF.explicit_drop @@ -681,7 +713,7 @@ class Switches(app_manager.RyuApp): @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): - if not self.link_discovery: + if not self.link_discovery and not self.host_discovery: return msg = ev.msg @@ -689,7 +721,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 + if self.host_discovery: + 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 +912,18 @@ 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)
From 8afb7198bc686d376bc32c3a90fec330f9c8751d Mon Sep 17 00:00:00 2001 From: Takeshi <[email protected]> Date: Mon, 15 Jun 2015 01:06:28 +0800 Subject: [PATCH 2/2] Implement "get host" and "list host" RESTful api Signed-off-by: Takeshi <[email protected]> --- ryu/app/rest_topology.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/ryu/app/rest_topology.py b/ryu/app/rest_topology.py index 5eed243..77cfc37 100644 --- a/ryu/app/rest_topology.py +++ b/ryu/app/rest_topology.py @@ -19,7 +19,7 @@ from webob import Response from ryu.app.wsgi import ControllerBase, WSGIApplication, route from ryu.base import app_manager from ryu.lib import dpid as dpid_lib -from ryu.topology.api import get_switch, get_link +from ryu.topology.api import get_switch, get_link, get_host # REST API for switch configuration # @@ -76,6 +76,16 @@ class TopologyController(ControllerBase): def get_links(self, req, **kwargs): return self._links(req, **kwargs) + @route('topology', '/v1.0/topology/hosts', + methods=['GET']) + def list_hosts(self, req, **kwargs): + return self._hosts(req, **kwargs) + + @route('topology', '/v1.0/topology/hosts/{dpid}', + methods=['GET'], requirements={'dpid': dpid_lib.DPID_PATTERN}) + def get_hosts(self, req, **kwargs): + return self._hosts(req, **kwargs) + def _switches(self, req, **kwargs): dpid = None if 'dpid' in kwargs: @@ -91,3 +101,11 @@ class TopologyController(ControllerBase): links = get_link(self.topology_api_app, dpid) body = json.dumps([link.to_dict() for link in links]) return Response(content_type='application/json', body=body) + + def _hosts(self, req, **kwargs): + dpid = None + if 'dpid' in kwargs: + dpid = dpid_lib.str_to_dpid(kwargs['dpid']) + hosts = get_host(self.topology_api_app, dpid) + body = json.dumps([host.to_dict() for host in hosts]) + return Response(content_type='application/json', body=body) -- 2.3.2 (Apple Git-55)
------------------------------------------------------------------------------
_______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
