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

Reply via email to