show neighbor sent-routes/received-routes commands used to show the
routes in local rib, but the right behavior is to show adjacency rib
in/out.

Signed-off-by: ISHIDA Wataru <ishida.wat...@lab.ntt.co.jp>
---
 ryu/services/protocols/bgp/operator/command.py     |    2 +-
 .../bgp/operator/commands/show/neighbor.py         |  101 +++++++++++---------
 ryu/services/protocols/bgp/operator/views/bgp.py   |   44 ++++++++-
 ryu/services/protocols/bgp/peer.py                 |    8 ++
 4 files changed, 107 insertions(+), 48 deletions(-)

diff --git a/ryu/services/protocols/bgp/operator/command.py 
b/ryu/services/protocols/bgp/operator/command.py
index 8cdb579..ccb445f 100644
--- a/ryu/services/protocols/bgp/operator/command.py
+++ b/ryu/services/protocols/bgp/operator/command.py
@@ -40,7 +40,7 @@ class Command(object):
     """
 
     help_msg = ''
-    param_help_msg = None
+    param_help_msg = ''
     command = ''
     cli_resp_line_template = '{0}: {1}\n'
 
diff --git a/ryu/services/protocols/bgp/operator/commands/show/neighbor.py 
b/ryu/services/protocols/bgp/operator/commands/show/neighbor.py
index f4d0f11..860c2ee 100644
--- a/ryu/services/protocols/bgp/operator/commands/show/neighbor.py
+++ b/ryu/services/protocols/bgp/operator/commands/show/neighbor.py
@@ -1,5 +1,5 @@
 import logging
-import pprint
+from time import strftime
 
 from ryu.services.protocols.bgp.operator.command import Command
 from ryu.services.protocols.bgp.operator.command import CommandsResponse
@@ -13,7 +13,7 @@ from ryu.lib.packet.bgp import RF_IPv6_UC
 from ryu.lib.packet.bgp import RF_IPv4_VPN
 from ryu.lib.packet.bgp import RF_IPv6_VPN
 
-LOG = logging.getLogger('bgpspeaker.operator.commands.show.summary')
+LOG = logging.getLogger('bgpspeaker.operator.commands.show.neighbor')
 
 
 class NeighborSummary(Command):
@@ -41,6 +41,8 @@ class SentRoutes(Command):
     help_msg = 'paths sent and not withdrawn to given peer'
     command = 'sent-routes'
     param_help_msg = '<ip_addr> <addr_family>{vpnv4, vpnv6, ipv4, ipv6, all}'
+    fmtstr = ' {0:<2s} {1:<19s} {2:<32s} {3:<8s} {4:<20s} '\
+        '{5:<6s} {6:<6s} {7:<}\n'
 
     def action(self, params):
         if len(params) != 2:
@@ -61,44 +63,63 @@ class SentRoutes(Command):
             return WrongParamResp('wrong addr_family name')
 
         ret = self._retrieve_paths(addr_family, rf, ip_addr).encode()
-        ret = dict([
-            (path['nlri']['formatted_nlri'], path)
-            for path in ret
-        ])
-
         return CommandsResponse(STATUS_OK, ret)
 
     def _retrieve_paths(self, addr_family, route_family, ip_addr):
-        global_tables_view = self._retrieve_global_tables_view(
-            addr_family,
-            route_family
-        )
-        sent = global_tables_view.c_rel('destinations').c_rel('sent_routes')
-        sent.apply_filter(
-            lambda route: route.sent_peer.ip_address == ip_addr
-        )
-        paths = sent.c_rel('path')
-        paths.apply_filter(
-            lambda path: not path.is_withdraw
-        )
-        return paths
-
-    def _retrieve_global_tables_view(self, addr_family, route_family):
+        peer_view = self._retrieve_peer_view(ip_addr)
+        adj_rib_out = peer_view.c_rel('adj_rib_out')
+        adj_rib_out.apply_filter(lambda k, v: addr_family == 'all' or
+                                 v.path.route_family == route_family)
+        return adj_rib_out
+
+    def _retrieve_peer_view(self, ip_addr):
         core_service = self.api.get_core_service()
         core_sv = CoreServiceDetailView(core_service)
-        table_manager_view = core_sv.rel('table_manager')
-        global_tables_view = table_manager_view.rel('global_tables')
-        global_tables_view.apply_filter(
-            lambda k, v: addr_family == 'all' or k == route_family
-        )
-        return global_tables_view
+        peers_view = core_sv.rel('peer_manager').rel('peers')
+        peers_view.apply_filter(lambda k, v: v.ip_address == ip_addr)
+        return peers_view
 
     @classmethod
     def cli_resp_formatter(cls, resp):
         if resp.status == STATUS_ERROR:
             return Command.cli_resp_formatter(resp)
+        return cls._format_header() + cls._format_value(resp.value)
 
-        return '\n{0}'.format(pprint.pformat(resp.value))
+    @classmethod
+    def _format_header(cls):
+        ret = ''
+        ret += ('Status codes: x filtered\n')
+        ret += ('Origin codes: i - IGP, e - EGP, ? - incomplete\n')
+        ret += cls.fmtstr.format('', 'Timestamp', 'Network', 'Labels',
+                                 'Next Hop', 'Metric', 'LocPrf', 'Path')
+        return ret
+
+    @classmethod
+    def _format_value(cls, value):
+        ret = ''
+        for v in value:
+            path = v.get('path')
+            aspath = path.get('as_path')
+            origin = path.get('origin')
+            if origin:
+                aspath.append(origin)
+
+            next_hop = path.get('nexthop')
+            med = path.get('metric')
+            labels = path.get('labels')
+            localpref = path.get('local_pref')
+            prefix = path.get('nlri').get('prefix')
+
+            path_status = ''
+            if v.get('filtered'):
+                path_status = 'x'
+            time = 'N/A'
+            if v.get('timestamp'):
+                time = strftime("%Y/%m/%d %H:%M:%S", v.get('timestamp'))
+            ret += cls.fmtstr.format(path_status, time, prefix, labels,
+                                     next_hop, str(med), str(localpref),
+                                     ' '.join(map(str, aspath)))
+        return ret
 
 
 class ReceivedRoutes(SentRoutes):
@@ -106,23 +127,11 @@ class ReceivedRoutes(SentRoutes):
     command = 'received-routes'
 
     def _retrieve_paths(self, addr_family, route_family, ip_addr):
-        global_tables_view = self._retrieve_global_tables_view(
-            addr_family,
-            route_family
-        )
-        paths = global_tables_view.c_rel(
-            'destinations'
-        ).c_rel('known_path_list')
-
-        def path_filter(path):
-            return path.source is not None and \
-                path.source.ip_address == ip_addr and \
-                not path.is_withdraw
-
-        paths.apply_filter(
-            path_filter
-        )
-        return paths
+        peer_view = self._retrieve_peer_view(ip_addr)
+        adj_rib_in = peer_view.c_rel('adj_rib_in')
+        adj_rib_in.apply_filter(lambda k, v: addr_family == 'all' or
+                                v.path.route_family == route_family)
+        return adj_rib_in
 
 
 class Neighbor(Command):
diff --git a/ryu/services/protocols/bgp/operator/views/bgp.py 
b/ryu/services/protocols/bgp/operator/views/bgp.py
index 4724544..b116ee1 100644
--- a/ryu/services/protocols/bgp/operator/views/bgp.py
+++ b/ryu/services/protocols/bgp/operator/views/bgp.py
@@ -80,6 +80,14 @@ class PeerDetailView(OperatorDetailView):
     remote_as = fields.DataField('remote_as')
     ip_address = fields.DataField('ip_address')
     enabled = fields.DataField('enabled')
+    adj_rib_in = fields.RelatedViewField(
+        'adj_rib_in',
+        'ryu.services.protocols.bgp.operator.views.bgp.ReceivedRouteDictView'
+    )
+    adj_rib_out = fields.RelatedViewField(
+        'adj_rib_out',
+        'ryu.services.protocols.bgp.operator.views.bgp.SentRouteDictView'
+    )
     neigh_conf = fields.RelatedViewField(
         '_neigh_conf',
         'ryu.services.protocols.bgp.operator.views.conf.ConfDetailView'
@@ -171,15 +179,44 @@ class PathDetailView(OperatorDetailView):
 
 
 class SentRouteDetailView(OperatorDetailView):
+    timestamp = fields.DataField('timestamp')
+    filtered = fields.DataField('filtered')
     path = fields.RelatedViewField(
         'path',
         'ryu.services.protocols.bgp.operator.views.bgp.PathDetailView',
     )
     peer = fields.RelatedViewField(
-        '_sent_peer',
+        'sent_peer',
         'ryu.services.protocols.bgp.operator.views.bgp.PeerDetailView'
     )
 
+    def encode(self):
+        ret = super(SentRouteDetailView, self).encode()
+        ret.update({
+            'path': self.rel('path').encode(),
+        })
+        return ret
+
+
+class ReceivedRouteDetailView(OperatorDetailView):
+    timestamp = fields.DataField('timestamp')
+    filtered = fields.DataField('filtered')
+    path = fields.RelatedViewField(
+        'path',
+        'ryu.services.protocols.bgp.operator.views.bgp.PathDetailView',
+    )
+    peer = fields.RelatedViewField(
+        'received_peer',
+        'ryu.services.protocols.bgp.operator.views.bgp.PeerDetailView'
+    )
+
+    def encode(self):
+        ret = super(ReceivedRouteDetailView, self).encode()
+        ret.update({
+            'path': self.rel('path').encode(),
+        })
+        return ret
+
 
 class DestinationDetailView(OperatorDetailView):
     table = fields.RelatedViewField(
@@ -280,3 +317,8 @@ SentRouteDictView = create_dict_view_class(
     SentRouteDetailView,
     'SentRouteDictView'
 )
+
+ReceivedRouteDictView = create_dict_view_class(
+    ReceivedRouteDetailView,
+    'ReceivedRouteDictView'
+)
diff --git a/ryu/services/protocols/bgp/peer.py 
b/ryu/services/protocols/bgp/peer.py
index 5f78b3a..c9631d3 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
@@ -409,6 +409,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
         self.on_update_out_filter()
 
     @property
+    def adj_rib_in(self):
+        return self._adj_rib_in
+
+    @property
+    def adj_rib_out(self):
+        return self._adj_rib_out
+
+    @property
     def is_route_server_client(self):
         return self._neigh_conf.is_route_server_client
 
-- 
1.7.10.4


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to