Hi Iwase,
I've made the modifications accordingly. *Now i am able to see the output
for vrfs_get() and rib_get()*. *However there is still no output
for neighbor_get() . ---output is in **BGPTest-output.py*
*Pls advice how to get the output for neighbor_get().*
*Enclosed herewith: (1) modified bgpapplication1.py & (2)
BGPTest-output.py*
Thanks
Hadem
On Fri, Jan 12, 2018 at 7:36 AM, Iwase Yusuke <iwase.yusu...@gmail.com>
wrote:
> Hi Hadem,
>
> First, the return value for each BGPSpeaker's API (with format="json") is
> str
> type value.
> Why you need to split them like;
> vrf_result = self.speaker.vrfs_get('routes', None, 'all', 'json')
> nowtime = vrf_result[0] # <--- ?
> result = vrf_result[1] # <--- ?
>
> And, please confirm the meaning of each argument when calling BGPSpeaker's
> APIs.
> For example, to getting all VRF configurations, you need to specify
> "summary"
> instead of "routes".
> http://ryu.readthedocs.io/en/latest/library_bgp_speaker_ref.
> html#ryu.services.protocols.bgp.bgpspeaker.BGPSpeaker.vrfs_get
>
> Thanks,
> Iwase
>
>
> On 2018年01月11日 21:55, Pynbiang Hadem wrote:
>
>> *Hi,*
>> *
>> *
>> *I am getting blank output for BGPSpeaker show_vrf, show_rib,
>> show_neighbor. The partial output is as below:*
>> ----------------------------------
>> /Sending MED Update Message.../
>> /Send BGP UPDATE Message for changing MED[100]/
>> /API method neighbor.update called with args: {'ip_address': '10.0.0.2',
>> 'changes': {'multi_exit_disc': 100}}/
>> /on_update_med fired/
>> /MED value for neigh: Neighbor: 10.0.0.2 updated to 100/
>> /Calling get VRFs Information .../
>> /Shows BGP VRF information in a json format/
>> /API method operator.show called with args: {'params': ['vrf', 'routes',
>> 'all'], 'format': 'json'}/
>> /+++++++++++++++++++++++++++++++/
>> /{ : Show VRFs /
>> /+++++++++++++++++++++++++++++++/
>> /"/
>> /
>> /
>> /Calling SHOW RIB .../
>> /Shows BGP routing information in a json format/
>> /API method operator.show called with args: {'params': ['rib', 'all'],
>> 'format': 'json'}/
>> /+++++++++++++++++++++++++++++++/
>> /{ : Show rib /
>> /+++++++++++++++++++++++++++++++/
>> /"/
>> /
>> /
>> /Calling SHOW Neighbor.../
>> /Inside Show Neighbor BGP UPDATE Message/
>> /API method operator.show called with args: {'params': ['neighbor',
>> 'received-routes', '10.0.0.2', 'all'], 'format': 'json'}/
>> /[]/
>> /+++++++++++++++++++++++++++++++/
>> /[ : Show neighbor /
>> /+++++++++++++++++++++++++++++++/
>> /]/
>> ------------------------------------------
>>
>> *I am attaching herewith my BGP application file(bgpapplication1.py). *
>> *Pls let me know what mistake i have done and how to display the above
>> details.*
>> *
>> *
>> *Thanks*
>> *Hadem*
>>
>>
>>
>>
>> ------------------------------------------------------------
>> ------------------
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>>
>>
>>
>> _______________________________________________
>> Ryu-devel mailing list
>> Ryu-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/ryu-devel
>>
>>
# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Defines bases classes to create a BGP application.
"""
import logging
import os
#Hadem
import json
from ryu import cfg
from ryu.lib import hub
from ryu.utils import load_source
from ryu.base.app_manager import RyuApp
from ryu.controller.event import EventBase
from ryu.services.protocols.bgp.base import add_bgp_error_metadata
from ryu.services.protocols.bgp.base import BGPSException
from ryu.services.protocols.bgp.base import BIN_ERROR
from ryu.services.protocols.bgp.bgpspeaker import BGPSpeaker
from ryu.services.protocols.bgp.net_ctrl import NET_CONTROLLER
from ryu.services.protocols.bgp.net_ctrl import NC_RPC_BIND_IP
from ryu.services.protocols.bgp.net_ctrl import NC_RPC_BIND_PORT
from ryu.services.protocols.bgp.rtconf.base import RuntimeConfigError
from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_PORT
from ryu.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_PORT
from ryu.services.protocols.bgp.rtconf.common import (
DEFAULT_REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_STALEPATH_TIME)
from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LABEL_RANGE
from ryu.services.protocols.bgp.rtconf.common import LABEL_RANGE
from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
from ryu.services.protocols.bgp.rtconf.common import REFRESH_MAX_EOR_TIME
from ryu.services.protocols.bgp.rtconf.common import REFRESH_STALEPATH_TIME
from ryu.services.protocols.bgp.rtconf.common import ROUTER_ID
from ryu.services.protocols.bgp.rtconf.common import LOCAL_PREF
from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LOCAL_PREF
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv6
LOG = logging.getLogger('bgpspeaker.application')
CONF = cfg.CONF['bgp-app']
@add_bgp_error_metadata(code=BIN_ERROR,
sub_code=1,
def_desc='Unknown bootstrap exception.')
class ApplicationException(BGPSException):
"""
Specific Base exception related to `BSPSpeaker`.
"""
pass
def validate_rpc_host(ip):
"""
Validates the given ip for use as RPC server address.
"""
if not is_valid_ipv4(ip) and not is_valid_ipv6(ip):
raise ApplicationException(
desc='Invalid RPC ip address: %s' % ip)
return ip
def load_config(config_file):
"""
Validates the given file for use as the settings file for BGPSpeaker
and loads the configuration from the given file as a module instance.
"""
if not config_file or not os.path.isfile(config_file):
raise ApplicationException(
desc='Invalid configuration file: %s' % config_file)
# Loads the configuration from the given file, if available.
try:
return load_source('bgpspeaker.application.settings', config_file)
except Exception as e:
raise ApplicationException(desc=str(e))
class EventBestPathChanged(EventBase):
"""
Event called when any best remote path is changed due to UPDATE messages
or remote peer's down.
This event is the wrapper for ``best_path_change_handler`` of
``bgpspeaker.BGPSpeaker``.
``path`` attribute contains an instance of ``info_base.base.Path``
subclasses.
If ``is_withdraw`` attribute is ``True``, ``path`` attribute has the
information of the withdraw route.
"""
def __init__(self, path, is_withdraw):
super(EventBestPathChanged, self).__init__()
self.path = path
self.is_withdraw = is_withdraw
class EventPeerDown(EventBase):
"""
Event called when the session to the remote peer goes down.
This event is the wrapper for ``peer_down_handler`` of
``bgpspeaker.BGPSpeaker``.
``remote_ip`` attribute is the IP address of the remote peer.
``remote_as`` attribute is the AS number of the remote peer.
"""
def __init__(self, remote_ip, remote_as):
super(EventPeerDown, self).__init__()
self.remote_ip = remote_ip
self.remote_as = remote_as
class EventPeerUp(EventBase):
"""
Event called when the session to the remote peer goes up.
This event is the wrapper for ``peer_up_handler`` of
``bgpspeaker.BGPSpeaker``.
``remote_ip`` attribute is the IP address of the remote peer.
``remote_as`` attribute is the AS number of the remote peer.
"""
def __init__(self, remote_ip, remote_as):
super(EventPeerUp, self).__init__()
self.remote_ip = remote_ip
self.remote_as = remote_as
class RyuBGPSpeaker(RyuApp):
"""
Base application for implementing BGP applications.
This application will notifies
- ``EventBestPathChanged``
- ``EventPeerDown``
- ``EventPeerUp``
to other BGP applications.
To catch these events, specify ``@set_ev_cls()`` decorator to the event
handlers in the Ryu applications.
Example::
...
from ryu.base import app_manager
from ryu.controller.handler import set_ev_cls
from ryu.services.protocols.bgp import application as bgp_application
...
class MyBGPApp(app_manager.RyuApp):
_CONTEXTS = {
'ryubgpspeaker': bgp_application.RyuBGPSpeaker,
}
...
@set_ev_cls(bgp_application.EventBestPathChanged)
def _best_patch_changed_handler(self, ev):
self.logger.info(
'Best path changed: is_withdraw=%s, path=%s',
ev.is_withdraw, ev.path)
"""
_EVENTS = [
EventBestPathChanged,
EventPeerDown,
EventPeerUp,
]
def __init__(self, *args, **kwargs):
super(RyuBGPSpeaker, self).__init__(*args, **kwargs)
self.config_file = CONF.config_file
# BGPSpeaker instance (not instantiated yet)
self.speaker = None
def start(self):
super(RyuBGPSpeaker, self).start()
# If configuration file was provided and loaded successfully, we start
# BGPSpeaker using the given settings.
# If no configuration file is provided or if any minimum required
# setting is missing, BGPSpeaker will not be started.
if self.config_file:
LOG.debug('Loading config file %s...', self.config_file)
settings = load_config(self.config_file)
# Configure logging settings, if available.
if hasattr(settings, 'LOGGING'):
# Not implemented yet.
LOG.debug('Loading LOGGING settings... (NOT implemented yet)')
# from logging.config import dictConfig
# logging_settings = dictConfig(settings.LOGGING)
# Configure BGP settings, if available.
if hasattr(settings, 'BGP'):
LOG.debug('Loading BGP settings...')
self._start_speaker(settings.BGP)
# Configure SSH settings, if available.
if hasattr(settings, 'SSH'):
LOG.debug('Loading SSH settings...')
# Note: paramiko used in bgp.operator.ssh is the optional
# requirements, imports bgp.operator.ssh here.
from ryu.services.protocols.bgp.operator import ssh
hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **settings.SSH)
# Start RPC server with the given RPC settings.
rpc_settings = {
NC_RPC_BIND_PORT: CONF.rpc_port,
NC_RPC_BIND_IP: validate_rpc_host(CONF.rpc_host),
}
return hub.spawn(NET_CONTROLLER.start, **rpc_settings)
def _start_speaker(self, settings):
"""
Starts BGPSpeaker using the given settings.
"""
# Settings for starting BGPSpeaker
bgp_settings = {}
# Get required settings.
try:
bgp_settings['as_number'] = settings.get(LOCAL_AS)
bgp_settings['router_id'] = settings.get(ROUTER_ID)
except KeyError as e:
raise ApplicationException(
desc='Required BGP configuration missing: %s' % e)
# Set event notify handlers if no corresponding handler specified.
bgp_settings['best_path_change_handler'] = settings.get(
'best_path_change_handler', self._notify_best_path_changed_event)
bgp_settings['peer_down_handler'] = settings.get(
'peer_down_handler', self._notify_peer_down_event)
bgp_settings['peer_up_handler'] = settings.get(
'peer_up_handler', self._notify_peer_up_event)
# Get optional settings.
bgp_settings[BGP_SERVER_PORT] = settings.get(
BGP_SERVER_PORT, DEFAULT_BGP_SERVER_PORT)
bgp_settings[REFRESH_STALEPATH_TIME] = settings.get(
REFRESH_STALEPATH_TIME, DEFAULT_REFRESH_STALEPATH_TIME)
bgp_settings[REFRESH_MAX_EOR_TIME] = settings.get(
REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_MAX_EOR_TIME)
bgp_settings[LABEL_RANGE] = settings.get(
LABEL_RANGE, DEFAULT_LABEL_RANGE)
bgp_settings['allow_local_as_in_count'] = settings.get(
'allow_local_as_in_count', 0)
bgp_settings[LOCAL_PREF] = settings.get(
LOCAL_PREF, DEFAULT_LOCAL_PREF)
# Create BGPSpeaker instance.
LOG.debug('Starting BGPSpeaker...')
self.speaker = BGPSpeaker(**bgp_settings)
# Add neighbors.
LOG.debug('Adding neighbors...')
self._add_neighbors(settings.get('neighbors', []))
# Add VRFs.
LOG.debug('Adding VRFs...')
self._add_vrfs(settings.get('vrfs', []))
# Add Networks
LOG.debug('Adding routes...')
self._add_routes(settings.get('routes', []))
# MED Update Messages
LOG.debug('Sending MED Update Message...')
#self._send_BGPupdate_message(settings.get('neighbors.address', []), 200)
self.send_BGPupdate_message('10.0.0.2', 100)
# Shows VRFs Information
LOG.debug('Calling get VRFs Information ...')
self.show_vrf()
# Hadem Shows RIB Information
LOG.debug('Calling SHOW RIB ...')
self.show_rib()
# Shows BGP Update Messages
LOG.debug('Calling SHOW Neighbor...')
self.show_neighbor()
def _notify_best_path_changed_event(self, ev):
ev = EventBestPathChanged(ev.path, ev.is_withdraw)
self.send_event_to_observers(ev)
def _notify_peer_down_event(self, remote_ip, remote_as):
ev = EventPeerDown(remote_ip, remote_as)
self.send_event_to_observers(ev)
def _notify_peer_up_event(self, remote_ip, remote_as):
ev = EventPeerUp(remote_ip, remote_as)
self.send_event_to_observers(ev)
def _add_neighbors(self, settings):
"""
Add BGP neighbors from the given settings.
All valid neighbors are loaded.
Miss-configured neighbors are ignored and errors are logged.
"""
for neighbor_settings in settings:
LOG.debug('Adding neighbor settings: %s', neighbor_settings)
try:
self.speaker.neighbor_add(**neighbor_settings)
except RuntimeConfigError as e:
LOG.exception(e)
def _add_vrfs(self, settings):
"""
Add BGP VRFs from the given settings.
All valid VRFs are loaded.
Miss-configured VRFs are ignored and errors are logged.
"""
for vrf_settings in settings:
LOG.debug('Adding VRF settings: %s', vrf_settings)
try:
self.speaker.vrf_add(**vrf_settings)
except RuntimeConfigError as e:
LOG.exception(e)
def _add_routes(self, settings):
"""
Add BGP routes from given settings.
All valid routes are loaded.
Miss-configured routes are ignored and errors are logged.
"""
for route_settings in settings:
if 'prefix' in route_settings:
prefix_add = self.speaker.prefix_add
elif 'route_type' in route_settings:
prefix_add = self.speaker.evpn_prefix_add
elif 'flowspec_family' in route_settings:
prefix_add = self.speaker.flowspec_prefix_add
else:
LOG.debug('Skip invalid route settings: %s', route_settings)
continue
LOG.debug('Adding route settings: %s', route_settings)
try:
prefix_add(**route_settings)
except RuntimeConfigError as e:
LOG.exception(e)
# Hadem
def send_BGPupdate_message(self, peerIp, med_value):
"""
Sends MED BGP Update Messages to Neighgours.
"""
conf_type = 'multi_exit_disc'
conf_value = med_value
peerIp = peerIp
LOG.info("Send BGP UPDATE Message for changing MED[%s]"%med_value)
return self.speaker.neighbor_update(peerIp, conf_type, conf_value)
def show_vrf(self):
"""
Displays VRF BGP Update Messages
"""
LOG.info("Shows BGP VRF information in a json format")
format = 'json'
vrf_result = self.speaker.vrfs_get('summary', None, 'all', 'json')
print "vrf_result: %s" % vrf_result
nowtime = vrf_result[0]
result = vrf_result[1]
print "+++++++++++++++++++++++++++++++"
print "%s : Show VRFs " % nowtime
print "+++++++++++++++++++++++++++++++"
print "%s" % result
print ""
return vrf_result
def show_rib(self):
"""
Shows BGP routing information in a json format
"""
LOG.info("Shows BGP routing information in a json format")
format = 'json'
rib_result = self.speaker.rib_get('all', 'json')
print "rib_result: %s" % rib_result
nowtime = rib_result[0]
result = rib_result[1]
print "+++++++++++++++++++++++++++++++"
print "%s : Show rib " % nowtime
print "+++++++++++++++++++++++++++++++"
print "%s" % result
print ""
return rib_result
def show_neighbor(self):
LOG.info("Inside Show Neighbor BGP UPDATE Message")
#format = "cli"
format = 'json'
neighbor_result = self.speaker.neighbor_get('received-routes', '10.0.0.2', 'json')
print "neighbor_result: %s" % neighbor_result
nowtime = neighbor_result[0]
#nowtime = json.loads(neighbor_result[0])
result = neighbor_result[1]
print "+++++++++++++++++++++++++++++++"
print "%s : Show neighbor " % nowtime
print "+++++++++++++++++++++++++++++++"
print "%s" % result
print ""
#return self.speaker.neighbor_get(route_type, peerIp, format)
return neighbor_result
Sending MED Update Message...
Send BGP UPDATE Message for changing MED[100]
API method neighbor.update called with args: {'ip_address': '10.0.0.2', 'changes': {'multi_exit_disc': 100}}
on_update_med fired
MED value for neigh: Neighbor: 10.0.0.2 updated to 100
Calling get VRFs Information ...
Shows BGP VRF information in a json format
API method operator.show called with args: {'params': ['vrf', 'summary', 'all'], 'format': 'json'}
vrf_result: {"('65001:250', 'ipv4fs')": {"import_rts": ["65001:250"], "name": "VrfConf-65001:250", "import_maps": [], "route_family": "ipv4fs", "statistics_log_enabled": false, "route_dist": "65001:250", "routes_count": 1, "export_rts": ["65001:250"], "statistics_interval": 60, "id": "cbf114ec-b508-42bf-9181-64d1052867e1", "description": "VrfConf-65001:250"}, "('65001:100', 'ipv4')": {"import_rts": ["65001:100"], "name": "VrfConf-65001:100", "import_maps": [], "route_family": "ipv4", "statistics_log_enabled": false, "route_dist": "65001:100", "routes_count": 1, "export_rts": ["65001:100"], "statistics_interval": 60, "id": "c6253be3-172d-485a-b5ca-2466593bff2e", "description": "VrfConf-65001:100"}, "('65001:350', 'l2vpnfs')": {"import_rts": ["65001:350"], "name": "VrfConf-65001:350", "import_maps": [], "route_family": "l2vpnfs", "statistics_log_enabled": false, "route_dist": "65001:350", "routes_count": 1, "export_rts": ["65001:350"], "statistics_interval": 60, "id": "42441d23-6d9b-4863-8568-5d61df319a10", "description": "VrfConf-65001:350"}, "('65001:200', 'evpn')": {"import_rts": ["65001:200"], "name": "VrfConf-65001:200", "import_maps": [], "route_family": "evpn", "statistics_log_enabled": false, "route_dist": "65001:200", "routes_count": 5, "export_rts": ["65001:200"], "statistics_interval": 60, "id": "36b6eb41-c20a-4e9b-8d38-ea0cd16483fd", "description": "VrfConf-65001:200"}, "('65001:150', 'ipv6')": {"import_rts": ["65001:150"], "name": "VrfConf-65001:150", "import_maps": [], "route_family": "ipv6", "statistics_log_enabled": false, "route_dist": "65001:150", "routes_count": 1, "export_rts": ["65001:150"], "statistics_interval": 60, "id": "080cbc28-3aaa-406f-8afc-9aec36795a7b", "description": "VrfConf-65001:150"}, "('65001:300', 'ipv6fs')": {"import_rts": ["65001:300"], "name": "VrfConf-65001:300", "import_maps": [], "route_family": "ipv6fs", "statistics_log_enabled": false, "route_dist": "65001:300", "routes_count": 1, "export_rts": ["65001:300"], "statistics_interval": 60, "id": "8b52c26d-720d-41da-94bb-e909cd455577", "description": "VrfConf-65001:300"}}
+++++++++++++++++++++++++++++++
{ : Show VRFs
+++++++++++++++++++++++++++++++
"
Calling SHOW RIB ...
Shows BGP routing information in a json format
API method operator.show called with args: {'params': ['rib', 'all'], 'format': 'json'}
rib_result: {"ipv6fs": [{"paths": [], "prefix": "ipv6fs(dst_prefix:2001::1/128/32,src_prefix:3001::2/128/0,next_header:==6,port:==80|==8000,dst_port:>9000&<9050,src_port:>=8500&<=9000,icmp_type:==0,icmp_code:==6,tcp_flags:SYN+ACK&!=URGENT,packet_len:==1000,dscp:==22|==24,fragment:LF|==FF,flow_label:==100)"}], "vpnv6": [], "ipv4fs": [{"paths": [], "prefix": "ipv4fs(dst_prefix:10.60.1.0/24,src_prefix:172.17.0.0/24,ip_proto:==6,port:==80|==8000,dst_port:>9000&<9050,src_port:>=8500&<=9000,icmp_type:==0,icmp_code:==6,tcp_flags:SYN+ACK&!=URGENT,packet_len:==1000,dscp:==22|==24,fragment:LF|==FF)"}], "vpnv4": [], "vpnv4fs": [], "vpnv6fs": [], "ipv4": [{"paths": [], "prefix": "10.10.1.0/24"}], "ipv6": [{"paths": [], "prefix": "2001:db8:1::/64"}], "rtfilter": [{"paths": [], "prefix": "65001:65001:100"}, {"paths": [], "prefix": "65001:65001:150"}, {"paths": [], "prefix": "65001:65001:200"}, {"paths": [], "prefix": "65001:65001:250"}, {"paths": [], "prefix": "65001:65001:300"}, {"paths": [], "prefix": "65001:65001:350"}], "evpn": [], "l2vpnfs": []}
+++++++++++++++++++++++++++++++
{ : Show rib
+++++++++++++++++++++++++++++++
"
Calling SHOW Neighbor...
Inside Show Neighbor BGP UPDATE Message
API method operator.show called with args: {'params': ['neighbor', 'received-routes', '10.0.0.2', 'all'], 'format': 'json'}
neighbor_result: []
+++++++++++++++++++++++++++++++
[ : Show neighbor
+++++++++++++++++++++++++++++++
]
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel