Skip to content

Commit

Permalink
Merge pull request #16751 from opensourcerouting/fix/solo_peer-group
Browse files Browse the repository at this point in the history
bgpd: Some peer-groups related changes/fixes
  • Loading branch information
donaldsharp authored Sep 5, 2024
2 parents ade1d8a + b63315f commit 340d51f
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 9 deletions.
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 @@ -17084,8 +17084,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 @@ -18690,11 +18695,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 @@ -4708,6 +4708,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))

0 comments on commit 340d51f

Please sign in to comment.