Merge pull request #9783 from mjstapp/fix_bgp_lu_lsp

bgpd, tests: BGP-labeled-unicast advertise implicit-null in more cases
This commit is contained in:
Russ White 2021-10-20 18:22:01 -04:00 committed by GitHub
commit 61a7ec774c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 468 additions and 8 deletions

View File

@ -244,6 +244,10 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,
p = bgp_dest_get_prefix(dest);
if (BGP_DEBUG(labelpool, LABELPOOL))
zlog_debug("%s: %pFX: %s ", __func__, p,
(reg ? "reg" : "dereg"));
if (reg) {
assert(pi);
/*

View File

@ -2711,6 +2711,28 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
}
/*
* Utility to determine whether a particular path_info should use
* the IMPLICIT_NULL label. This is pretty specialized: it's only called
* in a path where we basically _know_ this is a BGP-LU route.
*/
static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
{
/* Certain types get imp null; so do paths where the nexthop is
* not labeled.
*/
if (new_select->sub_type == BGP_ROUTE_STATIC
|| new_select->sub_type == BGP_ROUTE_AGGREGATE
|| new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
return true;
else if (new_select->extra == NULL ||
!bgp_is_valid_label(&new_select->extra->label[0]))
/* TODO -- should be configurable? */
return true;
else
return false;
}
/*
* old_select = The old best path
* new_select = the new best path
@ -2802,11 +2824,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
* implicit-null for local routes, aggregate
* and redistributed routes
*/
if (new_select->sub_type == BGP_ROUTE_STATIC
|| new_select->sub_type
== BGP_ROUTE_AGGREGATE
|| new_select->sub_type
== BGP_ROUTE_REDISTRIBUTE) {
if (bgp_lu_need_imp_null(new_select)) {
if (CHECK_FLAG(
dest->flags,
BGP_NODE_REGISTERED_FOR_LABEL)

View File

@ -1,8 +1,8 @@
{
"Ledger":506,
"InUse":506,
"Ledger":0,
"InUse":0,
"Requests":0,
"LabelChunks":11,
"LabelChunks":0,
"Pending":0,
"Reconnects":0
}

View File

@ -0,0 +1,29 @@
!
no log unique-id
!
debug bgp labelpool
debug bgp zebra
!
router bgp 1
bgp router-id 10.0.0.1
timers bgp 3 9
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 10.0.0.2 remote-as 2
! neighbor 10.0.0.2 solo
neighbor 10.0.0.2 timers connect 10
neighbor 10.0.4.4 remote-as 4
! neighbor 10.0.4.4 solo
neighbor 10.0.4.4 timers connect 10
!
address-family ipv4 unicast
no neighbor 10.0.0.2 activate
no neighbor 10.0.4.4 activate
redistribute connected
exit-address-family
!
address-family ipv4 labeled-unicast
neighbor 10.0.0.2 activate
neighbor 10.0.4.4 activate
exit-address-family
!

View File

@ -0,0 +1,8 @@
{
"Ledger":51,
"InUse":51,
"Requests":0,
"LabelChunks":2,
"Pending":0,
"Reconnects":0
}

View File

@ -0,0 +1,13 @@
!
no log unique-id
!
debug zebra events
debug zebra rib det
debug zebra dplane
debug zebra mpls
!
interface R1-eth0
ip address 10.0.0.1/24
!
interface R1-eth1
ip address 10.0.4.1/24

View File

@ -0,0 +1,27 @@
!
no log unique-id
!
debug bgp labelpool
debug bgp zebra
!
router bgp 2
bgp router-id 10.0.0.2
no bgp ebgp-requires-policy
no bgp network import-check
timers bgp 3 9
neighbor 10.0.0.1 remote-as 1
neighbor 10.0.0.1 timers connect 10
neighbor 10.0.1.3 remote-as 2
neighbor 10.0.1.3 update-source 10.0.1.2
neighbor 10.0.1.3 timers connect 10
!
address-family ipv4 unicast
network 10.0.0.0/24
neighbor 10.0.1.3 activate
no neighbor 10.0.0.1 activate
exit-address-family
!
address-family ipv4 labeled-unicast
neighbor 10.0.0.1 activate
exit-address-family
!

View File

@ -0,0 +1,8 @@
{
"Ledger":1,
"InUse":1,
"Requests":0,
"LabelChunks":1,
"Pending":0,
"Reconnects":0
}

View File

@ -0,0 +1,14 @@
!
no log unique-id
!
debug zebra events
debug zebra dplane
debug zebra mpls
debug zebra rib det
!
interface R2-eth0
ip address 10.0.0.2/24
!
interface R2-eth1
ip address 10.0.1.2/24
!

View File

@ -0,0 +1,70 @@
log file /tmp/bgpd.log
no log unique-id
!
!
debug bgp updates
!
router bgp 2
bgp router-id 10.0.1.3
no bgp ebgp-requires-policy
no bgp network import-check
timers bgp 3 9
neighbor 10.0.1.2 remote-as 2
neighbor 10.0.1.2 timers connect 10
!
address-family ipv4 unicast
neighbor 10.0.1.2 activate
network 10.0.1.0/24
network 11.0.0.1/32
network 11.0.0.2/32
network 11.0.0.3/32
network 11.0.0.4/32
network 11.0.0.5/32
network 11.0.0.6/32
network 11.0.0.7/32
network 11.0.0.8/32
network 11.0.0.9/32
network 11.0.0.10/32
network 11.0.0.11/32
network 11.0.0.12/32
network 11.0.0.13/32
network 11.0.0.14/32
network 11.0.0.15/32
network 11.0.0.16/32
network 11.0.0.17/32
network 11.0.0.18/32
network 11.0.0.19/32
network 11.0.0.20/32
network 11.0.0.21/32
network 11.0.0.22/32
network 11.0.0.23/32
network 11.0.0.24/32
network 11.0.0.25/32
network 11.0.0.26/32
network 11.0.0.27/32
network 11.0.0.28/32
network 11.0.0.29/32
network 11.0.0.30/32
network 11.0.0.31/32
network 11.0.0.32/32
network 11.0.0.33/32
network 11.0.0.34/32
network 11.0.0.35/32
network 11.0.0.36/32
network 11.0.0.37/32
network 11.0.0.38/32
network 11.0.0.39/32
network 11.0.0.40/32
network 11.0.0.41/32
network 11.0.0.42/32
network 11.0.0.43/32
network 11.0.0.44/32
network 11.0.0.45/32
network 11.0.0.46/32
network 11.0.0.47/32
network 11.0.0.48/32
network 11.0.0.49/32
network 11.0.0.50/32
exit-address-family
!
!

View File

@ -0,0 +1,5 @@
log file /tmp/staticd.log
no log unique-id
!
!
ip route 10.0.4.0/24 10.0.1.2

View File

@ -0,0 +1,11 @@
log file /tmp/zebra.log
no log unique-id
!
!
debug zebra events
debug zebra packet detail
debug zebra mpls
!
interface R3-eth0
ip address 10.0.1.3/24
!

View File

@ -0,0 +1,23 @@
!
no log unique-id
!
debug bgp labelpool
debug bgp zebra
!
router bgp 4
bgp router-id 10.0.4.4
timers bgp 3 9
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 10.0.4.1 remote-as 1
neighbor 10.0.4.1 solo
neighbor 10.0.4.1 timers connect 10
!
address-family ipv4 unicast
no neighbor 10.0.4.1 activate
exit-address-family
!
address-family ipv4 labeled-unicast
neighbor 10.0.4.1 activate
exit-address-family
!

View File

@ -0,0 +1,9 @@
no log unique-id
!
debug zebra events
debug zebra dplane
debug zebra mpls
debug zebra rib det
!
interface R4-eth0
ip address 10.0.4.4/24

View File

@ -0,0 +1,221 @@
#!/usr/bin/env python
#
# test_bgp_lu2.py
#
# Part of FRR/NetDEF Topology Tests
#
# Copyright (c) 2020 by Volta Networks
# Copyright (c) 2021 by Nvidia, Inc.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
test_bgp_lu2.py: Test BGP LU label allocation
"""
import os
import sys
import json
from functools import partial
import pytest
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
# pylint: disable=C0413
# Import topogen and topotest helpers
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
# Required to instantiate the topology builder class.
pytestmark = [pytest.mark.bgpd]
#
# Basic scenario for BGP-LU. Nodes are directly connected.
# Node 3 is advertising routes to 2, which advertises them
# as BGP-LU to 1; this way we get routes with actual labels, as
# opposed to implicit-null routes in the 2-node case.
#
# R2 is an LER, with MPLS towards R1, and IP towards R3. R1 is an LSR, with
# MPLS on both sides.
#
#
# AS4 BGP-LU AS1 BGP-LU AS2 iBGP AS2
# +-----+ +-----+ +-----+ +-----+
# | |.4 .1| |.1 .2| |.2 .3| |
# | 4 +-------------+ 1 +----------------+ 2 +-----------------+ 3 |
# | | 10.0.4.0/24 | | 10.0.0.0/24 | | 10.0.1.0/24 | |
# +-----+ +-----+ +-----+ +-----+
#
#
def build_topo(tgen):
"Build function"
# This function's only purpose is to define allocation and relationship
# between routers, switches and hosts.
#
#
# Create routers
tgen.add_router("R1")
tgen.add_router("R2")
tgen.add_router("R3")
tgen.add_router("R4")
# R1-R2
switch = tgen.add_switch("s1")
switch.add_link(tgen.gears["R1"])
switch.add_link(tgen.gears["R2"])
# R2-R3
switch = tgen.add_switch("s2")
switch.add_link(tgen.gears["R2"])
switch.add_link(tgen.gears["R3"])
# R1-R4
switch = tgen.add_switch("s3")
switch.add_link(tgen.gears["R1"])
switch.add_link(tgen.gears["R4"])
def setup_module(mod):
"Sets up the pytest environment"
# This function initiates the topology build with Topogen...
tgen = Topogen(build_topo, mod.__name__)
# Skip if no mpls support
if not tgen.hasmpls:
logger.info("MPLS is not available, skipping test")
pytest.skip("MPLS is not available, skipping")
return
# ... and here it calls Mininet initialization functions.
tgen.start_topology()
# This is a sample of configuration loading.
router_list = tgen.routers()
# Enable mpls input for routers, so we can ping
sval = "net.mpls.conf.{}.input"
topotest.sysctl_assure(router_list["R2"], sval.format("R2-eth0"), 1)
topotest.sysctl_assure(router_list["R1"], sval.format("R1-eth0"), 1)
topotest.sysctl_assure(router_list["R1"], sval.format("R1-eth1"), 1)
topotest.sysctl_assure(router_list["R4"], sval.format("R4-eth0"), 1)
# For all registered routers, load the zebra configuration file
for rname, router in router_list.items():
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))
)
# Have static config for R3 too
if router == router_list["R3"]:
router.load_config(
TopoRouter.RD_STATIC, os.path.join(CWD, "{}/staticd.conf".format(rname))
)
# After loading the configurations, this function loads configured daemons.
tgen.start_router()
def teardown_module(mod):
"Teardown the pytest environment"
tgen = get_topogen()
# This function tears down the whole topology.
tgen.stop_topology()
def check_labelpool(router):
json_file = "{}/{}/labelpool.summ.json".format(CWD, router.name)
expected = json.loads(open(json_file).read())
test_func = partial(
topotest.router_json_cmp, router, "show bgp labelpool summary json", expected
)
_, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
assertmsg = '"{}" JSON output mismatches - Did not converge'.format(router.name)
assert result is None, assertmsg
def test_converge_bgplu():
"Wait for protocol convergence"
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
# TODO -- enable for debugging
# tgen.mininet_cli()
r1 = tgen.gears["R1"]
r2 = tgen.gears["R2"]
check_labelpool(r1)
check_labelpool(r2)
def test_ping():
"Simple ping tests"
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
#
logger.info("Ping from R2 to R3")
router = tgen.gears["R2"]
output = router.run("ping -c 4 -w 4 {}".format("10.0.1.3"))
assert " 0% packet loss" in output, "Ping R2->R3 FAILED"
logger.info("Ping from R2 to R3 ... success")
#
logger.info("Ping from R4 to R2")
router = tgen.gears["R4"]
output = router.run("ping -c 4 -w 4 {}".format("10.0.0.2"))
assert " 0% packet loss" in output, "Ping R4->R2 FAILED"
logger.info("Ping from R4 to R2 ... success")
#
logger.info("Ping from R4 to R3")
router = tgen.gears["R4"]
output = router.run("ping -c 4 -w 4 {}".format("10.0.1.3"))
assert " 0% packet loss" in output, "Ping R4->R3 FAILED"
logger.info("Ping from R4 to R3 ... success")
def test_memory_leak():
"Run the memory leak test and report results."
tgen = get_topogen()
if not tgen.is_memleak_enabled():
pytest.skip("Memory leak test/report is disabled")
tgen.report_memory_leaks()
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))