Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Some peer-groups related changes/fixes #16751

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bgpd/bgp_updgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,8 @@ int update_group_adjust_soloness(struct peer *peer, int set)
struct peer_group *group;
struct listnode *node, *nnode;

peer_flag_set(peer, PEER_FLAG_LONESOUL);

if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer_lonesoul_or_not(peer, set);
if (peer_established(peer->connection))
Expand Down
16 changes: 9 additions & 7 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -17072,8 +17072,13 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group,
vty_out(vty, "\nBGP peer-group %s\n", group->name);
}

if ((group->bgp->as == conf->as) ||
CHECK_FLAG(conf->as_type, AS_INTERNAL)) {
if (CHECK_FLAG(conf->as_type, AS_AUTO)) {
if (json)
json_object_string_add(json_peer_group, "type", "auto");
else
vty_out(vty, " Peer-group type is auto\n");
} else if ((group->bgp->as == conf->as) ||
CHECK_FLAG(conf->as_type, AS_INTERNAL)) {
if (json)
json_object_string_add(json_peer_group, "type",
"internal");
Expand Down Expand Up @@ -18678,11 +18683,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
peer->password);

/* neighbor solo */
if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) {
if (!peer_group_active(peer)) {
vty_out(vty, " neighbor %s solo\n", addr);
}
}
if (peergroup_flag_check(peer, PEER_FLAG_LONESOUL))
vty_out(vty, " neighbor %s solo\n", addr);

/* BGP port */
if (peer->port != BGP_PORT_DEFAULT) {
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -4701,6 +4701,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_none},
{PEER_FLAG_AS_LOOP_DETECTION, 0, peer_change_none},
{PEER_FLAG_EXTENDED_LINK_BANDWIDTH, 0, peer_change_none},
{PEER_FLAG_LONESOUL, 0, peer_change_reset_out},
{0, 0, 0}};

static const struct peer_flag_action peer_af_flag_action_list[] = {
Expand Down
3 changes: 1 addition & 2 deletions doc/user/bgp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2191,8 +2191,7 @@ and will share updates.
.. clicmd:: neighbor PEER solo

This command is used to indicate that routes advertised by the peer
should not be reflected back to the peer. This command only is only
meaningful when there is a single peer defined in the peer-group.
should not be reflected back to the peer.

.. clicmd:: show [ip] bgp peer-group [json]

Expand Down
Empty file.
21 changes: 21 additions & 0 deletions tests/topotests/bgp_peer_group_solo/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
!
int r1-eth0
ip address 192.168.1.1/24
!
int r1-eth1
ip address 192.168.14.1/24
!
router bgp 65001
no bgp ebgp-requires-policy
no bgp network import-check
neighbor pg peer-group
neighbor pg remote-as external
neighbor pg solo
neighbor pg timers 1 3
neighbor pg timers connect 1
neighbor 192.168.1.2 peer-group pg
neighbor 192.168.1.3 peer-group pg
address-family ipv4 unicast
network 10.0.0.1/32
exit-address-family
!
10 changes: 10 additions & 0 deletions tests/topotests/bgp_peer_group_solo/r2/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
!
int r2-eth0
ip address 192.168.1.2/24
!
router bgp 65002
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as external
neighbor 192.168.1.1 timers 1 3
neighbor 192.168.1.1 timers connect 1
!
10 changes: 10 additions & 0 deletions tests/topotests/bgp_peer_group_solo/r3/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
!
int r3-eth0
ip address 192.168.1.3/24
!
router bgp 65003
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as external
neighbor 192.168.1.1 timers 1 3
neighbor 192.168.1.1 timers connect 1
!
102 changes: 102 additions & 0 deletions tests/topotests/bgp_peer_group_solo/test_bgp_peer_group_solo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
# SPDX-License-Identifier: ISC

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

import os
import re
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, get_topogen

pytestmark = [pytest.mark.bgpd]


def setup_module(mod):
topodef = {"s1": ("r1", "r2", "r3")}
tgen = Topogen(topodef, mod.__name__)
tgen.start_topology()

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_remote_as_auto():
tgen = get_topogen()

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

r1 = tgen.gears["r1"]

def _bgp_converge():
output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast summary json"))
expected = {
"peers": {
"192.168.1.2": {
"remoteAs": 65002,
"state": "Established",
"peerState": "OK",
},
"192.168.1.3": {
"remoteAs": 65003,
"state": "Established",
"peerState": "OK",
},
},
"totalPeers": 2,
}

return topotest.json_cmp(output, expected)

test_func = functools.partial(
_bgp_converge,
)
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Can't converge initial state"

def _bgp_update_groups():
actual = []
output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast update-groups json"))
expected = [
{"subGroup": [{"adjListCount": 1, "peers": ["192.168.1.2"]}]},
{"subGroup": [{"adjListCount": 1, "peers": ["192.168.1.3"]}]},
]

# update-group's number can be random and it's not deterministic,
# so we need to normalize the data a bit before checking.
# We care here about the `peers` array only actually.
for updgrp in output["default"].keys():
actual.append(output["default"][updgrp])

return topotest.json_cmp(actual, expected)

test_func = functools.partial(
_bgp_update_groups,
)
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Can't see separate update-groups"


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