For the moment I'm using the mx util by miniNext to run netstat -rn on each host, in this way I can easily get the routing table. The problem with what you're saying is that I had to install quagga using apt because when I built it from scratch there were no daemons in init.d and that was causing quagga itself to not work. Even if I manage to configure Zebra daemons to expose their APIs I'm still not sure on how to differentiate the different routers.
Apart the routing table I also need some statistic like packet count in each host or if it's not possible on the switches, how can I get that? Thanks, Alessandro On 27/11/2017 18:56, Iwase Yusuke wrote: > Hi, > > FYI, The following patch enables to connect multiply with the comma > "," separated host addresses > of "--zapi-server-host" option. (Not well tested yet) > > > $ git diff > diff --git a/ryu/services/protocols/zebra/client/zclient.py > b/ryu/services/protocols/zebra/client/zclient.py > index 845ac98..8bb20aa 100644 > --- a/ryu/services/protocols/zebra/client/zclient.py > +++ b/ryu/services/protocols/zebra/client/zclient.py > @@ -83,8 +83,9 @@ class ZServer(object): > Zebra server class. > """ > > - def __init__(self, client): > + def __init__(self, client, zserv_addr): > self.client = client > + self.zserv_addr = zserv_addr > self.logger = client.logger > self.is_active = False > self.sock = None # Client socket connecting to Zebra server > @@ -92,15 +93,20 @@ class ZServer(object): > > def start(self): > self.is_active = True > - try: > - self.sock = create_connection(self.client.zserv_addr) > - except socket.error as e: > - self.logger.exception( > - 'Cannot connect to Zebra server%s: %s', > - self.client.zserv_addr, e) > - self.stop() > - return None > - > + while self.is_active: > + try: > + self.sock = create_connection(self.zserv_addr) > + except socket.error as e: > + self.logger.exception( > + 'Cannot connect to Zebra server%s: %s', > + self.zserv_addr, e) > + # Do retry > + hub.sleep(CONF.retry_interval) > + continue > + > + self._serve() > + > + def _serve(self): > self.sock.settimeout(GLOBAL_CONF.socket_timeout) > > self.threads.append(hub.spawn(self._send_loop)) > @@ -195,8 +201,9 @@ class ZClient(RyuApp): > > def __init__(self, *args, **kwargs): > super(ZClient, self).__init__(*args, **kwargs) > - self.zserv = None # ZServer instance > - self.zserv_addr = (CONF.server_host, CONF.server_port) > + self.zserv_threads = [] # ZServer thread instances > + self.zserv_addrs = [ > + (h, CONF.server_port) for h in CONF.server_host.split(',')] > self.zserv_ver = CONF.server_version > self.send_q = hub.Queue(16) > self.route_type = get_zebra_route_type_by_name( > @@ -208,18 +215,22 @@ class ZClient(RyuApp): > return hub.spawn(self._service_loop) > > def _service_loop(self): > - while self.is_active: > - self.zserv = ZServer(self) > - self.zserv.start() > + for addr in self.zserv_addrs: > + zserv = ZServer(self, addr) > + self.zserv_threads.append(hub.spawn(zserv.start)) > > - hub.sleep(CONF.retry_interval) > + hub.joinall(self.zserv_threads) > > self.close() > > def close(self): > self.is_active = False > self._send_event(self._event_stop, None) > - self.zserv.stop() > + for t in self.zserv_threads: > + try: > + t.kill() > + except: > + pass > > def send_msg(self, msg): > """ > > > $ ryu-manager --zapi-server-host=<addr1>,<addr2> > ryu/services/protocols/zebra/client/sample_dumper.py > > > Please note you also need to configure Zebra daemons to expose their > APIs (Unix domain sockets or > TCP ports) to your Ryu host. > > Thanks, > Iwase > > > On 2017年11月28日 09:17, Iwase Yusuke wrote: >> Hi, >> >> Well... I didn't suppose the situation Ryu is connecting to multiple >> Zebra daemons. >> Because, by the default, Zebra (Quagga) uses the Unix domain socket >> to connect to other protocol >> daemons and the Unix domain socket provides its self like a "local >> file" (difficult to access >> it remotely), then I guess it requires the complex environment for >> multiple Zebra daemons topology. >> >> If you build (when "./configure") Zebra (Quagga) with >> "--enable-tcp-zebra" option, Zebra will expose >> the Zebra API as the TCP port (the default number is 2600), and you >> can access it with "ryu-manager >> --zapi-server-host=<Zebra Host IP>". >> (APT packaged Quagga is configured without "--enable-tcp-zebra") >> >> But, Anyway, the current Ryu Zebra service cannot connect to the >> multiple Zebra daemons... >> To enable to connect multiply, we need to some modifications on Ryu. >> >> Thanks, >> Iwase >> >> On 2017年11月28日 06:09, Alessandro Gaballo wrote: >>> Hi, >>> I'm using the following options for isolation: >>> >>> / privateLogDir=True// >>> // privateRunDir=True// >>> // inMountNamespace=True// >>> // inPIDNamespace=True// >>> // inUTSNamespace=True/ >>> >>> ryu-manager --zapi-server-host=/var/run/quagga/zserv.api >>> ryu/services/protocols/zebra/client/sample_dumper.py >>> >>> The command above works if I run it on the host, but I was looking >>> for a more centralized way, I wanted to get everything from the >>> controller with a single ryu-app. >>> >>> >>> On 25/11/2017 01:37, Iwase Yusuke wrote: >>>> Hi, >>>> >>>> Sorry, I haven't writing the docs for the Zebra service yet, >>>> because this feature is very >>>> experimental... >>>> >>>> For connecting to the specific Zebra daemon on a Mininet host, >>>> first, you need to find the >>>> path to the Zebra API socket (unix domain socket) or the TCP port >>>> for the Zebra API. >>>> This path or TCP port number is depending on the "configure" option >>>> when building the Zebra >>>> (Quagga) binaries, and mostly placed on "/var/run/quagga/zserv.api" >>>> or "127.0.0.1:2600". >>>> I don't know how you separate each namespaces for the Zebra >>>> daemons, please try to start >>>> the "sample_dumper.py" with >>>> "--zapi-server-host=/var/run/quagga/zserv.api" option on the >>>> Mininet host on which the Zebra daemon running. >>>> e.g.) >>>> $ ryu-manager --zapi-server-host=/var/run/quagga/zserv.api >>>> ryu/services/protocols/zebra/client/sample_dumper.py >>>> >>>> And for the naming of event classes which "sample_dumper.py" >>>> specifies, please refer the >>>> pydoc of the following module. The naming convention is the similar >>>> to the OpenFlow event >>>> classes. >>>> https://github.com/osrg/ryu/blob/ed2c6eca2227c9efb3c7e51cdd6db6bf578ec609/ryu/services/protocols/zebra/event.py#L35-L57 >>>> >>>> >>>> >>>> Thanks, >>>> Iwase >>>> >>>> >>>> On 2017年11月25日 02:17, Alessandro Gaballo wrote: >>>>> Thanks for the reply, I'm running quagga on mininet and each >>>>> router is >>>>> in its own namespace, I think I need to connect to one specific zebra >>>>> daemon. >>>>> Do you know where I can find other examples or a clear docs for >>>>> these APIs? >>>>> >>>>> >>>>> On 23/11/2017 23:48, Iwase Yusuke wrote: >>>>>> Hi, >>>>>> >>>>>> How about using the Zebra client service library of Ryu? >>>>>> https://github.com/osrg/ryu/blob/master/ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> >>>>>> >>>>>> >>>>>> This library provides the APIs to communicate with the Zebra >>>>>> daemon of >>>>>> Quagga (or FRRouting). >>>>>> For example, if you need "connected" routes in your Ryu application, >>>>>> the following dumps the >>>>>> "connected" routes which the Zebra daemon redistributed. >>>>>> >>>>>> >>>>>> $ git diff >>>>>> diff --git a/ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> b/ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> index 395620e..b4ab8ac 100644 >>>>>> --- a/ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> +++ b/ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> @@ -32,6 +32,17 @@ class ZClientDumper(ZClient): >>>>>> 'Zebra server connected to %s: %s', >>>>>> ev.zserv.sock.getpeername(), ev.zserv.sock) >>>>>> >>>>>> + # Send redistribute add message for the route type which >>>>>> you >>>>>> need >>>>>> + for route_type in [zebra.ZEBRA_ROUTE_CONNECT]: >>>>>> + self.send_msg( >>>>>> + zebra.ZebraMessage( >>>>>> + version=self.zserv_ver, >>>>>> + body=zebra.ZebraRedistributeAdd( >>>>>> + route_type=route_type, >>>>>> + ), >>>>>> + ), >>>>>> + ) >>>>>> + >>>>>> @set_ev_cls(event.EventZebraRouterIDUpdate) >>>>>> def _router_id_update_handler(self, ev): >>>>>> self.logger.info( >>>>>> @@ -47,6 +58,16 @@ class ZClientDumper(ZClient): >>>>>> self.logger.info( >>>>>> 'ZEBRA_INTERFACE_ADDRESS_ADD received: %s', >>>>>> ev.__dict__) >>>>>> >>>>>> + @set_ev_cls(event.EventZebraIPv4RouteAdd) >>>>>> + def _ipv4_route_add_handler(self, ev): >>>>>> + self.logger.info( >>>>>> + 'ZEBRA_IPV4_ROUTE_ADD received: %s', ev.__dict__) >>>>>> + >>>>>> + @set_ev_cls(event.EventZebraIPv4RouteDelete) >>>>>> + def _ipv4_route_delete_handler(self, ev): >>>>>> + self.logger.info( >>>>>> + 'ZEBRA_IPV4_ROUTE_DELETE received: %s', ev.__dict__) >>>>>> + >>>>>> @set_ev_cls(zclient_event.EventZServDisconnected) >>>>>> def _zserv_disconnected_handler(self, ev): >>>>>> self.logger.info( >>>>>> >>>>>> >>>>>> $ ryu-manager ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> loading app ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> instantiating app >>>>>> ryu/services/protocols/zebra/client/sample_dumper.py >>>>>> of ZClientDumper >>>>>> Zebra server connected to /var/run/quagga/zserv.api: >>>>>> <eventlet.greenio.base.GreenSocket object at 0x7fb945a14a90> >>>>>> ...(snip)... >>>>>> ZEBRA_IPV4_ROUTE_ADD received: {'zclient': >>>>>> <sample_dumper.ZClientDumper object at 0x7fb949b5a668>, >>>>>> 'version': 2, >>>>>> 'body': >>>>>> ZebraIPv4RouteAdd(distance=0,flags=16,from_zebra=True,ifindexes=[1],instance=None,message=15,metric=0,mtu=None,nexthops=['0.0.0.0'],prefix='2.2.2.2/32',route_type=2,safi=None,src_prefix=None,tag=None), >>>>>> >>>>>> >>>>>> 'command': 7, 'length': 29, 'vrf_id': 0} >>>>>> ZEBRA_IPV4_ROUTE_ADD received: {'zclient': >>>>>> <sample_dumper.ZClientDumper object at 0x7fb949b5a668>, >>>>>> 'version': 2, >>>>>> 'body': >>>>>> ZebraIPv4RouteAdd(distance=0,flags=16,from_zebra=True,ifindexes=[2],instance=None,message=15,metric=0,mtu=None,nexthops=['0.0.0.0'],prefix='192.168.23.0/24',route_type=2,safi=None,src_prefix=None,tag=None), >>>>>> >>>>>> >>>>>> 'command': 7, 'length': 28, 'vrf_id': 0} >>>>>> ZEBRA_IPV4_ROUTE_ADD received: {'zclient': >>>>>> <sample_dumper.ZClientDumper object at 0x7fb949b5a668>, >>>>>> 'version': 2, >>>>>> 'body': >>>>>> ZebraIPv4RouteAdd(distance=0,flags=16,from_zebra=True,ifindexes=[3],instance=None,message=15,metric=0,mtu=None,nexthops=['0.0.0.0'],prefix='192.168.24.0/24',route_type=2,safi=None,src_prefix=None,tag=None), >>>>>> >>>>>> >>>>>> 'command': 7, 'length': 28, 'vrf_id': 0} >>>>>> >>>>>> >>>>>> Thanks, >>>>>> Iwase >>>>>> >>>>>> >>>>>> On 2017年11月23日 00:27, Alessandro Gaballo wrote: >>>>>>> Hi, I'm running Quagga on my mininet topology to capture routing >>>>>>> information, I wanted to know if it's possible to retrieve the >>>>>>> routing >>>>>>> table on the quagga routers (which are basically mininet hosts) >>>>>>> or at >>>>>>> least the flow tables. If so, how do I do it? >>>>>>> >>>>>>> >>>>>>> ------------------------------------------------------------------------------ >>>>>>> >>>>>>> >>>>>>> >>>>>>> Check out the vibrant tech community on one of the world's most >>>>>>> engaging tech sites, Slashdot.org!http://sdm.link/slashdot >>>>>>> _______________________________________________ >>>>>>> Ryu-devel mailing list >>>>>>> Ryu-devel@lists.sourceforge.net >>>>>>> https://lists.sourceforge.net/lists/listinfo/ryu-devel >>>>>>> >>>>> ------------------------------------------------------------------------------ >>>>> >>>>> >>>>> Check out the vibrant tech community on one of the world's most >>>>> engaging tech sites, Slashdot.org!http://sdm.link/slashdot >>>>> _______________________________________________ >>>>> Ryu-devel mailing list >>>>> Ryu-devel@lists.sourceforge.net >>>>> https://lists.sourceforge.net/lists/listinfo/ryu-devel >>>>> >>> >>> >>> >>> ------------------------------------------------------------------------------ >>> >>> >>> Check out the vibrant tech community on one of the world's most >>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot >>> >>> >>> >>> _______________________________________________ >>> Ryu-devel mailing list >>> Ryu-devel@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/ryu-devel >>> ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel