mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 00:59:13 +00:00
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:
commit
61a7ec774c
@ -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);
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"Ledger":506,
|
||||
"InUse":506,
|
||||
"Ledger":0,
|
||||
"InUse":0,
|
||||
"Requests":0,
|
||||
"LabelChunks":11,
|
||||
"LabelChunks":0,
|
||||
"Pending":0,
|
||||
"Reconnects":0
|
||||
}
|
||||
|
29
tests/topotests/bgp_lu_topo2/R1/bgpd.conf
Normal file
29
tests/topotests/bgp_lu_topo2/R1/bgpd.conf
Normal 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
|
||||
!
|
8
tests/topotests/bgp_lu_topo2/R1/labelpool.summ.json
Normal file
8
tests/topotests/bgp_lu_topo2/R1/labelpool.summ.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Ledger":51,
|
||||
"InUse":51,
|
||||
"Requests":0,
|
||||
"LabelChunks":2,
|
||||
"Pending":0,
|
||||
"Reconnects":0
|
||||
}
|
13
tests/topotests/bgp_lu_topo2/R1/zebra.conf
Normal file
13
tests/topotests/bgp_lu_topo2/R1/zebra.conf
Normal 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
|
27
tests/topotests/bgp_lu_topo2/R2/bgpd.conf
Normal file
27
tests/topotests/bgp_lu_topo2/R2/bgpd.conf
Normal 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
|
||||
!
|
8
tests/topotests/bgp_lu_topo2/R2/labelpool.summ.json
Normal file
8
tests/topotests/bgp_lu_topo2/R2/labelpool.summ.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Ledger":1,
|
||||
"InUse":1,
|
||||
"Requests":0,
|
||||
"LabelChunks":1,
|
||||
"Pending":0,
|
||||
"Reconnects":0
|
||||
}
|
14
tests/topotests/bgp_lu_topo2/R2/zebra.conf
Normal file
14
tests/topotests/bgp_lu_topo2/R2/zebra.conf
Normal 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
|
||||
!
|
70
tests/topotests/bgp_lu_topo2/R3/bgpd.conf
Normal file
70
tests/topotests/bgp_lu_topo2/R3/bgpd.conf
Normal 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
|
||||
!
|
||||
!
|
5
tests/topotests/bgp_lu_topo2/R3/staticd.conf
Normal file
5
tests/topotests/bgp_lu_topo2/R3/staticd.conf
Normal 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
|
11
tests/topotests/bgp_lu_topo2/R3/zebra.conf
Normal file
11
tests/topotests/bgp_lu_topo2/R3/zebra.conf
Normal 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
|
||||
!
|
23
tests/topotests/bgp_lu_topo2/R4/bgpd.conf
Normal file
23
tests/topotests/bgp_lu_topo2/R4/bgpd.conf
Normal 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
|
||||
!
|
9
tests/topotests/bgp_lu_topo2/R4/zebra.conf
Normal file
9
tests/topotests/bgp_lu_topo2/R4/zebra.conf
Normal 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
|
221
tests/topotests/bgp_lu_topo2/test_bgp_lu2.py
Normal file
221
tests/topotests/bgp_lu_topo2/test_bgp_lu2.py
Normal 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))
|
Loading…
Reference in New Issue
Block a user