2 from time import strftime
4 from ryu.services.protocols.bgp.operator.command import Command
5 from ryu.services.protocols.bgp.operator.command import CommandsResponse
6 from ryu.services.protocols.bgp.operator.command import STATUS_ERROR
7 from ryu.services.protocols.bgp.operator.command import STATUS_OK
8 from ryu.services.protocols.bgp.operator.commands.responses import \
10 from ryu.services.protocols.bgp.operator.views.bgp import CoreServiceDetailView
11 from ryu.lib.packet.bgp import RF_IPv4_UC
12 from ryu.lib.packet.bgp import RF_IPv6_UC
13 from ryu.lib.packet.bgp import RF_IPv4_VPN
14 from ryu.lib.packet.bgp import RF_IPv6_VPN
15 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP
16 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP
17 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE
19 LOG = logging.getLogger('bgpspeaker.operator.commands.show.neighbor')
22 class NeighborSummary(Command):
23 help_msg = 'show summarized neighbor information'
26 def action(self, params):
29 requested_peers = [str(p) for p in params]
31 core_service = self.api.get_core_service()
32 core_service_view = CoreServiceDetailView(core_service)
33 peers_view = core_service_view.rel('peer_manager').rel('peers_summary')
35 def filter_requested(peer_id, peer_obj):
36 return not requested_peers or peer_id in requested_peers
38 peers_view.apply_filter(filter_requested)
39 ret = peers_view.encode()
40 return CommandsResponse(STATUS_OK, ret)
43 class SentRoutes(Command):
44 help_msg = 'paths sent and not withdrawn to given peer'
45 command = 'sent-routes'
46 param_help_msg = '<ip_addr> <addr_family>{vpnv4, vpnv6, ipv4, ipv6, all}'
47 fmtstr = ' {0:<2s} {1:<19s} {2:<32s} {3:<8s} {4:<20s} '\
48 '{5:<6s} {6:<6s} {7:<}\n'
50 def action(self, params):
52 return WrongParamResp()
53 ip_addr, addr_family = params
55 if addr_family == 'ipv4':
57 elif addr_family == 'ipv6':
59 elif addr_family == 'vpnv4':
61 elif addr_family == 'vpnv6':
63 elif addr_family == 'all':
66 return WrongParamResp('wrong addr_family name')
68 ret = self._retrieve_paths(addr_family, rf, ip_addr).encode()
69 return CommandsResponse(STATUS_OK, ret)
71 def _retrieve_paths(self, addr_family, route_family, ip_addr):
72 peer_view = self._retrieve_peer_view(ip_addr)
73 adj_rib_out = peer_view.c_rel('adj_rib_out')
74 adj_rib_out.apply_filter(lambda k, v: addr_family == 'all' or
75 v.path.route_family == route_family)
78 def _retrieve_peer_view(self, ip_addr):
79 core_service = self.api.get_core_service()
80 core_sv = CoreServiceDetailView(core_service)
81 peers_view = core_sv.rel('peer_manager').rel('peers')
82 peers_view.apply_filter(lambda k, v: v.ip_address == ip_addr)
86 def cli_resp_formatter(cls, resp):
87 if resp.status == STATUS_ERROR:
88 return Command.cli_resp_formatter(resp)
89 return cls._format_header() + cls._format_value(resp.value)
92 def _format_header(cls):
94 ret += ('Status codes: x filtered\n')
95 ret += ('Origin codes: i - IGP, e - EGP, ? - incomplete\n')
96 ret += cls.fmtstr.format('', 'Timestamp', 'Network', 'Labels',
97 'Next Hop', 'Metric', 'LocPrf', 'Path')
101 def _format_value(cls, value):
105 aspath = path.get('as_path')
106 origin = path.get('origin')
108 if origin == BGP_ATTR_ORIGIN_IGP:
110 elif origin == BGP_ATTR_ORIGIN_EGP:
112 elif origin == BGP_ATTR_ORIGIN_INCOMPLETE:
116 aspath = aspath + [origin]
118 next_hop = path.get('nexthop')
119 med = path.get('metric')
120 labels = path.get('labels')
121 localpref = path.get('local_pref')
122 prefix = path.get('nlri').get('prefix')
125 if v.get('filtered'):
128 if v.get('timestamp'):
129 time = strftime("%Y/%m/%d %H:%M:%S", v.get('timestamp'))
130 ret += cls.fmtstr.format(path_status, time, prefix, labels,
131 str(next_hop), str(med), str(localpref),
132 ' '.join(map(str, aspath)))
136 class ReceivedRoutes(SentRoutes):
137 help_msg = 'paths received and not withdrawn by given peer'
138 command = 'received-routes'
140 def _retrieve_paths(self, addr_family, route_family, ip_addr):
141 peer_view = self._retrieve_peer_view(ip_addr)
142 adj_rib_in = peer_view.c_rel('adj_rib_in')
143 adj_rib_in.apply_filter(lambda k, v: addr_family == 'all' or
144 v.path.route_family == route_family)
148 class Neighbor(Command):
149 help_msg = 'show neighbor information'
152 'summary': NeighborSummary,
153 'sent-routes': SentRoutes,
154 'received-routes': ReceivedRoutes
157 fmtstr = ' {0:<12s} {1:<12s} {2:<}\n'
159 def action(self, params):
160 core_service = self.api.get_core_service()
161 core_service_view = CoreServiceDetailView(core_service)
162 peers_view = core_service_view.rel('peer_manager').rel('peers')
164 ret = peers_view.encode()
165 return CommandsResponse(STATUS_OK,
167 'as_num': str(v['remote_as']),
168 'bgp_state': v['stats']['bgp_state']}
169 for k, v in ret.items()])
172 def cli_resp_formatter(cls, resp):
173 if resp.status == STATUS_ERROR:
174 return Command.cli_resp_formatter(resp)
175 return cls._format_header() + cls._format_value(resp.value)
178 def _format_header(cls):
179 return cls.fmtstr.format('IP Address', 'AS Number', 'BGP State')
182 def _format_value(cls, value):
185 ret += cls.fmtstr.format(v['ip_addr'], v['as_num'], v['bgp_state'])