AS_EXTERNAL,
};
+/* Zebra Gracaful Restart states */
+enum zebra_gr_mode {
+ ZEBRA_GR_DISABLE = 0,
+ ZEBRA_GR_ENABLE
+};
+
/* Typedef BGP specific types. */
typedef uint32_t as_t;
typedef uint16_t as16_t; /* we may still encounter 16 Bit asnums */
BGP_INSTANCE_TYPE_VIEW
};
+#define BGP_SEND_EOR(bgp, afi, safi) \
+ (!CHECK_FLAG(bgp->flags, BGP_FLAG_GR_DISABLE_EOR) \
+ && ((bgp->gr_info[afi][safi].t_select_deferral == NULL) \
+ || (bgp->gr_info[afi][safi].eor_required \
+ == bgp->gr_info[afi][safi].eor_received)))
/* BGP GR Global ds */
-#define GLOBAL_MODE 4
-#define EVENT_CMD 4
-
+#define BGP_GLOBAL_GR_MODE 4
+#define BGP_GLOBAL_GR_EVENT_CMD 4
/* Graceful restart selection deferral timer info */
struct graceful_restart_info {
struct list *route_list;
/* Best route select */
struct thread *t_route_select;
+ /* AFI, SAFI enabled */
+ bool af_enabled[AFI_MAX][SAFI_MAX];
+ /* Route update completed */
+ bool route_sync[AFI_MAX][SAFI_MAX];
};
-
enum global_mode {
GLOBAL_HELPER = 0, /* This is the default mode */
GLOBAL_GR,
#define BGP_GR_SUCCESS 0
#define BGP_GR_FAILURE 1
-
/* BGP instance structure. */
struct bgp {
/* AS number of this BGP instance. */
#define BGP_FLAG_GR_PRESERVE_FWD (1 << 20)
#define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 21)
#define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22)
+#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23)
+#define BGP_FLAG_GR_DISABLE_EOR (1 << 24)
-
- enum global_mode GLOBAL_GR_FSM[GLOBAL_MODE][EVENT_CMD];
+ enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
+ [BGP_GLOBAL_GR_EVENT_CMD];
enum global_mode global_gr_present_state;
+ /* This variable stores the current Graceful Restart state of Zebra
+ * - ZEBRA_GR_ENABLE / ZEBRA_GR_DISABLE
+ */
+ enum zebra_gr_mode present_zebra_gr_state;
+
/* BGP Per AF flags */
uint16_t af_flags[AFI_MAX][SAFI_MAX];
#define BGP_CONFIG_DAMPENING (1 << 0)
uint32_t stalepath_time;
uint32_t select_defer_time;
struct graceful_restart_info gr_info[AFI_MAX][SAFI_MAX];
+ uint32_t rib_stale_time;
+#define BGP_ROUTE_SELECT_DELAY 1
+#define BGP_MAX_BEST_ROUTE_SELECT 10000
/* Maximum-paths configuration */
struct bgp_maxpaths_cfg {
uint16_t maxpaths_ebgp;
#define BGP_VRF_RD_CFGD (1 << 3)
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 4)
-
/* unique ID for auto derivation of RD for this vrf */
uint16_t vrf_rd_id;
(struct bgp *bgp, struct vty *vty),
(bgp, vty))
+/* Thread callback information */
+struct afi_safi_info {
+ afi_t afi;
+ safi_t safi;
+ struct bgp *bgp;
+};
+
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
#define IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) \
|| (bgp->inst_type == BGP_INSTANCE_TYPE_VRF \
&& bgp->vrf_id != VRF_UNKNOWN))
+#define BGP_SELECT_DEFER_DISABLE(bgp) \
+ (CHECK_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE))
+
/* BGP peer-group support. */
struct peer_group {
/* Name of the peer-group. */
#define RMAP_OUT 1
#define RMAP_MAX 2
-#define BGP_DEFAULT_TTL 1
+#define BGP_DEFAULT_TTL 1
+#define BGP_GTSM_HOPS_DISABLED 0
+#define BGP_GTSM_HOPS_CONNECTED 1
#include "filter.h"
};
/* BGP GR per peer ds */
-
-#define PEER_MODE 5
-#define PEER_EVENT_CMD 6
+#define BGP_PEER_GR_MODE 5
+#define BGP_PEER_GR_EVENT_CMD 6
enum peer_mode {
PEER_HELPER = 0,
enum peer_gr_command {
PEER_GR_CMD = 0,
NO_PEER_GR_CMD,
- PEER_DISABLE_cmd,
+ PEER_DISABLE_CMD,
NO_PEER_DISABLE_CMD,
PEER_HELPER_CMD,
NO_PEER_HELPER_CMD
*and PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
*/
- struct bgp_peer_gr PEER_GR_FSM[PEER_MODE][PEER_EVENT_CMD];
+ struct bgp_peer_gr PEER_GR_FSM[BGP_PEER_GR_MODE][BGP_PEER_GR_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)
+#define PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT (1 << 2)
/* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
char *tx_shutdown_message;
/* NSF mode (graceful restart) */
uint8_t nsf[AFI_MAX][SAFI_MAX];
+ /* EOR Send time */
+ time_t eor_stime[AFI_MAX][SAFI_MAX];
+ /* Last update packet sent time */
+ time_t pkt_stime[AFI_MAX][SAFI_MAX];
/* Peer Per AF flags */
/*
#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 */
-/* orf capability send-mode */
-#define PEER_FLAG_ORF_PREFIX_SM (1 << 12)
+#define PEER_FLAG_ORF_PREFIX_SM (1 << 12) /* orf capability send-mode */
#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 */
#define PEER_DOWN_REMOTE_AS_CHANGE 2 /* neighbor remote-as command */
#define PEER_DOWN_LOCAL_AS_CHANGE 3 /* neighbor local-as command */
#define PEER_DOWN_CLID_CHANGE 4 /* bgp cluster-id command */
-#define PEER_DOWN_CONFED_ID_CHANGE 5 /* bgp confederation identifier command */
+#define PEER_DOWN_CONFED_ID_CHANGE 5 /* bgp confederation id command */
#define PEER_DOWN_CONFED_PEER_CHANGE 6 /* bgp confederation peer command */
-#define PEER_DOWN_RR_CLIENT_CHANGE 7 /* neighbor route-reflector-client command */
-#define PEER_DOWN_RS_CLIENT_CHANGE 8 /* neighbor route-server-client command */
+#define PEER_DOWN_RR_CLIENT_CHANGE 7 /* neighbor rr-client command */
+#define PEER_DOWN_RS_CLIENT_CHANGE 8 /* neighbor rs-client command */
#define PEER_DOWN_UPDATE_SOURCE_CHANGE 9 /* neighbor update-source command */
#define PEER_DOWN_AF_ACTIVATE 10 /* neighbor activate command */
#define PEER_DOWN_USER_SHUTDOWN 11 /* neighbor shutdown command */
#define PEER_DOWN_VRF_UNINIT 29 /* Associated VRF is not init yet */
#define PEER_DOWN_NOAFI_ACTIVATED 30 /* No AFI/SAFI activated for peer */
#define PEER_DOWN_AS_SETS_REJECT 31 /* Reject routes with AS_SET */
+#define PEER_DOWN_WAITING_OPEN 32 /* Waiting for open to succeed */
+ /*
+ * Remember to update peer_down_str in bgp_fsm.c when you add
+ * a new value to the last_reset reason
+ */
+
size_t last_reset_cause_size;
uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE];
((peer)->attr = (group)->conf->attr)
#define PEER_STR_ATTR_INHERIT(peer, group, attr, mt) \
do { \
- if ((peer)->attr) \
- XFREE(mt, (peer)->attr); \
+ XFREE(mt, (peer)->attr); \
if ((group)->conf->attr) \
(peer)->attr = XSTRDUP(mt, (group)->conf->attr); \
else \
/* BGP graceful restart */
#define BGP_DEFAULT_RESTART_TIME 120
#define BGP_DEFAULT_STALEPATH_TIME 360
+#define BGP_DEFAULT_SELECT_DEFERRAL_TIME 360
+#define BGP_DEFAULT_RIB_STALE_TIME 500
/* BGP uptime string length. */
#define BGP_UPTIME_LEN 25
#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
extern int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf,
vrf_id_t old_vrf_id, bool create);
-extern int bgp_flag_set(struct bgp *, int);
-extern int bgp_flag_unset(struct bgp *, int);
-extern int bgp_flag_check(struct bgp *, int);
-
extern void bgp_router_id_zebra_bump(vrf_id_t, const struct prefix *);
extern int bgp_router_id_static_set(struct bgp *, struct in_addr);
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);
+
+#define BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(_bgp, _peer_list) \
+ do { \
+ struct peer *peer_loop; \
+ bool gr_router_detected = false; \
+ struct listnode *node = {0}; \
+ for (ALL_LIST_ELEMENTS_RO(_peer_list, node, peer_loop)) { \
+ if (CHECK_FLAG(peer_loop->flags, \
+ PEER_FLAG_GRACEFUL_RESTART)) \
+ gr_router_detected = true; \
+ } \
+ if (gr_router_detected \
+ && _bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) { \
+ bgp_zebra_send_capabilities(_bgp, false); \
+ } else if (!gr_router_detected \
+ && _bgp->present_zebra_gr_state \
+ == ZEBRA_GR_ENABLE) { \
+ bgp_zebra_send_capabilities(_bgp, true); \
+ } \
+ } while (0)
+
static inline struct bgp *bgp_lock(struct bgp *bgp)
{
bgp->lock++;
/* Hooks */
DECLARE_HOOK(peer_status_changed, (struct peer * peer), (peer))
+void peer_nsf_stop(struct peer *peer);
#endif /* _QUAGGA_BGPD_H */