-
Notifications
You must be signed in to change notification settings - Fork 746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SRv6 uSID BGP L3VPN services #15510
base: master
Are you sure you want to change the base?
SRv6 uSID BGP L3VPN services #15510
Changes from 2 commits
130efb5
0fb8022
c949eeb
caa853c
e0a8962
607be4e
5bc41f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# SRv6 uSID Tests # | ||
|
||
## Outline | ||
|
||
- [Overview](#overview) | ||
- [Scope](#scope) | ||
- [Testbed](#testbed) | ||
- [Setup configuration](#setup-configuration) | ||
- [Test cases](#test-cases) | ||
|
||
## Overview | ||
The purpose of this test is to verify that FRR programs SRv6 SIDs and policies correctly into the SONiC dataplane. | ||
|
||
### Scope | ||
The test is targeting a running SONIC system with fully functioning configuration. The purpose of the test is to test SRv6 uSID functionality. | ||
|
||
### Testbed | ||
The test will run on t0 testbed. | ||
|
||
## Setup configuration | ||
The test requires to configure BGP neighborship between DUT and one neighbor. | ||
|
||
## Test cases | ||
### Test case # 1 - Verify SRv6 uSID BGP L3VPN services | ||
* Configure a BGP session between DUT and one neighbor. | ||
* Setup an SRv6 uSID L3VPN between the DUT and the neighbor. | ||
* Verify that the DUT programs a SID list in the SONiC data plane. | ||
* Verify that the DUT programs a route to steer VPN traffic over the SID list. | ||
* Verify that the DUT programs an SRv6 uDT6 SID to decapsulate and forward the VPN traffic received from the neighbor. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import pytest | ||
import logging | ||
from tests.common.helpers.assertions import pytest_assert as py_assert | ||
|
||
pytestmark = [ | ||
pytest.mark.topology('t0') | ||
] | ||
|
||
Logger = logging.getLogger(__name__) | ||
|
||
V6_PREFIX_NBR = "2001:db8::" | ||
V6_MASK_NBR = "64" | ||
|
||
V6_PREFIX_DUT = "2001:db8:1::" | ||
V6_MASK_DUT = "64" | ||
|
||
|
||
@pytest.fixture(name="setUp", scope="module") | ||
def fixture_setUp(nbrhosts, duthosts, enum_frontend_dut_hostname): | ||
|
||
# pick dut | ||
duthost = duthosts[enum_frontend_dut_hostname] | ||
|
||
# pick one neighbor | ||
nbr = None | ||
nbrnames = list(nbrhosts.keys()) | ||
for name in nbrnames: | ||
if 'T1' in name: | ||
nbr = nbrhosts[name] | ||
break | ||
py_assert(nbr is not None, "No T1 neighbors") | ||
|
||
yield (nbr, duthost) | ||
|
||
Logger.info("Performing cleanup") | ||
|
||
# cleanup neighbor | ||
cmd = "config vrf del Vrf10" | ||
nbr['host'].shell(cmd) | ||
|
||
# cleanup dut | ||
duthost = duthosts[enum_frontend_dut_hostname] | ||
cmd = "config vrf del Vrf10" | ||
duthost.shell(cmd) | ||
|
||
|
||
def run_srv6(enum_frontend_dut_hostname, hosts): | ||
""" Route added on All neighbor should be learned by the DUT""" | ||
Logger.info("Adding routes on neighbors") | ||
|
||
nbr = hosts[0] | ||
duthost = hosts[1] | ||
|
||
# configure bgp on neighbor | ||
cmd = "config vrf add Vrf10" | ||
nbr['host'].shell(cmd) | ||
cmd = "config loopback add Loopback1" | ||
nbr['host'].shell(cmd) | ||
cmd = "config interface vrf bind Loopback1 Vrf10" | ||
nbr['host'].shell(cmd) | ||
cmd = "config interface ip add Loopback1 2001:db8:2::1" | ||
nbr['host'].shell(cmd) | ||
cmd = ("vtysh" | ||
" -c 'configure'" | ||
" -c 'ipv6 route {}/{} Loopback1'" | ||
" -c 'segment-routing'" | ||
" -c 'srv6'" | ||
" -c 'locators'" | ||
" -c 'locator MAIN'" | ||
" -c 'prefix fcbb:bbbb:1::/48 block-len 32 node-len 16 func-bits 16'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'router bgp 64600'" | ||
" -c 'address-family ipv6 unicast'" | ||
" -c 'network {}/{}'" | ||
" -c 'exit'" | ||
" -c 'segment-routing srv6'" | ||
" -c 'locator MAIN'" | ||
" -c 'exit'" | ||
" -c 'router bgp 64600 vrf Vrf10'" | ||
" -c 'address-family ipv6 unicast'" | ||
" -c 'sid vpn export auto'" | ||
" -c 'rd vpn export 1:10'" | ||
" -c 'rt vpn both 99:99'" | ||
" -c 'import vpn'" | ||
" -c 'export vpn'" | ||
" -c 'redistribute connected'" | ||
" -c 'exit'" | ||
" -c 'exit'").format(V6_PREFIX_NBR, V6_MASK_NBR, V6_PREFIX_NBR, V6_MASK_NBR) | ||
nbr['host'].shell(cmd) | ||
Logger.info("Route %s added", V6_PREFIX_NBR) | ||
|
||
# configure bgp on dut | ||
cmd = "config vrf add Vrf10" | ||
duthost.shell(cmd) | ||
cmd = "config loopback add Loopback1" | ||
duthost.shell(cmd) | ||
cmd = "config interface vrf bind Loopback1 Vrf10" | ||
duthost.shell(cmd) | ||
cmd = "config interface ip add Loopback1 2001:db8:2::1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. although this may not have any functional impact, but we'd better use a different Loopback address for DUT instead of reusing the Loopback address. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with your point. I assigned the neighbor a Loopback address different from the DUT |
||
duthost.shell(cmd) | ||
cmd = ("vtysh" | ||
" -c 'configure'" | ||
" -c 'ipv6 route {}/{} Loopback1'" | ||
" -c 'segment-routing'" | ||
" -c 'srv6'" | ||
" -c 'locators'" | ||
" -c 'locator MAIN'" | ||
" -c 'prefix fcbb:bbbb:2::/48 block-len 32 node-len 16 func-bits 16'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'exit'" | ||
" -c 'router bgp 65100'" | ||
" -c 'address-family ipv6 unicast'" | ||
" -c 'network {}/{}'" | ||
" -c 'exit'" | ||
" -c 'segment-routing srv6'" | ||
" -c 'locator MAIN'" | ||
" -c 'exit'" | ||
" -c 'router bgp 65100 vrf Vrf10'" | ||
" -c 'address-family ipv6 unicast'" | ||
" -c 'sid vpn export auto'" | ||
" -c 'rd vpn export 2:10'" | ||
" -c 'rt vpn both 99:99'" | ||
" -c 'import vpn'" | ||
" -c 'export vpn'" | ||
" -c 'redistribute connected'" | ||
" -c 'exit'" | ||
" -c 'exit'").format(V6_PREFIX_DUT, V6_MASK_DUT, V6_PREFIX_DUT, V6_MASK_DUT) | ||
duthost.shell(cmd) | ||
Logger.info("Route %s added to :duthost", V6_PREFIX_DUT) | ||
|
||
# check ROUTE_TABLE | ||
Logger.info("checking DUT for route %s", V6_PREFIX_NBR) | ||
cmd = "redis-cli -n 0 hgetall \"ROUTE_TABLE:Vrf10:{}\"".format(V6_PREFIX_NBR) | ||
result = duthost.shell(cmd) | ||
result = result['stdout'] | ||
Logger.info("Route table nexthops are %s", result) | ||
py_assert(result != "", "The DUT did not program the SRv6 steering route") | ||
py_assert("segments: Vrf10:2001:db8::/64" not in result, | ||
"The DUT did not program the SRv6 steering route correctly, missing 'segments' field") | ||
py_assert("source: fc00:0:1::1" not in result, | ||
"The DUT did not program the SRv6 steering route correctly, missing 'source' field") | ||
|
||
# check SRV6_SID_LIST_TABLE | ||
Logger.info("checking DUT for route %s", V6_PREFIX_NBR) | ||
cmd = "redis-cli -n 0 hgetall \"SRV6_SID_LIST_TABLE:Vrf10:{}\"".format(V6_PREFIX_NBR) | ||
result = duthost.shell(cmd) | ||
result = result['stdout'] | ||
Logger.info("Route table nexthops are %s", result) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The log statements seems to be not updated accordingly? You are checking SID_LIST_TABLE here right? The log statement for MY_SID table seems to be not correct as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, indeed the log statement was incorrect. I fixed it. Thanks. |
||
py_assert(result != "", "The DUT did not program the SRv6 SID list") | ||
py_assert("path: fcbb:bbbb:1:1::" not in result, | ||
"The DUT did not program the SRv6 SID list correctly, missing 'path' field") | ||
|
||
# check SRV6_MY_SID_TABLE | ||
Logger.info("checking DUT for route %s", V6_PREFIX_NBR) | ||
cmd = "redis-cli -n 0 hgetall \"SRV6_MY_SID_TABLE:32:16:16:0:fcbb:bbbb:2:1::\"" | ||
result = duthost.shell(cmd) | ||
result = result['stdout'] | ||
Logger.info("Route table nexthops are %s", result) | ||
py_assert(result != "", "The DUT did not program SRv6 MySid entry") | ||
py_assert("action: udt6" not in result, "The DUT did not program SRv6 MySid entry, missing 'action' field") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where do you configure the udt6 action? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uDT6 SID is created automatically by BGP. When you set |
||
py_assert("vrf: Vrf10" not in result, "The DUT did not program SRv6 MySid entry correcly, missing 'vrf' field") | ||
|
||
|
||
def test_srv6(enum_frontend_dut_hostname, setUp): | ||
run_srv6(enum_frontend_dut_hostname, setUp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we configure the BGP session in this FRR config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the FRR config, the line below configures the BGP session with the other node.