Skip to content

Commit 5c194b3

Browse files
authored
Merge pull request #17001 from louis-6wind/bmp-new
bgpd: bmp loc-rib peer up/down for vrfs
2 parents f0d93a4 + 7bccb8d commit 5c194b3

File tree

14 files changed

+753
-73
lines changed

14 files changed

+753
-73
lines changed

bgpd/bgp_bmp.c

+232-35
Large diffs are not rendered by default.

bgpd/bgp_bmp.h

+19-5
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,19 @@ PREDECL_HASH(bmp_bgph);
268268

269269
#define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00
270270

271+
enum bmp_vrf_state {
272+
vrf_state_down = -1,
273+
vrf_state_unknown = 0,
274+
vrf_state_up = 1,
275+
};
276+
271277
struct bmp_bgp {
272278
struct bmp_bgph_item bbi;
273279

274280
struct bgp *bgp;
281+
282+
enum bmp_vrf_state vrf_state;
283+
275284
struct bmp_targets_head targets;
276285

277286
struct bmp_mirrorq_head mirrorq;
@@ -280,12 +289,17 @@ struct bmp_bgp {
280289
size_t mirror_qsizelimit;
281290
};
282291

292+
extern bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp, enum bmp_vrf_state force);
293+
283294
enum {
284-
BMP_PEERDOWN_LOCAL_NOTIFY = 1,
285-
BMP_PEERDOWN_LOCAL_FSM = 2,
286-
BMP_PEERDOWN_REMOTE_NOTIFY = 3,
287-
BMP_PEERDOWN_REMOTE_CLOSE = 4,
288-
BMP_PEERDOWN_ENDMONITOR = 5,
295+
/* RFC7854 - 10.8 */
296+
BMP_PEERDOWN_LOCAL_NOTIFY = 1,
297+
BMP_PEERDOWN_LOCAL_FSM = 2,
298+
BMP_PEERDOWN_REMOTE_NOTIFY = 3,
299+
BMP_PEERDOWN_REMOTE_CLOSE = 4,
300+
BMP_PEERDOWN_ENDMONITOR = 5,
301+
/* RFC9069 - 8.4 */
302+
BMP_PEERDOWN_LOCAL_TLV = 6,
289303
};
290304

291305
enum {

bgpd/bgp_packet.c

+29-22
Original file line numberDiff line numberDiff line change
@@ -641,31 +641,11 @@ void bgp_keepalive_send(struct peer *peer)
641641
bgp_writes_on(peer->connection);
642642
}
643643

644-
/*
645-
* Creates a BGP Open packet and appends it to the peer's output queue.
646-
* Sets capabilities as necessary.
647-
*/
648-
void bgp_open_send(struct peer_connection *connection)
644+
struct stream *bgp_open_make(struct peer *peer, uint16_t send_holdtime, as_t local_as)
649645
{
650-
struct stream *s;
651-
uint16_t send_holdtime;
652-
as_t local_as;
653-
struct peer *peer = connection->peer;
646+
struct stream *s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE);
654647
bool ext_opt_params = false;
655648

656-
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
657-
send_holdtime = peer->holdtime;
658-
else
659-
send_holdtime = peer->bgp->default_holdtime;
660-
661-
/* local-as Change */
662-
if (peer->change_local_as)
663-
local_as = peer->change_local_as;
664-
else
665-
local_as = peer->local_as;
666-
667-
s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE);
668-
669649
/* Make open packet. */
670650
bgp_packet_set_marker(s, BGP_MSG_OPEN);
671651

@@ -704,6 +684,33 @@ void bgp_open_send(struct peer_connection *connection)
704684
ext_opt_params ? " (Extended)" : "", BGP_VERSION_4,
705685
local_as, send_holdtime, &peer->local_id);
706686

687+
return s;
688+
}
689+
690+
/*
691+
* Creates a BGP Open packet and appends it to the peer's output queue.
692+
* Sets capabilities as necessary.
693+
*/
694+
void bgp_open_send(struct peer_connection *connection)
695+
{
696+
struct stream *s;
697+
uint16_t send_holdtime;
698+
as_t local_as;
699+
struct peer *peer = connection->peer;
700+
701+
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
702+
send_holdtime = peer->holdtime;
703+
else
704+
send_holdtime = peer->bgp->default_holdtime;
705+
706+
/* local-as Change */
707+
if (peer->change_local_as)
708+
local_as = peer->change_local_as;
709+
else
710+
local_as = peer->local_as;
711+
712+
s = bgp_open_make(peer, send_holdtime, local_as);
713+
707714
/* Dump packet if debug option is set. */
708715
/* bgp_packet_dump (s); */
709716
hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s);

bgpd/bgp_packet.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ DECLARE_HOOK(bgp_packet_send,
4343

4444
/* Packet send and receive function prototypes. */
4545
extern void bgp_keepalive_send(struct peer *peer);
46+
extern struct stream *bgp_open_make(struct peer *peer, uint16_t send_holdtime, as_t local_as);
4647
extern void bgp_open_send(struct peer_connection *connection);
4748
extern void bgp_notify_send(struct peer_connection *connection, uint8_t code,
4849
uint8_t sub_code);

bgpd/bgpd.c

+7
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ DEFINE_QOBJ_TYPE(bgp_master);
8585
DEFINE_QOBJ_TYPE(bgp);
8686
DEFINE_QOBJ_TYPE(peer);
8787
DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp));
88+
DEFINE_HOOK(bgp_instance_state, (struct bgp *bgp), (bgp));
8889

8990
/* BGP process wide configuration. */
9091
static struct bgp_master bgp_master;
@@ -3929,6 +3930,9 @@ void bgp_instance_up(struct bgp *bgp)
39293930
struct peer *peer;
39303931
struct listnode *node, *next;
39313932

3933+
/* notify BMP of instance state changed */
3934+
hook_call(bgp_instance_state, bgp);
3935+
39323936
bgp_set_redist_vrf_bitmaps(bgp, true);
39333937

39343938
/* Register with zebra. */
@@ -3957,6 +3961,9 @@ void bgp_instance_down(struct bgp *bgp)
39573961
/* Cleanup evpn instance state */
39583962
bgp_evpn_instance_down(bgp);
39593963

3964+
/* notify BMP of instance state changed */
3965+
hook_call(bgp_instance_state, bgp);
3966+
39603967
/* Stop timers. */
39613968
if (bgp->t_rmap_def_originate_eval)
39623969
EVENT_OFF(bgp->t_rmap_def_originate_eval);

bgpd/bgpd.h

+1
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,7 @@ DECLARE_HOOK(bgp_snmp_traps_config_write, (struct vty *vty), (vty));
880880
DECLARE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp));
881881
DECLARE_HOOK(bgp_hook_vrf_update, (struct vrf *vrf, bool enabled),
882882
(vrf, enabled));
883+
DECLARE_HOOK(bgp_instance_state, (struct bgp *bgp), (bgp));
883884

884885
/* Thread callback information */
885886
struct afi_safi_info {

tests/topotests/bgp_bmp/test_bgp_bmp.py

+64-9
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,34 @@ def check_for_prefixes(expected_prefixes, bmp_log_type, policy, labels=None):
160160
return True
161161

162162

163+
def check_for_peer_message(expected_peers, bmp_log_type):
164+
"""
165+
Check for the presence of a peer up message for the peer
166+
"""
167+
global SEQ
168+
# we care only about the new messages
169+
messages = [
170+
m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ
171+
]
172+
173+
# get the list of pairs (prefix, policy, seq) for the given message type
174+
peers = [
175+
m["peer_ip"]
176+
for m in messages
177+
if "peer_ip" in m.keys() and m["bmp_log_type"] == bmp_log_type
178+
]
179+
180+
# check for prefixes
181+
for ep in expected_peers:
182+
if ep not in peers:
183+
msg = "The peer {} is not present in the {} log messages."
184+
logger.debug(msg.format(ep, bmp_log_type))
185+
return False
186+
187+
SEQ = messages[-1]["seq"]
188+
return True
189+
190+
163191
def set_bmp_policy(tgen, node, asn, target, safi, policy, vrf=None):
164192
"""
165193
Configure the bmp policy.
@@ -234,15 +262,11 @@ def vpn_prefixes(policy):
234262

235263
prefixes = ["172.31.10.1/32", "2001::2222/128"]
236264

237-
if policy == PRE_POLICY:
238-
# labels are not yet supported in adj-RIB-in. Do not test for the moment
239-
labels = None
240-
else:
241-
# "label vpn export" value in r2/bgpd.conf
242-
labels = {
243-
"172.31.10.1/32": 102,
244-
"2001::2222/128": 105,
245-
}
265+
# "label vpn export" value in r2/bgpd.conf
266+
labels = {
267+
"172.31.10.1/32": 102,
268+
"2001::2222/128": 105,
269+
}
246270

247271
# add prefixes
248272
configure_prefixes(tgen, "r2", 65502, "unicast", prefixes, vrf="vrf1")
@@ -280,6 +304,20 @@ def check_for_log_file():
280304
assert success, "The BMP server is not logging"
281305

282306

307+
def test_peer_up():
308+
"""
309+
Checking for BMP peers up messages
310+
"""
311+
312+
peers = ["192.168.0.2", "192:168::2"]
313+
314+
logger.info("checking for BMP peers up messages")
315+
316+
test_func = partial(check_for_peer_message, peers, "peer up")
317+
success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
318+
assert success, "Checking the updated prefixes has been failed !."
319+
320+
283321
def test_bmp_bgp_unicast():
284322
"""
285323
Add/withdraw bgp unicast prefixes and check the bmp logs.
@@ -302,6 +340,23 @@ def test_bmp_bgp_vpn():
302340
vpn_prefixes(LOC_RIB)
303341

304342

343+
def test_peer_down():
344+
"""
345+
Checking for BMP peers down messages
346+
"""
347+
tgen = get_topogen()
348+
349+
tgen.gears["r2"].vtysh_cmd("clear bgp *")
350+
351+
peers = ["192.168.0.2", "192:168::2"]
352+
353+
logger.info("checking for BMP peers down messages")
354+
355+
test_func = partial(check_for_peer_message, peers, "peer down")
356+
success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
357+
assert success, "Checking the updated prefixes has been failed !."
358+
359+
305360
if __name__ == "__main__":
306361
args = ["-s"] + sys.argv[1:]
307362
sys.exit(pytest.main(args))

tests/topotests/bgp_bmp_vrf/__init__.py

Whitespace-only changes.
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
router bgp 65501 vrf vrf1
2+
bgp router-id 192.168.0.1
3+
bgp log-neighbor-changes
4+
no bgp ebgp-requires-policy
5+
neighbor 192.168.0.2 remote-as 65502
6+
neighbor 192:168::2 remote-as 65502
7+
!
8+
bmp targets bmp1
9+
bmp connect 192.0.2.10 port 1789 min-retry 100 max-retry 10000
10+
exit
11+
!
12+
13+
address-family ipv4 unicast
14+
neighbor 192.168.0.2 activate
15+
neighbor 192.168.0.2 soft-reconfiguration inbound
16+
no neighbor 192:168::2 activate
17+
exit-address-family
18+
!
19+
address-family ipv6 unicast
20+
neighbor 192:168::2 activate
21+
neighbor 192:168::2 soft-reconfiguration inbound
22+
exit-address-family
23+
!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
interface r1-eth0
2+
ip address 192.0.2.1/24
3+
!
4+
interface r1-eth1
5+
ip address 192.168.0.1/24
6+
ipv6 address 192:168::1/64
7+
!
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
router bgp 65502
2+
bgp router-id 192.168.0.2
3+
bgp log-neighbor-changes
4+
no bgp ebgp-requires-policy
5+
no bgp network import-check
6+
neighbor 192.168.0.1 remote-as 65501
7+
neighbor 192:168::1 remote-as 65501
8+
!
9+
address-family ipv4 unicast
10+
neighbor 192.168.0.1 activate
11+
no neighbor 192:168::1 activate
12+
redistribute connected
13+
exit-address-family
14+
!
15+
address-family ipv6 unicast
16+
neighbor 192:168::1 activate
17+
redistribute connected
18+
exit-address-family
19+
!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
interface r2-eth0
2+
ip address 192.168.0.2/24
3+
ipv6 address 192:168::2/64
4+
!
5+
interface r2-eth1
6+
ip address 172.31.0.2/24
7+
ipv6 address 172:31::2/64
8+
!

0 commit comments

Comments
 (0)