mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 10:32:00 +00:00
Merge pull request #8956 from pguibert6WIND/bgp_loop_through_itself
bgpd: prevent routes loop through itself
This commit is contained in:
commit
90737805d9
@ -2520,7 +2520,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
/* Gateway IP nexthop should be resolved */
|
/* Gateway IP nexthop should be resolved */
|
||||||
if (attr.evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
|
if (attr.evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
|
||||||
if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi,
|
if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi,
|
||||||
NULL, 0))
|
NULL, 0, NULL))
|
||||||
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
|
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
|
||||||
else {
|
else {
|
||||||
if (BGP_DEBUG(nht, NHT)) {
|
if (BGP_DEBUG(nht, NHT)) {
|
||||||
|
@ -110,9 +110,9 @@ int bgp_peer_reg_with_nht(struct peer *peer)
|
|||||||
&& !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
|
&& !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
|
||||||
connected = 1;
|
connected = 1;
|
||||||
|
|
||||||
return bgp_find_or_add_nexthop(peer->bgp, peer->bgp,
|
return bgp_find_or_add_nexthop(
|
||||||
family2afi(peer->su.sa.sa_family),
|
peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family),
|
||||||
SAFI_UNICAST, NULL, peer, connected);
|
SAFI_UNICAST, NULL, peer, connected, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
|
static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
|
||||||
|
@ -845,7 +845,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
* 'connected' parameter?
|
* 'connected' parameter?
|
||||||
*/
|
*/
|
||||||
nh_valid = bgp_find_or_add_nexthop(
|
nh_valid = bgp_find_or_add_nexthop(
|
||||||
bgp, bgp_nexthop, afi, safi, bpi, NULL, 0);
|
bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
@ -931,7 +931,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
|
|||||||
* 'connected' parameter?
|
* 'connected' parameter?
|
||||||
*/
|
*/
|
||||||
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
|
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
|
||||||
new, NULL, 0);
|
new, NULL, 0, p);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
|
@ -160,7 +160,8 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
|
|||||||
*/
|
*/
|
||||||
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||||
afi_t afi, safi_t safi, struct bgp_path_info *pi,
|
afi_t afi, safi_t safi, struct bgp_path_info *pi,
|
||||||
struct peer *peer, int connected)
|
struct peer *peer, int connected,
|
||||||
|
const struct prefix *orig_prefix)
|
||||||
{
|
{
|
||||||
struct bgp_nexthop_cache_head *tree = NULL;
|
struct bgp_nexthop_cache_head *tree = NULL;
|
||||||
struct bgp_nexthop_cache *bnc;
|
struct bgp_nexthop_cache *bnc;
|
||||||
@ -192,6 +193,16 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
if (make_prefix(afi, pi, &p) < 0)
|
if (make_prefix(afi, pi, &p) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (!is_bgp_static_route && orig_prefix
|
||||||
|
&& prefix_same(&p, orig_prefix)) {
|
||||||
|
if (BGP_DEBUG(nht, NHT)) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s(%pFX): prefix loops through itself",
|
||||||
|
__func__, &p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
srte_color = pi->attr->srte_color;
|
srte_color = pi->attr->srte_color;
|
||||||
} else if (peer) {
|
} else if (peer) {
|
||||||
/*
|
/*
|
||||||
|
@ -42,7 +42,8 @@ extern void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id);
|
|||||||
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
||||||
struct bgp *bgp_nexthop, afi_t a,
|
struct bgp *bgp_nexthop, afi_t a,
|
||||||
safi_t safi, struct bgp_path_info *p,
|
safi_t safi, struct bgp_path_info *p,
|
||||||
struct peer *peer, int connected);
|
struct peer *peer, int connected,
|
||||||
|
const struct prefix *orig_prefix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
||||||
|
@ -4103,7 +4103,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
|||||||
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
|
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
|
||||||
|
|
||||||
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
|
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
|
||||||
safi, pi, NULL, connected)
|
safi, pi, NULL, connected,
|
||||||
|
p)
|
||||||
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
|
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
|
||||||
bgp_path_info_set_flag(dest, pi,
|
bgp_path_info_set_flag(dest, pi,
|
||||||
BGP_PATH_VALID);
|
BGP_PATH_VALID);
|
||||||
@ -4244,7 +4245,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
|||||||
nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
|
nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
|
||||||
|
|
||||||
if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
|
if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
|
||||||
connected)
|
connected, p)
|
||||||
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
|
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
|
||||||
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
|
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
|
||||||
else {
|
else {
|
||||||
@ -5683,7 +5684,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
|
|||||||
|
|
||||||
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
|
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
|
||||||
afi, safi, pi, NULL,
|
afi, safi, pi, NULL,
|
||||||
0))
|
0, p))
|
||||||
bgp_path_info_set_flag(dest, pi,
|
bgp_path_info_set_flag(dest, pi,
|
||||||
BGP_PATH_VALID);
|
BGP_PATH_VALID);
|
||||||
else {
|
else {
|
||||||
@ -5735,7 +5736,8 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
|
|||||||
/* Nexthop reachability check. */
|
/* Nexthop reachability check. */
|
||||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
|
||||||
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
|
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
|
||||||
if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0))
|
if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
|
||||||
|
p))
|
||||||
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
|
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
|
||||||
else {
|
else {
|
||||||
if (BGP_DEBUG(nht, NHT)) {
|
if (BGP_DEBUG(nht, NHT)) {
|
||||||
|
@ -774,9 +774,9 @@ def test_BGP_attributes_with_vrf_default_keyword_p0(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
||||||
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
result = verify_rib(tgen, addr_type, dut, input_dict)
|
result = verify_rib(tgen, addr_type, dut, input_dict)
|
||||||
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
for addr_type in ADDR_TYPES:
|
for addr_type in ADDR_TYPES:
|
||||||
dut = "r4"
|
dut = "r4"
|
||||||
@ -793,9 +793,9 @@ def test_BGP_attributes_with_vrf_default_keyword_p0(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
||||||
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
result = verify_rib(tgen, addr_type, dut, input_dict)
|
result = verify_rib(tgen, addr_type, dut, input_dict)
|
||||||
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
|
input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
|
||||||
|
|
||||||
@ -1134,15 +1134,10 @@ def test_bgp_with_loopback_with_same_subnet_p1(request):
|
|||||||
dut = "r1"
|
dut = "r1"
|
||||||
protocol = "bgp"
|
protocol = "bgp"
|
||||||
for addr_type in ADDR_TYPES:
|
for addr_type in ADDR_TYPES:
|
||||||
result = verify_rib(tgen, addr_type, dut, input_dict_r1, protocol=protocol)
|
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1)
|
||||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(
|
assert result is not True, "Testcase {} : Failed \n".format(tc_name)
|
||||||
tc_name, result
|
|
||||||
)
|
|
||||||
|
|
||||||
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
|
|
||||||
assert result is not True, "Testcase {} : Failed \n"
|
|
||||||
"Expected behavior: routes should not present in fib \n"
|
"Expected behavior: routes should not present in fib \n"
|
||||||
"Error: {}".format(tc_name, result)
|
"Error: {}".format(result)
|
||||||
|
|
||||||
step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
|
step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
|
||||||
input_dict_r3 = {
|
input_dict_r3 = {
|
||||||
@ -1156,17 +1151,10 @@ def test_bgp_with_loopback_with_same_subnet_p1(request):
|
|||||||
dut = "r3"
|
dut = "r3"
|
||||||
protocol = "bgp"
|
protocol = "bgp"
|
||||||
for addr_type in ADDR_TYPES:
|
for addr_type in ADDR_TYPES:
|
||||||
result = verify_rib(
|
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1)
|
||||||
tgen, addr_type, dut, input_dict_r3, protocol=protocol, fib=None
|
assert result is not True, "Testcase {} : Failed \n".format(tc_name)
|
||||||
)
|
|
||||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(
|
|
||||||
tc_name, result
|
|
||||||
)
|
|
||||||
|
|
||||||
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
|
|
||||||
assert result is not True, "Testcase {} : Failed \n"
|
|
||||||
"Expected behavior: routes should not present in fib \n"
|
"Expected behavior: routes should not present in fib \n"
|
||||||
"Error: {}".format(tc_name, result)
|
"Error: {}".format(result)
|
||||||
|
|
||||||
write_test_footer(tc_name)
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user