Hi Alessandro,

First, the init.d script included in the APT package works well with the 
locally built Quagga on my
environment. How about trying it?
https://www.apt-browse.org/browse/ubuntu/xenial/main/amd64/quagga/0.99.24.1-2ubuntu1/file/etc/init.d/quagga

But well... Please let me confirm your original question.
You don't need to get routes "directly" from Quagga, right? You just need to 
get the routes
installed on the Kernel?

If so, the integration with Quagga might be too complex approach...
It seems the "netlink" is relatively reasonable way to get routes on the Kernel.
For example, invoke "netstat -nr", "ip route", "ip -s link" remotely from your 
application.
Or pyroute2 packages provides the netlink APIs.
https://github.com/svinota/pyroute2


> 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?

If you mention about the port statistics of the Kernel, it is out of scope of 
the OpenFlow.

With Quagga approach, if you set "link-params" for the Zebra interfaces, the 
Zebra daemons will
reports statistics via ZEBRA_INTERFACE_ADD or ZEBRA_INTERFACE_LINK_PARAMS 
messages.
http://www.nongnu.org/quagga/docs/docs-multi/Link-Parameters-Commands.html

With the netlink approach, "ip -s link" shows the statistics for each link.


Thanks,
Iwase


On 2017年11月29日 00:33, Alessandro Gaballo wrote:
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


------------------------------------------------------------------------------
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