diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2014-11-09 13:50:10 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-11-10 09:31:39 +0900 |
commit | cc544c8deac44a26df67fb23ab2d95440ac94fa6 (patch) | |
tree | e819bca275339ad41269ca70dbf1898fd6440a20 | |
parent | 9ed168178360c1ac490bd17461cbb44c674b832f (diff) |
bgp/cli: show adjacency rib in/out by show neighbor commands
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.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/services/protocols/bgp/operator/command.py | 2 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/operator/commands/show/neighbor.py | 101 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/operator/views/bgp.py | 44 | ||||
-rw-r--r-- | 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 8cdb579c..ccb445fe 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 f4d0f114..860c2eed 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 47245447..b116ee1d 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 5f78b3a8..c9631d39 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 |