Add graceful-restart test suite 77/77177/33
authortomas.markovic <tomas.markovic@pantheon.tech>
Mon, 22 Oct 2018 13:28:35 +0000 (15:28 +0200)
committerJamo Luhrsen <jluhrsen@redhat.com>
Tue, 18 Dec 2018 20:53:36 +0000 (20:53 +0000)
Change-Id: I370968d827149a59d0908ff0f184450c70426a9e
Signed-off-by: tomas.markovic <tomas.markovic@pantheon.tech>
28 files changed:
csit/suites/bgpcep/bgpfunct/100_bgp_functional_graceful_restart.robot [new file with mode: 0644]
csit/testplans/bgpcep-userfeatures-neon.txt
csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/volatiles.list [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/empty_route/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/empty_route/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/empty_route/volatiles.list [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_1/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_1/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_2/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_2/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv6.hex [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv6_1/data.json [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/ipv6_1/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/peers/data.xml [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/peers/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/restart/location.uri [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/restart/post_data.xml [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/tc1/tc1.hex [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/tc3/tc3.hex [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/tc4/tc4.hex [new file with mode: 0644]
csit/variables/bgpfunctional/graceful_restart/tc5/tc5.hex [new file with mode: 0644]
tools/fastbgp/play.py

diff --git a/csit/suites/bgpcep/bgpfunct/100_bgp_functional_graceful_restart.robot b/csit/suites/bgpcep/bgpfunct/100_bgp_functional_graceful_restart.robot
new file mode 100644 (file)
index 0000000..3fc49b2
--- /dev/null
@@ -0,0 +1,255 @@
+*** Settings ***
+Documentation     Functional test for bgp - graceful-restart
+...
+...               Copyright (c) 2018 AT&T Intellectual Property. 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 distbmution,
+...               and is available at http://www.eclipse.org/legal/epl-v10.html
+Suite Setup       Start_Suite
+Suite Teardown    Stop_Suite
+Test Setup        SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+Library           ../../../libraries/BgpRpcClient.py    ${ODL_SYSTEM_IP}    8001    WITH NAME    BgpRpcClient1
+Library           ../../../libraries/BgpRpcClient.py    ${ODL_SYSTEM_IP}    8002    WITH NAME    BgpRpcClient2
+Library           OperatingSystem
+Library           RequestsLibrary
+Library           SSHLibrary
+Library           String
+Resource          ../../../libraries/BGPcliKeywords.robot
+Resource          ../../../libraries/BgpOperations.robot
+Resource          ../../../libraries/BGPSpeaker.robot
+Resource          ../../../libraries/SetupUtils.robot
+Resource          ../../../libraries/SSHKeywords.robot
+Resource          ../../../libraries/TemplatedRequests.robot
+Resource          ../../../variables/Variables.robot
+
+*** Variables ***
+${HOLDTIME}       180
+${RIB_NAME}       example-bgp-rib
+${CONFIG_SESSION}    config-session
+${PLAY_SCRIPT}    ${CURDIR}/../../../../tools/fastbgp/play.py
+${GR_FOLDER}      ${CURDIR}/../../../variables/bgpfunctional/graceful_restart
+${PEER1_AS}       65000
+${PEER2_AS}       65001
+${PEER1_IP}       127.0.0.2
+${PEER2_IP}       127.0.0.3
+${PEER1_PORT}     8001
+${PEER2_PORT}     8002
+${FIRST_PREFIX}    8.1.0.0
+${SECOND_PREFIX}    8.2.0.0
+${NEXT_HOP}       1.1.1.1
+${PREFIX_LEN}     28
+
+*** Test Cases ***
+Verify_Empty_Rib_After_Graceful_Restart_Timer_Expired
+    [Documentation]    Prerequistes: One peer with one route running.
+    ...    Verify peer route is present in odl's loc-rib.
+    ...    Kill bgp speaker. After graceful-restart restart-time runs out, route must not be
+    ...    present in odl's loc-rib.
+    [Setup]    Setup_TC0
+    Verify_Routes    dir=ipv4_1
+    Kill_Talking_BGP_Speakers    log_name=gr_tc0.out
+    Verify_Routes    retry=10x
+    [Teardown]    Teardown_TC    gr_tc0.out
+
+Verify_Route_Was_Kept_After_Peer_Restart
+    [Documentation]    Prerequistes: One peer with one route was just killed.
+    ...    Restart killed peer with the same route.
+    ...    Verify that route is still present in loc-rib.
+    ...    Verify odl advertised end-of-rib message with appropriate flags.
+    [Setup]    Setup_TC1
+    Start_Bgp_Peer    grace=3    log_name=gr_tc1.out
+    Verify_Routes    dir=ipv4_1
+    Verify_Hex_Message    tc1
+    [Teardown]    Teardown_TC    gr_tc1.out
+
+Verify_Change_In_Amount_Of_Routes_After_Peer_Restart
+    [Documentation]    Prerequistes: One peer with two routes was just killed.
+    ...    Restart killed peer with just one route. Verify only one route is present in loc-rib.
+    [Setup]    Setup_TC2
+    Start_Bgp_Peer    grace=2    log_name=gr_tc2.out
+    Verify_Routes    dir=ipv4_1
+    [Teardown]    Teardown_TC    gr_tc2.out
+
+Verify_Odl_Advertisment_Of_New_Route_After_Peer_Restart
+    [Documentation]    Prerequistes: One peer with one route, was just killed. Second is still running with one route.
+    ...    Restart killed peer with two routes. Verify that two routes from restarted peer and one route
+    ...    from second peer is in loc-rib. Verify odl advertised update message to second peer with new route
+    ...    and appropriate end-of-rib message.
+    [Setup]    Setup_TC3
+    Start_Bgp_Peer    amount=2    grace=2
+    Verify_Hex_Message    tc3
+    Verify_Routes    dir=ipv4_2_1
+    [Teardown]    Teardown_TC    gr_tc3.out
+
+Verify_Odl_Kept_Route_After_Odl_Restart
+    [Documentation]    Prerequistes: One peer with one route running.
+    ...    Graceful-restart odl. Close tcp connection from peer side and reopen it.
+    ...    Send end-of-rib with all 0 flags, and expect the route still in loc-rib.
+    ...    Verify end-of-rib message from odl with all flags set to 1.
+    [Setup]    Setup_TC_PG
+    Post_Graceful_Restart
+    Kill_Talking_BGP_Speakers
+    Start_Bgp_Peer    grace=0    log_name=gr_tc4.out
+    Verify_Hex_Message    tc4
+    Verify_Routes    dir=ipv4_1
+    [Teardown]    Teardown_TC    gr_tc4.out
+
+Verify_Odl_Accepted_Routes_After_Odl_Restart
+    [Documentation]    Prerequistes: One peer with one route running.
+    ...    Graceful-restart odl. Close tcp connection from peer side and reopen it.
+    ...    Start bgp peer with two routes, and send end-of-rib message with ipv4 flag
+    ...    set to 1. Verify loc-rib and end-of-rib message from odl.
+    [Setup]    Setup_TC_PG
+    Post_Graceful_Restart
+    Kill_Talking_BGP_Speakers
+    Start_Bgp_Peer    amount=2    grace=2    log_name=gr_tc5.out
+    Verify_Hex_Message    tc5
+    Verify_Routes    dir=ipv4_2
+    [Teardown]    Teardown_TC    gr_tc5.out
+
+Verify_No_Ipv6_Route_Immediately_After_Peer_Was_Killed
+    [Documentation]    Prerequistes: One peer with one ipv4 route and one ipv6 route running.
+    ...    Kill the speaker. And Verify that there is ipv4 route still present, but ipv6 rib should be empty
+    ...    because it had no graceful-restart ability configured.
+    [Setup]    Setup_TC6
+    Kill_Talking_BGP_Speakers
+    Verify_Routes    dir=ipv4_1
+    Verify_Routes    dir=empty_ipv6_route    interval=1s
+    [Teardown]    Teardown_TC    gr_tc6.out
+
+*** Keywords ***
+Start_Suite
+    [Documentation]    Initialize SetupUtils. Suite setup keyword.
+    ...    Copies play.py script for peer simulation onto ODL VM.
+    ...    Configures peers on odl with graceful-restart enabled.
+    SetupUtils.Setup_Utils_For_Setup_And_Teardown
+    SSHLibrary.Open Connection    ${ODL_SYSTEM_IP}    prompt=${DEFAULT_LINUX_PROMPT}    timeout=6s
+    SSHKeywords.Flexible_Controller_Login
+    SSHLibrary.Put_File    ${PLAY_SCRIPT}    .
+    SSHKeywords.Assure_Library_Ipaddr    target_dir=.
+    RequestsLibrary.Create_Session    ${CONFIG_SESSION}    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}    auth=${AUTH}
+    Configure_BGP_Peers
+
+Stop_Suite
+    [Documentation]    Delete peer configuration, close all remaining ssh and http sessions.
+    Delete_Bgp_Peers_Configuration
+    SSHLibrary.Close_All_Connections
+    RequestsLibrary.Delete_All_Sessions
+
+Setup_TC0
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start one bgp peer with one routes.
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer    log_name=gr_tc0.out
+
+Setup_TC1
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start one bgp peer with one routes, and verify routes is present in loc-rib.
+    ...    Kill bgp speaker (effectively simulating graceful-restart)
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer
+    Verify_Routes    dir=ipv4_1
+    Kill_Talking_BGP_Speakers
+
+Setup_TC2
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start one bgp peer with two routes, and verify routes are present in loc-rib.
+    ...    Kill bgp speaker (effectively simulating graceful-restart)
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer    amount=2
+    Verify_Routes    dir=ipv4_2
+    Kill_Talking_BGP_Speakers
+
+Setup_TC3
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start two bgp peers, each with their default values, and verify their respective routes
+    ...    are present in loc-rib, than kill the first bgp speaker (effectively simulating graceful-restart)
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer    prefix=${SECOND_PREFIX}    myip=${PEER2_IP}    port=${PEER2_PORT}    as_number=${PEER2_AS}    log_name=gr_tc3.out
+    Start_Bgp_Peer    multiple=${EMPTY}
+    Verify_Routes    dir=ipv4_1_1
+    BGPSpeaker.Kill_BGP_Speaker
+
+Setup_TC_PG
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start one bgp peer, and verify it's route is present in loc-rib.
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer
+    Verify_Routes    dir=ipv4_1
+
+Setup_TC6
+    [Documentation]    Log Test Case name into karaf log, and make sure it wont fail other TC's.
+    ...    Start one bgp peer with one routes, and send ipv6 route without gr configured.
+    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    Start_Bgp_Peer    log_name=gr_tc6.out    ipv6=${SPACE}--ipv6
+    ${announce_hex} =    OperatingSystem.Get_File    ${GR_FOLDER}${/}ipv6.hex
+    ${announce_hex} =    String.Remove_String    ${announce_hex}    \n
+    Verify_Routes    dir=ipv4_1
+    BgpRpcClient1.play_send    ${announce_hex}
+    Verify_Routes    dir=ipv6_1
+
+Teardown_TC
+    [Arguments]    ${log_name}=play.py.out
+    [Documentation]    In case Test Case failed to close Python Speakers, we close them.
+    ...    Wait until there are no routes present in loc-rib.
+    Kill_Talking_BGP_Speakers    ${log_name}
+    Verify_Routes    dir=empty_route    retry=10x
+    Verify_Routes    dir=empty_ipv6_route    interval=1s
+
+Verify_Routes
+    [Arguments]    ${dir}=empty_route    ${retry}=5x    ${interval}=3s
+    [Documentation]    Verify route based on how many routes are present in rib.
+    BuiltIn.Wait_Until_Keyword_Succeeds    ${retry}    ${interval}    TemplatedRequests.Get_As_Json_Templated    ${GR_FOLDER}${/}${dir}    session=${CONFIG_SESSION}    verify=True
+
+Verify_Hex_Message
+    [Arguments]    ${file_dir}    ${peer}=${PEER1_IP}    ${file_name}=${file_dir}.hex
+    [Documentation]    Verify hex message advertised from odl.
+    ${expected} =    TemplatedRequests.Resolve_Text_From_Template_File    ${GR_FOLDER}${/}${file_dir}    ${file_name}
+    ${actual} =    BuiltIn.Wait_Until_Keyword_Succeeds    5x    3s    Get_Hex_Message    peer=${peer}
+    BgpOperations.Verify_Two_Hex_Messages_Are_Equal    ${expected}    ${actual}
+
+Get_Hex_Message
+    [Arguments]    ${peer}=${PEER1_IP}
+    [Documentation]    Gets open message in case of first peer, and update message in case of second peer.
+    ${hex} =    BuiltIn.Run_Keyword_If    "${peer}" == "${PEER1_IP}"    BgpRpcClient1.play_get    what=open
+    ...    ELSE    BgpRpcClient2.play_get
+    BuiltIn.Should_Not_Be_Equal    ${hex}    ${EMPTY}
+    [Return]    ${hex}
+
+Start_Bgp_Peer
+    [Arguments]    ${prefix}=${FIRST_PREFIX}    ${amount}=1    ${myip}=${PEER1_IP}    ${port}=${PEER1_PORT}    ${as_number}=${PEER1_AS}    ${grace}=0
+    ...    ${log_name}=play.py.out    ${multiple}=&    ${ipv6}=${EMPTY}
+    [Documentation]    Starts bgp peer.
+    ${command} =    BuiltIn.Set_Variable    python play.py${ipv6} --firstprefix ${prefix} --prefixlen ${PREFIX_LEN} --amount ${amount} --myip ${myip} --myport ${BGP_TOOL_PORT} --peerip ${ODL_SYSTEM_IP} --peerport ${ODL_BGP_PORT} --port ${port} --usepeerip --nexthop ${NEXT_HOP} --asnumber ${as_number} --debug --grace ${grace} --wfr 1 &> ${log_name} ${multiple}
+    BuiltIn.Log    ${command}
+    ${output} =    SSHLibrary.Write    ${command}
+
+Kill_Talking_BGP_Speakers
+    [Arguments]    ${log_name}=play.py.out
+    [Documentation]    Save play.py log into workspace, attempt to dump speaker logs into robot log.
+    ...    Abort all Python speakers.
+    BuiltIn.Run_Keyword_And_Ignore_Error    BGPcliKeywords.Store_File_To_Workspace    ${log_name}    ${log_name}.log
+    BuiltIn.Run_Keyword_And_Ignore_Error    BGPSpeaker.Dump_BGP_Speaker_Logs
+    BGPSpeaker.Kill_All_BGP_Speakers
+
+Configure_BGP_Peers
+    [Arguments]    ${folder}=${EMPTY}
+    [Documentation]    Configure two eBGP peers with graceful-restart enabled
+    &{mapping}    BuiltIn.Create_Dictionary    IP=${PEER1_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}    AS_NUMBER=${PEER1_AS}    BGP_RIB=${RIB_NAME}
+    TemplatedRequests.Put_As_Xml_Templated    ${GR_FOLDER}${/}${folder}peers    mapping=${mapping}    session=${CONFIG_SESSION}
+    &{mapping}    BuiltIn.Create_Dictionary    IP=${PEER2_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}    AS_NUMBER=${PEER2_AS}    BGP_RIB=${RIB_NAME}
+    TemplatedRequests.Put_As_Xml_Templated    ${GR_FOLDER}${/}${folder}peers    mapping=${mapping}    session=${CONFIG_SESSION}
+
+Delete_Bgp_Peers_Configuration
+    [Documentation]    Revert the BGP configuration to the original state: without any configured peers.
+    &{mapping}    BuiltIn.Create_Dictionary    IP=${PEER1_IP}    BGP_RIB=${RIB_NAME}
+    TemplatedRequests.Delete_Templated    ${GR_FOLDER}${/}peers    mapping=${mapping}    session=${CONFIG_SESSION}
+    &{mapping}    BuiltIn.Create_Dictionary    IP=${PEER2_IP}    BGP_RIB=${RIB_NAME}
+    TemplatedRequests.Delete_Templated    ${GR_FOLDER}${/}peers    mapping=${mapping}    session=${CONFIG_SESSION}
+
+Post_Graceful_Restart
+    [Arguments]    ${ip}=${PEER1_IP}
+    [Documentation]    Post rpc to odl, effectively restarting it.
+    &{mapping}    BuiltIn.Create_Dictionary    IP=${ip}    BGP_RIB=${RIB_NAME}
+    TemplatedRequests.Post_As_Xml_Templated    ${GR_FOLDER}${/}restart    mapping=${mapping}    session=${CONFIG_SESSION}
index a45fffd95ef9dcf9fb8f110a3493c1d7d4a6c8f2..81617b21ccc83fd11efc6c7954622648c04bc5f8 100644 (file)
@@ -23,5 +23,6 @@ integration/test/csit/suites/bgpcep/bgpfunct/060_bgp_functional_mvpn.robot
 integration/test/csit/suites/bgpcep/bgpfunct/070_bgp_functional_l3vpn_mcast.robot
 integration/test/csit/suites/bgpcep/bgpfunct/080_bgp_functional_rt_constrain.robot
 integration/test/csit/suites/bgpcep/bgpfunct/090_bgp_functional_rt_constrain_validation.robot
+integration/test/csit/suites/bgpcep/bgpfunct/100_bgp_functional_graceful_restart.robot
 integration/test/csit/suites/bgpcep/bgpfunct/bgp_policies_default.robot
 integration/test/csit/suites/bgpcep/tcpmd5user/tcpmd5user.robot
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/data.json b/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/data.json
new file mode 100644 (file)
index 0000000..b8ee584
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "tables": [
+    {
+      "afi": "bgp-types:ipv6-address-family",
+      "safi": "bgp-types:unicast-subsequent-address-family",
+      "attributes": {
+        "uptodate": "*"
+      }
+    }
+  ]
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/location.uri b/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/location.uri
new file mode 100644 (file)
index 0000000..1d7830b
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv6-address-family/bgp-types:unicast-subsequent-address-family/
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/volatiles.list b/csit/variables/bgpfunctional/graceful_restart/empty_ipv6_route/volatiles.list
new file mode 100644 (file)
index 0000000..e207934
--- /dev/null
@@ -0,0 +1 @@
+uptodate
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_route/data.json b/csit/variables/bgpfunctional/graceful_restart/empty_route/data.json
new file mode 100644 (file)
index 0000000..ee14cf4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "tables": [
+    {
+      "afi": "bgp-types:ipv4-address-family",
+      "safi": "bgp-types:unicast-subsequent-address-family",
+      "attributes": {
+        "uptodate": "*"
+      }
+    }
+  ]
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_route/location.uri b/csit/variables/bgpfunctional/graceful_restart/empty_route/location.uri
new file mode 100644 (file)
index 0000000..6a0a99b
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/
diff --git a/csit/variables/bgpfunctional/graceful_restart/empty_route/volatiles.list b/csit/variables/bgpfunctional/graceful_restart/empty_route/volatiles.list
new file mode 100644 (file)
index 0000000..e207934
--- /dev/null
@@ -0,0 +1 @@
+uptodate
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_1/data.json b/csit/variables/bgpfunctional/graceful_restart/ipv4_1/data.json
new file mode 100644 (file)
index 0000000..6eaf440
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "bgp-inet:ipv4-routes": {
+        "ipv4-route": [
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.0/28",
+                "prefix": "8.1.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            }
+        ]
+    }
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_1/location.uri b/csit/variables/bgpfunctional/graceful_restart/ipv4_1/location.uri
new file mode 100644 (file)
index 0000000..0a87e72
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/data.json b/csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/data.json
new file mode 100644 (file)
index 0000000..0ffe7b9
--- /dev/null
@@ -0,0 +1,52 @@
+{
+    "bgp-inet:ipv4-routes": {
+        "ipv4-route": [
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.0/28",
+                "prefix": "8.1.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                "path-id": 0,
+                "route-key": "8.2.0.0/28",
+                "prefix": "8.2.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65001
+                                ]
+                            }
+                        ]
+                    }
+                }
+            }
+        ]
+    }
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/location.uri b/csit/variables/bgpfunctional/graceful_restart/ipv4_1_1/location.uri
new file mode 100644 (file)
index 0000000..0a87e72
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_2/data.json b/csit/variables/bgpfunctional/graceful_restart/ipv4_2/data.json
new file mode 100644 (file)
index 0000000..8f07fc7
--- /dev/null
@@ -0,0 +1,52 @@
+{
+    "bgp-inet:ipv4-routes": {
+        "ipv4-route": [
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.0/28",
+                "prefix": "8.1.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.16/28",
+                "prefix": "8.1.0.16/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            }
+        ]
+    }
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_2/location.uri b/csit/variables/bgpfunctional/graceful_restart/ipv4_2/location.uri
new file mode 100644 (file)
index 0000000..0a87e72
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/data.json b/csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/data.json
new file mode 100644 (file)
index 0000000..bf4725a
--- /dev/null
@@ -0,0 +1,75 @@
+{
+    "bgp-inet:ipv4-routes": {
+        "ipv4-route": [
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.0/28",
+                "prefix": "8.1.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                "path-id": 0,
+                "route-key": "8.1.0.16/28",
+                "prefix": "8.1.0.16/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                "path-id": 0,
+                "route-key": "8.2.0.0/28",
+                "prefix": "8.2.0.0/28",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv4-next-hop": {
+                        "global": "1.1.1.1"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65001
+                                ]
+                            }
+                        ]
+                    }
+                }
+            }
+        ]
+    }
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/location.uri b/csit/variables/bgpfunctional/graceful_restart/ipv4_2_1/location.uri
new file mode 100644 (file)
index 0000000..0a87e72
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv6.hex b/csit/variables/bgpfunctional/graceful_restart/ipv6.hex
new file mode 100644 (file)
index 0000000..265b2bc
--- /dev/null
@@ -0,0 +1 @@
+ffffffffffffffffffffffffffffffff0043020000002c4001010040020602010000fde8800e1c00020110001000000000000000000000000000110030001000000000
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv6_1/data.json b/csit/variables/bgpfunctional/graceful_restart/ipv6_1/data.json
new file mode 100644 (file)
index 0000000..7e69158
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "bgp-inet:ipv6-routes": {
+        "ipv6-route": [
+            {
+                "route-key": "10::/48",
+                "path-id": 0,
+                "prefix": "10::/48",
+                "attributes": {
+                    "origin": {
+                        "value": "igp"
+                    },
+                    "ipv6-next-hop": {
+                        "global": "10::11"
+                    },
+                    "as-path": {
+                        "segments": [
+                            {
+                                "as-sequence": [
+                                    64496,
+                                    65000
+                                ]
+                            }
+                        ]
+                    }
+                }
+            }
+        ]
+    }
+}
diff --git a/csit/variables/bgpfunctional/graceful_restart/ipv6_1/location.uri b/csit/variables/bgpfunctional/graceful_restart/ipv6_1/location.uri
new file mode 100644 (file)
index 0000000..1ce5b5c
--- /dev/null
@@ -0,0 +1 @@
+restconf/operational/bgp-rib:bgp-rib/rib/example-bgp-rib/loc-rib/tables/bgp-types:ipv6-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv6-routes
diff --git a/csit/variables/bgpfunctional/graceful_restart/peers/data.xml b/csit/variables/bgpfunctional/graceful_restart/peers/data.xml
new file mode 100644 (file)
index 0000000..428e6aa
--- /dev/null
@@ -0,0 +1,37 @@
+<neighbor xmlns="urn:opendaylight:params:xml:ns:yang:bgp:openconfig-extensions">
+    <neighbor-address>$IP</neighbor-address>
+    <timers>
+        <config>
+            <hold-time>$HOLDTIME</hold-time>
+            <connect-retry>5</connect-retry>
+        </config>
+    </timers>
+    <transport>
+        <config>
+            <remote-port>$PEER_PORT</remote-port>
+            <passive-mode>true</passive-mode>
+        </config>
+    </transport>
+    <config>
+        <peer-type>EXTERNAL</peer-type>
+        <peer-as>$AS_NUMBER</peer-as>
+    </config>
+    <graceful-restart>
+        <config>
+            <restart-time>5</restart-time>
+        </config>
+    </graceful-restart>
+    <afi-safis>
+        <afi-safi>
+            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV4-UNICAST</afi-safi-name>
+            <graceful-restart>
+                <config>
+                    <enabled>true</enabled>
+                </config>
+            </graceful-restart>
+        </afi-safi>
+        <afi-safi>
+            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV6-UNICAST</afi-safi-name>
+        </afi-safi>
+    </afi-safis>
+</neighbor>
diff --git a/csit/variables/bgpfunctional/graceful_restart/peers/location.uri b/csit/variables/bgpfunctional/graceful_restart/peers/location.uri
new file mode 100644 (file)
index 0000000..2e9bef7
--- /dev/null
@@ -0,0 +1 @@
+restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/protocol/openconfig-policy-types:BGP/$BGP_RIB/bgp/neighbors/neighbor/$IP
diff --git a/csit/variables/bgpfunctional/graceful_restart/restart/location.uri b/csit/variables/bgpfunctional/graceful_restart/restart/location.uri
new file mode 100644 (file)
index 0000000..bd2e7e9
--- /dev/null
@@ -0,0 +1 @@
+restconf/operations/bgp-peer-rpc:restart-gracefully
diff --git a/csit/variables/bgpfunctional/graceful_restart/restart/post_data.xml b/csit/variables/bgpfunctional/graceful_restart/restart/post_data.xml
new file mode 100644 (file)
index 0000000..a3b09ea
--- /dev/null
@@ -0,0 +1,4 @@
+<input xmlns="urn:opendaylight:params:xml:ns:yang:bgp-peer-rpc">
+    <peer-ref xmlns:rib="urn:opendaylight:params:xml:ns:yang:bgp-rib">/rib:bgp-rib/rib:rib[rib:id="$BGP_RIB"]/rib:peer[rib:peer-id="bgp://$IP"]</peer-ref>
+    <selection-deferral-time>5</selection-deferral-time>
+</input>
diff --git a/csit/variables/bgpfunctional/graceful_restart/tc1/tc1.hex b/csit/variables/bgpfunctional/graceful_restart/tc1/tc1.hex
new file mode 100644 (file)
index 0000000..606debb
--- /dev/null
@@ -0,0 +1 @@
+ffffffffffffffffffffffffffffffff003d0104fbf000b4c000020220021e41040000fbf0060002000104000200010104000100014006000500010100
diff --git a/csit/variables/bgpfunctional/graceful_restart/tc3/tc3.hex b/csit/variables/bgpfunctional/graceful_restart/tc3/tc3.hex
new file mode 100644 (file)
index 0000000..606debb
--- /dev/null
@@ -0,0 +1 @@
+ffffffffffffffffffffffffffffffff003d0104fbf000b4c000020220021e41040000fbf0060002000104000200010104000100014006000500010100
diff --git a/csit/variables/bgpfunctional/graceful_restart/tc4/tc4.hex b/csit/variables/bgpfunctional/graceful_restart/tc4/tc4.hex
new file mode 100644 (file)
index 0000000..6fd5e41
--- /dev/null
@@ -0,0 +1 @@
+ffffffffffffffffffffffffffffffff003d0104fbf000b4c000020220021e41040000fbf0060002000104000200010104000100014006800500010180
diff --git a/csit/variables/bgpfunctional/graceful_restart/tc5/tc5.hex b/csit/variables/bgpfunctional/graceful_restart/tc5/tc5.hex
new file mode 100644 (file)
index 0000000..6fd5e41
--- /dev/null
@@ -0,0 +1 @@
+ffffffffffffffffffffffffffffffff003d0104fbf000b4c000020220021e41040000fbf0060002000104000200010104000100014006800500010180
index 728af5e75ff0668a1dbdb5a1a0cc0a0324215485..d04e2e75e7687127198bd4b07b656f5f846f9fed 100755 (executable)
@@ -163,6 +163,11 @@ def parse_arguments():
     str_help = "Open message includes Multicast in MPLS/BGP IP VPNs arguments.\
     Enabling this flag makes the script not decoding the update mesage, because of not\
     supported decoding for these elements."
+    parser.add_argument("--grace", default="8", type=int, help=str_help)
+    str_help = "Open message includes Graceful-restart capability, containing AFI/SAFIS:\
+    IPV4-Unicast, IPV6-Unicast, BGP-LS\
+    Enabling this flag makes the script not decoding the update mesage, because of not\
+    supported decoding for these elements."
     parser.add_argument("--mvpn", default=False, action="store_true", help=str_help)
     str_help = "Open message includes L3VPN-MULTICAST arguments.\
     Enabling this flag makes the script not decoding the update mesage, because of not\
@@ -172,6 +177,8 @@ def parse_arguments():
     parser.add_argument("--l3vpn", default=False, action="store_true", help=str_help)
     str_help = "Open message includes ROUTE-TARGET-CONSTRAIN arguments, without message decoding."
     parser.add_argument("--rt_constrain", default=False, action="store_true", help=str_help)
+    str_help = "Open message includes ipv6-unicast family, without message decoding."
+    parser.add_argument("--ipv6", default=False, action="store_true", help=str_help)
     str_help = "Add all supported families without message decoding."
     parser.add_argument("--allf", default=False, action="store_true", help=str_help)
     parser.add_argument("--wfr", default=10, type=int, help="Wait for read timeout")
@@ -378,8 +385,10 @@ class MessageGenerator(object):
         self.l3vpn_mcast = args.l3vpn_mcast
         self.l3vpn = args.l3vpn
         self.rt_constrain = args.rt_constrain
+        self.ipv6 = args.ipv6
         self.allf = args.allf
         self.skipattr = args.skipattr
+        self.grace = args.grace
         # Default values when BGP-LS Attributes are used
         if self.bgpls:
             self.prefix_count_to_add_default = 1
@@ -822,6 +831,18 @@ class MessageGenerator(object):
             )
             optional_parameters_hex += optional_parameter_hex
 
+        if self.ipv6 or self.allf:
+            optional_parameter_hex = (
+                "\x02"  # Param type ("Capability Ad")
+                "\x06"  # Length (6 bytes)
+                "\x01"  # Multiprotocol extetension capability,
+                "\x04"  # Capability value length
+                "\x00\x02"  # AFI (IPV6)
+                "\x00"  # (reserved)
+                "\x01"  # SAFI (UNICAST)
+            )
+            optional_parameters_hex += optional_parameter_hex
+
         if self.bgpls or self.allf:
             optional_parameter_hex = (
                 "\x02"  # Param type ("Capability Ad")
@@ -937,6 +958,39 @@ class MessageGenerator(object):
         )
         optional_parameters_hex += optional_parameter_hex
 
+        if self.grace != 8:
+            b = list(bin(self.grace)[2:])
+            b = b + [0] * (3 - len(b))
+            length = "\x08"
+            if b[1] == '1':
+                restart_flag = "\x80\x05"
+            else:
+                restart_flag = "\x00\x05"
+            if b[2] == '1':
+                ipv4_flag = "\x80"
+            else:
+                ipv4_flag = "\x00"
+            if b[0] == '1':
+                ll_gr = "\x47\x07\x00\x01\x01\x00\x00\x00\x1e"
+                length = "\x11"
+            else:
+                ll_gr = ""
+            logger.debug("Grace parameters list: {}".format(b))
+            # "\x02" Param type ("Capability Ad")
+            # :param length: Length of whole message
+            # "\x40" Graceful-restart capability
+            # "\x06" Length (6 bytes)
+            # "\x00" Restart Flag (customizable - turned on when grace == 2,3,6,7)
+            # "\x05" Restart timer (5sec)
+            # "\x00\x01" AFI (IPV4)
+            # "\x01"  SAFI (Unicast)
+            # "\x00"  Ipv4 Flag (customizable - turned on when grace == 1,3,5,7)
+            # "\x47\x07\x00\x01\x01\x00\x00\x00\x1e" ipv4 ll-graceful-restart capability, timer 30sec
+            # ll-gr turned on when grace is between 4-7
+            optional_parameter_hex = "\x02{}\x40\x06{}\x00\x01\x01{}{}".format(
+                length, restart_flag, ipv4_flag, ll_gr)
+            optional_parameters_hex += optional_parameter_hex
+
         # Optional Parameters Length
         optional_parameters_length = len(optional_parameters_hex)
         optional_parameters_length_hex = struct.pack("B",
@@ -1157,6 +1211,9 @@ class MessageGenerator(object):
             nlri_hex
         )
 
+        if self.grace != 8 and self.grace != 0 and end_of_rib:
+            message_hex = (marker_hex + binascii.unhexlify("00170200000000"))
+
         if self.log_debug:
             logger.debug("UPDATE message encoding")
             logger.debug("  Marker=0x" + binascii.hexlify(marker_hex))
@@ -1382,7 +1439,7 @@ class ReadTracker(object):
 
     def __init__(self, bgp_socket, timer, storage, evpn=False, mvpn=False,
                  l3vpn_mcast=False, allf=False, l3vpn=False, rt_constrain=False,
-                 wait_for_read=10):
+                 ipv6=False, grace=8, wait_for_read=10):
         """The reader initialisation.
 
         Arguments:
@@ -1391,6 +1448,7 @@ class ReadTracker(object):
             storage: thread safe dict
             evpn: flag that evpn functionality is tested
             mvpn: flag that mvpn functionality is tested
+            grace: flag that grace-restart functionality is tested
             l3vpn_mcast: flag that l3vpn_mcast functionality is tested
             l3vpn: flag that l3vpn unicast functionality is tested
             rt_constrain: flag that rt-constrain functionality is tested
@@ -1421,8 +1479,10 @@ class ReadTracker(object):
         self.l3vpn_mcast = l3vpn_mcast
         self.l3vpn = l3vpn
         self.rt_constrain = rt_constrain
+        self.ipv6 = ipv6
         self.allf = allf
         self.wfr = wait_for_read
+        self.grace = grace
 
     def read_message_chunk(self):
         """Read up to one message
@@ -1630,6 +1690,11 @@ class ReadTracker(object):
             logger.debug("Skipping update decoding due to evpn data expected")
             return
 
+        logger.debug("Graceful-restart {}".format(self.grace))
+        if self.grace != 8:
+            logger.debug("Skipping update decoding due to graceful-restart data expected")
+            return
+
         logger.debug("Mvpn {}".format(self.mvpn))
         if self.mvpn:
             logger.debug("Skipping update decoding due to mvpn data expected")
@@ -1650,6 +1715,11 @@ class ReadTracker(object):
             logger.debug("Skipping update decoding due to Route-Target-Constrain data expected")
             return
 
+        logger.debug("Ipv6-Unicast {}".format(self.ipv6))
+        if self.ipv6:
+            logger.debug("Skipping update decoding due to Ipv6 data expected")
+            return
+
         logger.debug("Allf {}".format(self.allf))
         if self.allf:
             logger.debug("Skipping update decoding")
@@ -1821,7 +1891,8 @@ class StateTracker(object):
         # Sub-trackers.
         self.reader = ReadTracker(bgp_socket, timer, storage, evpn=cliargs.evpn, mvpn=cliargs.mvpn,
                                   l3vpn_mcast=cliargs.l3vpn_mcast, l3vpn=cliargs.l3vpn, allf=cliargs.allf,
-                                  rt_constrain=cliargs.rt_constrain, wait_for_read=cliargs.wfr)
+                                  rt_constrain=cliargs.rt_constrain, ipv6=cliargs.ipv6, grace=cliargs.grace,
+                                  wait_for_read=cliargs.wfr)
         self.writer = WriteTracker(bgp_socket, generator, timer)
         # Prioritization state.
         self.prioritize_writing = False
@@ -1965,6 +2036,8 @@ def job(arguments, inqueue, storage):
     # FIXME: Add parameter to send default open message first,
     # to work with "you first" peers.
     msg_in = read_open_message(bgp_socket)
+    logger.info(binascii.hexlify(msg_in))
+    storage['open'] = binascii.hexlify(msg_in)
     timer = TimeTracker(msg_in)
     generator = MessageGenerator(arguments)
     msg_out = generator.open_message()