mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-09 22:36:10 +02:00
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:
parent
9ed1681783
commit
cc544c8dea
@ -40,7 +40,7 @@ class Command(object):
|
||||
"""
|
||||
|
||||
help_msg = ''
|
||||
param_help_msg = None
|
||||
param_help_msg = ''
|
||||
command = ''
|
||||
cli_resp_line_template = '{0}: {1}\n'
|
||||
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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'
|
||||
)
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user