diff options
184 files changed, 3633 insertions, 3802 deletions
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 2dec0863c0..42f3937580 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -74,6 +74,7 @@ bgp_evpn_es_path_update_on_vtep_chg(struct bgp_evpn_es_vtep *es_vtep, bool active); esi_t zero_esi_buf, *zero_esi = &zero_esi_buf; +static int bgp_evpn_run_consistency_checks(struct thread *t); /****************************************************************************** * per-ES (Ethernet Segment) routing table @@ -1621,21 +1622,18 @@ static void bgp_evpn_es_remote_info_re_eval(struct bgp_evpn_es *es) } } -/* Process ES link oper-down by withdrawing ES-EAD and ESR */ -static void bgp_evpn_local_es_down(struct bgp *bgp, - struct bgp_evpn_es *es) +static inline bool bgp_evpn_local_es_is_active(struct bgp_evpn_es *es) +{ + return (es->flags & BGP_EVPNES_OPER_UP) + && !(es->flags & BGP_EVPNES_BYPASS); +} + +static void bgp_evpn_local_es_deactivate(struct bgp *bgp, + struct bgp_evpn_es *es) { struct prefix_evpn p; int ret; - if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) - return; - - UNSET_FLAG(es->flags, BGP_EVPNES_OPER_UP); - - if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("local es %s down", es->esi_str); - /* withdraw ESR */ /* Delete and withdraw locally learnt ES route */ build_evpn_type4_prefix(&p, &es->esi, es->originator_ip); @@ -1661,21 +1659,28 @@ static void bgp_evpn_local_es_down(struct bgp *bgp, } } -/* Process ES link oper-up by generating ES-EAD and ESR */ -static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es, - bool regen_esr) +/* Process ES link oper-down by withdrawing ES-EAD and ESR */ +static void bgp_evpn_local_es_down(struct bgp *bgp, struct bgp_evpn_es *es) { - struct prefix_evpn p; - bool regen_ead = false; + bool old_active; - if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { - if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("local es %s up", es->esi_str); + if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) + return; - SET_FLAG(es->flags, BGP_EVPNES_OPER_UP); - regen_esr = true; - regen_ead = true; - } + old_active = bgp_evpn_local_es_is_active(es); + UNSET_FLAG(es->flags, BGP_EVPNES_OPER_UP); + + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s down", es->esi_str); + + if (old_active) + bgp_evpn_local_es_deactivate(bgp, es); +} + +static void bgp_evpn_local_es_activate(struct bgp *bgp, struct bgp_evpn_es *es, + bool regen_ead, bool regen_esr) +{ + struct prefix_evpn p; if (regen_esr) { if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) @@ -1701,6 +1706,61 @@ static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es, } } +/* Process ES link oper-up by generating ES-EAD and ESR */ +static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es, + bool regen_esr) +{ + bool regen_ead = false; + bool active = false; + + if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s up", es->esi_str); + + SET_FLAG(es->flags, BGP_EVPNES_OPER_UP); + regen_esr = true; + regen_ead = true; + } + + active = bgp_evpn_local_es_is_active(es); + if (active && (regen_ead || regen_esr)) + bgp_evpn_local_es_activate(bgp, es, regen_ead, regen_esr); +} + +/* If an ethernet segment is in LACP bypass we cannot advertise + * reachability to it i.e. EAD-per-ES and ESR is not advertised in + * bypass state. + * PS: EAD-per-EVI will continue to be advertised + */ +static void bgp_evpn_local_es_bypass_update(struct bgp *bgp, + struct bgp_evpn_es *es, bool bypass) +{ + bool old_bypass = !!(es->flags & BGP_EVPNES_BYPASS); + bool old_active; + bool new_active; + + if (bypass == old_bypass) + return; + + old_active = bgp_evpn_local_es_is_active(es); + if (bypass) + SET_FLAG(es->flags, BGP_EVPNES_BYPASS); + else + UNSET_FLAG(es->flags, BGP_EVPNES_BYPASS); + + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s bypass %s", es->esi_str, + bypass ? "set" : "clear"); + + new_active = bgp_evpn_local_es_is_active(es); + if (old_active != new_active) { + if (new_active) + bgp_evpn_local_es_activate(bgp, es, true, true); + else + bgp_evpn_local_es_deactivate(bgp, es); + } +} + static void bgp_evpn_local_es_do_del(struct bgp *bgp, struct bgp_evpn_es *es) { struct bgp_evpn_es_evi *es_evi; @@ -1757,7 +1817,7 @@ int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi) */ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, struct in_addr originator_ip, bool oper_up, - uint16_t df_pref) + uint16_t df_pref, bool bypass) { char buf[ESI_STR_LEN]; struct bgp_evpn_es *es; @@ -1780,8 +1840,9 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, } if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("add local es %s orig-ip %pI4 df_pref %u", es->esi_str, - &originator_ip, df_pref); + zlog_debug("add local es %s orig-ip %pI4 df_pref %u %s", + es->esi_str, &originator_ip, df_pref, + bypass ? "bypass" : ""); es->originator_ip = originator_ip; if (df_pref != es->df_pref) { @@ -1802,6 +1863,8 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, if (bgp_mh_info->ead_evi_adv_for_down_links) bgp_evpn_local_type1_evi_route_add(bgp, es); + bgp_evpn_local_es_bypass_update(bgp, es, bypass); + /* If the ES link is operationally up generate EAD-ES. EAD-EVI * can be generated even if the link is inactive. */ @@ -1952,6 +2015,8 @@ static void bgp_evpn_es_show_entry(struct vty *vty, char vtep_str[ES_VTEP_LIST_STR_SZ + BGP_EVPN_VTEPS_FLAG_STR_SZ]; type_str[0] = '\0'; + if (es->flags & BGP_EVPNES_BYPASS) + strlcat(type_str, "B", sizeof(type_str)); if (es->flags & BGP_EVPNES_LOCAL) strlcat(type_str, "L", sizeof(type_str)); if (es->flags & BGP_EVPNES_REMOTE) @@ -1986,13 +2051,17 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, /* Add the "brief" info first */ bgp_evpn_es_show_entry(vty, es, json); - if (es->flags & (BGP_EVPNES_OPER_UP | BGP_EVPNES_ADV_EVI)) { + if (es->flags + & (BGP_EVPNES_OPER_UP | BGP_EVPNES_ADV_EVI + | BGP_EVPNES_BYPASS)) { json_flags = json_object_new_array(); if (es->flags & BGP_EVPNES_OPER_UP) json_array_string_add(json_flags, "up"); if (es->flags & BGP_EVPNES_ADV_EVI) json_array_string_add(json_flags, "advertiseEVI"); + if (es->flags & BGP_EVPNES_BYPASS) + json_array_string_add(json_flags, "bypass"); json_object_object_add(json, "flags", json_flags); } json_object_string_add(json, "originator_ip", @@ -2045,6 +2114,8 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, if (es->flags & BGP_EVPNES_LOCAL) vty_out(vty, " Local ES DF preference: %u\n", es->df_pref); + if (es->flags & BGP_EVPNES_BYPASS) + vty_out(vty, " LACP bypass: on\n"); vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list)); vty_out(vty, " Remote VNI Count: %d\n", es->remote_es_evi_cnt); @@ -2084,7 +2155,7 @@ void bgp_evpn_es_show(struct vty *vty, bool uj, bool detail) } else { if (!detail) { vty_out(vty, - "ES Flags: L local, R remote, I inconsistent\n"); + "ES Flags: B - bypass, L local, R remote, I inconsistent\n"); vty_out(vty, "VTEP Flags: E ESR/Type-4, A active nexthop\n"); vty_out(vty, @@ -2973,7 +3044,7 @@ static void bgp_evpn_local_es_evi_do_del(struct bgp_evpn_es_evi *es_evi) if (bgp) { /* update EAD-ES with new list of VNIs */ - if (CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { + if (bgp_evpn_local_es_is_active(es)) { build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, &es->esi, es->originator_ip); if (bgp_evpn_type1_route_update(bgp, es, NULL, &p)) @@ -3098,7 +3169,7 @@ int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni) /* update EAD-ES */ build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, &es->esi, es->originator_ip); - if (CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { + if (bgp_evpn_local_es_is_active(es)) { if (bgp_evpn_type1_route_update(bgp, es, NULL, &p)) flog_err(EC_BGP_EVPN_ROUTE_CREATE, "%u: EAD-ES route creation failure for ESI %s VNI %u", @@ -3508,6 +3579,19 @@ void bgp_evpn_es_evi_show_vni(struct vty *vty, vni_t vni, * show commands) at this point. A more drastic action can be executed (based * on user config) in the future. */ +static void bgp_evpn_es_cons_checks_timer_start(void) +{ + if (!bgp_mh_info->consistency_checking || bgp_mh_info->t_cons_check) + return; + + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("periodic consistency checking started"); + + thread_add_timer(bm->master, bgp_evpn_run_consistency_checks, NULL, + BGP_EVPN_CONS_CHECK_INTERVAL, + &bgp_mh_info->t_cons_check); +} + /* queue up the es for background consistency checks */ static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es) { @@ -3519,6 +3603,10 @@ static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es) /* already queued for consistency checking */ return; + /* start the periodic timer for consistency checks if it is not + * already running */ + bgp_evpn_es_cons_checks_timer_start(); + SET_FLAG(es->flags, BGP_EVPNES_CONS_CHECK_PEND); listnode_init(&es->pend_es_listnode, es); listnode_add_after(bgp_mh_info->pend_es_list, @@ -3737,11 +3825,6 @@ void bgp_evpn_mh_init(void) bgp_mh_info->install_l3nhg = false; bgp_mh_info->host_routes_use_l3nhg = BGP_EVPN_MH_USE_ES_L3NHG_DEF; - if (bgp_mh_info->consistency_checking) - thread_add_timer(bm->master, bgp_evpn_run_consistency_checks, - NULL, BGP_EVPN_CONS_CHECK_INTERVAL, - &bgp_mh_info->t_cons_check); - memset(&zero_esi_buf, 0, sizeof(esi_t)); } @@ -3757,7 +3840,8 @@ void bgp_evpn_mh_finish(void) es_next) { bgp_evpn_es_local_info_clear(es); } - thread_cancel(&bgp_mh_info->t_cons_check); + if (bgp_mh_info->t_cons_check) + thread_cancel(&bgp_mh_info->t_cons_check); list_delete(&bgp_mh_info->local_es_list); list_delete(&bgp_mh_info->pend_es_list); diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h index 6199113e87..818fad2eb6 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h @@ -29,7 +29,6 @@ #define BGP_EVPN_AD_EVI_ETH_TAG 0 #define BGP_EVPNES_INCONS_STR_SZ 80 -#define BGP_EVPN_FLAG_STR_SZ 5 #define BGP_EVPN_VTEPS_FLAG_STR_SZ (BGP_EVPN_FLAG_STR_SZ * ES_VTEP_MAX_CNT) #define BGP_EVPN_CONS_CHECK_INTERVAL 60 @@ -62,6 +61,10 @@ struct bgp_evpn_es { #define BGP_EVPNES_ADV_EVI (1 << 3) /* consistency checks pending */ #define BGP_EVPNES_CONS_CHECK_PEND (1 << 4) + /* ES is in LACP bypass mode - don't advertise EAD-ES or ESR */ +#define BGP_EVPNES_BYPASS (1 << 5) + /* bits needed for printing the flags + null */ +#define BGP_EVPN_FLAG_STR_SZ 7 /* memory used for adding the es to bgp->es_rb_tree */ RB_ENTRY(bgp_evpn_es) rb_node; @@ -340,7 +343,7 @@ int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi, uint32_t addpath_id); extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, struct in_addr originator_ip, bool oper_up, - uint16_t df_pref); + uint16_t df_pref, bool bypass); extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi); extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni); extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 5b0b3bb6e5..73bce5df9a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -4803,7 +4803,7 @@ DEFPY_HIDDEN(test_es_add, vtep_ip = bgp->router_id; ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up, - EVPN_MH_DF_PREF_MIN); + EVPN_MH_DF_PREF_MIN, false); if (ret == -1) { vty_out(vty, "%%Failed to add ES\n"); return CMD_WARNING; diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index ff5cfe05fb..37639f4bce 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -616,7 +616,8 @@ void bgp_path_info_mpath_update(struct bgp_dest *dest, all_paths_lb = false; if (debug) { bgp_path_info_path_with_addpath_rx_str( - cur_mpath, path_buf); + cur_mpath, path_buf, + sizeof(path_buf)); zlog_debug( "%pRN: %s is still multipath, cur count %d", bgp_dest_to_rnode(dest), @@ -626,7 +627,8 @@ void bgp_path_info_mpath_update(struct bgp_dest *dest, mpath_changed = 1; if (debug) { bgp_path_info_path_with_addpath_rx_str( - cur_mpath, path_buf); + cur_mpath, path_buf, + sizeof(path_buf)); zlog_debug( "%pRN: remove mpath %s nexthop %s, cur count %d", bgp_dest_to_rnode(dest), @@ -660,7 +662,7 @@ void bgp_path_info_mpath_update(struct bgp_dest *dest, mpath_changed = 1; if (debug) { bgp_path_info_path_with_addpath_rx_str( - cur_mpath, path_buf); + cur_mpath, path_buf, sizeof(path_buf)); zlog_debug( "%pRN: remove mpath %s nexthop %s, cur count %d", bgp_dest_to_rnode(dest), path_buf, @@ -710,7 +712,8 @@ void bgp_path_info_mpath_update(struct bgp_dest *dest, all_paths_lb = false; if (debug) { bgp_path_info_path_with_addpath_rx_str( - new_mpath, path_buf); + new_mpath, path_buf, + sizeof(path_buf)); zlog_debug( "%pRN: add mpath %s nexthop %s, cur count %d", bgp_dest_to_rnode(dest), diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index a3f58db88f..721ce5b5c6 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -69,7 +69,7 @@ int bgp_router_create(struct nb_cb_create_args *args) { const struct lyd_node *vrf_dnode; struct bgp *bgp; - struct vrf *vrf; + const char *vrf_name; const char *name = NULL; as_t as; enum bgp_instance_type inst_type; @@ -87,12 +87,12 @@ int bgp_router_create(struct nb_cb_create_args *args) case NB_EV_APPLY: vrf_dnode = yang_dnode_get_parent(args->dnode, "control-plane-protocol"); - vrf = nb_running_get_entry(vrf_dnode, NULL, true); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); - if (strmatch(vrf->name, VRF_DEFAULT_NAME)) { + if (strmatch(vrf_name, VRF_DEFAULT_NAME)) { name = NULL; } else { - name = vrf->name; + name = vrf_name; inst_type = BGP_INSTANCE_TYPE_VRF; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0f135985ed..d7a4a43633 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -525,13 +525,14 @@ static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp) } } -void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf) +void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf, + size_t buf_len) { if (pi->addpath_rx_id) - sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host, - pi->addpath_rx_id); + snprintf(buf, buf_len, "path %s (addpath rxid %d)", + pi->peer->host, pi->addpath_rx_id); else - sprintf(buf, "path %s", pi->peer->host); + snprintf(buf, buf_len, "path %s", pi->peer->host); } /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. @@ -582,7 +583,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, } if (debug) - bgp_path_info_path_with_addpath_rx_str(new, new_buf); + bgp_path_info_path_with_addpath_rx_str(new, new_buf, + sizeof(new_buf)); if (exist == NULL) { *reason = bgp_path_selection_first; @@ -593,7 +595,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, } if (debug) { - bgp_path_info_path_with_addpath_rx_str(exist, exist_buf); + bgp_path_info_path_with_addpath_rx_str(exist, exist_buf, + sizeof(exist_buf)); zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x", pfx_buf, new_buf, new->flags, exist_buf, exist->flags); @@ -621,10 +624,10 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, prefix2str( bgp_dest_get_prefix(new->net), pfx_buf, sizeof(*pfx_buf) * PREFIX2STR_BUFFER); - bgp_path_info_path_with_addpath_rx_str(new, - new_buf); bgp_path_info_path_with_addpath_rx_str( - exist, exist_buf); + new, new_buf, sizeof(new_buf)); + bgp_path_info_path_with_addpath_rx_str( + exist, exist_buf, sizeof(exist_buf)); } if (newattr->sticky && !existattr->sticky) { @@ -2348,7 +2351,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (debug) { bgp_path_info_path_with_addpath_rx_str( - new_select, path_buf); + new_select, path_buf, sizeof(path_buf)); zlog_debug( "%pBD: %s is the bestpath from AS %u", dest, path_buf, @@ -2422,8 +2425,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, */ if (debug) { if (new_select) - bgp_path_info_path_with_addpath_rx_str(new_select, - path_buf); + bgp_path_info_path_with_addpath_rx_str( + new_select, path_buf, sizeof(path_buf)); else snprintf(path_buf, sizeof(path_buf), "NONE"); zlog_debug( @@ -2438,7 +2441,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (debug) bgp_path_info_path_with_addpath_rx_str( - pi, path_buf); + pi, path_buf, sizeof(path_buf)); if (pi == new_select) { if (debug) @@ -3594,19 +3597,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (has_valid_label) assert(label != NULL); - /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following - * condition : - * Suppress fib is enabled - * BGP_OPT_NO_FIB is not enabled - * Route type is BGP_ROUTE_NORMAL (peer learnt routes) - * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set) - */ - if (BGP_SUPPRESS_FIB_ENABLED(bgp) && - (sub_type == BGP_ROUTE_NORMAL) && - (!bgp_option_check(BGP_OPT_NO_FIB)) && - (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED))) - SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); - /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ if (!soft_reconfig @@ -3788,6 +3778,19 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, evpn == NULL ? NULL : &evpn->gw_ip); } + /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following + * condition : + * Suppress fib is enabled + * BGP_OPT_NO_FIB is not enabled + * Route type is BGP_ROUTE_NORMAL (peer learnt routes) + * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set) + */ + if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp) + && (sub_type == BGP_ROUTE_NORMAL) + && (!bgp_option_check(BGP_OPT_NO_FIB)) + && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED))) + SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); + attr_new = bgp_attr_intern(&new_attr); /* If maximum prefix count is configured and current prefix @@ -6389,7 +6392,8 @@ DEFPY_YANG (bgp_network, bgp_network_cmd, int ret; ret = netmask_str2prefix_str(address_str, netmask_str, - addr_prefix_str); + addr_prefix_str, + sizeof(addr_prefix_str)); if (!ret) { vty_out(vty, "%% Inconsistent address and mask\n"); return CMD_WARNING_CONFIG_FAILED; @@ -7780,7 +7784,8 @@ DEFPY_YANG( char prefix_buf[PREFIX2STR_BUFFER]; if (addr_str) { - if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf) + if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf, + sizeof(prefix_buf)) == 0) { vty_out(vty, "%% Inconsistent address and mask\n"); return CMD_WARNING_CONFIG_FAILED; @@ -14398,7 +14403,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask, char prefix_str[BUFSIZ]; ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, - prefix_str); + prefix_str, sizeof(prefix_str)); if (!ret) { vty_out(vty, "%% Inconsistent address and mask\n"); return CMD_WARNING; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 1060d2e60d..766e5ade92 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -598,7 +598,7 @@ extern void bgp_path_info_set_flag(struct bgp_dest *dest, extern void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *path, uint32_t flag); extern void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, - char *buf); + char *buf, size_t buf_len); extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 3dc2cfbd5c..b7f3289ffc 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -4315,13 +4315,15 @@ DEFUN (match_community, int idx_comm_list = 2; int ret; char *argstr; + size_t argstr_len; if (argc == 4) { - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, - strlen(argv[idx_comm_list]->arg) - + strlen("exact-match") + 2); + argstr_len = strlen(argv[idx_comm_list]->arg) + + strlen("exact-match") + 2; + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); - sprintf(argstr, "%s exact-match", argv[idx_comm_list]->arg); + snprintf(argstr, argstr_len, "%s exact-match", + argv[idx_comm_list]->arg); } else argstr = argv[idx_comm_list]->arg; @@ -4362,13 +4364,15 @@ DEFUN (match_lcommunity, int idx_lcomm_list = 2; int ret; char *argstr; + size_t argstr_len; if (argc == 4) { - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, - strlen(argv[idx_lcomm_list]->arg) - + strlen("exact-match") + 2); + argstr_len = strlen(argv[idx_lcomm_list]->arg) + + strlen("exact-match") + 2; + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); - sprintf(argstr, "%s exact-match", argv[idx_lcomm_list]->arg); + snprintf(argstr, argstr_len, "%s exact-match", + argv[idx_lcomm_list]->arg); } else argstr = argv[idx_lcomm_list]->arg; @@ -5252,6 +5256,7 @@ DEFUN (set_aggregator_as, int ret; struct in_addr address; char *argstr; + size_t argstr_len; ret = inet_aton(argv[idx_ipv4]->arg, &address); if (ret == 0) { @@ -5259,11 +5264,12 @@ DEFUN (set_aggregator_as, return CMD_WARNING_CONFIG_FAILED; } - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, - strlen(argv[idx_number]->arg) - + strlen(argv[idx_ipv4]->arg) + 2); + argstr_len = + strlen(argv[idx_number]->arg) + strlen(argv[idx_ipv4]->arg) + 2; + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); - sprintf(argstr, "%s %s", argv[idx_number]->arg, argv[idx_ipv4]->arg); + snprintf(argstr, argstr_len, "%s %s", argv[idx_number]->arg, + argv[idx_ipv4]->arg); ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "aggregator as", argstr); @@ -5289,6 +5295,7 @@ DEFUN (no_set_aggregator_as, int ret; struct in_addr address; char *argstr; + size_t argstr_len; if (argc <= idx_asn) return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), @@ -5300,11 +5307,11 @@ DEFUN (no_set_aggregator_as, return CMD_WARNING_CONFIG_FAILED; } - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, - strlen(argv[idx_asn]->arg) + strlen(argv[idx_ip]->arg) - + 2); + argstr_len = strlen(argv[idx_asn]->arg) + strlen(argv[idx_ip]->arg) + 2; + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); - sprintf(argstr, "%s %s", argv[idx_asn]->arg, argv[idx_ip]->arg); + snprintf(argstr, argstr_len, "%s %s", argv[idx_asn]->arg, + argv[idx_ip]->arg); ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), "aggregator as", argstr); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ab9e8af96d..9e8065691e 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1483,8 +1483,26 @@ DEFUN_YANG(no_router_bgp, struct bgp *tmp_bgp; for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) { - if (tmp_bgp->inst_type - == BGP_INSTANCE_TYPE_VRF) { + if (tmp_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) + continue; + if (CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_EXPORT) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_EXPORT) || + (bgp == bgp_get_evpn() && + (CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN], + BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST) || + CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN], + BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))) || + (tmp_bgp->vnihash && hashcount(tmp_bgp->vnihash))) { vty_out(vty, "%% Cannot delete default BGP instance. Dependent VRF instances exist\n"); return CMD_WARNING_CONFIG_FAILED; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index d397a5241a..3be721824e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2660,6 +2660,7 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS) char buf[ESI_STR_LEN]; struct in_addr originator_ip; uint8_t active; + uint8_t bypass; uint16_t df_pref; bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -2671,14 +2672,16 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS) originator_ip.s_addr = stream_get_ipv4(s); active = stream_getc(s); df_pref = stream_getw(s); + bypass = stream_getc(s); if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug( - "Rx add ESI %s originator-ip %pI4 active %u df_pref %u", - esi_to_str(&esi, buf, sizeof(buf)), - &originator_ip, active, df_pref); + "Rx add ESI %s originator-ip %pI4 active %u df_pref %u %s", + esi_to_str(&esi, buf, sizeof(buf)), &originator_ip, + active, df_pref, bypass ? "bypass" : ""); - bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref); + bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref, + !!bypass); return 0; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b11fd5288a..07ca247ee6 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -5246,8 +5246,8 @@ int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime) /* Set flag and configuration on peer-group member. */ SET_FLAG(member->flags, PEER_FLAG_TIMER); - PEER_ATTR_INHERIT(peer, peer->group, holdtime); - PEER_ATTR_INHERIT(peer, peer->group, keepalive); + PEER_ATTR_INHERIT(member, peer->group, holdtime); + PEER_ATTR_INHERIT(member, peer->group, keepalive); } return 0; diff --git a/doc/developer/tracing.rst b/doc/developer/tracing.rst index c194ae1270..ae4d621a8e 100644 --- a/doc/developer/tracing.rst +++ b/doc/developer/tracing.rst @@ -62,117 +62,189 @@ use your tracer as usual. To see available USDT probes:: - readelf -n /usr/lib/frr/bgpd + readelf -n /usr/lib/frr/bgpd Example:: - root@host ~> readelf -n /usr/lib/frr/bgpd - - Displaying notes found in: .note.ABI-tag - Owner Data size Description - GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) - OS: Linux, ABI: 3.2.0 - - Displaying notes found in: .note.gnu.build-id - Owner Data size Description - GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) - Build ID: 4f42933a69dcb42a519bc459b2105177c8adf55d - - Displaying notes found in: .note.stapsdt - Owner Data size Description - stapsdt 0x00000045 NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: packet_read - Location: 0x000000000045ee48, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-96(%rbp) 8@-104(%rbp) - stapsdt 0x00000047 NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: open_process - Location: 0x000000000047c43b, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-224(%rbp) 2@-226(%rbp) - stapsdt 0x00000049 NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: update_process - Location: 0x000000000047c4bf, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-208(%rbp) 2@-210(%rbp) - stapsdt 0x0000004f NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: notification_process - Location: 0x000000000047c557, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-192(%rbp) 2@-194(%rbp) - stapsdt 0x0000004c NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: keepalive_process - Location: 0x000000000047c5db, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-176(%rbp) 2@-178(%rbp) - stapsdt 0x0000004a NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: refresh_process - Location: 0x000000000047c673, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-160(%rbp) 2@-162(%rbp) - stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: capability_process - Location: 0x000000000047c6f7, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-144(%rbp) 2@-146(%rbp) - stapsdt 0x0000006f NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: output_filter - Location: 0x000000000048e33a, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) - stapsdt 0x0000007d NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: process_update - Location: 0x0000000000491f10, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-800(%rbp) 8@-808(%rbp) 4@-812(%rbp) 4@-816(%rbp) 4@-820(%rbp) 8@-832(%rbp) - stapsdt 0x0000006e NT_STAPSDT (SystemTap probe descriptors) - Provider: frr_bgp - Name: input_filter - Location: 0x00000000004940ed, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 - Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) + root@host ~> readelf -n /usr/lib/frr/bgpd + + Displaying notes found in: .note.ABI-tag + Owner Data size Description + GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) + OS: Linux, ABI: 3.2.0 + + Displaying notes found in: .note.gnu.build-id + Owner Data size Description + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) + Build ID: 4f42933a69dcb42a519bc459b2105177c8adf55d + + Displaying notes found in: .note.stapsdt + Owner Data size Description + stapsdt 0x00000045 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: packet_read + Location: 0x000000000045ee48, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-96(%rbp) 8@-104(%rbp) + stapsdt 0x00000047 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: open_process + Location: 0x000000000047c43b, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-224(%rbp) 2@-226(%rbp) + stapsdt 0x00000049 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: update_process + Location: 0x000000000047c4bf, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-208(%rbp) 2@-210(%rbp) + stapsdt 0x0000004f NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: notification_process + Location: 0x000000000047c557, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-192(%rbp) 2@-194(%rbp) + stapsdt 0x0000004c NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: keepalive_process + Location: 0x000000000047c5db, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-176(%rbp) 2@-178(%rbp) + stapsdt 0x0000004a NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: refresh_process + Location: 0x000000000047c673, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-160(%rbp) 2@-162(%rbp) + stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: capability_process + Location: 0x000000000047c6f7, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 2@-146(%rbp) + stapsdt 0x0000006f NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: output_filter + Location: 0x000000000048e33a, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) + stapsdt 0x0000007d NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: process_update + Location: 0x0000000000491f10, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-800(%rbp) 8@-808(%rbp) 4@-812(%rbp) 4@-816(%rbp) 4@-820(%rbp) 8@-832(%rbp) + stapsdt 0x0000006e NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: input_filter + Location: 0x00000000004940ed, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) To see available LTTng probes, run the target, create a session and then:: - lttng list --userspace | grep frr + lttng list --userspace | grep frr Example:: - root@host ~> lttng list --userspace | grep frr - PID: 11157 - Name: /usr/lib/frr/bgpd - frr_libfrr:route_node_get (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:list_sort (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:list_delete_node (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:list_remove (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:list_add (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:memfree (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:memalloc (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:frr_pthread_stop (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:frr_pthread_run (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) - frr_libfrr:thread_call (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:thread_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:thread_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:schedule_write (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:schedule_read (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:schedule_event (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:schedule_timer (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:hash_release (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:hash_insert (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_libfrr:hash_get (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:output_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:input_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:process_update (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:packet_read (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:refresh_process (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:capability_process (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:notification_process (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:update_process (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:keepalive_process (loglevel: TRACE_INFO (6)) (type: tracepoint) - frr_bgp:open_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + root@host ~> lttng list --userspace | grep frr + PID: 11157 - Name: /usr/lib/frr/bgpd + frr_libfrr:route_node_get (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_sort (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_delete_node (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_remove (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_add (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:memfree (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:memalloc (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:frr_pthread_stop (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:frr_pthread_run (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:thread_call (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:thread_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:thread_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_write (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_read (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_event (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_timer (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_release (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_insert (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_get (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:output_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:input_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:process_update (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:packet_read (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:refresh_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:capability_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:notification_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:update_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:keepalive_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:open_process (loglevel: TRACE_INFO (6)) (type: tracepoint) When using LTTng, you can also get zlogs as trace events by enabling the ``lttng_ust_tracelog:*`` event class. +To see available SystemTap USDT probes, run:: + + stap -L 'process("/usr/lib/frr/bgpd").mark("*")' + +Example:: + + root@host ~> stap -L 'process("/usr/lib/frr/bgpd").mark("*")' + process("/usr/lib/frr/bgpd").mark("capability_process") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("input_filter") $arg1:long $arg2:long $arg3:long $arg4:long $arg5:long + process("/usr/lib/frr/bgpd").mark("keepalive_process") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("notification_process") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("open_process") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("output_filter") $arg1:long $arg2:long $arg3:long $arg4:long $arg5:long + process("/usr/lib/frr/bgpd").mark("packet_read") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("process_update") $arg1:long $arg2:long $arg3:long $arg4:long $arg5:long $arg6:long + process("/usr/lib/frr/bgpd").mark("refresh_process") $arg1:long $arg2:long + process("/usr/lib/frr/bgpd").mark("update_process") $arg1:long $arg2:long + +When using SystemTap, you can also easily attach to an existing function:: + + stap -L 'process("/usr/lib/frr/bgpd").function("bgp_update_receive")' + +Example:: + + root@host ~> stap -L 'process("/usr/lib/frr/bgpd").function("bgp_update_receive")' + process("/usr/lib/frr/bgpd").function("bgp_update_receive@bgpd/bgp_packet.c:1531") $peer:struct peer* $size:bgp_size_t $attr:struct attr $restart:_Bool $nlris:struct bgp_nlri[] $__func__:char const[] const + +Complete ``bgp.stp`` example using SystemTap to show BGP peer, prefix and aspath +using ``process_update`` USDT:: + + global pkt_size; + probe begin + { + ansi_clear_screen(); + println("Starting..."); + } + probe process("/usr/lib/frr/bgpd").function("bgp_update_receive") + { + pkt_size <<< $size; + } + probe process("/usr/lib/frr/bgpd").mark("process_update") + { + aspath = @cast($arg6, "attr")->aspath; + printf("> %s via %s (%s)\n", + user_string($arg2), + user_string(@cast($arg1, "peer")->host), + user_string(@cast(aspath, "aspath")->str)); + } + probe end + { + if (@count(pkt_size)) + print(@hist_linear(pkt_size, 0, 20, 2)); + } + +Output:: + + Starting... + > 192.168.0.0/24 via 192.168.0.1 (65534) + > 192.168.100.1/32 via 192.168.0.1 (65534) + > 172.16.16.1/32 via 192.168.0.1 (65534 65030) + ^Cvalue |-------------------------------------------------- count + 0 | 0 + 2 | 0 + 4 |@ 1 + 6 | 0 + 8 | 0 + ~ + 18 | 0 + 20 | 0 + >20 |@@@@@ 5 + + Concepts -------- diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 861d87b998..abdbea5a9c 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -563,7 +563,7 @@ In general, code submitted into FRR will be rejected if it uses unsafe programming practices. While there is no enforced overall ruleset, the following requirements have achieved consensus: -- ``strcpy``, ``strcat`` and ``sprintf`` are inacceptable without exception. +- ``strcpy``, ``strcat`` and ``sprintf`` are unacceptable without exception. Use ``strlcpy``, ``strlcat`` and ``snprintf`` instead. (Rationale: even if you know the operation cannot overflow the buffer, a future code change may inadvertedly introduce an overflow.) @@ -1229,9 +1229,9 @@ towards making documentation easier to use, write and maintain. CLI Commands ^^^^^^^^^^^^ -When documenting CLI please use a combination of the ``.. index::`` and -``.. clicmd::`` directives. For example, the command :clicmd:`show pony` would -be documented as follows: +When documenting CLI please use the ``.. clicmd::`` directive. This directive +will format the command and generate index entries automatically. For example, +the command :clicmd:`show pony` would be documented as follows: .. code-block:: rest @@ -1252,6 +1252,7 @@ be documented as follows: hjw |_>|> /_] // /_] /_] + When documented this way, CLI commands can be cross referenced with the ``:clicmd:`` inline markup like so: @@ -1262,8 +1263,27 @@ When documented this way, CLI commands can be cross referenced with the This is very helpful for users who want to quickly remind themselves what a particular command does. -When documenting a cli that has a ``no`` form, please do not include -the ``no`` in the ``.. index::`` line. +When documenting a cli that has a ``no`` form, please do not include the ``no`` +form. I.e. ``no show pony`` would not be documented anywhere. Since most +commands have ``no`` forms, users should be able to infer these or get help +from vtysh's completions. + +When documenting commands that have lots of possible variants, just document +the single command in summary rather than enumerating each possible variant. +E.g. for ``show pony [foo|bar]``, do not: + +.. code-block:: rest + + .. clicmd:: show pony + .. clicmd:: show pony foo + .. clicmd:: show pony bar + +Do: + +.. code-block:: rest + + .. clicmd:: show pony [foo|bar] + Configuration Snippets ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/user/babeld.rst b/doc/user/babeld.rst index 62d50d5d65..7b41988340 100644 --- a/doc/user/babeld.rst +++ b/doc/user/babeld.rst @@ -34,26 +34,22 @@ Configuration of *babeld* is done in its configuration file Babel configuration =================== -.. index:: router babel -.. clicmd:: [no] router babel +.. clicmd:: router babel Enable or disable Babel routing. -.. index:: babel resend-delay (20-655340) -.. clicmd:: [no] babel resend-delay (20-655340) +.. clicmd:: babel resend-delay (20-655340) Specifies the time after which important messages are resent when avoiding a black-hole. The default is 2000 ms. -.. index:: babel diversity -.. clicmd:: [no] babel diversity +.. clicmd:: babel diversity Enable or disable routing using radio frequency diversity. This is highly recommended in networks with many wireless nodes. If you enable this, you will probably want to set `babel diversity-factor` and `babel channel` below. -.. index:: babel diversity-factor (1-256) .. clicmd:: babel diversity-factor (1-256) @@ -63,12 +59,10 @@ Babel configuration no role in route selection; you will probably want to set that to 128 or less on nodes with multiple independent radios. -.. index:: network IFNAME -.. clicmd:: [no] network IFNAME +.. clicmd:: network IFNAME Enable or disable Babel on the given interface. -.. index:: babel <wired|wireless> .. clicmd:: babel <wired|wireless> @@ -77,8 +71,7 @@ Babel configuration Specifying `wireless` (the default) is always correct, but may cause slower convergence and extra routing traffic. -.. index:: babel split-horizon -.. clicmd:: [no] babel split-horizon +.. clicmd:: babel split-horizon Specifies whether to perform split-horizon on the interface. Specifying ``no babel split-horizon`` is always correct, while ``babel @@ -88,7 +81,6 @@ Babel configuration interfaces. This flag is reset when the wired/wireless status of an interface is changed. -.. index:: babel hello-interval (20-655340) .. clicmd:: babel hello-interval (20-655340) @@ -97,7 +89,6 @@ Babel configuration on wireless links, the link quality value is reestimated at every hello interval. The default is 4000 ms. -.. index:: babel update-interval (20-655340) .. clicmd:: babel update-interval (20-655340) @@ -105,7 +96,6 @@ Babel configuration Babel makes extensive use of triggered updates, this can be set to fairly high values on links with little packet loss. The default is 20000 ms. -.. index:: babel channel .. clicmd:: babel channel (1-254) .. clicmd:: babel channel interfering @@ -121,7 +111,6 @@ Babel configuration interfaces. This is reset when the wired/wireless status of an interface is changed. -.. index:: babel rxcost (1-65534) .. clicmd:: babel rxcost (1-65534) @@ -136,7 +125,6 @@ Babel configuration networks, acting directly on the cost using route maps is a better technique. -.. index:: babel rtt-decay (1-256) .. clicmd:: babel rtt-decay (1-256) @@ -144,7 +132,6 @@ Babel configuration RTT samples, in units of 1/256. Higher values discard old samples faster. The default is 42. -.. index:: babel rtt-min (1-65535) .. clicmd:: babel rtt-min (1-65535) @@ -152,14 +139,12 @@ Babel configuration increase the cost to a neighbour. The additional cost is linear in (rtt - rtt-min). The default is 100 ms. -.. index:: babel rtt-max (1-65535) .. clicmd:: babel rtt-max (1-65535) This specifies the maximum RTT, in milliseconds, above which we don't increase the cost to a neighbour. The default is 120 ms. -.. index:: babel max-rtt-penalty (0-65535) .. clicmd:: babel max-rtt-penalty (0-65535) @@ -167,14 +152,12 @@ Babel configuration when the RTT is higher or equal than rtt-max. The default is 0, which effectively disables the use of a RTT-based cost. -.. index:: babel enable-timestamps -.. clicmd:: [no] babel enable-timestamps +.. clicmd:: babel enable-timestamps Enable or disable sending timestamps with each Hello and IHU message in order to compute RTT values. The default is `no babel enable-timestamps`. -.. index:: babel resend-delay (20-655340) .. clicmd:: babel resend-delay (20-655340) @@ -182,7 +165,6 @@ Babel configuration update will be resent. The default is 2000 ms. You probably don't want to tweak this value. -.. index:: babel smoothing-half-life (0-65534) .. clicmd:: babel smoothing-half-life (0-65534) @@ -196,9 +178,8 @@ Babel configuration Babel redistribution ==================== -.. index:: redistribute <ipv4|ipv6> KIND -.. clicmd:: [no] redistribute <ipv4|ipv6> KIND +.. clicmd:: redistribute <ipv4|ipv6> KIND Specify which kind of routes should be redistributed into Babel. @@ -209,50 +190,40 @@ Show Babel information These commands dump various parts of *babeld*'s internal state. -.. index:: show babel route .. clicmd:: show babel route -.. index:: show babel route A.B.C.D .. clicmd:: show babel route A.B.C.D -.. index:: show babel route X:X::X:X .. clicmd:: show babel route X:X::X:X -.. index:: show babel route A.B.C.D/M .. clicmd:: show babel route A.B.C.D/M -.. index:: show babel route X:X::X:X/M .. clicmd:: show babel route X:X::X:X/M -.. index:: show babel interface .. clicmd:: show babel interface -.. index:: show babel interface IFNAME .. clicmd:: show babel interface IFNAME -.. index:: show babel neighbor .. clicmd:: show babel neighbor -.. index:: show babel parameters .. clicmd:: show babel parameters Babel debugging commands ======================== -.. index:: simple: debug babel KIND simple: no debug babel KIND -.. clicmd:: [no] debug babel KIND +.. clicmd:: debug babel KIND Enable or disable debugging messages of a given kind. ``KIND`` can be one of: diff --git a/doc/user/basic.rst b/doc/user/basic.rst index 1ca3ca3cf2..5cbd3692dc 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -11,13 +11,9 @@ The following sections discuss commands common to all the routing daemons. Config Commands =============== -.. index:: Configuration files for running the software -.. index:: Files for running configurations -.. index:: Modifying the herd's behavior -.. index:: Getting the herd running In a config file, you can write the debugging options, a vty's password, routing daemon configurations, a log file name, and so forth. This information @@ -60,25 +56,21 @@ If desired, you can specify a config file using the :option:`-f` or Basic Config Commands --------------------- -.. index:: hostname HOSTNAME .. clicmd:: hostname HOSTNAME Set hostname of the router. -.. index:: password PASSWORD -.. clicmd:: [no] password PASSWORD +.. clicmd:: password PASSWORD Set password for vty interface. The ``no`` form of the command deletes the password. If there is no password, a vty won't accept connections. -.. index:: enable password PASSWORD -.. clicmd:: [no] enable password PASSWORD +.. clicmd:: enable password PASSWORD Set enable password. The ``no`` form of the command deletes the enable password. -.. index:: log trap LEVEL -.. clicmd:: [no] log trap LEVEL +.. clicmd:: log trap LEVEL These commands are deprecated and are present only for historical compatibility. The log trap command sets the current logging level for all @@ -88,9 +80,8 @@ Basic Config Commands future logging commands to debugging, but it does not change the logging level of existing logging destinations. -.. index:: log stdout [LEVEL] -.. clicmd:: [no] log stdout LEVEL +.. clicmd:: log stdout LEVEL Enable logging output to stdout. If the optional second argument specifying the logging level is not present, the default logging level (typically @@ -109,8 +100,7 @@ Basic Config Commands terminal output. Use a log file and ``tail -f`` if this rare chance is inacceptable to your setup. -.. index:: log file FILENAME [LEVEL] -.. clicmd:: [no] log file [FILENAME [LEVEL]] +.. clicmd:: log file [FILENAME [LEVEL]] If you want to log into a file, please specify ``filename`` as in this example: @@ -124,16 +114,14 @@ Basic Config Commands deprecated ``log trap`` command) will be used. The ``no`` form of the command disables logging to a file. -.. index:: log syslog [LEVEL] -.. clicmd:: [no] log syslog [LEVEL] +.. clicmd:: log syslog [LEVEL] Enable logging output to syslog. If the optional second argument specifying the logging level is not present, the default logging level (typically debugging, but can be changed using the deprecated ``log trap`` command) will be used. The ``no`` form of the command disables logging to syslog. -.. index:: log monitor [LEVEL] -.. clicmd:: [no] log monitor [LEVEL] +.. clicmd:: log monitor [LEVEL] Enable logging output to vty terminals that have enabled logging using the ``terminal monitor`` command. By default, monitor logging is enabled at the @@ -143,15 +131,13 @@ Basic Config Commands level (typically debugging) will be used. The ``no`` form of the command disables logging to terminal monitors. -.. index:: log facility [FACILITY] -.. clicmd:: [no] log facility [FACILITY] +.. clicmd:: log facility [FACILITY] This command changes the facility used in syslog messages. The default facility is ``daemon``. The ``no`` form of the command resets the facility to the default ``daemon`` facility. -.. index:: log record-priority -.. clicmd:: [no] log record-priority +.. clicmd:: log record-priority To include the severity in all messages logged to a file, to stdout, or to a terminal monitor (i.e. anything except syslog), @@ -161,8 +147,7 @@ Basic Config Commands versions of syslogd can be configured to include the facility and level in the messages emitted. -.. index:: log timestamp precision (0-6) -.. clicmd:: [no] log timestamp precision [(0-6)] +.. clicmd:: log timestamp precision [(0-6)] This command sets the precision of log message timestamps to the given number of digits after the decimal point. Currently, the value must be in @@ -177,8 +162,7 @@ Basic Config Commands In this example, the precision is set to provide timestamps with millisecond accuracy. -.. index:: log commands -.. clicmd:: [no] log commands +.. clicmd:: log commands This command enables the logging of all commands typed by a user to all enabled log destinations. The note that logging includes full command lines, @@ -186,8 +170,7 @@ Basic Config Commands is used to start the daemon then this command is turned on by default and cannot be turned off and the [no] form of the command is dissallowed. -.. index:: log-filter WORD [DAEMON] -.. clicmd:: [no] log-filter WORD [DAEMON] +.. clicmd:: log-filter WORD [DAEMON] This command forces logs to be filtered on a specific string. A log message will only be printed if it matches on one of the filters in the log-filter @@ -200,55 +183,41 @@ Basic Config Commands Log filters prevent this but you should still expect a small performance hit due to filtering each of all those logs. -.. index:: log-filter clear [DAEMON] .. clicmd:: log-filter clear [DAEMON] This command clears all current filters in the log-filter table. Can be daemon independent. -.. index:: service password-encryption .. clicmd:: service password-encryption Encrypt password. -.. index:: service advanced-vty .. clicmd:: service advanced-vty Enable advanced mode VTY. -.. index:: service terminal-length (0-512) .. clicmd:: service terminal-length (0-512) Set system wide line configuration. This configuration command applies to all VTY interfaces. -.. index:: line vty .. clicmd:: line vty Enter vty configuration mode. -.. index:: banner motd default .. clicmd:: banner motd default Set default motd string. -.. index:: banner motd file FILE .. clicmd:: banner motd file FILE Set motd string from file. The file must be in directory specified under ``--sysconfdir``. -.. index:: banner motd line LINE .. clicmd:: banner motd line LINE Set motd string from an input. -.. index:: banner motd -.. clicmd:: no banner motd - - No motd banner string will be printed. - -.. index:: exec-timeout MINUTE [SECOND] .. clicmd:: exec-timeout MINUTE [SECOND] Set VTY connection timeout value. When only one argument is specified @@ -256,13 +225,9 @@ Basic Config Commands used for timeout value in seconds. Default timeout value is 10 minutes. When timeout value is zero, it means no timeout. -.. index:: exec-timeout -.. clicmd:: no exec-timeout - - Do not perform timeout at all. This command is as same as - ``exec-timeout 0 0``. + Not setting this, or setting the values to 0 0, means a timeout will not be + enabled. -.. index:: access-class ACCESS-LIST .. clicmd:: access-class ACCESS-LIST Restrict vty connections with an access list. @@ -440,55 +405,45 @@ Puppet, etc.), upgrade considerations differ somewhat: Terminal Mode Commands ====================== -.. index:: write terminal .. clicmd:: write terminal Displays the current configuration to the vty interface. -.. index:: write file .. clicmd:: write file Write current configuration to configuration file. -.. index:: configure [terminal] .. clicmd:: configure [terminal] Change to configuration mode. This command is the first step to configuration. -.. index:: terminal length (0-512) .. clicmd:: terminal length (0-512) Set terminal display length to ``(0-512)``. If length is 0, no display control is performed. -.. index:: who .. clicmd:: who Show a list of currently connected vty sessions. -.. index:: list .. clicmd:: list List all available commands. -.. index:: show version .. clicmd:: show version Show the current version of |PACKAGE_NAME| and its build host information. -.. index:: show logging .. clicmd:: show logging Shows the current configuration of the logging system. This includes the status of all logging destinations. -.. index:: show log-filter .. clicmd:: show log-filter Shows the current log filters applied to each daemon. -.. index:: show memory .. clicmd:: show memory Show information on how much memory is used for which specific things in @@ -549,18 +504,15 @@ Terminal Mode Commands When executing this command from ``vtysh``, each of the daemons' memory usage is printed sequentially. -.. index:: show history .. clicmd:: show history Dump the vtysh cli history. -.. index:: logmsg LEVEL MESSAGE .. clicmd:: logmsg LEVEL MESSAGE Send a message to all logging destinations that are enabled for messages of the given severity. -.. index:: find COMMAND... .. clicmd:: find COMMAND... This command performs a simple substring search across all defined commands @@ -589,7 +541,6 @@ Terminal Mode Commands .. _common-show-commands: -.. index:: show thread cpu .. clicmd:: show thread cpu [r|w|t|e|x] This command displays system run statistics for all the different event @@ -598,7 +549,6 @@ Terminal Mode Commands (e)vent and e(x)ecute thread event types. If you have compiled with disable-cpu-time then this command will not show up. -.. index:: show thread poll .. clicmd:: show thread poll This command displays FRR's poll data. It allows a glimpse into how diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index 6c83ffa19a..b8f749b740 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -90,12 +90,10 @@ may also be specified (:ref:`common-invocation-options`). BFDd Commands ============= -.. index:: bfd .. clicmd:: bfd Opens the BFD daemon configuration node. -.. index:: peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}] .. clicmd:: peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}] Creates and configures a new BFD peer to listen and talk to. @@ -113,41 +111,27 @@ BFDd Commands `vrf` selects which domain we want to use. -.. index:: peer <A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname|vrf NAME$vrf_name}] -.. clicmd:: no peer <A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname|vrf NAME$vrf_name}] - Stops and removes the selected peer. - - -.. index:: profile WORD .. clicmd:: profile WORD Creates a peer profile that can be configured in multiple peers. + Deleting the profile will cause all peers using it to reset to the default + values. -.. index:: profile WORD -.. clicmd:: no profile WORD - - Deletes a peer profile. Any peer using the profile will have their - configurations reset to the default values. - -.. index:: show bfd [vrf NAME] peers [json] .. clicmd:: show bfd [vrf NAME] peers [json] Show all configured BFD peers information and current status. -.. index:: show bfd [vrf NAME$vrf_name] peer <WORD$label|<A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname}]> [json] .. clicmd:: show bfd [vrf NAME$vrf_name] peer <WORD$label|<A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname}]> [json] Show status for a specific BFD peer. -.. index:: show bfd [vrf NAME] peers brief [json] .. clicmd:: show bfd [vrf NAME] peers brief [json] Show all configured BFD peers information and current status in brief. -.. index:: show bfd distributed .. clicmd:: show bfd distributed Show the BFD data plane (distributed BFD) statistics. @@ -160,7 +144,6 @@ Peer / Profile Configuration BFD peers and profiles share the same BFD session configuration commands. -.. index:: detect-multiplier (2-255) .. clicmd:: detect-multiplier (2-255) Configures the detection multiplier to determine packet loss. The @@ -173,26 +156,22 @@ BFD peers and profiles share the same BFD session configuration commands. detect failures only after 900 milliseconds without receiving packets. -.. index:: receive-interval (10-60000) .. clicmd:: receive-interval (10-60000) Configures the minimum interval that this system is capable of receiving control packets. The default value is 300 milliseconds. -.. index:: transmit-interval (10-60000) .. clicmd:: transmit-interval (10-60000) The minimum transmission interval (less jitter) that this system wants to use to send BFD control packets. Defaults to 300ms. -.. index:: echo-interval (10-60000) .. clicmd:: echo-interval (10-60000) Configures the minimal echo receive transmission interval that this system is capable of handling. -.. index:: echo-mode -.. clicmd:: [no] echo-mode +.. clicmd:: echo-mode Enables or disables the echo transmission mode. This mode is disabled by default. @@ -204,15 +183,13 @@ BFD peers and profiles share the same BFD session configuration commands. Echo mode is not supported on multi-hop setups (see :rfc:`5883` section 3). -.. index:: shutdown -.. clicmd:: [no] shutdown +.. clicmd:: shutdown Enables or disables the peer. When the peer is disabled an 'administrative down' message is sent to the remote peer. -.. index:: passive-mode -.. clicmd:: [no] passive-mode +.. clicmd:: passive-mode Mark session as passive: a passive session will not attempt to start the connection and will wait for control packets from peer before it @@ -224,8 +201,7 @@ BFD peers and profiles share the same BFD session configuration commands. The default is active-mode (or ``no passive-mode``). -.. index:: minimum-ttl (1-254) -.. clicmd:: [no] minimum-ttl (1-254) +.. clicmd:: minimum-ttl (1-254) For multi hop sessions only: configure the minimum expected TTL for an incoming BFD control packet. @@ -241,14 +217,12 @@ BFD peers and profiles share the same BFD session configuration commands. BFD Peer Specific Commands -------------------------- -.. index:: label WORD .. clicmd:: label WORD Labels a peer with the provided word. This word can be referenced later on other daemons to refer to a specific peer. -.. index:: profile BFDPROF .. clicmd:: profile BFDPROF Configure peer to use the profile configurations. @@ -270,7 +244,6 @@ BGP BFD Configuration The following commands are available inside the BGP configuration node. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd Listen for BFD events registered on the same target as this BGP @@ -278,12 +251,7 @@ The following commands are available inside the BGP configuration node. the connection with its neighbor and, when it goes back up, notify BGP to try to connect to it. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd -.. clicmd:: no neighbor <A.B.C.D|X:X::X:X|WORD> bfd - - Removes any notification registration for this neighbor. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure Allow to write CBIT independence in BFD outgoing packets. Also allow to @@ -293,26 +261,16 @@ The following commands are available inside the BGP configuration node. This is the case when graceful restart is enabled, and it is wished to ignore the BD event while waiting for the remote router to restart. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure -.. clicmd:: no neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure + Disabling this disables presence of CBIT independence in BFD outgoing + packets and pays attention to BFD down notifications. This is the default. - Disallow to write CBIT independence in BFD outgoing packets. Also disallow - to ignore BFD down notification. This is the default behaviour. - -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF Same as command ``neighbor <A.B.C.D|X:X::X:X|WORD> bfd``, but applies the BFD profile to the sessions it creates or that already exist. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF -.. clicmd:: no neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF - - Removes the BFD profile configuration from peer session(s). - - .. _bfd-isis-peer-config: IS-IS BFD Configuration @@ -320,31 +278,20 @@ IS-IS BFD Configuration The following commands are available inside the interface configuration node. -.. index:: isis bfd .. clicmd:: isis bfd Listen for BFD events on peers created on the interface. Every time a new neighbor is found a BFD peer is created to monitor the link status for fast convergence. -.. index:: isis bfd -.. clicmd:: no isis bfd - - Removes any notification registration for this interface peers. - Note that there will be just one BFD session per interface. In case both IPv4 and IPv6 support are configured then just a IPv6 based session is created. -.. index:: isis bfd profile BFDPROF .. clicmd:: isis bfd profile BFDPROF Use a BFD profile BFDPROF as provided in the BFD configuration. -.. index:: isis bfd profile BFDPROF -.. clicmd:: no isis bfd profile BFDPROF - - Removes any BFD profile if present. .. _bfd-ospf-peer-config: @@ -353,18 +300,12 @@ OSPF BFD Configuration The following commands are available inside the interface configuration node. -.. index:: ip ospf bfd .. clicmd:: ip ospf bfd Listen for BFD events on peers created on the interface. Every time a new neighbor is found a BFD peer is created to monitor the link status for fast convergence. -.. index:: ip ospf bfd -.. clicmd:: no ip ospf bfd - - Removes any notification registration for this interface peers. - .. _bfd-ospf6-peer-config: @@ -373,18 +314,12 @@ OSPF6 BFD Configuration The following commands are available inside the interface configuration node. -.. index:: ipv6 ospf6 bfd .. clicmd:: ipv6 ospf6 bfd Listen for BFD events on peers created on the interface. Every time a new neighbor is found a BFD peer is created to monitor the link status for fast convergence. -.. index:: ipv6 ospf6 bfd -.. clicmd:: no ipv6 ospf6 bfd - - Removes any notification registration for this interface peers. - .. _bfd-pim-peer-config: @@ -393,18 +328,12 @@ PIM BFD Configuration The following commands are available inside the interface configuration node. -.. index:: ip pim bfd .. clicmd:: ip pim bfd Listen for BFD events on peers created on the interface. Every time a new neighbor is found a BFD peer is created to monitor the link status for fast convergence. -.. index:: ip pim bfd -.. clicmd:: no ip pim bfd - - Removes any notification registration for this interface peers. - .. _bfd-configuration: @@ -721,8 +650,7 @@ sure you have `debugging` level enabled: You may also fine tune the debug messages by selecting one or more of the debug levels: -.. index:: debug bfd distributed -.. clicmd:: [no] debug bfd distributed +.. clicmd:: debug bfd distributed Toggle BFD data plane (distributed BFD) debugging. @@ -731,20 +659,17 @@ debug levels: * Data plane received / send messages * Connection events -.. index:: debug bfd network -.. clicmd:: [no] debug bfd network +.. clicmd:: debug bfd network Toggle network events: show messages about socket failures and unexpected BFD messages that may not belong to registered peers. -.. index:: debug bfd peer -.. clicmd:: [no] debug bfd peer +.. clicmd:: debug bfd peer Toggle peer event log messages: show messages about peer creation/removal and state changes. -.. index:: debug bfd zebra -.. clicmd:: [no] debug bfd zebra +.. clicmd:: debug bfd zebra Toggle zebra message events: show messages about interfaces, local addresses, VRF and daemon peer registrations. diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index cb97ee22df..da6c0d9824 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -252,18 +252,11 @@ command. The AS number is an identifier for the autonomous system. The BGP protocol uses the AS number for detecting whether the BGP connection is internal or external. -.. index:: router bgp ASN .. clicmd:: router bgp ASN Enable a BGP protocol process with the specified ASN. After this statement you can input any `BGP Commands`. -.. index:: router bgp ASN -.. clicmd:: no router bgp ASN - - Destroy a BGP protocol process with the specified ASN. - -.. index:: bgp router-id A.B.C.D .. clicmd:: bgp router-id A.B.C.D This command specifies the router-ID. If *bgpd* connects to *zebra* it gets @@ -301,7 +294,6 @@ However, the same AS can be used with different VRFs. Configuration of additional autonomous systems, or of a router that targets a specific VRF, is accomplished with the following command: -.. index:: router bgp ASN vrf VRFNAME .. clicmd:: router bgp ASN vrf VRFNAME ``VRFNAME`` is matched against VRFs configured in the kernel. When ``vrf @@ -344,7 +336,6 @@ via BGP. Multiple views can be supported, and BGP view information is always independent from other routing protocols and Zebra/kernel routes. BGP views use the core instance (i.e., default VRF) for communication with peers. -.. index:: router bgp AS-NUMBER view NAME .. clicmd:: router bgp AS-NUMBER view NAME Make a new BGP view. You can use an arbitrary word for the ``NAME``. Routes @@ -363,7 +354,6 @@ the core instance (i.e., default VRF) for communication with peers. neighbor 10.0.0.3 remote-as 4 neighbor 10.0.0.4 remote-as 5 -.. index:: show [ip] bgp view NAME .. clicmd:: show [ip] bgp view NAME Display the routing table of BGP view ``NAME``. @@ -372,14 +362,12 @@ the core instance (i.e., default VRF) for communication with peers. Route Selection --------------- -.. index:: bgp bestpath as-path confed .. clicmd:: bgp bestpath as-path confed This command specifies that the length of confederation path sets and sequences should should be taken into account during the BGP best path decision process. -.. index:: bgp bestpath as-path multipath-relax .. clicmd:: bgp bestpath as-path multipath-relax This command specifies that BGP decision process should consider paths @@ -411,17 +399,14 @@ Route Selection Administrative Distance Metrics ------------------------------- -.. index:: distance bgp (1-255) (1-255) (1-255) .. clicmd:: distance bgp (1-255) (1-255) (1-255) This command change distance value of BGP. The arguments are the distance values for for external routes, internal routes and local routes respectively. -.. index:: distance (1-255) A.B.C.D/M .. clicmd:: distance (1-255) A.B.C.D/M -.. index:: distance (1-255) A.B.C.D/M WORD .. clicmd:: distance (1-255) A.B.C.D/M WORD Sets the administrative distance for a particular route. @@ -431,8 +416,7 @@ Administrative Distance Metrics Require policy on EBGP ------------------------------- -.. index:: bgp ebgp-requires-policy -.. clicmd:: [no] bgp ebgp-requires-policy +.. clicmd:: bgp ebgp-requires-policy This command requires incoming and outgoing filters to be applied for eBGP sessions as part of RFC-8212 compliance. Without the incoming @@ -480,16 +464,14 @@ Require policy on EBGP Reject routes with AS_SET or AS_CONFED_SET types ------------------------------------------------ -.. index:: bgp reject-as-sets -.. clicmd:: [no] bgp reject-as-sets +.. clicmd:: bgp reject-as-sets This command enables rejection of incoming and outgoing routes having AS_SET or AS_CONFED_SET type. Suppress duplicate updates -------------------------- -.. index:: bgp suppress-duplicates -.. clicmd:: [no] bgp suppress-duplicates +.. clicmd:: bgp suppress-duplicates For example, BGP routers can generate multiple identical announcements with empty community attributes if stripped at egress. This is an undesired behavior. @@ -499,8 +481,7 @@ Suppress duplicate updates Disable checking if nexthop is connected on EBGP sessions --------------------------------------------------------- -.. index:: bgp disable-ebgp-connected-route-check -.. clicmd:: [no] bgp disable-ebgp-connected-route-check +.. clicmd:: bgp disable-ebgp-connected-route-check This command is used to disable the connection verification process for EBGP peering sessions that are reachable by a single hop but are configured on a loopback interface or otherwise @@ -511,20 +492,17 @@ Disable checking if nexthop is connected on EBGP sessions Route Flap Dampening -------------------- -.. index:: [no] bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]] -.. clicmd:: [no] bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]] This command enables (with optionally specified dampening parameters) or disables route-flap dampening for all routes of a BGP instance. -.. index:: [no] neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] -.. clicmd:: [no] neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] This command enables (with optionally specified dampening parameters) or disables route-flap dampening for all routes learned from a BGP peer. -.. index:: [no] neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] -.. clicmd:: [no] neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] This command enables (with optionally specified dampening parameters) or disables route-flap dampening for all routes learned from peers of a peer @@ -769,7 +747,6 @@ topologies are at cross-purposes with each other - see the Flavel and Roughan paper above for an example. Hence the guideline that the iBGP topology should follow the IGP topology. -.. index:: bgp deterministic-med .. clicmd:: bgp deterministic-med Carry out route-selection in way that produces deterministic answers @@ -789,7 +766,6 @@ Note that there are other sources of indeterminism in the route selection process, specifically, the preference for older and already selected routes from eBGP peers, :ref:`bgp-route-selection`. -.. index:: bgp always-compare-med .. clicmd:: bgp always-compare-med Always compare the MED on routes, even when they were received from @@ -893,7 +869,6 @@ forwarding state has been preserved. The remaining bits are reserved and MUST be set to zero by the sender and ignored by the receiver. -.. index:: bgp graceful-restart preserve-fw-state .. clicmd:: bgp graceful-restart preserve-fw-state FRR gives us the option to enable/disable the "F" flag using this specific @@ -943,18 +918,15 @@ However, it MUST defer route selection for an address family until it either. that do not advertise the graceful restart capability). 2. The Selection_Deferral_Timer timeout. -.. index:: bgp graceful-restart select-defer-time (0-3600) .. clicmd:: bgp graceful-restart select-defer-time (0-3600) This is command, will set deferral time to value specified. -.. index:: bgp graceful-restart rib-stale-time (1-3600) .. clicmd:: bgp graceful-restart rib-stale-time (1-3600) This is command, will set the time for which stale routes are kept in RIB. -.. index:: bgp graceful-restart stalepath-time (1-4095) .. clicmd:: bgp graceful-restart stalepath-time (1-4095) This is command, will set the max time (in seconds) to hold onto @@ -988,13 +960,11 @@ override the global mode. BGP GR Global Mode Commands ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: bgp graceful-restart .. clicmd:: bgp graceful-restart This command will enable BGP graceful restart ifunctionality at the global level. -.. index:: bgp graceful-restart disable .. clicmd:: bgp graceful-restart disable This command will disable both the functionality graceful restart and helper @@ -1006,19 +976,16 @@ BGP GR Global Mode Commands BGP GR Peer Mode Commands ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: neighbor A.B.C.D graceful-restart .. clicmd:: neighbor A.B.C.D graceful-restart This command will enable BGP graceful restart ifunctionality at the peer level. -.. index:: neighbor A.B.C.D graceful-restart-helper .. clicmd:: neighbor A.B.C.D graceful-restart-helper This command will enable BGP graceful restart helper only functionality at the peer level. -.. index:: neighbor A.B.C.D graceful-restart-disable .. clicmd:: neighbor A.B.C.D graceful-restart-disable This command will disable the entire BGP graceful restart functionality @@ -1030,8 +997,7 @@ BGP GR Peer Mode Commands Administrative Shutdown ----------------------- -.. index:: bgp shutdown [message MSG...] -.. clicmd:: [no] bgp shutdown [message MSG...] +.. clicmd:: bgp shutdown [message MSG...] Administrative shutdown of all peers of a bgp instance. Drop all BGP peers, but preserve their configurations. The peers are notified in accordance with @@ -1049,7 +1015,6 @@ Administrative Shutdown Networks -------- -.. index:: network A.B.C.D/M .. clicmd:: network A.B.C.D/M This command adds the announcement network. @@ -1066,11 +1031,8 @@ Networks routes if they aren't present in their IGP routing tables; `bgpd` doesn't care about IGP routes when announcing its routes. -.. index:: network A.B.C.D/M -.. clicmd:: no network A.B.C.D/M -.. index:: bgp network import-check -.. clicmd:: [no] bgp network import-check +.. clicmd:: bgp network import-check This configuration modifies the behavior of the network statement. If you have this configured the underlying network must exist in @@ -1085,8 +1047,7 @@ Networks IPv6 Support ------------ -.. index:: neighbor A.B.C.D activate -.. clicmd:: [no] neighbor A.B.C.D activate +.. clicmd:: neighbor A.B.C.D activate This configuration modifies whether to enable an address family for a specific neighbor. By default only the IPv4 unicast address family is @@ -1137,53 +1098,41 @@ Route Aggregation Route Aggregation-IPv4 Address Family ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: aggregate-address A.B.C.D/M .. clicmd:: aggregate-address A.B.C.D/M This command specifies an aggregate address. -.. index:: aggregate-address A.B.C.D/M route-map NAME .. clicmd:: aggregate-address A.B.C.D/M route-map NAME Apply a route-map for an aggregated prefix. -.. index:: aggregate-address A.B.C.D/M origin <egp|igp|incomplete> .. clicmd:: aggregate-address A.B.C.D/M origin <egp|igp|incomplete> Override ORIGIN for an aggregated prefix. -.. index:: aggregate-address A.B.C.D/M as-set .. clicmd:: aggregate-address A.B.C.D/M as-set This command specifies an aggregate address. Resulting routes include AS set. -.. index:: aggregate-address A.B.C.D/M summary-only .. clicmd:: aggregate-address A.B.C.D/M summary-only This command specifies an aggregate address. Aggregated routes will not be announced. -.. index:: aggregate-address A.B.C.D/M matching-MED-only .. clicmd:: aggregate-address A.B.C.D/M matching-MED-only Configure the aggregated address to only be created when the routes MED match, otherwise no aggregated route will be created. -.. index:: aggregate-address A.B.C.D/M suppress-map NAME .. clicmd:: aggregate-address A.B.C.D/M suppress-map NAME Similar to `summary-only`, but will only suppress more specific routes that are matched by the selected route-map. -.. index:: aggregate-address A.B.C.D/M -.. clicmd:: no aggregate-address A.B.C.D/M - - This command removes an aggregate address. - - This configuration example setup the aggregate-address under - ipv4 address-family. + This configuration example sets up an ``aggregate-address`` under the ipv4 + address-family. .. code-block:: frr @@ -1201,53 +1150,41 @@ Route Aggregation-IPv4 Address Family Route Aggregation-IPv6 Address Family ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: aggregate-address X:X::X:X/M .. clicmd:: aggregate-address X:X::X:X/M This command specifies an aggregate address. -.. index:: aggregate-address X:X::X:X/M route-map NAME .. clicmd:: aggregate-address X:X::X:X/M route-map NAME Apply a route-map for an aggregated prefix. -.. index:: aggregate-address X:X::X:X/M origin <egp|igp|incomplete> .. clicmd:: aggregate-address X:X::X:X/M origin <egp|igp|incomplete> Override ORIGIN for an aggregated prefix. -.. index:: aggregate-address X:X::X:X/M as-set .. clicmd:: aggregate-address X:X::X:X/M as-set This command specifies an aggregate address. Resulting routes include AS set. -.. index:: aggregate-address X:X::X:X/M summary-only .. clicmd:: aggregate-address X:X::X:X/M summary-only This command specifies an aggregate address. Aggregated routes will not be announced. -.. index:: aggregate-address X:X::X:X/M matching-MED-only .. clicmd:: aggregate-address X:X::X:X/M matching-MED-only Configure the aggregated address to only be created when the routes MED match, otherwise no aggregated route will be created. -.. index:: aggregate-address X:X::X:X/M suppress-map NAME .. clicmd:: aggregate-address X:X::X:X/M suppress-map NAME Similar to `summary-only`, but will only suppress more specific routes that are matched by the selected route-map. -.. index:: aggregate-address X:X::X:X/M -.. clicmd:: no aggregate-address X:X::X:X/M - - This command removes an aggregate address. - - This configuration example setup the aggregate-address under - ipv6 address-family. + This configuration example sets up an ``aggregate-address`` under the ipv6 + address-family. .. code-block:: frr @@ -1259,50 +1196,27 @@ Route Aggregation-IPv6 Address Family aggregate-address 50::0/64 route-map aggr-rmap exit-address-family + .. _bgp-redistribute-to-bgp: Redistribution -------------- -.. index:: redistribute kernel -.. clicmd:: redistribute kernel - - Redistribute kernel route to BGP process. - -.. index:: redistribute static -.. clicmd:: redistribute static +Redistribution configuration should be placed under the ``address-family`` +section for the specific AF to redistribute into. Protocol availability for +redistribution is determined by BGP AF; for example, you cannot redistribute +OSPFv3 into ``address-family ipv4 unicast`` as OSPFv3 supports IPv6. - Redistribute static route to BGP process. +.. clicmd:: redistribute <babel|connected|eigrp|isis|kernel|openfabric|ospf|ospf6|rip|ripng|sharp|static|table> [metric (0-4294967295)] [route-map WORD] -.. index:: redistribute connected -.. clicmd:: redistribute connected +Redistribute routes from other protocols into BGP. - Redistribute connected route to BGP process. - -.. index:: redistribute rip -.. clicmd:: redistribute rip - - Redistribute RIP route to BGP process. - -.. index:: redistribute ospf -.. clicmd:: redistribute ospf - - Redistribute OSPF route to BGP process. - -.. index:: redistribute vnc -.. clicmd:: redistribute vnc - - Redistribute VNC routes to BGP process. - -.. index:: redistribute vnc-direct .. clicmd:: redistribute vnc-direct Redistribute VNC direct (not via zebra) routes to BGP process. -.. index:: bgp update-delay MAX-DELAY .. clicmd:: bgp update-delay MAX-DELAY -.. index:: bgp update-delay MAX-DELAY ESTABLISH-WAIT .. clicmd:: bgp update-delay MAX-DELAY ESTABLISH-WAIT This feature is used to enable read-only mode on BGP process restart or when @@ -1334,10 +1248,8 @@ Redistribution Default max-delay is 0, i.e. the feature is off by default. -.. index:: update-delay MAX-DELAY .. clicmd:: update-delay MAX-DELAY -.. index:: update-delay MAX-DELAY ESTABLISH-WAIT .. clicmd:: update-delay MAX-DELAY ESTABLISH-WAIT This feature is used to enable read-only mode on BGP process restart or when @@ -1368,7 +1280,6 @@ Redistribution Default max-delay is 0, i.e. the feature is off by default. -.. index:: table-map ROUTE-MAP-NAME .. clicmd:: table-map ROUTE-MAP-NAME This feature is used to apply a route-map on route updates from BGP to @@ -1390,7 +1301,6 @@ Peers Defining Peers ^^^^^^^^^^^^^^ -.. index:: neighbor PEER remote-as ASN .. clicmd:: neighbor PEER remote-as ASN Creates a new neighbor whose remote-as is ASN. PEER can be an IPv4 address @@ -1408,22 +1318,19 @@ Defining Peers can't find neighbor 10.0.0.1 -.. index:: neighbor PEER remote-as internal .. clicmd:: neighbor PEER remote-as internal Create a peer as you would when you specify an ASN, except that if the peers ASN is different than mine as specified under the :clicmd:`router bgp ASN` command the connection will be denied. -.. index:: neighbor PEER remote-as external .. clicmd:: neighbor PEER remote-as external Create a peer as you would when you specify an ASN, except that if the peers ASN is the same as mine as specified under the :clicmd:`router bgp ASN` command the connection will be denied. -.. index:: bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME -.. clicmd:: [no] bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME +.. clicmd:: bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME Accept connections from any peers in the specified prefix. Configuration from the specified peer-group is used to configure these peers. @@ -1446,8 +1353,7 @@ Defining Peers ``net.core.optmem_max`` to allow the kernel to allocate the necessary option memory. -.. index:: coalesce-time (0-4294967295) -.. clicmd:: [no] coalesce-time (0-4294967295) +.. clicmd:: coalesce-time (0-4294967295) The time in milliseconds that BGP will delay before deciding what peers can be put into an update-group together in order to generate a single @@ -1458,8 +1364,7 @@ Defining Peers Configuring Peers ^^^^^^^^^^^^^^^^^ -.. index:: neighbor PEER shutdown [message MSG...] [rtt (1-65535) [count (1-255)]] -.. clicmd:: [no] neighbor PEER shutdown [message MSG...] [rtt (1-65535) [count (1-255)]] +.. clicmd:: neighbor PEER shutdown [message MSG...] [rtt (1-65535) [count (1-255)]] Shutdown the peer. We can delete the neighbor's configuration by ``no neighbor PEER remote-as ASN`` but all configuration of the neighbor @@ -1474,14 +1379,12 @@ Configuring Peers Additional ``count`` parameter is the number of keepalive messages to count before shutdown the peer if round-trip-time becomes higher than defined. -.. index:: neighbor PEER disable-connected-check -.. clicmd:: [no] neighbor PEER disable-connected-check +.. clicmd:: neighbor PEER disable-connected-check Allow peerings between directly connected eBGP peers using loopback addresses. -.. index:: neighbor PEER ebgp-multihop -.. clicmd:: [no] neighbor PEER ebgp-multihop +.. clicmd:: neighbor PEER ebgp-multihop Specifying ``ebgp-multihop`` allows sessions with eBGP neighbors to establish when they are multiple hops away. When the neighbor is not @@ -1491,13 +1394,11 @@ Configuring Peers If the peer's IP address is not in the RIB and is reachable via the default route, then you have to enable ``ip nht resolve-via-default``. -.. index:: neighbor PEER description ... -.. clicmd:: [no] neighbor PEER description ... +.. clicmd:: neighbor PEER description ... Set description of the peer. -.. index:: neighbor PEER version VERSION -.. clicmd:: [no] neighbor PEER version VERSION +.. clicmd:: neighbor PEER version VERSION Set up the neighbor's BGP version. `version` can be `4`, `4+` or `4-`. BGP version `4` is the default value used for BGP peering. BGP version `4+` @@ -1506,8 +1407,7 @@ Configuring Peers revision 00's Multiprotocol Extensions for BGP-4. Some routing software is still using this version. -.. index:: neighbor PEER interface IFNAME -.. clicmd:: [no] neighbor PEER interface IFNAME +.. clicmd:: neighbor PEER interface IFNAME When you connect to a BGP peer over an IPv6 link-local address, you have to specify the IFNAME of the interface used for the connection. To specify @@ -1517,15 +1417,13 @@ Configuring Peers This command is deprecated and may be removed in a future release. Its use should be avoided. -.. index:: neighbor PEER next-hop-self [all] -.. clicmd:: [no] neighbor PEER next-hop-self [all] +.. clicmd:: neighbor PEER next-hop-self [all] This command specifies an announced route's nexthop as being equivalent to the address of the bgp router if it is learned via eBGP. If the optional keyword `all` is specified the modification is done also for routes learned via iBGP. -.. index:: neighbor PEER attribute-unchanged [{as-path|next-hop|med}] .. clicmd:: neighbor PEER attribute-unchanged [{as-path|next-hop|med}] This command specifies attributes to be left unchanged for advertisements @@ -1533,8 +1431,7 @@ Configuring Peers configurations, as the route-map directive to leave the next-hop unchanged is only available for ipv4. -.. index:: neighbor PEER update-source <IFNAME|ADDRESS> -.. clicmd:: [no] neighbor PEER update-source <IFNAME|ADDRESS> +.. clicmd:: neighbor PEER update-source <IFNAME|ADDRESS> Specify the IPv4 source address to use for the :abbr:`BGP` session to this neighbour, may be specified as either an IPv4 address directly or as an @@ -1548,18 +1445,15 @@ Configuring Peers neighbor bar update-source lo0 -.. index:: neighbor PEER default-originate -.. clicmd:: [no] neighbor PEER default-originate +.. clicmd:: neighbor PEER default-originate *bgpd*'s default is to not announce the default route (0.0.0.0/0) even if it is in routing table. When you want to announce default routes to the peer, use this command. -.. index:: neighbor PEER port PORT .. clicmd:: neighbor PEER port PORT -.. index:: neighbor PEER password PASSWORD -.. clicmd:: [no] neighbor PEER password PASSWORD +.. clicmd:: neighbor PEER password PASSWORD Set a MD5 password to be used with the tcp socket that is being used to connect to the remote peer. Please note if you are using this @@ -1567,16 +1461,13 @@ Configuring Peers modifying the `net.core.optmem_max` sysctl to a larger value to avoid out of memory errors from the linux kernel. -.. index:: neighbor PEER send-community .. clicmd:: neighbor PEER send-community -.. index:: neighbor PEER weight WEIGHT -.. clicmd:: [no] neighbor PEER weight WEIGHT +.. clicmd:: neighbor PEER weight WEIGHT This command specifies a default `weight` value for the neighbor's routes. -.. index:: neighbor PEER maximum-prefix NUMBER [force] -.. clicmd:: [no] neighbor PEER maximum-prefix NUMBER [force] +.. clicmd:: neighbor PEER maximum-prefix NUMBER [force] Sets a maximum number of prefixes we can receive from a given peer. If this number is exceeded, the BGP session will be destroyed. @@ -1593,16 +1484,14 @@ Configuring Peers but you want maximum-prefix to act on ALL (including filtered) prefixes. This option requires `soft-reconfiguration inbound` to be enabled for the peer. -.. index:: neighbor PEER maximum-prefix-out NUMBER -.. clicmd:: [no] neighbor PEER maximum-prefix-out NUMBER +.. clicmd:: neighbor PEER maximum-prefix-out NUMBER Sets a maximum number of prefixes we can send to a given peer. Since sent prefix count is managed by update-groups, this option creates a separate update-group for outgoing updates. -.. index:: neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as] -.. clicmd:: [no] neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as] +.. clicmd:: neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as] Specify an alternate AS for this BGP process when interacting with the specified peer. With no modifiers, the specified local-as is prepended to @@ -1620,8 +1509,7 @@ Configuring Peers This command is only allowed for eBGP peers. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> as-override -.. clicmd:: [no] neighbor <A.B.C.D|X:X::X:X|WORD> as-override +.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> as-override Override AS number of the originating router with the local AS number. @@ -1633,8 +1521,7 @@ Configuring Peers This command is only allowed for eBGP peers. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>] -.. clicmd:: [no] neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>] +.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>] Accept incoming routes with AS path containing AS number with the same value as the current system AS. @@ -1651,28 +1538,24 @@ Configuring Peers This command is only allowed for eBGP peers. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths -.. clicmd:: [no] neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths +.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths Configure BGP to send all known paths to neighbor in order to preserve multi path capabilities inside a network. -.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS -.. clicmd:: [no] neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS +.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS Configure BGP to send best known paths to neighbor in order to preserve multi path capabilities inside a network. -.. index:: neighbor PEER ttl-security hops NUMBER -.. clicmd:: [no] neighbor PEER ttl-security hops NUMBER +.. clicmd:: neighbor PEER ttl-security hops NUMBER This command enforces Generalized TTL Security Mechanism (GTSM), as specified in RFC 5082. With this command, only neighbors that are the specified number of hops away will be allowed to become neighbors. This command is mutually exclusive with *ebgp-multihop*. -.. index:: neighbor PEER capability extended-nexthop -.. clicmd:: [no] neighbor PEER capability extended-nexthop +.. clicmd:: neighbor PEER capability extended-nexthop Allow bgp to negotiate the extended-nexthop capability with it's peer. If you are peering over a v6 LL address then this capability is turned @@ -1680,43 +1563,37 @@ Configuring Peers turning on this command will allow BGP to install v4 routes with v6 nexthops if you do not have v4 configured on interfaces. -.. index:: bgp fast-external-failover -.. clicmd:: [no] bgp fast-external-failover +.. clicmd:: bgp fast-external-failover This command causes bgp to not take down ebgp peers immediately when a link flaps. `bgp fast-external-failover` is the default and will not be displayed as part of a `show run`. The no form of the command turns off this ability. -.. index:: bgp default ipv4-unicast -.. clicmd:: [no] bgp default ipv4-unicast +.. clicmd:: bgp default ipv4-unicast This command allows the user to specify that v4 peering is turned on by default or not. This command defaults to on and is not displayed. The `no bgp default ipv4-unicast` form of the command is displayed. -.. index:: bgp default show-hostname -.. clicmd:: [no] bgp default show-hostname +.. clicmd:: bgp default show-hostname This command shows the hostname of the peer in certain BGP commands outputs. It's easier to troubleshoot if you have a number of BGP peers. -.. index:: bgp default show-nexthop-hostname -.. clicmd:: [no] bgp default show-nexthop-hostname +.. clicmd:: bgp default show-nexthop-hostname This command shows the hostname of the next-hop in certain BGP commands outputs. It's easier to troubleshoot if you have a number of BGP peers and a number of routes to check. -.. index:: neighbor PEER advertisement-interval (0-600) -.. clicmd:: [no] neighbor PEER advertisement-interval (0-600) +.. clicmd:: neighbor PEER advertisement-interval (0-600) Setup the minimum route advertisement interval(mrai) for the peer in question. This number is between 0 and 600 seconds, with the default advertisement interval being 0. -.. index:: neighbor PEER timers delayopen (1-240) -.. clicmd:: [no] neighbor PEER timers delayopen (1-240) +.. clicmd:: neighbor PEER timers delayopen (1-240) This command allows the user enable the `RFC 4271 <https://tools.ietf.org/html/rfc4271/>` DelayOpenTimer with the @@ -1727,7 +1604,6 @@ Configuring Peers Displaying Information about Peers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide] .. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide] For the given neighbor, WORD, that is specified list the routes selected @@ -1738,32 +1614,26 @@ Displaying Information about Peers Peer Filtering ^^^^^^^^^^^^^^ -.. index:: neighbor PEER distribute-list NAME [in|out] .. clicmd:: neighbor PEER distribute-list NAME [in|out] This command specifies a distribute-list for the peer. `direct` is ``in`` or ``out``. -.. index:: neighbor PEER prefix-list NAME [in|out] .. clicmd:: neighbor PEER prefix-list NAME [in|out] -.. index:: neighbor PEER filter-list NAME [in|out] .. clicmd:: neighbor PEER filter-list NAME [in|out] -.. index:: neighbor PEER route-map NAME [in|out] .. clicmd:: neighbor PEER route-map NAME [in|out] Apply a route-map on the neighbor. `direct` must be `in` or `out`. -.. index:: bgp route-reflector allow-outbound-policy .. clicmd:: bgp route-reflector allow-outbound-policy By default, attribute modification via route-map policy out is not reflected on reflected routes. This option allows the modifications to be reflected as well. Once enabled, it affects all reflected routes. -.. index:: neighbor PEER sender-as-path-loop-detection -.. clicmd:: [no] neighbor PEER sender-as-path-loop-detection +.. clicmd:: neighbor PEER sender-as-path-loop-detection Enable the detection of sender side AS path loops and filter the bad routes before they are sent. @@ -1783,17 +1653,14 @@ indicated the originating peer. All peers not associated with a specific peer group are treated as belonging to a default peer group, and will share updates. -.. index:: neighbor WORD peer-group .. clicmd:: neighbor WORD peer-group This command defines a new peer group. -.. index:: neighbor PEER peer-group PGNAME .. clicmd:: neighbor PEER peer-group PGNAME This command bind specific peer to peer group WORD. -.. index:: neighbor PEER solo .. clicmd:: neighbor PEER solo This command is used to indicate that routes advertised by the peer @@ -1803,11 +1670,8 @@ and will share updates. Capability Negotiation ^^^^^^^^^^^^^^^^^^^^^^ -.. index:: neighbor PEER strict-capability-match .. clicmd:: neighbor PEER strict-capability-match -.. index:: neighbor PEER strict-capability-match -.. clicmd:: no neighbor PEER strict-capability-match Strictly compares remote capabilities and local capabilities. If capabilities are different, send Unsupported Capability error then reset @@ -1818,8 +1682,7 @@ Capability Negotiation Negotiation. Please use *dont-capability-negotiate* command to disable the feature. -.. index:: neighbor PEER dont-capability-negotiate -.. clicmd:: [no] neighbor PEER dont-capability-negotiate +.. clicmd:: neighbor PEER dont-capability-negotiate Suppress sending Capability Negotiation as OPEN message optional parameter to the peer. This command only affects the peer is configured other than @@ -1839,11 +1702,8 @@ Capability Negotiation hostname support, AS4, Addpath, Route Refresh, ORF, Dynamic Capabilities, and graceful restart. -.. index:: neighbor PEER override-capability .. clicmd:: neighbor PEER override-capability -.. index:: neighbor PEER override-capability -.. clicmd:: no neighbor PEER override-capability Override the result of Capability Negotiation with local configuration. Ignore remote peer's capability value. @@ -1855,16 +1715,11 @@ AS Path Access Lists AS path access list is user defined AS path. -.. index:: bgp as-path access-list WORD permit|deny LINE .. clicmd:: bgp as-path access-list WORD permit|deny LINE This command defines a new AS path access list. -.. index:: bgp as-path access-list WORD -.. clicmd:: no bgp as-path access-list WORD -.. index:: bgp as-path access-list WORD permit|deny LINE -.. clicmd:: no bgp as-path access-list WORD permit|deny LINE .. _bgp-bogon-filter-example: @@ -1882,21 +1737,18 @@ Bogon ASN filter policy configuration example Using AS Path in Route Map -------------------------- -.. index:: match as-path WORD -.. clicmd:: [no] match as-path WORD +.. clicmd:: match as-path WORD For a given as-path, WORD, match it on the BGP as-path given for the prefix and if it matches do normal route-map actions. The no form of the command removes this match from the route-map. -.. index:: set as-path prepend AS-PATH -.. clicmd:: [no] set as-path prepend AS-PATH +.. clicmd:: set as-path prepend AS-PATH Prepend the given string of AS numbers to the AS_PATH of the BGP path's NLRI. The no form of this command removes this set operation from the route-map. -.. index:: set as-path prepend last-as NUM -.. clicmd:: [no] set as-path prepend last-as NUM +.. clicmd:: set as-path prepend last-as NUM Prepend the existing last AS number (the leftmost ASN) to the AS_PATH. The no form of this command removes this set operation from the route-map. @@ -2042,7 +1894,6 @@ expanded interpreted on each use expanded community lists are slower than standard lists. -.. index:: bgp community-list standard NAME permit|deny COMMUNITY .. clicmd:: bgp community-list standard NAME permit|deny COMMUNITY This command defines a new standard community list. ``COMMUNITY`` is @@ -2053,7 +1904,6 @@ expanded community list definition. When there is no matched entry, deny will be returned. When ``COMMUNITY`` is empty it matches to any routes. -.. index:: bgp community-list expanded NAME permit|deny COMMUNITY .. clicmd:: bgp community-list expanded NAME permit|deny COMMUNITY This command defines a new expanded community list. ``COMMUNITY`` is a @@ -2065,7 +1915,6 @@ expanded .. deprecated:: 5.0 It is recommended to use the more explicit versions of this command. -.. index:: bgp community-list NAME permit|deny COMMUNITY .. clicmd:: bgp community-list NAME permit|deny COMMUNITY When the community list type is not specified, the community list type is @@ -2074,15 +1923,10 @@ expanded Otherwise it is defined as an expanded community list. This feature is left for backward compatibility. Use of this feature is not recommended. + Note that all community lists share the same namespace, so it's not + necessary to specify ``standard`` or ``expanded``; these modifiers are + purely aesthetic. -.. index:: bgp community-list [standard|expanded] NAME -.. clicmd:: no bgp community-list [standard|expanded] NAME - - Deletes the community list specified by ``NAME``. All community lists share - the same namespace, so it's not necessary to specify ``standard`` or - ``expanded``; these modifiers are purely aesthetic. - -.. index:: show bgp community-list [NAME detail] .. clicmd:: show bgp community-list [NAME detail] Displays community list information. When ``NAME`` is specified the @@ -2115,13 +1959,11 @@ to 199 is expanded community list. These community lists are called as numbered community lists. On the other hand normal community lists is called as named community lists. -.. index:: bgp community-list (1-99) permit|deny COMMUNITY .. clicmd:: bgp community-list (1-99) permit|deny COMMUNITY This command defines a new community list. The argument to (1-99) defines the list identifier. -.. index:: bgp community-list (100-199) permit|deny COMMUNITY .. clicmd:: bgp community-list (100-199) permit|deny COMMUNITY This command defines a new expanded community list. The argument to @@ -2138,7 +1980,6 @@ communities attribute. The following commands can be used in route maps: -.. index:: match community WORD exact-match [exact-match] .. clicmd:: match community WORD exact-match [exact-match] This command perform match to BGP updates using community list WORD. When @@ -2147,7 +1988,6 @@ The following commands can be used in route maps: happen only when BGP updates have completely same communities value specified in the community list. -.. index:: set community <none|COMMUNITY> additive .. clicmd:: set community <none|COMMUNITY> additive This command sets the community value in BGP updates. If the attribute is @@ -2160,7 +2000,6 @@ The following commands can be used in route maps: It is not possible to set an expanded community list. -.. index:: set comm-list WORD delete .. clicmd:: set comm-list WORD delete This command remove communities value from BGP communities attribute. The @@ -2337,7 +2176,6 @@ the other is IP address based format. Extended Community Lists ^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: bgp extcommunity-list standard NAME permit|deny EXTCOMMUNITY .. clicmd:: bgp extcommunity-list standard NAME permit|deny EXTCOMMUNITY This command defines a new standard extcommunity-list. `extcommunity` is @@ -2349,7 +2187,6 @@ Extended Community Lists there is no matched entry, deny will be returned. When `extcommunity` is empty it matches to any routes. -.. index:: bgp extcommunity-list expanded NAME permit|deny LINE .. clicmd:: bgp extcommunity-list expanded NAME permit|deny LINE This command defines a new expanded extcommunity-list. `line` is a string @@ -2357,29 +2194,13 @@ Extended Community Lists expression (:ref:`bgp-regular-expressions`) to match an extended communities attribute in BGP updates. -.. index:: bgp extcommunity-list NAME -.. clicmd:: no bgp extcommunity-list NAME - -.. index:: bgp extcommunity-list standard NAME -.. clicmd:: no bgp extcommunity-list standard NAME + Note that all extended community lists shares a single name space, so it's + not necessary to specify their type when creating or destroying them. -.. index:: bgp extcommunity-list expanded NAME -.. clicmd:: no bgp extcommunity-list expanded NAME - - These commands delete extended community lists specified by `name`. All of - extended community lists shares a single name space. So extended community - lists can be removed simply specifying the name. - -.. index:: show bgp extcommunity-list -.. clicmd:: show bgp extcommunity-list - -.. index:: show bgp extcommunity-list NAME detail -.. clicmd:: show bgp extcommunity-list NAME detail +.. clicmd:: show bgp extcommunity-list [NAME detail] This command displays current extcommunity-list information. When `name` is - specified the community list's information is shown.:: - - # show bgp extcommunity-list + specified the community list's information is shown. .. _bgp-extended-communities-in-route-map: @@ -2387,20 +2208,16 @@ Extended Community Lists BGP Extended Communities in Route Map """"""""""""""""""""""""""""""""""""" -.. index:: match extcommunity WORD .. clicmd:: match extcommunity WORD -.. index:: set extcommunity rt EXTCOMMUNITY .. clicmd:: set extcommunity rt EXTCOMMUNITY This command set Route Target value. -.. index:: set extcommunity soo EXTCOMMUNITY .. clicmd:: set extcommunity soo EXTCOMMUNITY This command set Site of Origin value. -.. index:: set extcommunity bandwidth <(1-25600) | cumulative | num-multipaths> [non-transitive] .. clicmd:: set extcommunity bandwidth <(1-25600) | cumulative | num-multipaths> [non-transitive] This command sets the BGP link-bandwidth extended community for the prefix @@ -2452,7 +2269,6 @@ Large Community Lists Two types of large community lists are supported, namely `standard` and `expanded`. -.. index:: bgp large-community-list standard NAME permit|deny LARGE-COMMUNITY .. clicmd:: bgp large-community-list standard NAME permit|deny LARGE-COMMUNITY This command defines a new standard large-community-list. `large-community` @@ -2463,7 +2279,6 @@ Two types of large community lists are supported, namely `standard` and definition. When there is no matched entry, a deny will be returned. When `large-community` is empty it matches any routes. -.. index:: bgp large-community-list expanded NAME permit|deny LINE .. clicmd:: bgp large-community-list expanded NAME permit|deny LINE This command defines a new expanded large-community-list. Where `line` is a @@ -2472,29 +2287,17 @@ Two types of large community lists are supported, namely `standard` and lowest to highest. `line` can also be a regular expression which matches this Large Community attribute. -.. index:: bgp large-community-list NAME -.. clicmd:: no bgp large-community-list NAME - -.. index:: bgp large-community-list standard NAME -.. clicmd:: no bgp large-community-list standard NAME - -.. index:: bgp large-community-list expanded NAME -.. clicmd:: no bgp large-community-list expanded NAME + Note that all community lists share the same namespace, so it's not + necessary to specify ``standard`` or ``expanded``; these modifiers are + purely aesthetic. - These commands delete Large Community lists specified by `name`. All Large - Community lists share a single namespace. This means Large Community lists - can be removed by simply specifying the name. - -.. index:: show bgp large-community-list .. clicmd:: show bgp large-community-list -.. index:: show bgp large-community-list NAME detail .. clicmd:: show bgp large-community-list NAME detail This command display current large-community-list information. When `name` is specified the community list information is shown. -.. index:: show ip bgp large-community-info .. clicmd:: show ip bgp large-community-info This command displays the current large communities in use. @@ -2504,7 +2307,6 @@ Two types of large community lists are supported, namely `standard` and Large Communities in Route Map """""""""""""""""""""""""""""" -.. index:: match large-community LINE [exact-match] .. clicmd:: match large-community LINE [exact-match] Where `line` can be a simple string to match, or a regular expression. It @@ -2514,13 +2316,10 @@ Large Communities in Route Map happen only when BGP updates have completely same large communities value specified in the large community list. -.. index:: set large-community LARGE-COMMUNITY .. clicmd:: set large-community LARGE-COMMUNITY -.. index:: set large-community LARGE-COMMUNITY LARGE-COMMUNITY .. clicmd:: set large-community LARGE-COMMUNITY LARGE-COMMUNITY -.. index:: set large-community LARGE-COMMUNITY additive .. clicmd:: set large-community LARGE-COMMUNITY additive These commands are used for setting large-community values. The first @@ -2602,18 +2401,11 @@ Configuration of route leaking between a unicast VRF RIB and the VPN SAFI RIB of the default VRF is accomplished via commands in the context of a VRF address-family: -.. index:: rd vpn export AS:NN|IP:nn .. clicmd:: rd vpn export AS:NN|IP:nn Specifies the route distinguisher to be added to a route exported from the current unicast VRF to VPN. -.. index:: rd vpn export [AS:NN|IP:nn] -.. clicmd:: no rd vpn export [AS:NN|IP:nn] - - Deletes any previously-configured export route distinguisher. - -.. index:: rt vpn import|export|both RTLIST... .. clicmd:: rt vpn import|export|both RTLIST... Specifies the route-target list to be attached to a route (export) or the @@ -2624,12 +2416,6 @@ address-family: extended community values as described in :ref:`bgp-extended-communities-attribute`. -.. index:: rt vpn import|export|both [RTLIST...] -.. clicmd:: no rt vpn import|export|both [RTLIST...] - - Deletes any previously-configured import or export route-target list. - -.. index:: label vpn export (0..1048575)|auto .. clicmd:: label vpn export (0..1048575)|auto Enables an MPLS label to be attached to a route exported from the current @@ -2638,45 +2424,21 @@ address-family: is not running, or if this command is not configured, automatic label assignment will not complete, which will block corresponding route export. -.. index:: label vpn export [(0..1048575)|auto] -.. clicmd:: no label vpn export [(0..1048575)|auto] - - Deletes any previously-configured export label. - -.. index:: nexthop vpn export A.B.C.D|X:X::X:X .. clicmd:: nexthop vpn export A.B.C.D|X:X::X:X Specifies an optional nexthop value to be assigned to a route exported from the current unicast VRF to VPN. If left unspecified, the nexthop will be set to 0.0.0.0 or 0:0::0:0 (self). -.. index:: nexthop vpn export [A.B.C.D|X:X::X:X] -.. clicmd:: no nexthop vpn export [A.B.C.D|X:X::X:X] - - Deletes any previously-configured export nexthop. - -.. index:: route-map vpn import|export MAP .. clicmd:: route-map vpn import|export MAP Specifies an optional route-map to be applied to routes imported or exported between the current unicast VRF and VPN. -.. index:: route-map vpn import|export [MAP] -.. clicmd:: no route-map vpn import|export [MAP] - - Deletes any previously-configured import or export route-map. - -.. index:: import|export vpn .. clicmd:: import|export vpn Enables import or export of routes between the current unicast VRF and VPN. -.. index:: import|export vpn -.. clicmd:: no import|export vpn - - Disables import or export of routes between the current unicast VRF and VPN. - -.. index:: import vrf VRFNAME .. clicmd:: import vrf VRFNAME Shortcut syntax for specifying automatic leaking from vrf VRFNAME to @@ -2689,12 +2451,6 @@ address-family: The CLI will disallow attempts to configure incompatible leaking modes. -.. index:: import vrf VRFNAME -.. clicmd:: no import vrf VRFNAME - - Disables automatic leaking from vrf VRFNAME to the current VRF using - the VPN RIB as intermediary. - .. _bgp-evpn: @@ -2745,8 +2501,7 @@ disable the feature via configuration CLI. Once the feature is disable under bgp vrf instance or MAC-VLAN interface is not configured, all the routes follow the same behavior of using same next-hop and RMAC values. -.. index:: advertise-pip [ip <addr> [mac <addr>]] -.. clicmd:: [no] advertise-pip [ip <addr> [mac <addr>]] +.. clicmd:: advertise-pip [ip <addr> [mac <addr>]] Enables or disables advertise-pip feature, specifiy system-IP and/or system-MAC parameters. @@ -2763,11 +2518,9 @@ Ethernet Segments An Ethernet Segment can be configured by specifying a system-MAC and a local discriminatior against the bond interface on the PE (via zebra) - -.. index:: evpn mh es-id (1-16777215) -.. clicmd:: [no] evpn mh es-id (1-16777215) +.. clicmd:: evpn mh es-id (1-16777215) -.. index:: evpn mh es-sys-mac X:X:X:X:X:X -.. clicmd:: [no] evpn mh es-sys-mac X:X:X:X:X:X +.. clicmd:: evpn mh es-sys-mac X:X:X:X:X:X The sys-mac and local discriminator are used for generating a 10-byte, Type-3 Ethernet Segment ID. @@ -2790,8 +2543,7 @@ forward BUM traffic received via the overlay network. This implementation uses a preference based DF election specified by draft-ietf-bess-evpn-pref-df. The DF preference is configurable per-ES (via zebra) - -.. index:: evpn mh es-df-pref (1-16777215) -.. clicmd:: [no] evpn mh es-df-pref (1-16777215) +.. clicmd:: evpn mh es-df-pref (1-16777215) BUM traffic is rxed via the overlay by all PEs attached to a server but only the DF can forward the de-capsulated traffic to the access port. To @@ -2809,11 +2561,9 @@ ES-PE based on just the EAD-per-ES route. Note that by default we advertise and expect EAD-per-EVI routes. -.. index:: disable-ead-evi-rx -.. clicmd:: [no] disable-ead-evi-rx +.. clicmd:: disable-ead-evi-rx -.. index:: disable-ead-evi-tx -.. clicmd:: [no] disable-ead-evi-tx +.. clicmd:: disable-ead-evi-tx Fast failover """"""""""""" @@ -2827,15 +2577,13 @@ been introduced for the express purpose of efficient ES failovers. On dataplanes that support layer3 nexthop groups the feature can be turned on via the following BGP config - -.. index:: use-es-l3nhg -.. clicmd:: [no] use-es-l3nhg +.. clicmd:: use-es-l3nhg - Local ES (MAC/Neigh) failover via ES-redirect. On dataplanes that do not have support for ES-redirect the feature can be turned off via the following zebra config - -.. index:: evpn mh redirect-off -.. clicmd:: [no] evpn mh redirect-off +.. clicmd:: evpn mh redirect-off Uplink/Core tracking """""""""""""""""""" @@ -2844,8 +2592,7 @@ When all the underlay links go down the PE no longer has access to the VxLAN protodowned on the PE. A link can be setup for uplink tracking via the following zebra configuration - -.. index:: evpn mh uplink -.. clicmd:: [no] evpn mh uplink +.. clicmd:: evpn mh uplink Proxy advertisements """""""""""""""""""" @@ -2856,11 +2603,9 @@ the ES peer (PE2) goes down PE1 continues to advertise hosts learnt from PE2 for a holdtime during which it attempts to establish local reachability of the host. This holdtime is configurable via the following zebra commands - -.. index:: evpn mh neigh-holdtime (0-86400) -.. clicmd:: [no] evpn mh neigh-holdtime (0-86400) +.. clicmd:: evpn mh neigh-holdtime (0-86400) -.. index:: evpn mh mac-holdtime (0-86400) -.. clicmd:: [no] evpn mh mac-holdtime (0-86400) +.. clicmd:: evpn mh mac-holdtime (0-86400) Startup delay """"""""""""" @@ -2869,8 +2614,7 @@ and EVPN network to converge before enabling the ESs. For this duration the ES bonds are held protodown. The startup delay is configurable via the following zebra command - -.. index:: evpn mh startup-delay (0-3600) -.. clicmd:: [no] evpn mh startup-delay (0-3600) +.. clicmd:: evpn mh startup-delay (0-3600) +Support with VRF network namespace backend +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2928,8 +2672,7 @@ advertisement to take effect is 60 seconds. The conditional advertisement can ta effect depending on when the tracked route is removed from the BGP table and when the next instance of the BGP scanner occurs. -.. index:: neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME -.. clicmd:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME +.. clicmd:: neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME This command enables BGP scanner process to monitor routes specified by exist-map or non-exist-map command in BGP table and conditionally advertises @@ -3086,70 +2829,57 @@ When default route is not present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2 Debugging --------- -.. index:: show debug .. clicmd:: show debug Show all enabled debugs. -.. index:: show bgp listeners .. clicmd:: show bgp listeners Display Listen sockets and the vrf that created them. Useful for debugging of when listen is not working and this is considered a developer debug statement. -.. index:: debug bgp neighbor-events -.. clicmd:: [no] debug bgp neighbor-events +.. clicmd:: debug bgp neighbor-events Enable or disable debugging for neighbor events. This provides general information on BGP events such as peer connection / disconnection, session establishment / teardown, and capability negotiation. -.. index:: debug bgp updates -.. clicmd:: [no] debug bgp updates +.. clicmd:: debug bgp updates Enable or disable debugging for BGP updates. This provides information on BGP UPDATE messages transmitted and received between local and remote instances. -.. index:: debug bgp keepalives -.. clicmd:: [no] debug bgp keepalives +.. clicmd:: debug bgp keepalives Enable or disable debugging for BGP keepalives. This provides information on BGP KEEPALIVE messages transmitted and received between local and remote instances. -.. index:: debug bgp bestpath <A.B.C.D/M|X:X::X:X/M> -.. clicmd:: [no] debug bgp bestpath <A.B.C.D/M|X:X::X:X/M> +.. clicmd:: debug bgp bestpath <A.B.C.D/M|X:X::X:X/M> Enable or disable debugging for bestpath selection on the specified prefix. -.. index:: debug bgp nht -.. clicmd:: [no] debug bgp nht +.. clicmd:: debug bgp nht Enable or disable debugging of BGP nexthop tracking. -.. index:: debug bgp update-groups -.. clicmd:: [no] debug bgp update-groups +.. clicmd:: debug bgp update-groups Enable or disable debugging of dynamic update groups. This provides general information on group creation, deletion, join and prune events. -.. index:: debug bgp zebra -.. clicmd:: [no] debug bgp zebra +.. clicmd:: debug bgp zebra Enable or disable debugging of communications between *bgpd* and *zebra*. Dumping Messages and Routing Tables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: dump bgp all PATH [INTERVAL] .. clicmd:: dump bgp all PATH [INTERVAL] -.. index:: dump bgp all-et PATH [INTERVAL] .. clicmd:: dump bgp all-et PATH [INTERVAL] -.. index:: dump bgp all [PATH] [INTERVAL] -.. clicmd:: no dump bgp all [PATH] [INTERVAL] Dump all BGP packet and events to `path` file. If `interval` is set, a new file will be created for echo `interval` of @@ -3157,14 +2887,10 @@ Dumping Messages and Routing Tables (strftime). The type ‘all-et’ enables support for Extended Timestamp Header (:ref:`packet-binary-dump-format`). -.. index:: dump bgp updates PATH [INTERVAL] .. clicmd:: dump bgp updates PATH [INTERVAL] -.. index:: dump bgp updates-et PATH [INTERVAL] .. clicmd:: dump bgp updates-et PATH [INTERVAL] -.. index:: dump bgp updates [PATH] [INTERVAL] -.. clicmd:: no dump bgp updates [PATH] [INTERVAL] Dump only BGP updates messages to `path` file. If `interval` is set, a new file will be created for echo `interval` of @@ -3172,14 +2898,10 @@ Dumping Messages and Routing Tables (strftime). The type ‘updates-et’ enables support for Extended Timestamp Header (:ref:`packet-binary-dump-format`). -.. index:: dump bgp routes-mrt PATH .. clicmd:: dump bgp routes-mrt PATH -.. index:: dump bgp routes-mrt PATH INTERVAL .. clicmd:: dump bgp routes-mrt PATH INTERVAL -.. index:: dump bgp route-mrt [PATH] [INTERVAL] -.. clicmd:: no dump bgp route-mrt [PATH] [INTERVAL] Dump whole BGP routing table to `path`. This is heavy process. The path `path` can be set with date and time formatting (strftime). If `interval` is @@ -3195,44 +2917,36 @@ Other BGP Commands The following are available in the top level *enable* mode: -.. index:: clear bgp \* .. clicmd:: clear bgp \* Clear all peers. -.. index:: clear bgp ipv4|ipv6 \* .. clicmd:: clear bgp ipv4|ipv6 \* Clear all peers with this address-family activated. -.. index:: clear bgp ipv4|ipv6 unicast \* .. clicmd:: clear bgp ipv4|ipv6 unicast \* Clear all peers with this address-family and sub-address-family activated. -.. index:: clear bgp ipv4|ipv6 PEER .. clicmd:: clear bgp ipv4|ipv6 PEER Clear peers with address of X.X.X.X and this address-family activated. -.. index:: clear bgp ipv4|ipv6 unicast PEER .. clicmd:: clear bgp ipv4|ipv6 unicast PEER Clear peer with address of X.X.X.X and this address-family and sub-address-family activated. -.. index:: clear bgp ipv4|ipv6 PEER soft|in|out .. clicmd:: clear bgp ipv4|ipv6 PEER soft|in|out Clear peer using soft reconfiguration in this address-family. -.. index:: clear bgp ipv4|ipv6 unicast PEER soft|in|out .. clicmd:: clear bgp ipv4|ipv6 unicast PEER soft|in|out Clear peer using soft reconfiguration in this address-family and sub-address-family. The following are available in the ``router bgp`` mode: -.. index:: write-quanta (1-64) .. clicmd:: write-quanta (1-64) BGP message Tx I/O is vectored. This means that multiple packets are written @@ -3242,7 +2956,6 @@ The following are available in the ``router bgp`` mode: less 'bursty'. In practice, leave this settings on the default (64) unless you truly know what you are doing. -.. index:: read-quanta (1-10) .. clicmd:: read-quanta (1-10) Unlike Tx, BGP Rx traffic is not vectored. Packets are read off the wire one @@ -3252,7 +2965,6 @@ The following are available in the ``router bgp`` mode: The following command is available in ``config`` mode as well as in the ``router bgp`` mode: -.. index:: bgp graceful-shutdown .. clicmd:: bgp graceful-shutdown The purpose of this command is to initiate BGP Graceful Shutdown which @@ -3287,16 +2999,12 @@ daemon project, while :clicmd:`show bgp` command is the new format. The choice has been done to keep old format with IPv4 routing table, while new format displays IPv6 routing table. -.. index:: show ip bgp [all] [wide|json] .. clicmd:: show ip bgp [all] [wide|json] -.. index:: show ip bgp A.B.C.D [json] .. clicmd:: show ip bgp A.B.C.D [json] -.. index:: show bgp [all] [wide|json] .. clicmd:: show bgp [all] [wide|json] -.. index:: show bgp X:X::X:X [json] .. clicmd:: show bgp X:X::X:X [json] These commands display BGP routes. When no route is specified, the default @@ -3326,13 +3034,11 @@ displays IPv6 routing table. Some other commands provide additional options for filtering the output. -.. index:: show [ip] bgp regexp LINE .. clicmd:: show [ip] bgp regexp LINE This command displays BGP routes using AS path regular expression (:ref:`bgp-regular-expressions`). -.. index:: show [ip] bgp [all] summary [wide] [json] .. clicmd:: show [ip] bgp [all] summary [wide] [json] Show a bgp peer summary for the specified address family. @@ -3361,10 +3067,8 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. Total number of neighbors 1 exit1# -.. index:: show bgp [afi] [safi] [all] [wide|json] .. clicmd:: show bgp [afi] [safi] [all] [wide|json] -.. index:: show bgp <ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast> .. clicmd:: show bgp <ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast> These commands display BGP routes for the specific routing table indicated by @@ -3373,62 +3077,51 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. For EVPN prefixes, you can display the full BGP table for this AFI/SAFI using the standard `show bgp [afi] [safi]` syntax. -.. index:: show bgp l2vpn evpn route [type <macip|2|multicast|3|es|4|prefix|5>] .. clicmd:: show bgp l2vpn evpn route [type <macip|2|multicast|3|es|4|prefix|5>] Additionally, you can also filter this output by route type. -.. index:: show bgp [afi] [safi] [all] summary [json] .. clicmd:: show bgp [afi] [safi] [all] summary [json] Show a bgp peer summary for the specified address family, and subsequent address-family. -.. index:: show bgp [afi] [safi] [all] summary failed [json] .. clicmd:: show bgp [afi] [safi] [all] summary failed [json] Show a bgp peer summary for peers that are not succesfully exchanging routes for the specified address family, and subsequent address-family. -.. index:: show bgp [afi] [safi] [all] summary established [json] .. clicmd:: show bgp [afi] [safi] [all] summary established [json] Show a bgp peer summary for peers that are succesfully exchanging routes for the specified address family, and subsequent address-family. -.. index:: show bgp [afi] [safi] neighbor [PEER] .. clicmd:: show bgp [afi] [safi] neighbor [PEER] This command shows information on a specific BGP peer of the relevant afi and safi selected. -.. index:: show bgp [afi] [safi] [all] dampening dampened-paths [wide|json] .. clicmd:: show bgp [afi] [safi] [all] dampening dampened-paths [wide|json] Display paths suppressed due to dampening of the selected afi and safi selected. -.. index:: show bgp [afi] [safi] [all] dampening flap-statistics [wide|json] .. clicmd:: show bgp [afi] [safi] [all] dampening flap-statistics [wide|json] Display flap statistics of routes of the selected afi and safi selected. -.. index:: show bgp [afi] [safi] statistics .. clicmd:: show bgp [afi] [safi] statistics Display statistics of routes of the selected afi and safi. -.. index:: show bgp statistics-all .. clicmd:: show bgp statistics-all Display statistics of routes of all the afi and safi. -.. index:: show [ip] bgp [afi] [safi] [all] cidr-only [wide|json] .. clicmd:: show [ip] bgp [afi] [safi] [all] cidr-only [wide|json] Display routes with non-natural netmasks. -.. index:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [json|wide] .. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [json|wide] Display the routes advertised to a BGP neighbor or received routes @@ -3456,13 +3149,10 @@ Displaying Routes by Community Attribute The following commands allow displaying routes based on their community attribute. -.. index:: show [ip] bgp <ipv4|ipv6> [all] community [wide|json] .. clicmd:: show [ip] bgp <ipv4|ipv6> [all] community [wide|json] -.. index:: show [ip] bgp <ipv4|ipv6> [all] community COMMUNITY [wide|json] .. clicmd:: show [ip] bgp <ipv4|ipv6> [all] community COMMUNITY [wide|json] -.. index:: show [ip] bgp <ipv4|ipv6> [all] community COMMUNITY exact-match [wide|json] .. clicmd:: show [ip] bgp <ipv4|ipv6> [all] community COMMUNITY exact-match [wide|json] These commands display BGP routes which have the community attribute. @@ -3470,10 +3160,8 @@ attribute. community are displayed. When `exact-match` is specified, it display only routes that have an exact match. -.. index:: show [ip] bgp <ipv4|ipv6> community-list WORD .. clicmd:: show [ip] bgp <ipv4|ipv6> community-list WORD -.. index:: show [ip] bgp <ipv4|ipv6> community-list WORD exact-match .. clicmd:: show [ip] bgp <ipv4|ipv6> community-list WORD exact-match These commands display BGP routes for the address family specified that @@ -3493,7 +3181,6 @@ attribute. If ``json`` option is specified, output is displayed in JSON format. -.. index:: show bgp labelpool <chunks|inuse|ledger|requests|summary> [json] .. clicmd:: show bgp labelpool <chunks|inuse|ledger|requests|summary> [json] These commands display information about the BGP labelpool used for @@ -3527,16 +3214,12 @@ Displaying Routes by Large Community Attribute The following commands allow displaying routes based on their large community attribute. -.. index:: show [ip] bgp <ipv4|ipv6> large-community .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community -.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY -.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY exact-match .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY exact-match -.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY json .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY json These commands display BGP routes which have the large community attribute. @@ -3545,13 +3228,10 @@ large community attribute. only routes that have an exact match. When `json` is specified, it display routes in json format. -.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD -.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD exact-match .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD exact-match -.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD json .. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD json These commands display BGP routes for the address family specified that @@ -3565,24 +3245,19 @@ large community attribute. Displaying Routes by AS Path ---------------------------- -.. index:: show bgp ipv4|ipv6 regexp LINE .. clicmd:: show bgp ipv4|ipv6 regexp LINE This commands displays BGP routes that matches a regular expression `line` (:ref:`bgp-regular-expressions`). -.. index:: show [ip] bgp ipv4 vpn .. clicmd:: show [ip] bgp ipv4 vpn -.. index:: show [ip] bgp ipv6 vpn .. clicmd:: show [ip] bgp ipv6 vpn Print active IPV4 or IPV6 routes advertised via the VPN SAFI. -.. index:: show bgp ipv4 vpn summary .. clicmd:: show bgp ipv4 vpn summary -.. index:: show bgp ipv6 vpn summary .. clicmd:: show bgp ipv6 vpn summary Print a summary of neighbor connections for the specified AFI/SAFI combination. @@ -3590,7 +3265,6 @@ Displaying Routes by AS Path Displaying Update Group Information ----------------------------------- -.. index:: show bgp update-groups SUBGROUP-ID [advertise-queue|advertised-routes|packet-queue] .. clicmd:: show bgp update-groups [advertise-queue|advertised-routes|packet-queue] Display Information about each individual update-group being used. @@ -3600,7 +3274,6 @@ Displaying Update Group Information the list of routes we have sent to the peers in the update-group and packet-queue specifies the list of packets in the queue to be sent. -.. index:: show bgp update-groups statistics .. clicmd:: show bgp update-groups statistics Display Information about update-group events in FRR. @@ -3620,22 +3293,17 @@ When route reflectors are configured, these will reflect the routes announced by the peers configured as clients. A route reflector client is configured with: -.. index:: neighbor PEER route-reflector-client .. clicmd:: neighbor PEER route-reflector-client -.. index:: neighbor PEER route-reflector-client -.. clicmd:: no neighbor PEER route-reflector-client To avoid single points of failure, multiple route reflectors can be configured. A cluster is a collection of route reflectors and their clients, and is used by route reflectors to avoid looping. -.. index:: bgp cluster-id A.B.C.D .. clicmd:: bgp cluster-id A.B.C.D -.. index:: bgp no-rib -.. clicmd:: [no] bgp no-rib +.. clicmd:: bgp no-rib To set and unset the BGP daemon ``-n`` / ``--no_kernel`` options during runtime to disable BGP route installation to the RIB (Zebra), the ``[no] bgp no-rib`` @@ -3648,8 +3316,7 @@ starting the daemon and the configuration gets saved, the option will persist unless removed from the configuration with the negating command prior to the configuration write operation. -.. index:: bgp send-extra-data zebra -.. clicmd:: [no] bgp send-extra-data zebra +.. clicmd:: bgp send-extra-data zebra This Command turns off the ability of BGP to send extra data to zebra. In this case it's the AS-Path being used for the path. The default behavior @@ -3698,8 +3365,7 @@ status in FIB: 7. If the route which is already installed in dataplane is removed for some reason, sending withdraw message to peers is not currently supported. -.. index:: bgp suppress-fib-pending -.. clicmd:: [no] bgp suppress-fib-pending +.. clicmd:: bgp suppress-fib-pending This command is applicable at the global level and at an individual bgp level. If applied at the global level all bgp instances will diff --git a/doc/user/bmp.rst b/doc/user/bmp.rst index 061800c14e..f925910d45 100644 --- a/doc/user/bmp.rst +++ b/doc/user/bmp.rst @@ -73,8 +73,7 @@ setup. There is one option that applies to the BGP instance as a whole: -.. index:: bmp mirror buffer-limit(0-4294967294) -.. clicmd:: [no] bmp mirror buffer-limit(0-4294967294) +.. clicmd:: bmp mirror buffer-limit(0-4294967294) This sets the maximum amount of memory used for buffering BGP messages (updates, keepalives, ...) for sending in BMP Route Mirroring. @@ -94,8 +93,7 @@ There is one option that applies to the BGP instance as a whole: All other configuration is managed per targets: -.. index:: bmp targets NAME -.. clicmd:: [no] bmp targets NAME +.. clicmd:: bmp targets NAME Create/delete a targets group. As implied by the plural name, targets may cover multiple outbound active BMP sessions as well as inbound passive @@ -110,8 +108,7 @@ BMP session configuration Inside a ``bmp targets`` block, the following commands control session establishment: -.. index:: bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC} -.. clicmd:: [no] bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC} +.. clicmd:: bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC} Add/remove an active outbound BMP session. HOSTNAME is resolved via DNS, if multiple addresses are returned they are tried in nondeterministic @@ -124,14 +121,13 @@ establishment: ``ip access-list`` and ``ipv6 access-list`` are checked for outbound connections resulting from ``bmp connect`` statements. -.. index:: bmp listener <X:X::X:X|A.B.C.D> port (1-65535) -.. clicmd:: [no] bmp listener <X:X::X:X|A.B.C.D> port (1-65535) +.. clicmd:: bmp listener <X:X::X:X|A.B.C.D> port (1-65535) Accept incoming BMP sessions on the specified address and port. You can use ``0.0.0.0`` and ``::`` to listen on all IPv4/IPv6 addresses. -.. clicmd:: [no] ip access-list NAME -.. clicmd:: [no] ipv6 access-list NAME +.. clicmd:: ip access-list NAME +.. clicmd:: ipv6 access-list NAME Restrict BMP sessions to the addresses allowed by the respective access lists. The access lists are checked for both passive and active BMP @@ -143,14 +139,12 @@ BMP data feed configuration The following commands configure what BMP messages are sent on sessions associated with a particular ``bmp targets``: -.. index:: bmp stats [interval (100-86400000)] -.. clicmd:: [no] bmp stats [interval (100-86400000)] +.. clicmd:: bmp stats [interval (100-86400000)] Send BMP Statistics (counter) messages at the specified interval (in milliseconds.) -.. index:: bmp monitor AFI SAFI <pre-policy|post-policy> -.. clicmd:: [no] bmp monitor AFI SAFI <pre-policy|post-policy> +.. clicmd:: bmp monitor AFI SAFI <pre-policy|post-policy> Perform Route Monitoring for the specified AFI and SAFI. Only IPv4 and IPv6 are currently valid for AFI, and only unicast and multicast are valid @@ -159,8 +153,7 @@ associated with a particular ``bmp targets``: All BGP neighbors are included in Route Monitoring. Options to select a subset of BGP sessions may be added in the future. -.. index:: bmp mirror -.. clicmd:: [no] bmp mirror +.. clicmd:: bmp mirror Perform Route Mirroring for all BGP neighbors. Since this provides a direct feed of BGP messages, there are no AFI/SAFI options to be diff --git a/doc/user/bugs.rst b/doc/user/bugs.rst index 2bd632e3a5..2af9e317a0 100644 --- a/doc/user/bugs.rst +++ b/doc/user/bugs.rst @@ -1,5 +1,5 @@ -.. index:: Bug Reports -.. index:: Reporting bugs +.. index:: + pair: bug reports; contact .. _bug-reports: diff --git a/doc/user/conf.py b/doc/user/conf.py index 79b37e7850..e0aec40443 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -384,7 +384,7 @@ def vparse(s): def setup(app): # object type for FRR CLI commands, can be extended to document parent CLI # node later on - app.add_object_type("clicmd", "clicmd") + app.add_object_type("clicmd", "clicmd", indextemplate="pair: %s; configuration command") # css overrides for HTML theme # Note sphinx version differences diff --git a/doc/user/eigrpd.rst b/doc/user/eigrpd.rst index 4ce2e280c7..88d289d27e 100644 --- a/doc/user/eigrpd.rst +++ b/doc/user/eigrpd.rst @@ -65,7 +65,6 @@ Certain signals have special meanings to *eigrpd*. EIGRP Configuration =================== -.. index:: router eigrp (1-65535) [vrf NAME] .. clicmd:: router eigrp (1-65535) [vrf NAME] The `router eigrp` command is necessary to enable EIGRP. To disable EIGRP, @@ -73,17 +72,8 @@ EIGRP Configuration carrying out any of the EIGRP commands. Specify vrf NAME if you want eigrp to work within the specified vrf. -.. index:: router eigrp (1-65535) [vrf NAME] -.. clicmd:: no router eigrp (1-65535) [vrf NAME] - - Disable EIGRP. - -.. index:: network NETWORK .. clicmd:: network NETWORK -.. index:: network NETWORK -.. clicmd:: no network NETWORK - Set the EIGRP enable interface by `network`. The interfaces which have addresses matching with `network` are enabled. @@ -104,11 +94,8 @@ EIGRP Configuration ! -.. index:: passive-interface (IFNAME|default) .. clicmd:: passive-interface (IFNAME|default) -.. index:: passive-interface IFNAME -.. clicmd:: no passive-interface IFNAME This command sets the specified interface to passive mode. On passive mode interface, all receiving packets are ignored and eigrpd does not send either @@ -123,74 +110,26 @@ EIGRP Configuration How to Announce EIGRP route =========================== -.. index:: redistribute kernel -.. clicmd:: redistribute kernel - -.. index:: redistribute kernel metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) -.. clicmd:: redistribute kernel metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) - -.. index:: redistribute kernel -.. clicmd:: no redistribute kernel - - `redistribute kernel` redistributes routing information from kernel route - entries into the EIGRP tables. `no redistribute kernel` disables the routes. - -.. index:: redistribute static -.. clicmd:: redistribute static - -.. index:: redistribute static metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) -.. clicmd:: redistribute static metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) - -.. index:: redistribute static -.. clicmd:: no redistribute static - - `redistribute static` redistributes routing information from static route - entries into the EIGRP tables. `no redistribute static` disables the routes. - -.. index:: redistribute connected -.. clicmd:: redistribute connected - -.. index:: redistribute connected metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) -.. clicmd:: redistribute connected metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) - -.. index:: redistribute connected -.. clicmd:: no redistribute connected - - Redistribute connected routes into the EIGRP tables. `no redistribute - connected` disables the connected routes in the EIGRP tables. This command - redistribute connected of the interface which EIGRP disabled. The connected - route on EIGRP enabled interface is announced by default. - -.. index:: redistribute ospf -.. clicmd:: redistribute ospf - -.. index:: redistribute ospf metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) -.. clicmd:: redistribute ospf metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) - -.. index:: redistribute ospf -.. clicmd:: no redistribute ospf +Redistribute routes into EIGRP: - `redistribute ospf` redistributes routing information from ospf route - entries into the EIGRP tables. `no redistribute ospf` disables the routes. +.. clicmd:: redistribute <babel|bgp|connected|isis|kernel|openfabric|ospf|rip|sharp|static|table> [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)] -.. index:: redistribute bgp -.. clicmd:: redistribute bgp + The ``redistribute`` family of commands imports routing information from + other sources into EIGRP's tables. Redistribution may be disabled with the + ``no`` form of the commands. -.. index:: redistribute bgp metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) -.. clicmd:: redistribute bgp metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535) + Note that connected routes on interfaces EIGRP is enabled on are announced + by default. -.. index:: redistribute bgp -.. clicmd:: no redistribute bgp + Optionally, various EIGRP metrics may be specified. These metrics will be + applied to the imported routes. - `redistribute bgp` redistributes routing information from bgp route entries - into the EIGRP tables. `no redistribute bgp` disables the routes. .. _show-eigrp-information: Show EIGRP Information ====================== -.. index:: show ip eigrp [vrf NAME] topology .. clicmd:: show ip eigrp [vrf NAME] topology Display current EIGRP status. @@ -208,7 +147,6 @@ Show EIGRP Information P 10.0.2.0/24, 1 successors, FD is 256256, serno: 0 via Connected, enp0s3 -.. index:: show ip eigrp [vrf NAME] interface .. clicmd:: show ip eigrp [vrf NAME] interface Display the list of interfaces associated with a particular eigrp @@ -225,14 +163,12 @@ EIGRP Debug Commands Debug for EIGRP protocol. -.. index:: debug eigrp packets .. clicmd:: debug eigrp packets Debug eigrp packets ``debug eigrp`` will show EIGRP packets that are sent and received. -.. index:: debug eigrp transmit .. clicmd:: debug eigrp transmit Debug eigrp transmit events @@ -240,7 +176,6 @@ Debug for EIGRP protocol. ``debug eigrp transmit`` will display detailed information about the EIGRP transmit events. -.. index:: show debugging eigrp .. clicmd:: show debugging eigrp Display *eigrpd*'s debugging option. diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst index 17a51ccb3c..611bc1caaa 100644 --- a/doc/user/fabricd.rst +++ b/doc/user/fabricd.rst @@ -32,37 +32,21 @@ OpenFabric router To enable the OpenFabric routing protocol, an OpenFabric router needs to be created in the configuration: -.. index:: router openfabric WORD .. clicmd:: router openfabric WORD -.. index:: router openfabric WORD -.. clicmd:: no router openfabric WORD - Enable or disable the OpenFabric process by specifying the OpenFabric domain with 'WORD'. -.. index:: net XX.XXXX. ... .XXX.XX .. clicmd:: net XX.XXXX. ... .XXX.XX -.. index:: net XX.XXXX. ... .XXX.XX -.. clicmd:: no net XX.XXXX. ... .XXX.XX - Set/Unset network entity title (NET) provided in ISO format. -.. index:: domain-password [clear | md5] <password> .. clicmd:: domain-password [clear | md5] <password> -.. index:: domain-password -.. clicmd:: no domain-password - Configure the authentication password for a domain, as clear text or md5 one. -.. index:: attached-bit [receive ignore | send] .. clicmd:: attached-bit [receive ignore | send] -.. index:: attached-bit -.. clicmd:: no attached-bit - Set attached bit for inter-area traffic: - receive @@ -70,35 +54,22 @@ in the configuration: - send If L1|L2 router, set attached bit in LSP sent to L1 router -.. index:: log-adjacency-changes .. clicmd:: log-adjacency-changes -.. index:: log-adjacency-changes -.. clicmd:: no log-adjacency-changes - Log changes in adjacency state. -.. index:: set-overload-bit .. clicmd:: set-overload-bit -.. index:: set-overload-bit -.. clicmd:: no set-overload-bit Set overload bit to avoid any transit traffic. -.. index:: purge-originator .. clicmd:: purge-originator -.. index:: purge-originator -.. clicmd:: no purge-originator Enable or disable :rfc:`6232` purge originator identification. -.. index:: fabric-tier (0-14) .. clicmd:: fabric-tier (0-14) -.. index:: fabric-tier -.. clicmd:: no fabric-tier Configure a static tier number to advertise as location in the fabric @@ -107,35 +78,23 @@ in the configuration: OpenFabric Timer ================ -.. index:: lsp-gen-interval (1-120) .. clicmd:: lsp-gen-interval (1-120) -.. index:: lsp-gen-interval -.. clicmd:: no lsp-gen-interval Set minimum interval in seconds between regenerating same LSP. -.. index:: lsp-refresh-interval (1-65235) .. clicmd:: lsp-refresh-interval (1-65235) -.. index:: lsp-refresh-interval -.. clicmd:: no lsp-refresh-interval Set LSP refresh interval in seconds. -.. index:: max-lsp-lifetime (360-65535) .. clicmd:: max-lsp-lifetime (360-65535) -.. index:: max-lsp-lifetime -.. clicmd:: no max-lsp-lifetime Set LSP maximum LSP lifetime in seconds. -.. index:: spf-interval (1-120) .. clicmd:: spf-interval (1-120) -.. index:: spf-interval -.. clicmd:: no spf-interval Set minimum interval between consecutive SPF calculations in seconds. @@ -144,11 +103,8 @@ OpenFabric Timer OpenFabric interface ==================== -.. index:: ip router openfabric WORD .. clicmd:: ip router openfabric WORD -.. index:: ip router openfabric WORD -.. clicmd:: no ip router openfabric WORD .. _ip-router-openfabric-word: @@ -156,60 +112,39 @@ OpenFabric interface of OpenFabric instance must be the same as the one used to configure the routing process (see command :clicmd:`router openfabric WORD`). -.. index:: openfabric csnp-interval (1-600) .. clicmd:: openfabric csnp-interval (1-600) -.. index:: openfabric csnp-interval -.. clicmd:: no openfabric csnp-interval Set CSNP interval in seconds. -.. index:: openfabric hello-interval (1-600) .. clicmd:: openfabric hello-interval (1-600) -.. index:: openfabric hello-interval -.. clicmd:: no openfabric hello-interval Set Hello interval in seconds. -.. index:: openfabric hello-multiplier (2-100) .. clicmd:: openfabric hello-multiplier (2-100) -.. index:: openfabric hello-multiplier -.. clicmd:: no openfabric hello-multiplier Set multiplier for Hello holding time. -.. index:: openfabric metric (0-16777215) .. clicmd:: openfabric metric (0-16777215) -.. index:: openfabric metric -.. clicmd:: no openfabric metric Set interface metric value. -.. index:: openfabric passive .. clicmd:: openfabric passive -.. index:: openfabric passive -.. clicmd:: no openfabric passive Configure the passive mode for this interface. -.. index:: openfabric password [clear | md5] <password> .. clicmd:: openfabric password [clear | md5] <password> -.. index:: openfabric password -.. clicmd:: no openfabric password Configure the authentication password (clear or encoded text) for the interface. -.. index:: openfabric psnp-interval (1-120) .. clicmd:: openfabric psnp-interval (1-120) -.. index:: openfabric psnp-interval -.. clicmd:: no openfabric psnp-interval Set PSNP interval in seconds. @@ -218,56 +153,43 @@ OpenFabric interface Showing OpenFabric information ============================== -.. index:: show openfabric summary .. clicmd:: show openfabric summary Show summary information about OpenFabric. -.. index:: show openfabric hostname .. clicmd:: show openfabric hostname Show which hostnames are associated with which OpenFabric system ids. -.. index:: show openfabric interface .. clicmd:: show openfabric interface -.. index:: show openfabric interface detail .. clicmd:: show openfabric interface detail -.. index:: show openfabric interface <interface name> .. clicmd:: show openfabric interface <interface name> Show state and configuration of specified OpenFabric interface, or all interfaces if no interface is given with or without details. -.. index:: show openfabric neighbor .. clicmd:: show openfabric neighbor -.. index:: show openfabric neighbor <System Id> .. clicmd:: show openfabric neighbor <System Id> -.. index:: show openfabric neighbor detail .. clicmd:: show openfabric neighbor detail Show state and information of specified OpenFabric neighbor, or all neighbors if no system id is given with or without details. -.. index:: show openfabric database .. clicmd:: show openfabric database -.. index:: show openfabric database [detail] .. clicmd:: show openfabric database [detail] -.. index:: show openfabric database <LSP id> [detail] .. clicmd:: show openfabric database <LSP id> [detail] -.. index:: show openfabric database detail <LSP id> .. clicmd:: show openfabric database detail <LSP id> Show the OpenFabric database globally, for a specific LSP id without or with details. -.. index:: show openfabric topology .. clicmd:: show openfabric topology Show calculated OpenFabric paths and associated topology information. @@ -277,120 +199,64 @@ Showing OpenFabric information Debugging OpenFabric ==================== -.. index:: debug openfabric adj-packets .. clicmd:: debug openfabric adj-packets -.. index:: debug openfabric adj-packets -.. clicmd:: no debug openfabric adj-packets + OpenFabric Adjacency related packets. -OpenFabric Adjacency related packets. - -.. index:: debug openfabric checksum-errors .. clicmd:: debug openfabric checksum-errors -.. index:: debug openfabric checksum-errors -.. clicmd:: no debug openfabric checksum-errors - -OpenFabric LSP checksum errors. + OpenFabric LSP checksum errors. -.. index:: debug openfabric events .. clicmd:: debug openfabric events -.. index:: debug openfabric events -.. clicmd:: no debug openfabric events - -OpenFabric Events. + OpenFabric Events. -.. index:: debug openfabric local-updates .. clicmd:: debug openfabric local-updates -.. index:: debug openfabric local-updates -.. clicmd:: no debug openfabric local-updates + OpenFabric local update packets. -OpenFabric local update packets. - -.. index:: debug openfabric lsp-gen .. clicmd:: debug openfabric lsp-gen -.. index:: debug openfabric lsp-gen -.. clicmd:: no debug openfabric lsp-gen - -Generation of own LSPs. + Generation of own LSPs. -.. index:: debug openfabric lsp-sched .. clicmd:: debug openfabric lsp-sched -.. index:: debug openfabric lsp-sched -.. clicmd:: no debug openfabric lsp-sched + Debug scheduling of generation of own LSPs. -Debug scheduling of generation of own LSPs. - -.. index:: debug openfabric packet-dump .. clicmd:: debug openfabric packet-dump -.. index:: debug openfabric packet-dump -.. clicmd:: no debug openfabric packet-dump - -OpenFabric packet dump. + OpenFabric packet dump. -.. index:: debug openfabric protocol-errors .. clicmd:: debug openfabric protocol-errors -.. index:: debug openfabric protocol-errors -.. clicmd:: no debug openfabric protocol-errors - -OpenFabric LSP protocol errors. + OpenFabric LSP protocol errors. -.. index:: debug openfabric route-events .. clicmd:: debug openfabric route-events -.. index:: debug openfabric route-events -.. clicmd:: no debug openfabric route-events + OpenFabric Route related events. -OpenFabric Route related events. - -.. index:: debug openfabric snp-packets .. clicmd:: debug openfabric snp-packets -.. index:: debug openfabric snp-packets -.. clicmd:: no debug openfabric snp-packets - -OpenFabric CSNP/PSNP packets. + OpenFabric CSNP/PSNP packets. -.. index:: debug openfabric spf-events .. clicmd:: debug openfabric spf-events -.. index:: debug openfabric spf-statistics .. clicmd:: debug openfabric spf-statistics -.. index:: debug openfabric spf-triggers .. clicmd:: debug openfabric spf-triggers -.. index:: debug openfabric spf-events -.. clicmd:: no debug openfabric spf-events + OpenFabric Shortest Path First Events, Timing and Statistic Data and + triggering events. -.. index:: debug openfabric spf-statistics -.. clicmd:: no debug openfabric spf-statistics - -.. index:: debug openfabric spf-triggers -.. clicmd:: no debug openfabric spf-triggers - -OpenFabric Shortest Path First Events, Timing and Statistic Data and triggering -events. - -.. index:: debug openfabric update-packets .. clicmd:: debug openfabric update-packets -.. index:: debug openfabric update-packets -.. clicmd:: no debug openfabric update-packets + Update-related packets. -Update related packets. - -.. index:: show debugging openfabric .. clicmd:: show debugging openfabric Print which OpenFabric debug levels are active. + OpenFabric configuration example ================================ diff --git a/doc/user/filter.rst b/doc/user/filter.rst index 910da7246d..78043e779b 100644 --- a/doc/user/filter.rst +++ b/doc/user/filter.rst @@ -9,10 +9,8 @@ defined, it can be applied in any direction. IP Access List ============== -.. index:: access-list NAME [seq (1-4294967295)] permit IPV4-NETWORK .. clicmd:: access-list NAME [seq (1-4294967295)] permit IPV4-NETWORK -.. index:: access-list NAME [seq (1-4294967295)] deny IPV4-NETWORK .. clicmd:: access-list NAME [seq (1-4294967295)] deny IPV4-NETWORK seq @@ -50,10 +48,8 @@ filters to arbitrary points of prefix-list using sequential number specification If no ip prefix-list is specified, it acts as permit. If *ip prefix-list* is defined, and no match is found, default deny is applied. -.. index:: ip prefix-list NAME (permit|deny) PREFIX [le LEN] [ge LEN] .. clicmd:: ip prefix-list NAME (permit|deny) PREFIX [le LEN] [ge LEN] -.. index:: ip prefix-list NAME seq NUMBER (permit|deny) PREFIX [le LEN] [ge LEN] .. clicmd:: ip prefix-list NAME seq NUMBER (permit|deny) PREFIX [le LEN] [ge LEN] You can create *ip prefix-list* using above commands. @@ -98,88 +94,63 @@ is defined, and no match is found, default deny is applied. In the case of no le or ge command, the prefix length must match exactly the length specified in the prefix list. -.. index:: ip prefix-list NAME -.. clicmd:: no ip prefix-list NAME .. _ip-prefix-list-description: ip prefix-list description -------------------------- -.. index:: ip prefix-list NAME description DESC .. clicmd:: ip prefix-list NAME description DESC Descriptions may be added to prefix lists. This command adds a description to the prefix list. -.. index:: ip prefix-list NAME description [DESC] -.. clicmd:: no ip prefix-list NAME description [DESC] - - Deletes the description from a prefix list. It is possible to use the - command without the full description. .. _ip-prefix-list-sequential-number-control: ip prefix-list sequential number control ---------------------------------------- -.. index:: ip prefix-list sequence-number .. clicmd:: ip prefix-list sequence-number With this command, the IP prefix list sequential number is displayed. This is the default behavior. -.. index:: ip prefix-list sequence-number -.. clicmd:: no ip prefix-list sequence-number - - With this command, the IP prefix list sequential number is not - displayed. .. _showing-ip-prefix-list: Showing ip prefix-list ---------------------- -.. index:: show ip prefix-list .. clicmd:: show ip prefix-list Display all IP prefix lists. -.. index:: show ip prefix-list NAME .. clicmd:: show ip prefix-list NAME Show IP prefix list can be used with a prefix list name. -.. index:: show ip prefix-list NAME seq NUM .. clicmd:: show ip prefix-list NAME seq NUM Show IP prefix list can be used with a prefix list name and sequential number. -.. index:: show ip prefix-list NAME A.B.C.D/M .. clicmd:: show ip prefix-list NAME A.B.C.D/M If the command longer is used, all prefix lists with prefix lengths equal to or longer than the specified length will be displayed. If the command first match is used, the first prefix length match will be displayed. -.. index:: show ip prefix-list NAME A.B.C.D/M longer .. clicmd:: show ip prefix-list NAME A.B.C.D/M longer -.. index:: show ip prefix-list NAME A.B.C.D/M first-match .. clicmd:: show ip prefix-list NAME A.B.C.D/M first-match -.. index:: show ip prefix-list summary .. clicmd:: show ip prefix-list summary -.. index:: show ip prefix-list summary NAME .. clicmd:: show ip prefix-list summary NAME -.. index:: show ip prefix-list detail .. clicmd:: show ip prefix-list detail -.. index:: show ip prefix-list detail NAME .. clicmd:: show ip prefix-list detail NAME Clear counter of ip prefix-list ------------------------------- -.. index:: clear ip prefix-list [NAME [A.B.C.D/M]] .. clicmd:: clear ip prefix-list [NAME [A.B.C.D/M]] Clears the counters of all IP prefix lists. Clear IP Prefix List can be used diff --git a/doc/user/flowspec.rst b/doc/user/flowspec.rst index c303ebdba4..faf5973460 100644 --- a/doc/user/flowspec.rst +++ b/doc/user/flowspec.rst @@ -123,10 +123,8 @@ As of today, it is only possible to configure Flowspec on the default VRF. You can see Flowspec entries, by using one of the following show commands: -.. index:: show bgp ipv4 flowspec [detail | A.B.C.D] .. clicmd:: show bgp ipv4 flowspec [detail | A.B.C.D] -.. index:: show bgp ipv6 flowspec [detail | A:B::C:D] .. clicmd:: show bgp ipv6 flowspec [detail | A:B::C:D] Per-interface configuration @@ -141,8 +139,7 @@ twice the traffic, or slow down the traffic (filtering costs). To limit Flowspec to one specific interface, use the following command, under `flowspec address-family` node. -.. index:: local-install <IFNAME | any> -.. clicmd:: [no] local-install <IFNAME | any> +.. clicmd:: local-install <IFNAME | any> By default, Flowspec is activated on all interfaces. Installing it to a named interface will result in allowing only this interface. Conversely, enabling any @@ -168,8 +165,7 @@ following: - The first VRF with the matching Route Target will be selected to route traffic to. Use the following command under ipv4 unicast address-family node -.. index:: rt redirect import RTLIST... -.. clicmd:: [no] rt redirect import RTLIST... +.. clicmd:: rt redirect import RTLIST... In order to illustrate, if the Route Target configured in the Flowspec entry is ``E.F.G.H:II``, then a BGP VRF instance with the same Route Target will be set @@ -223,7 +219,6 @@ Those command rely on the filtering contexts configured from BGP, and get the statistics information retrieved from the underlying system. In other words, those statistics are retrieved from ``Netfilter``. -.. index:: show pbr ipset IPSETNAME | iptable .. clicmd:: show pbr ipset IPSETNAME | iptable ``IPSETNAME`` is the policy routing object name created by ``ipset``. About @@ -235,21 +230,18 @@ match. .. code-block:: frr -.. index:: show ip route table TABLEID .. clicmd:: show ip route table TABLEID ``TABLEID`` is the table number identifier referencing the non standard routing table used in this example. -.. index:: debug bgp flowspec -.. clicmd:: [no] debug bgp flowspec +.. clicmd:: debug bgp flowspec You can troubleshoot Flowspec, or BGP policy based routing. For instance, if you encounter some issues when decoding a Flowspec entry, you should enable :clicmd:`debug bgp flowspec`. -.. index:: debug bgp pbr [error] -.. clicmd:: [no] debug bgp pbr [error] +.. clicmd:: debug bgp pbr [error] If you fail to apply the flowspec entry into *zebra*, there should be some relationship with policy routing mechanism. Here, diff --git a/doc/user/installation.rst b/doc/user/installation.rst index a13e6ce43b..dbd95aca40 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -1,16 +1,16 @@ +.. index:: + single: How to install FRR + single: Installing FRR + single: Building FRR + .. _installation: Installation ============ -.. index:: How to install FRR -.. index:: Installation -.. index:: Installing FRR -.. index:: Building the system -.. index:: Making FRR - This section covers the basics of building, installing and setting up FRR. + From Packages ------------- @@ -55,14 +55,18 @@ is the release version. In addition, release tarballs are published on the GitHub releases page `here <https://github.com/FRRouting/frr/releases>`_. -Configuration -^^^^^^^^^^^^^ -.. index:: Configuration options -.. index:: Options for configuring -.. index:: Build options -.. index:: Distribution configuration -.. index:: Options to `./configure` +.. index:: + single: Configuration options + single: Options for configuring + single: Build options + single: Distribution configuration + single: Options to `./configure` + +.. _build-configuration: + +Build Configuration +^^^^^^^^^^^^^^^^^^^ FRR has an excellent configure script which automatically detects most host configurations. There are several additional configure options to customize the @@ -420,14 +424,15 @@ The `sphinx` and `pytest` dependencies can be avoided by not building documentation / not running ``make check``, but the CPython dependency is a hard dependency of the FRR build process (for the `clippy` tool.) +.. index:: + single: FRR Least-Privileges + single: FRR Privileges + .. _least-privilege-support: Least-Privilege Support """"""""""""""""""""""" -.. index:: FRR Least-Privileges -.. index:: FRR Privileges - Additionally, you may configure zebra to drop its elevated privileges shortly after startup and switch to another user. The configure script will automatically try to configure this support. There are three configure @@ -460,12 +465,14 @@ only Linux), FRR will retain only minimal capabilities required and will only raise these capabilities for brief periods. On systems without libcap, FRR will run as the user specified and only raise its UID to 0 for brief periods. + +.. index:: + pair: building; Linux + pair: configuration; Linux + Linux Notes """"""""""" -.. index:: Building on Linux boxes -.. index:: Linux configurations - There are several options available only to GNU/Linux systems. If you use GNU/Linux, make sure that the current kernel configuration is what you want. FRR will run with any kernel configuration but some recommendations do exist. diff --git a/doc/user/ipv6.rst b/doc/user/ipv6.rst index 26341f04f1..089fae39b1 100644 --- a/doc/user/ipv6.rst +++ b/doc/user/ipv6.rst @@ -17,17 +17,11 @@ no longer possible. Router Advertisement ==================== -.. index:: ipv6 nd suppress-ra -.. clicmd:: no ipv6 nd suppress-ra - - Send router advertisement messages. - -.. index:: ipv6 nd suppress-ra .. clicmd:: ipv6 nd suppress-ra - Don't send router advertisement messages. + Don't send router advertisement messages. The ``no`` form of this command + enables sending RA messages. -.. index:: ipv6 nd prefix ipv6prefix [valid-lifetime] [preferred-lifetime] [off-link] [no-autoconfig] [router-address] .. clicmd:: ipv6 nd prefix ipv6prefix [valid-lifetime] [preferred-lifetime] [off-link] [no-autoconfig] [router-address] Configuring the IPv6 prefix to include in router advertisements. Several prefix @@ -57,22 +51,19 @@ Router Advertisement Default: not set, i.e. hosts do not assume a complete IP address is placed. -.. index:: ipv6 nd ra-interval [(1-1800)] -.. clicmd:: [no] ipv6 nd ra-interval [(1-1800)] +.. clicmd:: ipv6 nd ra-interval [(1-1800)] The maximum time allowed between sending unsolicited multicast router advertisements from the interface, in seconds. Default: ``600`` -.. index:: ipv6 nd ra-interval msec (70-1800000) -.. clicmd:: [no] ipv6 nd ra-interval [msec (70-1800000)] +.. clicmd:: ipv6 nd ra-interval [msec (70-1800000)] The maximum time allowed between sending unsolicited multicast router advertisements from the interface, in milliseconds. Default: ``600000`` -.. index:: ipv6 nd ra-fast-retrans -.. clicmd:: [no] ipv6 nd ra-fast-retrans +.. clicmd:: ipv6 nd ra-fast-retrans RFC4861 states that consecutive RA packets should be sent no more frequently than three seconds apart. FRR by default allows faster @@ -83,8 +74,7 @@ Router Advertisement and neighbor establishment. Default: enabled -.. index:: ipv6 nd ra-retrans-interval (0-4294967295) -.. clicmd:: [no] ipv6 nd ra-retrans-interval [(0-4294967295)] +.. clicmd:: ipv6 nd ra-retrans-interval [(0-4294967295)] The value to be placed in the retrans timer field of router advertisements sent from the interface, in msec. Indicates the interval between router @@ -93,8 +83,7 @@ Router Advertisement msec. Default: ``0`` -.. index:: ipv6 nd ra-hop-limit (0-255) -.. clicmd:: [no] ipv6 nd ra-hop-limit [(0-255)] +.. clicmd:: ipv6 nd ra-hop-limit [(0-255)] The value to be placed in the hop count field of router advertisements sent from the interface, in hops. Indicates the maximum diameter of the network. @@ -102,8 +91,7 @@ Router Advertisement router. Must be between zero or 255 hops. Default: ``64`` -.. index:: ipv6 nd ra-lifetime (0-9000) -.. clicmd:: [no] ipv6 nd ra-lifetime [(0-9000)] +.. clicmd:: ipv6 nd ra-lifetime [(0-9000)] The value to be placed in the Router Lifetime field of router advertisements sent from the interface, in seconds. Indicates the usefulness of the router @@ -113,8 +101,7 @@ Router Advertisement (or default) and 9000 seconds. Default: ``1800`` -.. index:: ipv6 nd reachable-time (1-3600000) -.. clicmd:: [no] ipv6 nd reachable-time [(1-3600000)] +.. clicmd:: ipv6 nd reachable-time [(1-3600000)] The value to be placed in the Reachable Time field in the Router Advertisement messages sent by the router, in milliseconds. The configured @@ -122,8 +109,7 @@ Router Advertisement means unspecified (by this router). Default: ``0`` -.. index:: ipv6 nd managed-config-flag -.. clicmd:: [no] ipv6 nd managed-config-flag +.. clicmd:: ipv6 nd managed-config-flag Set/unset flag in IPv6 router advertisements which indicates to hosts that they should use managed (stateful) protocol for addresses autoconfiguration @@ -131,33 +117,28 @@ Router Advertisement autoconfiguration. Default: not set -.. index:: ipv6 nd other-config-flag -.. clicmd:: [no] ipv6 nd other-config-flag +.. clicmd:: ipv6 nd other-config-flag Set/unset flag in IPv6 router advertisements which indicates to hosts that they should use administered (stateful) protocol to obtain autoconfiguration information other than addresses. Default: not set -.. index:: ipv6 nd home-agent-config-flag -.. clicmd:: [no] ipv6 nd home-agent-config-flag +.. clicmd:: ipv6 nd home-agent-config-flag Set/unset flag in IPv6 router advertisements which indicates to hosts that the router acts as a Home Agent and includes a Home Agent Option. Default: not set -.. index:: ipv6 nd home-agent-preference (0-65535) -.. index:: ipv6 nd home-agent-preference (0-65535) -.. clicmd:: [no] ipv6 nd home-agent-preference [(0-65535)] +.. clicmd:: ipv6 nd home-agent-preference [(0-65535)] The value to be placed in Home Agent Option, when Home Agent config flag is set, which indicates to hosts Home Agent preference. The default value of 0 stands for the lowest preference possible. Default: ``0`` -.. index:: ipv6 nd home-agent-lifetime (0-65520) -.. clicmd:: [no] ipv6 nd home-agent-lifetime [(0-65520)] +.. clicmd:: ipv6 nd home-agent-lifetime [(0-65520)] The value to be placed in Home Agent Option, when Home Agent config flag is set, which indicates to hosts Home Agent Lifetime. The default value of 0 means to @@ -165,21 +146,18 @@ Router Advertisement Default: ``0`` -.. index:: ipv6 nd adv-interval-option -.. clicmd:: [no] ipv6 nd adv-interval-option +.. clicmd:: ipv6 nd adv-interval-option Include an Advertisement Interval option which indicates to hosts the maximum time, in milliseconds, between successive unsolicited Router Advertisements. Default: not set -.. index:: ipv6 nd router-preference (high|medium|low) -.. clicmd:: [no] ipv6 nd router-preference [(high|medium|low)] +.. clicmd:: ipv6 nd router-preference [(high|medium|low)] Set default router preference in IPv6 router advertisements per RFC4191. Default: medium -.. index:: ipv6 nd mtu (1-65535) -.. clicmd:: [no] ipv6 nd mtu [(1-65535)] +.. clicmd:: ipv6 nd mtu [(1-65535)] Include an MTU (type 5) option in each RA packet to assist the attached hosts in proper interface configuration. The announced value is not verified @@ -187,8 +165,7 @@ Router Advertisement Default: don't advertise any MTU option. -.. index:: ipv6 nd rdnss ipv6address [lifetime] -.. clicmd:: [no] ipv6 nd rdnss ipv6address [lifetime] +.. clicmd:: ipv6 nd rdnss ipv6address [lifetime] Recursive DNS server address to advertise using the RDNSS (type 25) option described in RFC8106. Can be specified more than once to advertise multiple @@ -205,8 +182,7 @@ Router Advertisement Default: do not emit RDNSS option -.. index:: ipv6 nd dnssl domain-name-suffix [lifetime] -.. clicmd:: [no] ipv6 nd dnssl domain-name-suffix [lifetime] +.. clicmd:: ipv6 nd dnssl domain-name-suffix [lifetime] Advertise DNS search list using the DNSSL (type 31) option described in RFC8106. Specify more than once to advertise multiple domain name suffixes. diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 352701728d..ebcf21b04c 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -33,51 +33,30 @@ ISIS router To start the ISIS process you have to specify the ISIS router. As of this writing, *isisd* does not support multiple ISIS processes. -.. index:: router isis WORD [vrf NAME] -.. clicmd:: [no] router isis WORD [vrf NAME] +.. clicmd:: router isis WORD [vrf NAME] Enable or disable the ISIS process by specifying the ISIS domain with 'WORD'. *isisd* does not yet support multiple ISIS processes but you must specify the name of ISIS process. The ISIS process name 'WORD' is then used for interface (see command :clicmd:`ip router isis WORD`). -.. index:: net XX.XXXX. ... .XXX.XX .. clicmd:: net XX.XXXX. ... .XXX.XX -.. index:: net XX.XXXX. ... .XXX.XX -.. clicmd:: no net XX.XXXX. ... .XXX.XX - Set/Unset network entity title (NET) provided in ISO format. -.. index:: hostname dynamic .. clicmd:: hostname dynamic -.. index:: hostname dynamic -.. clicmd:: no hostname dynamic - Enable support for dynamic hostname. -.. index:: area-password [clear | md5] <password> .. clicmd:: area-password [clear | md5] <password> -.. index:: domain-password [clear | md5] <password> .. clicmd:: domain-password [clear | md5] <password> -.. index:: area-password -.. clicmd:: no area-password - -.. index:: domain-password -.. clicmd:: no domain-password - Configure the authentication password for an area, respectively a domain, as clear text or md5 one. -.. index:: attached-bit [receive ignore | send] .. clicmd:: attached-bit [receive ignore | send] -.. index:: attached-bit -.. clicmd:: no attached-bit - Set attached bit for inter-area traffic: - receive @@ -85,20 +64,12 @@ writing, *isisd* does not support multiple ISIS processes. - send If L1|L2 router, set attached bit in LSP sent to L1 router -.. index:: log-adjacency-changes .. clicmd:: log-adjacency-changes -.. index:: log-adjacency-changes -.. clicmd:: no log-adjacency-changes - Log changes in adjacency state. -.. index:: metric-style [narrow | transition | wide] .. clicmd:: metric-style [narrow | transition | wide] -.. index:: metric-style -.. clicmd:: no metric-style - Set old-style (ISO 10589) or new-style packet formats: - narrow @@ -108,24 +79,15 @@ writing, *isisd* does not support multiple ISIS processes. - wide Use new style of TLVs to carry wider metric -.. index:: set-overload-bit .. clicmd:: set-overload-bit -.. index:: set-overload-bit -.. clicmd:: no set-overload-bit - Set overload bit to avoid any transit traffic. -.. index:: purge-originator .. clicmd:: purge-originator -.. index:: purge-originator -.. clicmd:: no purge-originator - Enable or disable :rfc:`6232` purge originator identification. -.. index:: lsp-mtu (128-4352) -.. clicmd:: [no] lsp-mtu (128-4352) +.. clicmd:: lsp-mtu (128-4352) Configure the maximum size of generated LSPs, in bytes. @@ -135,57 +97,23 @@ writing, *isisd* does not support multiple ISIS processes. ISIS Timer ========== -.. index:: lsp-gen-interval (1-120) -.. clicmd:: lsp-gen-interval (1-120) - -.. index:: lsp-gen-interval [level-1 | level-2] (1-120) .. clicmd:: lsp-gen-interval [level-1 | level-2] (1-120) -.. index:: lsp-gen-interval -.. clicmd:: no lsp-gen-interval - -.. index:: lsp-gen-interval [level-1 | level-2] -.. clicmd:: no lsp-gen-interval [level-1 | level-2] - Set minimum interval in seconds between regenerating same LSP, globally, for an area (level-1) or a domain (level-2). -.. index:: lsp-refresh-interval [level-1 | level-2] (1-65235) .. clicmd:: lsp-refresh-interval [level-1 | level-2] (1-65235) -.. index:: lsp-refresh-interval [level-1 | level-2] -.. clicmd:: no lsp-refresh-interval [level-1 | level-2] - Set LSP refresh interval in seconds, globally, for an area (level-1) or a domain (level-2). -.. index:: max-lsp-lifetime (360-65535) -.. clicmd:: max-lsp-lifetime (360-65535) - -.. index:: max-lsp-lifetime [level-1 | level-2] (360-65535) .. clicmd:: max-lsp-lifetime [level-1 | level-2] (360-65535) -.. index:: max-lsp-lifetime -.. clicmd:: no max-lsp-lifetime - -.. index:: max-lsp-lifetime [level-1 | level-2] -.. clicmd:: no max-lsp-lifetime [level-1 | level-2] - Set LSP maximum LSP lifetime in seconds, globally, for an area (level-1) or a domain (level-2). -.. index:: spf-interval (1-120) -.. clicmd:: spf-interval (1-120) - -.. index:: spf-interval [level-1 | level-2] (1-120) .. clicmd:: spf-interval [level-1 | level-2] (1-120) -.. index:: spf-interval -.. clicmd:: no spf-interval - -.. index:: spf-interval [level-1 | level-2] -.. clicmd:: no spf-interval [level-1 | level-2] - Set minimum interval between consecutive SPF calculations in seconds. .. _isis-fast-reroute: @@ -193,47 +121,41 @@ ISIS Timer ISIS Fast-Reroute ================= -.. index:: spf prefix-priority [critical | high | medium] WORD -.. clicmd:: spf prefix-priority [critical | high | medium] WORD +Unless stated otherwise, commands in this section apply to all LFA +flavors (local LFA, Remote LFA and TI-LFA). -.. index:: spf prefix-priority [critical | high | medium] WORD -.. clicmd:: no spf prefix-priority [critical | high | medium] [WORD] +.. clicmd:: spf prefix-priority [critical | high | medium] WORD Assign a priority to the prefixes that match the specified access-list. -.. index:: fast-reroute priority-limit [critical | high | medium] [level-1 | level-2] -.. clicmd:: [no] fast-reroute priority-limit [critical | high | medium] [level-1 | level-2] + By default loopback prefixes have medium priority and non-loopback prefixes + have low priority. + +.. clicmd:: fast-reroute priority-limit [critical | high | medium] [level-1 | level-2] Limit LFA backup computation up to the specified prefix priority. -.. index:: fast-reroute lfa tiebreaker [downstream | lowest-backup-metric | node-protecting] index (1-255) [level-1 | level-2] -.. clicmd:: [no] fast-reroute lfa tiebreaker [downstream | lowest-backup-metric | node-protecting] index (1-255) [level-1 | level-2] +.. clicmd:: fast-reroute lfa tiebreaker [downstream | lowest-backup-metric | node-protecting] index (1-255) [level-1 | level-2] - Configure a tie-breaker for multiple LFA backups. Lower indexes are processed - first. + Configure a tie-breaker for multiple local LFA backups. Lower indexes are + processed first. -.. index:: fast-reroute load-sharing disable [level-1 | level-2] -.. clicmd:: [no] fast-reroute load-sharing disable [level-1 | level-2] +.. clicmd:: fast-reroute load-sharing disable [level-1 | level-2] Disable load sharing across multiple LFA backups. -.. index:: fast-reroute remote-lfa prefix-list WORD [level-1 | level-2] -.. clicmd:: [no] fast-reroute remote-lfa prefix-list [WORD] [level-1 | level-2] +.. clicmd:: fast-reroute remote-lfa prefix-list [WORD] [level-1 | level-2] - Configure a prefix-list to select eligible PQ nodes (valid for all protected - interfaces). + Configure a prefix-list to select eligible PQ nodes for remote LFA + backups (valid for all protected interfaces). .. _isis-region: ISIS region =========== -.. index:: is-type [level-1 | level-1-2 | level-2-only] .. clicmd:: is-type [level-1 | level-1-2 | level-2-only] -.. index:: is-type -.. clicmd:: no is-type - Define the ISIS router behavior: - level-1 @@ -250,21 +172,15 @@ ISIS interface .. _ip-router-isis-word: -.. index:: ip router isis WORD [vrf NAME] -.. index:: ipv6 router isis WORD [vrf NAME] -.. clicmd:: [no] <ip|ipv6> router isis WORD [vrf NAME] +.. clicmd:: <ip|ipv6> router isis WORD [vrf NAME] Activate ISIS adjacency on this interface. Note that the name of ISIS instance must be the same as the one used to configure the ISIS process (see command :clicmd:`router isis WORD`). To enable IPv4, issue ``ip router isis WORD``; to enable IPv6, issue ``ipv6 router isis WORD``. -.. index:: isis circuit-type [level-1 | level-1-2 | level-2] .. clicmd:: isis circuit-type [level-1 | level-1-2 | level-2] -.. index:: isis circuit-type -.. clicmd:: no isis circuit-type - Configure circuit type for interface: - level-1 @@ -274,238 +190,126 @@ ISIS interface - level-2-only Level-2 only adjacencies are formed -.. index:: isis csnp-interval (1-600) -.. clicmd:: isis csnp-interval (1-600) - -.. index:: isis csnp-interval (1-600) [level-1 | level-2] .. clicmd:: isis csnp-interval (1-600) [level-1 | level-2] -.. index:: isis csnp-interval -.. clicmd:: no isis csnp-interval - -.. index:: isis csnp-interval [level-1 | level-2] -.. clicmd:: no isis csnp-interval [level-1 | level-2] - Set CSNP interval in seconds globally, for an area (level-1) or a domain (level-2). -.. index:: isis hello padding .. clicmd:: isis hello padding Add padding to IS-IS hello packets. -.. index:: isis hello-interval (1-600) -.. clicmd:: isis hello-interval (1-600) - -.. index:: isis hello-interval (1-600) [level-1 | level-2] .. clicmd:: isis hello-interval (1-600) [level-1 | level-2] -.. index:: isis hello-interval -.. clicmd:: no isis hello-interval - -.. index:: isis hello-interval [level-1 | level-2] -.. clicmd:: no isis hello-interval [level-1 | level-2] - Set Hello interval in seconds globally, for an area (level-1) or a domain (level-2). -.. index:: isis hello-multiplier (2-100) -.. clicmd:: isis hello-multiplier (2-100) - -.. index:: isis hello-multiplier (2-100) [level-1 | level-2] .. clicmd:: isis hello-multiplier (2-100) [level-1 | level-2] -.. index:: isis hello-multiplier -.. clicmd:: no isis hello-multiplier - -.. index:: isis hello-multiplier [level-1 | level-2] -.. clicmd:: no isis hello-multiplier [level-1 | level-2] - Set multiplier for Hello holding time globally, for an area (level-1) or a domain (level-2). -.. index:: isis metric [(0-255) | (0-16777215)] -.. clicmd:: isis metric [(0-255) | (0-16777215)] - -.. index:: isis metric [(0-255) | (0-16777215)] [level-1 | level-2] .. clicmd:: isis metric [(0-255) | (0-16777215)] [level-1 | level-2] -.. index:: isis metric -.. clicmd:: no isis metric - -.. index:: isis metric [level-1 | level-2] -.. clicmd:: no isis metric [level-1 | level-2] - Set default metric value globally, for an area (level-1) or a domain (level-2). Max value depend if metric support narrow or wide value (see command :clicmd:`metric-style [narrow | transition | wide]`). -.. index:: isis network point-to-point .. clicmd:: isis network point-to-point -.. index:: isis network point-to-point -.. clicmd:: no isis network point-to-point - Set network type to 'Point-to-Point' (broadcast by default). -.. index:: isis passive .. clicmd:: isis passive -.. index:: isis passive -.. clicmd:: no isis passive - Configure the passive mode for this interface. -.. index:: isis password [clear | md5] <password> .. clicmd:: isis password [clear | md5] <password> -.. index:: isis password -.. clicmd:: no isis password - Configure the authentication password (clear or encoded text) for the interface. -.. index:: isis priority (0-127) -.. clicmd:: isis priority (0-127) - -.. index:: isis priority (0-127) [level-1 | level-2] .. clicmd:: isis priority (0-127) [level-1 | level-2] -.. index:: isis priority -.. clicmd:: no isis priority - -.. index:: isis priority [level-1 | level-2] -.. clicmd:: no isis priority [level-1 | level-2] - Set priority for Designated Router election, globally, for the area (level-1) or the domain (level-2). -.. index:: isis psnp-interval (1-120) -.. clicmd:: isis psnp-interval (1-120) - -.. index:: isis psnp-interval (1-120) [level-1 | level-2] .. clicmd:: isis psnp-interval (1-120) [level-1 | level-2] -.. index:: isis psnp-interval -.. clicmd:: no isis psnp-interval - -.. index:: isis psnp-interval [level-1 | level-2] -.. clicmd:: no isis psnp-interval [level-1 | level-2] - Set PSNP interval in seconds globally, for an area (level-1) or a domain (level-2). -.. index:: isis three-way-handshake .. clicmd:: isis three-way-handshake -.. index:: isis three-way-handshake -.. clicmd:: no isis three-way-handshake - Enable or disable :rfc:`5303` Three-Way Handshake for P2P adjacencies. Three-Way Handshake is enabled by default. -.. index:: isis fast-reroute lfa [level-1 | level-2] -.. clicmd:: [no] isis fast-reroute lfa [level-1 | level-2] - - Enable per-prefix LFA fast reroute link protection. +.. clicmd:: isis fast-reroute lfa [level-1 | level-2] -.. index:: isis fast-reroute lfa [level-1 | level-2] exclude interface IFNAME -.. clicmd:: [no] isis fast-reroute lfa [level-1 | level-2] exclude interface IFNAME + Enable per-prefix local LFA fast reroute link protection. - Exclude an interface from the LFA backup nexthop computation. +.. clicmd:: isis fast-reroute lfa [level-1 | level-2] exclude interface IFNAME -.. index:: isis fast-reroute ti-lfa [level-1|level-2] [node-protection] -.. clicmd:: [no] isis fast-reroute ti-lfa [level-1|level-2] [node-protection] + Exclude an interface from the local LFA backup nexthop computation. - Enable per-prefix TI-LFA fast reroute link or node protection. - -.. index:: isis fast-reroute remote-lfa tunnel mpls-ldp [level-1 | level-2] -.. clicmd:: [no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1 | level-2] +.. clicmd:: isis fast-reroute remote-lfa tunnel mpls-ldp [level-1 | level-2] Enable per-prefix Remote LFA fast reroute link protection. Note that other routers in the network need to be configured to accept LDP targeted hello messages in order for RLFA to work. -.. index:: isis fast-reroute remote-lfa maximum-metric (1-16777215) [level-1 | level-2] -.. clicmd:: [no] isis fast-reroute remote-lfa maximum-metric (1-16777215) [level-1 | level-2] +.. clicmd:: isis fast-reroute remote-lfa maximum-metric (1-16777215) [level-1 | level-2] Limit Remote LFA PQ node selection within the specified metric. +.. clicmd:: isis fast-reroute ti-lfa [level-1|level-2] [node-protection] + + Enable per-prefix TI-LFA fast reroute link or node protection. + + .. _showing-isis-information: Showing ISIS information ======================== -.. index:: show isis summary .. clicmd:: show isis summary Show summary information about ISIS. -.. index:: show isis hostname .. clicmd:: show isis hostname Show information about ISIS node. -.. index:: show isis interface -.. clicmd:: show isis interface - -.. index:: show isis interface detail -.. clicmd:: show isis interface detail - -.. index:: show isis interface <interface name> -.. clicmd:: show isis interface <interface name> +.. clicmd:: show isis interface [detail] [IFNAME] Show state and configuration of ISIS specified interface, or all interfaces if no interface is given with or without details. -.. index:: show isis neighbor -.. clicmd:: show isis neighbor - -.. index:: show isis neighbor <System Id> -.. clicmd:: show isis neighbor <System Id> - -.. index:: show isis neighbor detail -.. clicmd:: show isis neighbor detail +.. clicmd:: show isis neighbor [detail] [SYSTEMID] Show state and information of ISIS specified neighbor, or all neighbors if no system id is given with or without details. -.. index:: show isis database -.. clicmd:: show isis database - -.. index:: show isis database [detail] -.. clicmd:: show isis database [detail] - -.. index:: show isis database <LSP id> [detail] -.. clicmd:: show isis database <LSP id> [detail] - -.. index:: show isis database detail <LSP id> -.. clicmd:: show isis database detail <LSP id> +.. clicmd:: show isis database [detail] [LSPID] Show the ISIS database globally, for a specific LSP id without or with details. -.. index:: show isis topology -.. clicmd:: show isis topology - -.. index:: show isis topology [level-1|level-2] .. clicmd:: show isis topology [level-1|level-2] Show topology IS-IS paths to Intermediate Systems, globally, in area (level-1) or domain (level-2). -.. index:: show isis route [level-1|level-2] [prefix-sid|backup] .. clicmd:: show isis route [level-1|level-2] [prefix-sid|backup] Show the ISIS routing table, as determined by the most recent SPF calculation. -.. index:: show isis fast-reroute summary [level-1|level-2] .. clicmd:: show isis fast-reroute summary [level-1|level-2] Show information about the number of prefixes having LFA protection, and network-wide LFA coverage. + .. _isis-traffic-engineering: Traffic Engineering @@ -513,35 +317,24 @@ Traffic Engineering .. note:: - At this time, FRR offers partial support for some of the routing - protocol extensions that can be used with MPLS-TE. FRR does not - support a complete RSVP-TE solution currently. + At this time, FRR offers partial support for some of the routing protocol + extensions that can be used with MPLS-TE. FRR does not currently support a + complete RSVP-TE solution. -.. index:: mpls-te on .. clicmd:: mpls-te on -.. index:: mpls-te -.. clicmd:: no mpls-te - Enable Traffic Engineering LSP flooding. -.. index:: mpls-te router-address <A.B.C.D> .. clicmd:: mpls-te router-address <A.B.C.D> -.. index:: mpls-te router-address -.. clicmd:: no mpls-te router-address - Configure stable IP address for MPLS-TE. -.. index:: show isis mpls-te interface .. clicmd:: show isis mpls-te interface -.. index:: show isis mpls-te interface INTERFACE .. clicmd:: show isis mpls-te interface INTERFACE Show MPLS Traffic Engineering parameters for all or specified interface. -.. index:: show isis mpls-te router .. clicmd:: show isis mpls-te router Show Traffic Engineering router parameters. @@ -550,6 +343,7 @@ Traffic Engineering :ref:`ospf-traffic-engineering` + .. _debugging-isis: Segment Routing @@ -566,36 +360,30 @@ Known limitations: - No support for SRLB - Only one SRGB and default SPF Algorithm is supported -.. index:: segment-routing on -.. clicmd:: [no] segment-routing on +.. clicmd:: segment-routing on Enable Segment Routing. -.. index:: segment-routing global-block (0-1048575) (0-1048575) -.. clicmd:: [no] segment-routing global-block (0-1048575) (0-1048575) +.. clicmd:: segment-routing global-block (0-1048575) (0-1048575) Set the Segment Routing Global Block i.e. the label range used by MPLS to store label in the MPLS FIB for Prefix SID. Note that the block size may not exceed 65535. -.. index:: segment-routing local-block (0-1048575) (0-1048575) -.. clicmd:: [no] segment-routing local-block (0-1048575) (0-1048575) +.. clicmd:: segment-routing local-block (0-1048575) (0-1048575) Set the Segment Routing Local Block i.e. the label range used by MPLS to store label in the MPLS FIB for Adjacency SID. Note that the block size may not exceed 65535. -.. index:: segment-routing node-msd (1-16) -.. clicmd:: [no] segment-routing node-msd (1-16) +.. clicmd:: segment-routing node-msd (1-16) Set the Maximum Stack Depth supported by the router. The value depend of the MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value is 32. -.. index:: segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null] [n-flag-clear] -.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] [n-flag-clear] +.. clicmd:: segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] [n-flag-clear] - Set the Segment Routing index or absolute label value for the specified prefix. The 'no-php-flag' means NO Penultimate Hop Popping that allows SR node to request to its neighbor to not pop the label. The 'explicit-null' flag allows SR node to request to its neighbor to send IP packet with the @@ -603,12 +391,10 @@ Known limitations: clear the Node flag that is set by default for Prefix-SIDs associated to loopback addresses. This option is necessary to configure Anycast-SIDs. -.. index:: show isis segment-routing prefix-sids .. clicmd:: show isis segment-routing prefix-sids Show detailed information about all learned Segment Routing Prefix-SIDs. -.. index:: show isis segment-routing nodes .. clicmd:: show isis segment-routing nodes Show detailed information about all learned Segment Routing Nodes. @@ -616,120 +402,66 @@ Known limitations: Debugging ISIS ============== -.. index:: debug isis adj-packets .. clicmd:: debug isis adj-packets -.. index:: debug isis adj-packets -.. clicmd:: no debug isis adj-packets - IS-IS Adjacency related packets. -.. index:: debug isis checksum-errors .. clicmd:: debug isis checksum-errors -.. index:: debug isis checksum-errors -.. clicmd:: no debug isis checksum-errors - IS-IS LSP checksum errors. -.. index:: debug isis events .. clicmd:: debug isis events -.. index:: debug isis events -.. clicmd:: no debug isis events - IS-IS Events. -.. index:: debug isis local-updates .. clicmd:: debug isis local-updates -.. index:: debug isis local-updates -.. clicmd:: no debug isis local-updates - IS-IS local update packets. -.. index:: debug isis packet-dump .. clicmd:: debug isis packet-dump -.. index:: debug isis packet-dump -.. clicmd:: no debug isis packet-dump - IS-IS packet dump. -.. index:: debug isis protocol-errors .. clicmd:: debug isis protocol-errors -.. index:: debug isis protocol-errors -.. clicmd:: no debug isis protocol-errors - IS-IS LSP protocol errors. -.. index:: debug isis route-events .. clicmd:: debug isis route-events -.. index:: debug isis route-events -.. clicmd:: no debug isis route-events - IS-IS Route related events. -.. index:: debug isis snp-packets .. clicmd:: debug isis snp-packets -.. index:: debug isis snp-packets -.. clicmd:: no debug isis snp-packets - IS-IS CSNP/PSNP packets. -.. index:: debug isis spf-events .. clicmd:: debug isis spf-events - -.. index:: debug isis spf-statistics .. clicmd:: debug isis spf-statistics - -.. index:: debug isis spf-triggers .. clicmd:: debug isis spf-triggers -.. index:: debug isis spf-events -.. clicmd:: no debug isis spf-events - -.. index:: debug isis spf-statistics -.. clicmd:: no debug isis spf-statistics - -.. index:: debug isis spf-triggers -.. clicmd:: no debug isis spf-triggers - IS-IS Shortest Path First Events, Timing and Statistic Data and triggering events. -.. index:: debug isis update-packets .. clicmd:: debug isis update-packets -.. index:: debug isis update-packets -.. clicmd:: no debug isis update-packets Update related packets. -.. index:: debug isis sr-events .. clicmd:: debug isis sr-events -.. index:: debug isis sr-events -.. clicmd:: no debug isis sr-events IS-IS Segment Routing events. -.. index:: debug isis lfa .. clicmd:: debug isis lfa -.. index:: debug isis lfa -.. clicmd:: no debug isis lfa IS-IS LFA events. -.. index:: show debugging isis .. clicmd:: show debugging isis Print which ISIS debug level is activate. +.. _isis-config-examples: + ISIS Configuration Examples =========================== @@ -843,6 +575,9 @@ A Segment Routing configuration, with IPv4, IPv6, SRGB and MSD configuration. segment-routing prefix 2001:db8:1000::1/128 index 101 explicit-null ! + +.. _isis-vrf-config-examples: + ISIS Vrf Configuration Examples =============================== @@ -860,5 +595,3 @@ A simple vrf example: net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00 metric-style wide is-type level-2-only - - diff --git a/doc/user/ldpd.rst b/doc/user/ldpd.rst index 375842f2ba..3e662b14d8 100644 --- a/doc/user/ldpd.rst +++ b/doc/user/ldpd.rst @@ -97,53 +97,45 @@ implementation. LDP Configuration =================== -.. index:: mpls ldp -.. clicmd:: [no] mpls ldp +.. clicmd:: mpls ldp Enable or disable LDP daemon -.. index:: router-id A.B.C.D -.. clicmd:: [no] router-id A.B.C.D +.. clicmd:: router-id A.B.C.D The following command located under MPLS router node configures the MPLS router-id of the local device. -.. index:: ordered-control -.. clicmd:: [no] ordered-control +.. clicmd:: ordered-control Configure LDP Ordered Label Distribution Control. -.. index:: address-family [ipv4 | ipv6] -.. clicmd:: [no] address-family [ipv4 | ipv6] +.. clicmd:: address-family [ipv4 | ipv6] Configure LDP for IPv4 or IPv6 address-family. Located under MPLS route node, this subnode permits configuring the LDP neighbors. -.. index:: interface IFACE -.. clicmd:: [no] interface IFACE +.. clicmd:: interface IFACE Located under MPLS address-family node, use this command to enable or disable LDP discovery per interface. IFACE stands for the interface name where LDP is enabled. By default it is disabled. Once this command executed, the address-family interface node is configured. -.. index:: discovery transport-address A.B.C.D | A:B::C:D -.. clicmd:: [no] discovery transport-address A.B.C.D | A:B::C:D +.. clicmd:: discovery transport-address A.B.C.D | A:B::C:D Located under mpls address-family interface node, use this command to set the IPv4 or IPv6 transport-address used by the LDP protocol to talk on this interface. -.. index:: neighbor A.B.C.D password PASSWORD -.. clicmd:: [no] neighbor A.B.C.D password PASSWORD +.. clicmd:: neighbor A.B.C.D password PASSWORD The following command located under MPLS router node configures the router of a LDP device. This device, if found, will have to comply with the configured password. PASSWORD is a clear text password wit its digest sent through the network. -.. index:: neighbor A.B.C.D holdtime HOLDTIME -.. clicmd:: [no] neighbor A.B.C.D holdtime HOLDTIME +.. clicmd:: neighbor A.B.C.D holdtime HOLDTIME The following command located under MPLS router node configures the holdtime value in seconds of the LDP neighbor ID. Configuring it triggers a keepalive @@ -151,19 +143,16 @@ LDP Configuration this time of non response, the LDP established session will be considered as set to down. By default, no holdtime is configured for the LDP devices. -.. index:: discovery hello holdtime HOLDTIME -.. clicmd:: [no] discovery hello holdtime HOLDTIME +.. clicmd:: discovery hello holdtime HOLDTIME -.. index:: discovery hello interval INTERVAL -.. clicmd:: [no] discovery hello interval INTERVAL +.. clicmd:: discovery hello interval INTERVAL INTERVAL value ranges from 1 to 65535 seconds. Default value is 5 seconds. This is the value between each hello timer message sent. HOLDTIME value ranges from 1 to 65535 seconds. Default value is 15 seconds. That value is added as a TLV in the LDP messages. -.. index:: dual-stack transport-connection prefer ipv4 -.. clicmd:: [no] dual-stack transport-connection prefer ipv4 +.. clicmd:: dual-stack transport-connection prefer ipv4 When *ldpd* is configured for dual-stack operation, the transport connection preference is IPv6 by default (as specified by :rfc:`7552`). On such @@ -179,7 +168,6 @@ Show LDP Information These commands dump various parts of *ldpd*. -.. index:: show mpls ldp neighbor [A.B.C.D] .. clicmd:: show mpls ldp neighbor [A.B.C.D] This command dumps the various neighbors discovered. Below example shows that @@ -192,29 +180,22 @@ These commands dump various parts of *ldpd*. ipv4 1.1.1.1 OPERATIONAL 1.1.1.1 00:01:37 west-vm# -.. index:: show mpls ldp neighbor [A.B.C.D] capabilities .. clicmd:: show mpls ldp neighbor [A.B.C.D] capabilities -.. index:: show mpls ldp neighbor [A.B.C.D] detail .. clicmd:: show mpls ldp neighbor [A.B.C.D] detail Above commands dump other neighbor information. -.. index:: show mpls ldp discovery [detail] .. clicmd:: show mpls ldp discovery [detail] -.. index:: show mpls ldp ipv4 discovery [detail] .. clicmd:: show mpls ldp ipv4 discovery [detail] -.. index:: show mpls ldp ipv6 discovery [detail] .. clicmd:: show mpls ldp ipv6 discovery [detail] Above commands dump discovery information. -.. index:: show mpls ldp ipv4 interface .. clicmd:: show mpls ldp ipv4 interface -.. index:: show mpls ldp ipv6 interface .. clicmd:: show mpls ldp ipv6 interface Above command dumps the IPv4 or IPv6 interface per where LDP is enabled. @@ -228,7 +209,6 @@ These commands dump various parts of *ldpd*. ipv4 eth3 ACTIVE 00:08:35 5/15 1 -.. index:: show mpls ldp ipv4|ipv6 binding .. clicmd:: show mpls ldp ipv4|ipv6 binding Above command dumps the binding obtained through MPLS exchanges with LDP. @@ -245,14 +225,12 @@ These commands dump various parts of *ldpd*. ipv4 10.200.0.0/24 1.1.1.1 17 imp-null yes west-vm# + LDP debugging commands ======================== -.. index:: - simple: debug mpls ldp KIND - simple: no debug mpls ldp KIND -.. clicmd:: [no] debug mpls ldp KIND +.. clicmd:: debug mpls ldp KIND Enable or disable debugging messages of a given kind. ``KIND`` can be one of: diff --git a/doc/user/nhrpd.rst b/doc/user/nhrpd.rst index 65645c519d..b02e761acc 100644 --- a/doc/user/nhrpd.rst +++ b/doc/user/nhrpd.rst @@ -77,7 +77,6 @@ command defines the GRE subnet): Configuring NHRP ================ -.. index:: ip nhrp holdtime (1-65000) .. clicmd:: ip nhrp holdtime (1-65000) Holdtime is the number of seconds that have to pass before stopping to @@ -85,12 +84,10 @@ Configuring NHRP registration requests are sent. By default registrations are sent every one third of the holdtime. -.. index:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local .. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local Map an IP address of a station to the station's NBMA address. -.. index:: ip nhrp network-id (1-4294967295) .. clicmd:: ip nhrp network-id (1-4294967295) Enable NHRP on this interface and set the interface's network ID. The @@ -101,30 +98,25 @@ Configuring NHRP different nodes do not need to match. When NHRP packets are received on an interface they are assigned to the local NHRP domain for that interface. -.. index:: ip nhrp nhs A.B.C.D nbma A.B.C.D|FQDN .. clicmd:: ip nhrp nhs A.B.C.D nbma A.B.C.D|FQDN Configure the Next Hop Server address and its NBMA address. -.. index:: ip nhrp nhs dynamic nbma A.B.C.D .. clicmd:: ip nhrp nhs dynamic nbma A.B.C.D Configure the Next Hop Server to have a dynamic address and set its NBMA address. -.. index:: ip nhrp registration no-unique .. clicmd:: ip nhrp registration no-unique Allow the client to not set the unique flag in the NHRP packets. This is useful when a station has a dynamic IP address that could change over time. -.. index:: ip nhrp shortcut .. clicmd:: ip nhrp shortcut Enable shortcut (spoke-to-spoke) tunnels to allow NHC to talk to each others directly after establishing a connection without going through the hub. -.. index:: ip nhrp mtu .. clicmd:: ip nhrp mtu Configure NHRP advertised MTU. @@ -159,13 +151,11 @@ However, the above should be good in most cases. This kernel NFLOG target's nflog-group is configured in global nhrp config with: -.. index:: nhrp nflog-group (1-65535) .. clicmd:: nhrp nflog-group (1-65535) To start sending these traffic notices out from hubs, use the nhrp per-interface directive: -.. index:: ip nhrp redirect .. clicmd:: ip nhrp redirect This enable redirect replies on the NHS similar to ICMP redirects except this @@ -195,7 +185,6 @@ https://gitlab.alpinelinux.org/alpine/aports/-/tree/master/main/strongswan NHRP Events =========== -.. index:: nhrp event socket SOCKET .. clicmd:: nhrp event socket SOCKET Configure the Unix path for the event socket. @@ -205,22 +194,18 @@ NHRP Events Show NHRP ========== -.. index:: show [ip|ipv6] nhrp cache [json] .. clicmd:: show [ip|ipv6] nhrp cache [json] Dump the cache entries. -.. index:: show [ip|ipv6] nhrp opennhrp [json] .. clicmd:: show [ip|ipv6] nhrp opennhrp [json] Dump the cache entries with opennhrp format. -.. index:: show [ip|ipv6] nhrp nhs [json] .. clicmd:: show [ip|ipv6] nhrp nhs [json] Dump the hub context. -.. index:: show dmvpn [json] .. clicmd:: show dmvpn [json] Dump the security contexts. diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index 99119bb7e5..6f8ac978de 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -12,28 +12,20 @@ described in :rfc:`2740`. OSPF6 router ============ -.. index:: router ospf6 .. clicmd:: router ospf6 -.. index:: ospf6 router-id A.B.C.D .. clicmd:: ospf6 router-id A.B.C.D Set router's Router-ID. -.. index:: interface IFNAME area (0-4294967295) .. clicmd:: interface IFNAME area (0-4294967295) -.. index:: interface IFNAME area A.B.C.D .. clicmd:: interface IFNAME area A.B.C.D Bind interface to specified area, and start sending OSPF packets. `area` can be specified as 0. -.. index:: timers throttle spf DELAY INITIAL-HOLDTIME MAX-HOLDTIME -.. clicmd:: timers throttle spf DELAY INITIAL-HOLDTIME MAX-HOLDTIME - -.. index:: timers throttle spf -.. clicmd:: no timers throttle spf +.. clicmd:: timers throttle spf (0-600000) (0-600000) (0-600000) This command sets the initial `delay`, the `initial-holdtime` and the `maximum-holdtime` between when SPF is calculated and the @@ -68,11 +60,8 @@ OSPF6 router time an SPF-triggering event occurs within the hold-time of the previous SPF calculation. -.. index:: auto-cost reference-bandwidth COST .. clicmd:: auto-cost reference-bandwidth COST -.. index:: auto-cost reference-bandwidth -.. clicmd:: no auto-cost reference-bandwidth This sets the reference bandwidth for cost calculations, where this bandwidth is considered equivalent to an OSPF cost of 1, specified in @@ -83,12 +72,12 @@ OSPF6 router This configuration setting MUST be consistent across all routers within the OSPF domain. -.. index:: maximum-paths (1-64) -.. clicmd::[no] maximum-paths (1-64) +.. clicmd:: maximum-paths (1-64) Use this command to control the maximum number of parallel routes that OSPFv3 can support. The default is 64. + .. _ospf6-area: OSPF6 area @@ -101,38 +90,31 @@ Area support for OSPFv3 is not yet implemented. OSPF6 interface =============== -.. index:: ipv6 ospf6 cost COST .. clicmd:: ipv6 ospf6 cost COST Sets interface's output cost. Default value depends on the interface bandwidth and on the auto-cost reference bandwidth. -.. index:: ipv6 ospf6 hello-interval HELLOINTERVAL .. clicmd:: ipv6 ospf6 hello-interval HELLOINTERVAL Sets interface's Hello Interval. Default 10 -.. index:: ipv6 ospf6 dead-interval DEADINTERVAL .. clicmd:: ipv6 ospf6 dead-interval DEADINTERVAL Sets interface's Router Dead Interval. Default value is 40. -.. index:: ipv6 ospf6 retransmit-interval RETRANSMITINTERVAL .. clicmd:: ipv6 ospf6 retransmit-interval RETRANSMITINTERVAL Sets interface's Rxmt Interval. Default value is 5. -.. index:: ipv6 ospf6 priority PRIORITY .. clicmd:: ipv6 ospf6 priority PRIORITY Sets interface's Router Priority. Default value is 1. -.. index:: ipv6 ospf6 transmit-delay TRANSMITDELAY .. clicmd:: ipv6 ospf6 transmit-delay TRANSMITDELAY Sets interface's Inf-Trans-Delay. Default value is 1. -.. index:: ipv6 ospf6 network (broadcast|point-to-point) .. clicmd:: ipv6 ospf6 network (broadcast|point-to-point) Set explicitly network type for specified interface. @@ -142,7 +124,6 @@ OSPF6 route-map Usage of *ospfd6*'s route-map support. -.. index:: set metric [+|-](0-4294967295) .. clicmd:: set metric [+|-](0-4294967295) Set a metric for matched route when sending announcement. Use plus (+) sign @@ -154,14 +135,9 @@ Usage of *ospfd6*'s route-map support. Redistribute routes to OSPF6 ============================ -.. index:: redistribute static -.. clicmd:: redistribute static - -.. index:: redistribute connected -.. clicmd:: redistribute connected +.. clicmd:: redistribute <babel|bgp|connected|isis|kernel|openfabric|ripng|sharp|static|table> [route-map WORD] -.. index:: redistribute ripng -.. clicmd:: redistribute ripng + Redistribute routes from other protocols into OSPFv3. .. _showing-ospf6-information: @@ -169,14 +145,12 @@ Redistribute routes to OSPF6 Showing OSPF6 information ========================= -.. index:: show ipv6 ospf6 [INSTANCE_ID] [json] .. clicmd:: show ipv6 ospf6 [INSTANCE_ID] [json] INSTANCE_ID is an optional OSPF instance ID. To see router ID and OSPF instance ID, simply type "show ipv6 ospf6 <cr>". JSON output can be obtained by appending 'json' to the end of command. -.. index:: show ipv6 ospf6 database [<detail|dump|internal>] [json] .. clicmd:: show ipv6 ospf6 database [<detail|dump|internal>] [json] This command shows LSAs present in the LSDB. There are three view options. @@ -184,14 +158,12 @@ Showing OSPF6 information can be obtained by appending 'json' to the end of command. JSON option is not applicable with 'dump' option. -.. index:: show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [json] .. clicmd:: show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [json] These options filters out the LSA based on its type. The three views options works here as well. JSON output can be obtained by appending 'json' to the end of command. -.. index:: show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D [json] .. clicmd:: show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D [json] The LSAs additinally can also be filtered with the linkstate-id and @@ -199,54 +171,45 @@ Showing OSPF6 information this command as well and visa-versa. JSON output can be obtained by appending 'json' to the end of command. -.. index:: show ipv6 ospf6 database self-originated [json] .. clicmd:: show ipv6 ospf6 database self-originated [json] This command is used to filter the LSAs which are originated by the present router. All the other filters are applicable here as well. -.. index:: show ipv6 ospf6 interface [json] .. clicmd:: show ipv6 ospf6 interface [json] To see OSPF interface configuration like costs. JSON output can be obtained by appending "json" in the end. -.. index:: show ipv6 ospf6 neighbor [json] .. clicmd:: show ipv6 ospf6 neighbor [json] Shows state and chosen (Backup) DR of neighbor. JSON output can be obtained by appending 'json' at the end. -.. index:: show ipv6 ospf6 interface traffic [json] .. clicmd:: show ipv6 ospf6 interface traffic [json] Shows counts of different packets that have been recieved and transmitted by the interfaces. JSON output can be obtained by appending "json" at the end. -.. index:: show ipv6 ospf6 request-list A.B.C.D .. clicmd:: show ipv6 ospf6 request-list A.B.C.D Shows requestlist of neighbor. -.. index:: show ipv6 route ospf6 .. clicmd:: show ipv6 route ospf6 This command shows internal routing table. -.. index:: show ipv6 ospf6 zebra [json] .. clicmd:: show ipv6 ospf6 zebra [json] Shows state about what is being redistributed between zebra and OSPF6. JSON output can be obtained by appending "json" at the end. -.. index:: show ipv6 ospf6 redistribute [json] .. clicmd:: show ipv6 ospf6 redistribute [json] Shows the routes which are redistributed by the router. JSON output can be obtained by appending 'json' at the end. -.. index:: show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json] .. clicmd:: show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json] This command displays the ospfv3 routing table as determined by the most @@ -255,13 +218,11 @@ Showing OSPF6 information and summary. JSON output can be obtained by appending 'json' to the end of command. -.. index:: show ipv6 ospf6 route X:X::X:X/M match [detail] [json] .. clicmd:: show ipv6 ospf6 route X:X::X:X/M match [detail] [json] The additional match option will match the given address to the destination of the routes, and return the result accordingly. -.. index:: show ipv6 ospf6 interface [IFNAME] prefix [detail|<X:X::X:X|X:X::X:X/M> [<match|detail>]] [json] .. clicmd:: show ipv6 ospf6 interface [IFNAME] prefix [detail|<X:X::X:X|X:X::X:X/M> [<match|detail>]] [json] This command shows the prefixes present in the interface routing table. diff --git a/doc/user/ospf_fundamentals.rst b/doc/user/ospf_fundamentals.rst index b0eb018107..38c18e5526 100644 --- a/doc/user/ospf_fundamentals.rst +++ b/doc/user/ospf_fundamentals.rst @@ -3,8 +3,10 @@ OSPF Fundamentals ================= -.. index:: Link-state routing protocol -.. index:: Distance-vector routing protocol +.. index:: + pair: Link-state routing protocol; OSPF + pair: Distance-vector routing protocol; OSPF + :abbr:`OSPF` is, mostly, a link-state routing protocol. In contrast to :term:`distance-vector` protocols, such as :abbr:`RIP` or :abbr:`BGP`, where @@ -12,10 +14,12 @@ routers describe available `paths` (i.e. routes) to each other, in :term:`link-state` protocols routers instead describe the state of their links to their immediate neighbouring routers. -.. index:: Link State Announcement -.. index:: Link State Advertisement -.. index:: LSA flooding -.. index:: Link State Database +.. index:: + single: Link State Announcement + single: Link State Advertisement + single: LSA flooding + single: Link State Database + Each router describes their link-state information in a message known as an :abbr:`LSA (Link State Advertisement)`, which is then propagated through to all @@ -27,7 +31,8 @@ metric, by using an algorithm such as `Edsger Dijkstra's <http://www.cs.utexas.edu/users/EWD/>`_ :abbr:`SPF (Shortest Path First)` algorithm. -.. index:: Link-state routing protocol advantages +.. index:: + pair: Link-state routing protocol; advantages By describing connectivity of a network in this way, in terms of routers and links rather than in terms of the paths through a network, @@ -39,7 +44,8 @@ reconverge on the best paths through the network. In contrast, distance vector protocols can require a progression of different path update messages from a series of different routers in order to converge. -.. index:: Link-state routing protocol disadvantages +.. index:: + pair: Link-state routing protocol; disadvantages The disadvantage to a link-state protocol is that the process of computing the best paths can be relatively intensive when compared to @@ -64,7 +70,8 @@ will nearly all be covered in greater detail further on. They may be broadly classed as: -.. index:: OSPF Hello Protocol +.. index:: + pair: Hello protocol; OSPF The Hello Protocol ^^^^^^^^^^^^^^^^^^ @@ -86,7 +93,10 @@ sharing a link, for example: The Hello protocol is comparatively trivial and will not be explored in more detail. -.. index:: OSPF LSA overview + +.. index:: + pair: LSA; OSPF + .. _ospf-lsas: LSAs @@ -120,7 +130,9 @@ OSPF defines several related mechanisms, used to manage synchronisation of :abbr:`LSDB` s between neighbours as neighbours form adjacencies and the propagation, or `flooding` of new or updated :abbr:`LSA` s. -.. index:: OSPF Areas overview + +.. index:: + pair: Area; OSPF .. _ospf-areas: diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index ee02a9dae5..8689bc4ccb 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -80,19 +80,13 @@ Routers To start OSPF process you have to specify the OSPF router. -.. index:: router ospf [(1-65535)] vrf NAME .. clicmd:: router ospf [(1-65535)] vrf NAME -.. index:: router ospf [(1-65535)] vrf NAME -.. clicmd:: no router ospf [(1-65535)] vrf NAME Enable or disable the OSPF process. -.. index:: ospf router-id A.B.C.D .. clicmd:: ospf router-id A.B.C.D -.. index:: ospf router-id [A.B.C.D] -.. clicmd:: no ospf router-id [A.B.C.D] This sets the router-ID of the OSPF process. The router-ID may be an IP address of the router, but need not be - it can be any arbitrary 32bit @@ -101,11 +95,8 @@ To start OSPF process you have to specify the OSPF router. with the same router-ID! If one is not specified then *ospfd* will obtain a router-ID automatically from *zebra*. -.. index:: ospf abr-type TYPE .. clicmd:: ospf abr-type TYPE -.. index:: ospf abr-type TYPE -.. clicmd:: no ospf abr-type TYPE `type` can be cisco|ibm|shortcut|standard. The "Cisco" and "IBM" types are equivalent. @@ -137,11 +128,8 @@ To start OSPF process you have to specify the OSPF router. OSPF domain, is dropped. This document describes alternative ABR behaviors implemented in Cisco and IBM routers." -.. index:: ospf rfc1583compatibility .. clicmd:: ospf rfc1583compatibility -.. index:: ospf rfc1583compatibility -.. clicmd:: no ospf rfc1583compatibility :rfc:`2328`, the successor to :rfc:`1583`, suggests according to section G.2 (changes) in section 16.4 a change to the path @@ -152,21 +140,15 @@ To start OSPF process you have to specify the OSPF router. This command should NOT be set normally. -.. index:: log-adjacency-changes [detail] .. clicmd:: log-adjacency-changes [detail] -.. index:: log-adjacency-changes [detail] -.. clicmd:: no log-adjacency-changes [detail] Configures ospfd to log changes in adjacency. With the optional detail argument, all changes in adjacency status are shown. Without detail, only changes to full or regressions are shown. -.. index:: passive-interface INTERFACE .. clicmd:: passive-interface INTERFACE -.. index:: passive-interface INTERFACE -.. clicmd:: no passive-interface INTERFACE Do not speak OSPF interface on the given interface, but do advertise the interface as a stub link in the @@ -177,12 +159,8 @@ To start OSPF process you have to specify the OSPF router. OSPF (:ref:`redistribute-routes-to-ospf`). This is the only way to advertise non-OSPF links into stub areas. -.. index:: timers throttle spf (0-600000) (0-600000) (0-600000) .. clicmd:: timers throttle spf (0-600000) (0-600000) (0-600000) -.. index:: timers throttle spf -.. clicmd:: no timers throttle spf - This command sets the initial `delay`, the `initial-holdtime` and the `maximum-holdtime` between when SPF is calculated and the event which triggered the calculation. The times are specified in @@ -221,14 +199,10 @@ To start OSPF process you have to specify the OSPF router. This command supersedes the *timers spf* command in previous FRR releases. -.. index:: max-metric router-lsa [on-startup|on-shutdown] (5-86400) .. clicmd:: max-metric router-lsa [on-startup|on-shutdown] (5-86400) -.. index:: max-metric router-lsa administrative .. clicmd:: max-metric router-lsa administrative -.. index:: max-metric router-lsa [on-startup|on-shutdown|administrative] -.. clicmd:: no max-metric router-lsa [on-startup|on-shutdown|administrative] This enables :rfc:`3137` support, where the OSPF process describes its transit links in its router-LSA as having infinite distance so that other @@ -257,11 +231,8 @@ To start OSPF process you have to specify the OSPF router. number of second remaining till on-startup or on-shutdown ends, can be viewed with the :clicmd:`show ip ospf` command. -.. index:: auto-cost reference-bandwidth (1-4294967) .. clicmd:: auto-cost reference-bandwidth (1-4294967) -.. index:: auto-cost reference-bandwidth -.. clicmd:: no auto-cost reference-bandwidth This sets the reference bandwidth for cost calculations, where this bandwidth is considered @@ -273,17 +244,11 @@ To start OSPF process you have to specify the OSPF router. This configuration setting MUST be consistent across all routers within the OSPF domain. -.. index:: network A.B.C.D/M area A.B.C.D .. clicmd:: network A.B.C.D/M area A.B.C.D -.. index:: network A.B.C.D/M area (0-4294967295) .. clicmd:: network A.B.C.D/M area (0-4294967295) -.. index:: network A.B.C.D/M area A.B.C.D -.. clicmd:: no network A.B.C.D/M area A.B.C.D -.. index:: network A.B.C.D/M area (0-4294967295) -.. clicmd:: no network A.B.C.D/M area (0-4294967295) This command specifies the OSPF enabled interface(s). If the interface has an address from range 192.168.1.0/24 then the command below enables ospf @@ -310,11 +275,8 @@ To start OSPF process you have to specify the OSPF router. In some cases it may be more convenient to enable OSPF on a per interface/subnet basis (:clicmd:`ip ospf area AREA [ADDR]`). -.. index:: proactive-arp .. clicmd:: proactive-arp -.. index:: proactive-arp -.. clicmd:: no proactive-arp This command enables or disables sending ARP requests to update neighbor table entries. It speeds up convergence for /32 networks on a P2P @@ -322,7 +284,6 @@ To start OSPF process you have to specify the OSPF router. This feature is enabled by default. -.. index:: clear ip ospf [(1-65535)] process .. clicmd:: clear ip ospf [(1-65535)] process This command can be used to clear the ospf process data structures. This @@ -331,7 +292,6 @@ To start OSPF process you have to specify the OSPF router. in router-id and if user wants the router-id change to take effect, user can use this cli instead of restarting the ospfd daemon. -.. index:: clear ip ospf [(1-65535)] neighbor .. clicmd:: clear ip ospf [(1-65535)] neighbor This command can be used to clear the ospf neighbor data structures. This @@ -344,17 +304,11 @@ To start OSPF process you have to specify the OSPF router. Areas ----- -.. index:: area A.B.C.D range A.B.C.D/M .. clicmd:: area A.B.C.D range A.B.C.D/M -.. index:: area (0-4294967295) range A.B.C.D/M .. clicmd:: area (0-4294967295) range A.B.C.D/M -.. index:: area A.B.C.D range A.B.C.D/M -.. clicmd:: no area A.B.C.D range A.B.C.D/M -.. index:: area (0-4294967295) range A.B.C.D/M -.. clicmd:: no area (0-4294967295) range A.B.C.D/M Summarize intra area paths from specified area into one Type-3 summary-LSA announced to other areas. This command can be used only in ABR and ONLY @@ -374,21 +328,15 @@ Areas announced into backbone area if area 0.0.0.10 contains at least one intra-area network (i.e. described with router or network LSA) from this range. -.. index:: area A.B.C.D range IPV4_PREFIX not-advertise .. clicmd:: area A.B.C.D range IPV4_PREFIX not-advertise -.. index:: area A.B.C.D range IPV4_PREFIX not-advertise -.. clicmd:: no area A.B.C.D range IPV4_PREFIX not-advertise Instead of summarizing intra area paths filter them - i.e. intra area paths from this range are not advertised into other areas. This command makes sense in ABR only. -.. index:: area A.B.C.D range IPV4_PREFIX substitute IPV4_PREFIX .. clicmd:: area A.B.C.D range IPV4_PREFIX substitute IPV4_PREFIX -.. index:: area A.B.C.D range IPV4_PREFIX substitute IPV4_PREFIX -.. clicmd:: no area A.B.C.D range IPV4_PREFIX substitute IPV4_PREFIX Substitute summarized prefix with another prefix. @@ -405,44 +353,26 @@ Areas network-LSA) from range 10.0.0.0/8. This command makes sense in ABR only. -.. index:: area A.B.C.D virtual-link A.B.C.D .. clicmd:: area A.B.C.D virtual-link A.B.C.D -.. index:: area (0-4294967295) virtual-link A.B.C.D .. clicmd:: area (0-4294967295) virtual-link A.B.C.D -.. index:: area A.B.C.D virtual-link A.B.C.D -.. clicmd:: no area A.B.C.D virtual-link A.B.C.D -.. index:: area (0-4294967295) virtual-link A.B.C.D -.. clicmd:: no area (0-4294967295) virtual-link A.B.C.D -.. index:: area A.B.C.D shortcut .. clicmd:: area A.B.C.D shortcut -.. index:: area (0-4294967295) shortcut .. clicmd:: area (0-4294967295) shortcut -.. index:: area A.B.C.D shortcut -.. clicmd:: no area A.B.C.D shortcut -.. index:: area (0-4294967295) shortcut -.. clicmd:: no area (0-4294967295) shortcut Configure the area as Shortcut capable. See :rfc:`3509`. This requires that the 'abr-type' be set to 'shortcut'. -.. index:: area A.B.C.D stub .. clicmd:: area A.B.C.D stub -.. index:: area (0-4294967295) stub .. clicmd:: area (0-4294967295) stub -.. index:: area A.B.C.D stub -.. clicmd:: no area A.B.C.D stub -.. index:: area (0-4294967295) stub -.. clicmd:: no area (0-4294967295) stub Configure the area to be a stub area. That is, an area where no router originates routes external to OSPF and hence an area where all external @@ -451,40 +381,25 @@ Areas area. They need only pass Network-Summary (type-3) LSAs into such an area, along with a default-route summary. -.. index:: area A.B.C.D stub no-summary .. clicmd:: area A.B.C.D stub no-summary -.. index:: area (0-4294967295) stub no-summary .. clicmd:: area (0-4294967295) stub no-summary -.. index:: area A.B.C.D stub no-summary -.. clicmd:: no area A.B.C.D stub no-summary -.. index:: area (0-4294967295) stub no-summary -.. clicmd:: no area (0-4294967295) stub no-summary Prevents an *ospfd* ABR from injecting inter-area summaries into the specified stub area. -.. index:: area A.B.C.D default-cost (0-16777215) .. clicmd:: area A.B.C.D default-cost (0-16777215) -.. index:: area A.B.C.D default-cost (0-16777215) -.. clicmd:: no area A.B.C.D default-cost (0-16777215) Set the cost of default-summary LSAs announced to stubby areas. -.. index:: area A.B.C.D export-list NAME .. clicmd:: area A.B.C.D export-list NAME -.. index:: area (0-4294967295) export-list NAME .. clicmd:: area (0-4294967295) export-list NAME -.. index:: area A.B.C.D export-list NAME -.. clicmd:: no area A.B.C.D export-list NAME -.. index:: area (0-4294967295) export-list NAME -.. clicmd:: no area (0-4294967295) export-list NAME Filter Type-3 summary-LSAs announced to other areas originated from intra- area paths from specified area. @@ -507,67 +422,41 @@ Areas This command is only relevant if the router is an ABR for the specified area. -.. index:: area A.B.C.D import-list NAME .. clicmd:: area A.B.C.D import-list NAME -.. index:: area (0-4294967295) import-list NAME .. clicmd:: area (0-4294967295) import-list NAME -.. index:: area A.B.C.D import-list NAME -.. clicmd:: no area A.B.C.D import-list NAME -.. index:: area (0-4294967295) import-list NAME -.. clicmd:: no area (0-4294967295) import-list NAME Same as export-list, but it applies to paths announced into specified area as Type-3 summary-LSAs. -.. index:: area A.B.C.D filter-list prefix NAME in .. clicmd:: area A.B.C.D filter-list prefix NAME in -.. index:: area A.B.C.D filter-list prefix NAME out .. clicmd:: area A.B.C.D filter-list prefix NAME out -.. index:: area (0-4294967295) filter-list prefix NAME in .. clicmd:: area (0-4294967295) filter-list prefix NAME in -.. index:: area (0-4294967295) filter-list prefix NAME out .. clicmd:: area (0-4294967295) filter-list prefix NAME out -.. index:: area A.B.C.D filter-list prefix NAME in -.. clicmd:: no area A.B.C.D filter-list prefix NAME in -.. index:: area A.B.C.D filter-list prefix NAME out -.. clicmd:: no area A.B.C.D filter-list prefix NAME out -.. index:: area (0-4294967295) filter-list prefix NAME in -.. clicmd:: no area (0-4294967295) filter-list prefix NAME in -.. index:: area (0-4294967295) filter-list prefix NAME out -.. clicmd:: no area (0-4294967295) filter-list prefix NAME out Filtering Type-3 summary-LSAs to/from area using prefix lists. This command makes sense in ABR only. -.. index:: area A.B.C.D authentication .. clicmd:: area A.B.C.D authentication -.. index:: area (0-4294967295) authentication .. clicmd:: area (0-4294967295) authentication -.. index:: area A.B.C.D authentication -.. clicmd:: no area A.B.C.D authentication -.. index:: area (0-4294967295) authentication -.. clicmd:: no area (0-4294967295) authentication Specify that simple password authentication should be used for the given area. -.. index:: area A.B.C.D authentication message-digest .. clicmd:: area A.B.C.D authentication message-digest -.. index:: area (0-4294967295) authentication message-digest .. clicmd:: area (0-4294967295) authentication message-digest Specify that OSPF packets must be authenticated with MD5 HMACs within the @@ -583,11 +472,8 @@ Areas Interfaces ---------- -.. index:: ip ospf area AREA [ADDR] .. clicmd:: ip ospf area AREA [ADDR] -.. index:: ip ospf area [ADDR] -.. clicmd:: no ip ospf area [ADDR] Enable OSPF on the interface, optionally restricted to just the IP address given by `ADDR`, putting it in the `AREA` area. Per interface area settings @@ -597,11 +483,8 @@ Interfaces If you have a lot of interfaces, and/or a lot of subnets, then enabling OSPF via this command may result in a slight performance improvement. -.. index:: ip ospf authentication-key AUTH_KEY .. clicmd:: ip ospf authentication-key AUTH_KEY -.. index:: ip ospf authentication-key -.. clicmd:: no ip ospf authentication-key Set OSPF authentication key to a simple password. After setting `AUTH_KEY`, all OSPF packets are authenticated. `AUTH_KEY` has length up to 8 chars. @@ -609,7 +492,6 @@ Interfaces Simple text password authentication is insecure and deprecated in favour of MD5 HMAC authentication. -.. index:: ip ospf authentication message-digest .. clicmd:: ip ospf authentication message-digest Specify that MD5 HMAC authentication must be used on this interface. MD5 @@ -626,11 +508,8 @@ Interfaces non-volatile storage and restored at boot if MD5 authentication is to be expected to work reliably. -.. index:: ip ospf message-digest-key KEYID md5 KEY .. clicmd:: ip ospf message-digest-key KEYID md5 KEY -.. index:: ip ospf message-digest-key -.. clicmd:: no ip ospf message-digest-key Set OSPF authentication key to a cryptographic password. The cryptographic algorithm is MD5. @@ -641,23 +520,16 @@ Interfaces KEY is the actual message digest key, of up to 16 chars (larger strings will be truncated), and is associated with the given KEYID. -.. index:: ip ospf cost (1-65535) .. clicmd:: ip ospf cost (1-65535) -.. index:: ip ospf cost -.. clicmd:: no ip ospf cost Set link cost for the specified interface. The cost value is set to router-LSA's metric field and used for SPF calculation. -.. index:: ip ospf dead-interval (1-65535) .. clicmd:: ip ospf dead-interval (1-65535) -.. index:: ip ospf dead-interval minimal hello-multiplier (2-20) .. clicmd:: ip ospf dead-interval minimal hello-multiplier (2-20) -.. index:: ip ospf dead-interval -.. clicmd:: no ip ospf dead-interval Set number of seconds for RouterDeadInterval timer value used for Wait Timer and Inactivity Timer. This value must be the same for all routers attached @@ -672,11 +544,8 @@ Interfaces hello-multiplier need NOT be the same across multiple routers on a common link. -.. index:: ip ospf hello-interval (1-65535) .. clicmd:: ip ospf hello-interval (1-65535) -.. index:: ip ospf hello-interval -.. clicmd:: no ip ospf hello-interval Set number of seconds for HelloInterval timer value. Setting this value, Hello packet will be sent every timer value seconds on the specified interface. @@ -687,7 +556,6 @@ Interfaces :clicmd:`ip ospf dead-interval minimal hello-multiplier (2-20)` is also specified for the interface. -.. index:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point) .. clicmd:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point) When configuring a point-to-point network on an interface and the interface @@ -696,45 +564,31 @@ Interfaces net.ipv4.conf.<interface name>.rp_filter value to 0. In order for the ospf multicast packets to be delivered by the kernel. -.. index:: ip ospf network -.. clicmd:: no ip ospf network Set explicitly network type for specified interface. -.. index:: ip ospf priority (0-255) .. clicmd:: ip ospf priority (0-255) -.. index:: ip ospf priority -.. clicmd:: no ip ospf priority Set RouterPriority integer value. The router with the highest priority will be more eligible to become Designated Router. Setting the value to 0, makes the router ineligible to become Designated Router. The default value is 1. -.. index:: ip ospf retransmit-interval (1-65535) .. clicmd:: ip ospf retransmit-interval (1-65535) -.. index:: ip ospf retransmit interval -.. clicmd:: no ip ospf retransmit interval Set number of seconds for RxmtInterval timer value. This value is used when retransmitting Database Description and Link State Request packets. The default value is 5 seconds. -.. index:: ip ospf transmit-delay (1-65535) [A.B.C.D] .. clicmd:: ip ospf transmit-delay (1-65535) [A.B.C.D] -.. index:: ip ospf transmit-delay [(1-65535)] [A.B.C.D] -.. clicmd:: no ip ospf transmit-delay [(1-65535)] [A.B.C.D] Set number of seconds for InfTransDelay value. LSAs' age should be incremented by this value when transmitting. The default value is 1 second. -.. index:: ip ospf area (A.B.C.D|(0-4294967295)) .. clicmd:: ip ospf area (A.B.C.D|(0-4294967295)) -.. index:: ip ospf area -.. clicmd:: no ip ospf area Enable ospf on an interface and set associated area. @@ -743,7 +597,6 @@ OSPF route-map Usage of *ospfd*'s route-map support. -.. index:: set metric [+|-](0-4294967295) .. clicmd:: set metric [+|-](0-4294967295) Set a metric for matched route when sending announcement. Use plus (+) sign @@ -755,35 +608,10 @@ Usage of *ospfd*'s route-map support. Redistribution -------------- -.. index:: redistribute (kernel|connected|static|rip|bgp) -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) - -.. index:: redistribute (kernel|connected|static|rip|bgp) ROUTE-MAP -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) ROUTE-MAP - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) route-map WORD -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) route-map WORD - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric (0-16777214) -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric (0-16777214) - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric (0-16777214) route-map WORD -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric (0-16777214) route-map WORD - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric (0-16777214) -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric (0-16777214) - -.. index:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric (0-16777214) route-map WORD -.. clicmd:: redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric (0-16777214) route-map WORD - -.. index:: redistribute (kernel|connected|static|rip|bgp) -.. clicmd:: no redistribute (kernel|connected|static|rip|bgp) - .. _ospf-redistribute: +.. clicmd:: redistribute <babel|bgp|connected|eigrp|isis|kernel|openfabric|ospf|rip|sharp|static|table> [metric-type (1-2)] [metric (0-16777214)] [route-map WORD] + Redistribute routes of the specified protocol or kind into OSPF, with the metric type and metric set if specified, filtering the routes using the given route-map if specified. Redistributed routes may also be filtered @@ -802,43 +630,30 @@ Redistribution clicmd:`passive-interface INTERFACE`. -.. index:: default-information originate .. clicmd:: default-information originate -.. index:: default-information originate metric (0-16777214) .. clicmd:: default-information originate metric (0-16777214) -.. index:: default-information originate metric (0-16777214) metric-type (1|2) .. clicmd:: default-information originate metric (0-16777214) metric-type (1|2) -.. index:: default-information originate metric (0-16777214) metric-type (1|2) route-map WORD .. clicmd:: default-information originate metric (0-16777214) metric-type (1|2) route-map WORD -.. index:: default-information originate always .. clicmd:: default-information originate always -.. index:: default-information originate always metric (0-16777214) .. clicmd:: default-information originate always metric (0-16777214) -.. index:: default-information originate always metric (0-16777214) metric-type (1|2) .. clicmd:: default-information originate always metric (0-16777214) metric-type (1|2) -.. index:: default-information originate always metric (0-16777214) metric-type (1|2) route-map WORD .. clicmd:: default-information originate always metric (0-16777214) metric-type (1|2) route-map WORD -.. index:: default-information originate -.. clicmd:: no default-information originate Originate an AS-External (type-5) LSA describing a default route into all external-routing capable areas, of the specified metric and metric type. If the 'always' keyword is given then the default is always advertised, even when there is no default present in the routing table. -.. index:: distribute-list NAME out (kernel|connected|static|rip|ospf .. clicmd:: distribute-list NAME out (kernel|connected|static|rip|ospf -.. index:: distribute-list NAME out (kernel|connected|static|rip|ospf -.. clicmd:: no distribute-list NAME out (kernel|connected|static|rip|ospf .. _ospf-distribute-list: @@ -846,38 +661,21 @@ Redistribution type before allowing the routes to redistributed into OSPF (:ref:`ospf redistribution <ospf-redistribute>`). -.. index:: default-metric (0-16777214) .. clicmd:: default-metric (0-16777214) -.. index:: default-metric -.. clicmd:: no default-metric -.. index:: distance (1-255) .. clicmd:: distance (1-255) -.. index:: distance (1-255) -.. clicmd:: no distance (1-255) -.. index:: distance ospf (intra-area|inter-area|external) (1-255) .. clicmd:: distance ospf (intra-area|inter-area|external) (1-255) -.. index:: distance ospf -.. clicmd:: no distance ospf - -.. index:: router zebra -.. clicmd:: router zebra -.. index:: router zebra -.. clicmd:: no router zebra Graceful Restart Helper ======================= -.. index:: graceful-restart helper-only [A.B.C.D] .. clicmd:: graceful-restart helper-only [A.B.C.D] -.. index:: graceful-restart helper-only [A.B.C.D] -.. clicmd:: no graceful-restart helper-only [A.B.C.D] Configure Graceful Restart (RFC 3623) helper support. By default, helper support is disabled for all neighbours. @@ -886,30 +684,21 @@ Graceful Restart Helper To enable/disable helper support for a specific neighbour, the router-id (A.B.C.D) has to be specified. -.. index:: graceful-restart helper strict-lsa-checking .. clicmd:: graceful-restart helper strict-lsa-checking -.. index:: graceful-restart helper strict-lsa-checking -.. clicmd:: no graceful-restart helper strict-lsa-checking If 'strict-lsa-checking' is configured then the helper will abort the Graceful Restart when a LSA change occurs which affects the restarting router. By default 'strict-lsa-checking' is enabled" -.. index:: graceful-restart helper supported-grace-time .. clicmd:: graceful-restart helper supported-grace-time -.. index:: graceful-restart helper supported-grace-time -.. clicmd:: no graceful-restart helper supported-grace-time Supports as HELPER for configured grace period. -.. index:: graceful-restart helper planned-only .. clicmd:: graceful-restart helper planned-only -.. index:: graceful-restart helper planned-only -.. clicmd:: no graceful-restart helper planned-only It helps to support as HELPER only for planned restarts. By default, it supports both planned and @@ -922,68 +711,51 @@ Showing Information .. _show-ip-ospf: -.. index:: show ip ospf [json] .. clicmd:: show ip ospf [json] Show information on a variety of general OSPF and area state and configuration information. -.. index:: show ip ospf interface [INTERFACE] [json] .. clicmd:: show ip ospf interface [INTERFACE] [json] Show state and configuration of OSPF the specified interface, or all interfaces if no interface is given. -.. index:: show ip ospf neighbor [json] .. clicmd:: show ip ospf neighbor [json] -.. index:: show ip ospf neighbor INTERFACE [json] .. clicmd:: show ip ospf neighbor INTERFACE [json] -.. index:: show ip ospf neighbor detail [json] .. clicmd:: show ip ospf neighbor detail [json] -.. index:: show ip ospf neighbor INTERFACE detail [json] .. clicmd:: show ip ospf neighbor INTERFACE detail [json] Display lsa information of LSDB. Json o/p of this command covers base route information i.e all LSAs except opaque lsa info. -.. index:: show ip ospf database [json] .. clicmd:: show ip ospf database [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] .. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] -.. index:: show ip ospf database max-age [json] .. clicmd:: show ip ospf database max-age [json] -.. index:: show ip ospf database self-originate [json] .. clicmd:: show ip ospf database self-originate [json] -.. index:: show ip ospf route [json] .. clicmd:: show ip ospf route [json] Show the OSPF routing table, as determined by the most recent SPF calculation. -.. index:: show ip ospf graceful-restart helper [detail] [json] .. clicmd:: show ip ospf graceful-restart helper [detail] [json] Displays the Grcaeful Restart Helper details including helper @@ -994,17 +766,11 @@ Showing Information Opaque LSA ========== -.. index:: ospf opaque-lsa .. clicmd:: ospf opaque-lsa -.. index:: capability opaque .. clicmd:: capability opaque -.. index:: ospf opaque-lsa -.. clicmd:: no ospf opaque-lsa -.. index:: capability opaque -.. clicmd:: no capability opaque *ospfd* supports Opaque LSA (:rfc:`2370`) as partial support for MPLS Traffic Engineering LSAs. The opaque-lsa capability must be @@ -1014,22 +780,16 @@ Opaque LSA extensions that are used with MPLS-TE; it does not support a complete RSVP-TE solution. -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID adv-router ADV-ROUTER .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID adv-router ADV-ROUTER -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) adv-router ADV-ROUTER .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) adv-router ADV-ROUTER -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID self-originate .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID self-originate -.. index:: show ip ospf database (opaque-link|opaque-area|opaque-external) self-originate .. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) self-originate Show Opaque LSA from the database. @@ -1045,40 +805,30 @@ Traffic Engineering protocol extensions that can be used with MPLS-TE. FRR does not support a complete RSVP-TE solution currently. -.. index:: mpls-te on .. clicmd:: mpls-te on -.. index:: mpls-te -.. clicmd:: no mpls-te Enable Traffic Engineering LSA flooding. -.. index:: mpls-te router-address <A.B.C.D> .. clicmd:: mpls-te router-address <A.B.C.D> Configure stable IP address for MPLS-TE. This IP address is then advertise in Opaque LSA Type-10 TLV=1 (TE) option 1 (Router-Address). -.. index:: mpls-te inter-as area <area-id>|as .. clicmd:: mpls-te inter-as area <area-id>|as -.. index:: mpls-te inter-as -.. clicmd:: no mpls-te inter-as Enable :rfc:`5392` support - Inter-AS TE v2 - to flood Traffic Engineering parameters of Inter-AS link. 2 modes are supported: AREA and AS; LSA are flood in AREA <area-id> with Opaque Type-10, respectively in AS with Opaque Type-11. In all case, Opaque-LSA TLV=6. -.. index:: show ip ospf mpls-te interface .. clicmd:: show ip ospf mpls-te interface -.. index:: show ip ospf mpls-te interface INTERFACE .. clicmd:: show ip ospf mpls-te interface INTERFACE Show MPLS Traffic Engineering parameters for all or specified interface. -.. index:: show ip ospf mpls-te router .. clicmd:: show ip ospf mpls-te router Show Traffic Engineering router parameters. @@ -1088,11 +838,8 @@ Traffic Engineering Router Information ================== -.. index:: router-info [as | area] .. clicmd:: router-info [as | area] -.. index:: router-info -.. clicmd:: no router-info Enable Router Information (:rfc:`4970`) LSA advertisement with AS scope (default) or Area scope flooding when area is specified. Old syntax @@ -1100,35 +847,20 @@ Router Information as the area ID is no more necessary. Indeed, router information support multi-area and detect automatically the areas. -.. index:: pce address <A.B.C.D> .. clicmd:: pce address <A.B.C.D> -.. index:: pce address -.. clicmd:: no pce address -.. index:: pce domain as (0-65535) .. clicmd:: pce domain as (0-65535) -.. index:: pce domain as (0-65535) -.. clicmd:: no pce domain as (0-65535) -.. index:: pce neighbor as (0-65535) .. clicmd:: pce neighbor as (0-65535) -.. index:: pce neighbor as (0-65535) -.. clicmd:: no pce neighbor as (0-65535) -.. index:: pce flag BITPATTERN .. clicmd:: pce flag BITPATTERN -.. index:: pce flag -.. clicmd:: no pce flag -.. index:: pce scope BITPATTERN .. clicmd:: pce scope BITPATTERN -.. index:: pce scope -.. clicmd:: no pce scope The commands are conform to :rfc:`5088` and allow OSPF router announce Path Computation Element (PCE) capabilities through the Router Information (RI) @@ -1138,12 +870,10 @@ Router Information refer to :rfc`5088` for the BITPATTERN recognition. Multiple 'pce neighbor' command could be specified in order to specify all PCE neighbours. -.. index:: show ip ospf router-info .. clicmd:: show ip ospf router-info Show Router Capabilities flag. -.. index:: show ip ospf router-info pce .. clicmd:: show ip ospf router-info pce Show Router Capabilities PCE parameters. @@ -1156,42 +886,35 @@ Segment Routing This is an EXPERIMENTAL support of Segment Routing as per `RFC 8665` for MPLS dataplane. -.. index:: segment-routing on -.. clicmd:: [no] segment-routing on +.. clicmd:: segment-routing on Enable Segment Routing. Even if this also activate routing information support, it is preferable to also activate routing information, and set accordingly the Area or AS flooding. -.. index:: segment-routing global-block (0-1048575) (0-1048575) -.. clicmd:: [no] segment-routing global-block (0-1048575) (0-1048575) +.. clicmd:: segment-routing global-block (0-1048575) (0-1048575) Fix the Segment Routing Global Block i.e. the label range used by MPLS to store label in the MPLS FIB for Prefix SID. -.. index:: segment-routing local-block (0-1048575) (0-1048575) -.. clicmd:: [no] segment-routing local-block (0-1048575) (0-1048575) +.. clicmd:: segment-routing local-block (0-1048575) (0-1048575) Fix the Segment Routing Local Block i.e. the label range used by MPLS to store label in the MPLS FIB for Adjacency SID. -.. index:: segment-routing node-msd (1-16) -.. clicmd:: [no] segment-routing node-msd (1-16) +.. clicmd:: segment-routing node-msd (1-16) Fix the Maximum Stack Depth supported by the router. The value depend of the MPLS dataplane. E.g. for Linux kernel, since version 4.13 it is 32. -.. index:: segment-routing prefix A.B.C.D/M index (0-65535) [no-php-flag|explicit-null] -.. clicmd:: [no] segment-routing prefix A.B.C.D/M [index (0-65535)|no-php-flag|explicit-null] +.. clicmd:: segment-routing prefix A.B.C.D/M [index (0-65535)|no-php-flag|explicit-null] - Set the Segment Routing index for the specified prefix. Note that, only prefix with /32 corresponding to a loopback interface are currently supported. The 'no-php-flag' means NO Penultimate Hop Popping that allows SR node to request to its neighbor to not pop the label. The 'explicit-null' means that neighbor nodes must swap the incoming label by the MPLS Explicit Null label before delivering the packet. -.. index:: show ip ospf database segment-routing <adv-router ADVROUTER|self-originate> [json] .. clicmd:: show ip ospf database segment-routing <adv-router ADVROUTER|self-originate> [json] Show Segment Routing Data Base, all SR nodes, specific advertised router or @@ -1203,31 +926,25 @@ External Route Summarisation This feature summarises originated external LSAs(Type-5 and Type-7). Summary Route will be originated on-behalf of all matched external LSAs. -.. index:: summary-address A.B.C.D/M [tag (1-4294967295)] -.. clicmd:: [no] summary-address A.B.C.D/M [tag (1-4294967295)] +.. clicmd:: summary-address A.B.C.D/M [tag (1-4294967295)] This command enable/disables summarisation for the configured address range. Tag is the optional parameter. If tag configured Summary route will be originated with the configured tag. -.. index:: summary-address A.B.C.D/M no-advertise -.. clicmd:: [no] summary-address A.B.C.D/M no-advertise +.. clicmd:: summary-address A.B.C.D/M no-advertise This command to ensure not advertise the summary lsa for the matched external LSAs. -.. index:: aggregation timer (5-1800) .. clicmd:: aggregation timer (5-1800) Configure aggregation delay timer interval. Summarisation starts only after this delay timer expiry. By default, delay interval is 5 secs. -.. index:: aggregation timer -.. clicmd:: no aggregation timer Resetting the aggregation delay interval to default value. -.. index:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json] .. clicmd:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json] Show configuration for display all configured summary routes with @@ -1240,7 +957,6 @@ Experimental support for Topology Independent LFA (Loop-Free Alternate), see for example 'draft-bashandy-rtgwg-segment-routing-ti-lfa-05'. Note that TI-LFA requires a proper Segment Routing configuration. -.. index:: fast-reroute ti-lfa [node-protection] .. clicmd:: fast-reroute ti-lfa [node-protection] Configured on the router level. Activates TI-LFA for all interfaces. @@ -1250,107 +966,66 @@ TI-LFA requires a proper Segment Routing configuration. Debugging OSPF ============== -.. index:: debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail] .. clicmd:: debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail] -.. index:: debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail] -.. clicmd:: no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail] Dump Packet for debugging -.. index:: debug ospf ism .. clicmd:: debug ospf ism -.. index:: debug ospf ism (status|events|timers) .. clicmd:: debug ospf ism (status|events|timers) -.. index:: debug ospf ism -.. clicmd:: no debug ospf ism -.. index:: debug ospf ism (status|events|timers) -.. clicmd:: no debug ospf ism (status|events|timers) Show debug information of Interface State Machine -.. index:: debug ospf nsm .. clicmd:: debug ospf nsm -.. index:: debug ospf nsm (status|events|timers) .. clicmd:: debug ospf nsm (status|events|timers) -.. index:: debug ospf nsm -.. clicmd:: no debug ospf nsm -.. index:: debug ospf nsm (status|events|timers) -.. clicmd:: no debug ospf nsm (status|events|timers) Show debug information of Network State Machine -.. index:: debug ospf event .. clicmd:: debug ospf event -.. index:: debug ospf event -.. clicmd:: no debug ospf event Show debug information of OSPF event -.. index:: debug ospf nssa .. clicmd:: debug ospf nssa -.. index:: debug ospf nssa -.. clicmd:: no debug ospf nssa Show debug information about Not So Stub Area -.. index:: debug ospf lsa .. clicmd:: debug ospf lsa -.. index:: debug ospf lsa (generate|flooding|refresh) .. clicmd:: debug ospf lsa (generate|flooding|refresh) -.. index:: debug ospf lsa -.. clicmd:: no debug ospf lsa -.. index:: debug ospf lsa (generate|flooding|refresh) -.. clicmd:: no debug ospf lsa (generate|flooding|refresh) Show debug detail of Link State messages -.. index:: debug ospf te .. clicmd:: debug ospf te -.. index:: debug ospf te -.. clicmd:: no debug ospf te Show debug information about Traffic Engineering LSA -.. index:: debug ospf zebra .. clicmd:: debug ospf zebra -.. index:: debug ospf zebra (interface|redistribute) .. clicmd:: debug ospf zebra (interface|redistribute) -.. index:: debug ospf zebra -.. clicmd:: no debug ospf zebra -.. index:: debug ospf zebra (interface|redistribute) -.. clicmd:: no debug ospf zebra (interface|redistribute) Show debug information of ZEBRA API -.. index:: debug ospf graceful-restart helper .. clicmd:: debug ospf graceful-restart helper -.. index:: debug ospf graceful-restart helper -.. clicmd:: no debug ospf graceful-restart helper Enable/disable debug information for OSPF Graceful Restart Helper -.. index:: show debugging ospf .. clicmd:: show debugging ospf -.. index:: debug ospf lsa aggregate -.. clicmd:: [no] debug ospf lsa aggregate +.. clicmd:: debug ospf lsa aggregate Debug commnd to enable/disable external route summarisation specific debugs. diff --git a/doc/user/overview.rst b/doc/user/overview.rst index f67698e404..5db2adef68 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -62,9 +62,8 @@ Feature support varies by platform; see the :ref:`feature-matrix`. System Architecture ------------------- -.. index:: System architecture -.. index:: Software architecture -.. index:: Software internals +.. index:: + pair: architecture; FRR Traditional routing software is made as a one process program which provides all of the routing protocol functionalities. FRR takes a different approach. @@ -114,15 +113,15 @@ data models. When this work is completed, FRR will be a fully programmable routing stack. +.. index:: + pair: platforms; FRR + pair: operating systems; FRR + .. _supported-platforms: Supported Platforms ------------------- -.. index:: Supported platforms -.. index:: FRR on other systems -.. index:: Compatibility with other systems -.. index:: Operating systems that support FRR Currently FRR supports GNU/Linux and BSD. Porting FRR to other platforms is not too difficult as platform dependent code should be mostly limited to the @@ -149,11 +148,9 @@ Recent versions of the following compilers are well tested: .. _unsupported-platforms: -UnSupported Platforms +Unsupported Platforms --------------------- -.. index:: UnSupported platforms - In General if the platform you are attempting to use is not listed above then FRR does not support being run on that platform. The only caveat here is that version 7.5 and before Solaris was supported in a limited fashion. @@ -264,6 +261,10 @@ Known Kernel Issues especially becomes apparent if the route is being transformed from one ECMP path to another. + +.. index:: + pair: rfcs; FRR + .. _supported-rfcs: Supported RFCs @@ -439,13 +440,14 @@ SNMP - :rfc:`2741` :t:`Agent Extensibility (AgentX) Protocol. M. Daniele, B. Wijnen. January 2000.` -Mailing Lists -============= -.. index:: How to get in touch with FRR -.. index:: Contact information -.. index:: Mailing lists +.. index:: + pair: mailing lists; contact +.. _mailing-lists: + +Mailing Lists +============= Italicized lists are private. @@ -471,6 +473,7 @@ results of such discussions are reflected in updates, as appropriate, to code changes, updates to the Development list and either this file or information posted at `FRR`_. + Bug Reports =========== diff --git a/doc/user/pathd.rst b/doc/user/pathd.rst index 0815a6c414..fe50a5e7eb 100644 --- a/doc/user/pathd.rst +++ b/doc/user/pathd.rst @@ -105,72 +105,59 @@ Example: Configuration Commands ---------------------- -.. index:: segment-routing .. clicmd:: segment-routing Configure segment routing. -.. index:: traffic-eng .. clicmd:: traffic-eng Configure segment routing traffic engineering. -.. index:: segment-list NAME -.. clicmd:: [no] segment-list NAME +.. clicmd:: segment-list NAME Delete or start a segment list definition. - -.. index:: index INDEX mpls label LABEL [nai node ADDRESS] -.. clicmd:: [no] index INDEX mpls label LABEL [nai node ADDRESS] +.. clicmd:: index INDEX mpls label LABEL [nai node ADDRESS] Delete or specify a segment in a segment list definition. -.. index:: policy color COLOR endpoint ENDPOINT -.. clicmd:: [no] policy color COLOR endpoint ENDPOINT +.. clicmd:: policy color COLOR endpoint ENDPOINT Delete or start a policy definition. -.. index:: name NAME .. clicmd:: name NAME Specify the policy name. -.. index:: binding-sid LABEL .. clicmd:: binding-sid LABEL Specify the policy SID. -.. index:: candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME -.. clicmd:: [no] candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME +.. clicmd:: candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME Delete or define an explicit candidate path. -.. index:: candidate-path preference PREFERENCE name NAME dynamic -.. clicmd:: [no] candidate-path preference PREFERENCE name NAME dynamic +.. clicmd:: candidate-path preference PREFERENCE name NAME dynamic Delete or start a dynamic candidate path definition. -.. index:: affinity {exclude-any|include-any|include-all} BITPATTERN -.. clicmd:: [no] affinity {exclude-any|include-any|include-all} BITPATTERN +.. clicmd:: affinity {exclude-any|include-any|include-all} BITPATTERN Delete or specify an affinity constraint for a dynamic candidate path. -.. index:: bandwidth BANDWIDTH [required] -.. clicmd:: [no] bandwidth BANDWIDTH [required] +.. clicmd:: bandwidth BANDWIDTH [required] Delete or specify a bandwidth constraint for a dynamic candidate path. -.. index:: metric [bound] METRIC VALUE [required] -.. clicmd:: [no] metric [bound] METRIC VALUE [required] +.. clicmd:: metric [bound] METRIC VALUE [required] Delete or specify a metric constraint for a dynamic candidate path. @@ -198,8 +185,7 @@ Configuration Commands - bnc: Border Node Count metric -.. index:: objective-function OBJFUN1 [required] -.. clicmd:: [no] objective-function OBJFUN1 [required] +.. clicmd:: objective-function OBJFUN1 [required] Delete or specify a PCEP objective function constraint for a dynamic candidate path. @@ -224,8 +210,7 @@ Configuration Commands - msn: Minimize the number of Shared Nodes [RFC8800] -.. index:: debug pathd pcep [basic|path|message|pceplib] -.. clicmd:: [no] debug pathd pcep [basic|path|message|pceplib] +.. clicmd:: debug pathd pcep [basic|path|message|pceplib] Enable or disable debugging for the pcep module: @@ -235,33 +220,28 @@ Configuration Commands - pceplib: Enable pceplib logging -.. index:: pcep .. clicmd:: pcep Configure PCEP support. -.. index:: cep-config NAME -.. clicmd:: [no] pce-config NAME +.. clicmd:: pce-config NAME Define a shared PCE configuration that can be used in multiple PCE declarations. -.. index:: pce NAME -.. clicmd:: [no] pce NAME +.. clicmd:: pce NAME Define or delete a PCE definition. -.. index:: config WORD .. clicmd:: config WORD Select a shared configuration. If not defined, the default configuration will be used. -.. index:: address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)] .. clicmd:: address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)] Define the address and port of the PCE. @@ -271,7 +251,6 @@ Configuration Commands This should be specified in the PCC peer definition. -.. index:: source-address [ip A.B.C.D | ipv6 X:X::X:X] [port PORT] .. clicmd:: source-address [ip A.B.C.D | ipv6 X:X::X:X] [port PORT] Define the address and/or port of the PCC as seen by the PCE. @@ -284,7 +263,6 @@ Configuration Commands configuration group. -.. index:: tcp-md5-auth WORD .. clicmd:: tcp-md5-auth WORD Enable TCP MD5 security with the given secret. @@ -293,7 +271,6 @@ Configuration Commands configuration group. -.. index:: sr-draft07 .. clicmd:: sr-draft07 Specify if a PCE only support segment routing draft 7, this flag will limit @@ -303,7 +280,6 @@ Configuration Commands configuration group. -.. index:: pce-initiated .. clicmd:: pce-initiated Specify if PCE-initiated LSP should be allowed for this PCE. @@ -312,7 +288,6 @@ Configuration Commands configuration group. -.. index:: timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] [dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] [pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)] .. clicmd:: timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] [dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] [pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)] Specify the PCEP timers. @@ -321,20 +296,17 @@ Configuration Commands configuration group. -.. index:: pcc -.. clicmd:: [no] pcc +.. clicmd:: pcc Disable or start the definition of a PCC. -.. index:: msd (1-32) .. clicmd:: msd (1-32) Specify the maximum SID depth in a PCC definition. -.. index:: peer WORD [precedence (1-255)] -.. clicmd:: [no] peer WORD [precedence (1-255)] +.. clicmd:: peer WORD [precedence (1-255)] Specify a peer and its precedence in a PCC definition. @@ -342,7 +314,6 @@ Configuration Commands Introspection Commands ---------------------- -.. index:: show sr-te policy [detail] .. clicmd:: show sr-te policy [detail] Display the segment routing policies. @@ -368,38 +339,22 @@ The asterisk (*) marks the best, e.g. active, candidate path. Note that for segm retrieved via PCEP a random number based name is generated. -.. index:: show debugging pathd -.. clicmd:: show debugging pathd - - Display the current status of the pathd debugging. - - -.. index:: show debugging pathd-pcep -.. clicmd:: show debugging pathd-pcep - - Display the current status of the pcep module debugging. - - -.. index:: show sr-te pcep counters .. clicmd:: show sr-te pcep counters Display the counters from pceplib. -.. index:: show sr-te pcep pce-config [NAME] .. clicmd:: show sr-te pcep pce-config [NAME] Display a shared configuration. if no name is specified, the default configuration will be displayed. -.. index:: show sr-te pcep pcc .. clicmd:: show sr-te pcep pcc Display PCC information. -.. index:: show sr-te pcep session [NAME] .. clicmd:: show sr-te pcep session [NAME] Display the information of a PCEP session, if not name is specified all the @@ -409,7 +364,6 @@ retrieved via PCEP a random number based name is generated. Utility Commands ---------------- -.. index:: clear sr-te pcep session [NAME] .. clicmd:: clear sr-te pcep session [NAME] Reset the pcep session by disconnecting from the PCE and performing the diff --git a/doc/user/pbr.rst b/doc/user/pbr.rst index 5cec7cbe62..14a05a69d7 100644 --- a/doc/user/pbr.rst +++ b/doc/user/pbr.rst @@ -45,7 +45,7 @@ listing of ECMP nexthops used to forward packets for when a pbr-map is matched. are used to are allowed here. The syntax was intentionally kept the same as creating nexthops as you would for static routes. -.. clicmd:: [no] pbr table range (10000-4294966272) (10000-4294966272) +.. clicmd:: pbr table range (10000-4294966272) (10000-4294966272) Set or unset the range used to assign numeric table ID's to new nexthop-group tables. Existing tables will not be modified to fit in this @@ -220,6 +220,10 @@ end destination. | installedInternally | Do we think this group is installed? | Integer | +---------------------+--------------------------------------+---------+ + +.. index:: + pair: policy; PBR + .. _pbr-policy: PBR Policy @@ -229,7 +233,6 @@ After you have specified a PBR map, in order for it to be turned on, you must apply the PBR map to an interface. This policy application to an interface causes the policy to be installed into the kernel. -.. index:: pbr-policy .. clicmd:: pbr-policy NAME This command is available under interface sub-mode. This turns @@ -263,12 +266,10 @@ causes the policy to be installed into the kernel. PBR Debugs =========== -.. index:: debug pbr .. clicmd:: debug pbr events|map|nht|zebra Debug pbr in pbrd daemon. You specify what types of debugs to turn on. -.. index:: debug zebra pbr .. clicmd:: debug zebra pbr Debug pbr in zebra daemon. @@ -281,12 +282,10 @@ PBR Details Under the covers a PBR map is translated into two separate constructs in the Linux kernel. -.. index:: PBR Rules The PBR map specified creates a `ip rule ...` that is inserted into the Linux kernel that points to a table to use for forwarding once the rule matches. -.. index:: PBR Tables The creation of a nexthop or nexthop-group is translated to a default route in a table with the nexthops specified as the nexthops for the default route. diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 201fe2f9ed..86716b49a4 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -56,7 +56,6 @@ Certain signals have special meanings to *pimd*. *pimd* invocation options. Common options that can be specified (:ref:`common-invocation-options`). -.. index:: ip pim rp A.B.C.D A.B.C.D/M .. clicmd:: ip pim rp A.B.C.D A.B.C.D/M In order to use pim, it is necessary to configure a RP for join messages to @@ -66,7 +65,6 @@ Certain signals have special meanings to *pimd*. prefix of group ranges covered. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim register-accept-list PLIST .. clicmd:: ip pim register-accept-list PLIST When pim receives a register packet the source of the packet will be compared @@ -74,14 +72,12 @@ Certain signals have special meanings to *pimd*. processing continues. If a deny is returned for the source address of the register packet a register stop message is sent to the source. -.. index:: ip pim spt-switchover infinity-and-beyond .. clicmd:: ip pim spt-switchover infinity-and-beyond On the last hop router if it is desired to not switch over to the SPT tree. Configure this command. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim ecmp .. clicmd:: ip pim ecmp If pim has the a choice of ECMP nexthops for a particular RPF, pim will @@ -89,7 +85,6 @@ Certain signals have special meanings to *pimd*. not specified then the first nexthop found will be used. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim ecmp rebalance .. clicmd:: ip pim ecmp rebalance If pim is using ECMP and an interface goes down, cause pim to rebalance all @@ -98,14 +93,12 @@ Certain signals have special meanings to *pimd*. down. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim join-prune-interval (60-600) .. clicmd:: ip pim join-prune-interval (60-600) Modify the join/prune interval that pim uses to the new value. Time is specified in seconds. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim keep-alive-timer (31-60000) .. clicmd:: ip pim keep-alive-timer (31-60000) Modify the time out value for a S,G flow from 31-60000 seconds. 31 seconds @@ -113,7 +106,6 @@ Certain signals have special meanings to *pimd*. flowing in better than 30 second chunks. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim packets (1-100) .. clicmd:: ip pim packets (1-100) When processing packets from a neighbor process the number of packets @@ -122,14 +114,12 @@ Certain signals have special meanings to *pimd*. a large number of pim control packets flowing. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim register-suppress-time (5-60000) .. clicmd:: ip pim register-suppress-time (5-60000) Modify the time that pim will register suppress a FHR will send register notifications to the kernel. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim send-v6-secondary .. clicmd:: ip pim send-v6-secondary When sending pim hello packets tell pim to send any v6 secondary addresses @@ -137,14 +127,12 @@ Certain signals have special meanings to *pimd*. in it's decision for RPF lookup. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip pim ssm prefix-list WORD .. clicmd:: ip pim ssm prefix-list WORD Specify a range of group addresses via a prefix-list that forces pim to never do SM over. This command is vrf aware, to configure for a vrf, enter the vrf submode. -.. index:: ip multicast rpf-lookup-mode WORD .. clicmd:: ip multicast rpf-lookup-mode WORD Modify how PIM does RPF lookups in the zebra routing table. You can use @@ -166,32 +154,27 @@ Certain signals have special meanings to *pimd*. urib-only Lookup in the Unicast Rib only. -.. index:: ip msdp mesh-group [WORD] -.. clicmd:: [no] ip msdp mesh-group [WORD] +.. clicmd:: ip msdp mesh-group [WORD] Create or Delete a multicast source discovery protocol mesh-group using [WORD] as the group name. -.. index:: ip msdp mesh-group WORD member A.B.C.D -.. clicmd:: [no] ip msdp mesh-group WORD member A.B.C.D +.. clicmd:: ip msdp mesh-group WORD member A.B.C.D Attach or Delete A.B.C.D to the MSDP mesh group WORD specified. -.. index:: ip msdp mesh-group WORD source A.B.C.D -.. clicmd:: [no] ip msdp mesh-group WORD source A.B.C.D +.. clicmd:: ip msdp mesh-group WORD source A.B.C.D For the address specified A.B.C.D use that as the source address for mesh group packets being sent. -.. index:: ip igmp generate-query-once [version (2-3)] .. clicmd:: ip igmp generate-query-once [version (2-3)] Generate IGMP query (v2/v3) on user requirement. This will not depend on the existing IGMP general query timer.If no version is provided in the cli, it will be considered as default v2 query.This is a hidden command. -.. index:: ip igmp watermark-warn (10-60000) -.. clicmd:: [no] ip igmp watermark-warn (10-60000) +.. clicmd:: ip igmp watermark-warn (10-60000) Configure watermark warning generation for an igmp group limit. Generates warning once the configured group limit is reached while adding new groups. @@ -207,44 +190,33 @@ PIM interface commands allow you to configure an interface as either a Receiver or a interface that you would like to form pim neighbors on. If the interface is in a vrf, enter the interface command with the vrf keyword at the end. -.. index:: ip pim active-active .. clicmd:: ip pim active-active Turn on pim active-active configuration for a Vxlan interface. This command will not do anything if you do not have the underlying ability of a mlag implementation. -.. index:: ip pim bfd -.. clicmd:: ip pim bfd - - Turns on BFD support for PIM for this interface. - -.. index:: ip pim bsm .. clicmd:: ip pim bsm Tell pim that we would like to use this interface to process bootstrap messages. This is enabled by default. 'no' form of this command is used to restrict bsm messages on this interface. -.. index:: ip pim unicast-bsm .. clicmd:: ip pim unicast-bsm Tell pim that we would like to allow interface to process unicast bootstrap messages. This is enabled by default. 'no' form of this command is used to restrict processing of unicast bsm messages on this interface. -.. index:: ip pim drpriority (1-4294967295) .. clicmd:: ip pim drpriority (1-4294967295) Set the DR Priority for the interface. This command is useful to allow the user to influence what node becomes the DR for a lan segment. -.. index:: ip pim hello (1-180) (1-180) .. clicmd:: ip pim hello (1-180) (1-180) Set the pim hello and hold interval for a interface. -.. index:: ip pim .. clicmd:: ip pim Tell pim that we would like to use this interface to form pim neighbors @@ -252,67 +224,63 @@ is in a vrf, enter the interface command with the vrf keyword at the end. reports on the interface. Refer to the next `ip igmp` command for IGMP management. -.. index:: ip pim use-source A.B.C.D -.. clicmd:: [no] ip pim use-source A.B.C.D +.. clicmd:: ip pim use-source A.B.C.D If you have multiple addresses configured on a particular interface and would like pim to use a specific source address associated with that interface. -.. index:: ip igmp .. clicmd:: ip igmp Tell pim to receive IGMP reports and Query on this interface. The default version is v3. This command is useful on a LHR. -.. index:: ip igmp join A.B.C.D [A.B.C.D] .. clicmd:: ip igmp join A.B.C.D [A.B.C.D] Join multicast group or source-group on an interface. -.. index:: ip igmp query-interval (1-1800) .. clicmd:: ip igmp query-interval (1-1800) Set the IGMP query interval that PIM will use. -.. index:: ip igmp query-max-response-time (10-250) .. clicmd:: ip igmp query-max-response-time (10-250) Set the IGMP query response timeout value. If an report is not returned in the specified time we will assume the S,G or \*,G has timed out. -.. index:: ip igmp version (2-3) .. clicmd:: ip igmp version (2-3) Set the IGMP version used on this interface. The default value is 3. -.. index:: ip multicast boundary oil WORD .. clicmd:: ip multicast boundary oil WORD Set a pim multicast boundary, based upon the WORD prefix-list. If a pim join or IGMP report is received on this interface and the Group is denied by the prefix-list, PIM will ignore the join or report. -.. index:: ip igmp last-member-query-count (1-7) .. clicmd:: ip igmp last-member-query-count (1-7) Set the IGMP last member query count. The default value is 2. 'no' form of this command is used to to configure back to the default value. -.. index:: ip igmp last-member-query-interval (1-255) .. clicmd:: ip igmp last-member-query-interval (1-255) Set the IGMP last member query interval in deciseconds. The default value is 10 deciseconds. 'no' form of this command is used to to configure back to the default value. -.. index:: ip mroute INTERFACE A.B.C.D [A.B.C.D] .. clicmd:: ip mroute INTERFACE A.B.C.D [A.B.C.D] Set a static multicast route for a traffic coming on the current interface to be forwarded on the given interface if the traffic matches the group address and optionally the source address. + +.. seealso:: + + :ref:`bfd-pim-peer-config` + + .. _pim-multicast-rib-insertion: PIM Multicast RIB insertion: @@ -325,13 +293,11 @@ into the kernel *or* for normal rib processing. As such it is possible to create weird states with these commands. Use with caution. Most of the time this will not be necessary. -.. index:: ip mroute A.B.C.D/M A.B.C.D (1-255) .. clicmd:: ip mroute A.B.C.D/M A.B.C.D (1-255) Insert into the Multicast Rib Route A.B.C.D/M with specified nexthop. The distance can be specified as well if desired. -.. index:: ip mroute A.B.C.D/M INTERFACE (1-255) .. clicmd:: ip mroute A.B.C.D/M INTERFACE (1-255) Insert into the Multicast Rib Route A.B.C.D/M using the specified INTERFACE. @@ -342,34 +308,25 @@ caution. Most of the time this will not be necessary. Multicast Source Discovery Protocol (MSDP) Configuration ======================================================== -.. index:: ip msdp mesh-group [WORD] member A.B.C.D .. clicmd:: ip msdp mesh-group [WORD] member A.B.C.D Include a MSDP peer as a member of a MSDP mesh-group. -.. index:: ip msdp mesh-group [WORD] source A.B.C.D .. clicmd:: ip msdp mesh-group [WORD] source A.B.C.D Create a MSDP mesh-group, defining a name for it and an associated local source address. -.. index:: ip msdp peer A.B.C.D source A.B.C.D .. clicmd:: ip msdp peer A.B.C.D source A.B.C.D Establish a MSDP connection with a peer. -.. index:: ip msdp mesh-group [WORD] member A.B.C.D -.. clicmd:: no ip msdp mesh-group [WORD] member A.B.C.D Remove a MSDP peer member from a MSDP mesh-group. -.. index:: ip msdp mesh-group [WORD] source A.B.C.D -.. clicmd:: no ip msdp mesh-group [WORD] source A.B.C.D Delete a MSDP mesh-group. -.. index:: ip msdp peer A.B.C.D -.. clicmd:: no ip msdp peer A.B.C.D Delete a MSDP peer connection. @@ -384,48 +341,39 @@ vrf is specified then the default vrf is assumed. Finally the special keyword 'all' allows you to look at all vrfs for the command. Naming a vrf 'all' will cause great confusion. -.. index:: show ip igmp interface .. clicmd:: show ip igmp interface Display IGMP interface information. -.. index:: show ip igmp [vrf NAME] join [json] .. clicmd:: show ip igmp [vrf NAME] join [json] Display IGMP static join information for a specific vrf. If "vrf all" is provided, it displays information for all the vrfs present. -.. index:: show ip igmp groups .. clicmd:: show ip igmp groups Display IGMP groups information. -.. index:: show ip igmp groups retransmissions .. clicmd:: show ip igmp groups retransmissions Display IGMP group retransmission information. -.. index:: show ip igmp sources .. clicmd:: show ip igmp sources Display IGMP sources information. -.. index:: show ip igmp sources retransmissions .. clicmd:: show ip igmp sources retransmissions Display IGMP source retransmission information. -.. index:: show ip igmp statistics .. clicmd:: show ip igmp statistics Display IGMP statistics information. -.. index:: show ip multicast .. clicmd:: show ip multicast Display various information about the interfaces used in this pim instance. -.. index:: show ip mroute [vrf NAME] [A.B.C.D [A.B.C.D]] [fill] [json] .. clicmd:: show ip mroute [vrf NAME] [A.B.C.D [A.B.C.D]] [fill] [json] Display information about installed into the kernel S,G mroutes. If @@ -434,200 +382,167 @@ cause great confusion. Source Group. The keyword `fill` says to fill in all assumed data for test/data gathering purposes. -.. index:: show ip mroute [vrf NAME] count [json] .. clicmd:: show ip mroute [vrf NAME] count [json] Display information about installed into the kernel S,G mroutes and in addition display data about packet flow for the mroutes for a specific vrf. -.. index:: show ip mroute vrf all count [json] .. clicmd:: show ip mroute vrf all count [json] Display information about installed into the kernel S,G mroutes and in addition display data about packet flow for the mroutes for all vrfs. -.. index:: show ip mroute [vrf NAME] summary [json] .. clicmd:: show ip mroute [vrf NAME] summary [json] Display total number of S,G mroutes and number of S,G mroutes installed into the kernel for a specific vrf. -.. index:: show ip mroute vrf all summary [json] .. clicmd:: show ip mroute vrf all summary [json] Display total number of S,G mroutes and number of S,G mroutes installed into the kernel for all vrfs. -.. index:: show ip msdp mesh-group .. clicmd:: show ip msdp mesh-group Display the configured mesh-groups, the local address associated with each mesh-group, the peer members included in each mesh-group, and their status. -.. index:: show ip msdp peer .. clicmd:: show ip msdp peer Display information about the MSDP peers. That includes the peer address, the local address used to establish the connection to the peer, the connection status, and the number of active sources. -.. index:: show ip pim assert .. clicmd:: show ip pim assert Display information about asserts in the PIM system for S,G mroutes. -.. index:: show ip pim assert-internal .. clicmd:: show ip pim assert-internal Display internal assert state for S,G mroutes -.. index:: show ip pim assert-metric .. clicmd:: show ip pim assert-metric Display metric information about assert state for S,G mroutes -.. index:: show ip pim assert-winner-metric .. clicmd:: show ip pim assert-winner-metric Display winner metric for assert state for S,G mroutes -.. index:: show ip pim group-type .. clicmd:: show ip pim group-type Display SSM group ranges. -.. index:: show ip pim interface .. clicmd:: show ip pim interface Display information about interfaces PIM is using. -.. index:: show ip pim mlag [vrf NAME] interface [detail|WORD] [json] .. clicmd:: show ip pim mlag [vrf NAME|all] interface [detail|WORD] [json] Display mlag interface information. -.. index:: show ip pim [vrf NAME] join [A.B.C.D [A.B.C.D]] [json] .. clicmd:: show ip pim join Display information about PIM joins received. If one address is specified then we assume it is the Group we are interested in displaying data on. If the second address is specified then it is Source Group. -.. index:: show ip pim local-membership .. clicmd:: show ip pim local-membership Display information about PIM interface local-membership. -.. index:: show ip pim mlag summary [json] .. clicmd:: show ip pim mlag summary [json] Display mlag information state that PIM is keeping track of. -.. index:: show ip pim neighbor .. clicmd:: show ip pim neighbor Display information about PIM neighbors. -.. index:: show ip pim nexthop .. clicmd:: show ip pim nexthop Display information about pim nexthops that are being used. -.. index:: show ip pim nexthop-lookup .. clicmd:: show ip pim nexthop-lookup Display information about a S,G pair and how the RPF would be chosen. This is especially useful if there are ECMP's available from the RPF lookup. -.. index:: show ip pim rp-info .. clicmd:: show ip pim rp-info Display information about RP's that are configured on this router. -.. index:: show ip pim rpf .. clicmd:: show ip pim rpf Display information about currently being used S,G's and their RPF lookup information. Additionally display some statistics about what has been happening on the router. -.. index:: show ip pim secondary .. clicmd:: show ip pim secondary Display information about an interface and all the secondary addresses associated with it. -.. index:: show ip pim state .. clicmd:: show ip pim state Display information about known S,G's and incoming interface as well as the OIL and how they were chosen. -.. index:: show ip pim [vrf NAME] upstream [A.B.C.D [A.B.C.D]] [json] -.. clicmd:: show ip pim upstream +.. clicmd:: show ip pim [vrf NAME] upstream [A.B.C.D [A.B.C.D]] [json] Display upstream information about a S,G mroute. Allow the user to specify sub Source and Groups that we are only interested in. -.. index:: show ip pim upstream-join-desired .. clicmd:: show ip pim upstream-join-desired Display upstream information for S,G's and if we desire to join the multicast tree -.. index:: show ip pim upstream-rpf .. clicmd:: show ip pim upstream-rpf Display upstream information for S,G's and the RPF data associated with them. -.. index:: show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json] -.. clicmd:: show ip pim mlag upstream +.. clicmd:: show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json] Display upstream entries that are synced across MLAG switches. Allow the user to specify sub Source and Groups address filters. -.. index:: show ip pim mlag summary .. clicmd:: show ip pim mlag summary Display PIM MLAG (multi-chassis link aggregation) session status and control message statistics. -.. index:: show ip pim bsr .. clicmd:: show ip pim bsr Display current bsr, its uptime and last received bsm age. -.. index:: show ip pim bsrp-info .. clicmd:: show ip pim bsrp-info Display group-to-rp mappings received from E-BSR. -.. index:: show ip pim bsm-database .. clicmd:: show ip pim bsm-database Display all fragments ofstored bootstrap message in user readable format. -.. index:: show ip rpf -.. clicmd:: show ip rpf - - Display the multicast RIB created in zebra. - -.. index:: mtrace A.B.C.D [A.B.C.D] .. clicmd:: mtrace A.B.C.D [A.B.C.D] Display multicast traceroute towards source, optionally for particular group. -.. index:: show ip multicast count [vrf NAME] [json] .. clicmd:: show ip multicast count [vrf NAME] [json] Display multicast data packets count per interface for a vrf. -.. index:: show ip multicast count vrf all [json] .. clicmd:: show ip multicast count vrf all [json] Display multicast data packets count per interface for all vrf. + +.. seealso:: + + :ref:`multicast-rib-commands` + + PIM Debug Commands ================== @@ -637,56 +552,46 @@ configure CLI mode. If you specify debug commands in the configuration cli mode, the debug commands can be persistent across restarts of the FRR pimd if the config was written out. -.. index:: debug igmp .. clicmd:: debug igmp This turns on debugging for IGMP protocol activity. -.. index:: debug mtrace .. clicmd:: debug mtrace This turns on debugging for mtrace protocol activity. -.. index:: debug mroute .. clicmd:: debug mroute This turns on debugging for PIM interaction with kernel MFC cache. -.. index:: debug pim events .. clicmd:: debug pim events This turns on debugging for PIM system events. Especially timers. -.. index:: debug pim nht .. clicmd:: debug pim nht This turns on debugging for PIM nexthop tracking. It will display information about RPF lookups and information about when a nexthop changes. -.. index:: debug pim packet-dump .. clicmd:: debug pim packet-dump This turns on an extraordinary amount of data. Each pim packet sent and received is dumped for debugging purposes. This should be considered a developer only command. -.. index:: debug pim packets .. clicmd:: debug pim packets This turns on information about packet generation for sending and about packet handling from a received packet. -.. index:: debug pim trace .. clicmd:: debug pim trace This traces pim code and how it is running. -.. index:: debug pim bsm .. clicmd:: debug pim bsm This turns on debugging for BSR message processing. -.. index:: debug pim zebra .. clicmd:: debug pim zebra This gathers data about events from zebra that come up through the ZAPI. @@ -695,39 +600,32 @@ PIM Clear Commands ================== Clear commands reset various variables. -.. index:: clear ip interfaces .. clicmd:: clear ip interfaces Reset interfaces. -.. index:: clear ip igmp interfaces .. clicmd:: clear ip igmp interfaces Reset IGMP interfaces. -.. index:: clear ip mroute .. clicmd:: clear ip mroute Reset multicast routes. -.. index:: clear ip mroute [vrf NAME] count .. clicmd:: clear ip mroute [vrf NAME] count When this command is issued, reset the counts of data shown for packet count, byte count and wrong interface to 0 and start count up from this spot. -.. index:: clear ip pim interfaces .. clicmd:: clear ip pim interfaces Reset PIM interfaces. -.. index:: clear ip pim oil .. clicmd:: clear ip pim oil Rescan PIM OIL (output interface list). -.. index:: clear ip pim [vrf NAME] bsr-data .. clicmd:: clear ip pim [vrf NAME] bsr-data This command will clear the BSM scope data struct. This command also diff --git a/doc/user/ripd.rst b/doc/user/ripd.rst index e83b505a19..cba93e0d84 100644 --- a/doc/user/ripd.rst +++ b/doc/user/ripd.rst @@ -87,23 +87,17 @@ multipath routing. RIP Configuration ================= -.. index:: router rip .. clicmd:: router rip The `router rip` command is necessary to enable RIP. To disable RIP, use the `no router rip` command. RIP must be enabled before carrying out any of the RIP commands. -.. index:: router rip -.. clicmd:: no router rip Disable RIP. -.. index:: network NETWORK .. clicmd:: network NETWORK -.. index:: network NETWORK -.. clicmd:: no network NETWORK Set the RIP enable interface by NETWORK. The interfaces which have addresses matching with NETWORK are enabled. @@ -114,22 +108,16 @@ RIP Configuration 10.0.0.0 to 10.0.0.255 being enabled for RIP. The `no network` command will disable RIP for the specified network. -.. index:: network IFNAME .. clicmd:: network IFNAME -.. index:: network IFNAME -.. clicmd:: no network IFNAME Set a RIP enabled interface by IFNAME. Both the sending and receiving of RIP packets will be enabled on the port specified in the `network ifname` command. The `no network ifname` command will disable RIP on the specified interface. -.. index:: neighbor A.B.C.D .. clicmd:: neighbor A.B.C.D -.. index:: neighbor A.B.C.D -.. clicmd:: no neighbor A.B.C.D Specify RIP neighbor. When a neighbor doesn't understand multicast, this command is used to specify neighbors. In some cases, not all routers will be @@ -152,11 +140,8 @@ RIP Configuration ! -.. index:: passive-interface (IFNAME|default) .. clicmd:: passive-interface (IFNAME|default) -.. index:: passive-interface IFNAME -.. clicmd:: no passive-interface IFNAME This command sets the specified interface to passive mode. On passive mode interface, all receiving packets are processed as normal and ripd does not @@ -166,11 +151,8 @@ RIP Configuration The default is to be passive on all interfaces. -.. index:: ip split-horizon .. clicmd:: ip split-horizon -.. index:: ip split-horizon -.. clicmd:: no ip split-horizon Control split-horizon on the interface. Default is `ip split-horizon`. If you don't perform split-horizon on the interface, please specify `no ip @@ -192,7 +174,6 @@ is enabled then RIP will reply to REQUEST packets, sending the state of its RIP routing table to any remote routers that ask on demand. For a more detailed discussion on the security implications of RIPv1 see :ref:`rip-authentication`. -.. index:: version VERSION .. clicmd:: version VERSION Set RIP version to accept for reads and send. ``VERSION`` can be either 1 or @@ -203,12 +184,6 @@ discussion on the security implications of RIPv1 see :ref:`rip-authentication`. Default: Send Version 2, and accept either version. -.. index:: version -.. clicmd:: no version - - Reset the global version setting back to the default. - -.. index:: ip rip send version VERSION .. clicmd:: ip rip send version VERSION VERSION can be ``1``, ``2``, or ``1 2``. @@ -221,7 +196,6 @@ discussion on the security implications of RIPv1 see :ref:`rip-authentication`. Default: Send packets according to the global version (version 2) -.. index:: ip rip receive version VERSION .. clicmd:: ip rip receive version VERSION VERSION can be ``1``, ``2``, or ``1 2``. @@ -232,98 +206,22 @@ discussion on the security implications of RIPv1 see :ref:`rip-authentication`. Default: Accept packets according to the global setting (both 1 and 2). + .. _how-to-announce-rip-route: How to Announce RIP route ========================= -.. index:: redistribute kernel -.. clicmd:: redistribute kernel - -.. index:: redistribute kernel metric (0-16) -.. clicmd:: redistribute kernel metric (0-16) - -.. index:: redistribute kernel route-map ROUTE-MAP -.. clicmd:: redistribute kernel route-map ROUTE-MAP - -.. index:: redistribute kernel -.. clicmd:: no redistribute kernel - - `redistribute kernel` redistributes routing information from kernel route - entries into the RIP tables. `no redistribute kernel` disables the routes. - -.. index:: redistribute static -.. clicmd:: redistribute static - -.. index:: redistribute static metric (0-16) -.. clicmd:: redistribute static metric (0-16) - -.. index:: redistribute static route-map ROUTE-MAP -.. clicmd:: redistribute static route-map ROUTE-MAP - -.. index:: redistribute static -.. clicmd:: no redistribute static - - `redistribute static` redistributes routing information from static route - entries into the RIP tables. `no redistribute static` disables the routes. - -.. index:: redistribute connected -.. clicmd:: redistribute connected - -.. index:: redistribute connected metric (0-16) -.. clicmd:: redistribute connected metric (0-16) +.. clicmd:: redistribute <babel|bgp|connected|eigrp|isis|kernel|openfabric|ospf|sharp|static|table> [metric (0-16)] [route-map WORD] -.. index:: redistribute connected route-map ROUTE-MAP -.. clicmd:: redistribute connected route-map ROUTE-MAP + Redistribute routes from other sources into RIP. -.. index:: redistribute connected -.. clicmd:: no redistribute connected +If you want to specify RIP only static routes: - Redistribute connected routes into the RIP tables. `no redistribute - connected` disables the connected routes in the RIP tables. This command - redistribute connected of the interface which RIP disabled. The connected - route on RIP enabled interface is announced by default. - -.. index:: redistribute ospf -.. clicmd:: redistribute ospf - -.. index:: redistribute ospf metric (0-16) -.. clicmd:: redistribute ospf metric (0-16) - -.. index:: redistribute ospf route-map ROUTE-MAP -.. clicmd:: redistribute ospf route-map ROUTE-MAP - -.. index:: redistribute ospf -.. clicmd:: no redistribute ospf - - `redistribute ospf` redistributes routing information from ospf route - entries into the RIP tables. `no redistribute ospf` disables the routes. - -.. index:: redistribute bgp -.. clicmd:: redistribute bgp - -.. index:: redistribute bgp metric (0-16) -.. clicmd:: redistribute bgp metric (0-16) - -.. index:: redistribute bgp route-map ROUTE-MAP -.. clicmd:: redistribute bgp route-map ROUTE-MAP - -.. index:: redistribute bgp -.. clicmd:: no redistribute bgp - - `redistribute bgp` redistributes routing information from bgp route entries - into the RIP tables. `no redistribute bgp` disables the routes. - - If you want to specify RIP only static routes: - -.. index:: default-information originate .. clicmd:: default-information originate -.. index:: route A.B.C.D/M .. clicmd:: route A.B.C.D/M -.. index:: route A.B.C.D/M -.. clicmd:: no route A.B.C.D/M This command is specific to FRR. The `route` command makes a static route only inside RIP. This command should be used only by advanced users who are @@ -338,7 +236,6 @@ Filtering RIP Routes RIP routes can be filtered by a distribute-list. -.. index:: distribute-list ACCESS_LIST DIRECT IFNAME .. clicmd:: distribute-list ACCESS_LIST DIRECT IFNAME You can apply access lists to the interface with a `distribute-list` command. @@ -364,7 +261,6 @@ RIP routes can be filtered by a distribute-list. `distribute-list` can be applied to both incoming and outgoing data. -.. index:: distribute-list prefix PREFIX_LIST (in|out) IFNAME .. clicmd:: distribute-list prefix PREFIX_LIST (in|out) IFNAME You can apply prefix lists to the interface with a `distribute-list` @@ -381,11 +277,8 @@ RIP metric is a value for distance for the network. Usually *ripd* increment the metric when the network information is received. Redistributed routes' metric is set to 1. -.. index:: default-metric (1-16) .. clicmd:: default-metric (1-16) -.. index:: default-metric (1-16) -.. clicmd:: no default-metric (1-16) This command modifies the default metric value for redistributed routes. The default value is 1. This command does not affect connected route even if @@ -393,10 +286,8 @@ received. Redistributed routes' metric is set to 1. metric value, please use ``redistribute connected metric`` or *route-map*. *offset-list* also affects connected routes. -.. index:: offset-list ACCESS-LIST (in|out) .. clicmd:: offset-list ACCESS-LIST (in|out) -.. index:: offset-list ACCESS-LIST (in|out) IFNAME .. clicmd:: offset-list ACCESS-LIST (in|out) IFNAME @@ -407,28 +298,19 @@ RIP distance Distance value is used in zebra daemon. Default RIP distance is 120. -.. index:: distance (1-255) .. clicmd:: distance (1-255) -.. index:: distance (1-255) -.. clicmd:: no distance (1-255) Set default RIP distance to specified value. -.. index:: distance (1-255) A.B.C.D/M .. clicmd:: distance (1-255) A.B.C.D/M -.. index:: distance (1-255) A.B.C.D/M -.. clicmd:: no distance (1-255) A.B.C.D/M Set default RIP distance to specified value when the route's source IP address matches the specified prefix. -.. index:: distance (1-255) A.B.C.D/M ACCESS-LIST .. clicmd:: distance (1-255) A.B.C.D/M ACCESS-LIST -.. index:: distance (1-255) A.B.C.D/M ACCESS-LIST -.. clicmd:: no distance (1-255) A.B.C.D/M ACCESS-LIST Set default RIP distance to specified value when the route's source IP address matches the specified prefix and the specified access-list. @@ -459,7 +341,6 @@ it may be changed at future. Route-map statement (:ref:`route-map`) is needed to use route-map functionality. -.. index:: match interface WORD .. clicmd:: match interface WORD This command match to incoming interface. Notation of this match is @@ -471,37 +352,30 @@ functionality. sends to different interfaces must be different. Maybe it'd be better to made new matches - say "match interface-out NAME" or something like that. -.. index:: match ip address WORD .. clicmd:: match ip address WORD -.. index:: match ip address prefix-list WORD .. clicmd:: match ip address prefix-list WORD Match if route destination is permitted by access-list. -.. index:: match ip next-hop WORD .. clicmd:: match ip next-hop WORD -.. index:: match ip next-hop prefix-list WORD .. clicmd:: match ip next-hop prefix-list WORD Match if route next-hop (meaning next-hop listed in the rip route-table as displayed by "show ip rip") is permitted by access-list. -.. index:: match metric (0-4294967295) .. clicmd:: match metric (0-4294967295) This command match to the metric value of RIP updates. For other protocol compatibility metric range is shown as (0-4294967295). But for RIP protocol only the value range (0-16) make sense. -.. index:: set ip next-hop A.B.C.D .. clicmd:: set ip next-hop A.B.C.D This command set next hop value in RIPv2 protocol. This command does not affect RIPv1 because there is no next hop field in the packet. -.. index:: set metric (0-4294967295) .. clicmd:: set metric (0-4294967295) Set a metric for matched route when sending announcement. The metric value @@ -536,36 +410,24 @@ on the internet, via RIPv1. To prevent such unauthenticated querying of routes disable RIPv1, :ref:`rip-version-control`. -.. index:: ip rip authentication mode md5 .. clicmd:: ip rip authentication mode md5 -.. index:: ip rip authentication mode md5 -.. clicmd:: no ip rip authentication mode md5 Set the interface with RIPv2 MD5 authentication. -.. index:: ip rip authentication mode text .. clicmd:: ip rip authentication mode text -.. index:: ip rip authentication mode text -.. clicmd:: no ip rip authentication mode text Set the interface with RIPv2 simple password authentication. -.. index:: ip rip authentication string STRING .. clicmd:: ip rip authentication string STRING -.. index:: ip rip authentication string STRING -.. clicmd:: no ip rip authentication string STRING RIP version 2 has simple text authentication. This command sets authentication string. The string must be shorter than 16 characters. -.. index:: ip rip authentication key-chain KEY-CHAIN .. clicmd:: ip rip authentication key-chain KEY-CHAIN -.. index:: ip rip authentication key-chain KEY-CHAIN -.. clicmd:: no ip rip authentication key-chain KEY-CHAIN Specify Keyed MD5 chain. @@ -587,7 +449,6 @@ To prevent such unauthenticated querying of routes disable RIPv1, RIP Timers ========== -.. index:: timers basic UPDATE TIMEOUT GARBAGE .. clicmd:: timers basic UPDATE TIMEOUT GARBAGE @@ -610,11 +471,6 @@ RIP Timers The ``timers basic`` command allows the the default values of the timers listed above to be changed. -.. index:: timers basic -.. clicmd:: no timers basic - - The `no timers basic` command will reset the timers to the default settings - listed above. .. _show-rip-information: @@ -623,7 +479,6 @@ Show RIP Information To display RIP routes. -.. index:: show ip rip .. clicmd:: show ip rip Show RIP routes. @@ -633,7 +488,6 @@ through RIP, this command will display the time the packet was sent and the tag information. This command will also display this information for routes redistributed into RIP. -.. index:: show ip rip status .. clicmd:: show ip rip status The command displays current RIP status. It includes RIP timer, @@ -665,26 +519,22 @@ RIP Debug Commands Debug for RIP protocol. -.. index:: debug rip events .. clicmd:: debug rip events Shows RIP events. Sending and receiving packets, timers, and changes in interfaces are events shown with *ripd*. -.. index:: debug rip packet .. clicmd:: debug rip packet Shows display detailed information about the RIP packets. The origin and port number of the packet as well as a packet dump is shown. -.. index:: debug rip zebra .. clicmd:: debug rip zebra This command will show the communication between *ripd* and *zebra*. The main information will include addition and deletion of paths to the kernel and the sending and receiving of interface information. -.. index:: show debugging rip .. clicmd:: show debugging rip Shows all information currently set for ripd debug. diff --git a/doc/user/ripngd.rst b/doc/user/ripngd.rst index ae2400f0bb..0387e36305 100644 --- a/doc/user/ripngd.rst +++ b/doc/user/ripngd.rst @@ -22,62 +22,46 @@ ripngd Configuration Currently ripngd supports the following commands: -.. index:: router ripng .. clicmd:: router ripng Enable RIPng. -.. index:: flush_timer TIME .. clicmd:: flush_timer TIME Set flush timer. -.. index:: network NETWORK .. clicmd:: network NETWORK Set RIPng enabled interface by NETWORK. -.. index:: network IFNAME .. clicmd:: network IFNAME Set RIPng enabled interface by IFNAME. -.. index:: route NETWORK .. clicmd:: route NETWORK Set RIPng static routing announcement of NETWORK. -.. index:: router zebra -.. clicmd:: router zebra - - This command is the default and does not appear in the configuration. With - this statement, RIPng routes go to the *zebra* daemon. .. _ripngd-terminal-mode-commands: ripngd Terminal Mode Commands ============================= -.. index:: show ip ripng .. clicmd:: show ip ripng -.. index:: show debugging ripng .. clicmd:: show debugging ripng -.. index:: debug ripng events .. clicmd:: debug ripng events -.. index:: debug ripng packet .. clicmd:: debug ripng packet -.. index:: debug ripng zebra .. clicmd:: debug ripng zebra ripngd Filtering Commands ========================= -.. index:: distribute-list ACCESS_LIST (in|out) IFNAME .. clicmd:: distribute-list ACCESS_LIST (in|out) IFNAME You can apply an access-list to the interface using the `distribute-list` diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index fa8eee815d..7f357b0925 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -90,7 +90,6 @@ cont .. _route-map-show-command: -.. index:: show route-map [WORD] .. clicmd:: show route-map [WORD] Display data about each daemons knowledge of individual route-maps. @@ -98,7 +97,6 @@ cont .. _route-map-clear-counter-command: -.. index:: clear route-map counter [WORD] .. clicmd:: clear route-map counter [WORD] Clear counters that are being stored about the route-map utilization @@ -110,7 +108,6 @@ cont Route Map Command ================= -.. index:: route-map ROUTE-MAP-NAME (permit|deny) ORDER .. clicmd:: route-map ROUTE-MAP-NAME (permit|deny) ORDER Configure the `order`'th entry in `route-map-name` with ``Match Policy`` of @@ -121,98 +118,80 @@ Route Map Command Route Map Match Command ======================= -.. index:: match ip address ACCESS_LIST .. clicmd:: match ip address ACCESS_LIST Matches the specified `access_list` -.. index:: match ip address prefix-list PREFIX_LIST .. clicmd:: match ip address prefix-list PREFIX_LIST Matches the specified `PREFIX_LIST` -.. index:: match ip address prefix-len 0-32 .. clicmd:: match ip address prefix-len 0-32 Matches the specified `prefix-len`. This is a Zebra specific command. -.. index:: match ipv6 address ACCESS_LIST .. clicmd:: match ipv6 address ACCESS_LIST Matches the specified `access_list` -.. index:: match ipv6 address prefix-list PREFIX_LIST .. clicmd:: match ipv6 address prefix-list PREFIX_LIST Matches the specified `PREFIX_LIST` -.. index:: match ipv6 address prefix-len 0-128 .. clicmd:: match ipv6 address prefix-len 0-128 Matches the specified `prefix-len`. This is a Zebra specific command. -.. index:: match ip next-hop address IPV4_ADDR .. clicmd:: match ip next-hop address IPV4_ADDR This is a BGP specific match command. Matches the specified `ipv4_addr`. -.. index:: match ipv6 next-hop IPV6_ADDR .. clicmd:: match ipv6 next-hop IPV6_ADDR This is a BGP specific match command. Matches the specified `ipv6_addr`. -.. index:: match as-path AS_PATH .. clicmd:: match as-path AS_PATH Matches the specified `as_path`. -.. index:: match metric METRIC .. clicmd:: match metric METRIC Matches the specified `metric`. -.. index:: match tag TAG .. clicmd:: match tag TAG Matches the specified tag value associated with the route. This tag value can be in the range of (1-4294967295). -.. index:: match local-preference METRIC .. clicmd:: match local-preference METRIC Matches the specified `local-preference`. -.. index:: match community COMMUNITY_LIST .. clicmd:: match community COMMUNITY_LIST Matches the specified `community_list` -.. index:: match peer IPV4_ADDR .. clicmd:: match peer IPV4_ADDR This is a BGP specific match command. Matches the peer ip address if the neighbor was specified in this manner. -.. index:: match peer IPV6_ADDR .. clicmd:: match peer IPV6_ADDR This is a BGP specific match command. Matches the peer ipv6 address if the neighbor was specified in this manner. -.. index:: match peer INTERFACE_NAME .. clicmd:: match peer INTERFACE_NAME This is a BGP specific match command. Matches the peer interface name specified if the neighbor was specified in this manner. -.. index:: match source-protocol PROTOCOL_NAME .. clicmd:: match source-protocol PROTOCOL_NAME This is a ZEBRA specific match command. Matches the originating protocol specified. -.. index:: match source-instance NUMBER .. clicmd:: match source-instance NUMBER This is a ZEBRA specific match command. The number is a range from (0-255). @@ -225,7 +204,6 @@ Route Map Set Command .. program:: configure -.. index:: set tag TAG .. clicmd:: set tag TAG Set a tag on the matched route. This tag value can be from (1-4294967295). @@ -233,13 +211,11 @@ Route Map Set Command configure option. Tag values from (1-255) are sent to the Linux kernel as a realm value. Then route policy can be applied. See the tc man page. -.. index:: set ip next-hop IPV4_ADDRESS .. clicmd:: set ip next-hop IPV4_ADDRESS Set the BGP nexthop address to the specified IPV4_ADDRESS. For both incoming and outgoing route-maps. -.. index:: set ip next-hop peer-address .. clicmd:: set ip next-hop peer-address Set the BGP nexthop address to the address of the peer. For an incoming @@ -247,13 +223,11 @@ Route Map Set Command route-map this means the ip address of our self is used to establish the peering with our neighbor. -.. index:: set ip next-hop unchanged .. clicmd:: set ip next-hop unchanged Set the route-map as unchanged. Pass the route-map through without changing it's value. -.. index:: set ipv6 next-hop peer-address .. clicmd:: set ipv6 next-hop peer-address Set the BGP nexthop address to the address of the peer. For an incoming @@ -261,121 +235,104 @@ Route Map Set Command route-map this means the ip address of our self is used to establish the peering with our neighbor. -.. index:: set ipv6 next-hop prefer-global .. clicmd:: set ipv6 next-hop prefer-global For Incoming and Import Route-maps if we receive a v6 global and v6 LL address for the route, then prefer to use the global address as the nexthop. -.. index:: set ipv6 next-hop global IPV6_ADDRESS .. clicmd:: set ipv6 next-hop global IPV6_ADDRESS Set the next-hop to the specified IPV6_ADDRESS for both incoming and outgoing route-maps. -.. index:: set local-preference LOCAL_PREF .. clicmd:: set local-preference LOCAL_PREF Set the BGP local preference to `local_pref`. -.. index:: set local-preference +LOCAL_PREF .. clicmd:: set local-preference +LOCAL_PREF Add the BGP local preference to an existing `local_pref`. -.. index:: set local-preference -LOCAL_PREF .. clicmd:: set local-preference -LOCAL_PREF Subtract the BGP local preference from an existing `local_pref`. -.. index:: set distance DISTANCE -.. clicmd:: [no] set distance DISTANCE +.. clicmd:: set distance DISTANCE Set the Administrative distance to DISTANCE to use for the route. This is only locally significant and will not be dispersed to peers. -.. index:: set weight WEIGHT .. clicmd:: set weight WEIGHT Set the route's weight. -.. index:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt> -.. clicmd:: [no] set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt> +.. clicmd:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt> Set the BGP attribute MED to a specific value. Use `+`/`-` to add or subtract the specified value to/from the MED. Use `rtt` to set the MED to the round trip time or `+rtt`/`-rtt` to add/subtract the round trip time to/from the MED. -.. index:: set as-path prepend AS_PATH .. clicmd:: set as-path prepend AS_PATH Set the BGP AS path to prepend. -.. index:: set community COMMUNITY .. clicmd:: set community COMMUNITY Set the BGP community attribute. -.. index:: set ipv6 next-hop local IPV6_ADDRESS .. clicmd:: set ipv6 next-hop local IPV6_ADDRESS Set the BGP-4+ link local IPv6 nexthop address. -.. index:: set origin ORIGIN <egp|igp|incomplete> .. clicmd:: set origin ORIGIN <egp|igp|incomplete> Set BGP route origin. -.. index:: set table (1-4294967295) .. clicmd:: set table (1-4294967295) Set the BGP table to a given table identifier -.. index:: set sr-te color (1-4294967295) .. clicmd:: set sr-te color (1-4294967295) Set the color of a SR-TE Policy to be applied to a learned route. The SR-TE Policy is uniquely determined by the color and the BGP nexthop. + .. _route-map-call-command: Route Map Call Command ====================== -.. index:: call NAME .. clicmd:: call NAME Call route-map `name`. If it returns deny, deny the route and finish processing the route-map. + .. _route-map-exit-action-command: Route Map Exit Action Command ============================= -.. index:: on-match next .. clicmd:: on-match next -.. index:: continue .. clicmd:: continue Proceed on to the next entry in the route-map. -.. index:: on-match goto N .. clicmd:: on-match goto N -.. index:: continue N .. clicmd:: continue N Proceed processing the route-map at the first entry whose order is >= N + .. _route-map-optimization-command: Route Map Optimization Command ============================== -.. index:: route-map optimization .. clicmd:: route-map optimization Enable route-map processing optimization. The optimization is @@ -387,10 +344,6 @@ Route Map Optimization Command of all the prefixes in all the prefix-lists that are included in the match rule of all the sequences of a route-map. -.. index:: route-map optimization -.. clicmd:: no route-map optimization - - Disable the route-map processing optimization. Route Map Examples ================== diff --git a/doc/user/routeserver.rst b/doc/user/routeserver.rst index 474a68db25..5100d679f7 100644 --- a/doc/user/routeserver.rst +++ b/doc/user/routeserver.rst @@ -163,13 +163,10 @@ Commands for configuring a Route Server Now we will describe the commands that have been added to frr in order to support the route server features. -.. index:: neighbor PEER-GROUP route-server-client .. clicmd:: neighbor PEER-GROUP route-server-client -.. index:: neighbor A.B.C.D route-server-client .. clicmd:: neighbor A.B.C.D route-server-client -.. index:: neighbor X:X::X:X route-server-client .. clicmd:: neighbor X:X::X:X route-server-client This command configures the peer given by `peer`, `A.B.C.D` or `X:X::X:X` as @@ -186,14 +183,12 @@ in order to support the route server features. that moment, every announcement received by the route server will be also considered for the new Loc-RIB. -.. index:: neigbor A.B.C.D|X.X::X.X|peer-group route-map WORD import|export .. clicmd:: neigbor A.B.C.D|X.X::X.X|peer-group route-map WORD import|export This set of commands can be used to specify the route-map that represents the Import or Export policy of a peer which is configured as a RS-client (with the previous command). -.. index:: match peer A.B.C.D|X:X::X:X .. clicmd:: match peer A.B.C.D|X:X::X:X This is a new *match* statement for use in route-maps, enabling them to @@ -210,7 +205,6 @@ in order to support the route server features. announce is going to be inserted (how the same export policy is applied before different Loc-RIBs is shown in :ref:`fig-rs-processing`.). -.. index:: call WORD .. clicmd:: call WORD This command (also used inside a route-map) jumps into a different diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index 451df1aa4e..01705f607c 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -54,7 +54,6 @@ In a nutshell, the current implementation provides the following features Enabling RPKI ------------- -.. index:: rpki .. clicmd:: rpki This command enables the RPKI configuration mode. Most commands that start @@ -67,7 +66,6 @@ Enabling RPKI to configure at least one reachable cache server. See section :ref:`configuring-rpki-rtr-cache-servers` for configuring a cache server. -.. index:: RPKI and daemons When first installing FRR with RPKI support from the pre-packaged binaries. Remember to add ``-M rpki`` to the variable ``bgpd_options`` in @@ -101,11 +99,8 @@ Configuring RPKI/RTR Cache Servers The following commands are independent of a specific cache server. -.. index:: rpki polling_period (1-3600) .. clicmd:: rpki polling_period (1-3600) -.. index:: rpki polling_period -.. clicmd:: no rpki polling_period Set the number of seconds the router waits until the router asks the cache again for updated data. @@ -114,11 +109,8 @@ The following commands are independent of a specific cache server. The following commands configure one or multiple cache servers. -.. index:: rpki cache (A.B.C.D|WORD) PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [SSH_PUBKEY_PATH] [KNOWN_HOSTS_PATH] PREFERENCE .. clicmd:: rpki cache (A.B.C.D|WORD) PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [SSH_PUBKEY_PATH] [KNOWN_HOSTS_PATH] PREFERENCE -.. index:: rpki cache (A.B.C.D|WORD) [PORT] PREFERENCE -.. clicmd:: no rpki cache (A.B.C.D|WORD) [PORT] PREFERENCE Add a cache server to the socket. By default, the connection between router and cache server is based on plain TCP. Protecting the connection between @@ -154,11 +146,8 @@ The following commands are independent of a specific cache server. Validating BGP Updates ---------------------- -.. index:: match rpki notfound|invalid|valid .. clicmd:: match rpki notfound|invalid|valid -.. index:: match rpki notfound|invalid|valid -.. clicmd:: no match rpki notfound|invalid|valid Create a clause for a route map to match prefixes with the specified RPKI state. @@ -187,11 +176,8 @@ Validating BGP Updates Debugging --------- -.. index:: debug rpki .. clicmd:: debug rpki -.. index:: debug rpki -.. clicmd:: no debug rpki Enable or disable debugging output for RPKI. @@ -200,26 +186,22 @@ Debugging Displaying RPKI --------------- -.. index:: show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)] .. clicmd:: show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)] Display validated prefixes received from the cache servers filtered by the specified prefix. -.. index:: show rpki as-number ASN .. clicmd:: show rpki as-number ASN Display validated prefixes received from the cache servers filtered by ASN. -.. index:: show rpki prefix-table .. clicmd:: show rpki prefix-table Display all validated prefix to origin AS mappings/records which have been received from the cache servers and stored in the router. Based on this data, the router validates BGP Updates. -.. index:: show rpki cache-connection .. clicmd:: show rpki cache-connection Display all configured cache servers, whether active or not. diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst index 90eae4d65a..9e83e44222 100644 --- a/doc/user/sharp.rst +++ b/doc/user/sharp.rst @@ -32,7 +32,6 @@ Using SHARP All sharp commands are under the enable node and preceded by the ``sharp`` keyword. At present, no sharp commands will be preserved in the config. -.. index:: sharp install .. clicmd:: sharp install routes A.B.C.D <nexthop <E.F.G.H|X:X::X:X>|nexthop-group NAME> (1-1000000) [instance (0-255)] [repeat (2-1000)] [opaque WORD] Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D`` @@ -49,7 +48,6 @@ keyword. At present, no sharp commands will be preserved in the config. number of times specified. If the keyword opaque is specified then the next word is sent down to zebra as part of the route installation. -.. index:: sharp remove .. clicmd:: sharp remove routes A.B.C.D (1-1000000) Remove up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D``. The @@ -57,7 +55,6 @@ keyword. At present, no sharp commands will be preserved in the config. log and when all routes have been successfully deleted the debug log will be updated with this information as well. -.. index:: sharp data route .. clicmd:: sharp data route Allow end user doing route install and deletion to get timing information @@ -65,14 +62,12 @@ keyword. At present, no sharp commands will be preserved in the config. is informational only and you should look at sharp_vty.c for explanation of the output as that it may change. -.. index:: sharp label .. clicmd:: sharp label <ipv4|ipv6> vrf NAME label (0-1000000) Install a label into the kernel that causes the specified vrf NAME table to be used for pop and forward operations when the specified label is seen. -.. index:: sharp watch -.. clicmd:: [no] sharp watch <nexthop <A.B.C.D|X:X::X:X>|import <A.B.C.D/M:X:X::X:X/M> [connected] +.. clicmd:: sharp watch <nexthop <A.B.C.D|X:X::X:X>|import <A.B.C.D/M:X:X::X:X/M> [connected] Instruct zebra to monitor and notify sharp when the specified nexthop is changed. The notification from zebra is written into the debug log. @@ -83,13 +78,11 @@ keyword. At present, no sharp commands will be preserved in the config. for the import keyword connected means exact match. The no form of the command obviously turns this watching off. -.. index:: sharp data nexthop .. clicmd:: sharp data nexthop Allow end user to dump associated data with the nexthop tracking that may have been turned on. -.. index:: sharp lsp .. clicmd:: sharp lsp [update] (0-100000) nexthop-group NAME [prefix A.B.C.D/M TYPE [instance (0-255)]] Install an LSP using the specified in-label, with nexthops as @@ -98,7 +91,6 @@ keyword. At present, no sharp commands will be preserved in the config. If ``prefix`` is specified, an existing route with type ``TYPE`` (and optional ``instance`` id) will be updated to use the LSP. -.. index:: sharp remove lsp .. clicmd:: sharp remove lsp (0-100000) nexthop-group NAME [prefix A.B.C.D/M TYPE [instance (0-255)]] Remove a SHARPD LSP that uses the specified in-label, where the @@ -106,13 +98,11 @@ keyword. At present, no sharp commands will be preserved in the config. specified, remove label bindings from the route of type ``TYPE`` also. -.. index:: sharp send opaque .. clicmd:: sharp send opaque type (1-255) (1-1000) Send opaque ZAPI messages with subtype ``type``. Sharpd will send a stream of messages if the count is greater than one. -.. index:: sharp send opaque unicast .. clicmd:: sharp send opaque unicast type (1-255) $proto_str [{instance (0-1000) | session (1-1000)}] (1-1000) Send unicast opaque ZAPI messages with subtype ``type``. The @@ -120,7 +110,6 @@ keyword. At present, no sharp commands will be preserved in the config. client. Sharpd will send a stream of messages if the count is greater than one. -.. index:: sharp send opaque reg unreg .. clicmd:: sharp send opaque <reg | unreg> $proto_str [{instance (0-1000) | session (1-1000)}] type (1-1000) Send opaque ZAPI registration and unregistration messages for a @@ -128,19 +117,16 @@ keyword. At present, no sharp commands will be preserved in the config. name, and can include optional zapi ``instance`` and ``session`` values. -.. index:: sharp create session .. clicmd:: sharp create session (1-1024) Create an additional zapi client session for testing, using the specified session id. -.. index:: sharp remove session .. clicmd:: sharp remove session (1-1024) Remove a test zapi client session that was created with the specified session id. -.. index:: sharp neigh discover .. clicmd:: sharp neigh discover [vrf NAME] <A.B.C.D|X:X::X:X> IFNAME Send an ARP/NDP request to trigger the addition of a neighbor in the ARP diff --git a/doc/user/snmp.rst b/doc/user/snmp.rst index ebbe178e0b..b9058cc0d3 100644 --- a/doc/user/snmp.rst +++ b/doc/user/snmp.rst @@ -130,10 +130,7 @@ need to configure FRR to use another transport, you can configure it through Here is the syntax for using AgentX: -.. index:: agentx .. clicmd:: agentx -.. index:: agentx -.. clicmd:: no agentx .. include:: snmptrap.rst diff --git a/doc/user/static.rst b/doc/user/static.rst index 6302d1b148..200d187370 100644 --- a/doc/user/static.rst +++ b/doc/user/static.rst @@ -35,10 +35,8 @@ Static Route Commands Static routing is a very fundamental feature of routing technology. It defines a static prefix and gateway. -.. index:: ip route NETWORK GATEWAY table TABLENO nexthop-vrf VRFNAME DISTANCE vrf VRFNAME .. clicmd:: ip route NETWORK GATEWAY table TABLENO nexthop-vrf VRFNAME DISTANCE vrf VRFNAME -.. index:: ipv6 route NETWORK from SRCPREFIX GATEWAY table TABLENO nexthop-vrf VRFNAME DISTANCE vrf VRFNAME .. clicmd:: ipv6 route NETWORK from SRCPREFIX GATEWAY table TABLENO nexthop-vrf VRFNAME DISTANCE vrf VRFNAME NETWORK is destination prefix with a valid v4 or v6 network based upon diff --git a/doc/user/vnc.rst b/doc/user/vnc.rst index 4f03e543ac..4ff27c6a63 100644 --- a/doc/user/vnc.rst +++ b/doc/user/vnc.rst @@ -110,7 +110,6 @@ These are the statements that can appear between ``vnc defaults`` and - :clicmd:`export bgp|zebra route-map MAP-NAME` - :clicmd:`export bgp|zebra no route-map` -.. index:: exit-vnc .. clicmd:: exit-vnc Exit VNC configuration mode. @@ -136,7 +135,6 @@ Defaults section. **At least one `nve-group` is mandatory for useful VNC operation.** -.. index:: vnc nve-group NAME .. clicmd:: vnc nve-group NAME Enter VNC configuration mode for defining the NVE group `name`. @@ -149,14 +147,8 @@ Defaults section. exit-vnc -.. index:: vnc nve-group NAME -.. clicmd:: no vnc nve-group NAME +The following statements are valid in an NVE group definition: - Delete the NVE group named `name`. - - The following statements are valid in an NVE group definition: - -.. index:: l2rd NVE-ID-VALUE .. clicmd:: l2rd NVE-ID-VALUE Set the value used to distinguish NVEs connected to the same physical @@ -166,7 +158,6 @@ Defaults section. 1-255, or it may be specified as `auto:vn`, which means to use the least-significant octet of the originating NVE's VN address. -.. index:: prefix vn|un A.B.C.D/M|X:X::X:X/M .. clicmd:: prefix vn|un A.B.C.D/M|X:X::X:X/M Specify the matching prefix for this NVE group by either virtual-network @@ -178,7 +169,6 @@ Defaults section. These prefixes are used only for determining assignments of NVEs to NVE Groups. -.. index:: rd ROUTE-DISTINGUISHER .. clicmd:: rd ROUTE-DISTINGUISHER Specify the route distinguisher for routes advertised via BGP @@ -202,7 +192,6 @@ Defaults section. `route-distinguisher` is configured, then the advertised RD is set to ``two-byte-autonomous-system-number=0:four-byte-integer=0``. -.. index:: response-lifetime LIFETIME|infinite .. clicmd:: response-lifetime LIFETIME|infinite Specify the response lifetime, in seconds, to be included in RFP response @@ -218,13 +207,10 @@ Defaults section. `response-lifetime` is configured, the value 3600 will be used. The maximum response lifetime is 2147483647. -.. index:: rt export RT-LIST .. clicmd:: rt export RT-LIST -.. index:: rt import RT-LIST .. clicmd:: rt import RT-LIST -.. index:: rt both RT-LIST .. clicmd:: rt both RT-LIST Specify route target import and export lists. `rt-list` is a @@ -258,7 +244,6 @@ Defaults section. simultaneously, and is equivalent to `rt export `rt-list`` followed by `rt import `rt-list``. -.. index:: export bgp|zebra route-map MAP-NAME .. clicmd:: export bgp|zebra route-map MAP-NAME Specify that the named route-map should be applied to routes being exported @@ -266,7 +251,6 @@ Defaults section. :ref:`configuring-export-of-routes-to-other-routing-protocols`. This item is optional. -.. index:: export bgp|zebra no route-map .. clicmd:: export bgp|zebra no route-map Specify that no route-map should be applied to routes being exported to bgp @@ -274,7 +258,6 @@ Defaults section. :ref:`configuring-export-of-routes-to-other-routing-protocols`. This item is optional. -.. index:: export bgp|zebra ipv4|ipv6 prefix-list LIST-NAME .. clicmd:: export bgp|zebra ipv4|ipv6 prefix-list LIST-NAME Specify that the named prefix-list filter should be applied to routes being @@ -283,7 +266,6 @@ Defaults section. :ref:`configuring-export-of-routes-to-other-routing-protocols`. This item is optional. -.. index:: export bgp|zebra no ipv4|ipv6 prefix-list .. clicmd:: export bgp|zebra no ipv4|ipv6 prefix-list Specify that no prefix-list filter should be applied to routes being @@ -309,7 +291,6 @@ Note that a corresponding NVE group configuration must be present, and that other NVE associated configuration information, notably RD, is not impacted by L2 Group Configuration. -.. index:: vnc l2-group NAME .. clicmd:: vnc l2-group NAME Enter VNC configuration mode for defining the L2 group `name`. @@ -322,35 +303,26 @@ L2 Group Configuration. exit-vnc -.. index:: vnc l2-group NAME -.. clicmd:: no vnc l2-group NAME Delete the L2 group named `name`. The following statements are valid in a L2 group definition: -.. index:: logical-network-id VALUE .. clicmd:: logical-network-id VALUE Define the Logical Network Identifier with a value in the range of 0-4294967295 that identifies the logical Ethernet segment. -.. index:: labels LABEL-LIST .. clicmd:: labels LABEL-LIST -.. index:: labels LABEL-LIST -.. clicmd:: no labels LABEL-LIST Add or remove labels associated with the group. `label-list` is a space separated list of label values in the range of 0-1048575. -.. index:: rt import RT-TARGET .. clicmd:: rt import RT-TARGET -.. index:: rt export RT-TARGET .. clicmd:: rt export RT-TARGET -.. index:: rt both RT-TARGET .. clicmd:: rt both RT-TARGET Specify the route target import and export value associated with the group. @@ -484,14 +456,10 @@ There is currently no policy (prefix-list or route-map) support for Redistribution Command Syntax ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. index:: vnc redistribute ipv4|ipv6 bgp|bgp-direct|ipv6 bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static .. clicmd:: vnc redistribute ipv4|ipv6 bgp|bgp-direct|ipv6 bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static -.. index:: vnc redistribute ipv4|ipv6 bgp-direct-to-nve-groups view VIEWNAME .. clicmd:: vnc redistribute ipv4|ipv6 bgp-direct-to-nve-groups view VIEWNAME -.. index:: vnc redistribute ipv4|ipv6 bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static -.. clicmd:: no vnc redistribute ipv4|ipv6 bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static Import (or do not import) prefixes from another routing protocols. Specify both the address family to import (`ipv4` or `ipv6`) and the protocol @@ -502,17 +470,13 @@ Redistribution Command Syntax Prefixes from all other protocols (including `bgp`) are imported via the `zebra` kernel routing process. -.. index:: vnc redistribute mode plain|nve-group|resolve-nve .. clicmd:: vnc redistribute mode plain|nve-group|resolve-nve Redistribute routes from other protocols into VNC using the specified mode. Not all combinations of modes and protocols are supported. -.. index:: vnc redistribute nve-group GROUP-NAME .. clicmd:: vnc redistribute nve-group GROUP-NAME -.. index:: vnc redistribute nve-group GROUP-NAME -.. clicmd:: no vnc redistribute nve-group GROUP-NAME When using `nve-group` mode, assign (or do not assign) the NVE group `group-name` to routes redistributed from another routing protocol. @@ -522,7 +486,6 @@ Redistribution Command Syntax prefix must be specified as a full-length (/32 for IPv4, /128 for IPv6) prefix. -.. index:: vnc redistribute lifetime LIFETIME|infinite .. clicmd:: vnc redistribute lifetime LIFETIME|infinite Assign a registration lifetime, either `lifetime` seconds or `infinite`, to @@ -530,7 +493,6 @@ Redistribution Command Syntax received via RFP registration messages from an NVE. `lifetime` can be any integer between 1 and 4294967295, inclusive. -.. index:: vnc redistribute resolve-nve roo-ec-local-admin 0-65536 .. clicmd:: vnc redistribute resolve-nve roo-ec-local-admin 0-65536 Assign a value to the local-administrator subfield used in the @@ -545,25 +507,21 @@ specified outside the context of an nve-group, then they apply only for redistribution modes `plain` and `resolve-nve`, and then only for routes being redistributed from `bgp-direct`. -.. index:: vnc redistribute bgp-direct (ipv4|ipv6) prefix-list LIST-NAME .. clicmd:: vnc redistribute bgp-direct (ipv4|ipv6) prefix-list LIST-NAME When redistributing `bgp-direct` routes, specifies that the named prefix-list should be applied. -.. index:: vnc redistribute bgp-direct no (ipv4|ipv6) prefix-list .. clicmd:: vnc redistribute bgp-direct no (ipv4|ipv6) prefix-list When redistributing `bgp-direct` routes, specifies that no prefix-list should be applied. -.. index:: vnc redistribute bgp-direct route-map MAP-NAME .. clicmd:: vnc redistribute bgp-direct route-map MAP-NAME When redistributing `bgp-direct` routes, specifies that the named route-map should be applied. -.. index:: vnc redistribute bgp-direct no route-map .. clicmd:: vnc redistribute bgp-direct no route-map When redistributing `bgp-direct` routes, @@ -582,7 +540,6 @@ downstream protocol must also be configured to import the routes. For example, when VNC routes are exported to unicast BGP, the BGP configuration must include a corresponding `redistribute vnc-direct` statement. -.. index:: export bgp|zebra mode none|group-nve|registering-nve|ce .. clicmd:: export bgp|zebra mode none|group-nve|registering-nve|ce Specify how routes should be exported to bgp or zebra. If the mode is @@ -600,10 +557,8 @@ a corresponding `redistribute vnc-direct` statement. The default for both bgp and zebra is mode `none`. -.. index:: vnc export bgp|zebra group-nve group GROUP-NAME .. clicmd:: vnc export bgp|zebra group-nve group GROUP-NAME -.. index:: vnc export bgp|zebra group-nve no group GROUP-NAME .. clicmd:: vnc export bgp|zebra group-nve no group GROUP-NAME When export mode is `group-nve`, export (or do not export) prefixes from the @@ -702,14 +657,12 @@ manually and dynamically added information. `local-next-hop` parameter is used to delete specific local nexthop information. -.. index:: clear vnc mac (\\*|xx:xx:xx:xx:xx:xx) virtual-network-identifier (\\*|(1-4294967295)) (\\*|[(vn|un) (A.B.C.D|X:X::X:X|\\*) [(un|vn) (A.B.C.D|X:X::X:X|\*)] [prefix (\\*|A.B.C.D/M|X:X::X:X/M)]) .. clicmd:: clear vnc mac (\*|xx:xx:xx:xx:xx:xx) virtual-network-identifier (\*|(1-4294967295)) (\*|[(vn|un) (A.B.C.D|X:X::X:X|\*) [(un|vn) (A.B.C.D|X:X::X:X|\*)] [prefix (\*|A.B.C.D/M|X:X::X:X/M)]) Delete mac forwarding information. Any or all of these parameters may be wildcarded to (potentially) match more than one registration. The default value for the `prefix` parameter is the wildcard value `*`. -.. index:: clear vnc nve (\*|((vn|un) (A.B.C.D|X:X::X:X) [(un|vn) (A.B.C.D|X:X::X:X)])) .. clicmd:: clear vnc nve (\*|((vn|un) (A.B.C.D|X:X::X:X) [(un|vn) (A.B.C.D|X:X::X:X)])) Delete prefixes associated with the NVE specified by the given VN and UN @@ -729,24 +682,20 @@ running-configuration` command when in `enable` mode. The following commands are used to clear and display Virtual Network Control related information: -.. index:: clear vnc counters .. clicmd:: clear vnc counters Reset the counter values stored by the NVA. Counter values can be seen using the `show vnc` commands listed above. This command is only available in `enable` mode. -.. index:: show vnc summary .. clicmd:: show vnc summary Print counter values and other general information about the NVA. Counter values can be reset using the `clear vnc counters` command listed below. -.. index:: show vnc nves .. clicmd:: show vnc nves -.. index:: show vnc nves vn|un ADDRESS .. clicmd:: show vnc nves vn|un ADDRESS Display the NVA's current clients. Specifying `address` limits the output to @@ -754,10 +703,8 @@ related information: communicated with the NVE, per-NVE summary counters and each NVE's addresses will be displayed. -.. index:: show vnc queries .. clicmd:: show vnc queries -.. index:: show vnc queries PREFIX .. clicmd:: show vnc queries PREFIX Display active Query information. Queries remain valid for the default @@ -768,10 +715,8 @@ related information: Query information is provided for each querying NVE, and includes the Query Target and the time remaining before the information is removed. -.. index:: show vnc registrations [all|local|remote|holddown|imported] .. clicmd:: show vnc registrations [all|local|remote|holddown|imported] -.. index:: show vnc registrations [all|local|remote|holddown|imported] PREFIX .. clicmd:: show vnc registrations [all|local|remote|holddown|imported] PREFIX Display local, remote, holddown, and/or imported registration information. @@ -791,10 +736,8 @@ related information: registrations, the amount of time remaining before the information is removed. -.. index:: show vnc responses [active|removed] .. clicmd:: show vnc responses [active|removed] -.. index:: show vnc responses [active|removed] PREFIX .. clicmd:: show vnc responses [active|removed] PREFIX Display all, active and/or removed response information which are @@ -811,7 +754,6 @@ related information: the administrative cost, the provided response lifetime and the time remaining before the information is to be removed or will become inactive. -.. index:: show memory vnc .. clicmd:: show memory vnc Print the number of memory items allocated by the NVA. diff --git a/doc/user/vrrp.rst b/doc/user/vrrp.rst index a39bd53844..44a56f2fca 100644 --- a/doc/user/vrrp.rst +++ b/doc/user/vrrp.rst @@ -358,30 +358,26 @@ using VRRPv2. All interface configuration commands are documented below. -.. index:: vrrp (1-255) [version (2-3)] -.. clicmd:: [no] vrrp (1-255) [version (2-3)] +.. clicmd:: vrrp (1-255) [version (2-3)] Create a VRRP router with the specified VRID on the interface. Optionally specify the protocol version. If the protocol version is not specified, the default is VRRPv3. -.. index:: vrrp (1-255) advertisement-interval (10-40950) -.. clicmd:: [no] vrrp (1-255) advertisement-interval (10-40950) +.. clicmd:: vrrp (1-255) advertisement-interval (10-40950) Set the advertisement interval. This is the interval at which VRRP advertisements will be sent. Values are given in milliseconds, but must be multiples of 10, as VRRP itself uses centiseconds. -.. index:: vrrp (1-255) ip A.B.C.D -.. clicmd:: [no] vrrp (1-255) ip A.B.C.D +.. clicmd:: vrrp (1-255) ip A.B.C.D Add an IPv4 address to the router. This address must already be configured on the appropriate macvlan device. Adding an IP address to the router will implicitly activate the router; see :clicmd:`[no] vrrp (1-255) shutdown` to override this behavior. -.. index:: vrrp (1-255) ipv6 X:X::X:X -.. clicmd:: [no] vrrp (1-255) ipv6 X:X::X:X +.. clicmd:: vrrp (1-255) ipv6 X:X::X:X Add an IPv6 address to the router. This address must already be configured on the appropriate macvlan device. Adding an IP address to the router will @@ -391,23 +387,20 @@ All interface configuration commands are documented below. This command will fail if the protocol version is set to VRRPv2, as VRRPv2 does not support IPv6. -.. index:: vrrp (1-255) preempt -.. clicmd:: [no] vrrp (1-255) preempt +.. clicmd:: vrrp (1-255) preempt Toggle preempt mode. When enabled, preemption allows Backup routers with higher priority to take over Master status from the existing Master. Enabled by default. -.. index:: vrrp (1-255) priority (1-254) -.. clicmd:: [no] vrrp (1-255) priority (1-254) +.. clicmd:: vrrp (1-255) priority (1-254) Set the router priority. The router with the highest priority is elected as the Master. If all routers in the VRRP virtual router are configured with the same priority, the router with the highest primary IP address is elected as the Master. Priority value 255 is reserved for the acting Master router. -.. index:: vrrp (1-255) shutdown -.. clicmd:: [no] vrrp (1-255) shutdown +.. clicmd:: vrrp (1-255) shutdown Place the router into administrative shutdown. VRRP will not activate for this router until this command is removed with the ``no`` form. @@ -419,7 +412,6 @@ Global Configuration Show commands, global defaults and debugging configuration commands. -.. index:: show vrrp [interface INTERFACE] [(1-255)] [json] .. clicmd:: show vrrp [interface INTERFACE] [(1-255)] [json] Shows VRRP status for some or all configured VRRP routers. Specifying an @@ -427,8 +419,7 @@ Show commands, global defaults and debugging configuration commands. VRID will only show routers with that VRID. Specifying ``json`` will dump each router state in a JSON array. -.. index:: debug vrrp [{protocol|autoconfigure|packets|sockets|ndisc|arp|zebra}] -.. clicmd:: [no] debug vrrp [{protocol|autoconfigure|packets|sockets|ndisc|arp|zebra}] +.. clicmd:: debug vrrp [{protocol|autoconfigure|packets|sockets|ndisc|arp|zebra}] Toggle debugging logs for VRRP components. If no component is specified, debugging for all components are turned on/off. @@ -457,8 +448,7 @@ Show commands, global defaults and debugging configuration commands. zebra Logs communications with Zebra. -.. index:: vrrp default <advertisement-interval (1-4096)|preempt|priority (1-254)|shutdown> -.. clicmd:: [no] vrrp default <advertisement-interval (1-4096)|preempt|priority (1-254)|shutdown> +.. clicmd:: vrrp default <advertisement-interval (1-4096)|preempt|priority (1-254)|shutdown> Configure defaults for new VRRP routers. These values will not affect already configured VRRP routers, but will be applied to newly configured @@ -480,8 +470,7 @@ After configuring the interfaces as described in :ref:`vrrp-system-configuration`, and configuring any defaults you may want, execute the following command: -.. index:: vrrp autoconfigure [version (2-3)] -.. clicmd:: [no] vrrp autoconfigure [version (2-3)] +.. clicmd:: vrrp autoconfigure [version (2-3)] Generates VRRP configuration based on the interface configuration on the base system. If the protocol version is not specified, the default is VRRPv3. diff --git a/doc/user/vtysh.rst b/doc/user/vtysh.rst index b1339f26e5..ec674e377c 100644 --- a/doc/user/vtysh.rst +++ b/doc/user/vtysh.rst @@ -22,7 +22,6 @@ administrator with an external editor. have effect for vtysh) need to be manually updated in :file:`vtysh.conf`. -.. index:: copy FILENAME running-config .. clicmd:: copy FILENAME running-config Process and load a configuration file manually; each line in the @@ -52,8 +51,7 @@ and the :clicmd:`terminal paginate` command: This variable should be set by the user according to their preferences, in their :file:`~/.profile` file. -.. index:: terminal paginate -.. clicmd:: [no] terminal paginate +.. clicmd:: terminal paginate Enables/disables vtysh output pagination. This command is intended to be placed in :file:`vtysh.conf` to set a system-wide default. If this @@ -100,7 +98,6 @@ could be made SGID (set group ID) to the |INSTALL_VTY_GROUP| group. No security guarantees are made for this configuration. -.. index:: username USERNAME nopassword .. clicmd:: username USERNAME nopassword If PAM support is enabled at build-time, this command allows disabling the @@ -162,11 +159,8 @@ it can lead to /all/ of your daemons being unable to start up. Per daemon files are more robust as impact of errors in configuration are limited to the daemon in whose file the error is made. -.. index:: service integrated-vtysh-config .. clicmd:: service integrated-vtysh-config -.. index:: service integrated-vtysh-config -.. clicmd:: no service integrated-vtysh-config Control whether integrated :file:`frr.conf` file is written when 'write file' is issued. @@ -195,7 +189,6 @@ in whose file the error is made. preset one of the two operating modes and ensure consistent operation across installations. -.. index:: write integrated .. clicmd:: write integrated Unconditionally (regardless of ``service integrated-vtysh-config`` setting) diff --git a/doc/user/watchfrr.rst b/doc/user/watchfrr.rst index b29e602fe5..3a19e3c4fa 100644 --- a/doc/user/watchfrr.rst +++ b/doc/user/watchfrr.rst @@ -16,14 +16,12 @@ require end users management. WATCHFRR commands ================= -.. index:: show watchfrr .. clicmd:: show watchfrr Give status information about the state of the different daemons being watched by WATCHFRR -.. index:: watchfrr ignore DAEMON -.. clicmd:: [no] watchfrr ignore DAEMON +.. clicmd:: watchfrr ignore DAEMON Tell WATCHFRR to ignore a particular DAEMON if it goes unresponsive. This is particularly useful when you are a developer and need to debug diff --git a/doc/user/wecmp_linkbw.rst b/doc/user/wecmp_linkbw.rst index 6e516bcf9f..4df6559e5c 100644 --- a/doc/user/wecmp_linkbw.rst +++ b/doc/user/wecmp_linkbw.rst @@ -173,7 +173,6 @@ ECMP as recommended in [Draft-IETF-idr-link-bandwidth]_. The operator can change these behaviors with the following configuration: -.. index:: bgp bestpath bandwidth <ignore | skip-missing | default-weight-for-missing> .. clicmd:: bgp bestpath bandwidth <ignore | skip-missing | default-weight-for-missing> The different options imply behavior as follows: diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index a9979558c3..e5cd1de201 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -115,44 +115,30 @@ Interface Commands Standard Commands ----------------- -.. index:: interface IFNAME .. clicmd:: interface IFNAME -.. index:: interface IFNAME vrf VRF .. clicmd:: interface IFNAME vrf VRF -.. index:: shutdown .. clicmd:: shutdown -.. index:: shutdown -.. clicmd:: no shutdown Up or down the current interface. -.. index:: ip address ADDRESS/PREFIX .. clicmd:: ip address ADDRESS/PREFIX -.. index:: ipv6 address ADDRESS/PREFIX .. clicmd:: ipv6 address ADDRESS/PREFIX -.. index:: ip address ADDRESS/PREFIX -.. clicmd:: no ip address ADDRESS/PREFIX -.. index:: ipv6 address ADDRESS/PREFIX -.. clicmd:: no ipv6 address ADDRESS/PREFIX Set the IPv4 or IPv6 address/prefix for the interface. -.. index:: ip address LOCAL-ADDR peer PEER-ADDR/PREFIX .. clicmd:: ip address LOCAL-ADDR peer PEER-ADDR/PREFIX -.. index:: ip address LOCAL-ADDR peer PEER-ADDR/PREFIX -.. clicmd:: no ip address LOCAL-ADDR peer PEER-ADDR/PREFIX Configure an IPv4 Point-to-Point address on the interface. (The concept of PtP addressing does not exist for IPv6.) @@ -162,38 +148,28 @@ Standard Commands behind the other end of the link (or even on the link in Point-to-Multipoint setups), though generally /32s are used. -.. index:: description DESCRIPTION ... .. clicmd:: description DESCRIPTION ... Set description for the interface. -.. index:: multicast .. clicmd:: multicast -.. index:: multicast -.. clicmd:: no multicast Enable or disables multicast flag for the interface. -.. index:: bandwidth (1-10000000) .. clicmd:: bandwidth (1-10000000) -.. index:: bandwidth (1-10000000) -.. clicmd:: no bandwidth (1-10000000) Set bandwidth value of the interface in kilobits/sec. This is for calculating OSPF cost. This command does not affect the actual device configuration. -.. index:: link-detect .. clicmd:: link-detect -.. index:: link-detect -.. clicmd:: no link-detect Enable/disable link-detect on platforms which support this. Currently only Linux, and only where network interface drivers support reporting @@ -212,11 +188,8 @@ Link Parameters Commands protocol extensions that can be used with MPLS-TE. FRR does not support a complete RSVP-TE solution currently. -.. index:: link-params .. clicmd:: link-params -.. index:: link-param -.. clicmd:: no link-param Enter into the link parameters sub node. At least 'enable' must be set to activate the link parameters, and consequently routing @@ -228,24 +201,18 @@ Link Parameters Commands Under link parameter statement, the following commands set the different TE values: -.. index:: link-params [enable] .. clicmd:: link-params [enable] Enable link parameters for this interface. -.. index:: link-params [metric (0-4294967295)] .. clicmd:: link-params [metric (0-4294967295)] -.. index:: link-params max-bw BANDWIDTH .. clicmd:: link-params max-bw BANDWIDTH -.. index:: link-params max-rsv-bw BANDWIDTH .. clicmd:: link-params max-rsv-bw BANDWIDTH -.. index:: link-params unrsv-bw (0-7) BANDWIDTH .. clicmd:: link-params unrsv-bw (0-7) BANDWIDTH -.. index:: link-params admin-grp BANDWIDTH .. clicmd:: link-params admin-grp BANDWIDTH These commands specifies the Traffic Engineering parameters of the interface @@ -258,22 +225,16 @@ Link Parameters Commands Note that BANDIWDTH is specified in IEEE floating point format and express in Bytes/second. -.. index:: link-param delay (0-16777215) [min (0-16777215) | max (0-16777215)] .. clicmd:: link-param delay (0-16777215) [min (0-16777215) | max (0-16777215)] -.. index:: link-param delay-variation (0-16777215) .. clicmd:: link-param delay-variation (0-16777215) -.. index:: link-param packet-loss PERCENTAGE .. clicmd:: link-param packet-loss PERCENTAGE -.. index:: link-param res-bw BANDWIDTH .. clicmd:: link-param res-bw BANDWIDTH -.. index:: link-param ava-bw BANDWIDTH .. clicmd:: link-param ava-bw BANDWIDTH -.. index:: link-param use-bw BANDWIDTH .. clicmd:: link-param use-bw BANDWIDTH These command specifies additional Traffic Engineering parameters of the @@ -287,17 +248,14 @@ Link Parameters Commands (µs). Loss is specified in PERCENTAGE ranging from 0 to 50.331642% by step of 0.000003. -.. index:: link-param neighbor <A.B.C.D> as (0-65535) .. clicmd:: link-param neighbor <A.B.C.D> as (0-65535) -.. index:: link-param no neighbor .. clicmd:: link-param no neighbor Specifies the remote ASBR IP address and Autonomous System (AS) number for InterASv2 link in OSPF (RFC5392). Note that this option is not yet supported for ISIS (RFC5316). -.. index:: ip nht resolve-via-default .. clicmd:: ip nht resolve-via-default Allows nexthop tracking to resolve via the default route. This is useful @@ -427,7 +385,6 @@ see https://www.kernel.org/doc/Documentation/networking/vrf.txt. Because of that difference, there are some subtle differences when running some commands in relationship to VRF. Here is an extract of some of those commands: -.. index:: vrf VRF .. clicmd:: vrf VRF This command is available on configuration mode. By default, above command @@ -436,7 +393,6 @@ commands in relationship to VRF. Here is an extract of some of those commands: The network administrator can however decide to provision this command in configuration file to provide more clarity about the intended configuration. -.. index:: netns NAMESPACE .. clicmd:: netns NAMESPACE This command is based on VRF configuration mode. This command is available @@ -447,7 +403,6 @@ commands in relationship to VRF. Here is an extract of some of those commands: decide to provision this command in configuration file to provide more clarity about the intended configuration. -.. index:: show ip route vrf VRF .. clicmd:: show ip route vrf VRF The show command permits dumping the routing table associated to the VRF. If @@ -457,20 +412,17 @@ commands in relationship to VRF. Here is an extract of some of those commands: launched with :option:`-n` option, this will be the default routing table of the *Linux network namespace* ``VRF``. -.. index:: show ip route vrf VRF table TABLENO .. clicmd:: show ip route vrf VRF table TABLENO The show command is only available with :option:`-n` option. This command will dump the routing table ``TABLENO`` of the *Linux network namespace* ``VRF``. -.. index:: show ip route vrf VRF tables .. clicmd:: show ip route vrf VRF tables This command will dump the routing tables within the vrf scope. If `vrf all` is executed, all routing tables will be dumped. -.. index:: show <ip|ipv6> route summary [vrf VRF] [table TABLENO] [prefix] .. clicmd:: show <ip|ipv6> route summary [vrf VRF] [table TABLENO] [prefix] This command will dump a summary output of the specified VRF and TABLENO @@ -537,8 +489,7 @@ The push action is generally used for LER devices, which want to encapsulate all traffic for a wished destination into an MPLS label. This action is stored in routing entry, and can be configured like a route: -.. index:: ip route NETWORK MASK GATEWAY|INTERFACE label LABEL -.. clicmd:: [no] ip route NETWORK MASK GATEWAY|INTERFACE label LABEL +.. clicmd:: ip route NETWORK MASK GATEWAY|INTERFACE label LABEL NETWORK and MASK stand for the IP prefix entry to be added as static route entry. @@ -568,8 +519,7 @@ The swap action is generally used for LSR devices, which swap a packet with a label, with an other label. The Pop action is used on LER devices, at the termination of the MPLS traffic; this is used to remove MPLS header. -.. index:: mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null -.. clicmd:: [no] mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null +.. clicmd:: mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null INCOMING_LABEL and OUTGOING_LABEL are MPLS labels with values ranging from 16 to 1048575. @@ -582,7 +532,6 @@ termination of the MPLS traffic; this is used to remove MPLS header. You can check that the MPLS actions are stored in the zebra MPLS table, by looking at the presence of the entry. -.. index:: show mpls table .. clicmd:: show mpls table :: @@ -616,11 +565,8 @@ WARNING: RPF lookup results are non-responsive in this version of FRR, i.e. multicast routing does not actively react to changes in underlying unicast topology! -.. index:: ip multicast rpf-lookup-mode MODE .. clicmd:: ip multicast rpf-lookup-mode MODE -.. index:: ip multicast rpf-lookup-mode [MODE] -.. clicmd:: no ip multicast rpf-lookup-mode [MODE] MODE sets the method used to perform RPF lookups. Supported modes: @@ -650,10 +596,10 @@ unicast topology! what the default behavior is. .. warning:: + Unreachable routes do not receive special treatment and do not cause fallback to a second lookup. -.. index:: show ip rpf ADDR .. clicmd:: show ip rpf ADDR Performs a Multicast RPF lookup, as configured with ``ip multicast @@ -672,18 +618,14 @@ unicast topology! Indicates that a multicast source lookup for 192.0.2.1 would use an Unicast RIB entry for 192.0.2.0/24 with a gateway of 198.51.100.1. -.. index:: show ip rpf .. clicmd:: show ip rpf Prints the entire Multicast RIB. Note that this is independent of the configured RPF lookup mode, the Multicast RIB may be printed yet not used at all. -.. index:: ip mroute PREFIX NEXTHOP [DISTANCE] .. clicmd:: ip mroute PREFIX NEXTHOP [DISTANCE] -.. index:: ip mroute PREFIX NEXTHOP [DISTANCE] -.. clicmd:: no ip mroute PREFIX NEXTHOP [DISTANCE] Adds a static route entry to the Multicast RIB. This performs exactly as the ``ip route`` command, except that it inserts the route in the Multicast RIB @@ -699,7 +641,6 @@ received from other FRR components. The permit/deny facilities provided by these commands can be used to filter which routes zebra will install in the kernel. -.. index:: ip protocol PROTOCOL route-map ROUTEMAP .. clicmd:: ip protocol PROTOCOL route-map ROUTEMAP Apply a route-map filter to routes for the specified protocol. PROTOCOL can @@ -728,7 +669,6 @@ kernel. on a per vrf basis, by entering this command under vrf mode for the vrf you want to apply the route-map against. -.. index:: set src ADDRESS .. clicmd:: set src ADDRESS Within a route-map, set the preferred source address for matching routes @@ -767,8 +707,7 @@ IPv6 example for OSPFv3. not created at startup. On Debian, FRR might start before ifupdown completes. Consider a reboot test. -.. index:: zebra route-map delay-timer (0-600) -.. clicmd:: [no] zebra route-map delay-timer (0-600) +.. clicmd:: zebra route-map delay-timer (0-600) Set the delay before any route-maps are processed in zebra. The default time for this is 5 seconds. @@ -842,21 +781,11 @@ FPM Commands ``fpm`` implementation ---------------------- -.. index:: fpm connection ip A.B.C.D port (1-65535) .. clicmd:: fpm connection ip A.B.C.D port (1-65535) - Configure ``zebra`` to connect to a different FPM server than - ``127.0.0.1`` port ``2620``. - - -.. index:: fpm connection ip A.B.C.D port (1-65535) -.. clicmd:: no fpm connection ip A.B.C.D port (1-65535) + Configure ``zebra`` to connect to a different FPM server than the default of + ``127.0.0.1:2060`` - Configure ``zebra`` to connect to the default FPM server at ``127.0.0.1`` - port ``2620``. - - -.. index:: show zebra fpm stats .. clicmd:: show zebra fpm stats Shows the FPM statistics. @@ -892,7 +821,6 @@ FPM Commands t_conn_up_finishes 1 0 -.. index:: clear zebra fpm stats .. clicmd:: clear zebra fpm stats Reset statistics related to the zebra code that interacts with the @@ -902,35 +830,22 @@ FPM Commands ``dplane_fpm_nl`` implementation -------------------------------- -.. index:: fpm address <A.B.C.D|X:X::X:X> [port (1-65535)] .. clicmd:: fpm address <A.B.C.D|X:X::X:X> [port (1-65535)] Configures the FPM server address. Once configured ``zebra`` will attempt to connect to it immediately. + The ``no`` form disables FPM entirely. ``zebra`` will close any current + connections and will not attempt to connect to it anymore. -.. index:: fpm address [<A.B.C.D|X:X::X:X> [port (1-65535)]] -.. clicmd:: no fpm address [<A.B.C.D|X:X::X:X> [port (1-65535)]] - - Disables FPM entirely. ``zebra`` will close any current connections and - will not attempt to connect to it anymore. - - -.. index:: fpm use-next-hop-groups .. clicmd:: fpm use-next-hop-groups Use the new netlink messages ``RTM_NEWNEXTHOP`` / ``RTM_DELNEXTHOP`` to group repeated route next hop information. + The ``no`` form uses the old known FPM behavior of including next hop + information in the route (e.g. ``RTM_NEWROUTE``) messages. -.. index:: fpm use-next-hop-groups -.. clicmd:: no fpm use-next-hop-groups - - Use the old known FPM behavior of including next hop information in the - route (e.g. ``RTM_NEWROUTE``) messages. - - -.. index:: show fpm counters [json] .. clicmd:: show fpm counters [json] Show the FPM statistics (plain text or JSON formatted). @@ -955,7 +870,6 @@ FPM Commands User FPM disable requests: 0 -.. index:: clear fpm counters .. clicmd:: clear fpm counters Reset statistics related to the zebra code that interacts with the @@ -974,14 +888,12 @@ interface IP addresses. The dataplane runs in its own pthread, in order to off-load work from the main zebra pthread. -.. index:: show zebra dplane [detailed] .. clicmd:: show zebra dplane [detailed] Display statistics about the updates and events passing through the dataplane subsystem. -.. index:: show zebra dplane providers .. clicmd:: show zebra dplane providers Display information about the running dataplane plugins that are @@ -989,7 +901,6 @@ order to off-load work from the main zebra pthread. present. -.. index:: zebra dplane limit [NUMBER] .. clicmd:: zebra dplane limit [NUMBER] Configure the limit on the number of pending updates that are @@ -999,7 +910,6 @@ order to off-load work from the main zebra pthread. zebra Terminal Mode Commands ============================ -.. index:: show ip route .. clicmd:: show ip route Display current routes which zebra holds in its database. @@ -1016,19 +926,15 @@ zebra Terminal Mode Commands C* 203.181.89.240/28 eth0 -.. index:: show ipv6 route .. clicmd:: show ipv6 route -.. index:: show [ip|ipv6] route [PREFIX] [nexthop-group] .. clicmd:: show [ip|ipv6] route [PREFIX] [nexthop-group] Display detailed information about a route. If [nexthop-group] is included, it will display the nexthop group ID the route is using as well. -.. index:: show interface [NAME] [{vrf VRF|brief}] [nexthop-group] .. clicmd:: show interface [NAME] [{vrf VRF|brief}] [nexthop-group] -.. index:: show interface [NAME] [{vrf all|brief}] [nexthop-group] .. clicmd:: show interface [NAME] [{vrf all|brief}] [nexthop-group] Display interface information. If no extra information is added, it will @@ -1036,34 +942,27 @@ zebra Terminal Mode Commands detailed information about that single interface. If [nexthop-group] is specified, it will display nexthop groups pointing out that interface. -.. index:: show ip prefix-list [NAME] .. clicmd:: show ip prefix-list [NAME] -.. index:: show route-map [NAME] .. clicmd:: show route-map [NAME] -.. index:: show ip protocol .. clicmd:: show ip protocol -.. index:: show ip forward .. clicmd:: show ip forward Display whether the host's IP forwarding function is enabled or not. Almost any UNIX kernel can be configured with IP forwarding disabled. If so, the box can't work as a router. -.. index:: show ipv6 forward .. clicmd:: show ipv6 forward Display whether the host's IP v6 forwarding is enabled or not. -.. index:: show zebra .. clicmd:: show zebra Display various statistics related to the installation and deletion of routes, neighbor updates, and LSP's into the kernel. -.. index:: show zebra client [summary] .. clicmd:: show zebra client [summary] Display statistics about clients that are connected to zebra. This is @@ -1071,7 +970,6 @@ zebra Terminal Mode Commands zebra and it's clients. If the summary form of the command is choosen a table is displayed with shortened information. -.. index:: show zebra router table summary .. clicmd:: show zebra router table summary Display summarized data about tables created, their afi/safi/tableid @@ -1079,7 +977,6 @@ zebra Terminal Mode Commands total number of route nodes in the table. Which will be higher than the actual number of routes that are held. -.. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type] .. clicmd:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type] Display nexthop groups created by zebra. The [vrf NAME] option @@ -1097,34 +994,29 @@ Many routing protocols require a router-id to be configured. To have a consistent router-id across all daemons, the following commands are available to configure and display the router-id: -.. index:: router-id A.B.C.D -.. clicmd:: [no] [ip] router-id A.B.C.D +.. clicmd:: [ip] router-id A.B.C.D Allow entering of the router-id. This command also works under the vrf subnode, to allow router-id's per vrf. -.. index:: router-id A.B.C.D vrf NAME -.. clicmd:: [no] [ip] router-id A.B.C.D vrf NAME +.. clicmd:: [ip] router-id A.B.C.D vrf NAME Configure the router-id of this router from the configure NODE. A show run of this command will display the router-id command under the vrf sub node. This command is deprecated and will be removed at some point in time in the future. -.. index:: show [ip] router-id [vrf NAME] .. clicmd:: show [ip] router-id [vrf NAME] Display the user configured router-id. For protocols requiring an IPv6 router-id, the following commands are available: -.. index:: ipv6 router-id X:X::X:X -.. clicmd:: [no] ipv6 router-id X:X::X:X +.. clicmd:: ipv6 router-id X:X::X:X Configure the IPv6 router-id of this router. Like its IPv4 counterpart, this command works under the vrf subnode, to allow router-id's per vrf. -.. index:: show ipv6 router-id [vrf NAME] .. clicmd:: show ipv6 router-id [vrf NAME] Display the user configured IPv6 router-id. diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c index 5b3a3827a2..3ebac8aaa9 100644 --- a/isisd/isis_lfa.c +++ b/isisd/isis_lfa.c @@ -541,10 +541,16 @@ static int tilfa_repair_list_apply(struct isis_spftree *spftree, struct isis_spf_adj *sadj = vadj->sadj; struct mpls_label_stack *label_stack; + /* + * Don't try to apply the repair list if one was already applied + * before (can't have ECMP past the P-node). + */ + if (vadj->label_stack) + continue; + if (!isis_vertex_adj_exists(spftree, vertex_pnode, sadj)) continue; - assert(!vadj->label_stack); label_stack = tilfa_compute_label_stack(spftree->lspdb, sadj, repair_list); if (!label_stack) { @@ -663,6 +669,21 @@ static int tilfa_build_repair_list(struct isis_spftree *spftree_pc, if ((!is_qnode || spftree_pc->lfa.protected_resource.type == LFA_NODE_PROTECTION) && vertex_child) { + /* + * If vertex is the penultimate hop router, then pushing an + * Adj-SID towards the final hop means that the No-PHP flag of + * the original Prefix-SID must be honored. We do that by + * removing the previously added Prefix-SID from the repair list + * when those conditions are met. + */ + if (vertex->depth == (vertex_dest->depth - 2) + && VTYPE_IP(vertex_dest->type) + && vertex_dest->N.ip.sr.present + && !CHECK_FLAG(vertex_dest->N.ip.sr.sid.flags, + ISIS_PREFIX_SID_NO_PHP)) { + list_delete_all_node(repair_list); + } + label_qnode = tilfa_find_qnode_adj_sid(spftree_pc, vertex->N.id, vertex_child->N.id); if (label_qnode == MPLS_INVALID_LABEL) { diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 6d2303817b..a17d9a6ae2 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -691,8 +691,8 @@ static void lsp_set_time(struct isis_lsp *lsp) stream_putw_at(lsp->pdu, 10, lsp->hdr.rem_lifetime); } -void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag, - struct isis *isis) +void lspid_print(uint8_t *lsp_id, char *dest, size_t dest_len, char dynhost, + char frag, struct isis *isis) { struct isis_dynhn *dyn = NULL; char id[SYSID_STRLEN]; @@ -710,10 +710,10 @@ void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag, memcpy(id, sysid_print(lsp_id), 15); if (frag) - sprintf(dest, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id), - LSP_FRAGMENT(lsp_id)); + snprintf(dest, dest_len, "%s.%02x-%02x", id, + LSP_PSEUDO_ID(lsp_id), LSP_FRAGMENT(lsp_id)); else - sprintf(dest, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id)); + snprintf(dest, dest_len, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id)); } /* Convert the lsp attribute bits to attribute string */ @@ -747,7 +747,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost, char age_out[8]; char b[200]; - lspid_print(lsp->hdr.lsp_id, LSPid, dynhost, 1, isis); + lspid_print(lsp->hdr.lsp_id, LSPid, sizeof(LSPid), dynhost, 1, isis); vty_out(vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' '); vty_out(vty, "%5hu ", lsp->hdr.pdu_len); vty_out(vty, "0x%08x ", lsp->hdr.seqno); diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 0783036e49..896d957607 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -116,8 +116,8 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, struct isis_tlvs *tlvs, struct stream *stream, struct isis_area *area, int level, bool confusion); void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno); -void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag, - struct isis *isis); +void lspid_print(uint8_t *lsp_id, char *dest, size_t dest_len, char dynhost, + char frag, struct isis *isis); void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost, struct isis *isis); void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost, diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 6e9cbaf98e..d3d081d376 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -59,27 +59,30 @@ char nlpidstring[30]; const char *isonet_print(const uint8_t *from, int len) { int i = 0; - char *pos = isonet; + char tbuf[4]; + isonet[0] = '\0'; if (!from) return "unknown"; while (i < len) { if (i & 1) { - sprintf(pos, "%02x", *(from + i)); - pos += 2; + snprintf(tbuf, sizeof(tbuf), "%02x", *(from + i)); + strlcat(isonet, tbuf, sizeof(isonet)); } else { if (i == (len - 1)) { /* No dot at the end of address */ - sprintf(pos, "%02x", *(from + i)); - pos += 2; + snprintf(tbuf, sizeof(tbuf), "%02x", + *(from + i)); + strlcat(isonet, tbuf, sizeof(isonet)); } else { - sprintf(pos, "%02x.", *(from + i)); - pos += 3; + snprintf(tbuf, sizeof(tbuf), "%02x.", + *(from + i)); + strlcat(isonet, tbuf, sizeof(isonet)); } } i++; } - *(pos) = '\0'; + return isonet; } @@ -202,17 +205,18 @@ const char *nlpid2str(uint8_t nlpid) char *nlpid2string(struct nlpids *nlpids) { - char *pos = nlpidstring; int i; + char tbuf[256]; + nlpidstring[0] = '\0'; for (i = 0; i < nlpids->count; i++) { - pos += sprintf(pos, "%s", nlpid2str(nlpids->nlpids[i])); + snprintf(tbuf, sizeof(tbuf), "%s", + nlpid2str(nlpids->nlpids[i])); + strlcat(nlpidstring, tbuf, sizeof(nlpidstring)); if (nlpids->count - i > 1) - pos += sprintf(pos, ", "); + strlcat(nlpidstring, ", ", sizeof(nlpidstring)); } - *(pos) = '\0'; - return nlpidstring; } @@ -359,34 +363,47 @@ const char *isis_format_id(const uint8_t *id, size_t len) const char *time2string(uint32_t time) { - char *pos = datestring; uint32_t rest; + char tbuf[32]; + datestring[0] = '\0'; if (time == 0) return "-"; - if (time / SECS_PER_YEAR) - pos += sprintf(pos, "%uY", time / SECS_PER_YEAR); + if (time / SECS_PER_YEAR) { + snprintf(tbuf, sizeof(tbuf), "%uY", time / SECS_PER_YEAR); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = time % SECS_PER_YEAR; - if (rest / SECS_PER_MONTH) - pos += sprintf(pos, "%uM", rest / SECS_PER_MONTH); + if (rest / SECS_PER_MONTH) { + snprintf(tbuf, sizeof(tbuf), "%uM", rest / SECS_PER_MONTH); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = rest % SECS_PER_MONTH; - if (rest / SECS_PER_WEEK) - pos += sprintf(pos, "%uw", rest / SECS_PER_WEEK); + if (rest / SECS_PER_WEEK) { + snprintf(tbuf, sizeof(tbuf), "%uw", rest / SECS_PER_WEEK); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = rest % SECS_PER_WEEK; - if (rest / SECS_PER_DAY) - pos += sprintf(pos, "%ud", rest / SECS_PER_DAY); + if (rest / SECS_PER_DAY) { + snprintf(tbuf, sizeof(tbuf), "%ud", rest / SECS_PER_DAY); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = rest % SECS_PER_DAY; - if (rest / SECS_PER_HOUR) - pos += sprintf(pos, "%uh", rest / SECS_PER_HOUR); + if (rest / SECS_PER_HOUR) { + snprintf(tbuf, sizeof(tbuf), "%uh", rest / SECS_PER_HOUR); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = rest % SECS_PER_HOUR; - if (rest / SECS_PER_MINUTE) - pos += sprintf(pos, "%um", rest / SECS_PER_MINUTE); + if (rest / SECS_PER_MINUTE) { + snprintf(tbuf, sizeof(tbuf), "%um", rest / SECS_PER_MINUTE); + strlcat(datestring, tbuf, sizeof(datestring)); + } rest = rest % SECS_PER_MINUTE; - if (rest) - pos += sprintf(pos, "%us", rest); - - *(pos) = 0; + if (rest) { + snprintf(tbuf, sizeof(tbuf), "%us", rest); + strlcat(datestring, tbuf, sizeof(datestring)); + } return datestring; } diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index d0a411a8db..6055984195 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -118,7 +118,7 @@ static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp, char lspid[255]; char buf[MONOTIME_STRLEN]; - lspid_print(lsp->hdr.lsp_id, lspid, true, true, isis); + lspid_print(lsp->hdr.lsp_id, lspid, sizeof(lspid), true, true, isis); vty_out(vty, "Flooding information for %s\n", lspid); if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) { diff --git a/lib/agentx.c b/lib/agentx.c index 5351f8bda2..c8d7d75a81 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -36,6 +36,8 @@ XREF_SETUP() +DEFINE_HOOK(agentx_enabled, (), ()) + static int agentx_enabled = 0; static struct thread_master *agentx_tm; @@ -226,6 +228,7 @@ DEFUN (agentx_enable, events = list_new(); agentx_events_update(); agentx_enabled = 1; + hook_call(agentx_enabled); } return CMD_SUCCESS; @@ -259,6 +262,16 @@ void smux_init(struct thread_master *tm) install_element(CONFIG_NODE, &no_agentx_cmd); } +void smux_agentx_enable(void) +{ + if (!agentx_enabled) { + init_snmp(FRR_SMUX_NAME); + events = list_new(); + agentx_events_update(); + agentx_enabled = 1; + } +} + void smux_register_mib(const char *descr, struct variable *var, size_t width, int num, oid name[], size_t namelen) { diff --git a/lib/nexthop.c b/lib/nexthop.c index b2fa945690..dd8c108205 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -739,6 +739,16 @@ static ssize_t printfrr_nh(char *buf, size_t bsz, const char *fmt, const char *s, *v_is = "", *v_via = "", *v_viaif = "via "; ssize_t ret = 3; + /* NULL-check */ + if (nexthop == NULL) { + if (fmt[2] == 'v' && fmt[3] == 'v') + ret++; + + strlcpy(buf, "NULL", bsz); + + return ret; + } + switch (fmt[2]) { case 'v': if (fmt[3] == 'v') { diff --git a/lib/northbound.c b/lib/northbound.c index ecfa2c9d11..224951b22b 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -185,6 +185,25 @@ struct nb_node *nb_node_find(const char *xpath) return snode->priv; } +void nb_node_set_dependency_cbs(const char *dependency_xpath, + const char *dependant_xpath, + struct nb_dependency_callbacks *cbs) +{ + struct nb_node *dependency = nb_node_find(dependency_xpath); + struct nb_node *dependant = nb_node_find(dependant_xpath); + + if (!dependency || !dependant) + return; + + dependency->dep_cbs.get_dependant_xpath = cbs->get_dependant_xpath; + dependant->dep_cbs.get_dependency_xpath = cbs->get_dependency_xpath; +} + +bool nb_node_has_dependency(struct nb_node *node) +{ + return node->dep_cbs.get_dependency_xpath != NULL; +} + static int nb_node_validate_cb(const struct nb_node *nb_node, enum nb_operation operation, int callback_implemented, bool optional) @@ -532,8 +551,9 @@ int nb_candidate_edit(struct nb_config *candidate, const struct yang_data *previous, const struct yang_data *data) { - struct lyd_node *dnode; + struct lyd_node *dnode, *dep_dnode; char xpath_edit[XPATH_MAXLEN]; + char dep_xpath[XPATH_MAXLEN]; /* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */ if (nb_node->snode->nodetype == LYS_LEAFLIST) @@ -549,9 +569,33 @@ int nb_candidate_edit(struct nb_config *candidate, dnode = lyd_new_path(candidate->dnode, ly_native_ctx, xpath_edit, (void *)data->value, 0, LYD_PATH_OPT_UPDATE); - if (!dnode && ly_errno) { - flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed", - __func__); + if (dnode) { + /* + * create dependency + * + * dnode returned by the lyd_new_path may be from a + * different schema, so we need to update the nb_node + */ + nb_node = dnode->schema->priv; + if (nb_node->dep_cbs.get_dependency_xpath) { + nb_node->dep_cbs.get_dependency_xpath( + dnode, dep_xpath); + + ly_errno = 0; + dep_dnode = lyd_new_path(candidate->dnode, + ly_native_ctx, + dep_xpath, NULL, 0, + LYD_PATH_OPT_UPDATE); + if (!dep_dnode && ly_errno) { + flog_warn(EC_LIB_LIBYANG, + "%s: lyd_new_path(%s) failed", + __func__, dep_xpath); + return NB_ERR; + } + } + } else if (ly_errno) { + flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed", + __func__, xpath_edit); return NB_ERR; } break; @@ -563,6 +607,14 @@ int nb_candidate_edit(struct nb_config *candidate, * whether to ignore it or not. */ return NB_ERR_NOT_FOUND; + /* destroy dependant */ + if (nb_node->dep_cbs.get_dependant_xpath) { + nb_node->dep_cbs.get_dependant_xpath(dnode, dep_xpath); + + dep_dnode = yang_dnode_get(candidate->dnode, dep_xpath); + if (dep_dnode) + lyd_free(dep_dnode); + } lyd_free(dnode); break; case NB_OP_MOVE: diff --git a/lib/northbound.h b/lib/northbound.h index 8dd6b4c337..3e1342f985 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -509,6 +509,11 @@ struct nb_callbacks { void (*cli_show_end)(struct vty *vty, struct lyd_node *dnode); }; +struct nb_dependency_callbacks { + void (*get_dependant_xpath)(const struct lyd_node *dnode, char *xpath); + void (*get_dependency_xpath)(const struct lyd_node *dnode, char *xpath); +}; + /* * Northbound-specific data that is allocated for each schema node of the native * YANG modules. @@ -523,6 +528,8 @@ struct nb_node { /* Priority - lower priorities are processed first. */ uint32_t priority; + struct nb_dependency_callbacks dep_cbs; + /* Callbacks implemented for this node. */ struct nb_callbacks cbs; @@ -722,6 +729,12 @@ void nb_nodes_delete(void); */ extern struct nb_node *nb_node_find(const char *xpath); +extern void nb_node_set_dependency_cbs(const char *dependency_xpath, + const char *dependant_xpath, + struct nb_dependency_callbacks *cbs); + +bool nb_node_has_dependency(struct nb_node *node); + /* * Create a new northbound configuration. * diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 1416b758d8..a2c8bc8633 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -1906,7 +1906,6 @@ void nb_cli_init(struct thread_master *tm) if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL) { install_element(ENABLE_NODE, &config_exclusive_cmd); install_element(ENABLE_NODE, &config_private_cmd); - install_element(ENABLE_NODE, &show_config_running_cmd); install_element(ENABLE_NODE, &show_config_compare_without_candidate_cmd); install_element(ENABLE_NODE, &show_config_transaction_cmd); @@ -1919,6 +1918,7 @@ void nb_cli_init(struct thread_master *tm) } /* Other commands. */ + install_element(ENABLE_NODE, &show_config_running_cmd); install_element(CONFIG_NODE, &yang_module_translator_load_cmd); install_element(CONFIG_NODE, &yang_module_translator_unload_cmd); install_element(ENABLE_NODE, &show_yang_operational_data_cmd); diff --git a/lib/prefix.c b/lib/prefix.c index 663a87afde..c98e0c1c72 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1160,7 +1160,7 @@ in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen) ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16" ex.) "1.0.0.0" NULL => "1.0.0.0/8" */ int netmask_str2prefix_str(const char *net_str, const char *mask_str, - char *prefix_str) + char *prefix_str, size_t prefix_str_len) { struct in_addr network; struct in_addr mask; @@ -1193,7 +1193,7 @@ int netmask_str2prefix_str(const char *net_str, const char *mask_str, return 0; } - sprintf(prefix_str, "%s/%d", net_str, prefixlen); + snprintf(prefix_str, prefix_str_len, "%s/%d", net_str, prefixlen); return 1; } diff --git a/lib/prefix.h b/lib/prefix.h index b7fdc26369..b2f3b0592f 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -491,7 +491,7 @@ extern void masklen2ip(const int, struct in_addr *); * special treatment for /31 according to RFC3021 section 3.3 */ extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen); -extern int netmask_str2prefix_str(const char *, const char *, char *); +extern int netmask_str2prefix_str(const char *, const char *, char *, size_t); extern struct prefix_ipv6 *prefix_ipv6_new(void); extern void prefix_ipv6_free(struct prefix_ipv6 **p); diff --git a/lib/routing_nb.h b/lib/routing_nb.h index d1b59ea29e..ffba631a10 100644 --- a/lib/routing_nb.h +++ b/lib/routing_nb.h @@ -15,10 +15,17 @@ int routing_control_plane_protocols_control_plane_protocol_destroy( #define FRR_ROUTING_KEY_XPATH \ "/frr-routing:routing/control-plane-protocols/" \ "control-plane-protocol[type='%s'][name='%s'][vrf='%s']" + +#define FRR_ROUTING_KEY_XPATH_VRF \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[vrf='%s']" + /* * callbacks for routing to handle configuration events * based on the control plane protocol */ DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args)) +void routing_control_plane_protocols_register_vrf_dependency(void); + #endif /* _FRR_ROUTING_NB_H_ */ diff --git a/lib/routing_nb_config.c b/lib/routing_nb_config.c index b789e8494e..17698d2b87 100644 --- a/lib/routing_nb_config.c +++ b/lib/routing_nb_config.c @@ -45,15 +45,21 @@ int routing_control_plane_protocols_control_plane_protocol_create( case NB_EV_ABORT: break; case NB_EV_APPLY: - vrfname = yang_dnode_get_string(args->dnode, "./vrf"); - vrf = vrf_lookup_by_name(vrfname); - vrf = vrf ? vrf : vrf_get(VRF_UNKNOWN, vrfname); - if (!vrf) { - flog_warn(EC_LIB_NB_CB_CONFIG_APPLY, - "vrf creation %s failed", vrfname); - return NB_ERR; + /* + * If the daemon relies on the VRF pointer stored in this + * dnode, then it should register the dependency between this + * module and the VRF module using + * routing_control_plane_protocols_register_vrf_dependency. + * If such dependency is not registered, then nothing is + * stored in the dnode. If the dependency is registered, + * find the vrf and store the pointer. + */ + if (nb_node_has_dependency(args->dnode->schema->priv)) { + vrfname = yang_dnode_get_string(args->dnode, "./vrf"); + vrf = vrf_lookup_by_name(vrfname); + assert(vrf); + nb_running_set_entry(args->dnode, vrf); } - nb_running_set_entry(args->dnode, vrf); break; }; @@ -63,12 +69,45 @@ int routing_control_plane_protocols_control_plane_protocol_create( int routing_control_plane_protocols_control_plane_protocol_destroy( struct nb_cb_destroy_args *args) { - struct vrf *vrf __attribute__((unused)); - if (args->event != NB_EV_APPLY) return NB_OK; - vrf = nb_running_unset_entry(args->dnode); + /* + * If dependency on VRF module is registered, then VRF + * pointer was stored and must be cleared. + */ + if (nb_node_has_dependency(args->dnode->schema->priv)) + nb_running_unset_entry(args->dnode); return NB_OK; } + +static void vrf_to_control_plane_protocol(const struct lyd_node *dnode, + char *xpath) +{ + const char *vrf; + + vrf = yang_dnode_get_string(dnode, "./name"); + + snprintf(xpath, XPATH_MAXLEN, FRR_ROUTING_KEY_XPATH_VRF, vrf); +} + +static void control_plane_protocol_to_vrf(const struct lyd_node *dnode, + char *xpath) +{ + const char *vrf; + + vrf = yang_dnode_get_string(dnode, "./vrf"); + + snprintf(xpath, XPATH_MAXLEN, FRR_VRF_KEY_XPATH, vrf); +} + +void routing_control_plane_protocols_register_vrf_dependency(void) +{ + struct nb_dependency_callbacks cbs; + + cbs.get_dependant_xpath = vrf_to_control_plane_protocol; + cbs.get_dependency_xpath = control_plane_protocol_to_vrf; + + nb_node_set_dependency_cbs(FRR_VRF_XPATH, FRR_ROUTING_XPATH, &cbs); +} diff --git a/lib/smux.h b/lib/smux.h index 11c1becd60..a263478a2e 100644 --- a/lib/smux.h +++ b/lib/smux.h @@ -25,6 +25,7 @@ #include <net-snmp/agent/snmp_vars.h> #include "thread.h" +#include "hook.h" #ifdef __cplusplus extern "C" { @@ -103,6 +104,7 @@ struct index_oid { #define SNMP_IP6ADDRESS(V) (*var_len = sizeof(struct in6_addr), (uint8_t *)&V) extern void smux_init(struct thread_master *tm); +extern void smux_agentx_enable(void); extern void smux_register_mib(const char *, struct variable *, size_t, int, oid[], size_t); extern int smux_header_generic(struct variable *, oid[], size_t *, int, @@ -151,6 +153,8 @@ extern void oid_copy_int(oid oid[], int *val); extern void oid2string(oid oid[], int len, char *string); extern void oid_copy_str(oid oid[], const char *string, int len); +DECLARE_HOOK(agentx_enabled, (), ()) + #ifdef __cplusplus } #endif @@ -686,8 +686,8 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, } if (vty) { - snprintf(xpath_list, sizeof(xpath_list), - "/frr-vrf:lib/vrf[name='%s']", vrfname); + snprintf(xpath_list, sizeof(xpath_list), FRR_VRF_KEY_XPATH, + vrfname); nb_cli_enqueue_change(vty, xpath_list, NB_OP_CREATE, NULL); ret = nb_cli_apply_changes(vty, xpath_list); @@ -821,8 +821,7 @@ DEFUN_YANG (no_vrf, return CMD_WARNING_CONFIG_FAILED; } - snprintf(xpath_list, sizeof(xpath_list), "/frr-vrf:lib/vrf[name='%s']", - vrfname); + snprintf(xpath_list, sizeof(xpath_list), FRR_VRF_KEY_XPATH, vrfname); nb_cli_enqueue_change(vty, xpath_list, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, xpath_list); @@ -52,6 +52,9 @@ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX }; #define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n" #define VRF_FULL_CMD_HELP_STR "Specify the VRF\nThe VRF name\nAll VRFs\n" +#define FRR_VRF_XPATH "/frr-vrf:lib/vrf" +#define FRR_VRF_KEY_XPATH "/frr-vrf:lib/vrf[name='%s']" + /* * Pass some OS specific data up through * to the daemons @@ -2427,9 +2427,9 @@ bool vty_read_config(struct nb_config *config, const char *config_file, __func__, errno); goto tmp_free_and_out; } - tmp = XMALLOC(MTYPE_TMP, - strlen(cwd) + strlen(config_file) + 2); - sprintf(tmp, "%s/%s", cwd, config_file); + size_t tmp_len = strlen(cwd) + strlen(config_file) + 2; + tmp = XMALLOC(MTYPE_TMP, tmp_len); + snprintf(tmp, tmp_len, "%s/%s", cwd, config_file); fullpath = tmp; } else fullpath = config_file; diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index abcdb40547..f6a246500b 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -1292,6 +1292,7 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, { struct ospf6_inter_prefix_lsa *prefix_lsa; struct in6_addr in6; + char tbuf[16]; if (lsa != NULL) { prefix_lsa = @@ -1301,8 +1302,9 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, ospf6_prefix_in6_addr(&in6, prefix_lsa, &prefix_lsa->prefix); if (buf) { inet_ntop(AF_INET6, &in6, buf, buflen); - sprintf(&buf[strlen(buf)], "/%d", - prefix_lsa->prefix.prefix_length); + snprintf(tbuf, sizeof(tbuf), "/%d", + prefix_lsa->prefix.prefix_length); + strlcat(buf, tbuf, buflen); } } diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 3449f48267..d0c93dd577 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1865,6 +1865,7 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa, struct ospf6_as_external_lsa *external; struct in6_addr in6; int prefix_length = 0; + char tbuf[16]; if (lsa) { external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( @@ -1885,9 +1886,11 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa, } if (buf) { inet_ntop(AF_INET6, &in6, buf, buflen); - if (prefix_length) - sprintf(&buf[strlen(buf)], "/%d", - prefix_length); + if (prefix_length) { + snprintf(tbuf, sizeof(tbuf), "/%d", + prefix_length); + strlcat(buf, tbuf, buflen); + } } } return (buf); diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 5394ba9786..2cffc3a397 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -84,7 +84,7 @@ static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf, sizeof(buf1)); inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf2, sizeof(buf2)); - sprintf(buf, "%s/%s", buf2, buf1); + snprintf(buf, buflen, "%s/%s", buf2, buf1); return buf; } @@ -866,6 +866,7 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, struct in6_addr in6; int prefixnum, cnt = 0; struct ospf6_prefix *prefix; + char tbuf[16]; if (lsa) { intra_prefix_lsa = @@ -898,8 +899,9 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, OSPF6_PREFIX_SPACE( prefix->prefix_length)); inet_ntop(AF_INET6, &in6, buf, buflen); - sprintf(&buf[strlen(buf)], "/%d", - prefix->prefix_length); + snprintf(tbuf, sizeof(tbuf), "/%d", + prefix->prefix_length); + strlcat(buf, tbuf, buflen); return (buf); } } diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index f1b04c9bec..e1c3b4038c 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -145,7 +145,7 @@ const char *ospf6_lstype_short_name(uint16_t type) const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); - if (handler && handler != &unknown_handler) + if (handler) return handler->lh_short_name; snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type)); @@ -420,9 +420,10 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa, if (use_json) json_obj = json_object_new_object(); - if ((type == OSPF6_LSTYPE_INTER_PREFIX) - || (type == OSPF6_LSTYPE_INTER_ROUTER) - || (type == OSPF6_LSTYPE_AS_EXTERNAL)) { + switch (type) { + case OSPF6_LSTYPE_INTER_PREFIX: + case OSPF6_LSTYPE_INTER_ROUTER: + case OSPF6_LSTYPE_AS_EXTERNAL: if (use_json) { json_object_string_add( json_obj, "type", @@ -447,7 +448,13 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa, (unsigned long)ntohl(lsa->header->seqnum), handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0)); - } else if (type != OSPF6_LSTYPE_UNKNOWN) { + break; + case OSPF6_LSTYPE_ROUTER: + case OSPF6_LSTYPE_NETWORK: + case OSPF6_LSTYPE_GROUP_MEMBERSHIP: + case OSPF6_LSTYPE_TYPE_7: + case OSPF6_LSTYPE_LINK: + case OSPF6_LSTYPE_INTRA_PREFIX: while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL) { if (use_json) { @@ -481,7 +488,8 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa, } if (use_json) json_object_free(json_obj); - } else { + break; + default: if (use_json) { json_object_string_add( json_obj, "type", @@ -500,6 +508,7 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa, ospf6_lstype_short_name(lsa->header->type), id, adv_router, ospf6_lsa_age_current(lsa), (unsigned long)ntohl(lsa->header->seqnum)); + break; } } diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index f94252991c..b3c71462a3 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -649,14 +649,10 @@ static int ospf6_spf_calculation_thread(struct thread *t) ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf)); if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) - zlog_debug("SPF runtime: %lld sec %lld usec", - (long long)runtime.tv_sec, - (long long)runtime.tv_usec); - - zlog_info( - "SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, Reason: %s", - areas_processed, (long long)runtime.tv_sec, - (long long)runtime.tv_usec, rbuf); + zlog_debug( + "SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, Reason: %s", + areas_processed, (long long)runtime.tv_sec, + (long long)runtime.tv_usec, rbuf); ospf6->last_spf_reason = ospf6->spf_reason; ospf6_reset_spf_reason(ospf6); @@ -718,9 +714,7 @@ void ospf6_spf_schedule(struct ospf6 *ospf6, unsigned int reason) } if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) - zlog_debug("SPF: calculation timer delay = %ld", delay); - - zlog_info("SPF: Scheduled in %ld msec", delay); + zlog_debug("SPF: Rescheduling in %ld msec", delay); ospf6->t_spf_calc = NULL; thread_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6, diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index b98852eeee..19829d4546 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -616,7 +616,7 @@ DEFUN (debug_ospf_packet, if (inst) // user passed instance ID { - if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10))) + if (inst != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -692,7 +692,7 @@ DEFUN (no_debug_ospf_packet, if (inst) // user passed instance ID { - if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10))) + if (inst != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -763,7 +763,7 @@ DEFUN (debug_ospf_ism, if (inst) // user passed instance ID { - if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10))) + if (inst != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -814,7 +814,7 @@ DEFUN (no_debug_ospf_ism, if (inst) // user passed instance ID { - if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10))) + if (inst != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -909,8 +909,8 @@ DEFUN (debug_ospf_instance_nsm, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; return debug_ospf_nsm_common(vty, 4, argc, argv); } @@ -981,7 +981,7 @@ DEFUN (no_debug_ospf_instance_nsm, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; return no_debug_ospf_nsm_common(vty, 5, argc, argv); @@ -1062,7 +1062,7 @@ DEFUN (debug_ospf_instance_lsa, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; return debug_ospf_lsa_common(vty, 4, argc, argv); @@ -1145,7 +1145,7 @@ DEFUN (no_debug_ospf_instance_lsa, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; return no_debug_ospf_lsa_common(vty, 5, argc, argv); @@ -1207,7 +1207,7 @@ DEFUN (debug_ospf_instance_zebra, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; return debug_ospf_zebra_common(vty, 4, argc, argv); @@ -1271,8 +1271,8 @@ DEFUN (no_debug_ospf_instance_zebra, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; return no_debug_ospf_zebra_common(vty, 5, argc, argv); } @@ -1317,8 +1317,8 @@ DEFUN (debug_ospf_instance_event, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; if (vty->node == CONFIG_NODE) CONF_DEBUG_ON(event, EVENT); @@ -1339,8 +1339,8 @@ DEFUN (no_debug_ospf_instance_event, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; if (vty->node == CONFIG_NODE) CONF_DEBUG_OFF(event, EVENT); @@ -1387,8 +1387,8 @@ DEFUN (debug_ospf_instance_nssa, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; if (vty->node == CONFIG_NODE) CONF_DEBUG_ON(nssa, NSSA); @@ -1409,8 +1409,8 @@ DEFUN (no_debug_ospf_instance_nssa, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance(instance)) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; if (vty->node == CONFIG_NODE) CONF_DEBUG_OFF(nssa, NSSA); @@ -1625,12 +1625,12 @@ DEFUN (no_debug_ospf, return CMD_SUCCESS; } -static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf) +static int show_debugging_ospf_common(struct vty *vty) { int i; - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + if (ospf_instance) + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf_instance); vty_out(vty, "OSPF debugging status:\n"); @@ -1742,13 +1742,7 @@ DEFUN_NOSH (show_debugging_ospf, DEBUG_STR OSPF_STR) { - struct ospf *ospf = NULL; - - ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL) - return CMD_SUCCESS; - - return show_debugging_ospf_common(vty, ospf); + return show_debugging_ospf_common(vty); } DEFUN_NOSH (show_debugging_ospf_instance, @@ -1760,14 +1754,13 @@ DEFUN_NOSH (show_debugging_ospf_instance, "Instance ID\n") { int idx_number = 3; - struct ospf *ospf; unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL) - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; - return show_debugging_ospf_common(vty, ospf); + return show_debugging_ospf_common(vty); } static int config_write_debug(struct vty *vty); @@ -1790,16 +1783,11 @@ static int config_write_debug(struct vty *vty) "", " send", " recv", "", " detail", " send detail", " recv detail", " detail"}; - struct ospf *ospf; char str[16]; memset(str, 0, 16); - ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL) - return CMD_SUCCESS; - - if (ospf->instance) - snprintf(str, sizeof(str), " %u", ospf->instance); + if (ospf_instance) + snprintf(str, sizeof(str), " %u", ospf_instance); /* debug ospf ism (status|events|timers). */ if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM) diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 6be5486b55..6a90dbff11 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -146,9 +146,6 @@ FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT, /* OSPFd main routine. */ int main(int argc, char **argv) { - unsigned short instance = 0; - bool created = false; - #ifdef SUPPORT_OSPF_API /* OSPF apiserver is disabled by default. */ ospf_apiserver_enable = 0; @@ -169,8 +166,8 @@ int main(int argc, char **argv) switch (opt) { case 'n': - ospfd_di.instance = instance = atoi(optarg); - if (instance < 1) + ospfd_di.instance = ospf_instance = atoi(optarg); + if (ospf_instance < 1) exit(0); break; case 0: @@ -208,7 +205,7 @@ int main(int argc, char **argv) /* OSPFd inits. */ ospf_if_init(); - ospf_zebra_init(master, instance); + ospf_zebra_init(master, ospf_instance); /* OSPF vty inits. */ ospf_vty_init(); @@ -227,17 +224,6 @@ int main(int argc, char **argv) /* OSPF errors init */ ospf_error_init(); - /* - * Need to initialize the default ospf structure, so the interface mode - * commands can be duly processed if they are received before 'router - * ospf', when ospfd is restarted - */ - if (instance && !ospf_get_instance(instance, &created)) { - flog_err(EC_OSPF_INIT_FAIL, "OSPF instance init failed: %s", - strerror(errno)); - exit(1); - } - frr_config_fork(); frr_run(master); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4132452069..2ff59ccf49 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -140,44 +140,37 @@ int ospf_oi_count(struct interface *ifp) all_vrf = strmatch(vrf_name, "all"); \ } -static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty, - struct cmd_token *argv[], - const int argc, uint32_t enable, - unsigned short *instance) +static int ospf_router_cmd_parse(struct vty *vty, struct cmd_token *argv[], + const int argc, unsigned short *instance, + const char **vrf_name) { - struct ospf *ospf = NULL; int idx_vrf = 0, idx_inst = 0; - const char *vrf_name = NULL; - bool created = false; *instance = 0; - if (argv_find(argv, argc, "(1-65535)", &idx_inst)) + if (argv_find(argv, argc, "(1-65535)", &idx_inst)) { + if (ospf_instance == 0) { + vty_out(vty, + "%% OSPF is not running in instance mode\n"); + return CMD_WARNING_CONFIG_FAILED; + } + *instance = strtoul(argv[idx_inst]->arg, NULL, 10); + } + *vrf_name = NULL; if (argv_find(argv, argc, "vrf", &idx_vrf)) { - vrf_name = argv[idx_vrf + 1]->arg; - if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME)) - vrf_name = NULL; - if (enable) { - /* Allocate VRF aware instance */ - ospf = ospf_get(*instance, vrf_name, &created); - } else { - ospf = ospf_lookup_by_inst_name(*instance, vrf_name); - } - } else { - if (enable) { - ospf = ospf_get(*instance, NULL, &created); - } else { - ospf = ospf_lookup_instance(*instance); + if (ospf_instance != 0) { + vty_out(vty, + "%% VRF is not supported in instance mode\n"); + return CMD_WARNING_CONFIG_FAILED; } - } - if (created) { - if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) - SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); + *vrf_name = argv[idx_vrf + 1]->arg; + if (*vrf_name && strmatch(*vrf_name, VRF_DEFAULT_NAME)) + *vrf_name = NULL; } - return ospf; + return CMD_SUCCESS; } static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty, @@ -213,28 +206,35 @@ DEFUN_NOSH (router_ospf, "Instance ID\n" VRF_CMD_HELP_STR) { - struct ospf *ospf = NULL; - int ret = CMD_SUCCESS; - unsigned short instance = 0; + unsigned short instance; + const char *vrf_name; + bool created = false; + struct ospf *ospf; + int ret; - ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance); - if (!ospf) - return CMD_WARNING_CONFIG_FAILED; + ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name); + if (ret != CMD_SUCCESS) + return ret; - /* The following logic to set the vty qobj index is in place to be able - to ignore the commands which dont belong to this instance. */ - if (ospf->instance != instance) { + if (instance != ospf_instance) { VTY_PUSH_CONTEXT_NULL(OSPF_NODE); - ret = CMD_NOT_MY_INSTANCE; - } else { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "Config command 'router ospf %d' received, vrf %s id %u oi_running %u", - instance, ospf->name ? ospf->name : "NIL", - ospf->vrf_id, ospf->oi_running); - VTY_PUSH_CONTEXT(OSPF_NODE, ospf); + return CMD_NOT_MY_INSTANCE; } + ospf = ospf_get(instance, vrf_name, &created); + + if (created) + if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Config command 'router ospf %d' received, vrf %s id %u oi_running %u", + ospf->instance, ospf->name ? ospf->name : "NIL", + ospf->vrf_id, ospf->oi_running); + + VTY_PUSH_CONTEXT(OSPF_NODE, ospf); + return ret; } @@ -247,19 +247,25 @@ DEFUN (no_router_ospf, "Instance ID\n" VRF_CMD_HELP_STR) { + unsigned short instance; + const char *vrf_name; struct ospf *ospf; - unsigned short instance = 0; + int ret; - ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance); - if (ospf == NULL) { - if (instance) - return CMD_NOT_MY_INSTANCE; - else - return CMD_WARNING; - } - ospf_finish(ospf); + ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name); + if (ret != CMD_SUCCESS) + return ret; - return CMD_SUCCESS; + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + + ospf = ospf_lookup(instance, vrf_name); + if (ospf) + ospf_finish(ospf); + else + ret = CMD_WARNING_CONFIG_FAILED; + + return ret; } @@ -3381,11 +3387,11 @@ DEFUN (show_ip_ospf_instance, json_object *json = NULL; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) @@ -4131,11 +4137,11 @@ DEFUN (show_ip_ospf_instance_interface, json_object *json = NULL; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) @@ -4526,11 +4532,11 @@ DEFUN (show_ip_ospf_instance_neighbor, int ret = CMD_SUCCESS; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) @@ -4741,11 +4747,11 @@ DEFUN (show_ip_ospf_instance_neighbor_all, int ret = CMD_SUCCESS; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) json = json_object_new_object(); @@ -4881,11 +4887,11 @@ DEFUN (show_ip_ospf_instance_neighbor_int, show_ip_ospf_neighbour_header(vty); instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (!uj) @@ -5359,11 +5365,11 @@ DEFPY (show_ip_ospf_instance_neighbor_id, { struct ospf *ospf; - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json, @@ -5532,11 +5538,11 @@ DEFUN (show_ip_ospf_instance_neighbor_detail, int ret = CMD_SUCCESS; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) @@ -5727,11 +5733,11 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all, int ret = CMD_SUCCESS; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; if (uj) @@ -5859,11 +5865,11 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail, bool uj = use_json(argc, argv); instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname, @@ -7136,10 +7142,11 @@ DEFUN (show_ip_ospf_instance_database, if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; return (show_ip_ospf_database_common( @@ -7212,15 +7219,12 @@ DEFUN (show_ip_ospf_instance_database_max, json = json_object_new_object(); instance = strtoul(argv[idx_number]->arg, NULL, 10); - - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) { - vty_out(vty, "%% OSPF instance not found\n"); + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; - } show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0, json, uj); @@ -7355,13 +7359,12 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) { - vty_out(vty, "%% OSPF instance not found\n"); + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; - } return (show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); @@ -8819,7 +8822,7 @@ DEFUN (ip_ospf_area, else ospf = ospf_lookup_instance(instance); - if (instance && ospf == NULL) { + if (instance && instance != ospf_instance) { /* * At this point we know we have received * an instance and there is no ospf instance @@ -8944,7 +8947,7 @@ DEFUN (no_ip_ospf_area, else ospf = ospf_lookup_instance(instance); - if (instance && ospf == NULL) + if (instance && instance != ospf_instance) return CMD_NOT_MY_INSTANCE; argv_find(argv, argc, "area", &idx); @@ -10918,11 +10921,11 @@ DEFUN (show_ip_ospf_instance_border_routers, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; return show_ip_ospf_border_routers_common(vty, ospf, 0); @@ -11086,11 +11089,11 @@ DEFUN (show_ip_ospf_instance_route, unsigned short instance = 0; instance = strtoul(argv[idx_number]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) return CMD_SUCCESS; return show_ip_ospf_route_common(vty, ospf, NULL, 0); @@ -11189,8 +11192,7 @@ DEFPY (clear_ip_ospf_neighbor, */ if (instance != 0) { /* This means clear only the particular ospf process */ - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -11220,8 +11222,7 @@ DEFPY (clear_ip_ospf_process, /* Check if instance is not passed as an argument */ if (instance != 0) { /* This means clear only the particular ospf process */ - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance != ospf_instance) return CMD_NOT_MY_INSTANCE; } @@ -11545,7 +11546,6 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) struct ospf_if_params *params; const char *auth_str; int write = 0; - struct ospf *ospf = vrf->info; FOR_ALL_INTERFACES (vrf, ifp) { @@ -11698,9 +11698,9 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) /* Area print. */ if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { - if (ospf && ospf->instance) + if (ospf_instance) vty_out(vty, " ip ospf %d", - ospf->instance); + ospf_instance); else vty_out(vty, " ip ospf"); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 04397d50a5..9590a9c73b 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -70,6 +70,8 @@ static struct ospf_master ospf_master; /* OSPF process wide configuration pointer to export. */ struct ospf_master *om; +unsigned short ospf_instance; + extern struct zclient *zclient; @@ -511,36 +513,28 @@ static void ospf_init(struct ospf *ospf) ospf_router_id_update(ospf); } -struct ospf *ospf_get(unsigned short instance, const char *name, bool *created) +struct ospf *ospf_lookup(unsigned short instance, const char *name) { struct ospf *ospf; - /* vrf name provided call inst and name based api - * in case of no name pass default ospf instance */ - if (name) + if (ospf_instance) { + ospf = ospf_lookup_instance(instance); + } else { ospf = ospf_lookup_by_inst_name(instance, name); - else - ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - - *created = (ospf == NULL); - if (ospf == NULL) { - ospf = ospf_new(instance, name); - ospf_add(ospf); - - ospf_init(ospf); } return ospf; } -struct ospf *ospf_get_instance(unsigned short instance, bool *created) +struct ospf *ospf_get(unsigned short instance, const char *name, bool *created) { struct ospf *ospf; - ospf = ospf_lookup_instance(instance); + ospf = ospf_lookup(instance, name); + *created = (ospf == NULL); if (ospf == NULL) { - ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/); + ospf = ospf_new(instance, name); ospf_add(ospf); ospf_init(ospf); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 954a469b68..5148bf555c 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -633,6 +633,7 @@ struct ospf_nbr_nbma { /* Extern variables. */ extern struct ospf_master *om; +extern unsigned short ospf_instance; extern const int ospf_redistributed_proto_max; extern struct zclient *zclient; extern struct thread_master *master; @@ -642,10 +643,10 @@ extern struct zebra_privs_t ospfd_privs; /* Prototypes. */ extern const char *ospf_redist_string(unsigned int route_type); extern struct ospf *ospf_lookup_instance(unsigned short); +extern struct ospf *ospf_lookup(unsigned short instance, const char *name); extern struct ospf *ospf_get(unsigned short instance, const char *name, bool *created); extern struct ospf *ospf_new_alloc(unsigned short instance, const char *name); -extern struct ospf *ospf_get_instance(unsigned short, bool *created); extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name); extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id); diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 9c11cc47d5..5a09e7a8ee 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -145,6 +145,8 @@ int main(int argc, char **argv, char **envp) hook_register(routing_conf_event, routing_control_plane_protocols_name_validate); + routing_control_plane_protocols_register_vrf_dependency(); + frr_config_fork(); #ifdef PIM_DEBUG_BYDEFAULT diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 4bc78529a8..11cfe09964 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -2394,6 +2394,13 @@ int lib_interface_pim_address_family_mroute_oif_modify( struct ipaddr group_addr; const struct lyd_node *if_dnode; + iif = nb_running_get_entry(args->dnode, NULL, true); + pim_iifp = iif->info; + pim = pim_iifp->pim; + + oifname = yang_dnode_get_string(args->dnode, NULL); + oif = if_lookup_by_name(oifname, pim->vrf_id); + switch (args->event) { case NB_EV_VALIDATE: if_dnode = yang_dnode_get_parent(args->dnode, "interface"); @@ -2402,18 +2409,20 @@ int lib_interface_pim_address_family_mroute_oif_modify( "%% Enable PIM and/or IGMP on this interface first"); return NB_ERR_VALIDATION; } + +#ifdef PIM_ENFORCE_LOOPFREE_MFC + if (iif->ifindex == oif->ifindex) { + strlcpy(args->errmsg, + "% IIF same as OIF and loopfree enforcement is enabled; rejecting", + args->errmsg_len); + return NB_ERR_VALIDATION; + } +#endif break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - iif = nb_running_get_entry(args->dnode, NULL, true); - pim_iifp = iif->info; - pim = pim_iifp->pim; - - oifname = yang_dnode_get_string(args->dnode, NULL); - oif = if_lookup_by_name(oifname, pim->vrf_id); - if (!oif) { snprintf(args->errmsg, args->errmsg_len, "No such interface name %s", diff --git a/staticd/static_main.c b/staticd/static_main.c index ac8f8ff029..560814771d 100644 --- a/staticd/static_main.c +++ b/staticd/static_main.c @@ -164,6 +164,8 @@ int main(int argc, char **argv, char **envp) hook_register(routing_conf_event, routing_control_plane_protocols_name_validate); + routing_control_plane_protocols_register_vrf_dependency(); + snprintf(backup_config_file, sizeof(backup_config_file), "%s/zebra.conf", frr_sysconfdir); staticd_di.backup_config_file = backup_config_file; diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index 024f7256e0..bdd5b2e439 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -3146,9 +3146,9 @@ rt3 TE-IS 50 rt5 - rt5(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------------
- 10.0.255.3/32 60 - rt5 16050/18/16030
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.3/32 60 - rt5 16050/18
P-space (self):
rt2
@@ -3194,9 +3194,9 @@ rt3 TE-IS 50 rt5 - rt5(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------------
- 2001:db8::3/128 60 - rt5 16051/19/16031
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::3/128 60 - rt5 16051/19
test# test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1
P-space (self):
@@ -3236,7 +3236,7 @@ IS-IS L1 IPv4 routing table: Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------------
- 10.0.255.4/32 65 - rt2 16020/18/16040
+ 10.0.255.4/32 65 - rt2 16020/18
10.0.255.5/32 75 - rt2 16020/18/16050
10.0.255.6/32 75 - rt2 16020/18/16060
@@ -3277,7 +3277,7 @@ IS-IS L1 IPv6 routing table: Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------------
- 2001:db8::4/128 65 - rt2 16021/19/16041
+ 2001:db8::4/128 65 - rt2 16021/19
2001:db8::5/128 75 - rt2 16021/19/16051
2001:db8::6/128 75 - rt2 16021/19/16061
@@ -3508,7 +3508,7 @@ IS-IS L1 IPv4 routing table: -----------------------------------------------------------
10.0.255.2/32 100 - rt3 16050/17/16020
10.0.255.4/32 90 - rt3 16050/17/16040
- 10.0.255.6/32 80 - rt3 16050/17/16060
+ 10.0.255.6/32 80 - rt3 16050/17
10.0.255.8/32 90 - rt3 16050/17/16080
test# test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only
@@ -3553,7 +3553,7 @@ IS-IS L1 IPv4 routing table: Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------------
- 10.0.255.6/32 100 - rt2 16050/17/16060
+ 10.0.255.6/32 100 - rt2 16050/17
10.0.255.8/32 110 - rt2 16050/17/16080
test# test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only
@@ -3865,7 +3865,7 @@ IS-IS L1 IPv4 routing table: 10.0.255.1/32 100 - rt5 16110/17/16010
10.0.255.4/32 90 - rt5 16110/17/16040
10.0.255.7/32 80 - rt5 16110/17/16070
- 10.0.255.10/32 70 - rt5 16110/17/16100
+ 10.0.255.10/32 70 - rt5 16110/17
test# test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only
P-space (self):
@@ -3979,9 +3979,9 @@ rt3 TE-IS 120 rt2 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------------
- 10.0.255.3/32 130 - rt2 16040/18/16030
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.3/32 130 - rt2 16040/18
P-space (self):
rt2
@@ -4030,9 +4030,9 @@ rt3 TE-IS 120 rt2 - rt4(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------------
- 2001:db8::3/128 130 - rt2 16041/19/16031
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::3/128 130 - rt2 16041/19
test# test isis topology 9 root rt1 ti-lfa system-id rt2
P-space (self):
@@ -4079,7 +4079,7 @@ IS-IS L1 IPv4 routing table: Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------------
10.0.255.2/32 130 - rt3 16030/18/16020
- 10.0.255.4/32 120 - rt3 16030/18/16040
+ 10.0.255.4/32 120 - rt3 16030/18
10.0.255.5/32 130 - rt3 16030/18/16050
10.0.255.6/32 150 - rt3 16030/18/16060
10.0.255.7/32 150 - rt3 16030/18/16070
@@ -4130,7 +4130,7 @@ IS-IS L1 IPv6 routing table: Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------------
2001:db8::2/128 130 - rt3 16031/19/16021
- 2001:db8::4/128 120 - rt3 16031/19/16041
+ 2001:db8::4/128 120 - rt3 16031/19
2001:db8::5/128 130 - rt3 16031/19/16051
2001:db8::6/128 150 - rt3 16031/19/16061
2001:db8::7/128 150 - rt3 16031/19/16071
@@ -4213,9 +4213,9 @@ IS-IS L1 IPv4 routing table: 10.0.255.3/32 80 - rt6 16060/16/16030
- rt7 16070/16/16030
- rt8 16080/16/16030
- 10.0.255.4/32 50 - rt6 16060/16/16040
- - rt7 16070/16/16040
- - rt8 16080/16/16040
+ 10.0.255.4/32 50 - rt6 16060/16
+ - rt7 16070/16
+ - rt8 16080/16
10.0.255.5/32 60 - rt6 16060/16/16050
- rt7 16070/16/16050
- rt8 16080/16/16050
@@ -4295,9 +4295,9 @@ IS-IS L1 IPv6 routing table: 2001:db8::3/128 80 - rt6 16061/17/16031
- rt7 16071/17/16031
- rt8 16081/17/16031
- 2001:db8::4/128 50 - rt6 16061/17/16041
- - rt7 16071/17/16041
- - rt8 16081/17/16041
+ 2001:db8::4/128 50 - rt6 16061/17
+ - rt7 16071/17
+ - rt8 16081/17
2001:db8::5/128 60 - rt6 16061/17/16051
- rt7 16071/17/16051
- rt8 16081/17/16051
@@ -4351,9 +4351,9 @@ rt3 TE-IS 50 rt5 - rt1(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------------
- 10.0.255.8/32 60 - rt5 16040/26/16080
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.8/32 60 - rt5 16040/26
P-space (self):
rt1
@@ -4403,9 +4403,9 @@ rt3 TE-IS 50 rt5 - rt1(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------------
- 2001:db8::8/128 60 - rt5 16041/27/16081
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::8/128 60 - rt5 16041/27
test# test isis topology 10 root rt1 ti-lfa system-id rt2
P-space (self):
@@ -4460,8 +4460,8 @@ IS-IS L1 IPv4 routing table: - rt4 16070/18/16020
10.0.255.5/32 100 - rt3 20060/18/16050
- rt4 16070/18/16050
- 10.0.255.8/32 90 - rt3 20060/18/16080
- - rt4 16070/18/16080
+ 10.0.255.8/32 90 - rt3 20060/18
+ - rt4 16070/18
P-space (self):
rt3
@@ -4515,8 +4515,8 @@ IS-IS L1 IPv6 routing table: - rt4 16071/19/16021
2001:db8::5/128 100 - rt3 20061/19/16051
- rt4 16071/19/16051
- 2001:db8::8/128 90 - rt3 20061/19/16081
- - rt4 16071/19/16081
+ 2001:db8::8/128 90 - rt3 20061/19
+ - rt4 16071/19
test# test isis topology 10 root rt1 ti-lfa system-id rt4
P-space (self):
@@ -4563,7 +4563,7 @@ IS-IS L1 IPv4 routing table: Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------------
10.0.255.4/32 100 - rt2 16080/20/16040
- 10.0.255.7/32 90 - rt2 16080/20/16070
+ 10.0.255.7/32 90 - rt2 16080/20
P-space (self):
rt2
@@ -4609,7 +4609,7 @@ IS-IS L1 IPv6 routing table: Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------------
2001:db8::4/128 100 - rt2 16081/21/16041
- 2001:db8::7/128 90 - rt2 16081/21/16071
+ 2001:db8::7/128 90 - rt2 16081/21
test# test isis topology 11 root rt2 ti-lfa system-id rt4
P-space (self):
@@ -4747,12 +4747,12 @@ rt3 TE-IS 740 rt2 - rt5(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------------------
- 10.0.255.3/32 750 - rt2 16080/17/16/16/16030
- 10.0.255.5/32 350 - rt2 16080/17/16/16050
- 10.0.255.7/32 150 - rt2 16080/17/16070
- 10.0.255.9/32 160 - rt2 16080/17/18/16090
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.3/32 750 - rt2 16080/17/16/16
+ 10.0.255.5/32 350 - rt2 16080/17/16
+ 10.0.255.7/32 150 - rt2 16080/17
+ 10.0.255.9/32 160 - rt2 16080/17/18
test# test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only
P-space (self):
diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py index f7ed29782d..afe546d502 100644 --- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py +++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py @@ -352,7 +352,7 @@ def test_converge_protocols(): actual = ( net["r%s" % i] .cmd( - 'vtysh -c "show ip route" | sed -e \'/^Codes: /,/^\s*$/d\' | env LC_ALL=en_US.UTF-8 sort 2> /dev/null' + "vtysh -c \"show ip route\" | sed -e '/^Codes: /,/^\s*$/d' | env LC_ALL=en_US.UTF-8 sort 2> /dev/null" ) .rstrip() ) @@ -383,7 +383,7 @@ def test_converge_protocols(): actual = ( net["r%s" % i] .cmd( - 'vtysh -c "show ipv6 route" | sed -e \'/^Codes: /,/^\s*$/d\' | env LC_ALL=en_US.UTF-8 sort 2> /dev/null' + "vtysh -c \"show ipv6 route\" | sed -e '/^Codes: /,/^\s*$/d' | env LC_ALL=en_US.UTF-8 sort 2> /dev/null" ) .rstrip() ) diff --git a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py index 4c3bad1280..560d6eebec 100644 --- a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py +++ b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py @@ -44,7 +44,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -pytestmark = [pytest.mark.bfdd] +pytestmark = [pytest.mark.bgpd, pytest.mark.bfdd] + class BFDTopo(Topo): "Test topology builder" @@ -65,6 +66,7 @@ class BFDTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) + def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDTopo, mod.__name__) diff --git a/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py b/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py index bb930141ac..fcb5672dce 100644 --- a/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py +++ b/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py @@ -92,6 +92,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.bfdd, pytest.mark.isisd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py b/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py index 9ce14dd75e..ae148f948c 100755 --- a/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py +++ b/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py @@ -92,6 +92,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.bfdd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py index 76e9ef247f..4a2c8ee002 100644 --- a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py +++ b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py @@ -45,7 +45,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -pytestmark = [pytest.mark.bfdd, pytest.mark.isisd, pytest.mark.ospfd] +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.ospfd] + class BFDProfTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-topo1/test_bfd_topo1.py b/tests/topotests/bfd-topo1/test_bfd_topo1.py index 76078b5d7d..86bdcfed04 100644 --- a/tests/topotests/bfd-topo1/test_bfd_topo1.py +++ b/tests/topotests/bfd-topo1/test_bfd_topo1.py @@ -45,7 +45,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -pytestmark = [pytest.mark.bfdd] +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd] + class BFDTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-topo2/test_bfd_topo2.py b/tests/topotests/bfd-topo2/test_bfd_topo2.py index c31cc02b3a..e85b2644dd 100644 --- a/tests/topotests/bfd-topo2/test_bfd_topo2.py +++ b/tests/topotests/bfd-topo2/test_bfd_topo2.py @@ -46,7 +46,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -pytestmark = [pytest.mark.bfdd, pytest.mark.ospfd] +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd, pytest.mark.ospfd] + class BFDTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-topo3/test_bfd_topo3.py b/tests/topotests/bfd-topo3/test_bfd_topo3.py index f473b67108..6bb223e203 100644 --- a/tests/topotests/bfd-topo3/test_bfd_topo3.py +++ b/tests/topotests/bfd-topo3/test_bfd_topo3.py @@ -45,6 +45,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd] + class BFDTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py b/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py index a238ff8da3..8a1ffe085d 100644 --- a/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py +++ b/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py @@ -46,7 +46,8 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -pytestmark = [pytest.mark.bfdd] +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd] + class BFDTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bgp-aggregator-zero/__init__.py b/tests/topotests/bgp-aggregator-zero/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/__init__.py diff --git a/tests/topotests/bgp-aggregator-zero/exabgp.env b/tests/topotests/bgp-aggregator-zero/exabgp.env new file mode 100644 index 0000000000..28e642360a --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/exabgp.env @@ -0,0 +1,53 @@ +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp-aggregator-zero/peer1/exabgp.cfg b/tests/topotests/bgp-aggregator-zero/peer1/exabgp.cfg new file mode 100644 index 0000000000..b3f25272d2 --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/peer1/exabgp.cfg @@ -0,0 +1,18 @@ +neighbor 10.0.0.1 { + router-id 10.0.0.2; + local-address 10.0.0.2; + local-as 65001; + peer-as 65534; + + static { + route 192.168.100.101/32 { + aggregator (0:10.0.0.2); + next-hop 10.0.0.2; + } + + route 192.168.100.102/32 { + aggregator (65001:10.0.0.2); + next-hop 10.0.0.2; + } + } +} diff --git a/tests/topotests/bgp-aggregator-zero/r1/bgpd.conf b/tests/topotests/bgp-aggregator-zero/r1/bgpd.conf new file mode 100644 index 0000000000..002a5c78c0 --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/r1/bgpd.conf @@ -0,0 +1,6 @@ +! +router bgp 65534 + no bgp ebgp-requires-policy + neighbor 10.0.0.2 remote-as external + neighbor 10.0.0.2 timers 3 10 +! diff --git a/tests/topotests/bgp-aggregator-zero/r1/zebra.conf b/tests/topotests/bgp-aggregator-zero/r1/zebra.conf new file mode 100644 index 0000000000..22a26ac610 --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/r1/zebra.conf @@ -0,0 +1,6 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp-aggregator-zero/test_bgp_aggregator_zero.py b/tests/topotests/bgp-aggregator-zero/test_bgp_aggregator_zero.py new file mode 100644 index 0000000000..c4bbdce2c3 --- /dev/null +++ b/tests/topotests/bgp-aggregator-zero/test_bgp_aggregator_zero.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if BGP UPDATE with AGGREGATOR AS attribute with value zero (0) +is continued to be processed, but AGGREGATOR attribute is discarded. +""" + +import os +import sys +import json +import time +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, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + +pytestmark = [pytest.mark.bgpd] + + +class BgpAggregatorAsnZero(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + r1 = tgen.add_router("r1") + peer1 = tgen.add_exabgp_peer( + "peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1" + ) + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(peer1) + + +def setup_module(mod): + tgen = Topogen(BgpAggregatorAsnZero, mod.__name__) + tgen.start_topology() + + router = tgen.gears["r1"] + router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf")) + router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf")) + router.start() + + peer = tgen.gears["peer1"] + peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env")) + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_aggregator_zero(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_converge(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip bgp neighbor 10.0.0.2 json") + ) + expected = { + "10.0.0.2": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r1"]) + + def _bgp_has_correct_aggregator_route_with_asn_0(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip bgp 192.168.100.101/32 json") + ) + + if "aggregatorAs" in output["paths"][0].keys(): + return False + else: + return True + + assert ( + _bgp_has_correct_aggregator_route_with_asn_0() is True + ), 'Aggregator AS attribute with ASN 0 found in "{}"'.format(tgen.gears["r1"]) + + def _bgp_has_correct_aggregator_route_with_good_asn(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip bgp 192.168.100.102/32 json") + ) + expected = {"paths": [{"aggregatorAs": 65001, "aggregatorId": "10.0.0.2"}]} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_has_correct_aggregator_route_with_good_asn) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Aggregator AS attribute not found in "{}"'.format( + tgen.gears["r1"] + ) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py index b701a0d61e..374cce21f6 100644 --- a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py +++ b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py @@ -91,6 +91,9 @@ from lib.bgp import ( ) from lib.topojson import build_topo_from_json, build_config_from_json +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/bgp_basic_functionality.json".format(CWD) try: diff --git a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py index 353df0684b..dfe6a8074d 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py @@ -324,6 +324,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type): write_test_footer(tc_name) + @pytest.mark.parametrize("ecmp_num", ["8", "16", "32"]) @pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"]) def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): @@ -349,7 +350,7 @@ def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): addr_type, dut, input_dict_1, - next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)], + next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)], protocol=protocol, ) assert result is True, "Testcase {} : Failed \n Error: {}".format( @@ -372,7 +373,7 @@ def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): addr_type, dut, input_dict_1, - next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)], + next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)], protocol=protocol, ) assert result is True, "Testcase {} : Failed \n Error: {}".format( diff --git a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py index 2f73bdb1b8..2bde52af1d 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py @@ -325,6 +325,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type): write_test_footer(tc_name) + @pytest.mark.parametrize("ecmp_num", ["8", "16", "32"]) @pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"]) def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): @@ -350,7 +351,7 @@ def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): addr_type, dut, input_dict_1, - next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)], + next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)], protocol=protocol, ) assert result is True, "Testcase {} : Failed \n Error: {}".format( @@ -373,7 +374,7 @@ def test_ecmp_after_clear_bgp(request, ecmp_num, test_type): addr_type, dut, input_dict_1, - next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)], + next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)], protocol=protocol, ) assert result is True, "Testcase {} : Failed \n Error: {}".format( diff --git a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py index aec78179ff..2744920272 100644 --- a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py +++ b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py @@ -482,7 +482,7 @@ def check_es(dut): curr_es_set.append(esi) types = es["type"] vtep_ips = [] - for vtep in es["vteps"]: + for vtep in es.get("vteps", []): vtep_ips.append(vtep["vtep_ip"]) if "local" in types: @@ -513,7 +513,7 @@ def check_one_es(dut, esi, down_vteps): esi = es["esi"] types = es["type"] vtep_ips = [] - for vtep in es["vteps"]: + for vtep in es.get("vteps", []): vtep_ips.append(vtep["vtep_ip"]) if "local" in types: @@ -593,11 +593,25 @@ def test_evpn_ead_update(): # tgen.mininet_cli() -def check_mac(dut, vni, mac, m_type, esi, intf): +def ping_anycast_gw(tgen): + local_host = tgen.gears["hostd11"] + remote_host = tgen.gears["hostd21"] + + # ping the anycast gw from the local and remote hosts to populate + # the mac address on the PEs + cmd_str = "arping -I torbond -c 1 45.0.0.1" + local_host.run(cmd_str) + remote_host.run(cmd_str) + + +def check_mac(dut, vni, mac, m_type, esi, intf, ping_gw=False, tgen=None): """ checks if mac is present and if desination matches the one provided """ + if ping_gw: + ping_anycast_gw(tgen) + out = dut.vtysh_cmd("show evpn mac vni %d mac %s json" % (vni, mac)) mac_js = json.loads(out) @@ -627,11 +641,6 @@ def test_evpn_mac(): tors.append(tgen.gears["torm11"]) tors.append(tgen.gears["torm12"]) - # ping the anycast gw from the local and remote hosts to populate - # the mac address on the PEs - local_host.run("arping -I torbond -c 1 45.0.0.1") - remote_host.run("arping -I torbond -c 1 45.0.0.1") - vni = 1000 # check if the rack-1 host MAC is present on all rack-1 PEs @@ -642,7 +651,7 @@ def test_evpn_mac(): intf = "hostbond1" for tor in tors: - test_fn = partial(check_mac, tor, vni, mac, m_type, esi, intf) + test_fn = partial(check_mac, tor, vni, mac, m_type, esi, intf, True, tgen) _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) assertmsg = '"{}" local MAC content incorrect'.format(tor.name) assert result is None, assertmsg diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py b/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py index 785a3acbf9..086bad6481 100755 --- a/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py +++ b/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py @@ -47,6 +47,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py b/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py index 5eb1738632..df6c76539c 100755 --- a/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py +++ b/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py @@ -47,6 +47,8 @@ from lib.snmptest import SnmpTester # Required to instantiate the topology builder class. from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.snmp] + class TemplateTopo(Topo): "Test topology builder" @@ -266,7 +268,7 @@ def test_pe1_converge_evpn(): break count += 1 sleep(1) - #tgen.mininet_cli() + # tgen.mininet_cli() assertmsg = "BGP Peer 10.4.4.4 did not connect" assert passed, assertmsg @@ -503,8 +505,10 @@ def test_r1_mplsvpn_VrfTable(): associated_int = r1_snmp.get( "mplsL3VpnVrfAssociatedInterfaces.{}".format(snmp_str_to_oid("VRF-a")) ) - assertmsg = "mplsL3VpnVrfAssociatedInterfaces incorrect should be 3 value {}".format( - associated_int + assertmsg = ( + "mplsL3VpnVrfAssociatedInterfaces incorrect should be 3 value {}".format( + associated_int + ) ) assert associated_int == "3", assertmsg @@ -620,7 +624,7 @@ rte_table_test = { "unknown(0)", "ipv4(1)", "unknown(0)", - ], + ], "mplsL3VpnVrfRteInetCidrNextHop": [ "C0 A8 64 0A", "C0 A8 C8 0A", @@ -649,7 +653,15 @@ rte_table_test = { "bgp(14)", "local(2)", ], - "mplsL3VpnVrfRteInetCidrNextHopAS": ["65001", "65001", "0", "65001", "0", "65001", "0"], + "mplsL3VpnVrfRteInetCidrNextHopAS": [ + "65001", + "65001", + "0", + "65001", + "0", + "65001", + "0", + ], "mplsL3VpnVrfRteInetCidrMetric1": ["0", "0", "20", "0", "0", "0", "0"], "mplsL3VpnVrfRteInetCidrMetric2": ["-1", "-1", "-1", "-1", "-1", "-1", "-1"], "mplsL3VpnVrfRteInetCidrMetric3": ["-1", "-1", "-1", "-1", "-1", "-1", "-1"], @@ -663,7 +675,7 @@ rte_table_test = { "active(1)", "active(1)", "active(1)", - "active(1)", + "active(1)", ], } diff --git a/tests/topotests/bgp_aggregate-address_origin/test_bgp_aggregate-address_origin.py b/tests/topotests/bgp_aggregate-address_origin/test_bgp_aggregate-address_origin.py index 86fd4b601f..be07fab87b 100644 --- a/tests/topotests/bgp_aggregate-address_origin/test_bgp_aggregate-address_origin.py +++ b/tests/topotests/bgp_aggregate-address_origin/test_bgp_aggregate-address_origin.py @@ -47,6 +47,8 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py b/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py index c7d9f13f3f..484f40251f 100644 --- a/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py +++ b/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py @@ -50,6 +50,8 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py index 544bda145c..4d41c7a321 100644 --- a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py +++ b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py @@ -76,6 +76,9 @@ from lib.bgp import ( ) from lib.topojson import build_topo_from_json, build_config_from_json +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/bgp_as_allow_in.json".format(CWD) try: diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py index 02edb62ca0..a736463927 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py +++ b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py @@ -45,6 +45,8 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py b/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py index a856c9278f..6512e4d4c6 100644 --- a/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py +++ b/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py @@ -40,6 +40,8 @@ from lib.topolog import logger from mininet.topo import Topo from lib.common_config import step +pytestmark = [pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py b/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py index fe7052b80f..81bf8da31a 100644 --- a/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py +++ b/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py @@ -45,6 +45,8 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py index f2e54b24d6..6d4a7d82e5 100644 --- a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py @@ -66,6 +66,9 @@ from lib.bgp import ( from lib.topojson import build_topo_from_json, build_config_from_json from copy import deepcopy +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/bgp_communities.json".format(CWD) try: diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py index c0842148f1..3415789068 100644 --- a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py @@ -70,6 +70,9 @@ from lib.bgp import ( from lib.topojson import build_topo_from_json, build_config_from_json from copy import deepcopy +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/bgp_communities_topo2.json".format(CWD) try: diff --git a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py index 5fc4310266..95e63c617e 100644 --- a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py +++ b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py @@ -59,6 +59,8 @@ from mininet.topo import Topo from lib.common_config import step from time import sleep +pytestmark = [pytest.mark.bgpd, pytest.mark.bgpd] + class TemplateTopo(Topo): def build(self, *_args, **_opts): diff --git a/tests/topotests/bgp_features/peer1/exa_readpipe.py b/tests/topotests/bgp_features/peer1/exa_readpipe.py index dba1536388..9e689a27e3 100644 --- a/tests/topotests/bgp_features/peer1/exa_readpipe.py +++ b/tests/topotests/bgp_features/peer1/exa_readpipe.py @@ -8,7 +8,7 @@ if len(sys.argv) != 2: fifo = sys.argv[1] while True: - pipe = open(fifo, 'r') + pipe = open(fifo, "r") with pipe: line = pipe.readline().strip() if line != "": diff --git a/tests/topotests/bgp_features/peer2/exa_readpipe.py b/tests/topotests/bgp_features/peer2/exa_readpipe.py index dba1536388..9e689a27e3 100644 --- a/tests/topotests/bgp_features/peer2/exa_readpipe.py +++ b/tests/topotests/bgp_features/peer2/exa_readpipe.py @@ -8,7 +8,7 @@ if len(sys.argv) != 2: fifo = sys.argv[1] while True: - pipe = open(fifo, 'r') + pipe = open(fifo, "r") with pipe: line = pipe.readline().strip() if line != "": diff --git a/tests/topotests/bgp_features/peer3/exa_readpipe.py b/tests/topotests/bgp_features/peer3/exa_readpipe.py index dba1536388..9e689a27e3 100644 --- a/tests/topotests/bgp_features/peer3/exa_readpipe.py +++ b/tests/topotests/bgp_features/peer3/exa_readpipe.py @@ -8,7 +8,7 @@ if len(sys.argv) != 2: fifo = sys.argv[1] while True: - pipe = open(fifo, 'r') + pipe = open(fifo, "r") with pipe: line = pipe.readline().strip() if line != "": diff --git a/tests/topotests/bgp_features/peer4/exa_readpipe.py b/tests/topotests/bgp_features/peer4/exa_readpipe.py index dba1536388..9e689a27e3 100644 --- a/tests/topotests/bgp_features/peer4/exa_readpipe.py +++ b/tests/topotests/bgp_features/peer4/exa_readpipe.py @@ -8,7 +8,7 @@ if len(sys.argv) != 2: fifo = sys.argv[1] while True: - pipe = open(fifo, 'r') + pipe = open(fifo, "r") with pipe: line = pipe.readline().strip() if line != "": diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/test_bgp_l3vpn_to_bgp_direct.py b/tests/topotests/bgp_l3vpn_to_bgp_direct/test_bgp_l3vpn_to_bgp_direct.py index d863f9c3ed..be12cfde37 100755 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/test_bgp_l3vpn_to_bgp_direct.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/test_bgp_l3vpn_to_bgp_direct.py @@ -31,6 +31,7 @@ from lib.ltemplate import * pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd] + def test_adjacencies(): CliOnFail = None # For debugging, uncomment the next line diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py index d2e40037a6..8bb700235c 100755 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py @@ -31,6 +31,7 @@ from lib.ltemplate import * pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd] + def test_check_linux_vrf(): CliOnFail = None # For debugging, uncomment the next line diff --git a/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py b/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py index d773e87ef6..a3ca1408e2 100755 --- a/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py +++ b/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py @@ -142,7 +142,7 @@ def _bgp_converge_initial(router_name, peer_address, timeout=180): """ Waits for the BGP connection between a given router and a given peer (specified by its IP address) to be established. If the connection is - not established within a given timeout, then an exception is raised. + not established within a given timeout, then an exception is raised. """ tgen = get_topogen() router = tgen.routers()[router_name] diff --git a/tests/topotests/bgp_lu_topo1/test_bgp_lu.py b/tests/topotests/bgp_lu_topo1/test_bgp_lu.py index 61418d7a79..d550c38a2f 100644 --- a/tests/topotests/bgp_lu_topo1/test_bgp_lu.py +++ b/tests/topotests/bgp_lu_topo1/test_bgp_lu.py @@ -45,17 +45,18 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo -#Basic scenario for BGP-LU. Nodes are directly connected. -#Node 3 is advertising many routes to 2, which advertises them -#as BGP-LU to 1; this way we get routes with actual labels, as -#opposed to implicit-null routes in the 2-node case. +# Basic scenario for BGP-LU. Nodes are directly connected. +# Node 3 is advertising many routes to 2, which advertises them +# as BGP-LU to 1; this way we get routes with actual labels, as +# opposed to implicit-null routes in the 2-node case. # # AS1 BGP-LU AS2 iBGP AS2 -#+-----+ +-----+ +-----+ -#| |.1 .2| |.2 .3| | -#| 1 +----------------+ 2 +-----------------+ 3 | -#| | 10.0.0.0/24 | | 10.0.1.0/24 | | -#+-----+ +-----+ +-----+ +# +-----+ +-----+ +-----+ +# | |.1 .2| |.2 .3| | +# | 1 +----------------+ 2 +-----------------+ 3 | +# | | 10.0.0.0/24 | | 10.0.1.0/24 | | +# +-----+ +-----+ +-----+ + class TemplateTopo(Topo): "Test topology builder" @@ -84,7 +85,6 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["R3"]) - def setup_module(mod): "Sets up the pytest environment" # This function initiates the topology build with Topogen... @@ -115,15 +115,19 @@ def teardown_module(mod): # This function tears down the whole topology. tgen.stop_topology() + def check_labelpool(router): json_file = "{}/{}/labelpool.summ.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, router, "show bgp labelpool summary json", expected) + test_func = partial( + topotest.router_json_cmp, router, "show bgp labelpool summary json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) assertmsg = '"{}" JSON output mismatches - Did not converge'.format(router.name) assert result is None, assertmsg - + + def test_converge_bgplu(): "Wait for protocol convergence" @@ -132,13 +136,14 @@ def test_converge_bgplu(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - #tgen.mininet_cli(); + # tgen.mininet_cli(); r1 = tgen.gears["R1"] r2 = tgen.gears["R2"] check_labelpool(r1) check_labelpool(r2) + def test_clear_bgplu(): "Wait for protocol convergence" @@ -147,7 +152,7 @@ def test_clear_bgplu(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - #tgen.mininet_cli(); + # tgen.mininet_cli(); r1 = tgen.gears["R1"] r2 = tgen.gears["R2"] @@ -164,6 +169,7 @@ def test_clear_bgplu(): check_labelpool(r1) check_labelpool(r2) + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/tests/topotests/bgp_rfapi_basic_sanity/test_bgp_rfapi_basic_sanity.py b/tests/topotests/bgp_rfapi_basic_sanity/test_bgp_rfapi_basic_sanity.py index ce69f28aba..fa04aaf366 100755 --- a/tests/topotests/bgp_rfapi_basic_sanity/test_bgp_rfapi_basic_sanity.py +++ b/tests/topotests/bgp_rfapi_basic_sanity/test_bgp_rfapi_basic_sanity.py @@ -31,6 +31,7 @@ from lib.ltemplate import * pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd] + def test_add_routes(): CliOnFail = None # For debugging, uncomment the next line diff --git a/tests/topotests/example-test/test_template.py b/tests/topotests/example-test/test_template.py index 973303b830..0265dbe796 100644 --- a/tests/topotests/example-test/test_template.py +++ b/tests/topotests/example-test/test_template.py @@ -44,7 +44,7 @@ from lib.topolog import logger from mininet.topo import Topo -#TODO: select markers based on daemons used during test +# TODO: select markers based on daemons used during test # pytest module level markers """ pytestmark = pytest.mark.bfdd # single marker diff --git a/tests/topotests/example-topojson-test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py b/tests/topotests/example-topojson-test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py index cd48716905..09ac9f2fa4 100755 --- a/tests/topotests/example-topojson-test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py +++ b/tests/topotests/example-topojson-test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py @@ -54,7 +54,7 @@ from lib.bgp import verify_bgp_convergence from lib.topojson import build_topo_from_json, build_config_from_json -#TODO: select markers based on daemons used during test +# TODO: select markers based on daemons used during test # pytest module level markers """ pytestmark = pytest.mark.bfdd # single marker diff --git a/tests/topotests/example-topojson-test/test_topo_json_single_link/test_example_topojson.py b/tests/topotests/example-topojson-test/test_topo_json_single_link/test_example_topojson.py index 0c72e30044..26336d5de1 100755 --- a/tests/topotests/example-topojson-test/test_topo_json_single_link/test_example_topojson.py +++ b/tests/topotests/example-topojson-test/test_topo_json_single_link/test_example_topojson.py @@ -53,7 +53,7 @@ from lib.bgp import verify_bgp_convergence from lib.topojson import build_topo_from_json, build_config_from_json -#TODO: select markers based on daemons used during test +# TODO: select markers based on daemons used during test # pytest module level markers """ pytestmark = pytest.mark.bfdd # single marker diff --git a/tests/topotests/example-topojson-test/test_topo_json_single_link_loopback/test_example_topojson.py b/tests/topotests/example-topojson-test/test_topo_json_single_link_loopback/test_example_topojson.py index d05ad6db21..012b05d376 100755 --- a/tests/topotests/example-topojson-test/test_topo_json_single_link_loopback/test_example_topojson.py +++ b/tests/topotests/example-topojson-test/test_topo_json_single_link_loopback/test_example_topojson.py @@ -55,7 +55,7 @@ from lib.bgp import verify_bgp_convergence from lib.topojson import build_topo_from_json, build_config_from_json -#TODO: select markers based on daemons used during test +# TODO: select markers based on daemons used during test # pytest module level markers """ pytestmark = pytest.mark.bfdd # single marker diff --git a/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py b/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py index ab15c3542f..dcfcd11435 100755 --- a/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py +++ b/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py @@ -165,6 +165,7 @@ class TemplateTopo(Topo): f_in.close() f_out.close() + def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-lsp-bits-topo1/test_isis_lsp_bits_topo1.py b/tests/topotests/isis-lsp-bits-topo1/test_isis_lsp_bits_topo1.py index 95a0d87c33..27dc1073c6 100755 --- a/tests/topotests/isis-lsp-bits-topo1/test_isis_lsp_bits_topo1.py +++ b/tests/topotests/isis-lsp-bits-topo1/test_isis_lsp_bits_topo1.py @@ -73,7 +73,7 @@ from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -87,8 +87,10 @@ from mininet.topo import Topo # Global multi-dimensional dictionary containing all expected outputs outputs = {} + class TemplateTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) @@ -96,36 +98,36 @@ class TemplateTopo(Topo): # # Define FRR Routers # - for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: tgen.add_router(router) # # Define connections # - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1") + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1") - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4") - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2") + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2") - switch = tgen.add_switch('s4') - switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3") + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3") - switch = tgen.add_switch('s6') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4") + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") - switch = tgen.add_switch('s7') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4") + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4") - switch = tgen.add_switch('s8') - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5") + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") def setup_module(mod): @@ -138,16 +140,15 @@ def setup_module(mod): # For all registered routers, load the zebra configuration file for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_ISIS, - os.path.join(CWD, '{}/isisd.conf'.format(rname)) + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) tgen.start_router() + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() @@ -155,6 +156,7 @@ def teardown_module(mod): # This function tears down the whole topology. tgen.stop_topology() + def router_compare_json_output(rname, command, reference): "Compare router JSON output" @@ -170,6 +172,7 @@ def router_compare_json_output(rname, command, reference): assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg + # # Step 1 # @@ -184,13 +187,14 @@ def test_isis_adjacencies_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, + rname, "show yang operational-data /frr-interface:lib isisd", "step1/show_yang_interface_isis_adjacencies.ref", ) + def test_rib_ipv4_step1(): logger.info("Test (step 1): verify IPv4 RIB") tgen = get_topogen() @@ -199,11 +203,12 @@ def test_rib_ipv4_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( rname, "show ip route isis json", "step1/show_ip_route.ref" ) + def test_rib_ipv6_step1(): logger.info("Test (step 1): verify IPv6 RIB") tgen = get_topogen() @@ -212,11 +217,12 @@ def test_rib_ipv6_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref" ) + # # Step 2 # @@ -235,15 +241,20 @@ def test_rib_ipv4_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Disabling setting the attached-bit on RT2 and RT4') - tgen.net['rt2'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"') + logger.info("Disabling setting the attached-bit on RT2 and RT4") + tgen.net["rt2"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"' + ) + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"' + ) - for rname in ['rt1', 'rt6']: + for rname in ["rt1", "rt6"]: router_compare_json_output( rname, "show ip route isis json", "step2/show_ip_route.ref" ) + def test_rib_ipv6_step2(): logger.info("Test (step 2): verify IPv6 RIB") tgen = get_topogen() @@ -252,11 +263,12 @@ def test_rib_ipv6_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt6']: + for rname in ["rt1", "rt6"]: router_compare_json_output( rname, "show ipv6 route isis json", "step2/show_ipv6_route.ref" ) + # # Step 3 # @@ -265,7 +277,7 @@ def test_rib_ipv6_step2(): # -disble processing a LSP with attach bit set # # Expected changes: -# -RT1 and RT6 should not install a default route +# -RT1 and RT6 should not install a default route # def test_rib_ipv4_step3(): logger.info("Test (step 3): verify IPv4 RIB") @@ -275,19 +287,24 @@ def test_rib_ipv4_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Enable setting the attached-bit on RT2 and RT4') - tgen.net['rt2'].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"') + logger.info("Enable setting the attached-bit on RT2 and RT4") + tgen.net["rt2"].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"') + tgen.net["rt4"].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"') - logger.info('Disable processing received attached-bit in LSP on RT1 and RT6') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"') + logger.info("Disable processing received attached-bit in LSP on RT1 and RT6") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"' + ) - for rname in ['rt1', 'rt6']: + for rname in ["rt1", "rt6"]: router_compare_json_output( rname, "show ip route isis json", "step3/show_ip_route.ref" ) + def test_rib_ipv6_step3(): logger.info("Test (step 3): verify IPv6 RIB") tgen = get_topogen() @@ -296,11 +313,12 @@ def test_rib_ipv6_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt6']: + for rname in ["rt1", "rt6"]: router_compare_json_output( rname, "show ipv6 route isis json", "step3/show_ipv6_route.ref" ) + # # Step 4 # @@ -319,13 +337,21 @@ def test_rib_ipv4_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('restore default processing on received attached-bit in LSP on RT1 and RT6') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"') - - for rname in ['rt1', 'rt6']: + logger.info( + "restore default processing on received attached-bit in LSP on RT1 and RT6" + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"' + ) + + for rname in ["rt1", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", "step4/show_ip_route.ref") + rname, "show ip route isis json", "step4/show_ip_route.ref" + ) + def test_rib_ipv6_step4(): logger.info("Test (step 4): verify IPv6 RIB") @@ -335,19 +361,22 @@ def test_rib_ipv6_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt6']: + for rname in ["rt1", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", "step4/show_ipv6_route.ref") + rname, "show ipv6 route isis json", "step4/show_ipv6_route.ref" + ) + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -if __name__ == '__main__': + +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py b/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py index 4c692841ac..9ad41c5934 100755 --- a/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py +++ b/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py @@ -167,6 +167,7 @@ class TemplateTopo(Topo): f_in.close() f_out.close() + def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py b/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py index da59cfe772..6bbb570267 100755 --- a/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py +++ b/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py @@ -85,7 +85,7 @@ from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -101,6 +101,7 @@ pytestmark = [pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.pathd] class TemplateTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) @@ -108,48 +109,49 @@ class TemplateTopo(Topo): # # Define FRR Routers # - for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6', 'dst']: + for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "dst"]: tgen.add_router(router) # # Define connections # - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1") + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1") + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1") - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-1") - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-1") + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2") - switch = tgen.add_switch('s3') - switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-2") - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-2") + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1") - switch = tgen.add_switch('s4') - switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-1") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-1") + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2") - switch = tgen.add_switch('s5') - switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-2") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-2") + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") - switch = tgen.add_switch('s6') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4") + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4") - switch = tgen.add_switch('s7') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4") + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") - switch = tgen.add_switch('s8') - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5") + switch = tgen.add_switch("s9") + switch.add_link(tgen.gears["rt6"], nodeif="eth-dst") + switch.add_link(tgen.gears["dst"], nodeif="eth-rt6") - switch = tgen.add_switch('s9') - switch.add_link(tgen.gears['rt6'], nodeif="eth-dst") - switch.add_link(tgen.gears['dst'], nodeif="eth-rt6") def setup_module(mod): "Sets up the pytest environment" @@ -167,24 +169,21 @@ def setup_module(mod): # For all registered routers, load the zebra configuration file for rname, router in router_list.iteritems(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_ISIS, - os.path.join(CWD, '{}/isisd.conf'.format(rname)) + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) router.load_config( - TopoRouter.RD_PATH, - os.path.join(CWD, '{}/pathd.conf'.format(rname)) + TopoRouter.RD_PATH, os.path.join(CWD, "{}/pathd.conf".format(rname)) ) router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, '{}/bgpd.conf'.format(rname)) + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) ) tgen.start_router() + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() @@ -192,6 +191,7 @@ def teardown_module(mod): # This function tears down the whole topology. tgen.stop_topology() + def setup_testcase(msg): logger.info(msg) tgen = get_topogen() @@ -202,9 +202,11 @@ def setup_testcase(msg): return tgen + def print_cmd_result(rname, command): print(get_topogen().gears[rname].vtysh_cmd(command, isjson=False)) + def compare_json_test(router, command, reference, exact): output = router.vtysh_cmd(command, isjson=True) result = topotest.json_cmp(output, reference) @@ -212,9 +214,10 @@ def compare_json_test(router, command, reference, exact): # Note: topotest.json_cmp() just checks on inclusion of keys. # For exact matching also compare the other way around. if not result and exact: - return topotest.json_cmp(reference, output) + return topotest.json_cmp(reference, output) else: - return result + return result + def cmp_json_output(rname, command, reference, exact=False): "Compare router JSON output" @@ -222,78 +225,136 @@ def cmp_json_output(rname, command, reference, exact=False): logger.info('Comparing router "%s" "%s" output', rname, command) tgen = get_topogen() - filename = '{}/{}/{}'.format(CWD, rname, reference) + filename = "{}/{}/{}".format(CWD, rname, reference) expected = json.loads(open(filename).read()) # Run test function until we get an result. Wait at most 60 seconds. - test_func = partial(compare_json_test, - tgen.gears[rname], command, expected, exact) + test_func = partial(compare_json_test, tgen.gears[rname], command, expected, exact) _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg + def cmp_json_output_exact(rname, command, reference): return cmp_json_output(rname, command, reference, True) -def add_candidate_path(rname, endpoint, pref, name, segment_list='default'): - get_topogen().net[rname].cmd(''' \ + +def add_candidate_path(rname, endpoint, pref, name, segment_list="default"): + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "policy color 1 endpoint ''' + endpoint + '''" \ - -c "candidate-path preference ''' + str(pref) + ''' name ''' + name + ''' explicit segment-list ''' + segment_list + '''"''') + -c "policy color 1 endpoint """ + + endpoint + + """" \ + -c "candidate-path preference """ + + str(pref) + + """ name """ + + name + + """ explicit segment-list """ + + segment_list + + '''"''' + ) + def delete_candidate_path(rname, endpoint, pref): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "policy color 1 endpoint ''' + endpoint + '''" \ - -c "no candidate-path preference ''' + str(pref) + '''"''') + -c "policy color 1 endpoint """ + + endpoint + + """" \ + -c "no candidate-path preference """ + + str(pref) + + '''"''' + ) + def add_segment(rname, name, index, label): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "segment-list ''' + name + '''" \ - -c "index ''' + str(index) + ''' mpls label ''' + str(label) + '''"''') + -c "segment-list """ + + name + + """" \ + -c "index """ + + str(index) + + """ mpls label """ + + str(label) + + '''"''' + ) + def delete_segment(rname, name, index): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "segment-list ''' + name + '''" \ - -c "no index ''' + str(index) + '''"''') + -c "segment-list """ + + name + + """" \ + -c "no index """ + + str(index) + + '''"''' + ) + def create_sr_policy(rname, endpoint, bsid): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "policy color 1 endpoint ''' + endpoint + '''" \ + -c "policy color 1 endpoint """ + + endpoint + + """" \ -c "name default" \ - -c "binding-sid ''' + str(bsid) + '''"''') + -c "binding-sid """ + + str(bsid) + + '''"''' + ) + def delete_sr_policy(rname, endpoint): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "segment-routing" \ -c "traffic-eng" \ - -c "no policy color 1 endpoint ''' + endpoint + '''"''') + -c "no policy color 1 endpoint """ + + endpoint + + '''"''' + ) + def create_prefix_sid(rname, prefix, sid): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + """ \ vtysh -c "conf t" \ -c "router isis 1" \ - -c "segment-routing prefix ''' + prefix + " index " + str(sid) + '''"''') + -c "segment-routing prefix """ + + prefix + + " index " + + str(sid) + + '''"''' + ) + def delete_prefix_sid(rname, prefix): - get_topogen().net[rname].cmd(''' \ + get_topogen().net[rname].cmd( + ''' \ vtysh -c "conf t" \ -c "router isis 1" \ - -c "no segment-routing prefix "''' + prefix) + -c "no segment-routing prefix "''' + + prefix + ) + # # Step 1 @@ -303,37 +364,42 @@ def delete_prefix_sid(rname, prefix): def test_srte_init_step1(): setup_testcase("Test (step 1): wait for IS-IS convergence / label distribution") - for rname in ['rt1', 'rt6']: - cmp_json_output(rname, - "show mpls table json", - "step1/show_mpls_table_without_candidate.ref") + for rname in ["rt1", "rt6"]: + cmp_json_output( + rname, "show mpls table json", "step1/show_mpls_table_without_candidate.ref" + ) + def test_srte_add_candidate_check_mpls_table_step1(): setup_testcase("Test (step 1): check MPLS table regarding the added Candidate Path") - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - add_candidate_path(rname, endpoint, 100, 'default') - cmp_json_output(rname, - "show mpls table json", - "step1/show_mpls_table_with_candidate.ref") + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + add_candidate_path(rname, endpoint, 100, "default") + cmp_json_output( + rname, "show mpls table json", "step1/show_mpls_table_with_candidate.ref" + ) delete_candidate_path(rname, endpoint, 100) + def test_srte_reinstall_sr_policy_check_mpls_table_step1(): - setup_testcase("Test (step 1): check MPLS table after the SR Policy was removed and reinstalled") + setup_testcase( + "Test (step 1): check MPLS table after the SR Policy was removed and reinstalled" + ) - for rname, endpoint, bsid in [('rt1', '6.6.6.6', 1111), ('rt6', '1.1.1.1', 6666)]: - add_candidate_path(rname, endpoint, 100, 'default') + for rname, endpoint, bsid in [("rt1", "6.6.6.6", 1111), ("rt6", "1.1.1.1", 6666)]: + add_candidate_path(rname, endpoint, 100, "default") delete_sr_policy(rname, endpoint) - cmp_json_output(rname, - "show mpls table json", - "step1/show_mpls_table_without_candidate.ref") + cmp_json_output( + rname, "show mpls table json", "step1/show_mpls_table_without_candidate.ref" + ) create_sr_policy(rname, endpoint, bsid) - add_candidate_path(rname, endpoint, 100, 'default') - cmp_json_output(rname, - "show mpls table json", - "step1/show_mpls_table_with_candidate.ref") + add_candidate_path(rname, endpoint, 100, "default") + cmp_json_output( + rname, "show mpls table json", "step1/show_mpls_table_with_candidate.ref" + ) delete_candidate_path(rname, endpoint, 100) + # # Step 2 # @@ -342,28 +408,41 @@ def test_srte_reinstall_sr_policy_check_mpls_table_step1(): def test_srte_bare_policy_step2(): setup_testcase("Test (step 2): bare SR Policy should not be operational") - for rname in ['rt1', 'rt6']: - cmp_json_output_exact(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step2/show_operational_data.ref") + for rname in ["rt1", "rt6"]: + cmp_json_output_exact( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step2/show_operational_data.ref", + ) + def test_srte_add_candidate_check_operational_data_step2(): - setup_testcase("Test (step 2): add single Candidate Path, SR Policy should be operational") + setup_testcase( + "Test (step 2): add single Candidate Path, SR Policy should be operational" + ) + + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + add_candidate_path(rname, endpoint, 100, "default") + cmp_json_output( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step2/show_operational_data_with_candidate.ref", + ) - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - add_candidate_path(rname, endpoint, 100, 'default') - cmp_json_output(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step2/show_operational_data_with_candidate.ref") def test_srte_config_remove_candidate_check_operational_data_step2(): - setup_testcase("Test (step 2): remove single Candidate Path, SR Policy should not be operational anymore") + setup_testcase( + "Test (step 2): remove single Candidate Path, SR Policy should not be operational anymore" + ) - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: delete_candidate_path(rname, endpoint, 100) - cmp_json_output_exact(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step2/show_operational_data.ref") + cmp_json_output_exact( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step2/show_operational_data.ref", + ) + # # Step 3 @@ -373,53 +452,62 @@ def test_srte_config_remove_candidate_check_operational_data_step2(): def test_srte_add_two_candidates_step3(): setup_testcase("Test (step 3): second Candidate Path has higher Priority") - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - for pref, cand_name in [('100', 'first'), ('200', 'second')]: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + for pref, cand_name in [("100", "first"), ("200", "second")]: add_candidate_path(rname, endpoint, pref, cand_name) - cmp_json_output(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step3/show_operational_data_with_two_candidates.ref") + cmp_json_output( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step3/show_operational_data_with_two_candidates.ref", + ) # cleanup - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - for pref in ['100', '200']: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + for pref in ["100", "200"]: delete_candidate_path(rname, endpoint, pref) + def test_srte_add_two_candidates_with_reverse_priority_step3(): setup_testcase("Test (step 3): second Candidate Path has lower Priority") # Use reversed priorities here - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - for pref, cand_name in [('200', 'first'), ('100', 'second')]: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + for pref, cand_name in [("200", "first"), ("100", "second")]: add_candidate_path(rname, endpoint, pref, cand_name) - cmp_json_output(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step3/show_operational_data_with_two_candidates.ref") + cmp_json_output( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step3/show_operational_data_with_two_candidates.ref", + ) # cleanup - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - for pref in ['100', '200']: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + for pref in ["100", "200"]: delete_candidate_path(rname, endpoint, pref) + def test_srte_remove_best_candidate_step3(): setup_testcase("Test (step 3): delete the Candidate Path with higher priority") - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - for pref, cand_name in [('100', 'first'), ('200', 'second')]: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + for pref, cand_name in [("100", "first"), ("200", "second")]: add_candidate_path(rname, endpoint, pref, cand_name) # Delete candidate with higher priority - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: delete_candidate_path(rname, endpoint, 200) # Candidate with lower priority should get active now - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - cmp_json_output(rname, - "show yang operational-data /frr-pathd:pathd pathd", - "step3/show_operational_data_with_single_candidate.ref") + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + cmp_json_output( + rname, + "show yang operational-data /frr-pathd:pathd pathd", + "step3/show_operational_data_with_single_candidate.ref", + ) # cleanup delete_candidate_path(rname, endpoint, 100) + # # Step 4 # @@ -428,38 +516,38 @@ def test_srte_remove_best_candidate_step3(): def test_srte_change_segment_list_check_mpls_table_step4(): setup_testcase("Test (step 4): check MPLS table for changed Segment List") - for rname, endpoint in [('rt1', '6.6.6.6'), ('rt6', '1.1.1.1')]: - add_candidate_path(rname, endpoint, 100, 'default') - # now change the segment list name - add_candidate_path(rname, endpoint, 100, 'default', 'test') - cmp_json_output(rname, - "show mpls table json", - "step4/show_mpls_table.ref") + for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]: + add_candidate_path(rname, endpoint, 100, "default") + # now change the segment list name + add_candidate_path(rname, endpoint, 100, "default", "test") + cmp_json_output(rname, "show mpls table json", "step4/show_mpls_table.ref") delete_candidate_path(rname, endpoint, 100) + def test_srte_segment_list_add_segment_check_mpls_table_step4(): - setup_testcase("Test (step 4): check MPLS table for added (then changed and finally deleted) segment") + setup_testcase( + "Test (step 4): check MPLS table for added (then changed and finally deleted) segment" + ) - add_candidate_path('rt1', '6.6.6.6', 100, 'default', 'test') + add_candidate_path("rt1", "6.6.6.6", 100, "default", "test") # first add a new segment - add_segment('rt1', 'test', 25, 16050) - cmp_json_output('rt1', - "show mpls table json", - "step4/show_mpls_table_add_segment.ref") + add_segment("rt1", "test", 25, 16050) + cmp_json_output( + "rt1", "show mpls table json", "step4/show_mpls_table_add_segment.ref" + ) # ... then change it ... - add_segment('rt1', 'test', 25, 16030) - cmp_json_output('rt1', - "show mpls table json", - "step4/show_mpls_table_change_segment.ref") + add_segment("rt1", "test", 25, 16030) + cmp_json_output( + "rt1", "show mpls table json", "step4/show_mpls_table_change_segment.ref" + ) # ... and finally delete it - delete_segment('rt1', 'test', 25) - cmp_json_output('rt1', - "show mpls table json", - "step4/show_mpls_table.ref") - delete_candidate_path('rt1', '6.6.6.6', 100) + delete_segment("rt1", "test", 25) + cmp_json_output("rt1", "show mpls table json", "step4/show_mpls_table.ref") + delete_candidate_path("rt1", "6.6.6.6", 100) + # # Step 5 @@ -467,68 +555,81 @@ def test_srte_segment_list_add_segment_check_mpls_table_step4(): # Checking the nexthop using a single SR Policy and a Candidate Path with configured route-map # def test_srte_route_map_with_sr_policy_check_nextop_step5(): - setup_testcase("Test (step 5): recursive nexthop learned through BGP neighbour should be aligned with SR Policy from route-map") + setup_testcase( + "Test (step 5): recursive nexthop learned through BGP neighbour should be aligned with SR Policy from route-map" + ) # (re-)build the SR Policy two times to ensure that reinstalling still works - for i in [1,2]: - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_inactive_srte.ref") + for i in [1, 2]: + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_inactive_srte.ref" + ) - delete_sr_policy('rt1', '6.6.6.6') - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_inactive_srte.ref") + delete_sr_policy("rt1", "6.6.6.6") + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_inactive_srte.ref" + ) - create_sr_policy('rt1', '6.6.6.6', 1111) - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_inactive_srte.ref") + create_sr_policy("rt1", "6.6.6.6", 1111) + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_inactive_srte.ref" + ) + + add_candidate_path("rt1", "6.6.6.6", 100, "default") + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_active_srte.ref" + ) - add_candidate_path('rt1', '6.6.6.6', 100, 'default') - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_active_srte.ref") + delete_candidate_path("rt1", "6.6.6.6", 100) - delete_candidate_path('rt1', '6.6.6.6', 100) def test_srte_route_map_with_sr_policy_reinstall_prefix_sid_check_nextop_step5(): - setup_testcase("Test (step 5): remove and re-install prefix SID on fist path element and check SR Policy activity") + setup_testcase( + "Test (step 5): remove and re-install prefix SID on fist path element and check SR Policy activity" + ) # first add a candidate path so the SR Policy is active - add_candidate_path('rt1', '6.6.6.6', 100, 'default') - cmp_json_output('rt1', - "show yang operational-data /frr-pathd:pathd pathd", - "step5/show_operational_data_active.ref") + add_candidate_path("rt1", "6.6.6.6", 100, "default") + cmp_json_output( + "rt1", + "show yang operational-data /frr-pathd:pathd pathd", + "step5/show_operational_data_active.ref", + ) # delete prefix SID from first element of the configured path and check # if the SR Policy is inactive since the label can't be resolved anymore - delete_prefix_sid('rt5', "5.5.5.5/32") - cmp_json_output('rt1', - "show yang operational-data /frr-pathd:pathd pathd", - "step5/show_operational_data_inactive.ref") - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_inactive_srte.ref") + delete_prefix_sid("rt5", "5.5.5.5/32") + cmp_json_output( + "rt1", + "show yang operational-data /frr-pathd:pathd pathd", + "step5/show_operational_data_inactive.ref", + ) + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_inactive_srte.ref" + ) # re-create the prefix SID and check if the SR Policy is active - create_prefix_sid('rt5', "5.5.5.5/32", 50) - cmp_json_output('rt1', - "show yang operational-data /frr-pathd:pathd pathd", - "step5/show_operational_data_active.ref") - cmp_json_output('rt1', - "show ip route bgp json", - "step5/show_ip_route_bgp_active_srte.ref") + create_prefix_sid("rt5", "5.5.5.5/32", 50) + cmp_json_output( + "rt1", + "show yang operational-data /frr-pathd:pathd pathd", + "step5/show_operational_data_active.ref", + ) + cmp_json_output( + "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_active_srte.ref" + ) + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -if __name__ == '__main__': + +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py index 8a7d6ee882..148a89474e 100644 --- a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py +++ b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py @@ -86,6 +86,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.isisd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py index 39b3299603..00cb623999 100755 --- a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py @@ -179,6 +179,7 @@ class TemplateTopo(Topo): f_in.close() f_out.close() + def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py index 7bc694cbb0..24287ccd44 100644 --- a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -45,6 +45,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.isisd] + class ISISTopo1(Topo): "Simple two layer ISIS vrf topology" diff --git a/tests/topotests/isis-topo1/test_isis_topo1.py b/tests/topotests/isis-topo1/test_isis_topo1.py index 6963429288..6ec3bf9ea1 100644 --- a/tests/topotests/isis-topo1/test_isis_topo1.py +++ b/tests/topotests/isis-topo1/test_isis_topo1.py @@ -47,6 +47,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.isisd] + class ISISTopo1(Topo): "Simple two layer ISIS topology" diff --git a/tests/topotests/ldp-oc-acl-topo1/test_ldp_oc_acl_topo1.py b/tests/topotests/ldp-oc-acl-topo1/test_ldp_oc_acl_topo1.py index a74e80dd80..9aa4024598 100644 --- a/tests/topotests/ldp-oc-acl-topo1/test_ldp_oc_acl_topo1.py +++ b/tests/topotests/ldp-oc-acl-topo1/test_ldp_oc_acl_topo1.py @@ -80,6 +80,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ldpd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ldp-oc-topo1/test_ldp_oc_topo1.py b/tests/topotests/ldp-oc-topo1/test_ldp_oc_topo1.py index 97790487f2..aef22c395d 100644 --- a/tests/topotests/ldp-oc-topo1/test_ldp_oc_topo1.py +++ b/tests/topotests/ldp-oc-topo1/test_ldp_oc_topo1.py @@ -80,6 +80,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ldpd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py index 99c831c8cf..57b45e5fdf 100644 --- a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py +++ b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py @@ -81,6 +81,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ldpd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py index fe57f3707a..0ea7aca3eb 100644 --- a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py +++ b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py @@ -82,6 +82,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ldpd, pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 22602cb460..65e5840622 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -2516,8 +2516,9 @@ def verify_best_path_as_per_admin_distance( @retry(attempts=5, wait=2, return_is_str=True, initial_wait=2) -def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, -aspath=None, multi_nh=None): +def verify_bgp_rib( + tgen, addr_type, dut, input_dict, next_hop=None, aspath=None, multi_nh=None +): """ This API is to verify whether bgp rib has any matching route for a nexthop. @@ -2663,25 +2664,35 @@ aspath=None, multi_nh=None): if not isinstance(next_hop, list): next_hop = [next_hop] list1 = next_hop - found_hops = [rib_r["ip"] for rib_r in - rib_routes_json["routes"][ - st_rt][0]["nexthops"]] + found_hops = [ + rib_r["ip"] + for rib_r in rib_routes_json["routes"][st_rt][0][ + "nexthops" + ] + ] list2 = found_hops - missing_list_of_nexthops = \ - set(list2).difference(list1) - additional_nexthops_in_required_nhs = \ - set(list1).difference(list2) + missing_list_of_nexthops = set(list2).difference(list1) + additional_nexthops_in_required_nhs = set( + list1 + ).difference(list2) if list2: if additional_nexthops_in_required_nhs: - logger.info("Missing nexthop %s for route"\ - " %s in RIB of router %s\n", \ - additional_nexthops_in_required_nhs, \ - st_rt, dut) - errormsg=("Nexthop {} is Missing for "\ - "route {} in RIB of router {}\n".format( + logger.info( + "Missing nexthop %s for route" + " %s in RIB of router %s\n", additional_nexthops_in_required_nhs, - st_rt, dut)) + st_rt, + dut, + ) + errormsg = ( + "Nexthop {} is Missing for " + "route {} in RIB of router {}\n".format( + additional_nexthops_in_required_nhs, + st_rt, + dut, + ) + ) return errormsg else: nh_found = True diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 5bc9f14fea..79e4d97448 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -94,7 +94,9 @@ def create_router_ospf(tgen, topo, input_dict=None, build=False, load_config=Tru return result -def __create_ospf_global(tgen, input_dict, router, build=False, load_config=True, ospf="ospf"): +def __create_ospf_global( + tgen, input_dict, router, build=False, load_config=True, ospf="ospf" +): """ Helper API to create ospf global configuration. diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index 294f60bf68..d07b58a774 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -1564,26 +1564,30 @@ def verify_pim_interface(tgen, topo, dut, interface=None, interface_ip=None): logger.info("[DUT: %s]: Verifying PIM interface status:", dut) rnode = tgen.routers()[dut] - show_ip_pim_interface_json = rnode.\ - vtysh_cmd("show ip pim interface json", isjson=True) + show_ip_pim_interface_json = rnode.vtysh_cmd( + "show ip pim interface json", isjson=True + ) - logger.info("show_ip_pim_interface_json: \n %s", - show_ip_pim_interface_json) + logger.info("show_ip_pim_interface_json: \n %s", show_ip_pim_interface_json) if interface_ip: if interface in show_ip_pim_interface_json: pim_intf_json = show_ip_pim_interface_json[interface] if pim_intf_json["address"] != interface_ip: - errormsg = ("[DUT %s]: PIM interface " - "ip is not correct " - "[FAILED]!! Expected : %s, Found : %s" - %(dut, pim_intf_json["address"],interface_ip)) + errormsg = ( + "[DUT %s]: PIM interface " + "ip is not correct " + "[FAILED]!! Expected : %s, Found : %s" + % (dut, pim_intf_json["address"], interface_ip) + ) return errormsg else: - logger.info("[DUT %s]: PIM interface " - "ip is correct " - "[Passed]!! Expected : %s, Found : %s" - %(dut, pim_intf_json["address"],interface_ip)) + logger.info( + "[DUT %s]: PIM interface " + "ip is correct " + "[Passed]!! Expected : %s, Found : %s" + % (dut, pim_intf_json["address"], interface_ip) + ) return True else: for destLink, data in topo["routers"][dut]["links"].items(): @@ -1595,24 +1599,36 @@ def verify_pim_interface(tgen, topo, dut, interface=None, interface_ip=None): pim_intf_ip = data["ipv4"].split("/")[0] if pim_interface in show_ip_pim_interface_json: - pim_intf_json = show_ip_pim_interface_json\ - [pim_interface] + pim_intf_json = show_ip_pim_interface_json[pim_interface] # Verifying PIM interface - if pim_intf_json["address"] != pim_intf_ip and \ - pim_intf_json["state"] != "up": - errormsg = ("[DUT %s]: PIM interface: %s " - "PIM interface ip: %s, status check " - "[FAILED]!! Expected : %s, Found : %s" - %(dut, pim_interface, pim_intf_ip, - pim_interface, pim_intf_json["state"])) + if ( + pim_intf_json["address"] != pim_intf_ip + and pim_intf_json["state"] != "up" + ): + errormsg = ( + "[DUT %s]: PIM interface: %s " + "PIM interface ip: %s, status check " + "[FAILED]!! Expected : %s, Found : %s" + % ( + dut, + pim_interface, + pim_intf_ip, + pim_interface, + pim_intf_json["state"], + ) + ) return errormsg - logger.info("[DUT %s]: PIM interface: %s, " - "interface ip: %s, status: %s" - " [PASSED]!!", - dut, pim_interface, pim_intf_ip, - pim_intf_json["state"]) + logger.info( + "[DUT %s]: PIM interface: %s, " + "interface ip: %s, status: %s" + " [PASSED]!!", + dut, + pim_interface, + pim_intf_ip, + pim_intf_json["state"], + ) logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) return True @@ -3420,30 +3436,36 @@ def verify_igmp_interface(tgen, topo, dut, igmp_iface, interface_ip): if router != dut: continue - logger.info("[DUT: %s]: Verifying PIM interface status:", - dut) + logger.info("[DUT: %s]: Verifying PIM interface status:", dut) rnode = tgen.routers()[dut] - show_ip_igmp_interface_json = \ - run_frr_cmd(rnode, "show ip igmp interface json", isjson=True) + show_ip_igmp_interface_json = run_frr_cmd( + rnode, "show ip igmp interface json", isjson=True + ) - if igmp_iface in show_ip_igmp_interface_json: + if igmp_iface in show_ip_igmp_interface_json: igmp_intf_json = show_ip_igmp_interface_json[igmp_iface] # Verifying igmp interface - if igmp_intf_json["address"] != interface_ip: - errormsg = ("[DUT %s]: igmp interface ip is not correct " - "[FAILED]!! Expected : %s, Found : %s" - %(dut, igmp_intf_json["address"], interface_ip)) + if igmp_intf_json["address"] != interface_ip: + errormsg = ( + "[DUT %s]: igmp interface ip is not correct " + "[FAILED]!! Expected : %s, Found : %s" + % (dut, igmp_intf_json["address"], interface_ip) + ) return errormsg - logger.info("[DUT %s]: igmp interface: %s, " - "interface ip: %s" - " [PASSED]!!", - dut, igmp_iface, interface_ip) + logger.info( + "[DUT %s]: igmp interface: %s, " "interface ip: %s" " [PASSED]!!", + dut, + igmp_iface, + interface_ip, + ) else: - errormsg = ("[DUT %s]: igmp interface: %s " - "igmp interface ip: %s, is not present " - %(dut, igmp_iface, interface_ip)) + errormsg = ( + "[DUT %s]: igmp interface: %s " + "igmp interface ip: %s, is not present " + % (dut, igmp_iface, interface_ip) + ) return errormsg logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) diff --git a/tests/topotests/lib/snmptest.py b/tests/topotests/lib/snmptest.py index 5112500e0b..e6b140a0e2 100644 --- a/tests/topotests/lib/snmptest.py +++ b/tests/topotests/lib/snmptest.py @@ -86,12 +86,11 @@ class SnmpTester(object): def _get_snmp_oid(snmp_output): tokens = snmp_output.strip().split() -# if len(tokens) > 5: -# return None - + # if len(tokens) > 5: + # return None # third token is the value of the object - return tokens[0].split('.',1)[1] + return tokens[0].split(".", 1)[1] def _parse_multiline(self, snmp_output): results = snmp_output.strip().split("\r\n") @@ -142,7 +141,11 @@ class SnmpTester(object): print("FAIL: missing oid key {}".format(oid)) return False if results_dict[oid] != values[index]: - print("FAIL{} {} |{}| == |{}|".format(oid, index, results_dict[oid], values[index])) + print( + "FAIL{} {} |{}| == |{}|".format( + oid, index, results_dict[oid], values[index] + ) + ) return False index += 1 return True diff --git a/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py b/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py index c670c82d21..a353e3687b 100644 --- a/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py +++ b/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py @@ -644,7 +644,6 @@ def test_BSR_CRP_with_blackhole_address_p1(request): next_hop_lhr = topo["routers"]["i1"]["links"]["l1"]["ipv4"].split("/")[0] input_dict = { - "f1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": NEXT_HOP1}]}, "i1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_rp}]}, "l1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_lhr}]}, } @@ -706,7 +705,8 @@ def test_BSR_CRP_with_blackhole_address_p1(request): input_dict = { "f1": { "static_routes": [ - {"network": [BSR1_ADDR, CRP], "next_hop": "blackhole", "delete": True} + {"network": [BSR1_ADDR, CRP], "next_hop": "blackhole", "delete": True}, + {"network": BSR1_ADDR, "next_hop": NEXT_HOP1}, ] } } @@ -1118,7 +1118,10 @@ def test_static_rp_override_p1(request): "l1": { "pim": { "rp": [ - {"rp_addr": "33.33.33.33", "group_addr_range": ["225.1.1.1/32"],} + { + "rp_addr": "33.33.33.33", + "group_addr_range": ["225.1.1.1/32"], + } ] } } @@ -1294,7 +1297,8 @@ def test_bsmp_stress_add_del_restart_p2(request): assert ( rp_add1 == rp2[group] ), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format( - tc_name, rp_add1, + tc_name, + rp_add1, ) # Verify if that rp is installed @@ -1632,7 +1636,14 @@ def test_iif_join_state_p0(request): # Add back route for RP to make it reachable step("Add back route for RP to make it reachable") input_dict = { - "l1": {"static_routes": [{"network": rp_ip, "next_hop": next_hop_lhr,}]} + "l1": { + "static_routes": [ + { + "network": rp_ip, + "next_hop": next_hop_lhr, + } + ] + } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) diff --git a/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py index 459afb5a02..8bd91401c3 100644 --- a/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py +++ b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py @@ -695,7 +695,8 @@ def test_RP_priority_p0(request): assert ( rp_add1 == rp2[group] ), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format( - tc_name, rp_add1, + tc_name, + rp_add1, ) # Verify if that rp is installed diff --git a/tests/topotests/multicast-pim-sm-topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast-pim-sm-topo1/test_multicast_pim_sm_topo1.py index ac675c5c2f..e55e30270d 100755 --- a/tests/topotests/multicast-pim-sm-topo1/test_multicast_pim_sm_topo1.py +++ b/tests/topotests/multicast-pim-sm-topo1/test_multicast_pim_sm_topo1.py @@ -102,7 +102,7 @@ from lib.pim import ( clear_ip_mroute, clear_ip_pim_interface_traffic, verify_igmp_config, - clear_ip_mroute_verify + clear_ip_mroute_verify, ) from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json diff --git a/tests/topotests/multicast-pim-sm-topo2/test_multicast_pim_sm_topo2.py b/tests/topotests/multicast-pim-sm-topo2/test_multicast_pim_sm_topo2.py index a9d914da57..7e409c2a05 100755 --- a/tests/topotests/multicast-pim-sm-topo2/test_multicast_pim_sm_topo2.py +++ b/tests/topotests/multicast-pim-sm-topo2/test_multicast_pim_sm_topo2.py @@ -877,7 +877,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request): data["src_address"], _IGMP_JOIN_RANGE, data["iif"], - data["oil"] + data["oil"], ) assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) @@ -1122,8 +1122,9 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request): done_flag = False for retry in range(1, 11): - result = verify_upstream_iif(tgen, "l1", "Unknown", source, IGMP_JOIN_RANGE_2, - expected=False) + result = verify_upstream_iif( + tgen, "l1", "Unknown", source, IGMP_JOIN_RANGE_2, expected=False + ) if result is not True: done_flag = True else: @@ -1515,7 +1516,7 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request): _IGMP_JOIN_RANGE, data["iif"], data["oil"], - expected=False + expected=False, ) if result is not True: done_flag = True @@ -1928,9 +1929,10 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request "f1-i8-eth2", expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n mroutes are" - " still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behavior: {}".format(result)) diff --git a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py index fdceb77fd1..ad9a2fefde 100755 --- a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py +++ b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py @@ -597,9 +597,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): input_traffic = {"l1": {"traffic_sent": [intf_l1_i1]}} result = verify_multicast_traffic(tgen, input_traffic, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - " Traffic is not stopped yet \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " " Traffic is not stopped yet \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -612,9 +613,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): result = verify_igmp_groups( tgen, dut, intf_l1_i1, IGMP_JOIN_RANGE_1, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n " - "IGMP groups are not deleted \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "IGMP groups are not deleted \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -655,9 +657,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroutes are still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -722,9 +725,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}} result = verify_multicast_traffic(tgen, input_traffic, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - " Traffic is not stopped yet \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " " Traffic is not stopped yet \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -737,9 +741,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): result = verify_igmp_groups( tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n " - "IGMP groups are not deleted \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "IGMP groups are not deleted \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -775,9 +780,10 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroutes are still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -959,9 +965,10 @@ def test_verify_oil_when_join_prune_sent_scenario_2_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroutes are still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -1022,9 +1029,10 @@ def test_verify_oil_when_join_prune_sent_scenario_2_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroutes are still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -1190,9 +1198,10 @@ def test_shut_noshut_source_interface_when_upstream_cleared_from_LHR_p1(request) result = verify_ip_mroutes( tgen, "f1", source_i2, IGMP_JOIN_RANGE_1, intf_f1_i2, intf_f1_r2, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n mroutes are" - " still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behavior: {}".format(result)) @@ -1630,7 +1639,14 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): input_dict_2 = { "l1": { "igmp": { - "interfaces": {intf_l1_i1: {"igmp": {"version": "2", "delete": True,}}} + "interfaces": { + intf_l1_i1: { + "igmp": { + "version": "2", + "delete": True, + } + } + } } } } @@ -1642,9 +1658,10 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): dut = "l1" interface = topo["routers"]["l1"]["links"]["i1"]["interface"] result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Groups are not" - " present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n Groups are not" " present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -1712,7 +1729,14 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): input_dict_2 = { "l1": { "igmp": { - "interfaces": {intf_l1_i1: {"igmp": {"version": "2", "delete": True,}}} + "interfaces": { + intf_l1_i1: { + "igmp": { + "version": "2", + "delete": True, + } + } + } } } } @@ -1725,9 +1749,10 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): dut = "l1" interface = topo["routers"]["l1"]["links"]["i1"]["interface"] result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Groups are not" - " present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n Groups are not" " present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -1811,7 +1836,14 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): input_dict_2 = { "l1": { "igmp": { - "interfaces": {intf_l1_i1: {"igmp": {"version": "2", "delete": True,}}} + "interfaces": { + intf_l1_i1: { + "igmp": { + "version": "2", + "delete": True, + } + } + } } } } @@ -1831,9 +1863,10 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): result = verify_ip_mroutes( tgen, dut, source, IGMP_JOIN_RANGE_1, iif, oil, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n routes are still" - " present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n routes are still" " present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -1995,7 +2028,14 @@ def test_verify_remove_add_igmp_commands_when_pim_configured_p0(request): input_dict_2 = { "l1": { "igmp": { - "interfaces": {intf_l1_i1: {"igmp": {"version": "2", "delete": True,}}} + "interfaces": { + intf_l1_i1: { + "igmp": { + "version": "2", + "delete": True, + } + } + } } } } @@ -2009,9 +2049,10 @@ def test_verify_remove_add_igmp_commands_when_pim_configured_p0(request): ) result = verify_igmp_config(tgen, input_dict_1, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "IGMP interface is not removed \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "IGMP interface is not removed \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -2914,9 +2955,10 @@ def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroute still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3259,9 +3301,10 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "mroute still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3287,9 +3330,10 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n " - "upstream still present \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "upstream still present \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3311,9 +3355,10 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n " - "RP iif is not updated \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3459,9 +3504,10 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n " - "RP iif is not updated \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3606,9 +3652,10 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n " - "RP iif is not updated \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -3873,7 +3920,12 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): "l1": { "igmp": { "interfaces": { - "l1-i1-eth1": {"igmp": {"version": "2", "delete": True,}} + "l1-i1-eth1": { + "igmp": { + "version": "2", + "delete": True, + } + } } } } @@ -4107,9 +4159,10 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n" - "mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" "mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -4181,9 +4234,10 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n" - " mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -4248,9 +4302,10 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): result = verify_ip_mroutes( tgen, dut, src_address, _IGMP_JOIN_RANGE, iif, oil, expected=False ) - assert result is not True, ( - "Testcase {} : Failed \n" - " mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -4459,9 +4514,10 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n" - " mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -4524,9 +4580,10 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n" - " mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) @@ -4595,9 +4652,10 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert result is not True, ( - "Testcase {} : Failed \n" - " mroutes are cleared \n Error: {}".format(tc_name, result) + assert ( + result is not True + ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( + tc_name, result ) logger.info("Expected Behaviour: {}".format(result)) diff --git a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py index e8579e2a1e..bb2971842b 100755 --- a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py +++ b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py @@ -1009,7 +1009,11 @@ def test_PIM_hello_tx_rx_p1(request): intf_c1_l1 = topo["routers"]["c1"]["links"]["l1"]["interface"] step("verify before stats on C1") - state_dict = {"c1": {intf_c1_l1: ["helloTx", "helloRx"],}} + state_dict = { + "c1": { + intf_c1_l1: ["helloTx", "helloRx"], + } + } c1_state_before = verify_pim_interface_traffic(tgen, state_dict) assert isinstance( @@ -1040,7 +1044,11 @@ def test_PIM_hello_tx_rx_p1(request): ), "Testcase{} : Failed Error: {}" "stats incremented".format(tc_name, result) step("verify before stats on l1") - l1_state_dict = {"l1": {intf_l1_c1: ["helloTx", "helloRx"],}} + l1_state_dict = { + "l1": { + intf_l1_c1: ["helloTx", "helloRx"], + } + } l1_state_before = verify_pim_interface_traffic(tgen, l1_state_dict) assert isinstance( @@ -1077,7 +1085,11 @@ def test_PIM_hello_tx_rx_p1(request): l1_state_after = {} step("verify before stats on C1") - state_dict = {"c1": {intf_c1_l1: ["helloTx", "helloRx"],}} + state_dict = { + "c1": { + intf_c1_l1: ["helloTx", "helloRx"], + } + } c1_state_before = verify_pim_interface_traffic(tgen, state_dict) assert isinstance( diff --git a/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py index 8dfdd50527..f01f57d1eb 100755 --- a/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py +++ b/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py @@ -281,6 +281,7 @@ def teardown_module(): # ##################################################### + def config_to_send_igmp_join_and_traffic(tgen, tc_name): """ API to do pre-configuration to send IGMP join and multicast @@ -961,7 +962,12 @@ def test_add_RP_after_join_received_p1(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.2.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } } } @@ -1147,32 +1153,32 @@ def test_reachable_static_RP_after_join_p0(request): def test_send_join_on_higher_preffered_rp_p1(request): """ - TC_11_P1 : Verify PIM join send towards the higher preferred RP - TC_12_P1 : Verify PIM prune send towards the lower preferred RP - TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher - preferred overlapping RP configured - TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when - higher preferred overlapping RP configured - TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when - higher preferred overlapping RP is configured - TC_16_P1 : Verify join is send to lower preferred RP, when higher - preferred RP gets deleted - TC_17_P1 : Verify prune is send to higher preferred RP when higher - preferred RP gets deleted - TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP - gets deleted - TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher - preferred overlapping RP is deleted - TC_20_P1 : Verfiy PIM upstream IIF updated when higher preferred - overlapping RP deleted - - Topology used: - _______r2 - | - iperf | - r0-----r1 - | - |_______r4 + TC_11_P1 : Verify PIM join send towards the higher preferred RP + TC_12_P1 : Verify PIM prune send towards the lower preferred RP + TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher + preferred overlapping RP configured + TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when + higher preferred overlapping RP configured + TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when + higher preferred overlapping RP is configured + TC_16_P1 : Verify join is send to lower preferred RP, when higher + preferred RP gets deleted + TC_17_P1 : Verify prune is send to higher preferred RP when higher + preferred RP gets deleted + TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP + gets deleted + TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher + preferred overlapping RP is deleted + TC_20_P1 : Verfiy PIM upstream IIF updated when higher preferred + overlapping RP deleted + + Topology used: + _______r2 + | + iperf | + r0-----r1 + | + |_______r4 """ tgen = get_topogen() @@ -1241,7 +1247,12 @@ def test_send_join_on_higher_preffered_rp_p1(request): input_dict = { "r4": { "pim": { - "rp": [{"rp_addr": "1.0.4.17", "group_addr_range": ["225.1.1.1/32"],}] + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": ["225.1.1.1/32"], + } + ] } } } @@ -1483,22 +1494,42 @@ def test_RP_configured_as_LHR_1_p1(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r2": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r3": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, } @@ -1677,22 +1708,42 @@ def test_RP_configured_as_LHR_2_p1(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r2": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r3": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.1.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, } @@ -1863,22 +1914,42 @@ def test_RP_configured_as_FHR_1_p1(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r2": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r3": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, } @@ -2050,22 +2121,42 @@ def test_RP_configured_as_FHR_2_p2(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r2": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r3": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.3.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } }, } @@ -2733,7 +2824,12 @@ def test_multiple_groups_same_RP_address_p2(request): input_dict = { "r1": { "pim": { - "rp": [{"rp_addr": "1.0.2.17", "group_addr_range": GROUP_RANGE_ALL,}] + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] } } } @@ -2893,12 +2989,22 @@ def test_multiple_groups_different_RP_address_p2(request): input_dict = { "r2": { "pim": { - "rp": [{"rp_addr": "1.0.2.17", "group_addr_range": GROUP_RANGE_LIST_1,}] + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_LIST_1, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.4.17", "group_addr_range": GROUP_RANGE_LIST_2,}] + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": GROUP_RANGE_LIST_2, + } + ] } }, } @@ -3148,12 +3254,22 @@ def test_multiple_groups_different_RP_address_p2(request): input_dict = { "r2": { "pim": { - "rp": [{"rp_addr": "1.0.2.17", "group_addr_range": GROUP_RANGE_LIST_1,}] + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_LIST_1, + } + ] } }, "r4": { "pim": { - "rp": [{"rp_addr": "1.0.4.17", "group_addr_range": GROUP_RANGE_LIST_2,}] + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": GROUP_RANGE_LIST_2, + } + ] } }, } diff --git a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py index 5c901c067a..8a704790d4 100644 --- a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py +++ b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py @@ -50,6 +50,7 @@ import pytest pytestmark = [pytest.mark.ospfd] + class OspfSrTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ospf-tilfa-topo1/test_ospf_tilfa_topo1.py b/tests/topotests/ospf-tilfa-topo1/test_ospf_tilfa_topo1.py index eb3ad5d995..489690471c 100644 --- a/tests/topotests/ospf-tilfa-topo1/test_ospf_tilfa_topo1.py +++ b/tests/topotests/ospf-tilfa-topo1/test_ospf_tilfa_topo1.py @@ -166,6 +166,7 @@ def test_ospf_initial_convergence_step1(): "step1/show_ip_route_initial.ref", ) + def test_ospf_link_protection_step2(): logger.info("Test (step 2): check OSPF link protection") tgen = get_topogen() @@ -175,9 +176,7 @@ def test_ospf_link_protection_step2(): pytest.skip(tgen.errors) # enable TI-LFA link protection on all interfaces - tgen.net["rt1"].cmd( - 'vtysh -c "conf t" -c "router ospf" -c "fast-reroute ti-lfa"' - ) + tgen.net["rt1"].cmd('vtysh -c "conf t" -c "router ospf" -c "fast-reroute ti-lfa"') router_compare_json_output( "rt1", @@ -197,6 +196,7 @@ def test_ospf_link_protection_step2(): "step2/show_ip_route_initial.ref", ) + def test_ospf_node_protection_step3(): logger.info("Test (step 3): check OSPF node protection") tgen = get_topogen() @@ -228,6 +228,7 @@ def test_ospf_node_protection_step3(): "step3/show_ip_route_initial.ref", ) + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." @@ -237,6 +238,7 @@ def test_memory_leak(): tgen.report_memory_leaks() + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/ospf-topo1-vrf/test_ospf_topo1_vrf.py b/tests/topotests/ospf-topo1-vrf/test_ospf_topo1_vrf.py index 92dac0f39c..e2cb7bff03 100644 --- a/tests/topotests/ospf-topo1-vrf/test_ospf_topo1_vrf.py +++ b/tests/topotests/ospf-topo1-vrf/test_ospf_topo1_vrf.py @@ -47,6 +47,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ospfd] + class OSPFTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ospf-topo1/test_ospf_topo1.py b/tests/topotests/ospf-topo1/test_ospf_topo1.py index 7197c05812..5bb6c2c818 100644 --- a/tests/topotests/ospf-topo1/test_ospf_topo1.py +++ b/tests/topotests/ospf-topo1/test_ospf_topo1.py @@ -47,6 +47,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ospfd] + class OSPFTopo(Topo): "Test topology builder" diff --git a/tests/topotests/ospf6-topo1/test_ospf6_topo1.py b/tests/topotests/ospf6-topo1/test_ospf6_topo1.py index c3efb6ff22..6ae886b76e 100644 --- a/tests/topotests/ospf6-topo1/test_ospf6_topo1.py +++ b/tests/topotests/ospf6-topo1/test_ospf6_topo1.py @@ -384,15 +384,14 @@ def test_linux_ipv6_kernel_routingTable(): % (i, diff) ) else: - logger.error( - "r{} failed - no nhid ref file: {}".format(i, refTableFile) - ) + logger.error("r{} failed - no nhid ref file: {}".format(i, refTableFile)) assert False, ( "Linux Kernel IPv6 Routing Table verification failed for router r%s\n" % (i) ) + def test_shutdown_check_stderr(): tgen = get_topogen() diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py index ca7cb736f9..0dedc8f0df 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py @@ -49,15 +49,14 @@ from lib.common_config import ( shutdown_bringup_interface, topo_daemons, verify_rib, - stop_router, start_router, + stop_router, + start_router, create_static_routes, start_router_daemons, - kill_router_daemons + kill_router_daemons, ) -from lib.ospf import ( - verify_ospf_neighbor, verify_ospf_rib, - create_router_ospf) +from lib.ospf import verify_ospf_neighbor, verify_ospf_rib, create_router_ospf from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json @@ -69,8 +68,13 @@ pytestmark = [pytest.mark.ospfd, pytest.mark.staticd] topo = None NETWORK = { - "ipv4": ["11.0.20.1/32", "11.0.20.2/32", "11.0.20.3/32", "11.0.20.4/32", - "11.0.20.5/32"] + "ipv4": [ + "11.0.20.1/32", + "11.0.20.2/32", + "11.0.20.3/32", + "11.0.20.4/32", + "11.0.20.5/32", + ] } """ Topology: @@ -102,6 +106,7 @@ try: except IOError: assert False, "Could not read file {}".format(jsonFile) + class CreateTopo(Topo): """ Test topology builder. @@ -190,78 +195,70 @@ def test_ospf_chaos_tc31_p1(request): step( "Create static routes(10.0.20.1/32) in R1 and redistribute " - "to OSPF using route map.") + "to OSPF using route map." + ) # Create Static routes input_dict = { "r0": { "static_routes": [ { - "network": NETWORK['ipv4'][0], + "network": NETWORK["ipv4"][0], "no_of_ip": 5, - "next_hop": 'Null0', + "next_hop": "Null0", } ] } } result = create_static_routes(tgen, input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r0 = { - "r0": { - "ospf": { - "redistribute": [{ - "redist_type": "static" - }] - } - } - } + ospf_red_r0 = {"r0": {"ospf": {"redistribute": [{"redist_type": "static"}]}}} result = create_router_ospf(tgen, topo, ospf_red_r0) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Verify OSPF neighbors after base config is done.") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step("Verify that route is advertised to R1.") - dut = 'r1' - protocol = 'ospf' - nh = topo['routers']['r0']['links']['r1']['ipv4'].split('/')[0] + dut = "r1" + protocol = "ospf" + nh = topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0] result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib( - tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Kill OSPFd daemon on R0.") kill_router_daemons(tgen, "r0", ["ospfd"]) step("Verify OSPF neighbors are down after killing ospfd in R0") - dut = 'r0' + dut = "r0" # Api call verify whether OSPF is converged - ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, - expected=False) - assert ospf_covergence is not True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step("Verify that route advertised to R1 are deleted from RIB and FIB.") - dut = 'r1' - protocol = 'ospf' + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) assert result is not True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - expected=False) + result = verify_rib( + tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False + ) assert result is not True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) step("Bring up OSPFd daemon on R0.") start_router_daemons(tgen, "r0", ["ospfd"]) @@ -269,33 +266,32 @@ def test_ospf_chaos_tc31_p1(request): step("Verify OSPF neighbors are up after bringing back ospfd in R0") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") - dut = 'r1' - protocol = 'ospf' + " restart. Verify OSPF route table and ip route table." + ) + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Kill OSPFd daemon on R1.") kill_router_daemons(tgen, "r1", ["ospfd"]) step("Verify OSPF neighbors are down after killing ospfd in R1") - dut = 'r1' + dut = "r1" # Api call verify whether OSPF is converged - ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, - expected=False) - assert ospf_covergence is not True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step("Bring up OSPFd daemon on R1.") start_router_daemons(tgen, "r1", ["ospfd"]) @@ -303,23 +299,22 @@ def test_ospf_chaos_tc31_p1(request): step("Verify OSPF neighbors are up after bringing back ospfd in R1") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") + " restart. Verify OSPF route table and ip route table." + ) - dut = 'r1' - protocol = 'ospf' + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) write_test_footer(tc_name) @@ -335,104 +330,91 @@ def test_ospf_chaos_tc32_p1(request): step( "Create static routes(10.0.20.1/32) in R1 and redistribute " - "to OSPF using route map.") + "to OSPF using route map." + ) # Create Static routes input_dict = { "r0": { "static_routes": [ { - "network": NETWORK['ipv4'][0], + "network": NETWORK["ipv4"][0], "no_of_ip": 5, - "next_hop": 'Null0', + "next_hop": "Null0", } ] } } result = create_static_routes(tgen, input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r0 = { - "r0": { - "ospf": { - "redistribute": [{ - "redist_type": "static" - }] - } - } - } + ospf_red_r0 = {"r0": {"ospf": {"redistribute": [{"redist_type": "static"}]}}} result = create_router_ospf(tgen, topo, ospf_red_r0) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Verify OSPF neighbors after base config is done.") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step("Verify that route is advertised to R1.") - dut = 'r1' - protocol = 'ospf' + dut = "r1" + protocol = "ospf" - nh = topo['routers']['r0']['links']['r1']['ipv4'].split('/')[0] + nh = topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0] result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Restart frr on R0") - stop_router(tgen, 'r0') - start_router(tgen, 'r0') + stop_router(tgen, "r0") + start_router(tgen, "r0") step("Verify OSPF neighbors are up after restarting R0") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") - dut = 'r1' - protocol = 'ospf' + " restart. Verify OSPF route table and ip route table." + ) + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Restart frr on R1") - stop_router(tgen, 'r1') - start_router(tgen, 'r1') + stop_router(tgen, "r1") + start_router(tgen, "r1") step("Verify OSPF neighbors are up after restarting R1") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") - dut = 'r1' - protocol = 'ospf' + " restart. Verify OSPF route table and ip route table." + ) + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) write_test_footer(tc_name) @@ -453,70 +435,62 @@ def test_ospf_chaos_tc34_p1(request): step( "Create static routes(10.0.20.1/32) in R1 and redistribute " - "to OSPF using route map.") + "to OSPF using route map." + ) # Create Static routes input_dict = { "r0": { "static_routes": [ { - "network": NETWORK['ipv4'][0], + "network": NETWORK["ipv4"][0], "no_of_ip": 5, - "next_hop": 'Null0', + "next_hop": "Null0", } ] } } result = create_static_routes(tgen, input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r0 = { - "r0": { - "ospf": { - "redistribute": [{ - "redist_type": "static" - }] - } - } - } + ospf_red_r0 = {"r0": {"ospf": {"redistribute": [{"redist_type": "static"}]}}} result = create_router_ospf(tgen, topo, ospf_red_r0) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Verify OSPF neighbors after base config is done.") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step("Verify that route is advertised to R1.") - dut = 'r1' - protocol = 'ospf' - nh = topo['routers']['r0']['links']['r1']['ipv4'].split('/')[0] + dut = "r1" + protocol = "ospf" + nh = topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0] result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Kill staticd daemon on R0.") kill_router_daemons(tgen, "r0", ["staticd"]) step("Verify that route advertised to R1 are deleted from RIB and FIB.") - dut = 'r1' - protocol = 'ospf' + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) assert result is not True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - expected=False) + result = verify_rib( + tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False + ) assert result is not True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) step("Bring up staticd daemon on R0.") start_router_daemons(tgen, "r0", ["staticd"]) @@ -524,22 +498,21 @@ def test_ospf_chaos_tc34_p1(request): step("Verify OSPF neighbors are up after bringing back ospfd in R0") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") - dut = 'r1' - protocol = 'ospf' + " restart. Verify OSPF route table and ip route table." + ) + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Kill staticd daemon on R1.") kill_router_daemons(tgen, "r1", ["staticd"]) @@ -550,23 +523,22 @@ def test_ospf_chaos_tc34_p1(request): step("Verify OSPF neighbors are up after bringing back ospfd in R1") # Api call verify whether OSPF is converged ospf_covergence = verify_ospf_neighbor(tgen, topo) - assert ospf_covergence is True, ("setup_module :Failed \n Error:" - " {}".format(ospf_covergence)) + assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf_covergence + ) step( "All the neighbours are up and routes are installed before the" - " restart. Verify OSPF route table and ip route table.") + " restart. Verify OSPF route table and ip route table." + ) - dut = 'r1' - protocol = 'ospf' + dut = "r1" + protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - next_hop=nh) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) write_test_footer(tc_name) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py index c90275ecb0..be18ba5a78 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py @@ -146,7 +146,6 @@ def setup_module(mod): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info("Running setup_module() done") @@ -397,10 +396,7 @@ def test_ospf_p2mp_tc1_p0(request): "links": { "r3": { "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], - "ospf": { - "area": "0.0.0.0", - "networkType":"POINTOMULTIPOINT" - }, + "ospf": {"area": "0.0.0.0", "networkType": "POINTOMULTIPOINT"}, } } } diff --git a/tests/topotests/pbr-topo1/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index 4b6de51c86..1a024063b8 100644 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -82,6 +82,7 @@ class NetworkTopo(Topo): ## ##################################################### + def setup_module(module): "Setup topology" tgen = Topogen(NetworkTopo, module.__name__) diff --git a/tests/topotests/pim-basic/test_pim.py b/tests/topotests/pim-basic/test_pim.py index 918d3847ce..4debbeb851 100644 --- a/tests/topotests/pim-basic/test_pim.py +++ b/tests/topotests/pim-basic/test_pim.py @@ -45,6 +45,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.pimd] + class PIMTopo(Topo): def build(self, *_args, **_opts): "Build function" diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index 0c45a09445..562e754f21 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -24,6 +24,7 @@ markers = sharpd: Tests that run against SHARPD staticd: Tests that run against STATICD vrrpd: Tests that run against VRRPD + snmp: Tests that run against snmp changes [topogen] # Default configuration values diff --git a/tests/topotests/simple-snmp-test/test_simple_snmp.py b/tests/topotests/simple-snmp-test/test_simple_snmp.py index 88ff01bf0a..5647e2b663 100755 --- a/tests/topotests/simple-snmp-test/test_simple_snmp.py +++ b/tests/topotests/simple-snmp-test/test_simple_snmp.py @@ -46,6 +46,8 @@ from lib.snmptest import SnmpTester # Required to instantiate the topology builder class. from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.snmp] + class TemplateTopo(Topo): "Test topology builder" diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py index 712a40c738..a4cc8e8e7a 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py @@ -35,6 +35,7 @@ import time import os import pytest import platform + # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, "../")) @@ -44,6 +45,7 @@ sys.path.append(os.path.join(CWD, "../lib/")) from mininet.topo import Topo from lib.topogen import Topogen, get_topogen from lib.topotest import version_cmp + # Import topoJson from lib, to create topology and initial configuration from lib.common_config import ( start_topology, @@ -121,9 +123,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py index c009929a48..6649915dec 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py @@ -163,9 +163,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence @@ -854,12 +856,12 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ebgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) - write_test_footer(tc_name) @@ -1129,9 +1131,10 @@ def test_static_route_8nh_diff_AD_ebgp_ecmp_p1_tc8_ebgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) write_test_footer(tc_name) @@ -1339,7 +1342,15 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ebgp(request): " value and all the nexthop populated in RIB and FIB again" ) for addr_type in ADDR_TYPES: - input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type],}]}} + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + } + ] + } + } nh = NEXT_HOP_IP["nh1"][addr_type] result = verify_rib( tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True @@ -1468,9 +1479,10 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ebgp(request): protocol=protocol, fib=True, ) - assert result is True, ( - "Testcase {} : Failed \nError: Route " - " is missing in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \nError: Route " " is missing in RIB".format( + tc_name ) write_test_footer(tc_name) diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py index 3d41d89443..9b9749340e 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py @@ -88,6 +88,7 @@ NEXT_HOP_IP = {} pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + class CreateTopo(Topo): """ Test CreateTopo - topology 1. @@ -126,9 +127,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py index ca67ff6645..8c2fdfca13 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py @@ -125,9 +125,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py index 2dc0a60d51..644ddc02d4 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py @@ -165,9 +165,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence @@ -884,9 +886,10 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) step("BGP neighbor remove and add") @@ -907,9 +910,10 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) dut = "r3" @@ -917,9 +921,10 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) step("Remove the redistribute static knob") @@ -1274,9 +1279,10 @@ def test_static_route_8nh_diff_AD_ibgp_ecmp_p1_tc7_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) step("BGP neighbor remove and add") @@ -1297,9 +1303,10 @@ def test_static_route_8nh_diff_AD_ibgp_ecmp_p1_tc7_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) dut = "r3" @@ -1307,9 +1314,10 @@ def test_static_route_8nh_diff_AD_ibgp_ecmp_p1_tc7_ibgp(request): for addr_type in ADDR_TYPES: input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type]}]}} result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) - assert result is True, ( - "Testcase {} : Failed \n" - "Error: Routes are still present in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format( + tc_name ) step("Remove the redistribute static knob") @@ -1557,7 +1565,15 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ibgp(request): " value and all the nexthop populated in RIB and FIB again" ) for addr_type in ADDR_TYPES: - input_dict_4 = {"r2": {"static_routes": [{"network": PREFIX1[addr_type],}]}} + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + } + ] + } + } nh = NEXT_HOP_IP["nh1"][addr_type] result = verify_rib( tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True @@ -1686,9 +1702,10 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ibgp(request): protocol=protocol, fib=True, ) - assert result is True, ( - "Testcase {} : Failed \nError: Route " - " is missing in RIB".format(tc_name) + assert ( + result is True + ), "Testcase {} : Failed \nError: Route " " is missing in RIB".format( + tc_name ) step("Remove the redistribute static knob") diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py index 3eb431d64f..8f9d88a442 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py @@ -149,9 +149,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py index 01fdff69e6..e9960c7907 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py @@ -69,6 +69,7 @@ from lib.bgp import ( ) from lib.topojson import build_topo_from_json, build_config_from_json from lib.topotest import version_cmp + # Reading the data from JSON File for topology creation jsonFile = "{}/static_routes_topo4_ibgp.json".format(CWD) try: @@ -85,6 +86,7 @@ NEXT_HOP_IP = {} pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + class CreateTopo(Topo): """ Test CreateTopo - topology 1. @@ -123,9 +125,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('These tests will not run. (have kernel "{}", ' - 'requires kernel >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) # Checking BGP convergence diff --git a/tests/topotests/zebra_rib/test_zebra_rib.py b/tests/topotests/zebra_rib/test_zebra_rib.py index daf8f7be20..9fcf7b6820 100644 --- a/tests/topotests/zebra_rib/test_zebra_rib.py +++ b/tests/topotests/zebra_rib/test_zebra_rib.py @@ -76,9 +76,11 @@ def setup_module(mod): router_list = tgen.routers() for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) router.load_config( - TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname))) + TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname)) + ) # Initialize all routers. tgen.start_router() @@ -159,6 +161,7 @@ def test_zebra_kernel_override(): _, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5) assert result is None, '"r1" JSON output mismatches' + def test_route_map_usage(): "Test that FRR only reruns over routes associated with the routemap" logger.info("Test that FRR runs on selected re's on route-map changes") @@ -174,7 +177,9 @@ def test_route_map_usage(): r1.vtysh_cmd("conf\nroute-map static permit 10\nset src 192.168.215.1") r1.vtysh_cmd("conf\naccess-list 5 seq 5 permit 10.0.0.44/32") r1.vtysh_cmd("conf\naccess-list 10 seq 5 permit 10.0.1.0/24") - r1.vtysh_cmd("conf\nroute-map sharp permit 10\nmatch ip address 10\nset src 192.168.214.1") + r1.vtysh_cmd( + "conf\nroute-map sharp permit 10\nmatch ip address 10\nset src 192.168.214.1" + ) r1.vtysh_cmd("conf\nroute-map sharp permit 20\nset src 192.168.213.1") r1.vtysh_cmd("conf\nip protocol static route-map static") r1.vtysh_cmd("conf\nip protocol sharp route-map sharp") @@ -186,47 +191,57 @@ def test_route_map_usage(): static_rmapfile = "%s/r1/static_rmap.ref" % (thisDir) expected = open(static_rmapfile).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + expected = ("\n".join(expected.splitlines()) + "\n").rstrip() actual = r1.vtysh_cmd("show route-map static") - actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() - logger.info("Does the show route-map static command run the correct number of times") + actual = ("\n".join(actual.splitlines()) + "\n").rstrip() + logger.info( + "Does the show route-map static command run the correct number of times" + ) - diff = topotest.get_textdiff(actual, expected, - title1 = "Actual Route-map output", - title2 = "Expected Route-map output") + diff = topotest.get_textdiff( + actual, + expected, + title1="Actual Route-map output", + title2="Expected Route-map output", + ) if diff: logger.info("Actual:") logger.info(actual) logger.info("Expected:") logger.info(expected) srun = r1.vtysh_cmd("show run") - srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + srun = ("\n".join(srun.splitlines()) + "\n").rstrip() logger.info("Show run") logger.info(srun) assert 0, "r1 static route processing:\n" sharp_rmapfile = "%s/r1/sharp_rmap.ref" % (thisDir) expected = open(sharp_rmapfile).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + expected = ("\n".join(expected.splitlines()) + "\n").rstrip() actual = r1.vtysh_cmd("show route-map sharp") - actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() + actual = ("\n".join(actual.splitlines()) + "\n").rstrip() logger.info("Does the show route-map sharp command run the correct number of times") - diff = topotest.get_textdiff(actual, expected, - title1 = "Actual Route-map output", - title2 = "Expected Route-map output") + diff = topotest.get_textdiff( + actual, + expected, + title1="Actual Route-map output", + title2="Expected Route-map output", + ) if diff: logger.info("Actual:") logger.info(actual) logger.info("Expected:") logger.info(expected) srun = r1.vtysh_cmd("show run") - srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + srun = ("\n".join(srun.splitlines()) + "\n").rstrip() logger.info("Show run:") logger.info(srun) assert 0, "r1 sharp route-map processing:\n" - logger.info("Add a extension to the static route-map to see the static route go away") + logger.info( + "Add a extension to the static route-map to see the static route go away" + ) r1.vtysh_cmd("conf\nroute-map sharp deny 5\nmatch ip address 5") sleep(2) # we are only checking the kernel here as that this will give us the implied @@ -236,9 +251,9 @@ def test_route_map_usage(): logger.info("Test that the routes installed are correct") sharp_ipfile = "%s/r1/iproute.ref" % (thisDir) expected = open(sharp_ipfile).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + expected = ("\n".join(expected.splitlines()) + "\n").rstrip() actual = r1.run("ip route show") - actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() + actual = ("\n".join(actual.splitlines()) + "\n").rstrip() actual = re.sub(r" nhid [0-9][0-9]", "", actual) actual = re.sub(r" proto sharp", " proto XXXX", actual) actual = re.sub(r" proto static", " proto XXXX", actual) @@ -250,9 +265,9 @@ def test_route_map_usage(): actual = re.sub(r" proto XXXX ", " proto XXXX ", actual) actual = re.sub(r" metric", " metric", actual) actual = re.sub(r" link ", " link ", actual) - diff = topotest.get_textdiff(actual, expected, - title1 = "Actual ip route show", - title2 = "Expected ip route show") + diff = topotest.get_textdiff( + actual, expected, title1="Actual ip route show", title2="Expected ip route show" + ) if diff: logger.info("Actual:") @@ -260,11 +275,12 @@ def test_route_map_usage(): logger.info("Expected:") logger.info(expected) srun = r1.vtysh_cmd("show run") - srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + srun = ("\n".join(srun.splitlines()) + "\n").rstrip() logger.info("Show run:") logger.info(srun) assert 0, "r1 ip route show is not correct:" + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index e026a28628..6e809a0713 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2693,7 +2693,7 @@ static int show_per_daemon(struct vty *vty, struct cmd_token **argv, int argc, char *line = do_prepend(vty, argv, argc); for (i = 0; i < array_size(vtysh_client); i++) - if (vtysh_client[i].fd >= 0) { + if (vtysh_client[i].fd >= 0 || vtysh_client[i].next) { vty_out(vty, headline, vtysh_client[i].name); ret = vtysh_client_execute(&vtysh_client[i], line); vty_out(vty, "\n"); @@ -2851,6 +2851,24 @@ DEFUN (vtysh_show_error_code, } /* Northbound. */ +DEFUN (show_config_running, + show_config_running_cmd, + "show configuration running\ + [<json|xml> [translate WORD]]\ + [with-defaults]" DAEMONS_LIST, + SHOW_STR + "Configuration information\n" + "Running configuration\n" + "Change output format to JSON\n" + "Change output format to XML\n" + "Translate output\n" + "YANG module translator\n" + "Show default values\n" + DAEMONS_STR) +{ + return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text); +} + DEFUN (show_yang_operational_data, show_yang_operational_data_cmd, "show yang operational-data XPATH\ @@ -4564,6 +4582,7 @@ void vtysh_init_vty(void) install_element(CONFIG_NODE, &vtysh_debug_memstats_cmd); /* northbound */ + install_element(ENABLE_NODE, &show_config_running_cmd); install_element(ENABLE_NODE, &show_yang_operational_data_cmd); install_element(ENABLE_NODE, &debug_nb_cmd); install_element(CONFIG_NODE, &debug_nb_cmd); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 00471b9645..98bde4b3c0 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -561,6 +561,8 @@ static void netlink_interface_update_l2info(struct interface *ifp, netlink_extract_vlan_info(link_data, &vlan_info); zebra_l2_vlanif_update(ifp, &vlan_info); + zebra_evpn_acc_bd_svi_set(ifp->info, NULL, + !!if_is_operative(ifp)); } else if (IS_ZEBRA_IF_VXLAN(ifp)) { struct zebra_l2info_vxlan vxlan_info; @@ -717,6 +719,21 @@ static void netlink_proc_dplane_if_protodown(struct zebra_if *zif, } } +static uint8_t netlink_parse_lacp_bypass(struct rtattr **linkinfo) +{ + uint8_t bypass = 0; + struct rtattr *mbrinfo[IFLA_BOND_SLAVE_MAX + 1]; + + memset(mbrinfo, 0, sizeof(mbrinfo)); + parse_rtattr_nested(mbrinfo, IFLA_BOND_SLAVE_MAX, + linkinfo[IFLA_INFO_SLAVE_DATA]); + if (mbrinfo[IFLA_BOND_SLAVE_AD_RX_BYPASS]) + bypass = *(uint8_t *)RTA_DATA( + mbrinfo[IFLA_BOND_SLAVE_AD_RX_BYPASS]); + + return bypass; +} + /* * Called from interface_lookup_netlink(). This function is only used * during bootstrap. @@ -741,6 +758,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) ifindex_t bond_ifindex = IFINDEX_INTERNAL; struct zebra_if *zif; ns_id_t link_nsid = ns_id; + uint8_t bypass = 0; zns = zebra_ns_lookup(ns_id); ifi = NLMSG_DATA(h); @@ -814,6 +832,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) } else if (slave_kind && (strcmp(slave_kind, "bond") == 0)) { zif_slave_type = ZEBRA_IF_SLAVE_BOND; bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); + bypass = netlink_parse_lacp_bypass(linkinfo); } else zif_slave_type = ZEBRA_IF_SLAVE_OTHER; } @@ -880,7 +899,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) - zebra_l2if_update_bond_slave(ifp, bond_ifindex); + zebra_l2if_update_bond_slave(ifp, bond_ifindex, !!bypass); if (tb[IFLA_PROTO_DOWN]) { uint8_t protodown; @@ -1320,6 +1339,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) struct zebra_if *zif; ns_id_t link_nsid = ns_id; ifindex_t master_infindex = IFINDEX_INTERNAL; + uint8_t bypass = 0; zns = zebra_ns_lookup(ns_id); ifi = NLMSG_DATA(h); @@ -1421,6 +1441,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) zif_slave_type = ZEBRA_IF_SLAVE_BOND; master_infindex = bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); + bypass = netlink_parse_lacp_bypass(linkinfo); } else zif_slave_type = ZEBRA_IF_SLAVE_OTHER; } @@ -1482,7 +1503,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) bridge_ifindex, ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) - zebra_l2if_update_bond_slave(ifp, bond_ifindex); + zebra_l2if_update_bond_slave(ifp, bond_ifindex, + !!bypass); if (tb[IFLA_PROTO_DOWN]) { uint8_t protodown; @@ -1595,7 +1617,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) bridge_ifindex, ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave) - zebra_l2if_update_bond_slave(ifp, bond_ifindex); + zebra_l2if_update_bond_slave(ifp, bond_ifindex, + !!bypass); if (tb[IFLA_PROTO_DOWN]) { uint8_t protodown; @@ -1631,6 +1654,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BOND(ifp)) zebra_l2if_update_bond(ifp, false); + if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) + zebra_l2if_update_bond_slave(ifp, bond_ifindex, false); /* Special handling for bridge or VxLAN interfaces. */ if (IS_ZEBRA_IF_BRIDGE(ifp)) zebra_l2_bridge_del(ifp); diff --git a/zebra/interface.c b/zebra/interface.c index fc34a6fb9e..6373b4b200 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -241,6 +241,7 @@ static int if_zebra_delete_hook(struct interface *ifp) #endif /* HAVE_RTADV */ zebra_evpn_if_cleanup(zebra_if); + zebra_evpn_mac_ifp_del(ifp); if_nhg_dependents_release(ifp); zebra_if_nhg_dependents_free(zebra_if); @@ -826,6 +827,7 @@ void if_delete_update(struct interface *ifp) memset(&zif->brslave_info, 0, sizeof(struct zebra_l2info_brslave)); zebra_evpn_if_cleanup(zif); + zebra_evpn_mac_ifp_del(ifp); } if (!ifp->configured) { @@ -1183,6 +1185,11 @@ void zebra_if_update_all_links(void) zif->link?zif->link->name:"unk", zif->link_ifindex); } + + /* Update VLAN<=>SVI map */ + if (IS_ZEBRA_IF_VLAN(ifp)) + zebra_evpn_acc_bd_svi_set(zif, NULL, + !!if_is_operative(ifp)); } } @@ -1599,6 +1606,9 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) } } + if (zebra_if->flags & ZIF_FLAG_LACP_BYPASS) + vty_out(vty, " LACP bypass: on\n"); + zebra_evpn_if_es_print(vty, zebra_if); vty_out(vty, " protodown: %s %s\n", (zebra_if->flags & ZIF_FLAG_PROTODOWN) ? "on" : "off", diff --git a/zebra/interface.h b/zebra/interface.h index 8dcb477f10..64569742b4 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -286,6 +286,9 @@ struct zebra_es_if_info { esi_t esi; uint16_t df_pref; + uint8_t flags; +#define ZIF_CFG_ES_FLAG_BYPASS (1 << 0) + struct zebra_evpn_es *es; /* local ES */ }; @@ -297,7 +300,13 @@ enum zebra_if_flags { ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP = (1 << 1), /* Dataplane protodown-on */ - ZIF_FLAG_PROTODOWN = (1 << 2) + ZIF_FLAG_PROTODOWN = (1 << 2), + + /* LACP bypass state is set by the dataplane on a bond member + * and inherited by the bond (if one or more bond members are in + * a bypass state the bond is placed in a bypass state) + */ + ZIF_FLAG_LACP_BYPASS = (1 << 3) }; /* `zebra' daemon local interface structure. */ @@ -386,6 +395,9 @@ struct zebra_if { */ enum protodown_reasons protodown_rc; + /* list of zebra_mac entries using this interface as destination */ + struct list *mac_list; + /* Link fields - for sub-interfaces. */ ifindex_t link_ifindex; struct interface *link; diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 2ab5fd3a4c..5352c6214d 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -93,10 +93,10 @@ static int irdp_if_delete(struct interface *ifp) return 0; } -static const char *inet_2a(uint32_t a, char *b) +static const char *inet_2a(uint32_t a, char *b, size_t b_len) { - sprintf(b, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF, - (a >> 24) & 0xFF); + snprintf(b, b_len, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF, + (a >> 16) & 0xFF, (a >> 24) & 0xFF); return b; } @@ -140,7 +140,8 @@ static int if_group(struct interface *ifp, int sock, uint32_t group, flog_err_sys(EC_LIB_SOCKET, "IRDP: %s can't setsockopt %s: %s", add_leave == IP_ADD_MEMBERSHIP ? "join group" : "leave group", - inet_2a(group, b1), safe_strerror(errno)); + inet_2a(group, b1, sizeof(b1)), + safe_strerror(errno)); return ret; } @@ -162,7 +163,8 @@ static int if_add_group(struct interface *ifp) if (irdp->flags & IF_DEBUG_MISC) zlog_debug("IRDP: Adding group %s for %s", - inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); + inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1, sizeof(b1)), + ifp->name); return 0; } @@ -183,7 +185,8 @@ static int if_drop_group(struct interface *ifp) if (irdp->flags & IF_DEBUG_MISC) zlog_debug("IRDP: Leaving group %s for %s", - inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); + inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1, sizeof(b1)), + ifp->name); return 0; } @@ -383,7 +386,8 @@ int irdp_config_write(struct vty *vty, struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv)) vty_out(vty, " ip irdp address %s preference %d\n", - inet_2a(adv->ip.s_addr, b1), adv->pref); + inet_2a(adv->ip.s_addr, b1, sizeof(b1)), + adv->pref); vty_out(vty, " ip irdp holdtime %d\n", irdp->Lifetime); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b980306149..99cb82e224 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1132,8 +1132,8 @@ static int build_label_stack(struct mpls_label_stack *nh_label, if (IS_ZEBRA_DEBUG_KERNEL) { if (!num_labels) - sprintf(label_buf, "label %u", - nh_label->label[i]); + snprintf(label_buf, label_buf_size, "label %u", + nh_label->label[i]); else { snprintf(label_buf1, sizeof(label_buf1), "/%u", nh_label->label[i]); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index db2b9e002e..b9b6b4af71 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3251,6 +3251,24 @@ enum zebra_dplane_result dplane_local_mac_add(const struct interface *ifp, } /* + * Enqueue local mac del + */ +enum zebra_dplane_result +dplane_local_mac_del(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, + const struct ethaddr *mac) +{ + enum zebra_dplane_result result; + struct in_addr vtep_ip; + + vtep_ip.s_addr = 0; + + /* Use common helper api */ + result = mac_update_common(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp, vid, + mac, vtep_ip, false, 0, 0); + return result; +} +/* * Public api to init an empty context - either newly-allocated or * reset/cleared - for a MAC update. */ diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 595d3fe562..f3ab1058a5 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -582,6 +582,11 @@ enum zebra_dplane_result dplane_local_mac_add(const struct interface *ifp, uint32_t set_static, uint32_t set_inactive); +enum zebra_dplane_result +dplane_local_mac_del(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, + const struct ethaddr *mac); + enum zebra_dplane_result dplane_rem_mac_del(const struct interface *ifp, const struct interface *bridge_ifp, vlanid_t vid, diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index b232c664bc..d7076ccce6 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -151,6 +151,9 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) buf, sizeof(buf))); json_object_string_add(json, "advertiseGatewayMacip", zevpn->advertise_gw_macip ? "Yes" : "No"); + json_object_string_add(json, "advertiseSviMacip", + zevpn->advertise_svi_macip ? "Yes" + : "No"); json_object_int_add(json, "numMacs", num_macs); json_object_int_add(json, "numArpNd", num_neigh); } @@ -194,6 +197,8 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) num_neigh); vty_out(vty, " Advertise-gw-macip: %s\n", zevpn->advertise_gw_macip ? "Yes" : "No"); + vty_out(vty, " Advertise-svi-macip: %s\n", + zevpn->advertise_svi_macip ? "Yes" : "No"); } } @@ -429,7 +434,7 @@ int zebra_evpn_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, vxl = &zif->l2info.vxl; if (zebra_evpn_mac_gw_macip_add(ifp, zevpn, ip, &mac, macaddr, - vxl->access_vlan) + vxl->access_vlan, true) != 0) return -1; @@ -569,7 +574,9 @@ void zebra_evpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket, return; /* Add primary SVI MAC-IP */ - zebra_evpn_add_macip_for_intf(vlan_if, zevpn); + if (advertise_svi_macip_enabled(zevpn) + || advertise_gw_macip_enabled(zevpn)) + zebra_evpn_add_macip_for_intf(vlan_if, zevpn); if (advertise_gw_macip_enabled(zevpn)) { /* Add VRR MAC-IP - if any*/ @@ -925,14 +932,20 @@ void zebra_evpn_read_mac_neigh(zebra_evpn_t *zevpn, struct interface *ifp) macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if); vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (vlan_if) { + /* Add SVI MAC */ + zebra_evpn_acc_bd_svi_mac_add(vlan_if); /* Add SVI MAC-IP */ - zebra_evpn_add_macip_for_intf(vlan_if, zevpn); + if (advertise_svi_macip_enabled(zevpn) + || advertise_gw_macip_enabled(zevpn)) + zebra_evpn_add_macip_for_intf(vlan_if, zevpn); /* Add VRR MAC-IP - if any*/ - vrr_if = zebra_get_vrr_intf_for_svi(vlan_if); - if (vrr_if) - zebra_evpn_add_macip_for_intf(vrr_if, zevpn); + if (advertise_gw_macip_enabled(zevpn)) { + vrr_if = zebra_get_vrr_intf_for_svi(vlan_if); + if (vrr_if) + zebra_evpn_add_macip_for_intf(vrr_if, zevpn); + } neigh_read_for_vlan(zns, vlan_if); } diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 5227a480fc..142a199bd7 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -94,6 +94,97 @@ uint32_t num_dup_detected_macs(zebra_evpn_t *zevpn) return num_macs; } +/* Setup mac_list against the access port. This is done when a mac uses + * the ifp as destination for the first time + */ +static void zebra_evpn_mac_ifp_new(struct zebra_if *zif) +{ + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("MAC list created for ifp %s (%u)", zif->ifp->name, + zif->ifp->ifindex); + + zif->mac_list = list_new(); + listset_app_node_mem(zif->mac_list); +} + +/* Free up the mac_list if any as a part of the interface del/cleanup */ +void zebra_evpn_mac_ifp_del(struct interface *ifp) +{ + struct zebra_if *zif = ifp->info; + + if (zif->mac_list) { + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("MAC list deleted for ifp %s (%u)", + zif->ifp->name, zif->ifp->ifindex); + list_delete(&zif->mac_list); + } +} + +/* Unlink local mac from a destination access port */ +static void zebra_evpn_mac_ifp_unlink(zebra_mac_t *zmac) +{ + struct zebra_if *zif; + struct interface *ifp = zmac->ifp; + + if (!ifp) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("VNI %d MAC %pEA unlinked from ifp %s (%u)", + zmac->zevpn->vni, + &zmac->macaddr, + ifp->name, ifp->ifindex); + + zif = ifp->info; + list_delete_node(zif->mac_list, &zmac->ifp_listnode); + zmac->ifp = NULL; +} + +/* Link local mac to destination access port. This is done only if the + * local mac is associated with a zero ESI i.e. single attach or lacp-bypass + * bridge port member + */ +static void zebra_evpn_mac_ifp_link(zebra_mac_t *zmac, struct interface *ifp) +{ + struct zebra_if *zif; + + if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) + return; + + /* already linked to the destination */ + if (zmac->ifp == ifp) + return; + + /* unlink the mac from any old destination */ + if (zmac->ifp) + zebra_evpn_mac_ifp_unlink(zmac); + + if (!ifp) + return; + + zif = ifp->info; + /* the interface mac_list is created on first mac link attempt */ + if (!zif->mac_list) + zebra_evpn_mac_ifp_new(zif); + + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("VNI %d MAC %pEA linked to ifp %s (%u)", + zmac->zevpn->vni, + &zmac->macaddr, + ifp->name, ifp->ifindex); + + zmac->ifp = ifp; + listnode_init(&zmac->ifp_listnode, zmac); + listnode_add(zif->mac_list, &zmac->ifp_listnode); +} + +/* If the mac is a local mac clear links to destination access port */ +void zebra_evpn_mac_clear_fwd_info(zebra_mac_t *zmac) +{ + zebra_evpn_mac_ifp_unlink(zmac); + memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info)); +} + /* * Install remote MAC into the forwarding plane. */ @@ -221,8 +312,8 @@ void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); } - /* If no neighbors, delete the MAC. */ - if (list_isempty(mac->neigh_list)) + /* If no references, delete the MAC. */ + if (!zebra_evpn_mac_in_use(mac)) zebra_evpn_mac_del(zevpn, mac); } @@ -583,6 +674,9 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) json_object_boolean_true_add(json_mac, "stickyMac"); + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) + json_object_boolean_true_add(json_mac, "sviMac"); + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) json_object_boolean_true_add(json_mac, "defaultGateway"); @@ -685,6 +779,9 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) vty_out(vty, " Sticky Mac "); + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) + vty_out(vty, " SVI-Mac "); + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) vty_out(vty, " Default-gateway Mac "); @@ -747,14 +844,10 @@ static char *zebra_evpn_print_mac_flags(zebra_mac_t *mac, char *flags_buf, size_t flags_buf_sz) { snprintf(flags_buf, flags_buf_sz, "%s%s%s%s", - mac->sync_neigh_cnt ? - "N" : "", - (mac->flags & ZEBRA_MAC_ES_PEER_ACTIVE) ? - "P" : "", - (mac->flags & ZEBRA_MAC_ES_PEER_PROXY) ? - "X" : "", - (mac->flags & ZEBRA_MAC_LOCAL_INACTIVE) ? - "I" : ""); + mac->sync_neigh_cnt ? "N" : "", + (mac->flags & ZEBRA_MAC_ES_PEER_ACTIVE) ? "P" : "", + (mac->flags & ZEBRA_MAC_ES_PEER_PROXY) ? "X" : "", + (mac->flags & ZEBRA_MAC_LOCAL_INACTIVE) ? "I" : ""); return flags_buf; } @@ -1075,6 +1168,9 @@ int zebra_evpn_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac) /* force de-ref any ES entry linked to the MAC */ zebra_evpn_es_mac_deref_entry(mac); + /* remove links to the destination access port */ + zebra_evpn_mac_clear_fwd_info(mac); + /* Cancel proxy hold timer */ zebra_evpn_mac_stop_hold_timer(mac); @@ -1684,7 +1780,7 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, } } mac->rem_seq = 0; - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + zebra_evpn_mac_clear_fwd_info(mac); mac->flags = new_flags; if (IS_ZEBRA_DEBUG_EVPN_MH_MAC && (old_flags != new_flags)) { @@ -1710,6 +1806,7 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, inform_dataplane = true; ctx->mac_inactive = true; } + /* if peer-flag is being set notify dataplane that the * entry must not be expired because of local inactivity */ @@ -1790,20 +1887,25 @@ static bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac, bool es_change; ns_id_t local_ns_id = NS_DEFAULT; struct zebra_vrf *zvrf; + struct zebra_evpn_es *es; zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); if (zvrf && zvrf->zns) local_ns_id = zvrf->zns->ns_id; - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + zebra_evpn_mac_clear_fwd_info(mac); - es_change = zebra_evpn_es_mac_ref_entry(mac, zif->es_info.es); + es = zif->es_info.es; + if (es && (es->flags & ZEBRA_EVPNES_BYPASS)) + es = NULL; + es_change = zebra_evpn_es_mac_ref_entry(mac, es); if (!mac->es) { /* if es is set fwd_info is not-relevant/taped-out */ mac->fwd_info.local.ifindex = ifp->ifindex; mac->fwd_info.local.ns_id = local_ns_id; mac->fwd_info.local.vid = vid; + zebra_evpn_mac_ifp_link(mac, ifp); } return es_change; @@ -1908,6 +2010,8 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, esi_t *old_esi; bool old_static = false; zebra_mac_t *mac; + bool old_es_present; + bool new_es_present; sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW); @@ -1971,7 +2075,16 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, zevpn, mac, seq, ipa_len, ipaddr, false)) return -1; + old_es_present = !!mac->es; zebra_evpn_es_mac_ref(mac, esi); + new_es_present = !!mac->es; + /* XXX - dataplane is curently not able to handle a MAC + * replace if the destination changes from L2-NHG to + * single VTEP and vice-versa. So delete the old entry + * and re-install + */ + if (old_es_present != new_es_present) + zebra_evpn_rem_mac_uninstall(zevpn, mac, false); } /* Check MAC's curent state is local (this is the case @@ -2016,8 +2129,8 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, } /* Set "auto" and "remote" forwarding info. */ + zebra_evpn_mac_clear_fwd_info(mac); UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); mac->fwd_info.r_vtep_ip = vtep_ip; @@ -2058,9 +2171,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, struct interface *ifp, struct ethaddr *macaddr, vlanid_t vid, bool sticky, bool local_inactive, - bool dp_static) + bool dp_static, zebra_mac_t *mac) { - zebra_mac_t *mac; char buf[ETHER_ADDR_STRLEN]; bool mac_sticky = false; bool inform_client = false; @@ -2077,7 +2189,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, assert(ifp); /* Check if we need to create or update or it is a NO-OP. */ - mac = zebra_evpn_mac_lookup(zevpn, macaddr); + if (!mac) + mac = zebra_evpn_mac_lookup(zevpn, macaddr); if (!mac) { if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) zlog_debug( @@ -2128,6 +2241,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, old_static = zebra_evpn_mac_is_static(mac); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) mac_sticky = true; + es_change = zebra_evpn_local_mac_update_fwd_info( + mac, ifp, vid); /* * Update any changes and if changes are relevant to @@ -2136,7 +2251,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, if (mac_sticky == sticky && old_ifp == ifp && old_vid == vid && old_local_inactive == local_inactive - && dp_static == old_static) { + && dp_static == old_static && !es_change) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( " Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, " @@ -2160,15 +2275,17 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, inform_client = true; } - es_change = zebra_evpn_local_mac_update_fwd_info( - mac, ifp, vid); /* If an es_change is detected we need to advertise * the route with a sequence that is one * greater. This is need to indicate a mac-move * to the ES peers */ if (es_change) { - mac->loc_seq = mac->loc_seq + 1; + /* update the sequence number only if the entry + * is locally active + */ + if (!local_inactive) + mac->loc_seq = mac->loc_seq + 1; /* force drop the peer/sync info as it is * simply no longer relevant */ @@ -2302,7 +2419,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, return 0; } -int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) +int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac, + bool clear_static) { char buf[ETHER_ADDR_STRLEN]; bool old_bgp_ready; @@ -2315,11 +2433,11 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) listcount(mac->neigh_list)); old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); - if (zebra_evpn_mac_is_static(mac)) { + if (!clear_static && zebra_evpn_mac_is_static(mac)) { /* this is a synced entry and can only be removed when the * es-peers stop advertising it. */ - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + zebra_evpn_mac_clear_fwd_info(mac); if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; @@ -2350,6 +2468,9 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) return 0; } + /* flush the peer info */ + zebra_evpn_mac_clear_sync_info(mac); + /* Update all the neigh entries associated with this mac */ zebra_evpn_process_neigh_on_local_mac_del(zevpn, mac); @@ -2359,6 +2480,9 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) zebra_evpn_es_mac_deref_entry(mac); + /* remove links to the destination access port */ + zebra_evpn_mac_clear_fwd_info(mac); + /* * If there are no neigh associated with the mac delete the mac * else mark it as AUTO for forward reference @@ -2376,7 +2500,8 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id) + struct ethaddr *macaddr, vlanid_t vlan_id, + bool def_gw) { char buf[ETHER_ADDR_STRLEN]; zebra_mac_t *mac; @@ -2400,10 +2525,11 @@ int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, } /* Set "local" forwarding info. */ + zebra_evpn_mac_clear_fwd_info(mac); SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + if (def_gw) + SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW); mac->fwd_info.local.ifindex = ifp->ifindex; mac->fwd_info.local.ns_id = local_ns_id; mac->fwd_info.local.vid = vlan_id; @@ -2412,3 +2538,63 @@ int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, return 0; } + +void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn) +{ + zebra_mac_t *mac; + struct ethaddr macaddr; + bool old_bgp_ready; + + if (!zebra_evpn_mh_do_adv_svi_mac()) + return; + + memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); + mac = zebra_evpn_mac_lookup(zevpn, &macaddr); + if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("SVI %s mac free", ifp->name); + + old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); + UNSET_FLAG(mac->flags, ZEBRA_MAC_SVI); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + false); + zebra_evpn_deref_ip2mac(mac->zevpn, mac); + } +} + +void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn) +{ + zebra_mac_t *mac = NULL; + struct ethaddr macaddr; + struct zebra_if *zif = ifp->info; + bool old_bgp_ready; + bool new_bgp_ready; + + if (!zebra_evpn_mh_do_adv_svi_mac() + || !zebra_evpn_send_to_client_ok(zevpn)) + return; + + memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); + + /* dup check */ + mac = zebra_evpn_mac_lookup(zevpn, &macaddr); + if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) + return; + + /* add/update mac */ + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("SVI %s mac add", zif->ifp->name); + + old_bgp_ready = (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags)) + ? true + : false; + + mac = NULL; + zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false); + if (mac) + SET_FLAG(mac->flags, ZEBRA_MAC_SVI); + + new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); +} diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index 242097907f..fb162f1a93 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -80,6 +80,8 @@ struct zebra_mac_t_ { * to advertise it as locally attached but with a "proxy" flag */ #define ZEBRA_MAC_LOCAL_INACTIVE 0x800 +/* The MAC entry was created because of advertise_svi_mac */ +#define ZEBRA_MAC_SVI 0x1000 #define ZEBRA_MAC_ALL_LOCAL_FLAGS (ZEBRA_MAC_LOCAL | ZEBRA_MAC_LOCAL_INACTIVE) #define ZEBRA_MAC_ALL_PEER_FLAGS \ @@ -88,7 +90,9 @@ struct zebra_mac_t_ { /* back pointer to zevpn */ zebra_evpn_t *zevpn; - /* Local or remote info. */ + /* Local or remote info. + * Note: fwd_info is only relevant if mac->es is NULL. + */ union { struct { ifindex_t ifindex; @@ -104,6 +108,16 @@ struct zebra_mac_t_ { /* memory used to link the mac to the es */ struct listnode es_listnode; + /* access-port/bridge member. only relevant for local macs that + * are associated with a zero-ESI, + * XXX - this belongs in fwd_info.local; however fwd_info is + * being cleared and memset to zero in different ways that can + * mess up the links. + */ + struct interface *ifp; + /* memory used to link the mac to the ifp */ + struct listnode ifp_listnode; + /* Mobility sequence numbers associated with this entry. */ uint32_t rem_seq; uint32_t loc_seq; @@ -201,6 +215,12 @@ static inline void zebra_evpn_mac_clear_sync_info(zebra_mac_t *mac) zebra_evpn_mac_stop_hold_timer(mac); } +static inline bool zebra_evpn_mac_in_use(zebra_mac_t *mac) +{ + return !list_isempty(mac->neigh_list) + || CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI); +} + struct hash *zebra_mac_db_create(const char *desc); uint32_t num_valid_macs(zebra_evpn_t *zevi); uint32_t num_dup_detected_macs(zebra_evpn_t *zevi); @@ -252,11 +272,17 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, struct interface *ifp, struct ethaddr *macaddr, vlanid_t vid, bool sticky, bool local_inactive, - bool dp_static); -int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac); + bool dp_static, zebra_mac_t *mac); +int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac, + bool clear_static); int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id); + struct ethaddr *macaddr, vlanid_t vlan_id, + bool def_gw); +void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn); +void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn); +void zebra_evpn_mac_ifp_del(struct interface *ifp); +void zebra_evpn_mac_clear_fwd_info(zebra_mac_t *zmac); #ifdef __cplusplus } diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 7e712bf1ee..5a28ee10c6 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -130,12 +130,6 @@ static struct zebra_evpn_es_evi *zebra_evpn_es_evi_new(struct zebra_evpn_es *es, return es_evi; } -/* returns TRUE if the EVPN is ready to be sent to BGP */ -static inline bool zebra_evpn_send_to_client_ok(zebra_evpn_t *zevpn) -{ - return !!(zevpn->flags & ZEVPN_READY_FOR_BGP); -} - /* Evaluate if the es_evi is ready to be sent BGP - * 1. If it is ready an add is sent to BGP * 2. If it is not ready a del is sent (if the ES had been previously added @@ -466,6 +460,9 @@ void zebra_evpn_update_all_es(zebra_evpn_t *zevpn) { struct zebra_evpn_es_evi *es_evi; struct listnode *node; + struct interface *vlan_if; + struct interface *vxlan_if; + struct zebra_if *vxlan_zif; /* the EVPN is now elgible as a base for EVPN-MH */ if (zebra_evpn_send_to_client_ok(zevpn)) @@ -475,6 +472,20 @@ void zebra_evpn_update_all_es(zebra_evpn_t *zevpn) for (ALL_LIST_ELEMENTS_RO(zevpn->local_es_evi_list, node, es_evi)) zebra_evpn_es_evi_re_eval_send_to_client(es_evi); + + /* reinstall SVI MAC */ + vxlan_if = zevpn->vxlan_if; + if (vxlan_if) { + vxlan_zif = vxlan_if->info; + if (if_is_operative(vxlan_if) + && vxlan_zif->brslave_info.br_if) { + vlan_if = zvni_map_to_svi( + vxlan_zif->l2info.vxl.access_vlan, + vxlan_zif->brslave_info.br_if); + if (vlan_if) + zebra_evpn_acc_bd_svi_mac_add(vlan_if); + } + } } /*****************************************************************************/ @@ -524,9 +535,11 @@ static struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid) /* A new broadcast domain can be created when a VLAN member or VLAN<=>VxLAN_IF * mapping is added. */ -static struct zebra_evpn_access_bd *zebra_evpn_acc_vl_new(vlanid_t vid) +static struct zebra_evpn_access_bd * +zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if) { struct zebra_evpn_access_bd *acc_bd; + struct interface *vlan_if; if (IS_ZEBRA_DEBUG_EVPN_MH_ES) zlog_debug("access vlan %d add", vid); @@ -544,6 +557,16 @@ static struct zebra_evpn_access_bd *zebra_evpn_acc_vl_new(vlanid_t vid) return NULL; } + /* check if an svi exists for the vlan */ + if (br_if) { + vlan_if = zvni_map_to_svi(vid, br_if); + if (vlan_if) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("vlan %d SVI %s set", vid, + vlan_if->name); + acc_bd->vlan_zif = vlan_if->info; + } + } return acc_bd; } @@ -556,6 +579,9 @@ static void zebra_evpn_acc_vl_free(struct zebra_evpn_access_bd *acc_bd) if (IS_ZEBRA_DEBUG_EVPN_MH_ES) zlog_debug("access vlan %d del", acc_bd->vid); + if (acc_bd->vlan_zif && acc_bd->zevpn && acc_bd->zevpn->mac_table) + zebra_evpn_mac_svi_del(acc_bd->vlan_zif->ifp, acc_bd->zevpn); + /* cleanup resources maintained against the ES */ list_delete(&acc_bd->mbr_zifs); @@ -584,6 +610,59 @@ static void zebra_evpn_acc_bd_free_on_deref(struct zebra_evpn_access_bd *acc_bd) zebra_evpn_acc_vl_free(acc_bd); } +/* called when a SVI is goes up/down */ +void zebra_evpn_acc_bd_svi_set(struct zebra_if *vlan_zif, + struct zebra_if *br_zif, bool is_up) +{ + struct zebra_evpn_access_bd *acc_bd; + struct zebra_l2info_bridge *br; + uint16_t vid; + struct zebra_if *tmp_br_zif = br_zif; + + if (!tmp_br_zif) { + if (!vlan_zif->link || !vlan_zif->link->info) + return; + + tmp_br_zif = vlan_zif->link->info; + } + + br = &tmp_br_zif->l2info.br; + /* ignore vlan unaware bridges */ + if (!br->vlan_aware) + return; + + vid = vlan_zif->l2info.vl.vid; + acc_bd = zebra_evpn_acc_vl_find(vid); + if (!acc_bd) + return; + + if (is_up) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("vlan %d SVI %s set", vid, + vlan_zif->ifp->name); + + acc_bd->vlan_zif = vlan_zif; + if (acc_bd->zevpn) + zebra_evpn_mac_svi_add(acc_bd->vlan_zif->ifp, + acc_bd->zevpn); + } else if (acc_bd->vlan_zif) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("vlan %d SVI clear", vid); + acc_bd->vlan_zif = NULL; + if (acc_bd->zevpn && acc_bd->zevpn->mac_table) + zebra_evpn_mac_svi_del(vlan_zif->ifp, acc_bd->zevpn); + } +} + +/* On some events macs are force-flushed. This api can be used to reinstate + * the svi-mac after such cleanup-events. + */ +void zebra_evpn_acc_bd_svi_mac_add(struct interface *vlan_if) +{ + zebra_evpn_acc_bd_svi_set(vlan_if->info, NULL, + if_is_operative(vlan_if)); +} + /* called when a EVPN-L2VNI is set or cleared against a BD */ static void zebra_evpn_acc_bd_evpn_set(struct zebra_evpn_access_bd *acc_bd, zebra_evpn_t *zevpn, zebra_evpn_t *old_zevpn) @@ -604,6 +683,15 @@ static void zebra_evpn_acc_bd_evpn_set(struct zebra_evpn_access_bd *acc_bd, else if (old_zevpn) zebra_evpn_local_es_evi_del(zif->es_info.es, old_zevpn); } + + if (acc_bd->vlan_zif) { + if (zevpn) + zebra_evpn_mac_svi_add(acc_bd->vlan_zif->ifp, + acc_bd->zevpn); + else if (old_zevpn && old_zevpn->mac_table) + zebra_evpn_mac_svi_del(acc_bd->vlan_zif->ifp, + old_zevpn); + } } /* handle VLAN->VxLAN_IF association */ @@ -618,7 +706,8 @@ void zebra_evpn_vl_vxl_ref(uint16_t vid, struct zebra_if *vxlan_zif) acc_bd = zebra_evpn_acc_vl_find(vid); if (!acc_bd) - acc_bd = zebra_evpn_acc_vl_new(vid); + acc_bd = zebra_evpn_acc_vl_new(vid, + vxlan_zif->brslave_info.br_if); old_vxlan_zif = acc_bd->vxlan_zif; acc_bd->vxlan_zif = vxlan_zif; @@ -712,7 +801,7 @@ void zebra_evpn_vl_mbr_ref(uint16_t vid, struct zebra_if *zif) acc_bd = zebra_evpn_acc_vl_find(vid); if (!acc_bd) - acc_bd = zebra_evpn_acc_vl_new(vid); + acc_bd = zebra_evpn_acc_vl_new(vid, zif->brslave_info.br_if); if (listnode_lookup(acc_bd->mbr_zifs, zif)) return; @@ -756,6 +845,22 @@ void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif) zebra_evpn_acc_bd_free_on_deref(acc_bd); } +static void zebra_evpn_acc_vl_adv_svi_mac_cb(struct hash_bucket *bucket, + void *ctxt) +{ + struct zebra_evpn_access_bd *acc_bd = bucket->data; + + if (acc_bd->vlan_zif && acc_bd->zevpn) + zebra_evpn_mac_svi_add(acc_bd->vlan_zif->ifp, acc_bd->zevpn); +} + +/* called when advertise SVI MAC is enabled on the switch */ +static void zebra_evpn_acc_vl_adv_svi_mac_all(void) +{ + hash_iterate(zmh_info->evpn_vlan_table, + zebra_evpn_acc_vl_adv_svi_mac_cb, NULL); +} + static void zebra_evpn_acc_vl_json_fill(struct zebra_evpn_access_bd *acc_bd, json_object *json, bool detail) { @@ -800,6 +905,8 @@ static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty, vty_out(vty, " VxLAN Interface: %s\n", acc_bd->vxlan_zif ? acc_bd->vxlan_zif->ifp->name : "-"); + vty_out(vty, " SVI: %s\n", + acc_bd->vlan_zif ? acc_bd->vlan_zif->ifp->name : "-"); vty_out(vty, " L2-VNI: %d\n", acc_bd->zevpn ? acc_bd->zevpn->vni : 0); vty_out(vty, " Member Count: %d\n", @@ -817,12 +924,11 @@ static void zebra_evpn_acc_vl_show_entry(struct vty *vty, if (json) { zebra_evpn_acc_vl_json_fill(acc_bd, json, false); } else { - vty_out(vty, "%-5u %21s %-8d %u\n", - acc_bd->vid, - acc_bd->vxlan_zif ? - acc_bd->vxlan_zif->ifp->name : "-", - acc_bd->zevpn ? acc_bd->zevpn->vni : 0, - listcount(acc_bd->mbr_zifs)); + vty_out(vty, "%-5u %-15s %-8d %-15s %u\n", acc_bd->vid, + acc_bd->vlan_zif ? acc_bd->vlan_zif->ifp->name : "-", + acc_bd->zevpn ? acc_bd->zevpn->vni : 0, + acc_bd->vxlan_zif ? acc_bd->vxlan_zif->ifp->name : "-", + listcount(acc_bd->mbr_zifs)); } } @@ -856,8 +962,8 @@ void zebra_evpn_acc_vl_show(struct vty *vty, bool uj) wctx.detail = false; if (!uj) - vty_out(vty, "%-5s %21s %-8s %s\n", - "VLAN", "VxLAN-IF", "L2-VNI", "# Members"); + vty_out(vty, "%-5s %-15s %-8s %-15s %s\n", "VLAN", "SVI", + "L2-VNI", "VXLAN-IF", "# Members"); hash_iterate(zmh_info->evpn_vlan_table, zebra_evpn_acc_vl_show_hash, &wctx); @@ -1442,20 +1548,30 @@ static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es, return false; if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("es %s br-port dplane update by %s", es->esi_str, caller); + zlog_debug("es %s br-port dplane update by %s", es->esi_str, + caller); backup_nhg_id = (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) ? es->nhg_id : 0; memset(&sph_filters, 0, sizeof(sph_filters)); - if (listcount(es->es_vtep_list) > ES_VTEP_MAX_CNT) { - zlog_warn("es %s vtep count %d exceeds filter cnt %d", - es->esi_str, listcount(es->es_vtep_list), - ES_VTEP_MAX_CNT); + if (es->flags & ZEBRA_EVPNES_BYPASS) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "es %s SPH filter disabled as it is in bypass", + es->esi_str); } else { - for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { - if (es_vtep->flags & ZEBRA_EVPNES_VTEP_DEL_IN_PROG) - continue; - sph_filters[sph_filter_cnt] = es_vtep->vtep_ip; - ++sph_filter_cnt; + if (listcount(es->es_vtep_list) > ES_VTEP_MAX_CNT) { + zlog_warn("es %s vtep count %d exceeds filter cnt %d", + es->esi_str, listcount(es->es_vtep_list), + ES_VTEP_MAX_CNT); + } else { + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, + es_vtep)) { + if (es_vtep->flags + & ZEBRA_EVPNES_VTEP_DEL_IN_PROG) + continue; + sph_filters[sph_filter_cnt] = es_vtep->vtep_ip; + ++sph_filter_cnt; + } } } @@ -1503,6 +1619,7 @@ static bool zebra_evpn_es_run_df_election(struct zebra_evpn_es *es, * is no need to setup the BUM block filter */ if (!(es->flags & ZEBRA_EVPNES_LOCAL) + || (es->flags & ZEBRA_EVPNES_BYPASS) || !zmh_info->es_originator_ip.s_addr) return zebra_evpn_es_df_change(es, new_non_df, caller, "not-ready"); @@ -1728,6 +1845,7 @@ static int zebra_evpn_es_send_add_to_client(struct zebra_evpn_es *es) struct zserv *client; struct stream *s; uint8_t oper_up; + bool bypass; client = zserv_find_client(ZEBRA_ROUTE_BGP, 0); /* BGP may not be running. */ @@ -1742,15 +1860,18 @@ static int zebra_evpn_es_send_add_to_client(struct zebra_evpn_es *es) oper_up = !!(es->flags & ZEBRA_EVPNES_OPER_UP); stream_putc(s, oper_up); stream_putw(s, es->df_pref); + bypass = !!(es->flags & ZEBRA_EVPNES_BYPASS); + stream_putc(s, bypass); /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("send add local es %s %pI4 active %u df_pref %u to %s", - es->esi_str, &zmh_info->es_originator_ip, - oper_up, es->df_pref, - zebra_route_string(client->proto)); + zlog_debug( + "send add local es %s %pI4 active %u df_pref %u%s to %s", + es->esi_str, &zmh_info->es_originator_ip, oper_up, + es->df_pref, bypass ? " bypass" : "", + zebra_route_string(client->proto)); client->local_es_add_cnt++; return zserv_send_message(client, s); @@ -1874,18 +1995,50 @@ static void zebra_evpn_es_setup_evis(struct zebra_evpn_es *es) } } -static void zebra_evpn_es_local_mac_update(struct zebra_evpn_es *es, - bool force_clear_static) +static void zebra_evpn_flush_local_mac(zebra_mac_t *mac, struct interface *ifp) +{ + struct zebra_if *zif; + struct interface *br_ifp; + vlanid_t vid; + + zif = ifp->info; + br_ifp = zif->brslave_info.br_if; + if (!br_ifp) + return; + + if (mac->zevpn->vxlan_if) { + zif = mac->zevpn->vxlan_if->info; + vid = zif->l2info.vxl.access_vlan; + } else { + vid = 0; + } + + /* delete the local mac from the dataplane */ + dplane_local_mac_del(ifp, br_ifp, vid, &mac->macaddr); + /* delete the local mac in zebra */ + zebra_evpn_del_local_mac(mac->zevpn, mac, true); +} + +static void zebra_evpn_es_flush_local_macs(struct zebra_evpn_es *es, + struct interface *ifp, bool add) { zebra_mac_t *mac; struct listnode *node; + struct listnode *nnode; - for (ALL_LIST_ELEMENTS_RO(es->mac_list, node, mac)) { - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE)) { - zebra_evpn_sync_mac_dp_install( - mac, false /* set_inactive */, - force_clear_static, __func__); - } + for (ALL_LIST_ELEMENTS(es->mac_list, node, nnode, mac)) { + if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) + continue; + + /* If ES is being attached/detached from the access port we + * need to clear local activity and peer activity and start + * over */ + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("VNI %u mac %pEA update; local ES %s %s", + mac->zevpn->vni, + &mac->macaddr, + es->esi_str, add ? "add" : "del"); + zebra_evpn_flush_local_mac(mac, ifp); } } @@ -1960,6 +2113,20 @@ static void zebra_evpn_mh_advertise_reach_neigh_only(void) */ } +/* On config of first local-ES turn on advertisement of local SVI-MAC */ +static void zebra_evpn_mh_advertise_svi_mac(void) +{ + if (zmh_info->flags & ZEBRA_EVPN_MH_ADV_SVI_MAC) + return; + + zmh_info->flags |= ZEBRA_EVPN_MH_ADV_SVI_MAC; + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("evpn-mh: advertise SVI MAC"); + + /* walk through all SVIs and see if we need to advertise the MAC */ + zebra_evpn_acc_vl_adv_svi_mac_all(); +} + static int zebra_evpn_es_df_delay_exp_cb(struct thread *t) { struct zebra_evpn_es *es; @@ -1974,6 +2141,17 @@ static int zebra_evpn_es_df_delay_exp_cb(struct thread *t) return 0; } +/* currently there is no global config to turn on MH instead we use + * the addition of the first local Ethernet Segment as the trigger to + * init MH specific processing + */ +static void zebra_evpn_mh_on_first_local_es(void) +{ + zebra_evpn_mh_dup_addr_detect_off(); + zebra_evpn_mh_advertise_reach_neigh_only(); + zebra_evpn_mh_advertise_svi_mac(); +} + static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, struct zebra_if *zif) { @@ -1984,8 +2162,7 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, zlog_debug("local es %s add; nhg %u if %s", es->esi_str, es->nhg_id, zif->ifp->name); - zebra_evpn_mh_dup_addr_detect_off(); - zebra_evpn_mh_advertise_reach_neigh_only(); + zebra_evpn_mh_on_first_local_es(); es->flags |= ZEBRA_EVPNES_LOCAL; listnode_init(&es->local_es_listnode, es); @@ -2004,6 +2181,10 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, if (zif->brslave_info.bridge_ifindex != IFINDEX_INTERNAL) es->flags |= ZEBRA_EVPNES_BR_PORT; + /* inherit the bypass flag from the interface */ + if (zif->flags & ZIF_FLAG_LACP_BYPASS) + es->flags |= ZEBRA_EVPNES_BYPASS; + /* setup base-vni if one doesn't already exist; the ES will get sent * to BGP as a part of that process */ @@ -2035,11 +2216,9 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, */ zebra_evpn_es_setup_evis(es); /* if there any local macs referring to the ES as dest we - * need to set the static reference on them if the MAC is - * synced from an ES peer + * need to clear the contents and start over */ - zebra_evpn_es_local_mac_update(es, - false /* force_clear_static */); + zebra_evpn_es_flush_local_macs(es, zif->ifp, true); /* inherit EVPN protodown flags on the access port */ zebra_evpn_mh_update_protodown_es(es, true /*resync_dplane*/); @@ -2054,33 +2233,34 @@ static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es **esp) if (!(es->flags & ZEBRA_EVPNES_LOCAL)) return; + zif = es->zif; + + /* if there any local macs referring to the ES as dest we + * need to clear the contents and start over + */ + zebra_evpn_es_flush_local_macs(es, zif->ifp, false); + es->flags &= ~(ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_READY_FOR_BGP); THREAD_OFF(es->df_delay_timer); - /* remove the DF filter */ - dplane_updated = zebra_evpn_es_run_df_election(es, __func__); - /* clear EVPN protodown flags on the access port */ zebra_evpn_mh_clear_protodown_es(es); - /* if there any local macs referring to the ES as dest we - * need to clear the static reference on them - */ - zebra_evpn_es_local_mac_update(es, - true /* force_clear_static */); + /* remove the DF filter */ + dplane_updated = zebra_evpn_es_run_df_election(es, __func__); /* flush the BUM filters and backup NHG */ if (!dplane_updated) zebra_evpn_es_br_port_dplane_clear(es); /* clear the es from the parent interface */ - zif = es->zif; zif->es_info.es = NULL; es->zif = NULL; /* clear all local flags associated with the ES */ - es->flags &= ~(ZEBRA_EVPNES_OPER_UP | ZEBRA_EVPNES_BR_PORT); + es->flags &= ~(ZEBRA_EVPNES_OPER_UP | ZEBRA_EVPNES_BR_PORT + | ZEBRA_EVPNES_BYPASS); /* remove from the ES list */ list_delete_node(zmh_info->local_es_list, &es->local_es_listnode); @@ -2493,6 +2673,102 @@ static void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref) zebra_evpn_es_send_add_to_client(es); } +/* If bypass mode on an es changed we set all local macs to + * inactive and drop the sync info + */ +static void zebra_evpn_es_bypass_update_macs(struct zebra_evpn_es *es, + struct interface *ifp, bool bypass) +{ + zebra_mac_t *mac; + struct listnode *node; + struct listnode *nnode; + struct zebra_if *zif; + + /* Flush all MACs linked to the ES */ + for (ALL_LIST_ELEMENTS(es->mac_list, node, nnode, mac)) { + if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) + continue; + + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("VNI %u mac %pEA %s update es %s", + mac->zevpn->vni, + &mac->macaddr, + bypass ? "bypass" : "non-bypass", + es->esi_str); + zebra_evpn_flush_local_mac(mac, ifp); + } + + /* While in bypass-mode locally learnt MACs are linked + * to the access port instead of the ES + */ + zif = ifp->info; + if (!zif->mac_list) + return; + + for (ALL_LIST_ELEMENTS(zif->mac_list, node, nnode, mac)) { + if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) + continue; + + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("VNI %u mac %pEA %s update ifp %s", + mac->zevpn->vni, + &mac->macaddr, + bypass ? "bypass" : "non-bypass", ifp->name); + zebra_evpn_flush_local_mac(mac, ifp); + } +} + +void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es, + struct interface *ifp, bool bypass) +{ + bool old_bypass; + bool dplane_updated; + + old_bypass = !!(es->flags & ZEBRA_EVPNES_BYPASS); + if (old_bypass == bypass) + return; + + if (bypass) + es->flags |= ZEBRA_EVPNES_BYPASS; + else + es->flags &= ~ZEBRA_EVPNES_BYPASS; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("bond %s es %s lacp bypass changed to %s", ifp->name, + es->esi_str, bypass ? "on" : "off"); + + /* send bypass update to BGP */ + if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) + zebra_evpn_es_send_add_to_client(es); + + zebra_evpn_es_bypass_update_macs(es, ifp, bypass); + + /* re-run DF election */ + dplane_updated = zebra_evpn_es_run_df_election(es, __func__); + + /* disable SPH filter */ + if (!dplane_updated && (es->flags & ZEBRA_EVPNES_LOCAL) + && (listcount(es->es_vtep_list) > ES_VTEP_MAX_CNT)) + zebra_evpn_es_br_port_dplane_update(es, __func__); +} + +static void zebra_evpn_es_bypass_cfg_update(struct zebra_if *zif, bool bypass) +{ + bool old_bypass = !!(zif->es_info.flags & ZIF_CFG_ES_FLAG_BYPASS); + + if (old_bypass == bypass) + return; + + if (bypass) + zif->es_info.flags |= ZIF_CFG_ES_FLAG_BYPASS; + else + zif->es_info.flags &= ~ZIF_CFG_ES_FLAG_BYPASS; + + + if (zif->es_info.es) + zebra_evpn_es_bypass_update(zif->es_info.es, zif->ifp, bypass); +} + /* Only certain types of access ports can be setup as an Ethernet Segment */ bool zebra_evpn_is_if_es_capable(struct zebra_if *zif) @@ -2688,7 +2964,7 @@ static void zebra_evpn_es_json_vtep_fill(struct zebra_evpn_es *es, static void zebra_evpn_es_show_entry(struct vty *vty, struct zebra_evpn_es *es, json_object *json_array) { - char type_str[4]; + char type_str[5]; char vtep_str[ES_VTEP_LIST_STR_SZ]; if (json_array) { @@ -2709,6 +2985,8 @@ static void zebra_evpn_es_show_entry(struct vty *vty, struct zebra_evpn_es *es, json_array_string_add(json_flags, "remote"); if (es->flags & ZEBRA_EVPNES_NON_DF) json_array_string_add(json_flags, "nonDF"); + if (es->flags & ZEBRA_EVPNES_BYPASS) + json_array_string_add(json_flags, "bypass"); json_object_object_add(json, "flags", json_flags); } @@ -2730,6 +3008,8 @@ static void zebra_evpn_es_show_entry(struct vty *vty, struct zebra_evpn_es *es, strlcat(type_str, "R", sizeof(type_str)); if (es->flags & ZEBRA_EVPNES_NON_DF) strlcat(type_str, "N", sizeof(type_str)); + if (es->flags & ZEBRA_EVPNES_BYPASS) + strlcat(type_str, "B", sizeof(type_str)); zebra_evpn_es_vtep_str(vtep_str, es, sizeof(vtep_str)); @@ -2767,6 +3047,8 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty, json_array_string_add(json_flags, "remote"); if (es->flags & ZEBRA_EVPNES_NON_DF) json_array_string_add(json_flags, "nonDF"); + if (es->flags & ZEBRA_EVPNES_BYPASS) + json_array_string_add(json_flags, "bypass"); if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) json_array_string_add(json_flags, "readyForBgp"); @@ -2822,6 +3104,8 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty, vty_out(vty, " Ready for BGP: %s\n", (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) ? "yes" : "no"); + if (es->flags & ZEBRA_EVPNES_BYPASS) + vty_out(vty, " LACP bypass: on\n"); vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list)); vty_out(vty, " MAC Count: %d\n", listcount(es->mac_list)); if (es->flags & ZEBRA_EVPNES_LOCAL) @@ -2861,7 +3145,7 @@ void zebra_evpn_es_show(struct vty *vty, bool uj) if (uj) { json_array = json_object_new_array(); } else { - vty_out(vty, "Type: L local, R remote, N non-DF\n"); + vty_out(vty, "Type: B bypass, L local, R remote, N non-DF\n"); vty_out(vty, "%-30s %-4s %-21s %s\n", "ESI", "Type", "ES-IF", "VTEPs"); } @@ -2967,12 +3251,35 @@ int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp) #ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_evpn_mh_clippy.c" #endif +/* CLI for setting an ES in bypass mode */ +DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd, + "[no] evpn mh bypass", + NO_STR "EVPN\n" EVPN_MH_VTY_STR "set bypass mode\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif; + + zif = ifp->info; + + if (no) { + zebra_evpn_es_bypass_cfg_update(zif, false); + } else { + if (!zebra_evpn_is_if_es_capable(zif)) { + vty_out(vty, + "%%DF bypass cannot be associated with this interface type\n"); + return CMD_WARNING; + } + zebra_evpn_es_bypass_cfg_update(zif, true); + } + return CMD_SUCCESS; +} + /* CLI for configuring DF preference part for an ES */ DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd, "[no$no] evpn mh es-df-pref [(1-65535)$df_pref]", NO_STR "EVPN\n" EVPN_MH_VTY_STR "preference value used for DF election\n" - "ID\n") + "pref\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct zebra_if *zif; @@ -3637,6 +3944,7 @@ void zebra_evpn_interface_init(void) install_element(INTERFACE_NODE, &zebra_evpn_es_id_cmd); install_element(INTERFACE_NODE, &zebra_evpn_es_sys_mac_cmd); install_element(INTERFACE_NODE, &zebra_evpn_es_pref_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_es_bypass_cmd); install_element(INTERFACE_NODE, &zebra_evpn_mh_uplink_cmd); } diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 81ae740d49..2361a70bff 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -60,6 +60,10 @@ struct zebra_evpn_es { * filter, SPH filter and backup NHG for fast-failover */ #define ZEBRA_EVPNES_BR_PORT (1 << 6) +/* ES is in bypass mode i.e. must not be advertised. ES-bypass is set + * when the associated host bond goes into LACP bypass + */ +#define ZEBRA_EVPNES_BYPASS (1 << 7) /* memory used for adding the es to zmh_info->es_rb_tree */ RB_ENTRY(zebra_evpn_es) rb_node; @@ -180,6 +184,8 @@ struct zebra_evpn_access_bd { struct list *mbr_zifs; /* presence of zevpn activates the EVI on all the ESs in mbr_zifs */ zebra_evpn_t *zevpn; + /* SVI associated with the VLAN */ + struct zebra_if *vlan_zif; }; /* multihoming information stored in zrouter */ @@ -200,6 +206,10 @@ struct zebra_evpn_mh_info { * this flag when the first local ES is detected. */ #define ZEBRA_EVPN_MH_ADV_REACHABLE_NEIGH_ONLY (1 << 2) +/* If EVPN MH is enabled we advertise the SVI MAC address to avoid + * flooding of ARP replies rxed from the multi-homed host + */ +#define ZEBRA_EVPN_MH_ADV_SVI_MAC (1 << 3) /* RB tree of Ethernet segments (used for EVPN-MH) */ struct zebra_es_rb_head es_rb_tree; @@ -256,6 +266,12 @@ struct zebra_evpn_mh_info { enum protodown_reasons protodown_rc; }; +/* returns TRUE if the EVPN is ready to be sent to BGP */ +static inline bool zebra_evpn_send_to_client_ok(zebra_evpn_t *zevpn) +{ + return !!(zevpn->flags & ZEVPN_READY_FOR_BGP); +} + static inline bool zebra_evpn_mac_is_es_local(zebra_mac_t *mac) { return mac->es && (mac->es->flags & ZEBRA_EVPNES_LOCAL); @@ -285,6 +301,10 @@ static inline bool zebra_evpn_mh_do_adv_reachable_neigh_only(void) return !!(zmh_info->flags & ZEBRA_EVPN_MH_ADV_REACHABLE_NEIGH_ONLY); } +static inline bool zebra_evpn_mh_do_adv_svi_mac(void) +{ + return zmh_info && (zmh_info->flags & ZEBRA_EVPN_MH_ADV_SVI_MAC); +} /*****************************************************************************/ extern esi_t *zero_esi; @@ -357,5 +377,10 @@ extern bool zebra_evpn_is_es_bond_member(struct interface *ifp); extern void zebra_evpn_mh_print(struct vty *vty); extern void zebra_evpn_mh_json(json_object *json); extern void zebra_evpn_l2_nh_show(struct vty *vty, bool uj); +extern void zebra_evpn_acc_bd_svi_set(struct zebra_if *vlan_zif, + struct zebra_if *br_zif, bool is_up); +extern void zebra_evpn_acc_bd_svi_mac_add(struct interface *vlan_if); +extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es, + struct interface *ifp, bool bypass); #endif /* _ZEBRA_EVPN_MH_H */ diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 1f45b72e3a..dea0fea975 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -327,9 +327,9 @@ int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_SVI_IP)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP); - return zebra_evpn_macip_send_msg_to_client( - vni, macaddr, ip, flags, seq, ZEBRA_NEIGH_ACTIVE, - zmac ? zmac->es : NULL, ZEBRA_MACIP_ADD); + return zebra_evpn_macip_send_msg_to_client(vni, macaddr, ip, flags, seq, + ZEBRA_NEIGH_ACTIVE, zmac->es, + ZEBRA_MACIP_ADD); } /* @@ -1370,7 +1370,7 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, return -1; } - memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info)); + zebra_evpn_mac_clear_fwd_info(zmac); memset(&zmac->flags, 0, sizeof(uint32_t)); SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO); } else { @@ -2464,7 +2464,7 @@ int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip) /* see if the AUTO mac needs to be deleted */ if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO) - && !listcount(zmac->neigh_list)) + && !zebra_evpn_mac_in_use(zmac)) zebra_evpn_mac_del(zevpn, zmac); return 0; diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index c1ad91c8ca..3583c5fbf4 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -110,6 +110,44 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave) br_slave->br_if = NULL; } +/* If any of the bond members are in bypass state the bond is placed + * in bypass state + */ +static void zebra_l2_bond_lacp_bypass_eval(struct zebra_if *bond_zif) +{ + struct listnode *node; + struct zebra_if *bond_mbr; + bool old_bypass = !!(bond_zif->flags & ZIF_FLAG_LACP_BYPASS); + bool new_bypass = false; + + if (bond_zif->bond_info.mbr_zifs) { + for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node, + bond_mbr)) { + if (bond_mbr->flags & ZIF_FLAG_LACP_BYPASS) { + new_bypass = true; + break; + } + } + } + + if (old_bypass == new_bypass) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond %s lacp bypass changed to %s", + bond_zif->ifp->name, new_bypass ? "on" : "off"); + + if (new_bypass) + bond_zif->flags |= ZIF_FLAG_LACP_BYPASS; + else + bond_zif->flags &= ~ZIF_FLAG_LACP_BYPASS; + + if (bond_zif->es_info.es) + zebra_evpn_es_bypass_update(bond_zif->es_info.es, bond_zif->ifp, + new_bypass); +} + +/* Returns true if member was newly linked to bond */ void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id) { struct interface *bond_if; @@ -138,6 +176,7 @@ void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id) if (zebra_evpn_is_es_bond(bond_if)) zebra_evpn_mh_update_protodown_bond_mbr( zif, false /*clear*/, __func__); + zebra_l2_bond_lacp_bypass_eval(bond_zif); } } else { if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) @@ -170,6 +209,7 @@ void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif) __func__); listnode_delete(bond_zif->bond_info.mbr_zifs, zif); bond_slave->bond_if = NULL; + zebra_l2_bond_lacp_bypass_eval(bond_zif); } void zebra_l2if_update_bond(struct interface *ifp, bool add) @@ -378,14 +418,36 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp, } } -void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex) +void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex, + bool new_bypass) { struct zebra_if *zif; ifindex_t old_bond_ifindex; + bool old_bypass; + struct zebra_l2info_bondslave *bond_mbr; zif = ifp->info; assert(zif); + old_bypass = !!(zif->flags & ZIF_FLAG_LACP_BYPASS); + if (old_bypass != new_bypass) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond-mbr %s lacp bypass changed to %s", + zif->ifp->name, new_bypass ? "on" : "off"); + + if (new_bypass) + zif->flags |= ZIF_FLAG_LACP_BYPASS; + else + zif->flags &= ~ZIF_FLAG_LACP_BYPASS; + + bond_mbr = &zif->bondslave_info; + if (bond_mbr->bond_if) { + struct zebra_if *bond_zif = bond_mbr->bond_if->info; + + zebra_l2_bond_lacp_bypass_eval(bond_zif); + } + } + old_bond_ifindex = zif->bondslave_info.bond_ifindex; if (old_bond_ifindex == bond_ifindex) return; diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index 4b84eb071e..1834430287 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -107,7 +107,7 @@ extern void zebra_l2if_update_bridge_slave(struct interface *ifp, ns_id_t ns_id); extern void zebra_l2if_update_bond_slave(struct interface *ifp, - ifindex_t bond_ifindex); + ifindex_t bond_ifindex, bool bypass); extern void zebra_vlan_bitmap_compute(struct interface *ifp, uint32_t vid_start, uint16_t vid_end); extern void zebra_vlan_mbr_re_eval(struct interface *ifp, diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 424c00d5eb..6cb8010364 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -2852,11 +2852,10 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "Number of MACs (local and remote) known for this VNI: %u\n", num_macs); - vty_out(vty, - "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n"); - vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC", - "Type", "Flags", "Intf/Remote ES/VTEP", - "VLAN", "Seq #'s"); + vty_out(vty, + "Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy\n"); + vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %s\n", "MAC", "Type", + "Flags", "Intf/Remote ES/VTEP", "VLAN", "Seq #'s"); } else json_object_int_add(json, "numMacs", num_macs); @@ -3503,6 +3502,8 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) zvrf->advertise_gw_macip ? "Yes" : "No"); vty_out(vty, "Advertise svi mac-ip: %s\n", zvrf->advertise_svi_macip ? "Yes" : "No"); + vty_out(vty, "Advertise svi mac: %s\n", + zebra_evpn_mh_do_adv_svi_mac() ? "Yes" : "No"); vty_out(vty, "Duplicate address detection: %s\n", zebra_evpn_do_dup_addr_detect(zvrf) ? "Enable" : "Disable"); @@ -4025,6 +4026,7 @@ static int zebra_vxlan_check_del_local_mac(struct interface *ifp, if (!listcount(mac->neigh_list)) { zebra_evpn_mac_del(zevpn, mac); } else { + zebra_evpn_mac_clear_fwd_info(mac); UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS); UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); @@ -4121,7 +4123,8 @@ int zebra_vxlan_dp_network_mac_del(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) zlog_debug("dpDel local-nw-MAC %pEA VNI %u", macaddr, vni); - return zebra_evpn_del_local_mac(zevpn, mac); + + zebra_evpn_del_local_mac(zevpn, mac, false); } return 0; @@ -4158,7 +4161,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - return zebra_evpn_del_local_mac(zevpn, mac); + return zebra_evpn_del_local_mac(zevpn, mac, false); } /* @@ -4207,7 +4210,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid, sticky, local_inactive, - dp_static); + dp_static, NULL); } /* @@ -4493,6 +4496,16 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, return -1; } + /* VRR IP is advertised only if gw-macip-adv-enabled */ + if (IS_ZEBRA_IF_MACVLAN(ifp)) { + if (!advertise_gw_macip_enabled(zevpn)) + return 0; + } else { + /* SVI IP is advertised if gw or svi macip-adv-enabled */ + if (!advertise_svi_macip_enabled(zevpn) + && !advertise_gw_macip_enabled(zevpn)) + return 0; + } memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); @@ -4539,10 +4552,14 @@ int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) } else { zebra_evpn_t *zevpn = NULL; + /* Unlink the SVI from the access VLAN */ + zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, false); + /* since we dont have svi corresponding to zevpn, we associate it * to default vrf. Note: the corresponding neigh entries on the * SVI would have already been deleted */ zevpn = zebra_evpn_from_svi(ifp, link_if); + if (zevpn) { zevpn->vrf_id = VRF_DEFAULT; @@ -4606,6 +4623,9 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) n_wctx.zevpn = zevpn; hash_iterate(zevpn->neigh_table, zebra_evpn_install_neigh_hash, &n_wctx); + + /* Link the SVI from the access VLAN */ + zebra_evpn_acc_bd_svi_set(ifp->info, link_if->info, true); } return 0; |
