--- /dev/null
+"""
+The purpose of this library is communicate with tools which run xmlrpc server.
+At the moment it is going to be the with the exarpc.py (used with exabgp) and
+with play.py for bgp functional testing.
+exa_ methods apply to test/tools/exabgp_files/exarpc.py
+play_ methods apply to test/tool/fastbgp/play.py (only with --evpn used)
+"""
+
+import xmlrpclib
+
+
+class BgpRpcClient(object):
+ """The client for SimpleXMLRPCServer."""
+
+ def __init__(self, peer_addr):
+ """Setup destination point of the rpc server"""
+ self.proxy = xmlrpclib.ServerProxy("http://{}:8000".format(peer_addr))
+
+ def exa_announce(self, full_exabgp_cmd):
+ """The full command to be passed to exabgp."""
+ return self.proxy.execute(full_exabgp_cmd)
+
+ def _exa_get_counter(self, msg_type):
+ """Gets counter form the server of given message type."""
+ return self.proxy.get_counter(msg_type)
+
+ def exa_get_received_open_count(self):
+ """Gets open messages counter."""
+ return self._exa_get_counter('open')
+
+ def exa_get_received_keepalive_count(self):
+ """Gets keepalive messages counter."""
+ return self._exa_get_counter('keepalive')
+
+ def exa_get_received_update_count(self):
+ """Gets update messges counter."""
+ return self._exa_get_counter('update')
+
+ def exa_get_received_route_refresh_count(self):
+ """Gets route refresh message counter."""
+ return self._exa_get_counter('route_refresh')
+
+ def _exa_clean_counter(self, msg_type):
+ """Cleans counter on the server of given message type."""
+ return self.proxy.clean_counter(msg_type)
+
+ def exa_clean_received_open_count(self):
+ """Cleans open message counter."""
+ return self._exa_clean_counter('open')
+
+ def exa_clean_received_keepalive_count(self):
+ """Cleans keepalive message counter."""
+ return self._exa_clean_counter('keepalive')
+
+ def exa_clean_received_update_count(self):
+ """Cleans update message counter."""
+ return self._exa_clean_counter('update')
+
+ def exa_clean_received_route_refresh_count(self):
+ """Cleans route refresh message counter."""
+ return self._exa_clean_counter('route_refresh')
+
+ def _exa_clean_message(self, msg_type):
+ """Cleans stored message on the server of given message type."""
+ return self.proxy.clean_message(msg_type)
+
+ def exa_clean_update_message(self):
+ """Cleans update message."""
+ return self._exa_clean_message('update')
+
+ def _exa_get_message(self, msg_type):
+ """Gets stored message on the server of given message type."""
+ return self.proxy.get_message(msg_type)
+
+ def exa_get_update_message(self, msg_only=True):
+ """Cleans update message.
+
+ Exabgp provides more details than just message content (e.g. peer ip,
+ timestamp, ...). msg_only is a flag that we want just message content
+ and no details.
+ """
+ msg = self._exa_get_message('update')
+ if not msg_only:
+ return msg
+ return msg if 'neighbor' not in msg else msg['neighbor']['message']
+
+ def play_send(self, hexstring):
+ """Sends given hex data, already encoded bgp update message is expected."""
+ return self.proxy.send(hexstring)
+
+ def play_get(self, what='update'):
+ """Gets the last received (update) mesage as hex string."""
+ return self.proxy.get(what)
+
+ def play_clean(self, what='update'):
+ """Cleans the message (update) on the server."""
+ return self.proxy.clean(what)
Execute_Command_At_Cwd_Should_Pass virtualenv ${SSHKeywords__current_venv_path}
BuiltIn.Run_Keyword_And_Return Virtual_Env_Run_Cmd_At_Cwd pip install --upgrade pip
+Virtual_Env_Delete
+ [Documentation] Deletes a directory with virtual env.
+ Execute_Command_At_Cwd_Should_Pass rm -rf ${SSHKeywords__current_venv_path}
+
Virtual_Env_Run_Cmd_At_Cwd
[Arguments] ${cmd} ${log_on_success}=True ${log_on_failure}=True ${stderr_must_be_empty}=True
[Documentation] Runs given command within activated virtual env and returns stdout.
--- /dev/null
+*** Settings ***
+Documentation Functional test suite for bgp - l3vpn-ipv4
+...
+... Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+... This suite tests advertising and receiveing routes with l3vpn content.
+... It uses odl and exabgp as bgp peers. Routes advertized from odl
+... are configured via application peer. Routes advertised from exabgp is
+... statically configured in exabgp config file.
+Suite Setup Start_Suite
+Suite Teardown Stop_Suite
+Library RequestsLibrary
+Library SSHLibrary
+Variables ${CURDIR}/../../../variables/Variables.py
+Resource ${CURDIR}/../../../libraries/Utils.robot
+Resource ${CURDIR}/../../../libraries/SetupUtils.robot
+Resource ${CURDIR}/../../../libraries/TemplatedRequests.robot
+Resource ${CURDIR}/../../../libraries/KarafKeywords.robot
+Resource ${CURDIR}/../../../libraries/SSHKeywords.robot
+Library ${CURDIR}/../../../libraries/norm_json.py
+Library ${CURDIR}/../../../libraries/BgpRpcClient.py ${TOOLS_SYSTEM_IP}
+
+*** Variables ***
+${HOLDTIME} 180
+${DEVICE_NAME} controller-config
+${BGP_PEER_NAME} example-bgp-peer
+${RIB_INSTANCE} example-bgp-rib
+${APP_PEER_NAME} example-bgp-peer-app
+${CMD} env exabgp.tcp.port=1790 exabgp --debug
+${BGP_VAR_FOLDER} ${CURDIR}/../../../variables/bgpfunctional
+${BGP_L3VPN_DIR} ${BGP_VAR_FOLDER}/l3vpn_ipv4
+${DEFAUTL_EXA_CFG} exa.cfg
+${L3VPN_EXA_CFG} bgp-l3vpn-ipv4.cfg
+${L3VPN_RSPEMPTY} ${BGP_L3VPN_DIR}/bgp-l3vpn-ipv4-empty.json
+${L3VPN_RSP} ${BGP_L3VPN_DIR}/bgp-l3vpn-ipv4.json
+${L3VPN_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:mpls-labeled-vpn-subsequent-address-family/bgp-vpn-ipv4:vpn-ipv4-routes
+${CONFIG_SESSION} config-session
+${EXARPCSCRIPT} ${CURDIR}/../../../../tools/exabgp_files/exarpc.py
+${PEER_CHECK_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/peer/bgp:%2F%2F
+
+*** Test Cases ***
+Configure_App_Peer
+ [Documentation] Configures bgp application peer
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME} RIB_INSTANCE_NAME=${RIB_INSTANCE} APP_PEER_ID=${ODL_SYSTEM_IP}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Reconfigure_ODL_To_Accept_Connection
+ [Documentation] Configures BGP peer module with initiate-connection set to false.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME} IP=${TOOLS_SYSTEM_IP} HOLDTIME=${HOLDTIME} PEER_PORT=${BGP_TOOL_PORT}
+ ... INITIATE=false RIB_INSTANCE_NAME=${RIB_INSTANCE}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+L3vpn_Ipv4_To_Odl
+ [Documentation] Testing mpls vpn ipv4 routes reported to odl from exabgp
+ [Setup] Setup_Testcase ${L3VPN_EXA_CFG} ${L3VPN_URL} ${L3VPN_RSPEMPTY}
+ BuiltIn.Wait_Until_Keyword_Succeeds 15s 1s Verify Reported Data ${L3VPN_URL} ${L3VPN_RSP}
+ [Teardown] Teardown_Testcase ${L3VPN_URL} ${L3VPN_RSPEMPTY}
+
+L3vpn_Ipv4_From_Odl
+ [Documentation] Testing mpls vpn ipv4 routes reported from odl to exabgp
+ [Setup] Start_Tool_And_Verify_Connected ${DEFAUTL_EXA_CFG}
+ BgpRpcClient.exa_clean_update_message
+ &{mapping} BuiltIn.Create_Dictionary BGP_PEER_IP=${TOOLS_SYSTEM_IP}
+ TemplatedRequests.Post_As_Xml_Templated ${BGP_L3VPN_DIR}/route mapping=${mapping} session=${CONFIG_SESSION}
+ BuiltIn.Wait_Until_Keyword_Succeeds 5x 2s Verify_Tool_Received_Update ${BGP_L3VPN_DIR}/route/exa-expected.json
+ [Teardown] Remove_Route_And_Stop_Tool
+
+Delete_Bgp_Peer_Configuration
+ [Documentation] Revert the BGP configuration to the original state: without any configured peers.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Deconfigure_App_Peer
+ [Documentation] Revert the BGP configuration to the original state: without application peer
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+*** Keywords ***
+Start_Suite
+ [Documentation] Suite setup keyword
+ SetupUtils.Setup_Utils_For_Setup_And_Teardown
+ ${tools_system_conn_id}= SSHLibrary.Open_Connection ${TOOLS_SYSTEM_IP} prompt=${DEFAULT_LINUX_PROMPT} timeout=6s
+ Builtin.Set_Suite_Variable ${tools_system_conn_id}
+ Utils.Flexible_Mininet_Login ${TOOLS_SYSTEM_USER}
+ SSHKeywords.Virtual_Env_Create
+ SSHKeywords.Virtual_Env_Install_Package exabgp==3.4.16
+ RequestsLibrary.Create_Session ${CONFIG_SESSION} http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH}
+ Upload_Config_Files
+
+Stop_Suite
+ [Documentation] Suite teardown keyword
+ SSHKeywords.Virtual_Env_Delete
+ SSHLibrary.Close_All_Connections
+ RequestsLibrary.Delete_All_Sessions
+
+Upload_Config_Files
+ [Documentation] Uploads exabgp config files and needed scripts
+ SSHLibrary.Put_File ${BGP_VAR_FOLDER}/${DEFAUTL_EXA_CFG} .
+ SSHLibrary.Put_File ${BGP_L3VPN_DIR}/${L3VPN_EXA_CFG} .
+ SSHLibrary.Put_File ${EXARPCSCRIPT} .
+ @{cfgfiles}= SSHLibrary.List_Files_In_Directory . *.cfg
+ : FOR ${cfgfile} IN @{cfgfiles}
+ \ SSHLibrary.Execute_Command sed -i -e 's/EXABGPIP/${TOOLS_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ODLIP/${ODL_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ROUTEREFRESH/disable/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ADDPATH/disable/g' ${cfgfile}
+ \ ${stdout}= SSHLibrary.Execute_Command cat ${cfgfile}
+ \ Log ${stdout}
+
+Setup_Testcase
+ [Arguments] ${cfg_file} ${url} ${empty_response}
+ [Documentation] Verifies initial test condition and starts the tool
+ Verify_Reported_Data ${url} ${empty_response}
+ Start_Tool_And_Verify_Connected ${cfg_file}
+
+Start_Tool
+ [Arguments] ${cfg_file} ${mapping}={}
+ [Documentation] Start the tool ${cmd} ${cfg_file}
+ ${start_cmd} BuiltIn.Set_Variable ${cmd} ${cfg_file}
+ BuiltIn.Log ${start_cmd}
+ SSHKeywords.Virtual_Env_Activate_On_Current_Session log_output=${True}
+ ${output}= SSHLibrary.Write ${start_cmd}
+ BuiltIn.Log ${output}
+
+Verify_Tools_Connection
+ [Arguments] ${connected}=${True}
+ [Documentation] Checks peer presence in operational datastore
+ ${exp_status_code}= BuiltIn.Set_Variable_If ${connected} ${200} ${404}
+ ${rsp}= RequestsLibrary.Get Request ${CONFIG_SESSION} ${PEER_CHECK_URL}${TOOLS_SYSTEM_IP}
+ BuiltIn.Log ${rsp.content}
+ BuiltIn.Should_Be_Equal_As_Numbers ${exp_status_code} ${rsp.status_code}
+
+Start_Tool_And_Verify_Connected
+ [Arguments] ${cfg_file}
+ [Documentation] Start the tool and verify its connection
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ Start_Tool ${cfg_file}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 3s Verify_Tools_Connection connected=${True}
+
+Stop_Tool
+ [Documentation] Stop the tool by sending ctrl+c
+ ${output}= SSHLibrary.Read
+ BuiltIn.Log ${output}
+ Utils.Write_Bare_Ctrl_C
+ ${output}= SSHLibrary.Read_Until_Prompt
+ BuiltIn.Log ${output}
+ SSHKeywords.Virtual_Env_Deactivate_On_Current_Session log_output=${True}
+
+Remove_Route_And_Stop_Tool
+ [Documentation] Removes configured route from application peer and stops the tool
+ &{mapping} BuiltIn.Create_Dictionary
+ TemplatedRequests.Delete_Templated ${BGP_L3VPN_DIR}/route mapping=${mapping} session=${CONFIG_SESSION}
+ Stop_Tool
+
+Teardown_Testcase
+ [Arguments] ${url} ${empty_response}
+ [Documentation] Testcse teardown with data verification
+ Stop_Tool
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 1s Verify_Reported_Data ${url} ${empty_response}
+
+Verify_Tool_Received_Update
+ [Arguments] ${exp_update_fn}
+ [Documentation] Verification of receiving particular update message
+ ${exp_update}= Get_Expected_Response_From_File ${exp_update_fn}
+ ${rcv_update_dict}= BgpRpcClient.exa_get_update_message msg_only=${True}
+ ${rcv_update}= BuiltIn.Evaluate json.dumps(${rcv_update_dict}) modules=json
+ ${keys_with_bits}= BuiltIn.Create_List op
+ ${received_json}= norm_json.Normalize_Json_Text ${rcv_update} keys_with_bits=${keys_with_bits}
+ ${expected_json}= norm_json.Normalize_Json_Text ${exp_update} keys_with_bits=${keys_with_bits}
+ BuiltIn.Log ${received_json}
+ BuiltIn.Log ${expected_json}
+ BuiltIn.Should_Be_Equal ${received_json} ${expected_json}
+
+Verify_Reported_Data
+ [Arguments] ${url} ${exprspfile}
+ [Documentation] Verifies expected response
+ ${keys_with_bits}= BuiltIn.Create_List op
+ ${expected_rsp}= Get_Expected_Response_From_File ${exprspfile}
+ ${expected_json}= norm_json.Normalize_Json_Text ${expected_rsp} keys_with_bits=${keys_with_bits}
+ ${rsp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${url}
+ BuiltIn.Log ${rsp.content}
+ ${received_json}= norm_json.Normalize_Json_Text ${rsp.content} keys_with_bits=${keys_with_bits}
+ BuiltIn.Log ${received_json}
+ BuiltIn.Log ${expected_json}
+ BuiltIn.Should_Be_Equal ${received_json} ${expected_json}
+
+Get_Expected_Response_From_File
+ [Arguments] ${exprspfile}
+ [Documentation] Looks for release specific response first, then take default.
+ ${status} ${expresponse}= BuiltIn.Run_Keyword_And_Ignore_Error OperatingSystem.Get File ${exprspfile}.${ODL_STREAM}
+ Return From Keyword If '${status}' == 'PASS' ${expresponse}
+ ${expresponse}= OperatingSystem.Get File ${exprspfile}
+ [Return] ${expresponse}
--- /dev/null
+*** Settings ***
+Documentation Functional test suite for bgp - n-path and all-path selection
+...
+... Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+... This suite tests n-path and all-path selection policy.
+... It uses odl and exabgp as bgp peers. Routes advertized from odl
+... are configured via application peer.
+Suite Setup Start_Suite
+Suite Teardown Stop_Suite
+Library RequestsLibrary
+Library SSHLibrary
+Variables ${CURDIR}/../../../variables/Variables.py
+Resource ${CURDIR}/../../../libraries/Utils.robot
+Resource ${CURDIR}/../../../libraries/SetupUtils.robot
+Resource ${CURDIR}/../../../libraries/TemplatedRequests.robot
+Library ${CURDIR}/../../../libraries/norm_json.py
+Library ${CURDIR}/../../../libraries/BgpRpcClient.py ${TOOLS_SYSTEM_IP}
+Resource ${CURDIR}/../../../libraries/BGPcliKeywords.robot
+Resource ${CURDIR}/../../../libraries/KarafKeywords.robot
+Resource ${CURDIR}/../../../libraries/SSHKeywords.robot
+
+*** Variables ***
+${HOLDTIME} 180
+${DEVICE_NAME} controller-config
+${BGP_PEER_NAME} example-bgp-peer
+${RIB_INSTANCE} example-bgp-rib
+${APP_PEER_NAME} example-bgp-peer-app
+${CMD} env exabgp.tcp.port=1790 exabgp --debug
+${BGP_VAR_FOLDER} ${CURDIR}/../../../variables/bgpfunctional
+${MULT_VAR_FOLDER} ${BGP_VAR_FOLDER}/multipaths
+${DEFAUTL_RPC_CFG} exa.cfg
+${CONFIG_SESSION} config-session
+${EXARPCSCRIPT} ${CURDIR}/../../../../tools/exabgp_files/exarpc.py
+${N_PATHS_VALUE} 2
+&{DEFAULT_MAPPING} ODLIP=${ODL_SYSTEM_IP} EXAIP=${TOOLS_SYSTEM_IP} NPATHS=${N_PATHS_VALUE}
+@{PATH_ID_LIST} 1 2 3
+${PATH_ID_LIST_LEN} 3
+${NEXT_HOP_PREF} 100.100.100.
+${RIB_URI} /restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:rib-impl/example-bgp-rib
+${PEER_CHECK_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/peer/bgp:%2F%2F
+${NPATHS_SELM} n-paths
+${ALLPATHS_SELM} all-paths
+${ADDPATHCAP_SR} send\\/receive
+${ADDPATHCAP_S} send
+${ADDPATHCAP_R} receive
+${ADDPATHCAP_D} disable
+
+*** Test Cases ***
+Reconfigure_ODL_To_Accept_Connection
+ [Documentation] Configure BGP peer module with initiate-connection set to false.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME} IP=${TOOLS_SYSTEM_IP} HOLDTIME=${HOLDTIME} PEER_PORT=${BGP_TOOL_PORT}
+ ... INITIATE=false RIB_INSTANCE_NAME=${RIB_INSTANCE}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Odl Allpaths Exa SendReceived
+ [Documentation] all-paths selected policy selected
+ [Setup] Configure_Path_Selection_And_App_Peer_And_Connect_Peer ${ALLPATHS_SELM} ${ADDPATHCAP_SR}
+ Log_Loc_Rib_Operational
+ BuiltIn.Wait_Until_Keyword_Succeeds 6x 2s Verify_Expected_Update_Count ${PATH_ID_LIST_LEN}
+ [Teardown] Remove_App_Peer_Configuration_And_Stop_Tool
+
+Odl Npaths Exa SendReceived
+ [Documentation] n-paths policy selected on odl
+ [Setup] Configure_Path_Selection_And_App_Peer_And_Connect_Peer ${NPATHS_SELM} ${ADDPATHCAP_SR}
+ Log_Loc_Rib_Operational
+ BuiltIn.Wait_Until_Keyword_Succeeds 6x 2s Verify_Expected_Update_Count ${N_PATHS_VALUE}
+ [Teardown] Remove_App_Peer_Configuration_And_Stop_Tool
+
+Delete_Bgp_Peer_Configuration
+ [Documentation] Revert the BGP configuration to the original state: without any configured peers.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+*** Keywords ***
+Start_Suite
+ [Documentation] Suite setup keyword
+ SetupUtils.Setup_Utils_For_Setup_And_Teardown
+ ${mininet_conn_id}= SSHLibrary.Open Connection ${TOOLS_SYSTEM_IP} prompt=${DEFAULT_LINUX_PROMPT} timeout=6s
+ Builtin.Set Suite Variable ${mininet_conn_id}
+ Utils.Flexible Mininet Login ${TOOLS_SYSTEM_USER}
+ SSHKeywords.Virtual_Env_Create
+ SSHKeywords.Virtual_Env_Install_Package exabgp==3.4.16
+ RequestsLibrary.Create_Session ${CONFIG_SESSION} http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH}
+ Upload_Config_Files
+ Configure_Odl_With_Multipaths
+
+Stop_Suite
+ [Documentation] Suite teardown keyword with ord rib restoration
+ SSHKeywords.Virtual_Env_Delete
+ TemplatedRequests.Put_As_Xml_To_Uri ${RIB_URI} ${rib_old} session=${CONFIG_SESSION}
+ SSHLibrary.Close_All_Connections
+ RequestsLibrary.Delete_All_Sessions
+
+Upload_Config_Files
+ [Arguments] ${addpath}=disable
+ [Documentation] Uploads exabgp config files
+ SSHLibrary.Put_File ${BGP_VAR_FOLDER}/${DEFAUTL_RPC_CFG} .
+ SSHLibrary.Put_File ${EXARPCSCRIPT} .
+ @{cfgfiles}= SSHLibrary.List_Files_In_Directory . *.cfg
+ : FOR ${cfgfile} IN @{cfgfiles}
+ \ SSHLibrary.Execute_Command sed -i -e 's/EXABGPIP/${TOOLS_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ODLIP/${ODL_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ROUTEREFRESH/enable/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ADDPATH/${addpath}/g' ${cfgfile}
+ \ ${stdout}= SSHLibrary.Execute_Command cat ${cfgfile}
+ \ Log ${stdout}
+
+Configure_Path_Selection_And_App_Peer_And_Connect_Peer
+ [Arguments] ${odl_path_sel_mode} ${exa_add_path_value}
+ [Documentation] Setup test case keyword. Early after the path selection config the incomming connection
+ ... from exabgp towards odl may be rejected by odl due to config process not finished yet. Because of that
+ ... we try to start the tool 3 times in case early attempts fail.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ Configure_Path_Selection_Mode ${odl_path_sel_mode}
+ Configure_App_Peer_With_Routes
+ Upload_Config_Files addpath=${exa_add_path_value}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 1s Start_Tool_And_Verify_Connected ${DEFAUTL_RPC_CFG}
+
+Get_New_Config_File
+ [Arguments] ${cfg_template_file} ${mapping}={} ${new_cfg_name}=cfg.cfg
+ [Documentation] Returns a new config file from template
+ ${cfg_content}= TemplatedRequests.Resolve_Text_From_Template_File ${cfg_template} ${mapping}
+ SSHLibrary.Execute_Command echo ${cfg_content} > ${new_cfg_name}
+ [Return] ${new_cfg_name}
+
+Start_Tool
+ [Arguments] ${cfg_file} ${mapping}={}
+ [Documentation] Start the tool ${cmd} ${cfg_file}
+ ${start_cmd} BuiltIn.Set_Variable ${cmd} ${cfg_file}
+ BuiltIn.Log ${start_cmd}
+ SSHKeywords.Virtual_Env_Activate_On_Current_Session log_output=${True}
+ ${output}= SSHLibrary.Write ${start_cmd}
+ BuiltIn.Log ${output}
+
+Verify_Tools_Connection
+ [Arguments] ${connected}=${True}
+ [Documentation] Checks peer presence in operational datastore
+ ${exp_status_code}= BuiltIn.Set_Variable_If ${connected} ${200} ${404}
+ ${rsp}= RequestsLibrary.Get Request ${CONFIG_SESSION} ${PEER_CHECK_URL}${TOOLS_SYSTEM_IP}
+ BuiltIn.Log ${rsp.content}
+ BuiltIn.Should_Be_Equal_As_Numbers ${exp_status_code} ${rsp.status_code}
+
+Start_Tool_And_Verify_Connected
+ [Arguments] ${cfg_file}
+ [Documentation] Start the tool and verify its connection
+ Start_Tool ${cfg_file}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 3s Verify_Tools_Connection connected=${True}
+
+Stop_Tool
+ [Documentation] Stop the tool by sending ctrl+c
+ ${output}= SSHLibrary.Read
+ BuiltIn.Log ${output}
+ Utils.Write_Bare_Ctrl_C
+ ${output}= SSHLibrary.Read_Until_Prompt
+ BuiltIn.Log ${output}
+ SSHKeywords.Virtual_Env_Deactivate_On_Current_Session log_output=${True}
+
+Remove_App_Peer_Configuration_And_Stop_Tool
+ Deconfigure_App_Peer
+ Stop_Tool
+
+Verify_Expected_Update_Count
+ [Arguments] ${exp_count}
+ [Documentation] Verify number of received update messages
+ ${tool_count}= BgpRpcClient.exa_get_received_update_count
+ BuiltIn.Should_Be_Equal_As_Numbers ${exp_count} ${tool_count}
+
+Configure_Path_Selection_Mode
+ [Arguments] ${psm}
+ [Documentation] Configure path selection mode and get rib information for potential debug purposes
+ &{mapping} BuiltIn.Create_Dictionary PATHSELMODE=${psm}
+ TemplatedRequests.Get_As_Xml_Templated ${MULT_VAR_FOLDER}/rib mapping=${mapping} session=${CONFIG_SESSION}
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/module_psm mapping=${mapping} session=${CONFIG_SESSION}
+
+Configure_Odl_With_Multipaths
+ [Documentation] Configures odl to support n-paths or all-paths selection
+ ${mapping}= BuiltIn.Set Variable ${DEFAULT_MAPPING}
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/module_n_paths mapping=${mapping} session=${CONFIG_SESSION}
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/module_all_paths mapping=${mapping} session=${CONFIG_SESSION}
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/service_psmf mapping=${mapping} session=${CONFIG_SESSION}
+ Configure_Path_Selection_Mode n-paths
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/service_bpsm mapping=${mapping} session=${CONFIG_SESSION}
+ ${rib_old}= TemplatedRequests.Get_As_Xml_Templated ${MULT_VAR_FOLDER}/rib mapping=${mapping} session=${CONFIG_SESSION}
+ BuiltIn.Set_Suite_Variable ${rib_old}
+ TemplatedRequests.Put_As_Xml_Templated ${MULT_VAR_FOLDER}/rib mapping=${mapping} session=${CONFIG_SESSION}
+
+Log_Loc_Rib_Operational
+ ${rsp}= RequestsLibrary.Get Request ${CONFIG_SESSION} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/
+ BuiltIn.Log ${rsp.content}
+
+Configure_App_Peer_With_Routes
+ [Documentation] Configure bgp application peer and fill it immediately with routes.
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME} RIB_INSTANCE_NAME=${RIB_INSTANCE} APP_PEER_ID=${ODL_SYSTEM_IP}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+ : FOR ${pathid} IN @{PATH_ID_LIST}
+ \ &{route_mapping} BuiltIn.Create_Dictionary NEXTHOP=${NEXT_HOP_PREF}${pathid} LOCALPREF=${pathid}00 PATHID=${pathid}
+ \ TemplatedRequests.Post_As_Xml_Templated ${MULT_VAR_FOLDER}/route mapping=${route_mapping} session=${CONFIG_SESSION}
+
+Deconfigure_App_Peer
+ [Documentation] Revert the BGP configuration to the original state: without application peer
+ &{route_mapping} BuiltIn.Create_Dictionary
+ TemplatedRequests.Delete_Templated ${MULT_VAR_FOLDER}/route mapping=${route_mapping} session=${CONFIG_SESSION}
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
--- /dev/null
+*** Settings ***
+Documentation Functional test for bgp - evpn
+...
+... Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+... This suite tests advertising and receiveing routes with evpn content.
+... It uses play.py and odl as bgp peers. Routes advertized from odl
+... are configured via application peer. Routes advertised from play.py are
+... stored in *.hex files. These files are used also as expected data which
+... is recevied from odl.
+Suite Setup Start_Suite
+Suite Teardown Stop_Suite
+Test Setup Verify Test Preconditions
+Library RequestsLibrary
+Library SSHLibrary
+Variables ${CURDIR}/../../../variables/Variables.py
+Resource ${CURDIR}/../../../libraries/Utils.robot
+Resource ${CURDIR}/../../../libraries/SetupUtils.robot
+Resource ${CURDIR}/../../../libraries/TemplatedRequests.robot
+Library ${CURDIR}/../../../libraries/norm_json.py
+Library ${CURDIR}/../../../libraries/BgpRpcClient.py ${TOOLS_SYSTEM_IP}
+Resource ${CURDIR}/../../../libraries/BGPcliKeywords.robot
+Resource ${CURDIR}/../../../libraries/BGPSpeaker.robot
+Resource ${CURDIR}/../../../libraries/KarafKeywords.robot
+Resource ${CURDIR}/../../../libraries/SSHKeywords.robot
+
+*** Variables ***
+${HOLDTIME} 180
+${DEVICE_NAME} controller-config
+${BGP_PEER_NAME} example-bgp-peer
+${RIB_INSTANCE} example-bgp-rib
+${APP_PEER_NAME} example-bgp-peer-app
+${CMD} env exabgp.tcp.port=1790 exabgp --debug
+${BGP_VARIABLES_FOLDER} ${CURDIR}/../../../variables/bgpfunctional
+${DEFAUTL_RPC_CFG} exa.cfg
+${CONFIG_SESSION} config-session
+${EVPN_VARIABLES_DIR} ${CURDIR}/../../../variables/bgpfunctional/l2vpn_evpn
+${BGP_TOOL_LOG_LEVEL} debug
+${PLAY_SCRIPT} ${CURDIR}/../../../../tools/fastbgp/play.py
+${EVPN_CONF_URL} /restconf/config/bgp-rib:application-rib/example-app-rib/tables/odl-bgp-evpn:l2vpn-address-family/odl-bgp-evpn:evpn-subsequent-address-family/odl-bgp-evpn:evpn-routes/
+${EVPN_RIB_OPER_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/odl-bgp-evpn:l2vpn-address-family/odl-bgp-evpn:evpn-subsequent-address-family/odl-bgp-evpn:evpn-routes
+${LOC_RIB_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/odl-bgp-evpn:l2vpn-address-family/odl-bgp-evpn:evpn-subsequent-address-family/odl-bgp-evpn:evpn-routes
+
+*** Test Cases ***
+Configure_App_Peer
+ [Documentation] Configures bgp application peer
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME} RIB_INSTANCE_NAME=${RIB_INSTANCE} APP_PEER_ID=${ODL_SYSTEM_IP}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VARIABLES_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Reconfigure_ODL_To_Accept_Connection
+ [Documentation] Configures BGP peer module with initiate-connection set to false.
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME} IP=${TOOLS_SYSTEM_IP} HOLDTIME=${HOLDTIME} PEER_PORT=${BGP_TOOL_PORT}
+ ... INITIATE=false RIB_INSTANCE_NAME=${RIB_INSTANCE}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VARIABLES_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Start_Bgp_Peer
+ [Documentation] Start Python speaker to connect to ODL. We need to do WUKS until odl really starts to accept incomming bgp connection. The failure happens if the incomming connection comes too quickly after configuring the peer in the previous test case.
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 1s Start Bgp Peer
+
+Odl_To_Play_route_es_arb
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_arb
+ [Template] Play_To_Odl_Template
+ route_es_arb
+
+Odl_To_Play_route_es_as
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_as
+ [Template] Play_To_Odl_Template
+ route_es_as
+
+Odl_To_Play_route_es_lacp
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_lacp
+ [Template] Play_To_Odl_Template
+ route_es_lacp
+
+Odl_To_Play_route_es_lan
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_lan
+ [Template] Play_To_Odl_Template
+ route_es_lan
+
+Odl_To_Play_route_es_mac
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_mac
+ [Template] Play_To_Odl_Template
+ route_es_mac
+
+Odl_To_Play_route_es_rou
+ [Template] Odl_To_Play_Template
+ route_es_arb
+
+Play_To_Odl_route_es_rou
+ [Template] Play_To_Odl_Template
+ route_es_rou
+
+Odl_To_Play_route_eth_arb
+ [Template] Odl_To_Play_Template
+ route_eth_arb
+
+Play_To_Odl_route_eth_arb
+ [Template] Play_To_Odl_Template
+ route_eth_arb
+
+Odl_To_Play_route_eth_as
+ [Template] Odl_To_Play_Template
+ route_eth_as
+
+Play_To_Odl_route_eth_as
+ [Template] Play_To_Odl_Template
+ route_eth_as
+
+Odl_To_Play_route_eth_lacp
+ [Template] Odl_To_Play_Template
+ route_eth_lacp
+
+Play_To_Odl_route_eth_lacp
+ [Template] Play_To_Odl_Template
+ route_eth_lacp
+
+Odl_To_Play_route_eth_lacp_extdef
+ [Template] Odl_To_Play_Template
+ route_eth_lacp_extdef
+
+Play_To_Odl_route_eth_lacp_extdef
+ [Template] Play_To_Odl_Template
+ route_eth_lacp_extdef
+
+Odl_To_Play_route_eth_lacp_extesilab
+ [Template] Odl_To_Play_Template
+ route_eth_lacp_extesilab
+
+Play_To_Odl_route_eth_lacp_extesilab
+ [Template] Play_To_Odl_Template
+ route_eth_lacp_extesilab
+
+Odl_To_Play_route_eth_lacp_extesr
+ [Template] Odl_To_Play_Template
+ route_eth_lacp_extesr
+
+Play_To_Odl_route_eth_lacp_extesr
+ [Template] Play_To_Odl_Template
+ route_eth_lacp_extesr
+
+Odl_To_Play_route_eth_lacp_extl2
+ [Template] Odl_To_Play_Template
+ route_eth_lacp_extl2
+
+Play_To_Odl_route_eth_lacp_extl2
+ [Template] Play_To_Odl_Template
+ route_eth_lacp_extl2
+
+Odl_To_Play_route_eth_lacp_extmac
+ [Template] Odl_To_Play_Template
+ route_eth_lacp_extmac
+
+Play_To_Odl_route_eth_lacp_extmac
+ [Template] Play_To_Odl_Template
+ route_eth_lacp_extmac
+
+Odl_To_Play_route_eth_lan
+ [Template] Odl_To_Play_Template
+ route_eth_lan
+
+Play_To_Odl_route_eth_lan
+ [Template] Play_To_Odl_Template
+ route_eth_lan
+
+Odl_To_Play_route_eth_mac
+ [Template] Odl_To_Play_Template
+ route_eth_mac
+
+Play_To_Odl_route_eth_mac
+ [Template] Play_To_Odl_Template
+ route_eth_mac
+
+Odl_To_Play_route_eth_rou
+ [Template] Odl_To_Play_Template
+ route_eth_rou
+
+Play_To_Odl_route_eth_rou
+ [Template] Play_To_Odl_Template
+ route_eth_rou
+
+Odl_To_Play_route_inc_arb
+ [Template] Odl_To_Play_Template
+ route_inc_arb
+
+Play_To_Odl_route_inc_arb
+ [Template] Play_To_Odl_Template
+ route_inc_arb
+
+Odl_To_Play_route_inc_as
+ [Template] Odl_To_Play_Template
+ route_inc_as
+
+Play_To_Odl_route_inc_as
+ [Template] Play_To_Odl_Template
+ route_inc_as
+
+Odl_To_Play_route_inc_lacp
+ [Template] Odl_To_Play_Template
+ route_inc_lacp
+
+Play_To_Odl_route_inc_lacp
+ [Template] Play_To_Odl_Template
+ route_inc_lacp
+
+Odl_To_Play_route_inc_lan
+ [Template] Odl_To_Play_Template
+ route_inc_lan
+
+Play_To_Odl_route_inc_lan
+ [Template] Play_To_Odl_Template
+ route_inc_lan
+
+Odl_To_Play_route_inc_mac
+ [Template] Odl_To_Play_Template
+ route_inc_mac
+
+Play_To_Odl_route_inc_mac
+ [Template] Play_To_Odl_Template
+ route_inc_mac
+
+Odl_To_Play_route_inc_rou
+ [Template] Odl_To_Play_Template
+ route_inc_rou
+
+Play_To_Odl_route_inc_rou
+ [Template] Play_To_Odl_Template
+ route_inc_rou
+
+Odl_To_Play_route_mac_arb
+ [Template] Odl_To_Play_Template
+ route_mac_arb
+
+Play_To_Odl_route_mac_arb
+ [Template] Play_To_Odl_Template
+ route_mac_arb
+
+Odl_To_Play_route_mac_as
+ [Template] Odl_To_Play_Template
+ route_mac_as
+
+Play_To_Odl_route_mac_as
+ [Template] Play_To_Odl_Template
+ route_mac_as
+
+Odl_To_Play_route_mac_lacp
+ [Template] Odl_To_Play_Template
+ route_mac_lacp
+
+Play_To_Odl_route_mac_lacp
+ [Template] Play_To_Odl_Template
+ route_mac_lacp
+
+Odl_To_Play_route_mac_lan
+ [Template] Odl_To_Play_Template
+ route_mac_lan
+
+Play_To_Odl_route_mac_lan
+ [Template] Play_To_Odl_Template
+ route_mac_lan
+
+Odl_To_Play_route_mac_mac
+ [Template] Odl_To_Play_Template
+ route_mac_mac
+
+Play_To_Odl_route_mac_mac
+ [Template] Play_To_Odl_Template
+ route_mac_mac
+
+Odl_To_Play_route_mac_rou
+ [Template] Odl_To_Play_Template
+ route_mac_rou
+
+Play_To_Odl_route_mac_rou
+ [Template] Play_To_Odl_Template
+ route_mac_rou
+
+Kill_Talking_BGP_Speaker
+ [Documentation] Abort the Python speaker
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ BGPSpeaker.Kill_BGP_Speaker
+
+Delete_Bgp_Peer_Configuration
+ [Documentation] Revert the BGP configuration to the original state: without any configured peers.
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} Create Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VARIABLES_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Deconfigure_App_Peer
+ [Documentation] Revert the BGP configuration to the original state: without application peer
+ [Setup] KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} Create Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VARIABLES_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+*** Keywords ***
+Start_Suite
+ [Documentation] Suite setup keyword
+ SetupUtils.Setup_Utils_For_Setup_And_Teardown
+ ${mininet_conn_id}= SSHLibrary.Open Connection ${TOOLS_SYSTEM_IP} prompt=${DEFAULT_LINUX_PROMPT} timeout=6s
+ Builtin.Set Suite Variable ${mininet_conn_id}
+ Utils.Flexible Mininet Login ${TOOLS_SYSTEM_USER}
+ RequestsLibrary.Create Session ${CONFIG_SESSION} http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH}
+ SSHLibrary.Put File ${PLAY_SCRIPT} .
+ SSHKeywords.Assure_Library_Ipaddr target_dir=.
+
+Stop_Suite
+ [Documentation] Suite teardown keyword
+ SSHLibrary.Close_All_Connections
+ RequestsLibrary.Delete_All_Sessions
+
+Start_Bgp_Peer
+ [Documentation] Starts bgp peer and verifies that the peer runs.
+ BGPSpeaker.Start_BGP_Speaker --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_TOOL_LOG_LEVEL} --evpn --wfr 1
+ BGPcliKeywords.Read_And_Fail_If_Prompt_Is_Seen
+
+Odl_To_Play_Template
+ [Arguments] ${totest}
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ ${data_xml}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/${totest}.xml
+ ${data_json}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/${totest}.json
+ ${announce_hex}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/announce_${totest}.hex
+ ${withdraw_hex}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/withdraw_${totest}.hex
+ BuiltIn.Log ${data_xml}
+ BuiltIn.Log ${data_json}
+ BuiltIn.Log ${announce_hex}
+ BuiltIn.Log ${withdraw_hex}
+ BgpRpcClient.play_clean
+ ${resp}= RequestsLibrary.Post_Request ${CONFIG_SESSION} ${EVPN_CONF_URL} data=${data_xml} headers=${HEADERS_XML}
+ BuiltIn.Should_Be_Equal_As_Numbers ${resp.status_code} 204
+ ${resp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${EVPN_CONF_URL} headers=${HEADERS_XML}
+ BuiltIn.Log ${resp.content}
+ ${aupdate}= BuiltIn.Wait_Until_Keyword_Succeeds 4x 2s Get_Update_Content
+ BuiltIn.Log ${aupdate}
+ BuiltIn.Should_Be_Equal_As_Strings ${aupdate} ${announce_hex}
+ BgpRpcClient.play_clean
+ Remove_Configured_Routes
+ ${wupdate}= BuiltIn.Wait_Until_Keyword_Succeeds 4x 2s Get_Update_Content
+ BuiltIn.Log ${wupdate}
+ BuiltIn.Should Be Equal As Strings ${wupdate} ${withdraw_hex}
+ [Teardown] Remove_Configured_Routes
+
+Play_To_Odl_Template
+ [Arguments] ${totest}
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ ${data_xml}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/${totest}.xml
+ ${data_json}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/${totest}.json
+ ${announce_hex}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/announce_${totest}.hex
+ ${withdraw_hex}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/withdraw_${totest}.hex
+ ${empty_routes}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/empty_routes.json
+ BuiltIn.Set_Suite_Variable ${withdraw_hex}
+ BuiltIn.Set_Suite_Variable ${empty_routes}
+ BuiltIn.Log ${data_xml}
+ BuiltIn.Log ${data_json}
+ BuiltIn.Log ${announce_hex}
+ BuiltIn.Log ${withdraw_hex}
+ BuiltIn.Log ${empty_routes}
+ BgpRpcClient.play_clean
+ BgpRpcClient.play_send ${announce_hex}
+ BuiltIn.Wait_Until_Keyword_Succeeds 4x 2s Loc_Rib_Presnece ${data_json}
+ BgpRpcClient.play_send ${withdraw_hex}
+ BuiltIn.Wait_Until_Keyword_Succeeds 4x 2s Loc_Rib_Presnece ${empty_routes}
+ [Teardown] Withdraw_Route_And_Verify ${withdraw_hex}
+
+Verify_Test_Preconditions
+ ${resp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${EVPN_CONF_URL}
+ BuiltIn.Should_Be_Equal_As_Numbers ${resp.status_code} 404
+ ${empty_routes}= OperatingSystem.Get_File ${EVPN_VARIABLES_DIR}/empty_routes.json
+ Loc_Rib_Presnece ${empty_routes}
+
+Remove_Configured_Routes
+ ${rsp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${LOC_RIB_URL} headers=${HEADERS}
+ Log ${rsp.content}
+ ${resp}= RequestsLibrary.Delete_Request ${CONFIG_SESSION} ${EVPN_CONF_URL}
+ BuiltIn.Should_Be_Equal_As_Numbers ${resp.status_code} 200
+
+Withdraw_Route_And_Verify
+ [Arguments] ${withdraw_hex}
+ [Documentation] Sends withdraw update message from exabgp and verifies route removal from odl's rib
+ BgpRpcClient.play_send ${withdraw_hex}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 2s Loc Rib Presnece ${empty_routes}
+
+Get_Update_Content
+ [Documentation] Gets received data from odl's peer
+ ${resp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${EVPN_RIB_OPER_URL} headers=${HEADERS_XML}
+ BuiltIn.Log ${resp.content}
+ ${update}= BgpRpcClient.play_get
+ BuiltIn.Should_Not_Be_Equal ${update} ${Empty}
+ [Return] ${update}
+
+Loc_Rib_Presnece
+ [Arguments] ${exp_content}
+ [Documentation] Verifies if loc-rib contains expected data
+ ${rsp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${LOC_RIB_URL} headers=${HEADERS}
+ Log ${rsp.content}
+ ${keys_with_bits}= BuiltIn.Create_List op
+ ${received_json}= norm_json.Normalize_Json_Text ${rsp.content} keys_with_bits=${keys_with_bits}
+ BuiltIn.Log ${received_json}
+ ${expected_json}= norm_json.Normalize_Json_Text ${exp_content} keys_with_bits=${keys_with_bits}
+ BuiltIn.Log ${expected_json}
+ BuiltIn.Should_Be_Equal ${received_json} ${expected_json}
--- /dev/null
+*** Settings ***
+Documentation Functional test for bgp - route refresh
+...
+... Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+... This suite tests sending and receiveing route request message.
+... It uses odl and exabgp as bgp peers.
+... Sending route refresh message from odl is initiated via restconf.
+... If route refresh received by odl also correct advertising of routes
+... is verified. Receiving of route refresh by odl is verified by
+... checking appropriate message counter via ${JOLOKURL}. Feature
+... odl-jolokia is required by this test suite.
+Suite Setup Start_Suite
+Suite Teardown Stop_Suite
+Library RequestsLibrary
+Library SSHLibrary
+Variables ${CURDIR}/../../../variables/Variables.py
+Resource ${CURDIR}/../../../libraries/Utils.robot
+Resource ${CURDIR}/../../../libraries/SetupUtils.robot
+Resource ${CURDIR}/../../../libraries/TemplatedRequests.robot
+Resource ${CURDIR}/../../../libraries/KarafKeywords.robot
+Resource ${CURDIR}/../../../libraries/SSHKeywords.robot
+Library ${CURDIR}/../../../libraries/norm_json.py
+Library ${CURDIR}/../../../libraries/BgpRpcClient.py ${TOOLS_SYSTEM_IP}
+
+*** Variables ***
+${HOLDTIME} 180
+${DEVICE_NAME} controller-config
+${BGP_PEER_NAME} example-bgp-peer
+${RIB_INSTANCE} example-bgp-rib
+${APP_PEER_NAME} example-bgp-peer-app
+${CMD} env exabgp.tcp.port=1790 exabgp --debug
+${BGP_VAR_FOLDER} ${CURDIR}/../../../variables/bgpfunctional
+${BGP_RR_VAR_FOLDER} ${BGP_VAR_FOLDER}/route_refresh
+${BGP_CFG_NAME} exa.cfg
+${CONFIG_SESSION} config-session
+${EXARPCSCRIPT} ${CURDIR}/../../../../tools/exabgp_files/exarpc.py
+${JOLOKURL} /jolokia/read/org.opendaylight.controller:instanceName=${BGP_PEER_NAME},type=RuntimeBean,moduleFactoryName=bgp-peer
+${PEER_CHECK_URL} /restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/peer/bgp:%2F%2F
+
+*** Test Cases ***
+Configure_App_Peer
+ [Documentation] Configure bgp application peer
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME} RIB_INSTANCE_NAME=${RIB_INSTANCE} APP_PEER_ID=${ODL_SYSTEM_IP}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Reconfigure_ODL_To_Accept_Connection
+ [Documentation] Configure BGP peer module with initiate-connection set to false.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME} IP=${TOOLS_SYSTEM_IP} HOLDTIME=${HOLDTIME} PEER_PORT=${BGP_TOOL_PORT}
+ ... INITIATE=false RIB_INSTANCE_NAME=${RIB_INSTANCE}
+ TemplatedRequests.Put_As_Xml_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Exa_To_Send_Route_Request
+ [Documentation] Exabgp sends route refresh and count received updates
+ [Setup] Configure_Routes_And_Start_Tool ${BGP_CFG_NAME}
+ Verify_Odl_Received_Route_Request 0
+ BgpRpcClient.exa_clean_received_update_count
+ BgpRpcClient.exa_announce announce route-refresh ipv4 unicast
+ BuiltIn.Wait_Until_Keyword_Succeeds 5x 2s Verify_Odl_Received_Route_Request 1
+ BuiltIn.Wait_Until_Keyword_Succeeds 5x 2s Verify_Tool_Received_Updates ${nr_configured_routes}
+ [Teardown] Deconfigure_Routes_And_Stop_Tool
+
+Odl_To_Send_Route_Request
+ [Documentation] Sends route requests and checks if exabgp receives it
+ [Setup] Start_Tool_And_Verify_Connected ${BGP_CFG_NAME}
+ BgpRpcClient.exa_clean_received_route_refresh_count
+ &{mapping} BuiltIn.Create_Dictionary BGP_PEER_IP=${TOOLS_SYSTEM_IP}
+ TemplatedRequests.Post_As_Xml_Templated ${BGP_VAR_FOLDER}/route_refresh mapping=${mapping} session=${CONFIG_SESSION}
+ BuiltIn.Wait_Until_Keyword_Succeeds 5x 2s Verify_Odl_Sent_Route_Request 1
+ [Teardown] Stop_Tool
+
+Delete_Bgp_Peer_Configuration
+ [Documentation] Revert the BGP configuration to the original state: without any configured peers.
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} BGP_NAME=${BGP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/bgp_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+Deconfigure_App_Peer
+ [Documentation] Revert the BGP configuration to the original state: without application peer
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ &{mapping} BuiltIn.Create_Dictionary DEVICE_NAME=${DEVICE_NAME} APP_PEER_NAME=${APP_PEER_NAME}
+ TemplatedRequests.Delete_Templated ${BGP_VAR_FOLDER}/app_peer mapping=${mapping} session=${CONFIG_SESSION}
+
+*** Keywords ***
+Start_Suite
+ [Documentation] Suite setup keyword
+ SetupUtils.Setup_Utils_For_Setup_And_Teardown
+ ${mininet_conn_id}= SSHLibrary.Open Connection ${TOOLS_SYSTEM_IP} prompt=${DEFAULT_LINUX_PROMPT} timeout=6s
+ Builtin.Set_Suite_Variable ${mininet_conn_id}
+ Utils.Flexible_Mininet_Login ${TOOLS_SYSTEM_USER}
+ SSHKeywords.Virtual_Env_Create
+ SSHKeywords.Virtual_Env_Install_Package exabgp==3.4.16
+ RequestsLibrary.Create_Session ${CONFIG_SESSION} http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH}
+ Upload_Config_Files
+
+Stop_Suite
+ [Documentation] Suite teardown keyword
+ SSHKeywords.Virtual_Env_Delete
+ SSHLibrary.Close_All_Connections
+ RequestsLibrary.Delete_All_Sessions
+
+Upload_Config_Files
+ [Documentation] Uploads exabgp config files
+ SSHLibrary.Put_File ${BGP_VAR_FOLDER}/${BGP_CFG_NAME} .
+ SSHLibrary.Put_File ${EXARPCSCRIPT} .
+ @{cfgfiles}= SSHLibrary.List_Files_In_Directory . *.cfg
+ : FOR ${cfgfile} IN @{cfgfiles}
+ \ SSHLibrary.Execute_Command sed -i -e 's/EXABGPIP/${TOOLS_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ODLIP/${ODL_SYSTEM_IP}/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ROUTEREFRESH/enable/g' ${cfgfile}
+ \ SSHLibrary.Execute_Command sed -i -e 's/ADDPATH/disable/g' ${cfgfile}
+ \ ${stdout}= SSHLibrary.Execute_Command cat ${cfgfile}
+ \ Log ${stdout}
+
+Start_Tool
+ [Arguments] ${cfg_file} ${mapping}={}
+ [Documentation] Start the tool ${cmd} ${cfg_file}
+ ${start_cmd} BuiltIn.Set_Variable ${cmd} ${cfg_file}
+ BuiltIn.Log ${start_cmd}
+ SSHKeywords.Virtual_Env_Activate_On_Current_Session log_output=${True}
+ ${output}= SSHLibrary.Write ${start_cmd}
+ BuiltIn.Log ${output}
+
+Verify_Tools_Connection
+ [Arguments] ${connected}=${True}
+ [Documentation] Checks peer presence in operational datastore
+ ${exp_status_code}= BuiltIn.Set_Variable_If ${connected} ${200} ${404}
+ ${rsp}= RequestsLibrary.Get Request ${CONFIG_SESSION} ${PEER_CHECK_URL}${TOOLS_SYSTEM_IP}
+ BuiltIn.Log ${rsp.content}
+ BuiltIn.Should_Be_Equal_As_Numbers ${exp_status_code} ${rsp.status_code}
+
+Start_Tool_And_Verify_Connected
+ [Arguments] ${cfg_file}
+ [Documentation] Start the tool and verify its connection
+ KarafKeywords.Log_Testcase_Start_To_Controller_Karaf
+ Start_Tool ${cfg_file}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 3s Verify_Tools_Connection connected=${True}
+
+Stop_Tool
+ [Documentation] Stop the tool by sending ctrl+c
+ ${output}= SSHLibrary.Read
+ BuiltIn.Log ${output}
+ Utils.Write_Bare_Ctrl_C
+ ${output}= SSHLibrary.Read_Until_Prompt
+ BuiltIn.Log ${output}
+ SSHKeywords.Virtual_Env_Deactivate_On_Current_Session log_output=${True}
+
+Configure_Routes_And_Start_Tool
+ [Arguments] ${cfg_file}
+ [Documentation] Setup keyword for exa to odl test case
+ : FOR ${prefix} IN 1.1.1.1/32 2.2.2.2/32
+ \ &{mapping} BuiltIn.Create_Dictionary PREFIX=${prefix}
+ \ TemplatedRequests.Post_As_Xml_Templated ${BGP_RR_VAR_FOLDER}/route mapping=${mapping} session=${CONFIG_SESSION}
+ BuiltIn.Set_Suite_Variable ${nr_configured_routes} 2
+ Start_Tool_And_Verify_Connected ${cfg_file}
+ BuiltIn.Wait_Until_Keyword_Succeeds 3x 3s Verify_Tool_Received_Updates ${nr_configured_routes}
+
+Deconfigure_Routes_And_Stop_Tool
+ [Documentation] Teardown keyword for exa to odl test case
+ Stop_Tool
+ &{mapping} BuiltIn.Create_Dictionary PREFIX=${prefix}
+ TemplatedRequests.Delete_Templated ${BGP_RR_VAR_FOLDER}/route mapping=${mapping} session=${CONFIG_SESSION}
+
+Verify_Odl_Sent_Route_Request
+ [Arguments] ${expcount}
+ [Documentation] Compares expected count of route request messages on exabgp side
+ ${count}= BgpRpcClient.exa_get_received_route_refresh_count
+ BuiltIn.Should Be Equal As Numbers ${count} ${expcount}
+
+Verify_Odl_Received_Route_Request
+ [Arguments] ${expcount}
+ [Documentation] Gets numebr of received route requests and compares with given expected count
+ ${rsp}= RequestsLibrary.Get_Request ${CONFIG_SESSION} ${JOLOKURL}
+ BuiltIn.Log ${rsp.content}
+ BuiltIn.Should_Be_Equal_As_Numbers ${rsp.status_code} 200
+ BuiltIn.Should_Be_Equal_As_Numbers ${rsp.json()['status']} 200
+ BuiltIn.Should_Be_Equal_As_Numbers ${rsp.json()['value']['BgpSessionState']['messagesStats']['routeRefreshMsgs']['received']['count']['value']} ${expcount}
+
+Verify_Tool_Received_Updates
+ [Arguments] ${expcount}
+ [Documentation] Gets numebr of received update requests and compares with given expected count
+ ${count_recv}= BgpRpcClient.exa_get_received_update_count
+ BuiltIn.Should Be Equal As Numbers ${count_recv} ${expcount}
--- /dev/null
+# Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+
+# Place the suites in run order:
+integration/test/csit/suites/netconf/ready/netconfready.robot
+integration/test/csit/suites/bgpcep/bgpfunct/010_bgp_functional_l3vpn.robot
+integration/test/csit/suites/bgpcep/bgpfunct/030_bgp_functionalt_evpn.robot
+integration/test/csit/suites/bgpcep/bgpfunct/040_bgp_functional_route_ref.robot
+integration/test/csit/suites/bgpcep/bgpfunct/020_bgp_functional_multipath.robot
integration/test/csit/suites/bgpcep/bgpuser/ebgp_peers_basic.robot
integration/test/csit/suites/bgpcep/bgpflowspec/010_bgp_flowspec.robot
integration/test/csit/suites/bgpcep/bgpuser/ibgp_peer_lsp.robot
-
integration/test/csit/suites/bgpcep/bgpuser/ebgp_peers_basic.robot
integration/test/csit/suites/bgpcep/bgpflowspec/010_bgp_flowspec.robot
integration/test/csit/suites/bgpcep/bgpuser/ibgp_peer_lsp.robot
-
+integration/test/csit/suites/bgpcep/bgpfunct/010_bgp_functional_l3vpn.robot
+integration/test/csit/suites/bgpcep/bgpfunct/030_bgp_functionalt_evpn.robot
+integration/test/csit/suites/bgpcep/bgpfunct/040_bgp_functional_route_ref.robot
+integration/test/csit/suites/bgpcep/bgpfunct/020_bgp_functional_multipath.robot
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">x:bgp-application-peer</type>
+ <name>$APP_PEER_NAME</name>
+ <bgp-peer-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">$APP_PEER_ID</bgp-peer-id>
+ <target-rib xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">x:rib-instance</type>
+ <name>$RIB_INSTANCE_NAME</name>
+ </target-rib>
+ <application-rib-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">example-app-rib</application-rib-id>
+ <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">x:dom-async-data-broker</type>
+ <name>pingpong-broker</name>
+ </data-broker>
+ <bgp-peer-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-peer-registry</type>
+ <name>global-bgp-peer-registry</name>
+ </bgp-peer-registry>
+</module>
--- /dev/null
+restconf/config/network-topology:network-topology/topology/topology-netconf/node/$DEVICE_NAME/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:bgp-application-peer/$APP_PEER_NAME
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-peer</type>
+ <name>$BGP_NAME</name>
+ <host xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">$IP</host>
+ <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">$PEER_PORT</port>
+ <holdtimer xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">$HOLDTIME</holdtimer>
+ <initiate-connection xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">$INITIATE</initiate-connection>
+ <rib xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:rib-instance</type>
+ <name>$RIB_INSTANCE_NAME</name>
+ </rib>
+ <peer-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-peer-registry</type>
+ <name>global-bgp-peer-registry</name>
+ </peer-registry>
+ <rpc-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+ <advertized-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+ <name>ipv4-unicast</name>
+ </advertized-table>
+ <advertized-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+ <name>ipv6-unicast</name>
+ </advertized-table>
+ <advertized-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+ <name>linkstate</name>
+ </advertized-table>
+ <advertized-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+ <name>ipv4-l3vpn</name>
+ </advertized-table>
+ <advertized-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+ <name>evpn</name>
+ </advertized-table>
+ <add-path xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
+ <name>ipv4-unicast-both</name>
+ </add-path>
+ <add-path xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
+ <name>ipv6-unicast-both</name>
+ </add-path>
+</module>
--- /dev/null
+restconf/config/network-topology:network-topology/topology/topology-netconf/node/$DEVICE_NAME/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:bgp-peer/$BGP_NAME
--- /dev/null
+neighbor ODLIP {
+router-id EXABGPIP;
+local-address EXABGPIP;
+local-as 64496;
+peer-as 64496;
+ capability {
+ route-refresh ROUTEREFRESH;
+ add-path ADDPATH;
+ }
+
+ family {
+ ipv4 unicast;
+ ipv4 mpls-vpn;
+ }
+
+ process exarpcserver {
+ run exarpc.py --host EXABGPIP;
+ encoder json;
+ receive-routes;
+ neighbor-changes;
+ }
+}
+
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a629000417000219999999000100000000000000000000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a62900041700021999999900010501010101000007d000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a629000417000219999999000101f20cdd809ff7001600202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a629000417000219999999000102f20cdd809ff7001400202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a629000417000219999999000103f20cdd809ff70007d0202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004a02000000334001010040020040050400000064800e2200194604c714a6290004170002199999990001042b2b2b2b000007d000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a6290001190002199999990001000000000000000000000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a62900011900021999999900010501010101000007d0000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005702000000404001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10c01008030d000000000000
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005702000000404001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10c01008060101000005dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005702000000404001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10c010080602f20cdd809ff8
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005702000000404001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10c010084604000700c80000
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005702000000404001010040020040050400000064800e2400194604c714a629000119000219999999000101f20cdd809ff70016000000000a05dc10c0100806000100000000c8
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a629000119000219999999000102f20cdd809ff70014000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a629000119000219999999000103f20cdd809ff70007d00000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff004c02000000354001010040020040050400000064800e2400194604c714a6290001190002199999990001042b2b2b2b000007d0000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800e1c00194604c714a62900031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a6290002280002199999990001000000000000000000000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a62900022800021999999900010501010101000007d0000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a629000228000219999999000101f20cdd809ff70016000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a629000228000219999999000102f20cdd809ff70014000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a629000228000219999999000103f20cdd809ff70007d00000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff005b02000000444001010040020040050400000064800e3300194604c714a6290002280002199999990001042b2b2b2b000007d0000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {}
+}
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "orig-route-ip": "43.43.43.43",
+ "arbitrary": {
+ "arbitrary": "AAAAAAAAAAAA"
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQAAAAAAAAAAAAAgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQAAAAAAAAAAAAAgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <arbitrary>
+ <arbitrary>AAAAAAAAAAAA</arbitrary>
+ </arbitrary>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "as-generated": {
+ "as": 16843009,
+ "local-discriminator": 2000
+ },
+ "orig-route-ip": "43.43.43.43"
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQUBAQEBAAAH0AAgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQUBAQEBAAAH0AAgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <as-generated>
+ <as>16843009</as>
+ <local-discriminator>2000</local-discriminator>
+ </as-generated>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "orig-route-ip": "43.43.43.43",
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQHyDN2An/cAFgAgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQHyDN2An/cAFgAgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "lan-auto-generated": {
+ "root-bridge-priority": 20,
+ "root-bridge-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "orig-route-ip": "43.43.43.43"
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQLyDN2An/cAFAAgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQLyDN2An/cAFAAgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <lan-auto-generated>
+ <root-bridge-mac-address>f2:0c:dd:80:9f:f7</root-bridge-mac-address>
+ <root-bridge-priority>20</root-bridge-priority>
+ </lan-auto-generated>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "mac-auto-generated": {
+ "system-mac-address": "f2:0c:dd:80:9f:f7",
+ "local-discriminator": 2000
+ },
+ "orig-route-ip": "43.43.43.43"
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQPyDN2An/cAB9AgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQPyDN2An/cAB9AgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <mac-auto-generated>
+ <system-mac-address>f2:0c:dd:80:9f:f7</system-mac-address>
+ <local-discriminator>2000</local-discriminator>
+ </mac-auto-generated>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "es-route": {
+ "router-id-generated": {
+ "local-discriminator": 2000,
+ "router-id": "43.43.43.43"
+ },
+ "orig-route-ip": "43.43.43.43"
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "BBcAAhmZmZkAAQQrKysrAAAH0AAgKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>BBcAAhmZmZkAAQQrKysrAAAH0AAgKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <es-route>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ <router-id-generated>
+ <router-id>43.43.43.43</router-id>
+ <local-discriminator>2000</local-discriminator>
+ </router-id-generated>
+ </es-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQAAAAAAAAAAAAAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "arbitrary": {
+ "arbitrary": "AAAAAAAAAAAA"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQAAAAAAAAAAAAAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <arbitrary>
+ <arbitrary>AAAAAAAAAAAA</arbitrary>
+ </arbitrary>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQUBAQEBAAAH0AAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "as-generated": {
+ "as": 16843009,
+ "local-discriminator": 2000
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQUBAQEBAAAH0AAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <as-generated>
+ <as>16843009</as>
+ <local-discriminator>2000</local-discriminator>
+ </as-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "extended-communities": [
+ {
+ "transitive": true,
+ "default-gateway-extended-community": {}
+ }
+ ],
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <extended-communities>
+ <transitive>true</transitive>
+ <default-gateway-extended-community>
+ </default-gateway-extended-community>
+ </extended-communities>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "extended-communities": [
+ {
+ "transitive": true,
+ "esi-label-extended-community": {
+ "single-active-mode": true,
+ "esi-label": 24001
+ }
+ }
+ ],
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <extended-communities>
+ <transitive>true</transitive>
+ <esi-label-extended-community>
+ <single-active-mode>true</single-active-mode>
+ <esi-label>24001</esi-label>
+ </esi-label-extended-community>
+ </extended-communities>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "extended-communities": [
+ {
+ "transitive": true,
+ "es-import-route-extended-community": {
+ "es-import": "f2:0c:dd:80:9f:f8"
+ }
+ }
+ ],
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <extended-communities>
+ <transitive>true</transitive>
+ <es-import-route-extended-community>
+ <es-import>f2:0c:dd:80:9f:f8</es-import>
+ </es-import-route-extended-community>
+ </extended-communities>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "extended-communities": [
+ {
+ "transitive": false,
+ "layer-2-attributes-extended-community": {
+ "control-word": true,
+ "backup-pe": true,
+ "primary-pe": true,
+ "l2-mtu": 200
+ }
+ }
+ ],
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <extended-communities>
+ <transitive>false</transitive>
+ <layer-2-attributes-extended-community>
+ <primary-pe>true</primary-pe>
+ <backup-pe>true</backup-pe>
+ <control-word>true</control-word>
+ <l2-mtu>200</l2-mtu>
+ </layer-2-attributes-extended-community>
+ </extended-communities>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "extended-communities": [
+ {
+ "mac-mobility-extended-community": {
+ "seq-number": 200,
+ "static": true
+ },
+ "transitive": true
+ }
+ ],
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQHyDN2An/cAFgAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <extended-communities>
+ <transitive>true</transitive>
+ <mac-mobility-extended-community>
+ <static>true</static>
+ <seq-number>200</seq-number>
+ </mac-mobility-extended-community>
+ </extended-communities>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQLyDN2An/cAFAAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "lan-auto-generated": {
+ "root-bridge-priority": 20,
+ "root-bridge-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQLyDN2An/cAFAAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <lan-auto-generated>
+ <root-bridge-mac-address>f2:0c:dd:80:9f:f7</root-bridge-mac-address>
+ <root-bridge-priority>20</root-bridge-priority>
+ </lan-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQPyDN2An/cAB9AAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "mac-auto-generated": {
+ "system-mac-address": "f2:0c:dd:80:9f:f7",
+ "local-discriminator": 2000
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQPyDN2An/cAB9AAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-auto-generated>
+ <system-mac-address>f2:0c:dd:80:9f:f7</system-mac-address>
+ <local-discriminator>2000</local-discriminator>
+ </mac-auto-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "ARYAAhmZmZkAAQQrKysrAAAH0AAAAAAK",
+ "route-distinguisher": "429496729:1",
+ "ethernet-a-d-route": {
+ "router-id-generated": {
+ "local-discriminator": 2000,
+ "router-id": "43.43.43.43"
+ },
+ "mpls-label": 24001,
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>ARYAAhmZmZkAAQQrKysrAAAH0AAAAAAK</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <ethernet-a-d-route>
+ <mpls-label>24001</mpls-label>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <router-id-generated>
+ <router-id>43.43.43.43</router-id>
+ <local-discriminator>2000</local-discriminator>
+ </router-id-generated>
+ </ethernet-a-d-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "inc-multi-ethernet-tag-res": {
+ "orig-route-ip": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ }
+ },
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AxEAAhmZmZkAAQAAAAogKysrKw==",
+ "route-distinguisher": "429496729:1"
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AxEAAhmZmZkAAQAAAAogKysrKw==</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <inc-multi-ethernet-tag-res>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <orig-route-ip>43.43.43.43</orig-route-ip>
+ </inc-multi-ethernet-tag-res>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "ip-address": "43.43.43.43",
+ "arbitrary": {
+ "arbitrary": "AAAAAAAAAAAA"
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <arbitrary>
+ <arbitrary>AAAAAAAAAAAA</arbitrary>
+ </arbitrary>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "ip-address": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "as-generated": {
+ "as": 16843009,
+ "local-discriminator": 2000
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <as-generated>
+ <as>16843009</as>
+ <local-discriminator>2000</local-discriminator>
+ </as-generated>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "lacp-auto-generated": {
+ "ce-lacp-port-key": 22,
+ "ce-lacp-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "ip-address": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <lacp-auto-generated>
+ <ce-lacp-mac-address>f2:0c:dd:80:9f:f7</ce-lacp-mac-address>
+ <ce-lacp-port-key>22</ce-lacp-port-key>
+ </lacp-auto-generated>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "lan-auto-generated": {
+ "root-bridge-priority": 20,
+ "root-bridge-mac-address": "f2:0c:dd:80:9f:f7"
+ },
+ "ip-address": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <lan-auto-generated>
+ <root-bridge-mac-address>f2:0c:dd:80:9f:f7</root-bridge-mac-address>
+ <root-bridge-priority>20</root-bridge-priority>
+ </lan-auto-generated>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "mac-auto-generated": {
+ "system-mac-address": "f2:0c:dd:80:9f:f7",
+ "local-discriminator": 2000
+ },
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "ip-address": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <mac-auto-generated>
+ <system-mac-address>f2:0c:dd:80:9f:f7</system-mac-address>
+ <local-discriminator>2000</local-discriminator>
+ </mac-auto-generated>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+{
+ "odl-bgp-evpn:evpn-routes": {
+ "evpn-route": [
+ {
+ "attributes": {
+ "origin": {
+ "value": "igp"
+ },
+ "ipv4-next-hop": {
+ "global": "199.20.166.41"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "as-path": {}
+ },
+ "route-key": "AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=",
+ "route-distinguisher": "429496729:1",
+ "mac-ip-adv-route": {
+ "router-id-generated": {
+ "local-discriminator": 2000,
+ "router-id": "43.43.43.43"
+ },
+ "mpls-label1": 24002,
+ "mpls-label2": 24003,
+ "ip-address": "43.43.43.43",
+ "ethernet-tag-id": {
+ "vlan-id": 10
+ },
+ "mac-address": "f2:0c:dd:80:9f:f7"
+ }
+ }
+ ]
+ }
+}
--- /dev/null
+<?xml version="1.0" ?>
+<evpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-evpn">
+ <route-key>AhgAAhmZmZkAAQAAAAow8gzdgJ/3ICsrKys=</route-key>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <mac-ip-adv-route>
+ <router-id-generated>
+ <router-id>43.43.43.43</router-id>
+ <local-discriminator>2000</local-discriminator>
+ </router-id-generated>
+ <ethernet-tag-id>
+ <vlan-id>10</vlan-id>
+ </ethernet-tag-id>
+ <mac-address>f2:0c:dd:80:9f:f7</mac-address>
+ <ip-address>43.43.43.43</ip-address>
+ <mpls-label1>24002</mpls-label1>
+ <mpls-label2>24003</mpls-label2>
+ </mac-ip-adv-route>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</evpn-route>
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c0019460417000219999999000100000000000000000000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c001946041700021999999900010501010101000007d000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c0019460417000219999999000101f20cdd809ff7001600202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c0019460417000219999999000102f20cdd809ff7001400202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c0019460417000219999999000103f20cdd809ff70007d0202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0044020000002d4001010040020040050400000064800f1c00194604170002199999990001042b2b2b2b000007d000202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e00194601190002199999990001000000000000000000000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e001946011900021999999900010501010101000007d0000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0051020000003a4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10c01008030d000000000000
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0051020000003a4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10c01008060101000005dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0051020000003a4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10c010080602f20cdd809ff8
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0051020000003a4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10c010084604000700c80000
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0051020000003a4001010040020040050400000064800f1e0019460119000219999999000101f20cdd809ff70016000000000a05dc10c0100806000100000000c8
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e0019460119000219999999000102f20cdd809ff70014000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e0019460119000219999999000103f20cdd809ff70007d00000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0046020000002f4001010040020040050400000064800f1e00194601190002199999990001042b2b2b2b000007d0000000000a05dc10
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff003e02000000274001010040020040050400000064800f16001946031100021999999900010000000a202b2b2b2b
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d00194602280002199999990001000000000000000000000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d001946022800021999999900010501010101000007d0000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d0019460228000219999999000101f20cdd809ff70016000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d0019460228000219999999000102f20cdd809ff70014000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d0019460228000219999999000103f20cdd809ff70007d00000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+ffffffffffffffffffffffffffffffff0055020000003e4001010040020040050400000064800f2d00194602280002199999990001042b2b2b2b000007d0000000000a30f20cdd809ff7202b2b2b2b05dc2005dc30
\ No newline at end of file
--- /dev/null
+{
+ "bgp-vpn-ipv4:vpn-ipv4-routes": {}
+}
--- /dev/null
+neighbor ODLIP {
+router-id EXABGPIP;
+local-address EXABGPIP;
+local-as 64496;
+peer-as 64496;
+ family {
+ ipv4 mpls-vpn;
+ }
+ static {
+ route 1.1.1.0/24 {
+ next-hop 10.0.255.254;
+ rd 1.2.3.4:1;
+ label 24005;
+ }
+ }
+}
--- /dev/null
+{
+ "bgp-vpn-ipv4:vpn-ipv4-routes": {
+ "vpn-route": [
+ {
+ "attributes": {
+ "as-path": {},
+ "ipv4-next-hop": {
+ "global": "10.0.255.254"
+ },
+ "local-pref": {
+ "pref": 100
+ },
+ "origin": {
+ "value": "igp"
+ }
+ },
+ "label-stack": [
+ {
+ "label-value": 24005
+ }
+ ],
+ "prefix": "1.1.1.0/24",
+ "route-distinguisher": "1.2.3.4:1",
+ "route-key": "cAXcUQABAQIDBAABAQEB"
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "update": {
+ "announce": {
+ "ipv4 mpls-vpn": {
+ "199.20.166.41": {
+ "2.2.2.2/32": {
+ "label": [
+ 123
+ ],
+ "route-distinguisher": "429496729:1"
+ }
+ }
+ }
+ },
+ "attribute": {
+ "local-preference": 100,
+ "origin": "igp"
+ }
+ }
+}
--- /dev/null
+/restconf/config/bgp-rib:application-rib/example-app-rib/tables/bgp-types:ipv4-address-family/bgp-types:mpls-labeled-vpn-subsequent-address-family/bgp-vpn-ipv4:vpn-ipv4-routes/
--- /dev/null
+<vpn-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-vpn-ipv4">
+ <route-key>vpn1</route-key>
+ <label-stack>
+ <label-value>123</label-value>
+ </label-stack>
+ <route-distinguisher>429496729:1</route-distinguisher>
+ <prefix>2.2.2.2/32</prefix>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.166.41</global>
+ </ipv4-next-hop><as-path/>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ </attributes>
+</vpn-route>
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">x:advertise-all-paths</type>
+ <name>all-paths</name>
+</module>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-path-selection-mode:advertise-all-paths/all-paths
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">x:advertise-n-paths</type>
+ <name>n-paths</name>
+ <n-best-paths xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">$NPATHS</n-best-paths>
+</module>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-path-selection-mode:advertise-n-paths/n-paths
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">x:bgp-psm-impl</type>
+ <name>ipv4-unicast-path-selection-mode</name>
+ <path-address-family xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-unicast</name>
+ <type>bgp-table-type</type>
+ </path-address-family>
+ <path-selection-mode xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>$PATHSELMODE</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">x:path-selection-mode-factory</type>
+ </path-selection-mode>
+</module>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:bgp-psm-impl/ipv4-unicast-path-selection-mode
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules
--- /dev/null
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">x:rib-impl</type>
+ <name>example-bgp-rib</name>
+ <local-as xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">64496</local-as>
+ <dom-data-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>pingpong-broker</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">x:dom-async-data-broker</type>
+ </dom-data-provider>
+ <bgp-rib-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">192.0.2.2</bgp-rib-id>
+ <bgp-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>global-bgp-dispatcher</name>
+ <type>bgp-dispatcher</type>
+ </bgp-dispatcher>
+ <data-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>pingpong-binding-data-broker</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">x:binding-async-data-broker</type>
+ </data-provider>
+ <!--openconfig-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>openconfig-bgp</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp-openconfig-spi">x:bgp-openconfig-provider</type>
+ </openconfig-provider-->
+ <extensions xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>global-rib-extensions</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">x:extensions</type>
+ </extensions>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-unicast</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv6-unicast</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>linkstate</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-flowspec</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv6-flowspec</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-flowspec-l3vpn</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv6-flowspec-l3vpn</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-labeled-unicast</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv6-labeled-unicast</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-l3vpn</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv6-l3vpn</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <local-table xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>evpn</name>
+ <type>bgp-table-type</type>
+ </local-table>
+ <rib-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">example-bgp-rib</rib-id>
+ <codec-tree-factory xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>runtime-mapping-singleton</name>
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">x:binding-codec-tree-factory</type>
+ </codec-tree-factory>
+ <rib-path-selection-mode xmlns="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">
+ <name>ipv4-unicast-path-selection-mode</name>
+ <type>bgp-path-selection-mode</type>
+ </rib-path-selection-mode>
+</module>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:rib-impl/example-bgp-rib
--- /dev/null
+/restconf/config/bgp-rib:application-rib/example-app-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/
--- /dev/null
+ <ipv4-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-inet">
+ <prefix>1.1.1.1/32</prefix>
+ <path-id>$PATHID</path-id>
+ <attributes>
+ <ipv4-next-hop>
+ <global>$NEXTHOP</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <multi-exit-disc>
+ <med>0</med>
+ </multi-exit-disc>
+ <local-pref>
+ <pref>$LOCALPREF</pref>
+ </local-pref>
+ <originator-id>
+ <originator>41.41.41.41</originator>
+ </originator-id>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <cluster-id>
+ <cluster>40.40.40.40</cluster>
+ </cluster-id>
+ </attributes>
+ </ipv4-route>
--- /dev/null
+<service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">x:bgp-path-selection-mode</type>
+ <instance>
+ <name>ipv4-unicast-path-selection-mode</name>
+ <provider>/modules/module[type='bgp-psm-impl'][name='ipv4-unicast-path-selection-mode']</provider>
+ </instance>
+</service>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:services/service/odl-bgp-rib-impl-cfg:bgp-path-selection-mode
--- /dev/null
+<service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">x:path-selection-mode-factory</type>
+ <instance>
+ <name>all-paths</name>
+ <provider>/modules/module[type='advertise-all-paths'][name='all-paths']</provider>
+ </instance>
+ <instance>
+ <name>n-paths</name>
+ <provider>/modules/module[type='advertise-n-paths'][name='n-paths']</provider>
+ </instance>
+</service>
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:services/service/odl-bgp-path-selection-mode:path-selection-mode-factory/
--- /dev/null
+/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:services
--- /dev/null
+<service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">prefix:path-selection-mode-factory</type>
+ <instance>
+ <name>all-paths</name>
+ <provider>/config/modules/module[name='advertise-all-paths']/instance[name='all-paths']</provider>
+ </instance>
+</service>
--- /dev/null
+<service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:bgp:path:selection:mode">x:path-selection-mode-factory</type>
+ <instance>
+ <name>n-paths</name>
+ <provider>/modules/module[type='advertise-n-paths'][name='n-paths']</provider>
+ </instance>
+</service>
--- /dev/null
+<service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-path-selection-mode</type>
+ <instance>
+ <name>ipv4-unicast-path-selection-mode</name>
+ <provider>/modules/module[type='bgp-psm-impl'][name='ipv4-unicast-path-selection-mode']</provider>
+ </instance>
+</service>
--- /dev/null
+/restconf/operations/bgp-peer-rpc:route-refresh-request
--- /dev/null
+<input xmlns="urn:opendaylight:params:xml:ns:yang:bgp-peer-rpc">
+ <afi xmlns:types="urn:opendaylight:params:xml:ns:yang:bgp-types">types:ipv4-address-family</afi>
+ <safi xmlns:types="urn:opendaylight:params:xml:ns:yang:bgp-types">types:unicast-subsequent-address-family</safi>
+ <peer-ref xmlns:rib="urn:opendaylight:params:xml:ns:yang:bgp-rib">/rib:bgp-rib/rib:rib[rib:id="example-bgp-rib"]/rib:peer[rib:peer-id="bgp://$BGP_PEER_IP"]</peer-ref>
+</input>
--- /dev/null
+/restconf/config/bgp-rib:application-rib/example-app-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/
--- /dev/null
+ <ipv4-route xmlns="urn:opendaylight:params:xml:ns:yang:bgp-inet">
+ <prefix>$PREFIX</prefix>
+ <path-id>0</path-id>
+ <attributes>
+ <ipv4-next-hop>
+ <global>199.20.160.41</global>
+ </ipv4-next-hop>
+ <as-path/>
+ <multi-exit-disc>
+ <med>0</med>
+ </multi-exit-disc>
+ <local-pref>
+ <pref>100</pref>
+ </local-pref>
+ <originator-id>
+ <originator>41.41.41.41</originator>
+ </originator-id>
+ <origin>
+ <value>igp</value>
+ </origin>
+ <cluster-id>
+ <cluster>40.40.40.40</cluster>
+ </cluster-id>
+ </attributes>
+ </ipv4-route>
--- /dev/null
+#!/usr/bin/env python
+
+import argparse
+import binascii
+import json
+import logging
+import os
+import re
+import select
+import sys
+import threading
+from exabgp.bgp.message import Message
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+
+
+class ExaStorage(dict):
+ """Thread safe dictionary
+
+ The object will serve as thread safe data storage.
+ It should be used with "with" statement.
+
+ The content of thet dict may be changed dynamically, but i'll use it as
+ {
+ "counters": { <msg type>: count, ...}
+ "messages": { <msg type>: [hex_string1, ]}
+ """
+ def __init__(self):
+ """Thread safe dictionary init"""
+ super(ExaStorage, self).__init__()
+ self._lock = threading.Lock()
+
+ def __enter__(self):
+ """Entry point of "with" statement"""
+ self._lock.acquire()
+ return self
+
+ def __exit__(self, type_, value, traceback):
+ """End point of "with" statement"""
+ self._lock.release()
+
+
+class Rpcs(object):
+ """Handler for SimpleXMLRPCServer."""
+
+ def __init__(self, storage):
+ """Init method
+
+ Arguments:
+ :storage: thread safe dict
+ """
+ self.storage = storage
+
+ def _write(self, text):
+ """Pass commands from rpc server towards exabgp
+
+ Arguments:
+ :text: exabgp command
+ """
+ logging.debug('Command towards exabgp: {}'.format(text))
+ sys.stdout.write(text)
+ sys.stdout.write("\n")
+ sys.stdout.flush()
+ logging.debug('Connand flushed: {}.'.format(text))
+
+ def get_counter(self, msg_type):
+ """Gets counter value
+
+ Arguments:
+ :msg_type: message type which counter should be returned
+ Returns:
+ :cnt: counter value
+ """
+ logging.debug('get_counter rpc called, storage {}'.format(self.storage))
+ with self.storage as s:
+ if 'counters' not in s:
+ return 0
+ cnt = 0 if msg_type not in s['counters'] else s['counters'][msg_type]
+ return cnt
+
+ def clean_counter(self, msg_type):
+ """Cleans counter
+
+ Arguments:
+ :msg_type: message type which counter should be cleaned
+ """
+
+ logging.debug('clean_counter rpc called, storage {}'.format(self.storage))
+ with self.storage as s:
+ if 'counters' not in s:
+ return
+ if msg_type in s['counters']:
+ del s['counters'][msg_type]
+
+ def get_message(self, msg_type):
+ """Gets last received message
+
+ Arguments:
+ :msg_type: message type which counter should be returned
+ Returns:
+ :msg: message
+ """
+ logging.debug('get_message {} rpc called, storage {}'.format(msg_type, self.storage))
+ with self.storage as s:
+ if 'messages' not in s:
+ return None
+ msg = None if msg_type not in s['messages'] else s['messages'][msg_type]
+ return msg
+
+ def clean_message(self, msg_type):
+ """Removes stored message
+
+ Arguments:
+ :msg_type: message type which message should be cleaned
+ """
+
+ logging.debug('clean_message rpc called, storage {}'.format(self.storage))
+ with self.storage as s:
+ if 'messages' not in s:
+ return
+ if msg_type in s['messages']:
+ del s['messages'][msg_type]
+ return
+
+ def execute(self, exabgp_cmd):
+ """Execite given command on exabgp
+
+ Arguments:
+ :exabgp_cmd: command
+ """
+ logging.info('executing: {}.'.format(exabgp_cmd))
+ self._write(exabgp_cmd)
+
+
+def decode_message(header, body):
+ """Decodes message
+
+ Arguments:
+ :header: hexstring of the header
+ :body: hexstring of the body
+ Returns:
+ :msg_type: message type
+ :msg: None (in the future some decoded data)
+ """
+ headbin = binascii.unhexlify(header)
+
+ msg_type = ord(headbin[18])
+ msg = None
+
+ return msg_type, msg
+
+
+def _increment_counter(storage, key):
+ """Increments the counter for a message
+
+ Arguments:
+ :key: message type
+ """
+ with storage as s:
+ if 'counters' not in s:
+ s['counters'] = {}
+ if key not in s['counters']:
+ s['counters'][key] = 1
+ else:
+ s['counters'][key] += 1
+
+
+def _store_last_received_message(storage, key, msg):
+ """Stores message under key.
+
+ Arguments:
+ :key: message type
+ """
+ with storage as s:
+ if 'messages' not in s:
+ s['messages'] = {}
+ s['messages'][key] = msg
+
+
+def handle_open(storage, msg):
+ """Handles received bgp open message
+
+ - incements open counter
+
+ Arguments:
+ :msg: hex string of open body
+ """
+ logging.debug('Handling Open with storage {}'.format(storage))
+ _increment_counter(storage, 'open')
+
+
+def handle_keepalive(storage, msg):
+ """Handles received bgp keepalive message
+
+ - incements keepalive counter
+
+ Arguments:
+ :msg: hex string of message body (in fact it is None)
+ """
+ logging.debug('Handling KeepAlive with storage {}'.format(storage))
+ _increment_counter(storage, 'keepalive')
+
+
+def handle_update(storage, msg):
+ """Handles received bgp update message
+
+ - incements update counter
+
+ Arguments:
+ :msg: hex string of update body
+ """
+ logging.debug('Handling Update with storage {}'.format(storage))
+ _increment_counter(storage, 'update')
+
+
+def handle_route_refresh(storage, msg):
+ """Handles received bgp route refresh message
+
+ - incements route refresh counter
+
+ Arguments:
+ :msg: hex string of route refresh body
+ """
+ logging.debug('Handling Route Refresh with storage {}'.format(storage))
+ _increment_counter(storage, 'route_refresh')
+
+
+def handle_json_update(storage, jdata):
+ """Handles received json parsed bgp update message
+
+ - incements update counter
+
+ Arguments:
+ :jdata: json formated data of update message
+ """
+ logging.debug('Handling Json Update with storage {}'.format(storage))
+ _increment_counter(storage, 'update')
+ _store_last_received_message(storage, 'update', jdata)
+
+
+def handle_json_state(storage, jdata):
+ """Handles received json state message
+
+ This is for future use. This information is not used/required/needed
+ at the moment.
+
+ Arguments:
+ :jdata: json formated data about connection/peer state
+ """
+ logging.debug('Handling Json State with storage {}'.format(storage))
+
+
+def handle_json_refresh(storage, jdata):
+ """Handles received json route refresh message
+
+ This is for future use. This information is not used/required/needed
+ at the moment.
+
+ Arguments:
+ :jdata: json formated data about connection/peer state
+ """
+ logging.debug('Handling Json State with storage {}'.format(storage))
+ _increment_counter(storage, 'route_refresh')
+
+
+def exa_msg_handler(storage, data, encoder):
+ """Handles incomming messages"""
+
+ if encoder == 'text':
+ if not ('neighbor' in data and 'header' in data and 'body' in data):
+ logging.debug('Ignoring received notification from exabgp: {}'.format(data))
+ return
+ restr = 'neighbor (?P<ip>[0-9,\\.]+) received (?P<mid>[0-9]+) header\
+ (?P<header>[0-9,A-F]+) body.?(?P<body>[0-9,A-F]+)?'
+ pat = re.compile(restr)
+ match = re.search(pat, data)
+ if match is None:
+ logging.warn('Unexpected data in this part, only bgp message expected. Received: {}.'.format(data))
+ return
+ msg_type, msg = decode_message(match.groupdict()['header'], match.groupdict()['body'])
+ if msg_type == Message.CODE.KEEPALIVE:
+ handle_keepalive(storage, msg)
+ elif msg_type == Message.CODE.OPEN:
+ handle_open(storage, msg)
+ elif msg_type == Message.CODE.UPDATE:
+ handle_update(storage, msg)
+ elif msg_type == Message.CODE.ROUTE_REFRESH:
+ handle_route_refresh(storage, msg)
+ else:
+ logging.warn('No handler function for msg_type: {}'.format(msg_type))
+ elif encoder == 'json':
+ try:
+ jdata = json.loads(data)
+ except Exception:
+ logging.error('Unable to parse, expected json, received: {}.'.format(data))
+ return
+ if jdata['type'] == 'state':
+ logging.debug('State info received: {}.'.format(data))
+ handle_json_state(storage, jdata)
+ elif jdata['type'] == 'update':
+ logging.debug('Update info received: {}.'.format(data))
+ handle_json_update(storage, jdata)
+ elif jdata['type'] == 'notification':
+ logging.debug('Notification info received: {}.'.format(data))
+ elif jdata['type'] == 'refresh':
+ logging.debug('Route refresh received: {}.'.format(data))
+ handle_json_refresh(storage, jdata)
+ else:
+ logging.error('Unexpected type for data: {}'.format(data))
+ else:
+ logging.error('Ignoring received data, unknown encoder: {}'.format(encoder))
+
+
+def main(*argv):
+ """This script is used as i/o api for communication with exabgp
+
+ Arguments:
+ :*argv: unparsed cli arguments
+
+ In a separate thread an rpc server is started. This server will be used as an api towards the user.
+ Stdin and stdout are used for communication with exabgp.
+ """
+
+ parser = argparse.ArgumentParser(description='ExaBgp rpc server script')
+ parser.add_argument('--host', default='127.0.0.1', help='Host where exabgp is running (default is 127.0.0.1)')
+ parser.add_argument('--loglevel', default=logging.DEBUG, help='Log level')
+ parser.add_argument('--logfile', default='{}/exarpc.log'.format(os.path.dirname(os.path.abspath(__file__))),
+ help='Log file name.')
+ parser.add_argument('--encoder', default='json', help='Exabgp encoder type')
+ in_args = parser.parse_args(*argv)
+ logging.basicConfig(filename=in_args.logfile, level=in_args.loglevel)
+
+ storage = ExaStorage()
+ rpcserver = SimpleXMLRPCServer((in_args.host, 8000), allow_none=True)
+ rpcserver.register_instance(Rpcs(storage))
+ trpc = threading.Thread(target=rpcserver.serve_forever)
+ trpc.start()
+
+ epoll = select.epoll()
+
+ epoll.register(sys.__stdin__, select.EPOLLIN | select.EPOLLERR | select.EPOLLHUP)
+
+ try:
+ while True:
+ logging.debug('Epoll loop')
+ events = epoll.poll(10)
+ for fd, event_type in events:
+ logging.debug('Epoll returned: {},{}'.format(fd, event_type))
+ if event_type != select.EPOLLIN:
+ raise Exception('Unexpected epoll event')
+ else:
+ data = sys.stdin.readline()
+ logging.debug('Data recevied from exabgp: {}.'.format(data))
+ exa_msg_handler(storage, data, in_args.encoder)
+ except Exception as e:
+ logging.warn('Exception occured: {}'.format(e))
+ finally:
+ rpcserver.shutdown()
+ trpc.join()
+
+if __name__ == '__main__':
+ main()
# terms of the Eclipse Public License v1.0 which accompanies this distribution,
# and is available at http://www.eclipse.org/legal/epl-v10.html
+from copy import deepcopy
+from SimpleXMLRPCServer import SimpleXMLRPCServer
import argparse
import binascii
import ipaddr
+import logging
+import Queue
import select
import socket
-import time
-import logging
import struct
-
import thread
-from copy import deepcopy
+import threading
+import time
__author__ = "Vratko Polak"
__email__ = "vrpolak@cisco.com"
+class SafeDict(dict):
+ '''Thread safe dictionary
+
+ The object will serve as thread safe data storage.
+ It should be used with "with" statement.
+ '''
+
+ def __init__(self, * p_arg, ** n_arg):
+ super(SafeDict, self).__init__()
+ self._lock = threading.Lock()
+
+ def __enter__(self):
+ self._lock.acquire()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self._lock.release()
+
+
def parse_arguments():
"""Use argparse to get arguments,
parser.add_argument("-lsteaddrstep", default="1", type=int, help=str_help)
str_help = "How many play utilities are to be started."
parser.add_argument("--multiplicity", default="1", type=int, help=str_help)
+ str_help = "Open message includes multiprotocol extension capability l2vpn-evpn.\
+Enabling this flag makes the script not decoding the update mesage, because of not\
+supported decoding for these elements."
+ parser.add_argument("--evpn", default=False, action="store_true", help=str_help)
+ parser.add_argument("--wfr", default=10, type=int, help="Wait for read timeout")
arguments = parser.parse_args()
if arguments.multiplicity < 1:
print "Multiplicity", arguments.multiplicity, "is not positive."
self.performance_threshold_default = args.threshold
self.rfc4760 = args.rfc4760
self.bgpls = args.bgpls
+ self.evpn = args.evpn
# Default values when BGP-LS Attributes are used
if self.bgpls:
self.prefix_count_to_add_default = 1
)
optional_parameters_hex += optional_parameter_hex
+ if self.evpn:
+ optional_parameter_hex = (
+ "\x02" # Param type ("Capability Ad")
+ "\x06" # Length (6 bytes)
+ "\x01" # Multiprotocol extetension capability,
+ "\x04" # Capability value length
+ "\x00\x19" # AFI (L2-VPN)
+ "\x00" # (reserved)
+ "\x46" # SAFI (EVPN)
+ )
+ optional_parameters_hex += optional_parameter_hex
+
optional_parameter_hex = (
"\x02" # Param type ("Capability Ad")
"\x06" # Length (6 bytes)
for idle waiting.
"""
- def __init__(self, bgp_socket, timer):
+ def __init__(self, bgp_socket, timer, storage, evpn=False, wait_for_read=10):
"""The reader initialisation.
Arguments:
bgp_socket: socket to be used for sending
timer: timer to be used for scheduling
+ storage: thread safe dict
+ evpn: flag that evpn functionality is tested
"""
# References to outside objects.
self.socket = bgp_socket
self.prefixes_withdrawn = 0
self.rx_idle_time = 0
self.rx_activity_detected = True
+ self.storage = storage
+ self.evpn = evpn
+ self.wfr = wait_for_read
def read_message_chunk(self):
"""Read up to one message
# message header - message type
msg_type_hex = msg[18:19]
msg_type = int(binascii.b2a_hex(msg_type_hex), 16)
+
+ with self.storage as stor:
+ # this will replace the previously stored message
+ stor['update'] = binascii.hexlify(msg)
+
+ logger.debug("Evpn {}".format(self.evpn))
+ if self.evpn:
+ logger.debug("Skipping update decoding due to evpn data expected")
+ return
+
if msg_type == 2:
logger.debug("Message type: 0x%s (update)",
binascii.b2a_hex(msg_type_hex))
# Compute time to the first predictable state change
event_time = self.timer.get_next_event_time()
# snapshot_time would be imprecise
- wait_timedelta = min(event_time - time.time(), 10)
+ wait_timedelta = min(event_time - time.time(), self.wfr)
if wait_timedelta < 0:
# The program got around to waiting to an event in "very near
# future" so late that it became a "past" event, thus tell
class StateTracker(object):
"""Main loop has state so complex it warrants this separate class."""
- def __init__(self, bgp_socket, generator, timer):
+ def __init__(self, bgp_socket, generator, timer, inqueue, storage, cliargs):
"""The state tracker initialisation.
Arguments:
bgp_socket: socket to be used for sending / receiving
generator: generator to be used for message generation
timer: timer to be used for scheduling
+ inqueue: user initiated messages queue
+ storage: thread safe dict to store data for the rpc server
+ cliargs: cli args from the user
"""
# References to outside objects.
self.socket = bgp_socket
self.generator = generator
self.timer = timer
# Sub-trackers.
- self.reader = ReadTracker(bgp_socket, timer)
+ self.reader = ReadTracker(bgp_socket, timer, storage, evpn=cliargs.evpn, wait_for_read=cliargs.wfr)
self.writer = WriteTracker(bgp_socket, generator, timer)
# Prioritization state.
self.prioritize_writing = False
# TODO: Alternative is to switch fairly between reading and
# writing (called round robin from now on).
# Message counting is done in generator.
+ self.inqueue = inqueue
def perform_one_loop_iteration(self):
""" The main loop iteration
logger.info("KEEP ALIVE is sent.")
# We are sending a message now, so let's prioritize it.
self.prioritize_writing = True
+
+ try:
+ msg = self.inqueue.get_nowait()
+ logger.info("Received message: {}".format(msg))
+ msgbin = binascii.unhexlify(msg)
+ self.writer.enqueue_message_for_sending(msgbin)
+ except Queue.Empty:
+ pass
# Now we know what our priorities are, we have to check
# which actions are available.
# socket.socket() returns three lists,
return logger
-def job(arguments):
+def job(arguments, inqueue, storage):
"""One time initialisation and iterations looping.
Notes:
Establish BGP connection and run iterations.
Arguments:
:arguments: Command line arguments
+ :inqueue: Data to be sent from play.py
+ :storage: Shared dict for rpc server
Returns:
:return: None
"""
# Use the remembered time.
timer.reset_my_keepalive_time(timer.snapshot_time)
# End of initial handshake phase.
- state = StateTracker(bgp_socket, generator, timer)
+ state = StateTracker(bgp_socket, generator, timer, inqueue, storage, arguments)
while True: # main reactor loop
state.perform_one_loop_iteration()
+class Rpcs:
+ '''Handler for SimpleXMLRPCServer'''
+ def __init__(self, sendqueue, storage):
+ '''Init method
+
+ Arguments:
+ :sendqueue: queue for data to be sent towards odl
+ :storage: thread safe dict
+ '''
+ self.queue = sendqueue
+ self.storage = storage
+
+ def send(self, text):
+ '''Data to be sent
+
+ Arguments:
+ :text: hes string of the data to be sent
+ '''
+ self.queue.put(text)
+
+ def get(self, text=''):
+ '''Reads data form the storage
+
+ - returns stored data or an empty string, at the moment only
+ 'update' is stored
+
+ Arguments:
+ :text: a key to the storage to get the data
+ Returns:
+ :data: stored data
+ '''
+ with self.storage as stor:
+ return stor.get(text, '')
+
+ def clean(self, text=''):
+ '''Cleans data form the storage
+
+ Arguments:
+ :text: a key to the storage to clean the data
+ '''
+ with self.storage as stor:
+ if text in stor:
+ del stor[text]
+
+
def threaded_job(arguments):
"""Run the job threaded
prefix_current = arguments.firstprefix
myip_current = arguments.myip
thread_args = []
+ rpcqueue = Queue.Queue()
+ storage = SafeDict()
while 1:
amount_per_util = (amount_left - 1) / utils_left + 1 # round up
try:
# Create threads
for t in thread_args:
- thread.start_new_thread(job, (t,))
+ thread.start_new_thread(job, (t, rpcqueue, storage))
except Exception:
print "Error: unable to start thread."
raise SystemExit(2)
- # Work remains forever
- while 1:
- time.sleep(5)
+ rpcserver = SimpleXMLRPCServer((arguments.myip.compressed, 8000), allow_none=True)
+ rpcserver.register_instance(Rpcs(rpcqueue, storage))
+ rpcserver.serve_forever()
if __name__ == "__main__":