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>
This commit is contained in:
ISHIDA Wataru 2014-11-09 13:50:10 +09:00 committed by FUJITA Tomonori
parent 9ed1681783
commit cc544c8dea
4 changed files with 106 additions and 47 deletions

View File

@ -40,7 +40,7 @@ class Command(object):
"""
help_msg = ''
param_help_msg = None
param_help_msg = ''
command = ''
cli_resp_line_template = '{0}: {1}\n'

View File

@ -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
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_global_tables_view(self, addr_family, route_family):
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):

View File

@ -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'
)

View File

@ -408,6 +408,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
LOG.debug('set out-filter : %s' % filters)
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