Skip to content

Commit

Permalink
Merge pull request FRRouting#16399 from FRRouting/mergify/bp/dev/10.1…
Browse files Browse the repository at this point in the history
…/pr-16374

bgpd: Mark VRF instance as auto created if import vrf is configured for this instance (backport FRRouting#16374)
  • Loading branch information
Jafaral authored Jul 17, 2024
2 parents e014a46 + 2ab249e commit b139113
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 2 deletions.
28 changes: 26 additions & 2 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,10 @@ DEFUN (no_router_bgp,
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) {
if (tmp_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
continue;

if (CHECK_FLAG(tmp_bgp->vrf_flags, BGP_VRF_AUTO))
continue;

if (CHECK_FLAG(
tmp_bgp->af_flags[AFI_IP]
[SAFI_UNICAST],
Expand Down Expand Up @@ -10435,12 +10439,20 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,

vrf_bgp = bgp_lookup_by_name(import_name);
if (!vrf_bgp) {
if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) {
vrf_bgp = bgp_default;
else
} else {
/* Auto-create assuming the same AS */
ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type,
NULL, ASNOTATION_UNDEFINED);

/* Auto created VRF instances should be marked
* properly, otherwise we have a state after bgpd
* restart where VRF instance has default VRF's ASN.
*/
SET_FLAG(vrf_bgp->vrf_flags, BGP_VRF_AUTO);
}

if (ret) {
vty_out(vty,
"VRF %s is not configured as a bgp instance\n",
Expand Down Expand Up @@ -12613,6 +12625,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
vty_out(vty, "{\n");

for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
continue;

nbr_output = true;
if (use_json) {
if (!is_first)
Expand Down Expand Up @@ -15994,6 +16009,9 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
vty_out(vty, "{\n");

for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
continue;

nbr_output = true;
if (use_json) {
if (!(json = json_object_new_object())) {
Expand Down Expand Up @@ -16553,6 +16571,9 @@ static int bgp_show_all_instance_route_leak_vty(struct vty *vty, afi_t afi,
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
vrf_name = bgp->name;

if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
continue;

if (use_json) {
json_vrf = json_object_new_object();
} else {
Expand Down Expand Up @@ -16643,6 +16664,9 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
struct bgp *bgp;

for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
continue;

if (!uj)
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
Expand Down
Empty file.
18 changes: 18 additions & 0 deletions tests/topotests/bgp_vrf_different_asn/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
!
vrf vrf100
vni 10100
exit-vrf
!
interface r1-eth0 vrf vrf100
ip address 192.168.1.1/24
!
router bgp 65000
address-family ipv4 unicast
import vrf vrf100
exit-address-family
!
router bgp 65100 vrf vrf100
address-family ipv4 unicast
redistribute connected
exit-address-family
!
107 changes: 107 additions & 0 deletions tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env python
# SPDX-License-Identifier: ISC

#
# Copyright (c) 2024 by
# Donatas Abraitis <[email protected]>
#

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

pytestmark = [pytest.mark.bgpd]


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

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


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

r1 = tgen.gears["r1"]
r1.run("ip link add vrf100 type vrf table 1001")
r1.run("ip link set up dev vrf100")
r1.run("ip link set r1-eth0 master vrf100")

router_list = tgen.routers()

for _, (rname, router) in enumerate(router_list.items(), 1):
router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname)))

tgen.start_router()


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


def test_bgp_vrf_different_asn():
tgen = get_topogen()

if tgen.routers_have_failure():
pytest.skip(tgen.errors)

def _bgp_check_instances():
output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp vrf all json"))
expected = {
"default": {
"vrfName": "default",
"localAS": 65000,
},
"vrf100": {
"vrfName": "vrf100",
"localAS": 65100,
},
}
return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_check_instances)
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Can't see vrf100 to be under 65100 ASN"

def _bgp_check_imported_route():
output = json.loads(
tgen.gears["r1"].vtysh_cmd("show ip route 192.168.1.0/24 json")
)
expected = {
"192.168.1.0/24": [
{
"installed": True,
"selected": True,
"nexthops": [
{
"interfaceName": "vrf100",
"vrf": "vrf100",
"active": True,
}
],
}
]
}
return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_check_imported_route)
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Can't see 192.168.1.0/24 being imported into a default VRF"


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

0 comments on commit b139113

Please sign in to comment.