From b0965c44e942a06fedea73277aa164a27152a616 Mon Sep 17 00:00:00 2001 From: bisdhdh Date: Wed, 23 Oct 2019 11:02:45 +0530 Subject: [PATCH] bgpd: BGP Graceful Restart Per Neighbor(BGPN), DS & header files. This pr contains all the header files changes for BGP GR per Neighbour(BGPN) feature. Signed-off-by: Biswajit Sadhu --- bgpd/bgp_debug.h | 5 ++ bgpd/bgp_fsm.h | 69 ++++++++++++++++++++++++++- bgpd/bgp_vty.h | 28 ++++++++++- bgpd/bgpd.h | 119 ++++++++++++++++++++++++++++++++++++++++++++++- lib/command.h | 19 +++++++- 5 files changed, 236 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index e1072c3df2..9dff8266fa 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -76,6 +76,7 @@ extern unsigned long conf_bgp_debug_vpn; extern unsigned long conf_bgp_debug_flowspec; extern unsigned long conf_bgp_debug_labelpool; extern unsigned long conf_bgp_debug_pbr; +extern unsigned long conf_bgp_debug_graceful_restart; extern unsigned long term_bgp_debug_as4; extern unsigned long term_bgp_debug_neighbor_events; @@ -91,6 +92,8 @@ extern unsigned long term_bgp_debug_vpn; extern unsigned long term_bgp_debug_flowspec; extern unsigned long term_bgp_debug_labelpool; extern unsigned long term_bgp_debug_pbr; +extern unsigned long term_bgp_debug_graceful_restart; + extern struct list *bgp_debug_neighbor_events_peers; extern struct list *bgp_debug_keepalive_peers; @@ -131,6 +134,8 @@ struct bgp_debug_filter { #define BGP_DEBUG_PACKET_SEND 0x01 #define BGP_DEBUG_PACKET_SEND_DETAIL 0x02 +#define BGP_DEBUG_GRACEFUL_RESTART 0x01 + #define CONF_DEBUG_ON(a, b) (conf_bgp_debug_ ## a |= (BGP_DEBUG_ ## b)) #define CONF_DEBUG_OFF(a, b) (conf_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b)) diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 6f955c71be..da415db64c 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -56,6 +56,50 @@ #define FSM_PEER_TRANSFERRED 2 #define FSM_PEER_TRANSITIONED 3 +#define BGP_PEER_GR_HELPER_ENABLE(peer) \ + do { \ + UNSET_FLAG( \ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_RESTART); \ + SET_FLAG( \ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\ + } while (0) + + + +#define BGP_PEER_GR_ENABLE(peer)\ + do { \ + SET_FLAG( \ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_RESTART); \ + UNSET_FLAG( \ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\ + } while (0) + + +#define BGP_PEER_GR_DISABLE(peer)\ + do { \ + UNSET_FLAG( \ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_RESTART);\ + UNSET_FLAG(\ + peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\ + } while (0) + + +#define BGP_PEER_GR_GLOBAL_INHERIT_SET(peer) \ + SET_FLAG(peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT) + + +#define BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer) \ + UNSET_FLAG(peer->peer_gr_new_status_flag, \ + PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT) + + /* Prototypes. */ extern void bgp_fsm_event_update(struct peer *peer, int valid); extern int bgp_event(struct thread *); @@ -87,6 +131,29 @@ extern void bgp_start_routeadv(struct bgp *); extern void bgp_adjust_routeadv(struct peer *); #include "hook.h" -DECLARE_HOOK(peer_backward_transition, (struct peer * peer), (peer)) +DECLARE_HOOK(peer_backward_transition, (struct peer *peer), (peer)) +DECLARE_HOOK(peer_established, (struct peer *peer), (peer)) + +int bgp_gr_update_all(struct bgp *bgp, int global_GR_Cmd); +int bgp_neighbor_graceful_restart(struct peer *peer, + int peer_GR_Cmd); +unsigned int bgp_peer_gr_action(struct peer *peer, + int old_peer_state, int new_peer_state); +void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state); +unsigned int bgp_peer_gr_helper_enable(struct peer *peer); +unsigned int bgp_peer_gr_enable(struct peer *peer); +unsigned int bgp_peer_gr_global_inherit(struct peer *peer); +unsigned int bgp_peer_gr_disable(struct peer *peer); +enum peer_mode bgp_peer_gr_mode_get(struct peer *peer); +enum global_mode bgp_global_gr_mode_get(struct bgp *bgp); +enum peer_mode bgp_get_peer_gr_mode_from_flags(struct peer *peer); +unsigned int bgp_peer_gr_global_inherit_unset(struct peer *peer); +int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp, + enum global_mode global_new_state, + enum global_mode global_old_state); + +void bgp_peer_gr_flags_update(struct peer *peer); +extern int bgp_peer_flag_unset(struct peer *peer, int flag_bit); +extern int bgp_peer_flag_set(struct peer *peer, int flag_bit); #endif /* _QUAGGA_BGP_FSM_H */ diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 5f3ce9cd8e..e1109841d2 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -22,7 +22,7 @@ #define _QUAGGA_BGP_VTY_H #include "bgpd/bgpd.h" - +#include "stream.h" struct bgp; #define BGP_INSTANCE_HELP_STR "BGP view\nBGP VRF\nView/VRF name\n" @@ -46,6 +46,32 @@ struct bgp; "Address Family modifier\n" \ "Address Family modifier\n" + + +#define SHOW_GR_HEADER \ + "Codes: GR - Graceful Restart," \ + " * - Inheriting Global GR Config,\n" \ + " Restart - GR Mode-Restarting," \ + " Helper - GR Mode-Helper,\n" \ + " Disable - GR Mode-Disable.\n\n" + +#define BGP_SHOW_PEER_GR_CAPABILITY( \ + vty, p, use_json, json) \ + do { \ + bgp_show_neighbor_graceful_restart_local_mode( \ + vty, p, use_json, json); \ + bgp_show_neighbor_graceful_restart_remote_mode( \ + vty, p, use_json, json); \ + bgp_show_neighnor_graceful_restart_rbit( \ + vty, p, use_json, json); \ + bgp_show_neighbor_graceful_restart_time( \ + vty, p, use_json, json); \ + bgp_show_neighbor_graceful_restart_capability_per_afi_safi(\ + vty, p, use_json, json); \ + } while (0) + + + extern void bgp_vty_init(void); extern const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json); extern int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 4c4787ed5b..b0fe7b912a 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -232,6 +232,46 @@ enum bgp_instance_type { BGP_INSTANCE_TYPE_VIEW }; + +/* BGP GR Global ds */ + +#define GLOBAL_MODE 4 +#define EVENT_CMD 4 + + +/* Graceful restart selection deferral timer info */ +struct graceful_restart_info { + /* Count of EOR message expected */ + uint32_t eor_required; + /* Count of EOR received */ + uint32_t eor_received; + /* Deferral Timer */ + struct thread *t_select_deferral; + /* Route list */ + struct list *route_list; + /* Best route select */ + struct thread *t_route_select; +}; + + +enum global_mode { + GLOBAL_HELPER = 0, /* This is the default mode */ + GLOBAL_GR, + GLOBAL_DISABLE, + GLOBAL_INVALID +}; + +enum global_gr_command { + GLOBAL_GR_CMD = 0, + NO_GLOBAL_GR_CMD, + GLOBAL_DISABLE_CMD, + NO_GLOBAL_DISABLE_CMD +}; + +#define BGP_GR_SUCCESS 0 +#define BGP_GR_FAILURE 1 + + /* BGP instance structure. */ struct bgp { /* AS number of this BGP instance. */ @@ -356,7 +396,10 @@ struct bgp { #define BGP_FLAG_IMPORT_CHECK (1 << 9) #define BGP_FLAG_NO_FAST_EXT_FAILOVER (1 << 10) #define BGP_FLAG_LOG_NEIGHBOR_CHANGES (1 << 11) + +/* This flag is set when we have full BGP Graceful-Restart mode enable */ #define BGP_FLAG_GRACEFUL_RESTART (1 << 12) + #define BGP_FLAG_ASPATH_CONFED (1 << 13) #define BGP_FLAG_ASPATH_MULTIPATH_RELAX (1 << 14) #define BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY (1 << 15) @@ -368,6 +411,10 @@ struct bgp { #define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 21) #define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22) + + enum global_mode GLOBAL_GR_FSM[GLOBAL_MODE][EVENT_CMD]; + enum global_mode global_gr_present_state; + /* BGP Per AF flags */ uint16_t af_flags[AFI_MAX][SAFI_MAX]; #define BGP_CONFIG_DAMPENING (1 << 0) @@ -462,6 +509,8 @@ struct bgp { /* BGP graceful restart */ uint32_t restart_time; uint32_t stalepath_time; + uint32_t select_defer_time; + struct graceful_restart_info gr_info[AFI_MAX][SAFI_MAX]; /* Maximum-paths configuration */ struct bgp_maxpaths_cfg { @@ -726,6 +775,37 @@ struct peer_af { safi_t safi; int afid; }; +/* BGP GR per peer ds */ + + +#define PEER_MODE 5 +#define PEER_EVENT_CMD 6 + +enum peer_mode { + PEER_HELPER = 0, + PEER_GR, + PEER_DISABLE, + PEER_INVALID, + PEER_GLOBAL_INHERIT /* This is the default mode */ + +}; + +enum peer_gr_command { + PEER_GR_CMD = 0, + NO_PEER_GR_CMD, + PEER_DISABLE_cmd, + NO_PEER_DISABLE_CMD, + PEER_HELPER_CMD, + NO_PEER_HELPER_CMD +}; + +typedef unsigned int (*bgp_peer_gr_action_ptr)(struct peer *, int, int); + +struct bgp_peer_gr { + enum peer_mode next_state; + bgp_peer_gr_action_ptr action_fun; +}; + /* BGP neighbor structure. */ struct peer { @@ -947,6 +1027,27 @@ struct peer { #define PEER_FLAG_LOCAL_AS (1 << 21) /* local-as */ #define PEER_FLAG_UPDATE_SOURCE (1 << 22) /* update-source */ + /* BGP-GR Peer related flags */ +#define PEER_FLAG_GRACEFUL_RESTART_HELPER (1 << 23) /* Helper */ +#define PEER_FLAG_GRACEFUL_RESTART (1 << 24) /* Graceful Restart */ +#define PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT (1 << 25) /* Global-Inherit */ + + /* + *GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART + *& PEER_FLAG_GRACEFUL_RESTART_HELPER + *and PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT + */ + + struct bgp_peer_gr PEER_GR_FSM[PEER_MODE][PEER_EVENT_CMD]; + enum peer_mode peer_gr_present_state; + /* Non stop forwarding afi-safi count for BGP gr feature*/ + uint8_t nsf_af_count; + + uint8_t peer_gr_new_status_flag; +#define PEER_GRACEFUL_RESTART_NEW_STATE_HELPER (1 << 0) +#define PEER_GRACEFUL_RESTART_NEW_STATE_RESTART (1 << 1) +#define PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT (1 << 2) + /* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */ char *tx_shutdown_message; @@ -975,7 +1076,8 @@ struct peer { #define PEER_FLAG_DEFAULT_ORIGINATE (1 << 9) /* default-originate */ #define PEER_FLAG_REMOVE_PRIVATE_AS (1 << 10) /* remove-private-as */ #define PEER_FLAG_ALLOWAS_IN (1 << 11) /* set allowas-in */ -#define PEER_FLAG_ORF_PREFIX_SM (1 << 12) /* orf capability send-mode */ +/* orf capability send-mode */ +#define PEER_FLAG_ORF_PREFIX_SM (1 << 12) #define PEER_FLAG_ORF_PREFIX_RM (1 << 13) /* orf capability receive-mode */ #define PEER_FLAG_MAX_PREFIX (1 << 14) /* maximum prefix */ #define PEER_FLAG_MAX_PREFIX_WARNING (1 << 15) /* maximum prefix warning-only */ @@ -1521,6 +1623,12 @@ enum bgp_clear_type { #define BGP_ERR_INVALID_FOR_DIRECT_PEER -34 #define BGP_ERR_PEER_SAFI_CONFLICT -35 +/* BGP GR ERRORS */ + +#define BGP_ERR_GR_INVALID_CMD -36 +#define BGP_ERR_GR_OPERATION_FAILED -37 +#define BGP_GR_NO_OPERATION -38 + /* * Enumeration of different policy kinds a peer can be configured with. */ @@ -1773,6 +1881,15 @@ extern int peer_af_delete(struct peer *, afi_t, safi_t); extern void bgp_close(void); extern void bgp_free(struct bgp *); +void bgp_gr_apply_running_config(void); + +/* BGP GR */ + +int bgp_peer_flag_set(struct peer *peer, int flag_bit); +int bgp_peer_flag_unset(struct peer *peer, int flag_bit); +int bgp_peer_flag_check(struct peer *peer, int flag_bit); +int bgp_global_gr_init(struct bgp *bgp); +int bgp_peer_gr_init(struct peer *peer); static inline struct bgp *bgp_lock(struct bgp *bgp) { diff --git a/lib/command.h b/lib/command.h index c8dd04604d..ca2ff1d5fb 100644 --- a/lib/command.h +++ b/lib/command.h @@ -418,8 +418,25 @@ struct cmd_node { #define DAEMONS_LIST \ "" +/* Graceful Restart cli help strings */ + +#define GR_CMD "Global Graceful Restart command\n" +#define NO_GR_CMD "Undo Global Graceful Restart command\n" +#define GR "Global Graceful Restart - GR Mode\n" +#define GR_DISABLE "Global Graceful Restart - Disable Mode\n" +#define NO_GR_DISABLE "Undo Global Graceful Restart - Disable Mode\n" +#define GR_DEBUG "Graceful Restart - Enable Debug Logs\n" +#define GR_SHOW "Graceful Restart - Show command for Global and all neighbor mode\n" +#define GR_NEIGHBOR_CMD "Graceful Restart command for a neighbor\n" +#define NO_GR_NEIGHBOR_CMD "Undo Graceful Restart command for a neighbor\n" +#define GR_NEIGHBOR_DISABLE_CMD "Graceful Restart Disable command for a neighbor\n" +#define NO_GR_NEIGHBOR_DISABLE_CMD "Undo Graceful Restart Disable command for a neighbor\n" +#define GR_NEIGHBOR_HELPER_CMD "Graceful Restart Helper command for a neighbor\n" +#define NO_GR_NEIGHBOR_HELPER_CMD "Undo Graceful Restart Helper command for a neighbor\n" + + /* Prototypes. */ -extern void install_node(struct cmd_node *, int (*)(struct vty *)); +extern void install_node(struct cmd_node *node, int (*)(struct vty *)); extern void install_default(enum node_type); extern void install_element(enum node_type, const struct cmd_element *);