Skip to content

Commit

Permalink
lib, tests: Add topotest for srv6 static local SID
Browse files Browse the repository at this point in the history
Add topotest zebra_static_opcode_sid to check whether
static opcode can be configured manually and generate mySID properly.
Besides, supplement JSON display for these sids info.
The corresponding command is "show segment-rouing srv6 locator NAME detail json".

Signed-off-by: Yuqing Zhao <[email protected]>
  • Loading branch information
GaladrielZhao authored and zice312963205 committed Nov 28, 2024
1 parent c4f9ee1 commit 399547f
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 0 deletions.
33 changes: 33 additions & 0 deletions lib/srv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,27 @@ srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk)
return jo_root;
}

json_object *srv6_locator_sid_detailed_json(const struct srv6_locator *locator,
const struct seg6_sid *sid)
{
json_object *jo_root = NULL;
char buf[256];

jo_root = json_object_new_object();

/* set opcode */
prefix2str(&sid->ipv6Addr, buf, sizeof(buf));
json_object_string_add(jo_root, "opcode", buf);

/* set sidaction */
json_object_string_add(jo_root, "sidaction", seg6local_action2str(sid->sidaction));

/* set vrf */
json_object_string_add(jo_root, "vrf", sid->vrfName);

return jo_root;
}

json_object *srv6_locator_json(const struct srv6_locator *loc)
{
struct listnode *node;
Expand Down Expand Up @@ -392,10 +413,14 @@ json_object *srv6_locator_json(const struct srv6_locator *loc)
json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
{
struct listnode *node;
struct listnode *sidnode;
struct srv6_locator_chunk *chunk;
struct seg6_sid *sid = NULL;
json_object *jo_root = NULL;
json_object *jo_chunk = NULL;
json_object *jo_chunks = NULL;
json_object *jo_sid = NULL;
json_object *jo_sids = NULL;

jo_root = json_object_new_object();

Expand Down Expand Up @@ -461,5 +486,13 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
json_object_array_add(jo_chunks, jo_chunk);
}

/* set sids */
jo_sids = json_object_new_array();
json_object_object_add(jo_root, "sids", jo_sids);
for (ALL_LIST_ELEMENTS_RO(loc->sids, sidnode, sid)) {
jo_sid = srv6_locator_sid_detailed_json(loc, sid);
json_object_array_add(jo_sids, jo_sid);
}

return jo_root;
}
2 changes: 2 additions & 0 deletions lib/srv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ json_object *srv6_locator_json(const struct srv6_locator *loc);
json_object *srv6_locator_detailed_json(const struct srv6_locator *loc);
json_object *
srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk);
json_object *srv6_locator_sid_detailed_json(const struct srv6_locator *locator,
const struct seg6_sid *sid);

extern struct srv6_sid_format *srv6_sid_format_alloc(const char *name);
extern void srv6_sid_format_free(struct srv6_sid_format *format);
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions tests/topotests/zebra_static_opcode_sid/r1/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
router bgp 65000
no bgp ebgp-requires-policy
timers bgp start-timer 0
neighbor aaa peer-group
neighbor aaa remote-as 65001
neighbor 192.168.254.2 peer-group aaa
neighbor 192.168.255.2 remote-as 65001
neighbor 192.168.255.2 timers 3 10
exit-address-family
!
9 changes: 9 additions & 0 deletions tests/topotests/zebra_static_opcode_sid/r1/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!
interface r1-eth0
ip address 192.168.255.1/24
!
interface r1-eth1
ip address 192.168.254.1/24
!
ip forwarding
!
10 changes: 10 additions & 0 deletions tests/topotests/zebra_static_opcode_sid/r2/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
router bgp 65001
no bgp ebgp-requires-policy
timers bgp start-timer 0
neighbor aaa peer-group
neighbor aaa remote-as 65000
neighbor 192.168.254.1 peer-group aaa
neighbor 192.168.255.1 remote-as 65000
neighbor 192.168.255.1 timers 3 10
exit-address-family
!
9 changes: 9 additions & 0 deletions tests/topotests/zebra_static_opcode_sid/r2/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!
interface r2-eth0
ip address 192.168.255.2/24
!
interface r2-eth1
ip address 192.168.254.2/24
!
ip forwarding
!
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
"""
test_zebra_static_opcode_sid.py
Test if works the following commands:
segment-routing
srv6
locators
locator loc1
prefix fd00:201:201::/48 block-len 32 node-len 16 func-bits 16
opcode ::fff1:11:0:0:0 end-dt46 vrf Vrf1
opcode ::fff1:12:0:0:0 end-dt46 vrf Vrf2
Test contains two parts:
- Verify that the static opcode is configured and generates mySID correctly.
- Ensure that the opcode and the corresponding SID can be removed properly.
"""

import os
import sys
import json
import pytest
import functools

CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))

# pylint: disable=C0413
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from lib.common_config import step


def build_topo(tgen):
for routern in range(1, 3):
tgen.add_router("r{}".format(routern))

switch = tgen.add_switch("s1")
switch.add_link(tgen.gears["r1"])
switch.add_link(tgen.gears["r2"])

switch = tgen.add_switch("s2")
switch.add_link(tgen.gears["r1"])
switch.add_link(tgen.gears["r2"])


def setup_module(mod):
tgen = Topogen(build_topo, mod.__name__)
tgen.start_topology()

router_list = tgen.routers()

for i, (rname, router) in enumerate(router_list.items(), 1):
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
router.load_config(
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
)

tgen.start_router()


def teardown_module(mod):
tgen = get_topogen()
tgen.stop_topology()


def test_zebra_static_opcode_sid():
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
r1 = tgen.gears['r1']

def _zebra_conf_static_opcode(router, locator_conf_args):
router.vtysh_cmd(locator_conf_args)


def _zebra_check_static_opcode_sids(router, cmd_args, expected_args):
output = json.loads(router.vtysh_cmd(cmd_args))
return topotest.json_cmp(output, expected_args)


locator_conf_args = """
configure terminal
segment-routing
srv6
locators
locator loc1
prefix fd00:202:202::/48 block-len 32 node-len 16 func-bits 16
opcode ::fff1:11:0:0:0 end-dt46 vrf Vrf1
opcode ::fff1:12:0:0:0 end-dt46 vrf Vrf2
"""
locator_rm_conf_args = """
configure terminal
segment-routing
srv6
locators
locator loc1
prefix fd00:202:202::/48 block-len 32 node-len 16 func-bits 16
no opcode ::fff1:11:0:0:0
no opcode ::fff1:12:0:0:0
"""
cmd_args = "show segment-routing srv6 locator loc1 detail json"
expected_sids_args = {
"name":"loc1",
"prefix":"fd00:202:202::/48",
"blockBitsLength":32,
"nodeBitsLength":16,
"functionBitsLength":16,
"argumentBitsLength":0,
"algoNum":0,
"statusUp":True,
"chunks":[
{
"prefix":"fd00:202:202::/48",
"blockBitsLength":0,
"nodeBitsLength":0,
"functionBitsLength":0,
"argumentBitsLength":0,
"keep":0,
"proto":"system",
"instance":0,
"sessionId":0
}
],
"sids":[
{
"opcode":"::fff1:11:0:0:0/128",
"sidaction":"End.DT46",
"vrf":"Vrf1"
},
{
"opcode":"::fff1:12:0:0:0/128",
"sidaction":"End.DT46",
"vrf":"Vrf2"
}
]
}
expected_no_sids_args = {
"name":"loc1",
"prefix":"fd00:202:202::/48",
"blockBitsLength":32,
"nodeBitsLength":16,
"functionBitsLength":16,
"argumentBitsLength":0,
"algoNum":0,
"statusUp":True,
"chunks":[
{
"prefix":"fd00:202:202::/48",
"blockBitsLength":0,
"nodeBitsLength":0,
"functionBitsLength":0,
"argumentBitsLength":0,
"keep":0,
"proto":"system",
"instance":0,
"sessionId":0
}
],
"sids":[
]
}


step("Configure the static opcode for locator loc1 on router1")
_zebra_conf_static_opcode(r1, locator_conf_args)

step("Check mySID (ADD)")
test_func = functools.partial(_zebra_check_static_opcode_sids, r1,
cmd_args, expected_sids_args)
_, result = topotest.run_and_expect(test_func, None, count=5, wait=5)

assert result is None, 'Failed to add static opcode'

step("Remove the static opcode for locator loc1 on router1")
_zebra_conf_static_opcode(r1, locator_rm_conf_args)

step("Check mySID (DEL)")
test_func = functools.partial(_zebra_check_static_opcode_sids, r1,
cmd_args, expected_no_sids_args)
_, result = topotest.run_and_expect(test_func, None, count=5, wait=5)

assert result is None, 'Failed to remove static opcode'


if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

0 comments on commit 399547f

Please sign in to comment.