From c6bf7f4723158eb53383ed721150a1b4d0bf2e48 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 6 Oct 2023 17:41:18 +0300 Subject: [PATCH] bgpd: Add `clear bgp capabilities` command to resend some dynamic capabilities For instance, it's not possible to resend FQDN capability without resetting the session, so let's create some more elegant way to do that. Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 9 ++++++--- bgpd/bgpd.c | 13 +++++++++++++ bgpd/bgpd.h | 3 ++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9b4d8936828a..9b53eba411b1 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10601,7 +10601,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [ VIEWVRFNAME] [ []] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|ASNUM|external|peer-group PGNAME> []|in [prefix-filter]|out|message-stats>]", + "clear [ip] bgp [ VIEWVRFNAME] [ []] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|ASNUM|external|peer-group PGNAME> []|in [prefix-filter]|out|message-stats|capabilities>]", CLEAR_STR IP_STR BGP_STR @@ -10624,7 +10624,8 @@ DEFUN (clear_ip_bgp_all, BGP_SOFT_IN_STR "Push out prefix-list ORF and do inbound soft reconfig\n" BGP_SOFT_OUT_STR - "Reset message statistics\n") + "Reset message statistics\n" + "Resend capabilities\n") { char *vrf = NULL; @@ -10681,7 +10682,7 @@ DEFUN (clear_ip_bgp_all, clr_sort = clear_external; } - /* []|in [prefix-filter]|out|message-stats>] */ + /* []|in [prefix-filter]|out|message-stats|capabilities>] */ if (argv_find(argv, argc, "soft", &idx)) { if (argv_find(argv, argc, "in", &idx) || argv_find(argv, argc, "out", &idx)) @@ -10698,6 +10699,8 @@ DEFUN (clear_ip_bgp_all, clr_type = BGP_CLEAR_SOFT_OUT; } else if (argv_find(argv, argc, "message-stats", &idx)) { clr_type = BGP_CLEAR_MESSAGE_STATS; + } else if (argv_find(argv, argc, "capabilities", &idx)) { + clr_type = BGP_CLEAR_CAPABILITIES; } else clr_type = BGP_CLEAR_SOFT_NONE; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e760d4158768..b13ce5ad0b15 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -8034,6 +8034,16 @@ static void peer_reset_message_stats(struct peer *peer) } } +/* Helper function to resend some BGP capabilities that are uncontrolled. + * For instance, FQDN capability, that can't be turned off, but let's say + * we changed the hostname, we need to resend it. + */ +static void peer_clear_capabilities(struct peer *peer, afi_t afi, safi_t safi) +{ + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_FQDN, + CAPABILITY_ACTION_SET); +} + /* * If peer clear is invoked in a loop for all peers on the BGP instance, * it may end up freeing the doppelganger, and if this was the next node @@ -8142,6 +8152,9 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, if (stype == BGP_CLEAR_MESSAGE_STATS) peer_reset_message_stats(peer); + if (stype == BGP_CLEAR_CAPABILITIES) + peer_clear_capabilities(peer, afi, safi); + return 0; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 8f78e33f6517..665a38e76bcc 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2067,7 +2067,8 @@ enum bgp_clear_type { BGP_CLEAR_SOFT_IN, BGP_CLEAR_SOFT_BOTH, BGP_CLEAR_SOFT_IN_ORF_PREFIX, - BGP_CLEAR_MESSAGE_STATS + BGP_CLEAR_MESSAGE_STATS, + BGP_CLEAR_CAPABILITIES, }; /* Macros. */