diff options
| -rw-r--r-- | bgpd/bgp_evpn.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_mh.c | 8 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_mh.h | 10 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 40 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 4 | ||||
| -rw-r--r-- | isisd/isis_adjacency.c | 10 | ||||
| -rw-r--r-- | isisd/isis_circuit.c | 7 | ||||
| -rw-r--r-- | isisd/isis_nb_config.c | 48 | ||||
| -rw-r--r-- | ospf6d/ospf6_flood.c | 43 | ||||
| -rw-r--r-- | pimd/pim6_cmd.c | 4 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 8 | ||||
| -rw-r--r-- | tests/topotests/zebra_multiple_connected/r1/ip_route2.json | 102 | ||||
| -rw-r--r-- | tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py | 24 | ||||
| -rw-r--r-- | watchfrr/watchfrr.c | 6 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mh.c | 16 | ||||
| -rw-r--r-- | zebra/zebra_nhg.c | 3 |
16 files changed, 231 insertions, 113 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 3224c1a2b0..fbb0d2272a 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3366,7 +3366,9 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, assert(attr); - /* Only type-2, type-3, type-4 and type-5 are supported currently */ + /* Only type-1, type-2, type-3, type-4 and type-5 + * are supported currently + */ if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE || evp->prefix.route_type == BGP_EVPN_ES_ROUTE @@ -3471,7 +3473,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, if (evp->prefix.route_type == BGP_EVPN_ES_ROUTE) { /* we will match based on the entire esi to avoid - * imoort of an es route for esi2 into esi1 + * import of an es route for esi2 into esi1 */ es = bgp_evpn_es_find(&evp->prefix.es_addr.esi); if (es && bgp_evpn_is_es_local(es)) @@ -6097,8 +6099,9 @@ bool bgp_evpn_is_prefix_nht_supported(const struct prefix *pfx) * EVPN routes should be marked as valid only if the nexthop is * reachable. Only if this happens, the route should be imported * (into VNI or VRF routing tables) and/or advertised. - * Note: This is currently applied for EVPN type-2, type-3 and - * type-5 routes. It may be tweaked later on for other routes, or + * Note: This is currently applied for EVPN type-1, type-2, + * type-3, type-4 and type-5 routes. + * It may be tweaked later on for other routes, or * even removed completely when all routes are handled. */ if (pfx && pfx->family == AF_EVPN diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index b9e3577f5c..6db4cba44d 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -287,7 +287,7 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, return ret; } -/* Install or unistall a Tyoe-4 route in the per-ES routing table */ +/* Install or unistall a Type-4 route in the per-ES routing table */ int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, afi_t afi, safi_t safi, struct prefix_evpn *evp, struct bgp_path_info *pi, int install) @@ -378,16 +378,16 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, remote_pi = tmp_pi; } - /* we don't expect to see a remote_ri at this point as + /* we don't expect to see a remote_pi at this point as * an ES route has {esi, vtep_ip} as the key in the ES-rt-table * in the VNI-rt-table. */ if (remote_pi) { flog_err( EC_BGP_ES_INVALID, - "%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote", + "%u ERROR: local es route for ESI: %s vtep %pI4 also learnt from remote", bgp->vrf_id, es ? es->esi_str : "Null", - &es->originator_ip); + es ? &es->originator_ip : NULL); return -1; } diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h index 2e2e4231e6..dc3fe44776 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h @@ -50,7 +50,9 @@ struct bgp_evpn_es_frag { /* RD for this ES fragment */ struct prefix_rd prd; - /* Memory used for linking bgp_evpn_es_rd to bgp_evpn_es->rd_list */ + /* Memory used for linking bgp_evpn_es_frag to + * bgp_evpn_es->es_frag_list + */ struct listnode es_listnode; /* List of ES-EVIs associated with this fragment */ @@ -59,11 +61,11 @@ struct bgp_evpn_es_frag { /* Ethernet Segment entry - * - Local and remote ESs are maintained in a global RB tree, - * bgp_mh_info->es_rb_tree using ESI as key + * bgp_mh_info->es_rb_tree using ESI as key * - Local ESs are received from zebra (BGP_EVPNES_LOCAL) * - Remotes ESs are implicitly created (by reference) by a remote ES-EVI * (BGP_EVPNES_REMOTE) - * - An ES can be simulatenously LOCAL and REMOTE; infact all LOCAL ESs are + * - An ES can be simultaneously LOCAL and REMOTE; infact all LOCAL ESs are * expected to have REMOTE ES peers. */ struct bgp_evpn_es { @@ -101,7 +103,7 @@ struct bgp_evpn_es { */ struct listnode pend_es_listnode; - /* [EVPNES_LOCAL] List of RDs for this ES (bgp_evpn_es_rd) */ + /* [EVPNES_LOCAL] List of RDs for this ES (bgp_evpn_es_frag) */ struct list *es_frag_list; struct bgp_evpn_es_frag *es_base_frag; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 0074d5daac..b3d8d1b82d 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -516,28 +516,35 @@ static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid) } /* + * This function generates a new SID based on bgp->srv6_locator_chunks and + * index. The locator and generated SID are stored in arguments sid_locator + * and sid, respectively. + * * if index != 0: try to allocate as index-mode * else: try to allocate as auto-mode */ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, - struct in6_addr *sid_locator) + struct in6_addr *sid_locator, + struct in6_addr *sid) { struct listnode *node; struct srv6_locator_chunk *chunk; - struct in6_addr sid_buf; bool alloced = false; int label = 0; + uint8_t offset = 0; - if (!bgp || !sid_locator) + if (!bgp || !sid_locator || !sid) return false; for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) { *sid_locator = chunk->prefix.prefix; - sid_buf = chunk->prefix.prefix; + *sid = chunk->prefix.prefix; + offset = chunk->block_bits_length + chunk->node_bits_length; + if (index != 0) { label = index << 12; - transpose_sid(&sid_buf, label, 64, 16); - if (sid_exist(bgp, &sid_buf)) + transpose_sid(sid, label, offset, 16); + if (sid_exist(bgp, sid)) return false; alloced = true; break; @@ -545,8 +552,8 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, for (size_t i = 1; i < 255; i++) { label = i << 12; - transpose_sid(&sid_buf, label, 64, 16); - if (sid_exist(bgp, &sid_buf)) + transpose_sid(sid, label, offset, 16); + if (sid_exist(bgp, sid)) continue; alloced = true; break; @@ -556,7 +563,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, if (!alloced) return 0; - sid_register(bgp, &sid_buf, bgp->srv6_locator_name); + sid_register(bgp, sid, bgp->srv6_locator_name); return label; } @@ -600,20 +607,19 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi) tovpn_sid_locator = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); - tovpn_sid_transpose_label = - alloc_new_sid(bgp_vpn, tovpn_sid_index, tovpn_sid_locator); + tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); + + tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index, + tovpn_sid_locator, tovpn_sid); + if (tovpn_sid_transpose_label == 0) { zlog_debug("%s: not allocated new sid for vrf %s: afi %s", __func__, bgp_vrf->name_pretty, afi2str(afi)); + XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator); + XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid); return; } - tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); - *tovpn_sid = *tovpn_sid_locator; - transpose_sid(tovpn_sid, tovpn_sid_transpose_label, - BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET, - BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH); - if (debug) { inet_ntop(AF_INET6, tovpn_sid, buf, sizeof(buf)); zlog_debug("%s: new sid %s allocated for vrf %s: afi %s", diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index d3ebc0e6a2..f5b3556731 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -589,6 +589,10 @@ static void bgp_nht_ifp_handle(struct interface *ifp, bool up) if (!bgp) return; + bgp_nht_ifp_table_handle(bgp, &bgp->nexthop_cache_table[AFI_IP], ifp, + up); + bgp_nht_ifp_table_handle(bgp, &bgp->import_check_table[AFI_IP], ifp, + up); bgp_nht_ifp_table_handle(bgp, &bgp->nexthop_cache_table[AFI_IP6], ifp, up); bgp_nht_ifp_table_handle(bgp, &bgp->import_check_table[AFI_IP6], ifp, diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 2729dce382..11f17ec7bf 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -31,6 +31,7 @@ #include "thread.h" #include "if.h" #include "stream.h" +#include "bfd.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -814,6 +815,15 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, vty_out(vty, " %s\n", buf); } } + if (adj->circuit && adj->circuit->bfd_config.enabled) { + vty_out(vty, " BFD is %s%s\n", + adj->bfd_session ? "active, status " + : "configured", + !adj->bfd_session + ? "" + : bfd_get_status_str(bfd_sess_status( + adj->bfd_session))); + } for (ALL_LIST_ELEMENTS_RO(adj->adj_sids, anode, sra)) { const char *adj_type; const char *backup; diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index c7bf1e2012..fedceed3bb 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -661,8 +661,11 @@ int isis_circuit_up(struct isis_circuit *circuit) "Interface MTU %zu on %s is too low to support area lsp mtu %u!", isis_circuit_pdu_size(circuit), circuit->interface->name, circuit->area->lsp_mtu); - isis_circuit_update_all_srmflags(circuit, 0); - return ISIS_ERROR; + + /* Allow ISIS to continue configuration. With this + * configuration failure ISIS will attempt to send lsp + * packets but will fail until the mtu is configured properly + */ } if (circuit->circ_type == CIRCUIT_T_BROADCAST) { diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index de7797813a..cf4c2aea0a 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -393,30 +393,11 @@ int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args) */ int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args) { - struct listnode *node; - struct isis_circuit *circuit; uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL); struct isis_area *area; switch (args->event) { case NB_EV_VALIDATE: - area = nb_running_get_entry(args->dnode, NULL, false); - if (!area) - break; - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if (circuit->state != C_STATE_INIT - && circuit->state != C_STATE_UP) - continue; - if (lsp_mtu > isis_circuit_pdu_size(circuit)) { - snprintf( - args->errmsg, args->errmsg_len, - "ISIS area contains circuit %s, which has a maximum PDU size of %zu", - circuit->interface->name, - isis_circuit_pdu_size(circuit)); - return NB_ERR_VALIDATION; - } - } - break; case NB_EV_PREPARE: case NB_EV_ABORT: break; @@ -2552,43 +2533,14 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args) */ int lib_interface_isis_create(struct nb_cb_create_args *args) { - struct isis_area *area = NULL; struct interface *ifp; struct isis_circuit *circuit = NULL; const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag"); - uint32_t min_mtu, actual_mtu; switch (args->event) { case NB_EV_PREPARE: case NB_EV_ABORT: - break; case NB_EV_VALIDATE: - /* check if interface mtu is sufficient. If the area has not - * been created yet, assume default MTU for the area - */ - ifp = nb_running_get_entry(args->dnode, NULL, false); - /* zebra might not know yet about the MTU - nothing we can do */ - if (!ifp || ifp->mtu == 0) - break; - actual_mtu = - if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu; - - area = isis_area_lookup(area_tag, ifp->vrf->vrf_id); - if (area) - min_mtu = area->lsp_mtu; - else -#ifndef FABRICD - min_mtu = yang_get_default_uint16( - "/frr-isisd:isis/instance/lsp/mtu"); -#else - min_mtu = DEFAULT_LSP_MTU; -#endif /* ifndef FABRICD */ - if (actual_mtu < min_mtu) { - snprintf(args->errmsg, args->errmsg_len, - "Interface %s has MTU %u, minimum MTU for the area is %u", - ifp->name, actual_mtu, min_mtu); - return NB_ERR_VALIDATION; - } break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index cc82084e5e..bc9e2c3405 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -878,6 +878,28 @@ static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa, return 0; } +static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa, + struct ospf6_neighbor *from) +{ + struct timeval now, res; + unsigned int time_delta_ms; + + monotime(&now); + timersub(&now, &lsa->installed, &res); + time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec / 1000); + + if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) { + if (IS_OSPF6_DEBUG_FLOODING || + IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) + zlog_debug( + "LSA can't be updated within MinLSArrival, %dms < %dms, discard", + time_delta_ms, + from->ospf6_if->area->ospf6->lsa_minarrival); + return true; + } + return false; +} + /* RFC2328 section 13 The Flooding Procedure */ void ospf6_receive_lsa(struct ospf6_neighbor *from, struct ospf6_lsa_header *lsa_header) @@ -885,7 +907,6 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL; int ismore_recent; int is_debug = 0; - unsigned int time_delta_ms; ismore_recent = 1; assert(from); @@ -993,19 +1014,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, /* (a) MinLSArrival check */ if (old) { - struct timeval now, res; - monotime(&now); - timersub(&now, &old->installed, &res); - time_delta_ms = - (res.tv_sec * 1000) + (int)(res.tv_usec / 1000); - if (time_delta_ms - < from->ospf6_if->area->ospf6->lsa_minarrival) { - if (is_debug) - zlog_debug( - "LSA can't be updated within MinLSArrival, %dms < %dms, discard", - time_delta_ms, - from->ospf6_if->area->ospf6 - ->lsa_minarrival); + if (ospf6_lsa_check_min_arrival(old, from)) { ospf6_lsa_delete(new); return; /* examin next lsa */ } @@ -1222,7 +1231,11 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, __PRETTY_FUNCTION__, old->name); } - /* XXX, MinLSArrival check !? RFC 2328 13 (8) */ + /* MinLSArrival check as per RFC 2328 13 (8) */ + if (ospf6_lsa_check_min_arrival(old, from)) { + ospf6_lsa_delete(new); + return; /* examin next lsa */ + } ospf6_lsdb_add(ospf6_lsa_copy(old), from->lsupdate_list); diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index 90840a95e0..ce26f912f4 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -170,7 +170,7 @@ DEFPY (ipv6_pim_rp_keep_alive, "ipv6 pim rp keep-alive-timer (1-65535)$kat", IPV6_STR PIM_STR - "Rendevous Point\n" + "Rendezvous Point\n" "Keep alive Timer\n" "Seconds\n") { @@ -183,7 +183,7 @@ DEFPY (no_ipv6_pim_rp_keep_alive, NO_STR IPV6_STR PIM_STR - "Rendevous Point\n" + "Rendezvous Point\n" "Keep alive Timer\n" IGNORED_IN_NO_STR) { diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 8630f79b36..706a21322b 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4909,7 +4909,7 @@ DEFPY (ip_pim_rp_keep_alive, "ip pim rp keep-alive-timer (1-65535)$kat", IP_STR "pim multicast routing\n" - "Rendevous Point\n" + "Rendezvous Point\n" "Keep alive Timer\n" "Seconds\n") { @@ -4922,7 +4922,7 @@ DEFUN (no_ip_pim_rp_keep_alive, NO_STR IP_STR "pim multicast routing\n" - "Rendevous Point\n" + "Rendezvous Point\n" "Keep alive Timer\n" IGNORED_IN_NO_STR) { @@ -5062,7 +5062,7 @@ DEFPY (ip_pim_rp, "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp", IP_STR "pim multicast routing\n" - "Rendevous Point\n" + "Rendezvous Point\n" "ip address of RP\n" "Group Address range to cover\n") { @@ -5090,7 +5090,7 @@ DEFPY (no_ip_pim_rp, NO_STR IP_STR "pim multicast routing\n" - "Rendevous Point\n" + "Rendezvous Point\n" "ip address of RP\n" "Group Address range to cover\n") { diff --git a/tests/topotests/zebra_multiple_connected/r1/ip_route2.json b/tests/topotests/zebra_multiple_connected/r1/ip_route2.json new file mode 100644 index 0000000000..26995654f7 --- /dev/null +++ b/tests/topotests/zebra_multiple_connected/r1/ip_route2.json @@ -0,0 +1,102 @@ +{ + "10.0.1.0/24":[ + { + "prefix":"10.0.1.0/24", + "prefixLen":24, + "protocol":"connected", + "vrfName":"default", + "distance":0, + "metric":0, + "installed":true, + "table":254, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"r1-eth1", + "active":true + } + ] + }, + { + "prefix":"10.0.1.0/24", + "prefixLen":24, + "protocol":"connected", + "vrfName":"default", + "distance":0, + "metric":0, + "installed":true, + "table":254, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"r1-eth0", + "active":true + } + ] + } + ], + "10.0.1.30/32":[ + { + "prefix":"10.0.1.30/32", + "prefixLen":32, + "protocol":"kernel", + "vrfName":"default", + "distance":0, + "metric":0, + "installed":true, + "table":254, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"r1-eth1", + "active":true + } + ] + } + ], + "10.9.9.0/24":[ + { + "prefix":"10.9.9.0/24", + "prefixLen":24, + "protocol":"kernel", + "vrfName":"default", + "distance":0, + "metric":0, + "installed":true, + "table":254, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.30", + "afi":"ipv4", + "interfaceName":"r1-eth1", + "active":true + } + ] + } + ], + "192.168.1.1/32":[ + { + "prefix":"192.168.1.1/32", + "prefixLen":32, + "protocol":"kernel", + "vrfName":"default", + "distance":0, + "metric":0, + "installed":true, + "table":254, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.99", + "afi":"ipv4", + "interfaceName":"r1-eth1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py index 31ac831b35..8882cf5bda 100644 --- a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py +++ b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py @@ -133,6 +133,30 @@ def test_zebra_connected_multiple(): assert result is None, "Kernel route is missing from zebra" +def test_zebra_system_recursion(): + "Test a system route recursing through another system route" + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r1"] + router.run("ip route add 10.0.1.30/32 dev r1-eth1") + router.run("ip route add 10.9.9.0/24 via 10.0.1.30 dev r1-eth1") + router.run("ip link add dummy2 type dummy") + router.run("ip link set dummy2 up") + router.run("ip link set dummy2 down") + + routes = "{}/{}/ip_route2.json".format(CWD, router.name) + expected = json.loads(open(routes).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route json", expected + ) + + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Kernel route is missing from zebra" + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index e5afa68986..51e4f802c9 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -1053,6 +1053,12 @@ void watchfrr_status(struct vty *vty) struct timeval delay; vty_out(vty, "watchfrr global phase: %s\n", phase_str[gs.phase]); + vty_out(vty, " Restart Command: %pSQq\n", gs.restart_command); + vty_out(vty, " Start Command: %pSQq\n", gs.start_command); + vty_out(vty, " Stop Command: %pSQq\n", gs.stop_command); + vty_out(vty, " Min Restart Interval: %ld\n", gs.min_restart_interval); + vty_out(vty, " Max Restart Interval: %ld\n", gs.max_restart_interval); + vty_out(vty, " Restart Timeout: %ld\n", gs.restart_timeout); if (gs.restart.pid) vty_out(vty, " global restart running, pid %ld\n", (long)gs.restart.pid); diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 6c4e8b99f7..b1e48374c4 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -3761,18 +3761,10 @@ static inline bool zebra_evpn_mh_is_all_uplinks_down(void) static void zebra_evpn_mh_uplink_oper_flags_update(struct zebra_if *zif, bool set) { - if (set) { - if (if_is_operative(zif->ifp)) { - if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) { - zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; - ++zmh_info->uplink_oper_up_cnt; - } - } else { - if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) { - zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; - if (zmh_info->uplink_oper_up_cnt) - --zmh_info->uplink_oper_up_cnt; - } + if (set && if_is_operative(zif->ifp)) { + if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) { + zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; + ++zmh_info->uplink_oper_up_cnt; } } else { if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) { diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index f4524a8018..069d35c6a3 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2265,7 +2265,8 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe, continue; } - if (match->type == ZEBRA_ROUTE_CONNECT) { + if ((match->type == ZEBRA_ROUTE_CONNECT) || + (RIB_SYSTEM_ROUTE(match) && RSYSTEM_ROUTE(type))) { match = zebra_nhg_connected_ifindex(rn, match, nexthop->ifindex); |
