Hi, Excuse me for cutting in.
According to OpenFlow Spec 1.3, there is no MAC address info in OFPT_FEATURES_REPLY message, and we can not extract the MAC address info in switch_features_handler. I recommend to put your code into port_desc_stats_reply_handler. http://ryu.readthedocs.io/en/latest/ofproto_v1_3_ref.html#ryu.ofproto.ofproto_v1_3_parser.OFPPortDescStatsReply Ryu sends OFPPortDescStatsRequest messages automatically when the switches connecting to Ryu, and you need not to send this request message your self in your app. e.g.) $ git diff diff --git a/ryu/app/simple_switch_13.py b/ryu/app/simple_switch_13.py index 3e7c598..7e0b90b 100644 --- a/ryu/app/simple_switch_13.py +++ b/ryu/app/simple_switch_13.py @@ -117,3 +117,18 @@ class SimpleSwitch13(app_manager.RyuApp): out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out) + + @set_ev_cls(ofp_event.EventOFPPortDescStatsReply, CONFIG_DISPATCHER) + def port_desc_stats_reply_handler(self, ev): + ports = [] + for p in ev.msg.body: + ports.append('port_no=%d hw_addr=%s name=%s config=0x%08x ' + 'state=0x%08x curr=0x%08x advertised=0x%08x ' + 'supported=0x%08x peer=0x%08x curr_speed=%d ' + 'max_speed=%d' % + (p.port_no, p.hw_addr, + p.name, p.config, + p.state, p.curr, p.advertised, + p.supported, p.peer, p.curr_speed, + p.max_speed)) + self.logger.info('OFPPortDescStatsReply received: %s', ports) $ ryu-manager ryu/app/simple_switch_13.py loading app ryu/app/simple_switch_13.py loading app ryu.controller.ofp_handler instantiating app ryu/app/simple_switch_13.py of SimpleSwitch13 instantiating app ryu.controller.ofp_handler of OFPHandler OFPPortDescStatsReply received: ["port_no=4294967294 hw_addr=86:50:c9:21:a6:48 name=b's1' config=0x00000001 state=0x00000001 curr=0x00000000 advertised=0x00000000 supported=0x00000000 peer=0x00000000 curr_speed=0 max_speed=0", "port_no=1 hw_addr=16:e8:94:93:1e:e8 name=b's1-eth1' config=0x00000000 state=0x00000000 curr=0x00000840 advertised=0x00000000 supported=0x00000000 peer=0x00000000 curr_speed=10000000 max_speed=0", "port_no=2 hw_addr=8a:00:10:43:e6:02 name=b's1-eth2' config=0x00000000 state=0x00000000 curr=0x00000840 advertised=0x00000000 supported=0x00000000 peer=0x00000000 curr_speed=10000000 max_speed=0"] Please note that you need to specify CONFIG_DISPATCHER state to @set_ev_cls(), because the automatically sent OFPPortDescStatsRequest/Reply messages will be handle in the config state (this is the internal state of Ryu). Thanks, Iwase On 2016年09月20日 21:44, Nick Sedelnikov wrote: > Hi, > > I think this issue can be related to that fact, that dpset > consumes EventOFPSwitchFeatures event to populate it's switch table (as > shown in ryu-manager output): > > › ryu-manager myapp --verbose > loading app myapp > loading app ryu.controller.ofp_handler > instantiating app None of DPSet > creating context dpset > instantiating app myapp of MyApp > instantiating app ryu.controller.ofp_handler of OFPHandler > BRICK MyApp > CONSUMES EventOFPSwitchFeatures > CONSUMES EventOFPPacketIn > BRICK dpset > CONSUMES EventOFPSwitchFeatures > CONSUMES EventOFPStateChange > CONSUMES EventOFPPortStatus > > I think the best solution is to get switch info in different handler (e.g. > wsgi app), not in switch_features_handler. > > > Best Regards, > Nick > > > сб, 17 сент. 2016 г. в 14:01, Alan Wang <alan820...@gmail.com>: > >> Hi, >> >> Thanks for your reply kindly. >> >> I tried your code. It can run to achieve my goal. >> >> But i tried to add them to the function switch_features_handle of >> simple_switch_13. >> >> The result returned empty dict. Why? >> >> @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) >> def switch_features_handler(self, ev): >> datapath = ev.msg.datapath >> ofproto = datapath.ofproto >> parser = datapath.ofproto_parser >> match = parser.OFPMatch() >> actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, >> ofproto.OFPCML_NO_BUFFER)] >> self.add_flow(datapath, 0, match, actions) >> switches = self.dpset.get_all() >> mac_addresses = [(s[0], >> s[1].ports[ofproto_v1_3.OFPP_LOCAL].hw_addr) >> for s in switches] >> print("mac_addresses {}".format(mac_addresses)) >> >> Thanks, >> >> Regards, >> >> Alan >> >> 2016-09-17 6:32 GMT+08:00 Nick Sedelnikov <n.sedelni...@gmail.com>: >> >>> Alan, >>> >>> I've checked this on simple application: >>> """ >>> from ryu.base import app_manager >>> from ryu.controller import ofp_event >>> from ryu.controller.dpset import DPSet >>> from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls >>> from ryu.ofproto import ofproto_v1_3 >>> >>> >>> class MyApp(app_manager.RyuApp): >>> OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] >>> >>> _CONTEXTS = {'dpset': DPSet} >>> >>> def __init__(self, *args, **kwargs): >>> super(MyApp, self).__init__(*args, **kwargs) >>> self.dpset = kwargs['dpset'] >>> >>> @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) >>> def on_packetin(self, ev): >>> switches = self.dpset.get_all() >>> mac_addresses = [(s[0], >>> s[1].ports[ofproto_v1_3.OFPP_LOCAL].hw_addr) >>> for s in switches] >>> print("mac_addresses {}".format(mac_addresses)) >>> """ >>> >>> First I've started mn like this: `mn --topo=linear,2 --controller=remote` >>> Then I started `ryu-manager myapp --verbose`, and called `pingall` in mn. >>> On packetin i received: >>>>> EVENT ofp_event->MyApp EventOFPPacketIn >>>>> mac_addresses [(1, '3e:a1:63:df:fa:4e'), (2, '8e:8e:51:8f:df:47')] >>> >>> Hope it helps. >>> >>> If it still doesn't work check for correct switch registration by dpset - >>> there must be following lines in output (with --verbose flag set): >>>>> EVENT ofp_event->dpset EventOFPStateChange >>>>> DPSET: register datapath <ryu.controller.controller.Datapath object at >>> 0x7ff879a68550> >>> >>> >>> Nick >>> >>> пт, 16 сент. 2016 г. в 18:07, Alan Wang <alan820...@gmail.com>: >>> >>>> Hi, >>>> >>>> Thanks for your reply. >>>> >>>> I tried your code and simulate it with mininet. >>>> >>>> But it returns empty list. >>>> >>>> How to solve the problem? >>>> >>>> Thanks, >>>> >>>> Alan >>>> >>>> 2016-09-16 21:46 GMT+08:00 Nick Sedelnikov <n.sedelni...@gmail.com>: >>>> >>>>> Hi, >>>>> >>>>> To know all registered switches try: >>>>> """ >>>>> from ryu.controller.dpset import DPSet >>>>> >>>>> class MyApp(app_manager.RyuApp): >>>>> # ... >>>>> >>>>> _CONTEXTS = {'dpset': DPSet} >>>>> >>>>> def __init__(self, *args, **kwargs): >>>>> super(MyApp, self).__init__(*args, **kwargs) >>>>> # ... >>>>> self.dpset = kwargs['dpset'] >>>>> # ... >>>>> """ >>>>> Then fetch switches: >>>>>>> switches = self.dpset.get_all() >>>>>>> mac_addresses = [(s[0], s[1].ports[OFPP_LOCAL].hw_addr) for s in >>>>> switches] >>>>> It will return tuple(dpid, mac_address), like this: >>>>> [(1, '0a:74:ba:ce:11:47'), (2, '32:5b:11:d9:72:4f')] >>>>> >>>>> >>>>> >>>>> пт, 16 сент. 2016 г. в 15:25, Alan Wang <alan820...@gmail.com>: >>>>> >>>>>> Hi All, >>>>>> >>>>>> I want to know the mac address of all switches from controller. How to >>>>>> get the mac >>>>>> >>>>>> address of switch? >>>>>> >>>>>> Thanks, >>>>>> >>>>>> Alan >>>>>> >>>>>> ------------------------------------------------------------------------------ >>>>>> _______________________________________________ >>>>>> Ryu-devel mailing list >>>>>> Ryu-devel@lists.sourceforge.net >>>>>> https://lists.sourceforge.net/lists/listinfo/ryu-devel >>>>>> >>>>> >>>> >> > > > > ------------------------------------------------------------------------------ > > > > _______________________________________________ > Ryu-devel mailing list > Ryu-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/ryu-devel > ------------------------------------------------------------------------------ _______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel