diff options
317 files changed, 6077 insertions, 2347 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index c99dadd083..4653b96db4 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -755,8 +755,10 @@ babel_interface_close_all(void) } /* Disable babel redistribution */ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT); - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT); + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, AFI_IP, type, 0, + VRF_DEFAULT); + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, AFI_IP6, type, 0, + VRF_DEFAULT); } } @@ -974,6 +976,7 @@ DEFUN (show_babel_route, { struct route_stream *routes = NULL; struct xroute_stream *xroutes = NULL; + routes = route_stream(0); if(routes) { while(1) { diff --git a/babeld/babel_main.c b/babeld/babel_main.c index ddc75f7182..77658eb57d 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -19,6 +19,7 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek #include "memory.h" #include "libfrr.h" #include "lib_errors.h" +#include "plist.h" #include "babel_main.h" #include "babeld.h" @@ -313,6 +314,7 @@ babel_exit_properly(void) debugf(BABEL_DEBUG_COMMON, "Done."); vrf_terminate(); + prefix_list_reset(); frr_fini(); exit(0); diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index bead9f27ef..54f0f79aa0 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -19,7 +19,7 @@ void babelz_zebra_init(void); /* we must use a pointer because of zclient.c's functions (new, free). */ -struct zclient *zclient; +struct zclient *babel_zclient; /* Debug types */ static const struct { @@ -94,9 +94,10 @@ DEFUN (babel_redistribute_type, } if (!negate) - zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT); + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, babel_zclient, afi, type, 0, VRF_DEFAULT); else { - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT); + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, afi, type, 0, + VRF_DEFAULT); /* perhaps should we remove xroutes having the same type... */ } return CMD_SUCCESS; @@ -230,11 +231,11 @@ static zclient_handler *const babel_handlers[] = { void babelz_zebra_init(void) { - zclient = zclient_new(master, &zclient_options_default, babel_handlers, - array_size(babel_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs); + babel_zclient = zclient_new(master, &zclient_options_default, babel_handlers, + array_size(babel_handlers)); + zclient_init(babel_zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs); - zclient->zebra_connected = babel_zebra_connected; + babel_zclient->zebra_connected = babel_zebra_connected; install_element(BABEL_NODE, &babel_redistribute_type_cmd); install_element(ENABLE_NODE, &debug_babel_cmd); @@ -248,6 +249,6 @@ void babelz_zebra_init(void) void babel_zebra_close_connexion(void) { - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(babel_zclient); + zclient_free(babel_zclient); } diff --git a/babeld/babel_zebra.h b/babeld/babel_zebra.h index 7f960d3961..0455bad7e1 100644 --- a/babeld/babel_zebra.h +++ b/babeld/babel_zebra.h @@ -8,7 +8,7 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek #include "vty.h" -extern struct zclient *zclient; +extern struct zclient *babel_zclient; void babelz_zebra_init(void); void babel_zebra_close_connexion(void); diff --git a/babeld/babeld.c b/babeld/babeld.c index 4e68f05df4..a9ad97509a 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -108,8 +108,8 @@ babel_config_write (struct vty *vty) /* list redistributed protocols */ for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (i != zclient->redist_default && - vrf_bitmap_check(&zclient->redist[afi][i], VRF_DEFAULT)) { + if (i != babel_zclient->redist_default && + vrf_bitmap_check(&babel_zclient->redist[afi][i], VRF_DEFAULT)) { vty_out(vty, " redistribute %s %s\n", (afi == AFI_IP) ? "ipv4" : "ipv6", zebra_route_string(i)); @@ -183,6 +183,10 @@ static void babel_read_protocol(struct event *thread) flog_err_sys(EC_LIB_SOCKET, "recv: %s", safe_strerror(errno)); } } else { + if(ntohs(sin6.sin6_port) != BABEL_PORT) { + return; + } + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; @@ -212,7 +216,8 @@ static void babel_init_routing_process(struct event *thread) babel_main_loop(thread);/* this function self-add to the t_update thread */ } -/* fill "myid" with an unique id (only if myid != {0}). */ +/* fill "myid" with an unique id (only if myid != {0} and myid != {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}). */ static void babel_get_myid(void) { @@ -222,7 +227,7 @@ babel_get_myid(void) int i; /* if we already have an id (from state file), we return. */ - if (memcmp(myid, zeroes, 8) != 0) { + if (memcmp(myid, zeroes, 8) != 0 && memcmp(myid, ones, 8) != 0) { return; } diff --git a/babeld/babeld.h b/babeld/babeld.h index 17a0381d2c..f4ee09a761 100644 --- a/babeld/babeld.h +++ b/babeld/babeld.h @@ -21,6 +21,8 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek #undef MAX #undef MIN +#define BABEL_PORT 6696 + #define MAX(x,y) ((x)<=(y)?(y):(x)) #define MIN(x,y) ((x)<=(y)?(x):(y)) diff --git a/babeld/kernel.c b/babeld/kernel.c index 4957b04e77..ec562a9e93 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -176,8 +176,7 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, debugf(BABEL_DEBUG_ROUTE, "%s route (%s) to zebra", add ? "adding" : "removing", (family == AF_INET) ? "ipv4" : "ipv6"); - return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); + return zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, babel_zclient, &api); } int diff --git a/babeld/message.c b/babeld/message.c index c45daa2425..cc751426ba 100644 --- a/babeld/message.c +++ b/babeld/message.c @@ -27,6 +27,7 @@ int split_horizon = 1; unsigned short myseqno = 0; #define UNICAST_BUFSIZE 1024 +#define RESERVED 0 static int unicast_buffered = 0; static unsigned char *unicast_buffer = NULL; struct neighbour *unicast_neighbour = NULL; @@ -52,7 +53,17 @@ static const unsigned char tlv_min_length[MESSAGE_MAX + 1] = static bool known_ae(int ae) { - return ae <= 4; + return ae <= 3; +} + +static inline bool +is_all_zero(const unsigned char *data, int len) { + for (int j = 0; j < len; j++) { + if (data[j] != 0) { + return false; + } + } + return true; } /* Parse a network prefix, encoded in the somewhat baroque compressed @@ -151,7 +162,11 @@ static bool parse_update_subtlv(const unsigned char *a, int alen, "Received Mandatory bit set but this FRR version is not prepared to handle it at this point"); return true; } else if (type == SUBTLV_PADN) { - /* Nothing. */ + if (!is_all_zero(a + i + 2, len)) { + debugf(BABEL_DEBUG_COMMON, + "Received pad%d with non zero MBZ field.", + len); + } } else if (type == SUBTLV_DIVERSITY) { if (len > DIVERSITY_HOPS) { flog_err( @@ -214,7 +229,11 @@ parse_hello_subtlv(const unsigned char *a, int alen, "Received subtlv with Mandatory bit, this version of FRR is not prepared to handle this currently"); return -2; } else if (type == SUBTLV_PADN) { - /* Nothing to do. */ + if (!is_all_zero(a + i + 2, len)) { + debugf(BABEL_DEBUG_COMMON, + "Received pad%d with non zero MBZ field.", + len); + } } else if (type == SUBTLV_TIMESTAMP) { if (len >= 4) { DO_NTOHL(*hello_send_us, a + i + 2); @@ -261,7 +280,11 @@ parse_ihu_subtlv(const unsigned char *a, int alen, } if(type == SUBTLV_PADN) { - /* Nothing to do. */ + if (!is_all_zero(a + i + 2, len)) { + debugf(BABEL_DEBUG_COMMON, + "Received pad%d with non zero MBZ field.", + len); + } } else if(type == SUBTLV_TIMESTAMP) { if(len >= 8) { DO_NTOHL(*hello_send_us, a + i + 2); @@ -290,7 +313,7 @@ parse_request_subtlv(int ae, const unsigned char *a, int alen, int have_src_prefix = 0; while(i < alen) { - type = a[0]; + type = a[i]; if(type == SUBTLV_PAD1) { i++; continue; @@ -441,6 +464,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, return; } + if (v4mapped(from)) { + memcpy(v4_nh, from, 16); + have_v4_nh = 1; + } else { + memcpy(v6_nh, from, 16); + have_v6_nh = 1; + } + i = 0; while(i < bodylen) { message = packet + 4 + i; @@ -454,12 +485,23 @@ parse_packet(const unsigned char *from, struct interface *ifp, len = message[1]; if(type == MESSAGE_PADN) { + if (!is_all_zero(message + 2, len)) { + debugf(BABEL_DEBUG_COMMON, + "Received pad%d with non zero MBZ field.", + len); + } debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.", len, format_address(from), ifp->name); } else if(type == MESSAGE_ACK_REQ) { - unsigned short nonce, interval; + unsigned short nonce, interval, Reserved; + DO_NTOHS(Reserved, message + 2); DO_NTOHS(nonce, message + 4); DO_NTOHS(interval, message + 6); + if (Reserved != RESERVED) { + debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) with non zero Reserved from %s on %s.", + nonce, interval, format_address(from), ifp->name); + goto done; + } debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.", nonce, interval, format_address(from), ifp->name); send_ack(neigh, nonce, interval); @@ -520,8 +562,15 @@ parse_packet(const unsigned char *from, struct interface *ifp, } } else if(type == MESSAGE_IHU) { unsigned short txcost, interval; + unsigned char Reserved; unsigned char address[16]; int rc; + Reserved = message[3]; + if (Reserved != RESERVED) { + debugf(BABEL_DEBUG_COMMON,"Received ihu with non zero Reserved from %s on %s.", + format_address(from), ifp->name); + goto done; + } DO_NTOHS(txcost, message + 4); DO_NTOHS(interval, message + 6); rc = network_address(message[2], message + 8, len - 6, address); @@ -583,6 +632,20 @@ parse_packet(const unsigned char *from, struct interface *ifp, int rc, parsed_len; bool ignore_update = false; + // Basic sanity check on length + if (len < 10) { + if (len < 2 || (message[3] & 0x80)) { + have_v4_prefix = have_v6_prefix = 0; + } + goto fail; + } + + if(!known_ae(message[2])) { + debugf(BABEL_DEBUG_COMMON,"Received update with unknown AE %d. Ignoring.", + message[2]); + goto done; + } + DO_NTOHS(interval, message + 6); DO_NTOHS(seqno, message + 8); DO_NTOHS(metric, message + 10); @@ -621,7 +684,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, } have_router_id = 1; } - if(!have_router_id && message[2] != 0) { + if(metric < INFINITY && !have_router_id && message[2] != 0) { flog_err(EC_BABEL_PACKET, "Received prefix with no router id."); goto fail; @@ -633,9 +696,15 @@ parse_packet(const unsigned char *from, struct interface *ifp, format_address(from), ifp->name); if(message[2] == 0) { - if(metric < 0xFFFF) { + if(metric < INFINITY) { flog_err(EC_BABEL_PACKET, - "Received wildcard update with finite metric."); + "Received wildcard update with finite metric."); + goto done; + } + // Add check for Plen and Omitted + if(message[4] != 0 || message[5] != 0) { + flog_err(EC_BABEL_PACKET, + "Received wildcard retraction with non-zero Plen or Omitted."); goto done; } retract_neighbour_routes(neigh); @@ -737,8 +806,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, send_update(neigh->ifp, 0, prefix, plen); } } else if(type == MESSAGE_MH_REQUEST) { - unsigned char prefix[16], plen; + unsigned char prefix[16], plen, Reserved; unsigned short seqno; + Reserved = message[7]; + if (Reserved != RESERVED) { + debugf(BABEL_DEBUG_COMMON,"Received request with non zero Reserved from %s on %s.", + format_address(from), ifp->name); + goto done; + } int rc; DO_NTOHS(seqno, message + 4); rc = network_prefix(message[2], message[3], 0, @@ -750,6 +825,10 @@ parse_packet(const unsigned char *from, struct interface *ifp, format_prefix(prefix, plen), format_address(from), ifp->name, format_eui64(message + 8), seqno); + if(message[6] == 0) { + debugf(BABEL_DEBUG_COMMON, "Received request with invalid hop count 0"); + goto done; + } handle_request(neigh, prefix, plen, message[6], seqno, message + 8); } else { debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.", @@ -1921,8 +2000,14 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, /* We were about to forward a request to its requestor. Try to find a different neighbour to forward the request to. */ struct babel_route *other_route; + /* First try feasible routes as required by RFC */ + other_route = find_best_route(prefix, plen, 1, neigh); - other_route = find_best_route(prefix, plen, 0, neigh); + if(!other_route || route_metric(other_route) >= INFINITY) { + /* If no feasible route found, try non-feasible routes */ + other_route = find_best_route(prefix, plen, 0, neigh); + } + if(other_route && route_metric(other_route) < INFINITY) successor = other_route->neigh; } diff --git a/babeld/route.c b/babeld/route.c index 466f41383c..eefc5c94df 100644 --- a/babeld/route.c +++ b/babeld/route.c @@ -1078,17 +1078,26 @@ route_lost(struct source *src, unsigned oldmetric) new_route = find_best_route(src->prefix, src->plen, 1, NULL); if(new_route) { consider_route(new_route); - } else if(oldmetric < INFINITY) { - /* Avoid creating a blackhole. */ - send_update_resend(NULL, src->prefix, src->plen); - /* If the route was usable enough, try to get an alternate one. - If it was not, we could be dealing with oscillations around - the value of INFINITY. */ - if(oldmetric <= INFINITY / 2) + } else { + struct babel_route *unfeasible = find_best_route(src->prefix, src->plen, 0, NULL); + + if(unfeasible && !route_expired(unfeasible)) { + /* MUST send seqno request when we have unexpired unfeasible routes */ send_request_resend(NULL, src->prefix, src->plen, - src->metric >= INFINITY ? - src->seqno : seqno_plus(src->seqno, 1), + seqno_plus(src->seqno, 1), src->id); + } else if(oldmetric < INFINITY) { + /* Avoid creating a blackhole. */ + send_update_resend(NULL, src->prefix, src->plen); + /* If the route was usable enough, try to get an alternate one. + If it was not, we could be dealing with oscillations around + the value of INFINITY. */ + if(oldmetric <= INFINITY / 2) + send_request_resend(NULL, src->prefix, src->plen, + src->metric >= INFINITY ? + src->seqno : seqno_plus(src->seqno, 1), + src->id); + } } } diff --git a/babeld/route.h b/babeld/route.h index 89427b8415..ec050fd87b 100644 --- a/babeld/route.h +++ b/babeld/route.h @@ -38,7 +38,6 @@ struct babel_route { struct route_stream; -extern struct babel_route **routes; extern int kernel_metric; extern enum babel_diversity diversity_kind; extern int diversity_factor; diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 8d5306aaaf..e538aa64c2 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -755,26 +755,7 @@ void ptm_sbfd_echo_sess_dn(struct bfd_session *bfd, uint8_t diag) static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa, uint32_t ldisc) { - struct bfd_session *bs; - - bs = bfd_id_lookup(ldisc); - if (bs == NULL) - return NULL; - - switch (bs->key.family) { - case AF_INET: - if (memcmp(&sa->sa_sin.sin_addr, &bs->key.peer, - sizeof(sa->sa_sin.sin_addr))) - return NULL; - break; - case AF_INET6: - if (memcmp(&sa->sa_sin6.sin6_addr, &bs->key.peer, - sizeof(sa->sa_sin6.sin6_addr))) - return NULL; - break; - } - - return bs; + return bfd_id_lookup(ldisc); } struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, @@ -1564,6 +1545,7 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) return; SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN); + bs->local_diag = BD_ADMIN_DOWN; /* Handle data plane shutdown case. */ if (bs->bdc) { diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 74f2d39878..9728046fba 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -36,7 +36,7 @@ struct ptm_client { TAILQ_HEAD(pcqueue, ptm_client); static struct pcqueue pcqueue; -static struct zclient *zclient; +static struct zclient *bfd_zclient; /* @@ -209,7 +209,7 @@ int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state) * * q(64), l(32), w(16), c(8) */ - msg = zclient->obuf; + msg = bfd_zclient->obuf; stream_reset(msg); /* TODO: VRF handling */ @@ -264,7 +264,7 @@ int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state) /* Write packet size. */ stream_putw_at(msg, 0, stream_get_endp(msg)); - return zclient_send_message(zclient); + return zclient_send_message(bfd_zclient); } static void _ptm_msg_read_address(struct stream *msg, struct sockaddr_any *sa) @@ -600,7 +600,7 @@ stream_failure: static int bfdd_replay(ZAPI_CALLBACK_ARGS) { - struct stream *msg = zclient->ibuf; + struct stream *msg = bfd_zclient->ibuf; uint32_t rcmd; STREAM_GETL(msg, rcmd); @@ -653,7 +653,7 @@ static void bfdd_zebra_connected(struct zclient *zc) zclient_create_header(msg, ZEBRA_INTERFACE_ADD, VRF_DEFAULT); /* Send requests. */ - zclient_send_message(zclient); + zclient_send_message(zc); } static void bfdd_sessions_enable_interface(struct interface *ifp) @@ -837,32 +837,32 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv) { hook_register_prio(if_real, 0, bfd_ifp_create); hook_register_prio(if_unreal, 0, bfd_ifp_destroy); - zclient = zclient_new(master, &zclient_options_default, bfd_handlers, - array_size(bfd_handlers)); - assert(zclient != NULL); - zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv); + bfd_zclient = zclient_new(master, &zclient_options_default, bfd_handlers, + array_size(bfd_handlers)); + assert(bfd_zclient != NULL); + zclient_init(bfd_zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv); /* Send replay request on zebra connect. */ - zclient->zebra_connected = bfdd_zebra_connected; + bfd_zclient->zebra_connected = bfdd_zebra_connected; } void bfdd_zclient_register(vrf_id_t vrf_id) { - if (!zclient || zclient->sock < 0) + if (!bfd_zclient || bfd_zclient->sock < 0) return; - zclient_send_reg_requests(zclient, vrf_id); + zclient_send_reg_requests(bfd_zclient, vrf_id); } void bfdd_zclient_unregister(vrf_id_t vrf_id) { - if (!zclient || zclient->sock < 0) + if (!bfd_zclient || bfd_zclient->sock < 0) return; - zclient_send_dereg_requests(zclient, vrf_id); + zclient_send_dereg_requests(bfd_zclient, vrf_id); } void bfdd_zclient_stop(void) { - zclient_stop(zclient); + zclient_stop(bfd_zclient); /* Clean-up and free ptm clients data memory. */ pc_free_all(); @@ -870,7 +870,7 @@ void bfdd_zclient_stop(void) void bfdd_zclient_terminate(void) { - zclient_free(zclient); + zclient_free(bfd_zclient); } diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 9f8f1f6c69..b4adf47eb0 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1444,11 +1444,11 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, uint8_t *notify_datap = (length > 0 ? args->startp : NULL); if (bgp_debug_update(peer, NULL, NULL, 1)) { - char attr_str[BUFSIZ] = {0}; + char str[BUFSIZ] = { 0 }; - bgp_dump_attr(attr, attr_str, sizeof(attr_str)); + bgp_dump_attr(attr, str, sizeof(str)); - zlog_debug("%s: attributes: %s", __func__, attr_str); + zlog_debug("%s: attributes: %s", __func__, str); } /* Only relax error handling for eBGP peers */ @@ -2043,11 +2043,11 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args) peer->host, aspath_print(attr->aspath)); if (bgp_debug_update(peer, NULL, NULL, 1)) { - char attr_str[BUFSIZ] = {0}; + char str[BUFSIZ] = { 0 }; - bgp_dump_attr(attr, attr_str, sizeof(attr_str)); + bgp_dump_attr(attr, str, sizeof(str)); - zlog_debug("%s: attributes: %s", __func__, attr_str); + zlog_debug("%s: attributes: %s", __func__, str); } } else { SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)); @@ -2094,11 +2094,11 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args, peer->host, aspath_print(attr->aspath)); if (bgp_debug_update(peer, NULL, NULL, 1)) { - char attr_str[BUFSIZ] = {0}; + char str[BUFSIZ] = { 0 }; - bgp_dump_attr(attr, attr_str, sizeof(attr_str)); + bgp_dump_attr(attr, str, sizeof(str)); - zlog_debug("%s: attributes: %s", __func__, attr_str); + zlog_debug("%s: attributes: %s", __func__, str); } } else { SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)); diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 5437b67f34..cef1192c10 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -30,7 +30,7 @@ DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data"); -extern struct zclient *zclient; +extern struct zclient *bgp_zclient; static void bfd_session_status_update(struct bfd_session_params *bsp, const struct bfd_session_status *bss, @@ -651,7 +651,7 @@ DEFUN(no_neighbor_bfd_profile, no_neighbor_bfd_profile_cmd, void bgp_bfd_init(struct event_loop *tm) { /* Initialize BFD client functions */ - bfd_protocol_integration_init(zclient, tm); + bfd_protocol_integration_init(bgp_zclient, tm); /* "neighbor bfd" commands. */ install_element(BGP_NODE, &neighbor_bfd_cmd); diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index dcdf2ba25d..95c78cc49d 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1441,14 +1441,14 @@ static char *_ecommunity_ecom2str(struct ecommunity *ecom, int format, int filte snprintf(encbuf, sizeof(encbuf), "FS:action %s", action); } else if (sub_type == ECOMMUNITY_TRAFFIC_RATE) { - union traffic_rate data; + union traffic_rate rate; - data.rate_byte[3] = *(pnt+2); - data.rate_byte[2] = *(pnt+3); - data.rate_byte[1] = *(pnt+4); - data.rate_byte[0] = *(pnt+5); + rate.rate_byte[3] = *(pnt + 2); + rate.rate_byte[2] = *(pnt + 3); + rate.rate_byte[1] = *(pnt + 4); + rate.rate_byte[0] = *(pnt + 5); snprintf(encbuf, sizeof(encbuf), "FS:rate %f", - data.rate_float); + rate.rate_float); } else if (sub_type == ECOMMUNITY_TRAFFIC_MARKING) { snprintf(encbuf, sizeof(encbuf), "FS:marking %u", *(pnt + 5)); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 488f635b81..0ebef2ecfe 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -905,7 +905,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip( bool esi_valid; /* Check socket. */ - if (!zclient || zclient->sock < 0) { + if (!bgp_zclient || bgp_zclient->sock < 0) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: No zclient or zclient->sock exists", __func__); @@ -923,7 +923,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip( if (!esi) esi = zero_esi; - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header( @@ -984,7 +984,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip( frrtrace(5, frr_bgp, evpn_mac_ip_zsend, add, vpn, p, remote_vtep_ip, esi); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } /* @@ -998,7 +998,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, struct stream *s; /* Check socket. */ - if (!zclient || zclient->sock < 0) { + if (!bgp_zclient || bgp_zclient->sock < 0) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: No zclient or zclient->sock exists", __func__); @@ -1014,7 +1014,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, return ZCLIENT_SEND_SUCCESS; } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header( @@ -1041,7 +1041,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, frrtrace(3, frr_bgp, evpn_bum_vtep_zsend, add, vpn, p); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } /* @@ -2062,8 +2062,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, bgp_path_info_add(dest, tmp_pi); } else { tmp_pi = local_pi; - if (attrhash_cmp(tmp_pi->attr, attr) - && !CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED)) + if (!CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(tmp_pi->attr, attr)) route_change = 0; else { /* @@ -3154,8 +3153,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, pi = bgp_create_evpn_bgp_path_info(parent_pi, dest, &attr); new_pi = true; } else { - if (attrhash_cmp(pi->attr, &attr) - && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { + if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(pi->attr, &attr)) { bgp_dest_unlock_node(dest); return 0; } @@ -3184,8 +3182,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, /* Gateway IP nexthop should be resolved */ if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) { - if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi, - NULL, 0, NULL)) + if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi, NULL, 0, NULL, NULL)) bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); else { if (BGP_DEBUG(nht, NHT)) { @@ -3278,8 +3275,8 @@ static int install_evpn_route_entry_in_vni_common( * install_evpn_route_entry_in_vni_mac() or * install_evpn_route_entry_in_vni_ip() */ - if (attrhash_cmp(pi->attr, parent_pi->attr) && - !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) + if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && + attrhash_cmp(pi->attr, parent_pi->attr)) return 0; /* The attribute has changed. */ /* Add (or update) attribute to hash. */ diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 0ef3740d88..70040f83b9 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -212,8 +212,8 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); bgp_path_info_add(dest, pi); } else { - if (attrhash_cmp(pi->attr, parent_pi->attr) - && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { + if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && + attrhash_cmp(pi->attr, parent_pi->attr)) { bgp_dest_unlock_node(dest); return 0; } @@ -421,8 +421,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, bgp_path_info_add(dest, tmp_pi); } else { tmp_pi = local_pi; - if (attrhash_cmp(tmp_pi->attr, attr) - && !CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED)) + if (!CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(tmp_pi->attr, attr)) *route_changed = 0; else { /* The attribute has changed. @@ -1388,7 +1387,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, uint32_t flags = 0; /* Check socket. */ - if (!zclient || zclient->sock < 0) { + if (!bgp_zclient || bgp_zclient->sock < 0) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: No zclient or zclient->sock exists", __func__); @@ -1406,7 +1405,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, if (CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR)) SET_FLAG(flags, ZAPI_ES_VTEP_FLAG_ESR_RXED); - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -1428,7 +1427,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, frrtrace(3, frr_bgp, evpn_mh_vtep_zsend, add, es, es_vtep); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } static enum zclient_send_status bgp_evpn_es_vtep_re_eval_active( @@ -2877,7 +2876,7 @@ static void bgp_evpn_l3nhg_zebra_add_v4_or_v6(struct bgp_evpn_es_vrf *es_vrf, if (!api_nhg.nexthop_num) return; - zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg); + zclient_nhg_send(bgp_zclient, ZEBRA_NHG_ADD, &api_nhg); } static bool bgp_evpn_l3nhg_zebra_ok(struct bgp_evpn_es_vrf *es_vrf) @@ -2886,7 +2885,7 @@ static bool bgp_evpn_l3nhg_zebra_ok(struct bgp_evpn_es_vrf *es_vrf) return false; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return false; return true; @@ -2921,7 +2920,7 @@ static void bgp_evpn_l3nhg_zebra_del_v4_or_v6(struct bgp_evpn_es_vrf *es_vrf, frrtrace(4, frr_bgp, evpn_mh_nhg_zsend, false, v4_nhg, api_nhg.id, es_vrf); - zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg); + zclient_nhg_send(bgp_zclient, ZEBRA_NHG_DEL, &api_nhg); } static void bgp_evpn_l3nhg_zebra_del(struct bgp_evpn_es_vrf *es_vrf) @@ -4477,7 +4476,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add) struct bgp *bgp_vrf = nh->bgp_vrf; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -4488,7 +4487,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add) return; } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header( @@ -4513,7 +4512,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add) frrtrace(2, frr_bgp, evpn_mh_nh_rmac_zsend, add, nh); - zclient_send_message(zclient); + zclient_send_message(bgp_zclient); } static void bgp_evpn_nh_zebra_update(struct bgp_evpn_nh *nh, bool add) diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 568d3d45ee..51d32b5003 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -673,8 +673,6 @@ static inline bool bgp_evpn_is_path_local(struct bgp *bgp, && pi->sub_type == BGP_ROUTE_STATIC); } -extern struct zclient *zclient; - extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf, afi_t afi, safi_t safi, bool add); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 571cca22fd..bfd8fd7c22 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1462,22 +1462,22 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, output_count++; if (use_json && json_array) { - const struct prefix *p = + const struct prefix *pfx = bgp_dest_get_prefix(rm); json_prefix_info = json_object_new_object(); json_object_string_addf(json_prefix_info, - "prefix", "%pFX", p); + "prefix", "%pFX", pfx); json_object_int_add(json_prefix_info, - "prefixLen", p->prefixlen); + "prefixLen", pfx->prefixlen); json_object_object_add(json_prefix_info, "paths", json_array); json_object_object_addf(json_nroute, json_prefix_info, - "%pFX", p); + "%pFX", pfx); json_array = NULL; } } diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index bd04970fd5..6f1780665d 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -105,13 +105,6 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, if (!attr) withdraw = true; - if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) { - flog_err(EC_BGP_FLOWSPEC_PACKET, - "BGP flowspec nlri length maximum reached (%u)", - packet->length); - return BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT; - } - for (; pnt < lim; pnt += psize) { /* Clear prefix structure. */ memset(&p, 0, sizeof(p)); diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h index 049cb6df77..fa611bd372 100644 --- a/bgpd/bgp_flowspec_private.h +++ b/bgpd/bgp_flowspec_private.h @@ -7,7 +7,6 @@ #define _FRR_BGP_FLOWSPEC_PRIVATE_H #define FLOWSPEC_NLRI_SIZELIMIT 240 -#define FLOWSPEC_NLRI_SIZELIMIT_EXTENDED 4095 /* Flowspec raffic action bit*/ #define FLOWSPEC_TRAFFIC_ACTION_TERMINAL 1 diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 478f8c9136..f5d62828a1 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -94,10 +94,8 @@ int bgp_peer_reg_with_nht(struct peer *peer) connected = 1; return bgp_find_or_add_nexthop(peer->bgp, peer->bgp, - family2afi( - peer->connection->su.sa.sa_family), - SAFI_UNICAST, NULL, peer, connected, - NULL); + family2afi(peer->connection->su.sa.sa_family), SAFI_UNICAST, + NULL, peer, connected, NULL, NULL); } static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src) @@ -184,7 +182,11 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) EVENT_OFF(keeper->t_delayopen); EVENT_OFF(keeper->t_connect_check_r); EVENT_OFF(keeper->t_connect_check_w); - EVENT_OFF(keeper->t_process_packet); + + frr_with_mutex (&bm->peer_connection_mtx) { + if (peer_connection_fifo_member(&bm->connection_fifo, keeper)) + peer_connection_fifo_del(&bm->connection_fifo, keeper); + } /* * At this point in time, it is possible that there are packets pending @@ -305,8 +307,13 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) bgp_reads_on(keeper); bgp_writes_on(keeper); - event_add_event(bm->master, bgp_process_packet, keeper, 0, - &keeper->t_process_packet); + + frr_with_mutex (&bm->peer_connection_mtx) { + if (!peer_connection_fifo_member(&bm->connection_fifo, keeper)) { + peer_connection_fifo_add_tail(&bm->connection_fifo, keeper); + } + } + event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet); return (peer); } @@ -1260,7 +1267,7 @@ void bgp_fsm_change_status(struct peer_connection *connection, /* Transition into Clearing or Deleted must /always/ clear all routes.. * (and must do so before actually changing into Deleted.. */ - if (status >= Clearing && (peer->established || peer == bgp->peer_self)) { + if (status >= Clearing && (peer->established || peer != bgp->peer_self)) { bgp_clear_route_all(peer); /* If no route was queued for the clear-node processing, diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index 729a8fe299..dac915a73d 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -99,7 +99,11 @@ void bgp_reads_off(struct peer_connection *connection) assert(fpt->running); event_cancel_async(fpt->master, &connection->t_read, NULL); - EVENT_OFF(connection->t_process_packet); + + frr_with_mutex (&bm->peer_connection_mtx) { + if (peer_connection_fifo_member(&bm->connection_fifo, connection)) + peer_connection_fifo_del(&bm->connection_fifo, connection); + } UNSET_FLAG(connection->thread_flags, PEER_THREAD_READS_ON); } @@ -292,9 +296,13 @@ done: event_add_read(fpt->master, bgp_process_reads, connection, connection->fd, &connection->t_read); - if (added_pkt) - event_add_event(bm->master, bgp_process_packet, connection, 0, - &connection->t_process_packet); + if (added_pkt) { + frr_with_mutex (&bm->peer_connection_mtx) { + if (!peer_connection_fifo_member(&bm->connection_fifo, connection)) + peer_connection_fifo_add_tail(&bm->connection_fifo, connection); + } + event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet); + } } /* diff --git a/bgpd/bgp_io.h b/bgpd/bgp_io.h index 8d481129e5..278980fde6 100644 --- a/bgpd/bgp_io.h +++ b/bgpd/bgp_io.h @@ -10,6 +10,7 @@ #define BGP_WRITE_PACKET_MAX 64U #define BGP_READ_PACKET_MAX 10U +#define BGP_PACKET_PROCESS_LIMIT 100 #include "bgpd/bgpd.h" #include "frr_pthread.h" diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 8ed9584b0a..94f0659e44 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -26,7 +26,7 @@ #include "bgpd/bgp_debug.h" #include "bgpd/bgp_errors.h" -extern struct zclient *zclient; +extern struct zclient *bgp_zclient; /* MPLS Labels hash routines. */ @@ -157,7 +157,7 @@ int bgp_parse_fec_update(void) afi_t afi; safi_t safi; - s = zclient->ibuf; + s = bgp_zclient->ibuf; memset(&p, 0, sizeof(p)); p.family = stream_getw(s); @@ -249,7 +249,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg, p = bgp_dest_get_prefix(dest); /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return; if (BGP_DEBUG(labelpool, LABELPOOL)) @@ -258,7 +258,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg, /* If the route node has a local_label assigned or the * path node has an MPLS SR label index allowing zebra to * derive the label, proceed with registration. */ - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER; zclient_create_header(s, command, VRF_DEFAULT); @@ -288,7 +288,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg, if (reg) stream_putw_at(s, flags_pos, flags); - zclient_send_message(zclient); + zclient_send_message(bgp_zclient); } /** diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 86d6281ed1..d88e746143 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -219,6 +219,9 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr) if (!peer_established(peer->connection)) continue; + if (!peer->afc[afi][safi]) + continue; + if (bgp_debug_update(peer, NULL, NULL, 1)) zlog_debug( "Processing EVPN MAC interface change on peer %s %s", diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 9dbef791b0..1dbac2b864 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -161,6 +161,14 @@ __attribute__((__noreturn__)) void sigint(void) bgp_exit(0); + /* + * This is being done after bgp_exit because items may be removed + * from the connection_fifo + */ + peer_connection_fifo_fini(&bm->connection_fifo); + EVENT_OFF(bm->e_process_packet); + pthread_mutex_destroy(&bm->peer_connection_mtx); + exit(0); } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index d1d4c5af68..782d29a7f5 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -46,7 +46,7 @@ DEFINE_MTYPE_STATIC(BGPD, MPLSVPN_NH_LABEL_BIND_CACHE, /* * Definitions and external declarations. */ -extern struct zclient *zclient; +extern struct zclient *bgp_zclient; extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi) @@ -317,7 +317,7 @@ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi) if (label == BGP_PREVENT_VRF_2_VRF_LEAK) label = MPLS_LABEL_NONE; - zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP); + zclient_send_vrf_label(bgp_zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP); bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label; } @@ -344,7 +344,7 @@ void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi) bgp->name_pretty, bgp->vrf_id); } - zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP); + zclient_send_vrf_label(bgp_zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP); bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label; } @@ -397,11 +397,13 @@ void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi) ctx.argument_len = bgp->vpn_policy[afi] .tovpn_sid_locator->argument_bits_length; + if (CHECK_FLAG(bgp->vpn_policy[afi].tovpn_sid_locator->flags, SRV6_LOCATOR_USID)) + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); } ctx.table = vrf->data.l.table_id; act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6; - zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx); + zclient_send_localsid(bgp_zclient, tovpn_sid, bgp->vrf_id, act, &ctx); tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); *tovpn_sid_ls = *tovpn_sid; @@ -454,10 +456,12 @@ void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp) ctx.node_len = bgp->tovpn_sid_locator->node_bits_length; ctx.function_len = bgp->tovpn_sid_locator->function_bits_length; ctx.argument_len = bgp->tovpn_sid_locator->argument_bits_length; + if (CHECK_FLAG(bgp->tovpn_sid_locator->flags, SRV6_LOCATOR_USID)) + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); } ctx.table = vrf->data.l.table_id; act = ZEBRA_SEG6_LOCAL_ACTION_END_DT46; - zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx); + zclient_send_localsid(bgp_zclient, tovpn_sid, bgp->vrf_id, act, &ctx); tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); *tovpn_sid_ls = *tovpn_sid; @@ -519,7 +523,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi) bgp->vpn_policy[afi] .tovpn_sid_locator->argument_bits_length; } - zclient_send_localsid(zclient, + zclient_send_localsid(bgp_zclient, bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent, bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, &seg6localctx); @@ -564,7 +568,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp) seg6localctx.argument_len = bgp->tovpn_sid_locator->argument_bits_length; } - zclient_send_localsid(zclient, bgp->tovpn_zebra_vrf_sid_last_sent, + zclient_send_localsid(bgp_zclient, bgp->tovpn_zebra_vrf_sid_last_sent, bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, &seg6localctx); XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent); @@ -1088,10 +1092,8 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, /* the route is defined with the "network <prefix>" command */ if (CHECK_FLAG(bgp_nexthop->flags, BGP_FLAG_IMPORT_CHECK)) - nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, - afi, SAFI_UNICAST, - bpi_ultimate, NULL, - 0, p); + nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi, SAFI_UNICAST, + bpi_ultimate, NULL, 0, p, bpi_ultimate); else /* if "no bgp network import-check" is set, * then mark the nexthop as valid. @@ -1105,18 +1107,22 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, * TBD do we need to do anything about the * 'connected' parameter? */ - nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi, - safi, bpi, NULL, 0, p); + /* VPN paths: the new bpi may be altered like + * with 'nexthop vpn export' command. Use the bpi_ultimate + * to find the original nexthop + */ + nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p, + bpi_ultimate); /* * If you are using SRv6 VPN instead of MPLS, it need to check * the SID allocation. If the sid is not allocated, the rib * will be invalid. + * If the SID per VRF is not available, also consider the rib as + * invalid. */ - if (to_bgp->srv6_enabled && - (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) { - nh_valid = false; - } + if (to_bgp->srv6_enabled && nh_valid) + nh_valid = is_pi_srv6_valid(bpi, bgp_nexthop, afi, safi); if (debug) zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p, @@ -1207,8 +1213,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, return NULL; } - if (attrhash_cmp(bpi->attr, new_attr) && labelssame && - !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && + if (labelssame && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && + attrhash_cmp(bpi->attr, new_attr) && leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi, source_bpi, bpi, bgp_orig, p, debug) == !!CHECK_FLAG(bpi->flags, BGP_PATH_VALID)) { @@ -1594,8 +1600,8 @@ vpn_leak_from_vrf_get_per_nexthop_label(afi_t afi, struct bgp_path_info *pi, bgp_nexthop = from_bgp; nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); - nh_valid = bgp_find_or_add_nexthop(from_bgp, bgp_nexthop, nh_afi, - SAFI_UNICAST, pi, NULL, 0, NULL); + nh_valid = bgp_find_or_add_nexthop(from_bgp, bgp_nexthop, nh_afi, SAFI_UNICAST, pi, NULL, 0, + NULL, NULL); if (!nh_valid && is_bgp_static_route && !CHECK_FLAG(from_bgp->flags, BGP_FLAG_IMPORT_CHECK)) { @@ -2337,8 +2343,8 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ break; } - if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, - path_vpn, bpi, src_vrf, p, debug)) + if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, path_vpn, bpi, + src_vrf, p, debug)) SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID); else UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID); diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 56dd33f9b1..75c0264987 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -342,6 +342,37 @@ static inline bool is_pi_family_vpn(struct bgp_path_info *pi) is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN)); } +/* + * If you are using SRv6 VPN instead of MPLS, it need to check + * the SID allocation. If the sid is not allocated, the rib + * will be invalid. + * If the SID per VRF is not available, also consider the rib as + * invalid. + */ +static inline bool is_pi_srv6_valid(struct bgp_path_info *pi, struct bgp *bgp_nexthop, afi_t afi, + safi_t safi) +{ + if (!pi->attr->srv6_l3vpn && !pi->attr->srv6_vpn) + return false; + + /* imported paths from VPN: srv6 enabled and nht reachability + * are enough to know if that path is valid + */ + if (safi == SAFI_UNICAST) + return true; + + if (bgp_nexthop->vpn_policy[afi].tovpn_sid == NULL && bgp_nexthop->tovpn_sid == NULL) + return false; + + if (bgp_nexthop->tovpn_sid_index == 0 && + !CHECK_FLAG(bgp_nexthop->vrf_flags, BGP_VRF_TOVPN_SID_AUTO) && + bgp_nexthop->vpn_policy[afi].tovpn_sid_index == 0 && + !CHECK_FLAG(bgp_nexthop->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO)) + return false; + + return true; +} + extern void vpn_policy_routemap_event(const char *rmap_name); extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c index 93d9f67245..4a696fdcbf 100644 --- a/bgpd/bgp_mplsvpn_snmp.c +++ b/bgpd/bgp_mplsvpn_snmp.c @@ -1460,8 +1460,6 @@ static struct bgp_path_info *bgpL3vpnRte_lookup(struct variable *v, oid name[], pi = bgp_lookup_route_next(l3vpn_bgp, dest, &prefix, policy, &nexthop); if (pi) { - uint8_t vrf_name_len = - strnlen((*l3vpn_bgp)->name, VRF_NAMSIZ); const struct prefix *p = bgp_dest_get_prefix(*dest); uint8_t oid_index; bool v4 = (p->family == AF_INET); @@ -1469,6 +1467,8 @@ static struct bgp_path_info *bgpL3vpnRte_lookup(struct variable *v, oid name[], : sizeof(struct in6_addr); struct attr *attr = pi->attr; + vrf_name_len = strnlen((*l3vpn_bgp)->name, VRF_NAMSIZ); + /* copy the index parameters */ oid_copy_str(&name[namelen], (*l3vpn_bgp)->name, vrf_name_len); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index bd27562134..330af64379 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -34,11 +34,12 @@ #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_ecommunity.h" -extern struct zclient *zclient; +extern struct zclient *bgp_zclient; static void register_zebra_rnh(struct bgp_nexthop_cache *bnc); static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc); -static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p); +static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p, + struct bgp *bgp_nexthop, struct bgp_path_info *pi_source); static void bgp_nht_ifp_initial(struct event *thread); DEFINE_HOOK(bgp_nht_path_update, (struct bgp *bgp, struct bgp_path_info *pi, bool valid), @@ -297,10 +298,9 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer) * A route and its nexthop might belong to different VRFs. Therefore, * we need both the bgp_route and bgp_nexthop pointers. */ -int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, - afi_t afi, safi_t safi, struct bgp_path_info *pi, - struct peer *peer, int connected, - const struct prefix *orig_prefix) +int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi_t afi, safi_t safi, + struct bgp_path_info *pi, struct peer *peer, int connected, + const struct prefix *orig_prefix, struct bgp_path_info *source_pi) { struct bgp_nexthop_cache_head *tree = NULL; struct bgp_nexthop_cache *bnc; @@ -330,7 +330,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, /* This will return true if the global IPv6 NH is a link local * addr */ - if (!make_prefix(afi, pi, &p)) + if (!make_prefix(afi, pi, &p, bgp_nexthop, source_pi)) return 1; /* @@ -667,7 +667,7 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc, nexthop->vrf_id); if (ifp) zclient_send_interface_radv_req( - zclient, nexthop->vrf_id, ifp, + bgp_zclient, nexthop->vrf_id, ifp, true, BGP_UNNUM_DEFAULT_RA_INTERVAL); } @@ -994,7 +994,8 @@ void bgp_cleanup_nexthops(struct bgp *bgp) * make_prefix - make a prefix structure from the path (essentially * path's node. */ -static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) +static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p, + struct bgp *bgp_nexthop, struct bgp_path_info *source_pi) { int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP) @@ -1004,8 +1005,19 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) struct bgp_dest *net = pi->net; const struct prefix *p_orig = bgp_dest_get_prefix(net); struct in_addr ipv4; - struct peer *peer = pi->peer; - struct attr *attr = pi->attr; + struct peer *peer; + struct attr *attr; + bool local_sid = false; + struct bgp *bgp = bgp_get_default(); + struct prefix_ipv6 tmp_prefix; + + if (source_pi) { + attr = source_pi->attr; + peer = source_pi->peer; + } else { + peer = pi->peer; + attr = pi->attr; + } if (p_orig->family == AF_FLOWSPEC) { if (!peer) @@ -1035,37 +1047,50 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) break; case AFI_IP6: p->family = AF_INET6; - if (attr->srv6_l3vpn) { + if (bgp && bgp->srv6_locator && bgp->srv6_enabled && pi->attr->srv6_l3vpn) { + tmp_prefix.family = AF_INET6; + tmp_prefix.prefixlen = IPV6_MAX_BITLEN; + tmp_prefix.prefix = pi->attr->srv6_l3vpn->sid; + if (bgp_nexthop->vpn_policy[afi].tovpn_sid_locator && + bgp_nexthop->vpn_policy[afi].tovpn_sid) + local_sid = prefix_match(&bgp_nexthop->vpn_policy[afi] + .tovpn_sid_locator->prefix, + &tmp_prefix); + else if (bgp_nexthop->tovpn_sid_locator && bgp_nexthop->tovpn_sid) + local_sid = prefix_match(&bgp_nexthop->tovpn_sid_locator->prefix, + &tmp_prefix); + } + if (local_sid == false && pi->attr->srv6_l3vpn) { p->prefixlen = IPV6_MAX_BITLEN; - if (attr->srv6_l3vpn->transposition_len != 0 && + if (pi->attr->srv6_l3vpn->transposition_len != 0 && BGP_PATH_INFO_NUM_LABELS(pi)) { - IPV6_ADDR_COPY(&p->u.prefix6, &attr->srv6_l3vpn->sid); + IPV6_ADDR_COPY(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid); transpose_sid(&p->u.prefix6, decode_label(&pi->extra->labels->label[0]), - attr->srv6_l3vpn->transposition_offset, - attr->srv6_l3vpn->transposition_len); + pi->attr->srv6_l3vpn->transposition_offset, + pi->attr->srv6_l3vpn->transposition_len); } else - IPV6_ADDR_COPY(&(p->u.prefix6), &(attr->srv6_l3vpn->sid)); + IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3vpn->sid)); } else if (is_bgp_static) { p->u.prefix6 = p_orig->u.prefix6; p->prefixlen = p_orig->prefixlen; - } else { + } else if (attr) { /* If we receive MP_REACH nexthop with ::(LL) * or LL(LL), use LL address as nexthop cache. */ - if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL && + if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL && (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global) || IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))) p->u.prefix6 = attr->mp_nexthop_local; /* If we receive MR_REACH with (GA)::(LL) * then check for route-map to choose GA or LL */ - else if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { + else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { if (CHECK_FLAG(attr->nh_flags, BGP_ATTR_NH_MP_PREFER_GLOBAL)) p->u.prefix6 = attr->mp_nexthop_global; else p->u.prefix6 = attr->mp_nexthop_local; - } else if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL && + } else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) { /* If we receive MP_REACH with GUA as LL, we should * check if we have Link-Local Next Hop capability also. @@ -1106,11 +1131,11 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) */ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) { - bool exact_match = false; + bool match_p = false; bool resolve_via_default = false; int ret; - if (!zclient) + if (!bgp_zclient) return; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -1130,7 +1155,7 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) } if (command == ZEBRA_NEXTHOP_REGISTER) { if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) - exact_match = true; + match_p = true; if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)) resolve_via_default = true; } @@ -1140,8 +1165,8 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) zserv_command_string(command), &bnc->prefix, bnc->bgp->name_pretty); - ret = zclient_send_rnh(zclient, command, &bnc->prefix, SAFI_UNICAST, - exact_match, resolve_via_default, + ret = zclient_send_rnh(bgp_zclient, command, &bnc->prefix, SAFI_UNICAST, + match_p, resolve_via_default, bnc->bgp->vrf_id); if (ret == ZCLIENT_SEND_FAILURE) { flog_warn(EC_BGP_ZEBRA_SEND, @@ -1568,7 +1593,7 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer) if (!ifp) continue; - zclient_send_interface_radv_req(zclient, + zclient_send_interface_radv_req(bgp_zclient, nhop->vrf_id, ifp, true, BGP_UNNUM_DEFAULT_RA_INTERVAL); @@ -1618,7 +1643,7 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer) if (!ifp) continue; - zclient_send_interface_radv_req(zclient, nhop->vrf_id, ifp, 0, + zclient_send_interface_radv_req(bgp_zclient, nhop->vrf_id, ifp, 0, 0); } } diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h index 345089ac5a..76536d6ebf 100644 --- a/bgpd/bgp_nht.h +++ b/bgpd/bgp_nht.h @@ -25,11 +25,10 @@ extern void bgp_nexthop_update(struct vrf *vrf, struct prefix *match, * peer - The BGP peer associated with this NHT * connected - True if NH MUST be a connected route */ -extern int bgp_find_or_add_nexthop(struct bgp *bgp_route, - struct bgp *bgp_nexthop, afi_t a, - safi_t safi, struct bgp_path_info *p, - struct peer *peer, int connected, - const struct prefix *orig_prefix); +extern int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi_t a, + safi_t safi, struct bgp_path_info *p, struct peer *peer, + int connected, const struct prefix *orig_prefix, + struct bgp_path_info *source_pi); /** * bgp_unlink_nexthop() - Unlink the nexthop object from the path structure. diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 4c2eb03f3a..16e94d9fe2 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3148,8 +3148,6 @@ static void bgp_dynamic_capability_paths_limit(uint8_t *pnt, int action, SET_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_RCV); while (data + CAPABILITY_CODE_PATHS_LIMIT_LEN <= end) { - afi_t afi; - safi_t safi; iana_afi_t pkt_afi; iana_safi_t pkt_safi; uint16_t paths_limit = 0; @@ -3508,8 +3506,6 @@ static void bgp_dynamic_capability_llgr(uint8_t *pnt, int action, SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV); while (data + BGP_CAP_LLGR_MIN_PACKET_LEN <= end) { - afi_t afi; - safi_t safi; iana_afi_t pkt_afi; iana_safi_t pkt_safi; struct graceful_restart_af graf; @@ -3616,8 +3612,6 @@ static void bgp_dynamic_capability_graceful_restart(uint8_t *pnt, int action, while (data + GRACEFUL_RESTART_CAPABILITY_PER_AFI_SAFI_SIZE <= end) { - afi_t afi; - safi_t safi; iana_afi_t pkt_afi; iana_safi_t pkt_safi; struct graceful_restart_af graf; @@ -3974,6 +3968,18 @@ int bgp_capability_receive(struct peer_connection *connection, * would not, making event flow difficult to understand. Please think twice * before hacking this. * + * packet_processing is now a FIFO of connections that need to be handled + * This loop has a maximum run of 100(BGP_PACKET_PROCESS_LIMIT) packets, + * but each individual connection can only handle the quanta value as + * specified in bgp_vty.c. If the connection still has work to do, place it + * back on the back of the queue for more work. Do note that event_should_yield + * is also being called to figure out if processing should stop and work + * picked up after other items can run. This was added *After* withdrawals + * started being processed at scale and this function was taking cpu for 40+ seconds + * On my machine we are getting 2-3 packets before a yield should happen in the + * update case. Withdrawal is 1 packet being processed(note this is a very very + * fast computer) before other items should be run. + * * Thread type: EVENT_EVENT * @param thread * @return 0 @@ -3986,30 +3992,53 @@ void bgp_process_packet(struct event *thread) uint32_t rpkt_quanta_old; // how many packets to read int fsm_update_result; // return code of bgp_event_update() int mprc; // message processing return code + uint32_t processed = 0, curr_connection_processed = 0; + bool more_work = false; + size_t count; + uint32_t total_packets_to_process; + + frr_with_mutex (&bm->peer_connection_mtx) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + + if (!connection) + goto done; - connection = EVENT_ARG(thread); + total_packets_to_process = BGP_PACKET_PROCESS_LIMIT; peer = connection->peer; rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta, memory_order_relaxed); + fsm_update_result = 0; - /* Guard against scheduled events that occur after peer deletion. */ - if (connection->status == Deleted || connection->status == Clearing) - return; + while ((processed < total_packets_to_process) && connection) { + /* Guard against scheduled events that occur after peer deletion. */ + if (connection->status == Deleted || connection->status == Clearing) { + frr_with_mutex (&bm->peer_connection_mtx) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + + if (connection) + peer = connection->peer; - unsigned int processed = 0; + continue; + } - while (processed < rpkt_quanta_old) { uint8_t type = 0; bgp_size_t size; char notify_data_length[2]; - frr_with_mutex (&connection->io_mtx) { + frr_with_mutex (&connection->io_mtx) peer->curr = stream_fifo_pop(connection->ibuf); - } - if (peer->curr == NULL) // no packets to process, hmm... - return; + if (peer->curr == NULL) { + frr_with_mutex (&bm->peer_connection_mtx) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + + + if (connection) + peer = connection->peer; + + continue; + } /* skip the marker and copy the packet length */ stream_forward_getp(peer->curr, BGP_MARKER_SIZE); @@ -4113,32 +4142,81 @@ void bgp_process_packet(struct event *thread) stream_free(peer->curr); peer->curr = NULL; processed++; + curr_connection_processed++; /* Update FSM */ if (mprc != BGP_PACKET_NOOP) fsm_update_result = bgp_event_update(connection, mprc); - else - continue; /* * If peer was deleted, do not process any more packets. This * is usually due to executing BGP_Stop or a stub deletion. */ - if (fsm_update_result == FSM_PEER_TRANSFERRED - || fsm_update_result == FSM_PEER_STOPPED) - break; + if (fsm_update_result == FSM_PEER_TRANSFERRED || + fsm_update_result == FSM_PEER_STOPPED) { + frr_with_mutex (&bm->peer_connection_mtx) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + + if (connection) + peer = connection->peer; + + continue; + } + + bool yield = event_should_yield(thread); + if (curr_connection_processed >= rpkt_quanta_old || yield) { + curr_connection_processed = 0; + frr_with_mutex (&bm->peer_connection_mtx) { + if (!peer_connection_fifo_member(&bm->connection_fifo, connection)) + peer_connection_fifo_add_tail(&bm->connection_fifo, + connection); + if (!yield) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + else + connection = NULL; + } + if (connection) + peer = connection->peer; + + continue; + } + + frr_with_mutex (&connection->io_mtx) { + if (connection->ibuf->count > 0) + more_work = true; + else + more_work = false; + } + + if (!more_work) { + frr_with_mutex (&bm->peer_connection_mtx) + connection = peer_connection_fifo_pop(&bm->connection_fifo); + + if (connection) + peer = connection->peer; + } } - if (fsm_update_result != FSM_PEER_TRANSFERRED - && fsm_update_result != FSM_PEER_STOPPED) { + if (connection) { frr_with_mutex (&connection->io_mtx) { - // more work to do, come back later if (connection->ibuf->count > 0) - event_add_event(bm->master, bgp_process_packet, - connection, 0, - &connection->t_process_packet); + more_work = true; + else + more_work = false; + } + frr_with_mutex (&bm->peer_connection_mtx) { + if (more_work && + !peer_connection_fifo_member(&bm->connection_fifo, connection)) + peer_connection_fifo_add_tail(&bm->connection_fifo, connection); } } + +done: + frr_with_mutex (&bm->peer_connection_mtx) + count = peer_connection_fifo_count(&bm->connection_fifo); + + if (count) + event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet); } /* Send EOR when routes are processed by selection deferral timer */ diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index b85a8e2254..2b13715da3 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -279,6 +279,13 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add); +static void bgp_pbr_val_mask_free(void *arg) +{ + struct bgp_pbr_val_mask *pbr_val_mask = arg; + + XFREE(MTYPE_PBR_VALMASK, pbr_val_mask); +} + static bool bgp_pbr_extract_enumerate_unary_opposite( uint8_t unary_operator, struct bgp_pbr_val_mask *and_valmask, @@ -442,7 +449,7 @@ static bool bgp_pbr_extract(struct bgp_pbr_match_val list[], struct bgp_pbr_range_port *range) { int i = 0; - bool exact_match = false; + bool match_p = false; if (range) memset(range, 0, sizeof(struct bgp_pbr_range_port)); @@ -457,9 +464,9 @@ static bool bgp_pbr_extract(struct bgp_pbr_match_val list[], OPERATOR_COMPARE_EQUAL_TO)) { if (range) range->min_port = list[i].value; - exact_match = true; + match_p = true; } - if (exact_match && i > 0) + if (match_p && i > 0) return false; if (list[i].compare_operator == (OPERATOR_COMPARE_GREATER_THAN + @@ -965,7 +972,12 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, return 0; } -static void bgp_pbr_match_entry_free(void *arg) +static void bgp_pbr_match_entry_free(struct bgp_pbr_match_entry *bpme) +{ + XFREE(MTYPE_PBR_MATCH_ENTRY, bpme); +} + +static void bgp_pbr_match_entry_hash_free(void *arg) { struct bgp_pbr_match_entry *bpme; @@ -976,16 +988,21 @@ static void bgp_pbr_match_entry_free(void *arg) bpme->installed = false; bpme->backpointer = NULL; } - XFREE(MTYPE_PBR_MATCH_ENTRY, bpme); + bgp_pbr_match_entry_free(bpme); +} + +static void bgp_pbr_match_free(struct bgp_pbr_match *bpm) +{ + XFREE(MTYPE_PBR_MATCH, bpm); } -static void bgp_pbr_match_free(void *arg) +static void bgp_pbr_match_hash_free(void *arg) { struct bgp_pbr_match *bpm; bpm = (struct bgp_pbr_match *)arg; - hash_clean(bpm->entry_hash, bgp_pbr_match_entry_free); + hash_clean(bpm->entry_hash, bgp_pbr_match_entry_hash_free); if (hashcount(bpm->entry_hash) == 0) { /* delete iptable entry first */ @@ -1004,7 +1021,7 @@ static void bgp_pbr_match_free(void *arg) } hash_clean_and_free(&bpm->entry_hash, NULL); - XFREE(MTYPE_PBR_MATCH, bpm); + bgp_pbr_match_free(bpm); } static void *bgp_pbr_match_alloc_intern(void *arg) @@ -1019,7 +1036,12 @@ static void *bgp_pbr_match_alloc_intern(void *arg) return new; } -static void bgp_pbr_rule_free(void *arg) +static void bgp_pbr_rule_free(struct bgp_pbr_rule *pbr) +{ + XFREE(MTYPE_PBR_RULE, pbr); +} + +static void bgp_pbr_rule_hash_free(void *arg) { struct bgp_pbr_rule *bpr; @@ -1032,7 +1054,7 @@ static void bgp_pbr_rule_free(void *arg) bpr->action->refcnt--; bpr->action = NULL; } - XFREE(MTYPE_PBR_RULE, bpr); + bgp_pbr_rule_free(bpr); } static void *bgp_pbr_rule_alloc_intern(void *arg) @@ -1372,8 +1394,8 @@ struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id, void bgp_pbr_cleanup(struct bgp *bgp) { - hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_free); - hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_free); + hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_hash_free); + hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_hash_free); hash_clean_and_free(&bgp->pbr_action_hash, bgp_pbr_action_free); if (bgp->bgp_pbr_cfg == NULL) @@ -1656,6 +1678,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa, } } hash_release(bgp->pbr_rule_hash, bpr); + bgp_pbr_rule_free(bpr); + bgp_pbr_bpa_remove(bpa); } @@ -1685,6 +1709,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa, } } hash_release(bpm->entry_hash, bpme); + bgp_pbr_match_entry_free(bpme); if (hashcount(bpm->entry_hash) == 0) { /* delete iptable entry first */ /* then delete ipset match */ @@ -1700,6 +1725,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa, bpm->action = NULL; } hash_release(bgp->pbr_match_hash, bpm); + bgp_pbr_match_free(bpm); /* XXX release pbr_match_action if not used * note that drop does not need to call send_pbr_action */ @@ -2111,17 +2137,6 @@ static void bgp_pbr_policyroute_remove_from_zebra( bgp, path, bpf, bpof, FLOWSPEC_ICMP_TYPE); else bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path, bpf); - /* flush bpof */ - if (bpof->tcpflags) - list_delete_all_node(bpof->tcpflags); - if (bpof->dscp) - list_delete_all_node(bpof->dscp); - if (bpof->flowlabel) - list_delete_all_node(bpof->flowlabel); - if (bpof->pkt_len) - list_delete_all_node(bpof->pkt_len); - if (bpof->fragment) - list_delete_all_node(bpof->fragment); } static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add) @@ -2606,19 +2621,6 @@ static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp, bgp, path, bpf, bpof, nh, rate, FLOWSPEC_ICMP_TYPE); else bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh, rate); - /* flush bpof */ - if (bpof->tcpflags) - list_delete_all_node(bpof->tcpflags); - if (bpof->dscp) - list_delete_all_node(bpof->dscp); - if (bpof->pkt_len) - list_delete_all_node(bpof->pkt_len); - if (bpof->fragment) - list_delete_all_node(bpof->fragment); - if (bpof->icmp_type) - list_delete_all_node(bpof->icmp_type); - if (bpof->icmp_code) - list_delete_all_node(bpof->icmp_code); } static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, @@ -2684,6 +2686,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, srcp = ⦥ else { bpof.icmp_type = list_new(); + bpof.icmp_type->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->icmp_type, api->match_icmp_type_num, OPERATOR_UNARY_OR, @@ -2699,6 +2702,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, dstp = &range_icmp_code; else { bpof.icmp_code = list_new(); + bpof.icmp_code->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->icmp_code, api->match_icmp_code_num, OPERATOR_UNARY_OR, @@ -2719,6 +2723,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, FLOWSPEC_TCP_FLAGS); } else if (kind_enum == OPERATOR_UNARY_OR) { bpof.tcpflags = list_new(); + bpof.tcpflags->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->tcpflags, api->match_tcpflags_num, OPERATOR_UNARY_OR, @@ -2736,6 +2741,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, bpf.pkt_len = &pkt_len; else { bpof.pkt_len = list_new(); + bpof.pkt_len->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->packet_length, api->match_packet_length_num, OPERATOR_UNARY_OR, @@ -2745,12 +2751,14 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, } if (api->match_dscp_num >= 1) { bpof.dscp = list_new(); + bpof.dscp->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->dscp, api->match_dscp_num, OPERATOR_UNARY_OR, bpof.dscp, FLOWSPEC_DSCP); } if (api->match_fragment_num) { bpof.fragment = list_new(); + bpof.fragment->del = bgp_pbr_val_mask_free; bgp_pbr_extract_enumerate(api->fragment, api->match_fragment_num, OPERATOR_UNARY_OR, @@ -2766,7 +2774,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, bpf.family = afi2family(api->afi); if (!add) { bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf, &bpof); - return; + goto flush_bpof; } /* no action for add = true */ for (i = 0; i < api->action_num; i++) { @@ -2844,6 +2852,22 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path, if (continue_loop == 0) break; } + +flush_bpof: + if (bpof.tcpflags) + list_delete(&bpof.tcpflags); + if (bpof.dscp) + list_delete(&bpof.dscp); + if (bpof.flowlabel) + list_delete(&bpof.flowlabel); + if (bpof.pkt_len) + list_delete(&bpof.pkt_len); + if (bpof.fragment) + list_delete(&bpof.fragment); + if (bpof.icmp_type) + list_delete(&bpof.icmp_type); + if (bpof.icmp_code) + list_delete(&bpof.icmp_code); } void bgp_pbr_update_entry(struct bgp *bgp, const struct prefix *p, diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index cb16c4dc2e..c8116506a7 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -151,8 +151,6 @@ struct bgp_pbr_config { bool pbr_interface_any_ipv6; }; -extern struct bgp_pbr_config *bgp_pbr_cfg; - struct bgp_pbr_rule { uint32_t flags; struct prefix src; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 003a9a4d4d..fd860c9236 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4201,12 +4201,30 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data) { struct meta_queue *mq = data; uint32_t i; + uint32_t peers_on_fifo; + static uint32_t total_runs = 0; + + total_runs++; + + frr_with_mutex (&bm->peer_connection_mtx) + peers_on_fifo = peer_connection_fifo_count(&bm->connection_fifo); + + /* + * If the number of peers on the fifo is greater than 10 + * let's yield this run of the MetaQ to allow the packet processing to make + * progress against the incoming packets. But we should also + * attempt to allow this to run occassionally. Let's run + * something every 10 attempts to process the work queue. + */ + if (peers_on_fifo > 10 && total_runs % 10 != 0) + return WQ_QUEUE_BLOCKED; for (i = 0; i < MQ_SIZE; i++) if (process_subq(mq->subq[i], i)) { mq->size--; break; } + return mq->size ? WQ_REQUEUE : WQ_SUCCESS; } @@ -4323,9 +4341,14 @@ static void early_meta_queue_free(struct meta_queue *mq, struct bgp_dest_queue * struct bgp_dest *dest; while (!STAILQ_EMPTY(l)) { + struct bgp_table *table; + dest = STAILQ_FIRST(l); STAILQ_REMOVE_HEAD(l, pq); STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */ + + table = bgp_dest_table(dest); + bgp_table_unlock(table); mq->size--; } } @@ -4336,9 +4359,14 @@ static void other_meta_queue_free(struct meta_queue *mq, struct bgp_dest_queue * struct bgp_dest *dest; while (!STAILQ_EMPTY(l)) { + struct bgp_table *table; + dest = STAILQ_FIRST(l); STAILQ_REMOVE_HEAD(l, pq); STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */ + + table = bgp_dest_table(dest); + bgp_table_unlock(table); mq->size--; } } @@ -4909,6 +4937,7 @@ bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct { bool connected; afi_t nh_afi; + struct bgp_path_info *bpi_ultimate = NULL; if (((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || @@ -4924,13 +4953,16 @@ bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct struct bgp *bgp_nexthop = bgp; - if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) + if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) { bgp_nexthop = pi->extra->vrfleak->bgp_orig; + if (pi->sub_type == BGP_ROUTE_IMPORTED) + bpi_ultimate = bgp_get_imported_bpi_ultimate(pi); + } nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, safi, pi, NULL, connected, - bgp_nht_param_prefix) || + bgp_nht_param_prefix, bpi_ultimate) || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { if (accept_own) bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN); @@ -6793,6 +6825,16 @@ static int clear_batch_rib_helper(struct bgp_clearing_info *cinfo) */ UNSET_FLAG(cinfo->flags, BGP_CLEARING_INFO_FLAG_RESUME); } + + /* Return immediately, otherwise the 'ret' state will be overwritten + * by next afi/safi. Also resume state stored for current afi/safi + * in walk_batch_table_helper, will be overwritten. This may cause to + * skip the nets to be walked again, so they won't be marked for deletion + * from BGP table + */ + if (ret != 0) + return ret; + safi = SAFI_UNICAST; } return ret; @@ -7304,8 +7346,8 @@ static void bgp_nexthop_reachability_check(afi_t afi, safi_t safi, /* Nexthop reachability check. */ if (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST) { if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) { - if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi, - bpi, NULL, 0, p)) + if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p, + NULL)) bgp_path_info_set_flag(dest, bpi, BGP_PATH_VALID); else { @@ -7477,9 +7519,9 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, break; if (pi) { - if (attrhash_cmp(pi->attr, attr_new) - && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) - && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) { + if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && + !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS) && + attrhash_cmp(pi->attr, attr_new)) { bgp_dest_unlock_node(dest); bgp_attr_unintern(&attr_new); aspath_unintern(&attr.aspath); @@ -7973,6 +8015,8 @@ void bgp_static_delete(struct bgp *bgp) rm = bgp_dest_unlock_node(rm); assert(rm); } + + bgp_table_unlock(table); } else { bgp_static = bgp_dest_get_bgp_static_info(dest); bgp_static_withdraw(bgp, @@ -9731,8 +9775,8 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, if (bpi) { /* Ensure the (source route) type is updated. */ bpi->type = type; - if (attrhash_cmp(bpi->attr, new_attr) - && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) { + if (!CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && + attrhash_cmp(bpi->attr, new_attr)) { bgp_attr_unintern(&new_attr); aspath_unintern(&attr.aspath); bgp_dest_unlock_node(bn); @@ -12002,8 +12046,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, /* Line 7 display Originator, Cluster-id */ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) || CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { - char buf[BUFSIZ] = {0}; - if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) { if (json_paths) json_object_string_addf(json_path, @@ -12015,9 +12057,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { - struct cluster_list *cluster = - bgp_attr_get_cluster(attr); - int i; + struct cluster_list *cluster = bgp_attr_get_cluster(attr); if (json_paths) { json_cluster_list = json_object_new_object(); @@ -13297,8 +13337,6 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, struct bgp_ return CMD_WARNING; } - match.family = afi2family(afi); - if (use_json) json = json_object_new_object(); @@ -13547,7 +13585,7 @@ DEFUN (show_ip_bgp_large_community_list, afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; int idx = 0; - bool exact_match = 0; + bool match_p = 0; struct bgp *bgp = NULL; bool uj = use_json(argc, argv); @@ -13564,10 +13602,10 @@ DEFUN (show_ip_bgp_large_community_list, const char *clist_number_or_name = argv[++idx]->arg; if (++idx < argc && strmatch(argv[idx]->text, "exact-match")) - exact_match = 1; + match_p = 1; return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name, - exact_match, afi, safi, uj); + match_p, afi, safi, uj); } DEFUN (show_ip_bgp_large_community, show_ip_bgp_large_community_cmd, @@ -13586,7 +13624,7 @@ DEFUN (show_ip_bgp_large_community, afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; int idx = 0; - bool exact_match = 0; + bool match_p = false; struct bgp *bgp = NULL; bool uj = use_json(argc, argv); uint16_t show_flags = 0; @@ -13604,10 +13642,10 @@ DEFUN (show_ip_bgp_large_community, if (argv_find(argv, argc, "AA:BB:CC", &idx)) { if (argv_find(argv, argc, "exact-match", &idx)) { argc--; - exact_match = 1; + match_p = true; } return bgp_show_lcommunity(vty, bgp, argc, argv, - exact_match, afi, safi, uj); + match_p, afi, safi, uj); } else return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, show_flags, @@ -13878,7 +13916,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, void *output_arg = NULL; struct bgp *bgp = NULL; int idx = 0; - int exact_match = 0; + int match_p = 0; char *community = NULL; bool first = true; uint16_t show_flags = 0; @@ -13943,7 +13981,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, community = maybecomm; if (argv_find(argv, argc, "exact-match", &idx)) - exact_match = 1; + match_p = 1; if (!community) sh_type = bgp_show_type_community_all; @@ -13954,7 +13992,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, struct community_list *list; if (argv_find(argv, argc, "exact-match", &idx)) - exact_match = 1; + match_p = 1; list = community_list_lookup(bgp_clist, clist_number_or_name, 0, COMMUNITY_LIST_MASTER); @@ -13964,7 +14002,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, return CMD_WARNING; } - if (exact_match) + if (match_p) sh_type = bgp_show_type_community_list_exact; else sh_type = bgp_show_type_community_list; @@ -14074,7 +14112,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, /* show bgp: AFI_IP6, show ip bgp: AFI_IP */ if (community) return bgp_show_community(vty, bgp, community, - exact_match, afi, safi, + match_p, afi, safi, show_flags); else return bgp_show(vty, bgp, afi, safi, sh_type, @@ -14119,7 +14157,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, if (community) bgp_show_community( vty, abgp, community, - exact_match, afi, safi, + match_p, afi, safi, show_flags); else bgp_show(vty, abgp, afi, safi, @@ -14167,7 +14205,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, if (community) bgp_show_community( vty, abgp, community, - exact_match, afi, safi, + match_p, afi, safi, show_flags); else bgp_show(vty, abgp, afi, safi, @@ -15437,15 +15475,15 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, json_net = json_object_new_object(); - struct bgp_path_info bpi; + struct bgp_path_info pathi; struct bgp_dest buildit = *dest; struct bgp_dest *pass_in; if (route_filtered || ret == RMAP_DENY) { - bpi.attr = &attr; - bpi.peer = peer; - buildit.info = &bpi; + pathi.attr = &attr; + pathi.peer = peer; + buildit.info = &pathi; pass_in = &buildit; } else @@ -16709,8 +16747,6 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, return CMD_WARNING; } - match.family = afi2family(afi); - if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN)) { for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 5c10a865d1..af8c111043 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -88,7 +88,6 @@ enum bgp_show_adj_route_type { #define BGP_NLRI_PARSE_ERROR_EVPN_TYPE4_SIZE -9 #define BGP_NLRI_PARSE_ERROR_EVPN_TYPE5_SIZE -10 #define BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED -11 -#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT -12 #define BGP_NLRI_PARSE_ERROR_FLOWSPEC_BAD_FORMAT -13 #define BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY -14 #define BGP_NLRI_PARSE_ERROR_EVPN_TYPE1_SIZE -15 diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index c7c8f157ca..15ad921ad0 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2615,6 +2615,9 @@ route_set_aspath_exclude(void *rule, const struct prefix *dummy, void *object) path->attr->aspath = aspath_filter_exclude_acl(new_path, ase->exclude_aspath_acl); + else + aspath_free(new_path); + return RMAP_OKAY; } diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c index 5f5274c5e1..cf189a6aaf 100644 --- a/bgpd/bgp_routemap_nb_config.c +++ b/bgpd/bgp_routemap_nb_config.c @@ -1355,7 +1355,7 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish( { struct routemap_hook_context *rhc; const char *value; - bool exact_match = false; + bool match_p = false; bool any = false; char *argstr; const char *condition; @@ -1367,13 +1367,13 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish( value = yang_dnode_get_string(args->dnode, "comm-list-name"); if (yang_dnode_exists(args->dnode, "comm-list-name-exact-match")) - exact_match = yang_dnode_get_bool( + match_p = yang_dnode_get_bool( args->dnode, "./comm-list-name-exact-match"); if (yang_dnode_exists(args->dnode, "comm-list-name-any")) any = yang_dnode_get_bool(args->dnode, "comm-list-name-any"); - if (exact_match) { + if (match_p) { argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, strlen(value) + strlen("exact-match") + 2); diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 04a709b350..aefb58094b 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -529,7 +529,10 @@ static struct rtr_mgr_group *get_groups(struct list *cache_list) inline bool is_synchronized(struct rpki_vrf *rpki_vrf) { - return rpki_vrf->rtr_is_synced; + if (is_running(rpki_vrf)) + return rpki_vrf->rtr_is_synced; + else + return false; } inline bool is_running(struct rpki_vrf *rpki_vrf) diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 04e6a83552..d880c7b399 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -967,10 +967,10 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg) if (ctx->uj) { json_peers = json_object_new_array(); SUBGRP_FOREACH_PEER (subgrp, paf) { - json_object *peer = + json_object *jpeer = json_object_new_string( paf->peer->host); - json_object_array_add(json_peers, peer); + json_object_array_add(json_peers, jpeer); } json_object_object_add(json_subgrp, "peers", json_peers); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 66a2fe7997..1df8b4ffe2 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11080,7 +11080,6 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, return CMD_WARNING; } - match.family = afi2family(afi); rib = bgp->rib[afi][safi]; if (safi == SAFI_MPLS_VPN) { @@ -11504,7 +11503,7 @@ DEFPY (show_bgp_vrfs, json_vrfs = json_object_new_object(); for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) { - const char *name; + const char *bname; /* Skip Views. */ if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) @@ -11523,18 +11522,18 @@ DEFPY (show_bgp_vrfs, json_vrf = json_object_new_object(); if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) { - name = VRF_DEFAULT_NAME; + bname = VRF_DEFAULT_NAME; type = "DFLT"; } else { - name = bgp->name; + bname = bgp->name; type = "VRF"; } - show_bgp_vrfs_detail_common(vty, bgp, json_vrf, name, type, + show_bgp_vrfs_detail_common(vty, bgp, json_vrf, bname, type, false); if (uj) - json_object_object_add(json_vrfs, name, json_vrf); + json_object_object_add(json_vrfs, bname, json_vrf); } if (uj) { @@ -14089,9 +14088,14 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, ? "Advertise" : "Withdraw"); - /* Receive prefix count */ - vty_out(vty, " %u accepted prefixes\n", - p->pcount[afi][safi]); + /* Receive and sent prefix count, if available */ + paf = peer_af_find(p, afi, safi); + if (paf && PAF_SUBGRP(paf)) + vty_out(vty, " %u accepted, %u sent prefixes\n", + p->pcount[afi][safi], PAF_SUBGRP(paf)->scount); + else + vty_out(vty, " %u accepted prefixes\n", + p->pcount[afi][safi]); /* maximum-prefix-out */ if (CHECK_FLAG(p->af_flags[afi][safi], diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index b953da57ce..6a874d53b6 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -56,8 +56,8 @@ #include "bgpd/bgp_lcommunity.h" /* All information about zebra. */ -struct zclient *zclient = NULL; -struct zclient *zclient_sync; +struct zclient *bgp_zclient = NULL; +struct zclient *bgp_zclient_sync; static bool bgp_zebra_label_manager_connect(void); /* hook to indicate vrf status change for SNMP */ @@ -69,7 +69,7 @@ DEFINE_MTYPE_STATIC(BGPD, BGP_IF_INFO, "BGP interface context"); /* Can we install into zebra? */ static inline bool bgp_install_info_to_zebra(struct bgp *bgp) { - if (zclient->sock <= 0) + if (bgp_zclient->sock <= 0) return false; if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { @@ -1010,15 +1010,15 @@ struct bgp *bgp_tm_bgp; static void bgp_zebra_tm_connect(struct event *t) { - struct zclient *zclient; + struct zclient *zc; int delay = 10, ret = 0; - zclient = EVENT_ARG(t); - if (bgp_tm_status_connected && zclient->sock > 0) + zc = EVENT_ARG(t); + if (bgp_tm_status_connected && zc->sock > 0) delay = 60; else { bgp_tm_status_connected = false; - ret = tm_table_manager_connect(zclient); + ret = tm_table_manager_connect(zc); } if (ret < 0) { zlog_err("Error connecting to table manager!"); @@ -1031,7 +1031,7 @@ static void bgp_zebra_tm_connect(struct event *t) } bgp_tm_status_connected = true; if (!bgp_tm_chunk_obtained) { - if (bgp_zebra_get_table_range(zclient, bgp_tm_chunk_size, + if (bgp_zebra_get_table_range(zc, bgp_tm_chunk_size, &bgp_tm_min, &bgp_tm_max) >= 0) { bgp_tm_chunk_obtained = true; @@ -1040,7 +1040,7 @@ static void bgp_zebra_tm_connect(struct event *t) } } } - event_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay, + event_add_timer(bm->master, bgp_zebra_tm_connect, zc, delay, &bgp_tm_thread_connect); } @@ -1071,7 +1071,7 @@ void bgp_zebra_init_tm_connect(struct bgp *bgp) bgp_tm_min = bgp_tm_max = 0; bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK; bgp_tm_bgp = bgp; - event_add_timer(bm->master, bgp_zebra_tm_connect, zclient_sync, delay, + event_add_timer(bm->master, bgp_zebra_tm_connect, bgp_zclient_sync, delay, &bgp_tm_thread_connect); } @@ -1650,7 +1650,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, __func__, p, (allow_recursion ? "" : "NOT ")); } - return zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + return zclient_route_send(ZEBRA_ROUTE_ADD, bgp_zclient, &api); } @@ -1747,7 +1747,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, zlog_debug("Tx route delete %s (table id %u) %pFX", bgp->name_pretty, api.tableid, &api.prefix); - return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + return zclient_route_send(ZEBRA_ROUTE_DELETE, bgp_zclient, &api); } /* @@ -2071,19 +2071,19 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, .table_id = instance, .vrf_id = bgp->vrf_id, }; - if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) != - NULL) + if (redist_lookup_table_direct(&bgp_zclient->mi_redist[afi][type], + &table) != NULL) return CMD_WARNING; - redist_add_table_direct(&zclient->mi_redist[afi][type], &table); + redist_add_table_direct(&bgp_zclient->mi_redist[afi][type], &table); } else { - if (redist_check_instance(&zclient->mi_redist[afi][type], instance)) + if (redist_check_instance(&bgp_zclient->mi_redist[afi][type], instance)) return CMD_WARNING; - redist_add_instance(&zclient->mi_redist[afi][type], instance); + redist_add_instance(&bgp_zclient->mi_redist[afi][type], instance); } } else { - if (vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id)) + if (vrf_bitmap_check(&bgp_zclient->redist[afi][type], bgp->vrf_id)) return CMD_WARNING; #ifdef ENABLE_BGP_VNC @@ -2093,7 +2093,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, } #endif - vrf_bitmap_set(&zclient->redist[afi][type], bgp->vrf_id); + vrf_bitmap_set(&bgp_zclient->redist[afi][type], bgp->vrf_id); } /* @@ -2111,7 +2111,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, instance); /* Send distribute add message to zebra. */ - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, bgp_zclient, afi, type, instance, bgp->vrf_id); return CMD_SUCCESS; @@ -2132,9 +2132,9 @@ int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type, instance); /* Send distribute add message to zebra. */ - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, bgp_zclient, afi, type, instance, bgp->vrf_id); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, bgp_zclient, afi, type, instance, bgp->vrf_id); return 0; @@ -2214,21 +2214,21 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type, .table_id = instance, .vrf_id = bgp->vrf_id, }; - if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) == + if (redist_lookup_table_direct(&bgp_zclient->mi_redist[afi][type], &table) == NULL) return CMD_WARNING; - redist_del_table_direct(&zclient->mi_redist[afi][type], &table); + redist_del_table_direct(&bgp_zclient->mi_redist[afi][type], &table); } else { - if (!redist_check_instance(&zclient->mi_redist[afi][type], instance)) + if (!redist_check_instance(&bgp_zclient->mi_redist[afi][type], instance)) return CMD_WARNING; - redist_del_instance(&zclient->mi_redist[afi][type], instance); + redist_del_instance(&bgp_zclient->mi_redist[afi][type], instance); } } else { - if (!vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id)) + if (!vrf_bitmap_check(&bgp_zclient->redist[afi][type], bgp->vrf_id)) return CMD_WARNING; - vrf_bitmap_unset(&zclient->redist[afi][type], bgp->vrf_id); + vrf_bitmap_unset(&bgp_zclient->redist[afi][type], bgp->vrf_id); } if (bgp_install_info_to_zebra(bgp)) { @@ -2237,7 +2237,7 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type, zlog_debug("Tx redistribute del %s afi %d %s %d", bgp->name_pretty, afi, zebra_route_string(type), instance); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, bgp_zclient, afi, type, instance, bgp->vrf_id); } @@ -2325,7 +2325,7 @@ void bgp_redistribute_redo(struct bgp *bgp) void bgp_zclient_reset(void) { - zclient_reset(zclient); + zclient_reset(bgp_zclient); } /* Register this instance with Zebra. Invoked upon connect (for @@ -2335,14 +2335,14 @@ void bgp_zclient_reset(void) void bgp_zebra_instance_register(struct bgp *bgp) { /* Don't try to register if we're not connected to Zebra */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return; if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Registering %s", bgp->name_pretty); /* Register for router-id, interfaces, redistributed routes. */ - zclient_send_reg_requests(zclient, bgp->vrf_id); + zclient_send_reg_requests(bgp_zclient, bgp->vrf_id); /* For EVPN instance, register to learn about VNIs, if appropriate. */ if (bgp->advertise_all_vni) @@ -2364,7 +2364,7 @@ void bgp_zebra_instance_register(struct bgp *bgp) void bgp_zebra_instance_deregister(struct bgp *bgp) { /* Don't try to deregister if we're not connected to Zebra */ - if (zclient->sock < 0) + if (bgp_zclient->sock < 0) return; if (BGP_DEBUG(zebra, ZEBRA)) @@ -2375,7 +2375,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp) bgp_zebra_advertise_all_vni(bgp, 0); /* Deregister for router-id, interfaces, redistributed routes. */ - zclient_send_dereg_requests(zclient, bgp->vrf_id); + zclient_send_dereg_requests(bgp_zclient, bgp->vrf_id); } void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer) @@ -2386,7 +2386,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer) return; /* Don't try to initiate if we're not connected to Zebra */ - if (zclient->sock < 0) + if (bgp_zclient->sock < 0) return; if (BGP_DEBUG(zebra, ZEBRA)) @@ -2398,7 +2398,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer) * If we don't have an ifp pointer, call function to find the * ifps for a numbered enhe peer to turn RAs on. */ - peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id, + peer->ifp ? zclient_send_interface_radv_req(bgp_zclient, bgp->vrf_id, peer->ifp, 1, ra_interval) : bgp_nht_reg_enhe_cap_intfs(peer); } @@ -2406,7 +2406,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer) void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer) { /* Don't try to terminate if we're not connected to Zebra */ - if (zclient->sock < 0) + if (bgp_zclient->sock < 0) return; if (BGP_DEBUG(zebra, ZEBRA)) @@ -2418,7 +2418,7 @@ void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer) * If we don't have an ifp pointer, call function to find the * ifps for a numbered enhe peer to turn RAs off. */ - peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id, + peer->ifp ? zclient_send_interface_radv_req(bgp_zclient, bgp->vrf_id, peer->ifp, 0, 0) : bgp_nht_dereg_enhe_cap_intfs(peer); } @@ -2428,7 +2428,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni) struct stream *s = NULL; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -2440,7 +2440,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni) return 0; } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_ADVERTISE_SUBNET, bgp->vrf_id); @@ -2448,7 +2448,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni) stream_put3(s, vni); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni) @@ -2456,14 +2456,14 @@ int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni) struct stream *s = NULL; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) return 0; - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_ADVERTISE_SVI_MACIP, bgp->vrf_id); @@ -2471,7 +2471,7 @@ int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni) stream_putl(s, vni); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni) @@ -2479,7 +2479,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni) struct stream *s = NULL; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -2491,7 +2491,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni) return 0; } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id); @@ -2499,7 +2499,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni) stream_putl(s, vni); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } int bgp_zebra_vxlan_flood_control(struct bgp *bgp, @@ -2508,7 +2508,7 @@ int bgp_zebra_vxlan_flood_control(struct bgp *bgp, struct stream *s; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -2520,14 +2520,14 @@ int bgp_zebra_vxlan_flood_control(struct bgp *bgp, return 0; } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_VXLAN_FLOOD_CONTROL, bgp->vrf_id); stream_putc(s, flood_ctrl); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise) @@ -2535,14 +2535,14 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise) struct stream *s; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) return 0; - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id); @@ -2553,7 +2553,7 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise) stream_putc(s, bgp->vxlan_flood_ctrl); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } int bgp_zebra_dup_addr_detection(struct bgp *bgp) @@ -2561,7 +2561,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp) struct stream *s; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!bgp_zclient || bgp_zclient->sock < 0) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -2578,7 +2578,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp) "enable" : "disable", bgp->evpn_info->dad_freeze_time); - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_DUPLICATE_ADDR_DETECTION, bgp->vrf_id); @@ -2589,7 +2589,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp) stream_putl(s, bgp->evpn_info->dad_freeze_time); stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return zclient_send_message(bgp_zclient); } static int rule_notify_owner(ZAPI_CALLBACK_ARGS) @@ -3965,7 +3965,7 @@ void bgp_if_init(void) static bool bgp_zebra_label_manager_ready(void) { - return (zclient_sync->sock > 0); + return (bgp_zclient_sync->sock > 0); } static void bgp_start_label_manager(struct event *start) @@ -3979,29 +3979,29 @@ static void bgp_start_label_manager(struct event *start) static bool bgp_zebra_label_manager_connect(void) { /* Connect to label manager. */ - if (zclient_socket_connect(zclient_sync) < 0) { + if (zclient_socket_connect(bgp_zclient_sync) < 0) { zlog_warn("%s: failed connecting synchronous zclient!", __func__); return false; } /* make socket non-blocking */ - set_nonblocking(zclient_sync->sock); + set_nonblocking(bgp_zclient_sync->sock); /* Send hello to notify zebra this is a synchronous client */ - if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) { + if (zclient_send_hello(bgp_zclient_sync) == ZCLIENT_SEND_FAILURE) { zlog_warn("%s: failed sending hello for synchronous zclient!", __func__); - close(zclient_sync->sock); - zclient_sync->sock = -1; + close(bgp_zclient_sync->sock); + bgp_zclient_sync->sock = -1; return false; } /* Connect to label manager */ - if (lm_label_manager_connect(zclient_sync, 0) != 0) { + if (lm_label_manager_connect(bgp_zclient_sync, 0) != 0) { zlog_warn("%s: failed connecting to label manager!", __func__); - if (zclient_sync->sock > 0) { - close(zclient_sync->sock); - zclient_sync->sock = -1; + if (bgp_zclient_sync->sock > 0) { + close(bgp_zclient_sync->sock); + bgp_zclient_sync->sock = -1; } return false; } @@ -4030,22 +4030,22 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance) hook_register_prio(if_unreal, 0, bgp_ifp_destroy); /* Set default values. */ - zclient = zclient_new(master, &zclient_options_default, bgp_handlers, - array_size(bgp_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); - zclient->zebra_buffer_write_ready = bgp_zebra_buffer_write_ready; - zclient->zebra_connected = bgp_zebra_connected; - zclient->zebra_capabilities = bgp_zebra_capabilities; - zclient->nexthop_update = bgp_nexthop_update; - zclient->instance = instance; + bgp_zclient = zclient_new(master, &zclient_options_default, bgp_handlers, + array_size(bgp_handlers)); + zclient_init(bgp_zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); + bgp_zclient->zebra_buffer_write_ready = bgp_zebra_buffer_write_ready; + bgp_zclient->zebra_connected = bgp_zebra_connected; + bgp_zclient->zebra_capabilities = bgp_zebra_capabilities; + bgp_zclient->nexthop_update = bgp_nexthop_update; + bgp_zclient->instance = instance; /* Initialize special zclient for synchronous message exchanges. */ - zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0); - zclient_sync->sock = -1; - zclient_sync->redist_default = ZEBRA_ROUTE_BGP; - zclient_sync->instance = instance; - zclient_sync->session_id = 1; - zclient_sync->privs = &bgpd_privs; + bgp_zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0); + bgp_zclient_sync->sock = -1; + bgp_zclient_sync->redist_default = ZEBRA_ROUTE_BGP; + bgp_zclient_sync->instance = instance; + bgp_zclient_sync->session_id = 1; + bgp_zclient_sync->privs = &bgpd_privs; if (!bgp_zebra_label_manager_ready()) event_add_timer(master, bgp_start_label_manager, NULL, 1, @@ -4054,17 +4054,17 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance) void bgp_zebra_destroy(void) { - if (zclient == NULL) + if (bgp_zclient == NULL) return; - zclient_stop(zclient); - zclient_free(zclient); - zclient = NULL; + zclient_stop(bgp_zclient); + zclient_free(bgp_zclient); + bgp_zclient = NULL; - if (zclient_sync == NULL) + if (bgp_zclient_sync == NULL) return; - zclient_stop(zclient_sync); - zclient_free(zclient_sync); - zclient_sync = NULL; + zclient_stop(bgp_zclient_sync); + zclient_free(bgp_zclient_sync); + bgp_zclient_sync = NULL; } int bgp_zebra_num_connects(void) @@ -4090,7 +4090,7 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra, zlog_debug("%s: table %d fwmark %d %d", __func__, pbra->table_id, pbra->fwmark, install); } - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -4099,7 +4099,7 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra, bgp_encode_pbr_rule_action(s, pbra, pbr); - if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) + if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE) && install) { if (!pbr) pbra->install_in_progress = true; @@ -4118,7 +4118,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install) zlog_debug("%s: name %s type %d %d, ID %u", __func__, pbrim->ipset_name, pbrim->type, install, pbrim->unique); - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -4131,7 +4131,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install) bgp_encode_pbr_ipset_match(s, pbrim); stream_putw_at(s, 0, stream_get_endp(s)); - if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install) + if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE) && install) pbrim->install_in_progress = true; } @@ -4146,7 +4146,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime, zlog_debug("%s: name %s %d %d, ID %u", __func__, pbrime->backpointer->ipset_name, pbrime->unique, install, pbrime->unique); - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -4159,7 +4159,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime, bgp_encode_pbr_ipset_entry_match(s, pbrime); stream_putw_at(s, 0, stream_get_endp(s)); - if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install) + if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE) && install) pbrime->install_in_progress = true; } @@ -4218,7 +4218,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba, zlog_debug("%s: name %s type %d mark %d %d, ID %u", __func__, pbm->ipset_name, pbm->type, pba->fwmark, install, pbm->unique2); - s = zclient->obuf; + s = bgp_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -4232,7 +4232,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba, if (nb_interface) bgp_encode_pbr_interface_list(pba->bgp, s, pbm->family); stream_putw_at(s, 0, stream_get_endp(s)); - ret = zclient_send_message(zclient); + ret = zclient_send_message(bgp_zclient); if (install) { if (ret != ZCLIENT_SEND_FAILURE) pba->refcnt++; @@ -4319,7 +4319,7 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh, } zclient_route_send(announce ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); + bgp_zclient, &api); } /* Send capabilities to RIB */ @@ -4332,7 +4332,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) zlog_debug("%s: Sending %sable for %s", __func__, disable ? "dis" : "en", bgp->name_pretty); - if (zclient == NULL) { + if (bgp_zclient == NULL) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s zclient invalid", __func__, bgp->name_pretty); @@ -4340,7 +4340,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) } /* Check if the client is connected */ - if ((zclient->sock < 0) || (zclient->t_connect)) { + if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s client not connected", __func__, bgp->name_pretty); @@ -4365,7 +4365,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) api.vrf_id = bgp->vrf_id; } - if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api) + if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api) == ZCLIENT_SEND_FAILURE) { zlog_err("%s(%d): Error sending GR capability to zebra", bgp->name_pretty, bgp->vrf_id); @@ -4394,7 +4394,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi, bgp->name_pretty, afi, safi, zserv_gr_client_cap_string(type)); - if (zclient == NULL) { + if (bgp_zclient == NULL) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s zclient == NULL, invalid", __func__, bgp->name_pretty); @@ -4402,7 +4402,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi, } /* Check if the client is connected */ - if ((zclient->sock < 0) || (zclient->t_connect)) { + if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s client not connected", __func__, bgp->name_pretty); @@ -4414,7 +4414,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi, api.vrf_id = bgp->vrf_id; api.cap = type; - if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api) + if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api) == ZCLIENT_SEND_FAILURE) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s error sending capability", __func__, @@ -4434,14 +4434,14 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp) zlog_debug("%s: %s Timer Update to %u", __func__, bgp->name_pretty, bgp->rib_stale_time); - if (zclient == NULL) { + if (bgp_zclient == NULL) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("zclient invalid"); return BGP_GR_FAILURE; } /* Check if the client is connected */ - if ((zclient->sock < 0) || (zclient->t_connect)) { + if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s client not connected", __func__, bgp->name_pretty); @@ -4452,7 +4452,7 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp) api.cap = ZEBRA_CLIENT_RIB_STALE_TIME; api.stale_removal_time = bgp->rib_stale_time; api.vrf_id = bgp->vrf_id; - if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api) + if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api) == ZCLIENT_SEND_FAILURE) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: %s error sending capability", __func__, @@ -4465,12 +4465,12 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp) int bgp_zebra_srv6_manager_get_locator_chunk(const char *name) { - return srv6_manager_get_locator_chunk(zclient, name); + return srv6_manager_get_locator_chunk(bgp_zclient, name); } int bgp_zebra_srv6_manager_release_locator_chunk(const char *name) { - return srv6_manager_release_locator_chunk(zclient, name); + return srv6_manager_release_locator_chunk(bgp_zclient, name); } /** @@ -4488,7 +4488,7 @@ int bgp_zebra_srv6_manager_get_locator(const char *name) * Send the Get Locator request to the SRv6 Manager and return the * result */ - return srv6_manager_get_locator(zclient, name); + return srv6_manager_get_locator(bgp_zclient, name); } /** @@ -4520,7 +4520,7 @@ bool bgp_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx, * Send the Get SRv6 SID request to the SRv6 Manager and check the * result */ - ret = srv6_manager_get_sid(zclient, ctx, sid_value, locator_name, + ret = srv6_manager_get_sid(bgp_zclient, ctx, sid_value, locator_name, sid_func); if (ret < 0) { zlog_warn("%s: error getting SRv6 SID!", __func__); @@ -4549,7 +4549,7 @@ void bgp_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx) * Send the Release SRv6 SID request to the SRv6 Manager and check the * result */ - ret = srv6_manager_release_sid(zclient, ctx); + ret = srv6_manager_release_sid(bgp_zclient, ctx); if (ret < 0) { zlog_warn("%s: error releasing SRv6 SID!", __func__); return; @@ -4592,7 +4592,7 @@ void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label, znh->labels[i] = out_labels[i]; } /* vrf_id is DEFAULT_VRF */ - zebra_send_mpls_labels(zclient, cmd, &zl); + zebra_send_mpls_labels(bgp_zclient, cmd, &zl); } bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size, @@ -4601,10 +4601,10 @@ bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size, int ret; uint32_t start, end; - if (!zclient_sync || !bgp_zebra_label_manager_ready()) + if (!bgp_zclient_sync || !bgp_zebra_label_manager_ready()) return false; - ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start, + ret = lm_get_label_chunk(bgp_zclient_sync, 0, base, chunk_size, &start, &end); if (ret < 0) { zlog_warn("%s: error getting label range!", __func__); @@ -4633,10 +4633,10 @@ void bgp_zebra_release_label_range(uint32_t start, uint32_t end) { int ret; - if (!zclient_sync || !bgp_zebra_label_manager_ready()) + if (!bgp_zclient_sync || !bgp_zebra_label_manager_ready()) return; - ret = lm_release_label_chunk(zclient_sync, start, end); + ret = lm_release_label_chunk(bgp_zclient_sync, start, end); if (ret < 0) zlog_warn("%s: error releasing label range!", __func__); } diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 7e9d57cb85..fa5b9fc91b 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -8,6 +8,9 @@ #include "vxlan.h" +/* The global zapi session handle */ +extern struct zclient *bgp_zclient; + /* Macro to update bgp_original based on bpg_path_info */ #define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp) \ ((_mpinfo->extra && _mpinfo->extra->vrfleak && \ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 77150786ce..83f8057736 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -121,7 +121,7 @@ unsigned int bgp_suppress_fib_count; static void bgp_if_finish(struct bgp *bgp); static void peer_drop_dynamic_neighbor(struct peer *peer); -extern struct zclient *zclient; +extern struct zclient *bgp_zclient; /* handle main socket creation or deletion */ static int bgp_check_main_socket(bool create, struct bgp *bgp) @@ -447,9 +447,9 @@ void bm_wait_for_fib_set(bool set) send_msg = true; } - if (send_msg && zclient) + if (send_msg && bgp_zclient) zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, - zclient, set); + bgp_zclient, set); /* * If this is configed at a time when peers are already set @@ -507,9 +507,9 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Sending ZEBRA_ROUTE_NOTIFY_REQUEST"); - if (zclient) + if (bgp_zclient) zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, - zclient, set); + bgp_zclient, set); } /* @@ -3589,7 +3589,8 @@ peer_init: bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = MPLS_LABEL_NONE; - bgp->vpn_policy[afi].import_vrf = list_new(); + if (!bgp->vpn_policy[afi].import_vrf) + bgp->vpn_policy[afi].import_vrf = list_new(); bgp->vpn_policy[afi].import_vrf->del = bgp_vrf_string_name_delete; if (!hidden) { @@ -3607,7 +3608,7 @@ peer_init: bgp_mplsvpn_nh_label_bind_cache_init(&bgp->mplsvpn_nh_label_bind); - if (name) + if (name && !bgp->name) bgp->name = XSTRDUP(MTYPE_BGP_NAME, name); event_add_timer(bm->master, bgp_startup_timer_expire, bgp, @@ -3928,16 +3929,16 @@ static void bgp_zclient_set_redist(afi_t afi, int type, unsigned short instance, { if (instance) { if (set) - redist_add_instance(&zclient->mi_redist[afi][type], + redist_add_instance(&bgp_zclient->mi_redist[afi][type], instance); else - redist_del_instance(&zclient->mi_redist[afi][type], + redist_del_instance(&bgp_zclient->mi_redist[afi][type], instance); } else { if (set) - vrf_bitmap_set(&zclient->redist[afi][type], vrf_id); + vrf_bitmap_set(&bgp_zclient->redist[afi][type], vrf_id); else - vrf_bitmap_unset(&zclient->redist[afi][type], vrf_id); + vrf_bitmap_unset(&bgp_zclient->redist[afi][type], vrf_id); } } @@ -4264,7 +4265,7 @@ int bgp_delete(struct bgp *bgp) } } - if (bgp->peer_self && !IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (bgp->peer_self && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)) { peer_delete(bgp->peer_self); bgp->peer_self = NULL; } @@ -4281,7 +4282,7 @@ int bgp_delete(struct bgp *bgp) /* TODO - Other memory may need to be freed - e.g., NHT */ #ifdef ENABLE_BGP_VNC - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) rfapi_delete(bgp); #endif @@ -4289,8 +4290,7 @@ int bgp_delete(struct bgp *bgp) FOREACH_AFI_SAFI (afi, safi) { struct bgp_aggregate *aggregate = NULL; - for (struct bgp_dest *dest = - bgp_table_top(bgp->aggregate[afi][safi]); + for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest; dest = bgp_route_next(dest)) { aggregate = bgp_dest_get_bgp_aggregate_info(dest); if (aggregate == NULL) @@ -4332,7 +4332,7 @@ int bgp_delete(struct bgp *bgp) bgp_zebra_instance_deregister(bgp); } - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) { /* Remove visibility via the master list - * there may however still be routes to be processed * still referencing the struct bgp. @@ -4344,7 +4344,7 @@ int bgp_delete(struct bgp *bgp) vrf = bgp_vrf_lookup_by_instance_type(bgp); bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false); - if (vrf && !IS_BGP_INSTANCE_HIDDEN(bgp)) + if (vrf && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)) bgp_vrf_unlink(bgp, vrf); /* Update EVPN VRF pointer */ @@ -4355,7 +4355,7 @@ int bgp_delete(struct bgp *bgp) bgp_set_evpn(bgp_get_default()); } - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) { if (bgp->process_queue) work_queue_free_and_null(&bgp->process_queue); bgp_unlock(bgp); /* initial reference */ @@ -4789,7 +4789,7 @@ enum bgp_peer_active peer_active(struct peer_connection *connection) return BGP_PEER_CONNECTION_UNSPECIFIED; if (peer->bfd_config) { - if (bfd_session_is_down(peer->bfd_config->session)) + if (peer_established(connection) && bfd_session_is_down(peer->bfd_config->session)) return BGP_PEER_BFD_DOWN; } @@ -8683,6 +8683,10 @@ void bgp_master_init(struct event_loop *master, const int buffer_size, bm = &bgp_master; + /* Initialize the peer connection FIFO list */ + peer_connection_fifo_init(&bm->connection_fifo); + pthread_mutex_init(&bm->peer_connection_mtx, NULL); + zebra_announce_init(&bm->zebra_announce_head); zebra_l2_vni_init(&bm->zebra_l2_vni_head); zebra_l3_vni_init(&bm->zebra_l3_vni_head); @@ -8968,6 +8972,9 @@ void bgp_terminate(void) EVENT_OFF(bm->t_bgp_zebra_l3_vni); bgp_mac_finish(); +#ifdef ENABLE_BGP_VNC + rfapi_terminate(); +#endif } struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 4b5833151f..bbc45994b4 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -107,6 +107,9 @@ enum bgp_af_index { extern struct frr_pthread *bgp_pth_io; extern struct frr_pthread *bgp_pth_ka; +/* FIFO list for peer connections */ +PREDECL_LIST(peer_connection_fifo); + /* BGP master for system wide configurations and variables. */ struct bgp_master { /* BGP instance list. */ @@ -121,6 +124,11 @@ struct bgp_master { /* BGP port number. */ uint16_t port; + /* FIFO list head for peer connections */ + struct peer_connection_fifo_head connection_fifo; + struct event *e_process_packet; + pthread_mutex_t peer_connection_mtx; + /* Listener addresses */ struct list *addresses; @@ -1378,7 +1386,6 @@ struct peer_connection { struct event *t_pmax_restart; struct event *t_routeadv; - struct event *t_process_packet; struct event *t_stop_with_notify; @@ -1394,7 +1401,14 @@ struct peer_connection { union sockunion *su_local; /* Sockunion of local address. */ union sockunion *su_remote; /* Sockunion of remote address. */ + + /* For FIFO list */ + struct peer_connection_fifo_item fifo_item; }; + +/* Declare the FIFO list implementation */ +DECLARE_LIST(peer_connection_fifo, struct peer_connection, fifo_item); + const char *bgp_peer_get_connection_direction(struct peer_connection *connection); extern struct peer_connection *bgp_peer_connection_new(struct peer *peer); extern void bgp_peer_connection_free(struct peer_connection **connection); diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 241cbcb359..dfe52a9cba 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -946,8 +946,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ } } - if (attrhash_cmp(bpi->attr, new_attr) - && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) { + if (!CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && attrhash_cmp(bpi->attr, new_attr)) { bgp_attr_unintern(&new_attr); bgp_dest_unlock_node(bn); @@ -3546,6 +3545,8 @@ DEFUN (skiplist_debug_cli, void rfapi_init(void) { + rfapi_rib_init(); + rfapi_import_init(); bgp_rfapi_cfg_init(); vnc_debug_init(); @@ -3576,6 +3577,12 @@ void rfapi_init(void) rfapi_vty_init(); } +void rfapi_terminate(void) +{ + rfapi_import_terminate(); + rfapi_rib_terminate(); +} + #ifdef DEBUG_RFAPI static void rfapi_print_exported(struct bgp *bgp) { diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h index 32ea0a2821..b89df74b9a 100644 --- a/bgpd/rfapi/rfapi_backend.h +++ b/bgpd/rfapi/rfapi_backend.h @@ -14,6 +14,7 @@ #include "bgpd/bgp_nexthop.h" extern void rfapi_init(void); +extern void rfapi_terminate(void); extern void vnc_zebra_init(struct event_loop *master); extern void vnc_zebra_destroy(void); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index d9f63700f0..0d5a18afbb 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -53,13 +53,22 @@ #undef DEBUG_BI_SEARCH /* + * Hash to keep track of outstanding timers so we can force them to + * expire at shutdown time, thus freeing their allocated memory. + */ +PREDECL_HASH(rwcb); + +/* * Allocated for each withdraw timer instance; freed when the timer * expires or is canceled */ struct rfapi_withdraw { + struct rwcb_item rwcbi; + struct rfapi_import_table *import_table; struct agg_node *node; struct bgp_path_info *info; + void (*timer_service_func)(struct event *t); /* for cleanup */ safi_t safi; /* used only for bulk operations */ /* * For import table node reference count checking (i.e., debugging). @@ -72,6 +81,19 @@ struct rfapi_withdraw { int lockoffset; }; +static int _rwcb_cmp(const struct rfapi_withdraw *w1, const struct rfapi_withdraw *w2) +{ + return (w1 != w2); +} + +static uint32_t _rwcb_hash(const struct rfapi_withdraw *w) +{ + return (uintptr_t)w & 0xffffffff; +} + +DECLARE_HASH(rwcb, struct rfapi_withdraw, rwcbi, _rwcb_cmp, _rwcb_hash); +static struct rwcb_head _rwcbhash; + /* * DEBUG FUNCTION * Count remote routes and compare with actively-maintained values. @@ -826,6 +848,7 @@ static void rfapiBgpInfoChainFree(struct bgp_path_info *bpi) struct rfapi_withdraw *wcb = EVENT_ARG(bpi->extra->vnc->vnc.import.timer); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc.import.timer); } @@ -1329,11 +1352,11 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, bgp_attr_extcom_tunnel_type(bpi->attr, &tun_type); if (tun_type == BGP_ENCAP_TYPE_MPLS) { - struct prefix p; + struct prefix pfx; /* MPLS carries UN address in next hop */ - rfapiNexthop2Prefix(bpi->attr, &p); - if (p.family != AF_UNSPEC) { - rfapiQprefix2Raddr(&p, &new->un_address); + rfapiNexthop2Prefix(bpi->attr, &pfx); + if (pfx.family != AF_UNSPEC) { + rfapiQprefix2Raddr(&pfx, &new->un_address); have_vnc_tunnel_un = 1; } } @@ -1750,7 +1773,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( * Add non-withdrawn routes from less-specific prefix */ if (parent) { - const struct prefix *p = agg_node_get_prefix(parent); + p = agg_node_get_prefix(parent); rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, p) : NULL; rfapiQprefix2Rprefix(p, &rprefix); @@ -2349,6 +2372,7 @@ static void rfapiWithdrawTimerVPN(struct event *t) /* This callback is responsible for the withdraw object's memory */ if (early_exit) { + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); return; } @@ -2462,6 +2486,7 @@ done: RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); agg_unlock_node(wcb->node); /* decr ref count */ + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); } @@ -2705,6 +2730,7 @@ static void rfapiWithdrawTimerEncap(struct event *t) done: RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1); agg_unlock_node(wcb->node); /* decr ref count */ + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); skiplist_free(vpn_node_sl); } @@ -2754,6 +2780,8 @@ rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table, wcb->node = rn; wcb->info = bpi; wcb->import_table = import_table; + wcb->timer_service_func = timer_service_func; + rwcb_add(&_rwcbhash, wcb); bgp_attr_intern(bpi->attr); if (VNC_DEBUG(VERBOSE)) { @@ -2819,6 +2847,7 @@ static void rfapiExpireEncapNow(struct rfapi_import_table *it, wcb->info = bpi; wcb->node = rn; wcb->import_table = it; + rwcb_add(&_rwcbhash, wcb); memset(&t, 0, sizeof(t)); t.arg = wcb; rfapiWithdrawTimerEncap(&t); /* frees wcb */ @@ -3057,6 +3086,7 @@ static void rfapiBgpInfoFilteredImportEncap( struct rfapi_withdraw *wcb = EVENT_ARG( bpi->extra->vnc->vnc.import.timer); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc.import .timer); @@ -3083,6 +3113,7 @@ static void rfapiBgpInfoFilteredImportEncap( wcb->info = bpi; wcb->node = rn; wcb->import_table = import_table; + rwcb_add(&_rwcbhash, wcb); memset(&t, 0, sizeof(t)); t.arg = wcb; rfapiWithdrawTimerEncap( @@ -3149,6 +3180,7 @@ static void rfapiBgpInfoFilteredImportEncap( struct rfapi_withdraw *wcb = EVENT_ARG(bpi->extra->vnc->vnc.import.timer); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc.import.timer); } @@ -3192,7 +3224,7 @@ static void rfapiBgpInfoFilteredImportEncap( __func__, rn); #endif for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) { - const struct prefix *p; + const struct prefix *pfx; /* * For each referenced bpi/route, copy the ENCAP route's @@ -3220,9 +3252,9 @@ static void rfapiBgpInfoFilteredImportEncap( * list * per prefix. */ - p = agg_node_get_prefix(m->node); + pfx = agg_node_get_prefix(m->node); referenced_vpn_prefix = - agg_node_get(referenced_vpn_table, p); + agg_node_get(referenced_vpn_table, pfx); assert(referenced_vpn_prefix); for (mnext = referenced_vpn_prefix->info; mnext; mnext = mnext->next) { @@ -3293,6 +3325,7 @@ static void rfapiExpireVpnNow(struct rfapi_import_table *it, wcb->node = rn; wcb->import_table = it; wcb->lockoffset = lockoffset; + rwcb_add(&_rwcbhash, wcb); memset(&t, 0, sizeof(t)); t.arg = wcb; rfapiWithdrawTimerVPN(&t); /* frees wcb */ @@ -3510,6 +3543,7 @@ void rfapiBgpInfoFilteredImportVPN( struct rfapi_withdraw *wcb = EVENT_ARG( bpi->extra->vnc->vnc.import.timer); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc.import .timer); @@ -3729,6 +3763,7 @@ void rfapiBgpInfoFilteredImportVPN( struct rfapi_withdraw *wcb = EVENT_ARG(bpi->extra->vnc->vnc.import.timer); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc.import.timer); } @@ -4480,6 +4515,7 @@ static void rfapiDeleteRemotePrefixesIt( RFAPI_UPDATE_ITABLE_COUNT( bpi, wcb->import_table, afi, 1); + rwcb_del(&_rwcbhash, wcb); XFREE(MTYPE_RFAPI_WITHDRAW, wcb); EVENT_OFF(bpi->extra->vnc->vnc @@ -4804,3 +4840,33 @@ uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime) else return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; } + +void rfapi_import_init(void) +{ + rwcb_init(&_rwcbhash); +} + +void rfapi_import_terminate(void) +{ + struct rfapi_withdraw *wcb; + struct bgp_path_info *bpi; + void (*timer_service_func)(struct event *t); + struct event t; + + vnc_zlog_debug_verbose("%s: cleaning up %zu pending timers", __func__, + rwcb_count(&_rwcbhash)); + + /* + * clean up memory allocations stored in pending timers + */ + while ((wcb = rwcb_pop(&_rwcbhash))) { + bpi = wcb->info; + assert(wcb == EVENT_ARG(bpi->extra->vnc->vnc.import.timer)); + EVENT_OFF(bpi->extra->vnc->vnc.import.timer); + + timer_service_func = wcb->timer_service_func; + memset(&t, 0, sizeof(t)); + t.arg = wcb; + (*timer_service_func)(&t); /* frees wcb */ + } +} diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h index 1a37e1c2db..536b8f0525 100644 --- a/bgpd/rfapi/rfapi_import.h +++ b/bgpd/rfapi/rfapi_import.h @@ -225,4 +225,7 @@ extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */ --------------------------------------------*/ extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime); +extern void rfapi_import_init(void); +extern void rfapi_import_terminate(void); + #endif /* QUAGGA_HGP_RFAPI_IMPORT_H */ diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 53e416b2ee..fe6ad50f92 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -18,6 +18,7 @@ #include "lib/log.h" #include "lib/skiplist.h" #include "lib/workqueue.h" +#include <typesafe.h> #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" @@ -40,12 +41,11 @@ #define DEBUG_PENDING_DELETE_ROUTE 0 #define DEBUG_NHL 0 #define DEBUG_RIB_SL_RD 0 -#define DEBUG_CLEANUP 0 +#define DEBUG_CLEANUP 0 /* forward decl */ #if DEBUG_NHL -static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, - struct skiplist *sl); +static void rfapiRibShowRibSl(void *stream, const struct prefix *pfx, struct skiplist *sl); #endif /* @@ -234,9 +234,45 @@ void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p) } +/* + * Hash to keep track of outstanding timers so we can force them to + * expire at shutdown time, thus freeing their allocated memory. + */ +PREDECL_HASH(rrtcb); + +/* + * Timer control block for recently-deleted and expired routes + */ +struct rfapi_rib_tcb { + struct rrtcb_item tcbi; + + struct rfapi_descriptor *rfd; + struct skiplist *sl; + struct rfapi_info *ri; + struct agg_node *rn; + int flags; +#define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001 +}; + +static int _rrtcb_cmp(const struct rfapi_rib_tcb *t1, const struct rfapi_rib_tcb *t2) +{ + return (t1 != t2); +} + +static uint32_t _rrtcb_hash(const struct rfapi_rib_tcb *t) +{ + return (uintptr_t)t & 0xffffffff; +} + +DECLARE_HASH(rrtcb, struct rfapi_rib_tcb, tcbi, _rrtcb_cmp, _rrtcb_hash); +static struct rrtcb_head _rrtcbhash; + static void rfapi_info_free(struct rfapi_info *goner) { if (goner) { +#if DEBUG_CLEANUP + zlog_debug("%s: ri %p, timer %p", __func__, goner, goner->timer); +#endif if (goner->tea_options) { rfapiFreeBgpTeaOptionChain(goner->tea_options); goner->tea_options = NULL; @@ -253,32 +289,19 @@ static void rfapi_info_free(struct rfapi_info *goner) struct rfapi_rib_tcb *tcb; tcb = EVENT_ARG(goner->timer); +#if DEBUG_CLEANUP + zlog_debug("%s: ri %p, tcb %p", __func__, goner, tcb); +#endif EVENT_OFF(goner->timer); + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); } XFREE(MTYPE_RFAPI_INFO, goner); } } -/* - * Timer control block for recently-deleted and expired routes - */ -struct rfapi_rib_tcb { - struct rfapi_descriptor *rfd; - struct skiplist *sl; - struct rfapi_info *ri; - struct agg_node *rn; - int flags; -#define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001 -}; - -/* - * remove route from rib - */ -static void rfapiRibExpireTimer(struct event *t) +static void _rfapiRibExpireTimer(struct rfapi_rib_tcb *tcb) { - struct rfapi_rib_tcb *tcb = EVENT_ARG(t); - RFAPI_RIB_CHECK_COUNTS(1, 0); /* @@ -309,11 +332,22 @@ static void rfapiRibExpireTimer(struct event *t) agg_unlock_node(tcb->rn); } + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); RFAPI_RIB_CHECK_COUNTS(1, 0); } +/* + * remove route from rib + */ +static void rfapiRibExpireTimer(struct event *t) +{ + struct rfapi_rib_tcb *tcb = EVENT_ARG(t); + + _rfapiRibExpireTimer(tcb); +} + static void rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri, struct agg_node *rn, /* route node attached to */ @@ -349,6 +383,8 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd, event_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime, &ri->timer); + + rrtcb_add(&_rrtcbhash, tcb); } extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ @@ -519,6 +555,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) tcb = EVENT_ARG( ri->timer); EVENT_OFF(ri->timer); + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); } @@ -852,11 +889,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, int rib_node_started_nonempty = 0; int sendingsomeroutes = 0; const struct prefix *p; -#if DEBUG_PROCESS_PENDING_NODE - unsigned int count_rib_initial = 0; - unsigned int count_pend_vn_initial = 0; - unsigned int count_pend_cost_initial = 0; -#endif assert(pn); p = agg_node_get_prefix(pn); @@ -885,19 +917,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, slPendPt = (struct skiplist *)(pn->aggregate); lPendCost = (struct list *)(pn->info); -#if DEBUG_PROCESS_PENDING_NODE - /* debugging */ - if (slRibPt) - count_rib_initial = skiplist_count(slRibPt); - - if (slPendPt) - count_pend_vn_initial = skiplist_count(slPendPt); - - if (lPendCost && lPendCost != (struct list *)1) - count_pend_cost_initial = lPendCost->count; -#endif - - /* * Handle special case: delete all routes at prefix */ @@ -920,6 +939,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, tcb = EVENT_ARG(ri->timer); EVENT_OFF(ri->timer); + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); } @@ -1005,6 +1025,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, tcb = EVENT_ARG(ori->timer); EVENT_OFF(ori->timer); + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); } @@ -1017,6 +1038,11 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, #endif } else { +#if DEBUG_PROCESS_PENDING_NODE + vnc_zlog_debug_verbose("%s: slRibPt ri %p matched in pending list", + __func__, ori); +#endif + /* * Found in pending list. If same lifetime, * cost, options, @@ -1040,14 +1066,10 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, rfapi_info_free( ri); /* grr... */ } - } #if DEBUG_PROCESS_PENDING_NODE - vnc_zlog_debug_verbose( - "%s: slRibPt ri %p matched in pending list, %s", - __func__, ori, - (same ? "same info" - : "different info")); + vnc_zlog_debug_verbose("%s: same info", __func__); #endif + } } } /* @@ -1339,6 +1361,7 @@ callback: tcb = EVENT_ARG(ri->timer); EVENT_OFF(ri->timer); + rrtcb_del(&_rrtcbhash, tcb); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); } RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); @@ -2285,8 +2308,7 @@ static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty, /* * This one is for debugging (set stream to NULL to send output to log) */ -static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, - struct skiplist *sl) +static void rfapiRibShowRibSl(void *stream, const struct prefix *pfx, struct skiplist *sl) { int (*fp)(void *, const char *, ...); struct vty *vty; @@ -2426,3 +2448,25 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, fp(out, "\n"); } } + +void rfapi_rib_init(void) +{ + rrtcb_init(&_rrtcbhash); +} + +void rfapi_rib_terminate(void) +{ + struct rfapi_rib_tcb *tcb; + + vnc_zlog_debug_verbose("%s: cleaning up %zu pending timers", __func__, + rrtcb_count(&_rrtcbhash)); + + /* + * Clean up memory allocations stored in pending timers + */ + while ((tcb = rrtcb_pop(&_rrtcbhash))) { + assert(tcb == EVENT_ARG(tcb->ri->timer)); + EVENT_OFF(tcb->ri->timer); + _rfapiRibExpireTimer(tcb); /* deletes hash entry, frees tcb */ + } +} diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h index 5fa838bd34..3e34f26fcd 100644 --- a/bgpd/rfapi/rfapi_rib.h +++ b/bgpd/rfapi/rfapi_rib.h @@ -138,4 +138,7 @@ extern int rfapi_rib_key_cmp(const void *k1, const void *k2); extern void rfapiAdbFree(struct rfapi_adb *adb); +extern void rfapi_rib_init(void); +extern void rfapi_rib_terminate(void); + #endif /* QUAGGA_HGP_RFAPI_RIB_H */ diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index e688638ed7..612caed0cf 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -338,13 +338,12 @@ static int process_unicast_route(struct bgp *bgp, /* in */ hattr = *attr; if (rmap) { - struct bgp_path_info info; + struct bgp_path_info pinfo = {}; route_map_result_t ret; - memset(&info, 0, sizeof(info)); - info.peer = peer; - info.attr = &hattr; - ret = route_map_apply(rmap, prefix, &info); + pinfo.peer = peer; + pinfo.attr = &hattr; + ret = route_map_apply(rmap, prefix, &pinfo); if (ret == RMAP_DENYMATCH) { bgp_attr_flush(&hattr); vnc_zlog_debug_verbose( @@ -768,13 +767,12 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, hattr = *attr; if (rmap) { - struct bgp_path_info info; + struct bgp_path_info pinfo = {}; route_map_result_t ret; - memset(&info, 0, sizeof(info)); - info.peer = peer; - info.attr = &hattr; - ret = route_map_apply(rmap, prefix, &info); + pinfo.peer = peer; + pinfo.attr = &hattr; + ret = route_map_apply(rmap, prefix, &pinfo); if (ret == RMAP_DENYMATCH) { bgp_attr_flush(&hattr); vnc_zlog_debug_verbose( diff --git a/configure.ac b/configure.ac index f9f3286563..00a5620529 100644 --- a/configure.ac +++ b/configure.ac @@ -467,6 +467,7 @@ AC_C_FLAG([-Wbad-function-cast]) AC_C_FLAG([-Wwrite-strings]) AC_C_FLAG([-Wundef]) AC_C_FLAG([-Wimplicit-fallthrough]) +AC_C_FLAG([-Wshadow]) if test "$enable_gcc_ultra_verbose" = "yes" ; then AC_C_FLAG([-Wcast-qual]) AC_C_FLAG([-Wmissing-noreturn]) @@ -474,7 +475,6 @@ if test "$enable_gcc_ultra_verbose" = "yes" ; then AC_C_FLAG([-Wunreachable-code]) AC_C_FLAG([-Wpacked]) AC_C_FLAG([-Wpadded]) - AC_C_FLAG([-Wshadow]) else AC_C_FLAG([-Wno-unused-result]) fi diff --git a/doc/developer/mgmtd-dev.rst b/doc/developer/mgmtd-dev.rst index f113d1b521..554f767c39 100644 --- a/doc/developer/mgmtd-dev.rst +++ b/doc/developer/mgmtd-dev.rst @@ -429,3 +429,8 @@ The client and server sides of oper-state query .. figure:: ../figures/cli-oper-state.svg :align: center + +Config datastore cleanup for non-implict commits (i.e., file reads currently) + +.. figure:: ../figures/datastores.svg + :align: center diff --git a/doc/figures/datastores.drawio b/doc/figures/datastores.drawio new file mode 100644 index 0000000000..5e17087196 --- /dev/null +++ b/doc/figures/datastores.drawio @@ -0,0 +1,291 @@ +<mxfile host="Electron" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2"> + <diagram name="Page-1" id="i24xzCYeKZV1rkTH0XTW"> + <mxGraphModel dx="1667" dy="1191" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0"> + <root> + <mxCell id="0" /> + <mxCell id="1" parent="0" /> + <mxCell id="U9ftda_CDvz5WDsUi4ve-36" value="nb_candidate_commit_apply()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;verticalAlign=top;" vertex="1" parent="1"> + <mxGeometry x="890" y="670" width="180" height="136.87" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-29" value="<i><font style="font-size: 16px;">Daemon CLI Parsing (lib/vty.c)</font></i>" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#dae8fc;strokeColor=default;fillStyle=solid;strokeWidth=1;perimeterSpacing=0;dashPattern=1 2;gradientColor=none;gradientDirection=radial;glass=0;shadow=0;opacity=50;verticalAlign=bottom;spacingBottom=30;" parent="1" vertex="1"> + <mxGeometry x="50" y="220" width="660" height="170" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-7" value="<div style="font-size: 12px;">mgmtd</div><div style="font-size: 12px;">(new config path)</div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#dae8fc;strokeColor=#6c8ebf;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="1" vertex="1"> + <mxGeometry x="230" y="40" width="490" height="270" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-13" value="<div><font>vty_shared_</font></div><div><font>candidate_config</font></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> + <mxGeometry x="136.25" y="70" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-14" value="<div>running_config</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"> + <mxGeometry x="260" y="70" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-18" value="" style="group;shadow=0;" parent="1" vertex="1" connectable="0"> + <mxGeometry x="80" y="60" width="270" height="210" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-19" value="<div style="font-size: 12px;">B daemon&nbsp;<span style="background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));">(old direct vty)</span></div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#fad9d5;strokeColor=#ae4132;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="QL32OzfzetEIIOdSfswY-18" vertex="1"> + <mxGeometry x="-10" width="270" height="190" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-20" value="<div><font>vty_shared_</font></div><div><font>candidate_config</font></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="QL32OzfzetEIIOdSfswY-18" vertex="1"> + <mxGeometry x="20" y="30" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-21" value="<div>running_config</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="QL32OzfzetEIIOdSfswY-18" vertex="1"> + <mxGeometry x="150" y="30" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-23" value="<div style="font-size: 12px;">A daemon (old direct vty)</div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#fad9d5;strokeColor=#ae4132;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="QL32OzfzetEIIOdSfswY-18" vertex="1"> + <mxGeometry x="-40" y="20" width="270" height="190" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-25" value="<div>running_config</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"> + <mxGeometry x="200" y="110" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="4hLhriEXD62TuEoW85Ij-1" edge="1"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="648.75" y="160" as="sourcePoint" /> + <mxPoint x="487.5" y="585" as="targetPoint" /> + <Array as="points"> + <mxPoint x="790" y="160" /> + <mxPoint x="790" y="530" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-8" value="<div><font>vty_mgmt_</font></div><div><font>candidate_config</font></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> + <mxGeometry x="551.25" y="70" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-26" value="mm-&gt;running" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> + <mxGeometry x="370" y="230" width="120" height="60" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="QL32OzfzetEIIOdSfswY-27" target="QL32OzfzetEIIOdSfswY-26"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-27" value="mm-&gt;candidate" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> + <mxGeometry x="540" y="230" width="120" height="60" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-1" value="vty_config_entry()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" parent="1" vertex="1"> + <mxGeometry x="315" y="500" width="130" height="60" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="QL32OzfzetEIIOdSfswY-24" target="4hLhriEXD62TuEoW85Ij-1" edge="1"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="120" y="260" as="sourcePoint" /> + <mxPoint x="320" y="600" as="targetPoint" /> + <Array as="points"> + <mxPoint x="120" y="530" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-24" value="<div><font>vty_shared_</font></div><div><font>candidate_config</font></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> + <mxGeometry x="70" y="110" width="97.5" height="130" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-4" target="4hLhriEXD62TuEoW85Ij-7" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-4" value="CLI: config_exclusive()<div>(northbound_cli.c)</div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1"> + <mxGeometry x="910" y="40" width="140" height="50" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-5" value="CLI: config_private()<div>(northbound_cli.c)</div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1"> + <mxGeometry x="760" y="45" width="140" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-6" value="vty_config_entry()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" parent="1" vertex="1"> + <mxGeometry x="860" y="230" width="120" height="60" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-7" target="4hLhriEXD62TuEoW85Ij-6" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-7" value="<div>private_config</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> + <mxGeometry x="871.25" y="130" width="97.5" height="70" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-5" edge="1"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="910" y="130" as="targetPoint" /> + <Array as="points"> + <mxPoint x="850" y="110" /> + <mxPoint x="911" y="110" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="4hLhriEXD62TuEoW85Ij-1" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-20" value="2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="4hLhriEXD62TuEoW85Ij-1" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;strokeWidth=2;" edge="1" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="U9ftda_CDvz5WDsUi4ve-15"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-17" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-16"> + <mxGeometry x="0.0305" y="2" relative="1" as="geometry"> + <mxPoint as="offset" /> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-19" value="1: (mgmtd only)" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-16"> + <mxGeometry x="0.0074" y="1" relative="1" as="geometry"> + <mxPoint as="offset" /> + </mxGeometry> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-11" value="CLI: config_terminal()<div>(command.c)</div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1"> + <mxGeometry x="315" y="420" width="130" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-29" target="4hLhriEXD62TuEoW85Ij-11" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-27" value="<div style="font-size: 12px;"><br></div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=12;fillColor=#dae8fc;strokeColor=#6c8ebf;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1;container=0;" parent="1" vertex="1"> + <mxGeometry x="50" y="600" width="550" height="190" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-18" value="vty_read_config()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> + <mxGeometry x="260" y="670" width="130" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-21" value="vty_apply_config()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> + <mxGeometry x="260" y="730" width="130" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-22" value="<b><i>"copy FILE to rrunning"</i></b>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> + <mxGeometry x="63.75" y="730" width="150" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-23" value="<b><i>vtysh_main.c: main()</i></b>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> + <mxGeometry x="430" y="730" width="150" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-18" target="4hLhriEXD62TuEoW85Ij-16" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-21" target="4hLhriEXD62TuEoW85Ij-18" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-22" target="4hLhriEXD62TuEoW85Ij-21" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-23" target="4hLhriEXD62TuEoW85Ij-21" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-34" value="VTYSH" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=default;fontColor=#333333;opacity=50;dashed=1;dashPattern=8 8;" parent="1" vertex="1"> + <mxGeometry x="500" y="610" width="90" height="30" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-12" value="" style="curved=0;endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;dashed=1;startFill=0;" edge="1" parent="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="215" y="400" as="sourcePoint" /> + <mxPoint x="380" y="400" as="targetPoint" /> + <Array as="points"> + <mxPoint x="215" y="370" /> + <mxPoint x="380" y="370" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-16" value="vty_read_file()<div><b><i>"conf term file-lock"</i></b></div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> + <mxGeometry x="260" y="610" width="130" height="40" as="geometry" /> + </mxCell> + <mxCell id="4hLhriEXD62TuEoW85Ij-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;jumpStyle=line;exitX=0.5;exitY=0;exitDx=0;exitDy=0;shadow=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-16" edge="1"> + <mxGeometry relative="1" as="geometry"> + <Array as="points"> + <mxPoint x="325" y="580" /> + <mxPoint x="215" y="580" /> + </Array> + <mxPoint x="395" y="670" as="sourcePoint" /> + <mxPoint x="215" y="390" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;endArrow=oval;endFill=1;" parent="1" source="QL32OzfzetEIIOdSfswY-14" target="QL32OzfzetEIIOdSfswY-26" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="QL32OzfzetEIIOdSfswY-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=oval;startFill=1;startArrow=classic;endFill=1;" parent="1" source="QL32OzfzetEIIOdSfswY-8" target="QL32OzfzetEIIOdSfswY-27" edge="1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-15" value="<div>lock mm-&gt;candidate</div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"> + <mxGeometry x="580" y="420" width="130" height="40" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-20" value="If we don't lock for non-mgmtd then<div>multiple vtysh conf t are allowed!</div>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontStyle=3;fontColor=#FF0000;" vertex="1" parent="1"> + <mxGeometry x="425" y="463" width="210" height="40" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-21" target="U9ftda_CDvz5WDsUi4ve-23"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-21" value="vty_config_node_exit()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" vertex="1" parent="1"> + <mxGeometry x="830" y="340" width="180" height="45" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-23" target="U9ftda_CDvz5WDsUi4ve-25"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-29" value="pendign == true" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-26"> + <mxGeometry x="-0.0182" y="-3" relative="1" as="geometry"> + <mxPoint as="offset" /> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-23" value="<div>&nbsp; &nbsp;nb_cli_pending_commit_check()</div><div><br></div>" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1"> + <mxGeometry x="830" y="420" width="180" height="35" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" target="U9ftda_CDvz5WDsUi4ve-27"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="920" y="570" as="sourcePoint" /> + <Array as="points"> + <mxPoint x="920" y="569" /> + <mxPoint x="920" y="596" /> + <mxPoint x="910" y="596" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-27" target="U9ftda_CDvz5WDsUi4ve-36"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="920" y="574.37" as="sourcePoint" /> + <mxPoint x="1000" y="610.0000000000001" as="targetPoint" /> + <Array as="points"> + <mxPoint x="960" y="635" /> + <mxPoint x="980" y="635" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-47" value="success" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-35"> + <mxGeometry x="-0.275" y="1" relative="1" as="geometry"> + <mxPoint as="offset" /> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-25" target="U9ftda_CDvz5WDsUi4ve-27"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-25" value="nb_cli_classic_commit()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1"> + <mxGeometry x="830" y="500" width="180" height="37.5" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-27" target="U9ftda_CDvz5WDsUi4ve-30"> + <mxGeometry relative="1" as="geometry"> + <Array as="points"> + <mxPoint x="880" y="635" /> + <mxPoint x="781" y="635" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-32" value="fail" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-31"> + <mxGeometry x="-0.055" y="-3" relative="1" as="geometry"> + <mxPoint as="offset" /> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-27" value="nb_candidate_commit_prepare()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1"> + <mxGeometry x="830" y="566.25" width="180" height="33.75" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-30" value="" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1"> + <mxGeometry x="691.25" y="670.01" width="180" height="99.99" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-38" target="U9ftda_CDvz5WDsUi4ve-39"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-38" value="<div>running</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"> + <mxGeometry x="706.25" y="685" width="50" height="70" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-39" value="<div>private or</div><div>candidate</div><div><br></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"> + <mxGeometry x="796.25" y="685" width="60" height="70" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-42" value="<div>running</div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"> + <mxGeometry x="990" y="715" width="50" height="70" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-41" value="<div>private or</div><div>candidate</div><div><br></div>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"> + <mxGeometry x="900" y="715" width="65" height="70" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-44" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-36" target="U9ftda_CDvz5WDsUi4ve-36"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-41" target="U9ftda_CDvz5WDsUi4ve-42"> + <mxGeometry relative="1" as="geometry"> + <mxPoint x="960" y="705" as="sourcePoint" /> + <mxPoint x="990" y="705" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="U9ftda_CDvz5WDsUi4ve-52" value="<b><font style="font-size: 15px;">Config Datastore Non-Implicit Commit Cleanup</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1"> + <mxGeometry x="400" y="10" width="360" height="30" as="geometry" /> + </mxCell> + </root> + </mxGraphModel> + </diagram> +</mxfile> diff --git a/doc/figures/datastores.svg b/doc/figures/datastores.svg new file mode 100644 index 0000000000..41f612fc68 --- /dev/null +++ b/doc/figures/datastores.svg @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1035px" height="806px" viewBox="-0.5 -0.5 1035 806"><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="U9ftda_CDvz5WDsUi4ve-36"><g><rect x="854" y="660" width="180" height="136.87" rx="20.53" ry="20.53" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 667px; margin-left: 855px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_candidate_commit_apply()</div></div></div></foreignObject><text x="944" y="679" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">nb_candidate_commit_apply()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-29"><g><rect x="14" y="210" width="660" height="170" rx="25.5" ry="25.5" fill-opacity="0.5" fill="#dae8fc" stroke="#000000" stroke-opacity="0.5" stroke-dasharray="1 2" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 658px; height: 1px; padding-top: 347px; margin-left: 15px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><i><font style="font-size: 16px;">Daemon CLI Parsing (lib/vty.c)</font></i></div></div></div></foreignObject><text x="344" y="347" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">Daemon CLI Parsing (lib/vty.c)</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-7"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="194" y="30" width="490" height="270" rx="64.8" ry="64.8" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: rgb(108, 142, 191);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 488px; height: 1px; padding-top: 37px; margin-left: 195px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Verdana"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">mgmtd</div><div style="font-size: 12px;">(new config path)</div></div></div></div></foreignObject><text x="439" y="49" fill="light-dark(#000000, #ffffff)" font-family=""Verdana"" font-size="12px" text-anchor="middle" font-weight="bold">mgmtd...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-13"><g><path d="M 100.25 75 C 100.25 66.72 122.08 60 149 60 C 161.93 60 174.33 61.58 183.47 64.39 C 192.61 67.21 197.75 71.02 197.75 75 L 197.75 175 C 197.75 183.28 175.92 190 149 190 C 122.08 190 100.25 183.28 100.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 197.75 75 C 197.75 83.28 175.92 90 149 90 C 122.08 90 100.25 83.28 100.25 75" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 101px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="149" y="141" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-14"><g><path d="M 224 75 C 224 66.72 245.83 60 272.75 60 C 285.68 60 298.08 61.58 307.22 64.39 C 316.36 67.21 321.5 71.02 321.5 75 L 321.5 175 C 321.5 183.28 299.67 190 272.75 190 C 245.83 190 224 183.28 224 175 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 321.5 75 C 321.5 83.28 299.67 90 272.75 90 C 245.83 90 224 83.28 224 75" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="273" y="141" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-18"><g/><g data-cell-id="QL32OzfzetEIIOdSfswY-19"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="34" y="50" width="270" height="190" rx="45.6" ry="45.6" fill="#fad9d5" stroke="#ae4132" pointer-events="all" style="fill: rgb(250, 217, 213); stroke: rgb(174, 65, 50);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 57px; margin-left: 35px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Verdana"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">B daemon <span style="background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));">(old direct vty)</span></div></div></div></div></foreignObject><text x="169" y="69" fill="light-dark(#000000, #ffffff)" font-family=""Verdana"" font-size="12px" text-anchor="middle" font-weight="bold">B daemon (old direct vty)</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-20"><g><path d="M 64 95 C 64 86.72 85.83 80 112.75 80 C 125.68 80 138.08 81.58 147.22 84.39 C 156.36 87.21 161.5 91.02 161.5 95 L 161.5 195 C 161.5 203.28 139.67 210 112.75 210 C 85.83 210 64 203.28 64 195 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 161.5 95 C 161.5 103.28 139.67 110 112.75 110 C 85.83 110 64 103.28 64 95" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 158px; margin-left: 65px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="113" y="161" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-21"><g><path d="M 194 95 C 194 86.72 215.83 80 242.75 80 C 255.68 80 268.08 81.58 277.22 84.39 C 286.36 87.21 291.5 91.02 291.5 95 L 291.5 195 C 291.5 203.28 269.67 210 242.75 210 C 215.83 210 194 203.28 194 195 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 291.5 95 C 291.5 103.28 269.67 110 242.75 110 C 215.83 110 194 103.28 194 95" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 158px; margin-left: 195px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="243" y="161" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-23"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="4" y="70" width="270" height="190" rx="45.6" ry="45.6" fill="#fad9d5" stroke="#ae4132" pointer-events="all" style="fill: rgb(250, 217, 213); stroke: rgb(174, 65, 50);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 77px; margin-left: 5px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Verdana"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">A daemon (old direct vty)</div></div></div></div></foreignObject><text x="139" y="89" fill="light-dark(#000000, #ffffff)" font-family=""Verdana"" font-size="12px" text-anchor="middle" font-weight="bold">A daemon (old direct vty)</text></switch></g></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-25"><g><path d="M 164 115 C 164 106.72 185.83 100 212.75 100 C 225.68 100 238.08 101.58 247.22 104.39 C 256.36 107.21 261.5 111.02 261.5 115 L 261.5 215 C 261.5 223.28 239.67 230 212.75 230 C 185.83 230 164 223.28 164 215 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 261.5 115 C 261.5 123.28 239.67 130 212.75 130 C 185.83 130 164 123.28 164 115" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 178px; margin-left: 165px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="213" y="181" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-2"><g><path d="M 612.75 150 L 754 150 L 754 520 L 415.37 520" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 410.12 520 L 417.12 516.5 L 415.37 520 L 417.12 523.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-8"><g><path d="M 515.25 75 C 515.25 66.72 537.08 60 564 60 C 576.93 60 589.33 61.58 598.47 64.39 C 607.61 67.21 612.75 71.02 612.75 75 L 612.75 175 C 612.75 183.28 590.92 190 564 190 C 537.08 190 515.25 183.28 515.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 612.75 75 C 612.75 83.28 590.92 90 564 90 C 537.08 90 515.25 83.28 515.25 75" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 516px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_mgmt_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="564" y="141" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_mgmt_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-26"><g><rect x="334" y="220" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 335px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">mm->running</div></div></div></foreignObject><text x="394" y="254" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">mm->running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-14"><g><path d="M 504 250 L 460.37 250" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 455.12 250 L 462.12 246.5 L 460.37 250 L 462.12 253.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-27"><g><rect x="504" y="220" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 505px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">mm->candidate</div></div></div></foreignObject><text x="564" y="254" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">mm->candidate</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-1"><g><rect x="279" y="490" width="130" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 520px; margin-left: 280px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_entry()</div></div></div></foreignObject><text x="344" y="524" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_config_entry()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-3"><g><path d="M 84 230 L 84 520 L 272.63 520" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 277.88 520 L 270.88 523.5 L 272.63 520 L 270.88 516.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-24"><g><path d="M 34 115 C 34 106.72 55.83 100 82.75 100 C 95.68 100 108.08 101.58 117.22 104.39 C 126.36 107.21 131.5 111.02 131.5 115 L 131.5 215 C 131.5 223.28 109.67 230 82.75 230 C 55.83 230 34 223.28 34 215 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 131.5 115 C 131.5 123.28 109.67 130 82.75 130 C 55.83 130 34 123.28 34 115" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 178px; margin-left: 35px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="83" y="181" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-8"><g><path d="M 944 80 L 944 100 L 884.1 100 L 884.1 113.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884.1 118.88 L 880.6 111.88 L 884.1 113.63 L 887.6 111.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-4"><g><rect x="874" y="30" width="140" height="50" rx="7.5" ry="7.5" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 55px; margin-left: 875px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_exclusive()<div>(northbound_cli.c)</div></div></div></div></foreignObject><text x="944" y="59" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">CLI: config_exclusive()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-5"><g><rect x="724" y="35" width="140" height="40" rx="6" ry="6" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 55px; margin-left: 725px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_private()<div>(northbound_cli.c)</div></div></div></div></foreignObject><text x="794" y="59" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">CLI: config_private()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-6"><g><rect x="824" y="220" width="120" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 825px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_entry()</div></div></div></foreignObject><text x="884" y="254" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_config_entry()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-10"><g><path d="M 884.1 190 L 884.1 210 L 884.06 213.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884.01 218.88 L 880.58 211.85 L 884.06 213.63 L 887.58 211.92 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-7"><g><path d="M 835.25 135 C 835.25 126.72 857.08 120 884 120 C 896.93 120 909.33 121.58 918.47 124.39 C 927.61 127.21 932.75 131.02 932.75 135 L 932.75 175 C 932.75 183.28 910.92 190 884 190 C 857.08 190 835.25 183.28 835.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 932.75 135 C 932.75 143.28 910.92 150 884 150 C 857.08 150 835.25 143.28 835.25 135" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 168px; margin-left: 836px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private_config</div></div></div></div></foreignObject><text x="884" y="171" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">private_config</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-9"><g><path d="M 814 75 L 814 100 L 875 100 L 874.32 113.64" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 874.06 118.88 L 870.91 111.72 L 874.32 113.64 L 877.9 112.07 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-15"><g><path d="M 344 450 L 344 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 488.88 L 340.5 481.88 L 344 483.63 L 347.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-20"><g><path d="M 344 450 L 344 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 488.88 L 340.5 481.88 L 344 483.63 L 347.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 470px; margin-left: 344px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">2</div></div></div></foreignObject><text x="344" y="473" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">2</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-16"><g><path d="M 417.24 430 L 535.76 430" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 411.24 430 L 419.24 426 L 417.24 430 L 419.24 434 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 541.76 430 L 533.76 434 L 535.76 430 L 533.76 426 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-17"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 429px; margin-left: 480px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">1</div></div></div></foreignObject><text x="480" y="432" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">1</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-19"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 430px; margin-left: 478px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">1: (mgmtd only)</div></div></div></foreignObject><text x="478" y="433" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">1: (mgmtd only)</text></switch></g></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-11"><g><rect x="279" y="410" width="130" height="40" rx="6" ry="6" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 430px; margin-left: 280px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_terminal()<div>(command.c)</div></div></div></div></foreignObject><text x="344" y="434" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">CLI: config_terminal(...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-31"><g><path d="M 344 380 L 344 400 L 344 390 L 344 403.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 408.88 L 340.5 401.88 L 344 403.63 L 347.5 401.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-27"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="14" y="590" width="550" height="190" rx="22.8" ry="22.8" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: rgb(108, 142, 191);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 548px; height: 1px; padding-top: 597px; margin-left: 15px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Verdana"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;"><br /></div></div></div></div></foreignObject><text x="289" y="609" fill="light-dark(#000000, #ffffff)" font-family=""Verdana"" font-size="12px" text-anchor="middle" font-weight="bold">
</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-18"><g><rect x="224" y="660" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 680px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_read_config()</div></div></div></foreignObject><text x="289" y="684" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_read_config()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-21"><g><rect x="224" y="720" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 740px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_apply_config()</div></div></div></foreignObject><text x="289" y="744" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_apply_config()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-22"><g><rect x="27.75" y="720" width="150" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 148px; height: 1px; padding-top: 740px; margin-left: 29px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b><i>"copy FILE to rrunning"</i></b></div></div></div></foreignObject><text x="103" y="744" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">"copy FILE to rrunning"</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-23"><g><rect x="394" y="720" width="150" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 148px; height: 1px; padding-top: 740px; margin-left: 395px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b><i>vtysh_main.c: main()</i></b></div></div></div></foreignObject><text x="469" y="744" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vtysh_main.c: main()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-19"><g><path d="M 289 660 L 289 640 L 289 660 L 289 646.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 289 641.12 L 292.5 648.12 L 289 646.37 L 285.5 648.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-26"><g><path d="M 289 720 L 289 700 L 289 720 L 289 706.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 289 701.12 L 292.5 708.12 L 289 706.37 L 285.5 708.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-25"><g><path d="M 177.75 740 L 217.63 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 222.88 740 L 215.88 743.5 L 217.63 740 L 215.88 736.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-24"><g><path d="M 394 740 L 360.37 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 355.12 740 L 362.12 736.5 L 360.37 740 L 362.12 743.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-34"><g><rect x="464" y="600" width="90" height="30" rx="4.5" ry="4.5" fill-opacity="0.5" fill="#f5f5f5" stroke="#000000" stroke-opacity="0.5" stroke-dasharray="8 8" pointer-events="all" style="fill: rgb(245, 245, 245); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 615px; margin-left: 465px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">VTYSH</div></div></div></foreignObject><text x="509" y="619" fill="#333333" font-family=""Helvetica"" font-size="12px" text-anchor="middle">VTYSH</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-12"><g><path d="M 179 390 L 179 360 L 344 360 L 344 390" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-16"><g><rect x="224" y="600" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 620px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_read_file()<div><b><i>"conf term file-lock"</i></b></div></div></div></div></foreignObject><text x="289" y="624" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_read_file()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-17"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><path d="M 289 600 L 289 570 L 179 570 L 179 523 M 176 523 L 182 523 M 182 517 L 176 517 M 179 517 L 179 517 L 179 386.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 179 381.12 L 182.5 388.12 L 179 386.37 L 175.5 388.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-28"><g><path d="M 327.87 125 L 394 125 L 394 217" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 322.62 125 L 329.62 121.5 L 327.87 125 L 329.62 128.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><ellipse cx="394" cy="220" rx="3" ry="3" fill="#000000" stroke="#000000" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-29"><g><path d="M 564.1 196.37 L 564.1 210 L 564.03 217" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 564.1 191.12 L 567.6 198.12 L 564.1 196.37 L 560.6 198.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><ellipse cx="564" cy="220" rx="3" ry="3" fill="#000000" stroke="#000000" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-15"><g><rect x="544" y="410" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 430px; margin-left: 545px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>lock mm->candidate</div></div></div></div></foreignObject><text x="609" y="434" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">lock mm->candidate</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-20"><g><rect x="389" y="453" width="210" height="40" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 473px; margin-left: 494px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #FF0000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: #FF0000; line-height: 1.2; pointer-events: all; font-weight: bold; font-style: italic; white-space: nowrap; ">If we don't lock for non-mgmtd then<div>multiple vtysh conf t are allowed!</div></div></div></div></foreignObject><text x="494" y="477" fill="#FF0000" font-family=""Helvetica"" font-size="12px" text-anchor="middle" font-weight="bold" font-style="italic">If we don't lock for non-mgmtd then...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-24"><g><path d="M 884 375 L 884 395 L 884 390 L 884 403.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 408.88 L 880.5 401.88 L 884 403.63 L 887.5 401.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-21"><g><rect x="794" y="330" width="180" height="45" rx="6.75" ry="6.75" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 353px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_node_exit()</div></div></div></foreignObject><text x="884" y="356" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">vty_config_node_exit()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-26"><g><path d="M 884 445 L 884 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 488.88 L 880.5 481.88 L 884 483.63 L 887.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-29"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 468px; margin-left: 882px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">pendign == true</div></div></div></foreignObject><text x="882" y="471" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">pendign == true</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-23"><g><rect x="794" y="410" width="180" height="35" rx="5.25" ry="5.25" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 428px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>Â Â nb_cli_pending_commit_check()</div><div><br /></div></div></div></div></foreignObject><text x="884" y="431" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">nb_cli_pending_commit_check...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-28"><g><path d="M 884 560 L 884 562.62" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 557.37 L 887.5 564.37 L 884 562.62 L 880.5 564.37 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-35"><g><path d="M 924 590 L 924 625 L 944 625 L 944 653.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 944 658.88 L 940.5 651.88 L 944 653.63 L 947.5 651.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-47"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 624px; margin-left: 926px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">success</div></div></div></foreignObject><text x="926" y="627" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">success</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-51"><g><path d="M 884 527.5 L 884 547.5 L 884 536.3 L 884 549.88" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 555.13 L 880.5 548.13 L 884 549.88 L 887.5 548.13 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-25"><g><rect x="794" y="490" width="180" height="37.5" rx="5.63" ry="5.63" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 509px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_cli_classic_commit()</div></div></div></foreignObject><text x="884" y="512" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">nb_cli_classic_commit()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-31"><g><path d="M 844 590 L 844 625 L 745 625 L 745 653.64" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 745 658.89 L 741.5 651.89 L 745 653.64 L 748.5 651.89 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-32"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 623px; margin-left: 800px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">fail</div></div></div></foreignObject><text x="800" y="626" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="11px" text-anchor="middle">fail</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-27"><g><rect x="794" y="556.25" width="180" height="33.75" rx="5.06" ry="5.06" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 573px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_candidate_commit_prepare()</div></div></div></foreignObject><text x="884" y="577" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">nb_candidate_commit_prepare()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-30"><g><rect x="655.25" y="660.01" width="180" height="99.99" rx="15" ry="15" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-40"><g><path d="M 720.25 710 L 753.88 710" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 759.13 710 L 752.13 713.5 L 753.88 710 L 752.13 706.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-38"><g><path d="M 670.25 690 C 670.25 681.72 681.44 675 695.25 675 C 701.88 675 708.24 676.58 712.93 679.39 C 717.62 682.21 720.25 686.02 720.25 690 L 720.25 730 C 720.25 738.28 709.06 745 695.25 745 C 681.44 745 670.25 738.28 670.25 730 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 720.25 690 C 720.25 698.28 709.06 705 695.25 705 C 681.44 705 670.25 698.28 670.25 690" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 48px; height: 1px; padding-top: 723px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running</div></div></div></div></foreignObject><text x="695" y="726" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-39"><g><path d="M 760.25 690 C 760.25 681.72 773.68 675 790.25 675 C 798.21 675 805.84 676.58 811.46 679.39 C 817.09 682.21 820.25 686.02 820.25 690 L 820.25 730 C 820.25 738.28 806.82 745 790.25 745 C 773.68 745 760.25 738.28 760.25 730 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 820.25 690 C 820.25 698.28 806.82 705 790.25 705 C 773.68 705 760.25 698.28 760.25 690" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 723px; margin-left: 761px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private or</div><div>candidate</div><div><br /></div></div></div></div></foreignObject><text x="790" y="726" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">private or...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-42"><g><path d="M 954 720 C 954 711.72 965.19 705 979 705 C 985.63 705 991.99 706.58 996.68 709.39 C 1001.37 712.21 1004 716.02 1004 720 L 1004 760 C 1004 768.28 992.81 775 979 775 C 965.19 775 954 768.28 954 760 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 1004 720 C 1004 728.28 992.81 735 979 735 C 965.19 735 954 728.28 954 720" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 48px; height: 1px; padding-top: 753px; margin-left: 955px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running</div></div></div></div></foreignObject><text x="979" y="756" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-41"><g><path d="M 864 720 C 864 711.72 878.55 705 896.5 705 C 905.12 705 913.39 706.58 919.48 709.39 C 925.58 712.21 929 716.02 929 720 L 929 760 C 929 768.28 914.45 775 896.5 775 C 878.55 775 864 768.28 864 760 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 929 720 C 929 728.28 914.45 735 896.5 735 C 878.55 735 864 728.28 864 720" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 63px; height: 1px; padding-top: 753px; margin-left: 865px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private or</div><div>candidate</div><div><br /></div></div></div></div></foreignObject><text x="897" y="756" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">private or...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-44"><g/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-48"><g><path d="M 929 740 L 949 740 L 934 740 L 947.63 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 952.88 740 L 945.88 743.5 L 947.63 740 L 945.88 736.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-52"><g><rect x="364" y="0" width="360" height="30" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 15px; margin-left: 544px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: nowrap; "><b><font style="font-size: 15px;">Config Datastore Non-Implicit Commit Cleanup</font></b></div></div></div></foreignObject><text x="544" y="19" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="12px" text-anchor="middle">Config Datastore Non-Implicit Commit Cleanup</text></switch></g></g></g></g></g></g></svg>
\ No newline at end of file diff --git a/doc/user/frr-reload.rst b/doc/user/frr-reload.rst index bd295dbbad..586d6103b5 100644 --- a/doc/user/frr-reload.rst +++ b/doc/user/frr-reload.rst @@ -25,6 +25,8 @@ There are several options that control the behavior of ``frr-reload``: * ``--stdout``: print output to stdout * ``--bindir BINDIR``: path to the vtysh executable * ``--confdir CONFDIR``: path to the existing daemon config files +* ``--logfile FILENAME``: file (with path) to logfile for the reload operation. + Default is ``/var/log/frr/frr-reload.log`` * ``--rundir RUNDIR``: path to a folder to be used to write the temporary files needed by the script to do its job. The script should have write access to it * ``--daemon DAEMON``: by default ``frr-reload.py`` assumes that we are using diff --git a/doc/user/static.rst b/doc/user/static.rst index c1d11cf0b0..8a32460547 100644 --- a/doc/user/static.rst +++ b/doc/user/static.rst @@ -46,8 +46,8 @@ a static prefix and gateway, with several possible forms. NETWORK is destination prefix with a valid v4 or v6 network based upon initial form of the command. - GATEWAY is the IP address to use as next-hop for the prefix. Currently, it must match - the v4 or v6 route type specified at the start of the command. + GATEWAY is the IP address to use as next-hop for the prefix. Routes of type v4 can use v4 and v6 next-hops, + v6 routes only support v6 next-hops. IFNAME is the name of the interface to use as next-hop. If only IFNAME is specified (without GATEWAY), a connected route will be created. diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index 089e18439f..c9ce018966 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -99,6 +99,8 @@ static void sigint(void) keychain_terminate(); route_map_finish(); + prefix_list_reset(); + eigrp_terminate(); exit(0); diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index 90af47e9e2..de6da954cf 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -739,7 +739,7 @@ static int eigrpd_instance_redistribute_create(struct nb_cb_create_args *args) else vrfid = VRF_DEFAULT; - if (vrf_bitmap_check(&zclient->redist[AFI_IP][proto], vrfid)) + if (vrf_bitmap_check(&eigrp_zclient->redist[AFI_IP][proto], vrfid)) return NB_ERR_INCONSISTENCY; break; case NB_EV_PREPARE: diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index e68b85d801..2ad4a25422 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -280,14 +280,14 @@ DEFPY (show_ip_eigrp_neighbors, struct eigrp *eigrp; if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) { - struct vrf *vrf; + struct vrf *tvrf; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - eigrp = eigrp_lookup(vrf->vrf_id); + RB_FOREACH (tvrf, vrf_name_head, &vrfs_by_name) { + eigrp = eigrp_lookup(tvrf->vrf_id); if (!eigrp) continue; - vty_out(vty, "VRF %s:\n", vrf->name); + vty_out(vty, "VRF %s:\n", tvrf->name); eigrp_neighbors_helper(vty, eigrp, ifname, detail); } @@ -333,7 +333,7 @@ DEFPY (clear_ip_eigrp_neighbors, eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); /* iterate over all neighbors on eigrp interface */ - frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { + frr_each_safe (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { zlog_debug( "Neighbor %pI4 (%s) is down: manually cleared", @@ -393,7 +393,7 @@ DEFPY (clear_ip_eigrp_neighbors_int, eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); /* iterate over all neighbors on eigrp interface */ - frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { + frr_each_safe (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { zlog_debug( "Neighbor %pI4 (%s) is down: manually cleared", diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 5b0c64ffd0..955a3203ac 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -46,7 +46,7 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS); static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS); /* Zebra structure to hold current status. */ -struct zclient *zclient = NULL; +struct zclient *eigrp_zclient = NULL; /* For registering threads. */ extern struct event_loop *master; @@ -98,17 +98,17 @@ static zclient_handler *const eigrp_handlers[] = { void eigrp_zebra_init(void) { - zclient = zclient_new(master, &zclient_options_default, eigrp_handlers, - array_size(eigrp_handlers)); + eigrp_zclient = zclient_new(master, &zclient_options_default, eigrp_handlers, + array_size(eigrp_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs); - zclient->zebra_connected = eigrp_zebra_connected; + zclient_init(eigrp_zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs); + eigrp_zclient->zebra_connected = eigrp_zebra_connected; } void eigrp_zebra_stop(void) { - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(eigrp_zclient); + zclient_free(eigrp_zclient); } /* Zebra route add and delete treatment. */ @@ -192,7 +192,7 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p, struct listnode *node; int count = 0; - if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) + if (!eigrp_zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; memset(&api, 0, sizeof(api)); @@ -226,14 +226,14 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p, zlog_debug("Zebra: Route add %pFX", p); } - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, eigrp_zclient, &api); } void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p) { struct zapi_route api; - if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) + if (!eigrp_zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; memset(&api, 0, sizeof(api)); @@ -241,7 +241,7 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p) api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, eigrp_zclient, &api); if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Zebra: Route del %pFX", p); @@ -252,10 +252,8 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p) static int eigrp_is_type_redistributed(int type, vrf_id_t vrf_id) { return ((DEFAULT_ROUTE_TYPE(type)) - ? vrf_bitmap_check( - &zclient->default_information[AFI_IP], vrf_id) - : vrf_bitmap_check(&zclient->redist[AFI_IP][type], - vrf_id)); + ? vrf_bitmap_check(&eigrp_zclient->default_information[AFI_IP], vrf_id) + : vrf_bitmap_check(&eigrp_zclient->redist[AFI_IP][type], vrf_id)); } int eigrp_redistribute_set(struct eigrp *eigrp, int type, @@ -280,7 +278,7 @@ int eigrp_redistribute_set(struct eigrp *eigrp, int type, eigrp->dmetric[type] = metric; - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, eigrp_zclient, AFI_IP, type, 0, eigrp->vrf_id); ++eigrp->redistribute; @@ -293,7 +291,7 @@ int eigrp_redistribute_unset(struct eigrp *eigrp, int type) if (eigrp_is_type_redistributed(type, eigrp->vrf_id)) { memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics)); - zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, eigrp_zclient, AFI_IP, type, 0, eigrp->vrf_id); --eigrp->redistribute; } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 543a54da13..bc7c60c501 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -52,7 +52,6 @@ static struct eigrp_master eigrp_master; struct eigrp_master *eigrp_om; -extern struct zclient *zclient; extern struct in_addr router_id_zebra; int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b) diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index 15d2bb54ee..28b1dc9a11 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -52,7 +52,7 @@ struct eigrp_master { }; /* Extern variables. */ -extern struct zclient *zclient; +extern struct zclient *eigrp_zclient; extern struct event_loop *master; extern struct eigrp_master *eigrp_om; extern struct zebra_privs_t eigrpd_privs; diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 078280acf5..39ed076fab 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -653,7 +653,6 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json, json_object_object_add(iface_json, "ipv6-link-local", ipv6_link_json); for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) { - char buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i], buf, sizeof(buf)); json_object_string_add(ipv6_link_json, "ipv6", @@ -666,7 +665,6 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json, ipv6_non_link_json); for (unsigned int i = 0; i < adj->global_ipv6_count; i++) { - char buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &adj->global_ipv6_addrs[i], buf, sizeof(buf)); json_object_string_add(ipv6_non_link_json, diff --git a/isisd/isis_affinitymap.c b/isisd/isis_affinitymap.c index 595091db27..a6b9cf9d4c 100644 --- a/isisd/isis_affinitymap.c +++ b/isisd/isis_affinitymap.c @@ -64,4 +64,8 @@ void isis_affinity_map_init(void) affinity_map_set_update_hook(isis_affinity_map_update); } +void isis_affinity_map_terminate(void) +{ + affinity_map_terminate(); +} #endif /* ifndef FABRICD */ diff --git a/isisd/isis_affinitymap.h b/isisd/isis_affinitymap.h index c432e99f51..525ee0467a 100644 --- a/isisd/isis_affinitymap.h +++ b/isisd/isis_affinitymap.h @@ -15,6 +15,7 @@ extern "C" { #endif extern void isis_affinity_map_init(void); +extern void isis_affinity_map_terminate(void); #ifdef __cplusplus } diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index 5e24e35210..c003b8002d 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -211,7 +211,7 @@ static int bfd_handle_circuit_add_addr(struct isis_circuit *circuit) void isis_bfd_init(struct event_loop *tm) { - bfd_protocol_integration_init(zclient, tm); + bfd_protocol_integration_init(isis_zclient, tm); hook_register(isis_adj_state_change_hook, bfd_handle_adj_state_change); hook_register(isis_adj_ip_enabled_hook, bfd_handle_adj_ip_enabled); diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index c86d929903..46611a75ec 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -2157,7 +2157,7 @@ DEFPY_YANG_NOSH (isis_srv6_node_msd, /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-segs-left */ -DEFPY (isis_srv6_node_msd_max_segs_left, +DEFPY_YANG (isis_srv6_node_msd_max_segs_left, isis_srv6_node_msd_max_segs_left_cmd, "[no] max-segs-left (0-255)$max_segs_left", NO_STR @@ -2177,7 +2177,7 @@ DEFPY (isis_srv6_node_msd_max_segs_left, /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-pop */ -DEFPY (isis_srv6_node_msd_max_end_pop, +DEFPY_YANG (isis_srv6_node_msd_max_end_pop, isis_srv6_node_msd_max_end_pop_cmd, "[no] max-end-pop (0-255)$max_end_pop", NO_STR @@ -2196,7 +2196,7 @@ DEFPY (isis_srv6_node_msd_max_end_pop, /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-h-encaps */ -DEFPY (isis_srv6_node_msd_max_h_encaps, +DEFPY_YANG (isis_srv6_node_msd_max_h_encaps, isis_srv6_node_msd_max_h_encaps_cmd, "[no] max-h-encaps (0-255)$max_h_encaps", NO_STR @@ -2216,7 +2216,7 @@ DEFPY (isis_srv6_node_msd_max_h_encaps, /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-d */ -DEFPY (isis_srv6_node_msd_max_end_d, +DEFPY_YANG (isis_srv6_node_msd_max_end_d, isis_srv6_node_msd_max_end_d_cmd, "[no] max-end-d (0-255)$max_end_d", NO_STR @@ -2262,7 +2262,7 @@ void cli_show_isis_srv6_node_msd_end(struct vty *vty, const struct lyd_node *dno /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/interface */ -DEFPY (isis_srv6_interface, +DEFPY_YANG (isis_srv6_interface, isis_srv6_interface_cmd, "[no] interface WORD$interface", NO_STR @@ -3268,7 +3268,7 @@ void cli_show_ip_isis_frr(struct vty *vty, const struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/enable */ -DEFPY(isis_lfa, isis_lfa_cmd, +DEFPY_YANG(isis_lfa, isis_lfa_cmd, "[no] isis fast-reroute lfa [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -3311,7 +3311,7 @@ DEFPY(isis_lfa, isis_lfa_cmd, * XPath: * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/exclude-interface */ -DEFPY(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd, +DEFPY_YANG(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd, "[no] isis fast-reroute lfa [level-1|level-2]$level exclude interface IFNAME$ifname", NO_STR "IS-IS routing protocol\n" @@ -3362,7 +3362,7 @@ void cli_show_frr_lfa_exclude_interface(struct vty *vty, * XPath: * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/enable */ -DEFPY(isis_remote_lfa, isis_remote_lfa_cmd, +DEFPY_YANG(isis_remote_lfa, isis_remote_lfa_cmd, "[no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -3407,7 +3407,7 @@ DEFPY(isis_remote_lfa, isis_remote_lfa_cmd, * XPath: * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/maximum-metric */ -DEFPY(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd, +DEFPY_YANG(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd, "[no] isis fast-reroute remote-lfa maximum-metric (1-16777215)$metric [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -3460,7 +3460,7 @@ void cli_show_frr_remote_lfa_max_metric(struct vty *vty, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable */ -DEFPY(isis_ti_lfa, isis_ti_lfa_cmd, +DEFPY_YANG(isis_ti_lfa, isis_ti_lfa_cmd, "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection [link-fallback$link_fallback]]", NO_STR "IS-IS routing protocol\n" @@ -3578,7 +3578,7 @@ void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/mpls/ldp-sync */ -DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync", +DEFPY_YANG(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync", MPLS_STR MPLS_LDP_SYNC_STR) { nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_CREATE, NULL); @@ -3586,7 +3586,7 @@ DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_mpls_ldp_sync, no_isis_mpls_ldp_sync_cmd, "no mpls ldp-sync", +DEFPY_YANG(no_isis_mpls_ldp_sync, no_isis_mpls_ldp_sync_cmd, "no mpls ldp-sync", NO_STR MPLS_STR NO_MPLS_LDP_SYNC_STR) { nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_DESTROY, NULL); @@ -3600,7 +3600,7 @@ void cli_show_isis_mpls_ldp_sync(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " mpls ldp-sync\n"); } -DEFPY(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd, +DEFPY_YANG(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd, "mpls ldp-sync holddown (0-10000)", MPLS_STR MPLS_LDP_SYNC_STR "Time to wait for LDP-SYNC to occur before restoring interface metric\n" @@ -3612,7 +3612,7 @@ DEFPY(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_mpls_ldp_sync_holddown, no_isis_mpls_ldp_sync_holddown_cmd, +DEFPY_YANG(no_isis_mpls_ldp_sync_holddown, no_isis_mpls_ldp_sync_holddown_cmd, "no mpls ldp-sync holddown [<(1-10000)>]", NO_STR MPLS_STR MPLS_LDP_SYNC_STR NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n") { @@ -3633,7 +3633,7 @@ void cli_show_isis_mpls_ldp_sync_holddown(struct vty *vty, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/mpls/ldp-sync */ -DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd, +DEFPY_YANG(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd, "[no] isis mpls ldp-sync", NO_STR "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR) { @@ -3663,7 +3663,7 @@ void cli_show_isis_mpls_if_ldp_sync(struct vty *vty, vty_out(vty, " isis mpls ldp-sync\n"); } -DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd, +DEFPY_YANG(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd, "isis mpls ldp-sync holddown (0-10000)", "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR "Time to wait for LDP-SYNC to occur before restoring interface metric\n" @@ -3684,7 +3684,7 @@ DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd, +DEFPY_YANG(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd, "no isis mpls ldp-sync holddown [<(1-10000)>]", NO_STR "IS-IS routing protocol\n" MPLS_STR NO_MPLS_LDP_SYNC_STR NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n") diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c index a621b4b5ed..09f46fbb58 100644 --- a/isisd/isis_flags.c +++ b/isisd/isis_flags.c @@ -26,12 +26,14 @@ long int flags_get_index(struct flags *flags) { struct listnode *node; long int index; + const void *ptr; if (flags->free_idcs == NULL || flags->free_idcs->count == 0) { index = flags->maxindex++; } else { node = listhead(flags->free_idcs); - index = (long int)listgetdata(node); + ptr = listgetdata(node); + index = (long int)ptr; listnode_delete(flags->free_idcs, (void *)index); index--; } diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c index 53676ffe36..99e9227ad5 100644 --- a/isisd/isis_ldp_sync.c +++ b/isisd/isis_ldp_sync.c @@ -40,10 +40,9 @@ #include "isisd/isis_errors.h" #include "isisd/isis_tx_queue.h" #include "isisd/isis_nb.h" +#include "isisd/isis_zebra.h" #include "isisd/isis_ldp_sync.h" -extern struct zclient *zclient; - /* * LDP-SYNC msg between IGP and LDP */ @@ -122,8 +121,8 @@ void isis_ldp_sync_state_req_msg(struct isis_circuit *circuit) request.proto = LDP_IGP_SYNC_IF_STATE_REQUEST; request.ifindex = ifp->ifindex; - zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST, - (uint8_t *)&request, sizeof(request)); + zclient_send_opaque(isis_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST, + (uint8_t *)&request, sizeof(request)); } /* diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 28b987df38..4952c689fc 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -1125,7 +1125,6 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) struct isis_router_cap *rcap; #ifndef FABRICD struct isis_router_cap_fad *rcap_fad; - struct listnode *node; struct flex_algo *fa; #endif /* ifndef FABRICD */ diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 0d9b3df39c..c36c531a17 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -109,6 +109,10 @@ static __attribute__((__noreturn__)) void terminate(int i) isis_master_terminate(); route_map_finish(); + prefix_list_reset(); +#ifndef FABRICD + isis_affinity_map_terminate(); +#endif vrf_terminate(); frr_fini(); diff --git a/isisd/isis_route.c b/isisd/isis_route.c index b907c962be..0a0c6341d6 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -240,7 +240,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p, for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) { struct isis_spf_adj *sadj = vadj->sadj; struct isis_adjacency *adj = sadj->adj; - struct isis_sr_psid_info *sr = &vadj->sr; + struct isis_sr_psid_info *vsr = &vadj->sr; struct mpls_label_stack *label_stack = vadj->label_stack; /* @@ -248,7 +248,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p, * environment. */ if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) { - isis_route_add_dummy_nexthops(rinfo, sadj->id, sr, + isis_route_add_dummy_nexthops(rinfo, sadj->id, vsr, label_stack); if (!allow_ecmp) break; @@ -260,7 +260,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) SET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr, + adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, vsr, label_stack); if (!allow_ecmp) break; diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c index 83a06b6998..24320e9ed9 100644 --- a/isisd/isis_snmp.c +++ b/isisd/isis_snmp.c @@ -692,15 +692,15 @@ static int isis_circuit_snmp_id_free(struct isis_circuit *circuit) static struct isis_circuit *isis_snmp_circuit_next(struct isis_circuit *circuit) { uint32_t start; - uint32_t off; + uint32_t offset; start = 1; if (circuit != NULL) start = circuit->snmp_id + 1; - for (off = start; off < SNMP_CIRCUITS_MAX; off++) { - circuit = snmp_circuits[off]; + for (offset = start; offset < SNMP_CIRCUITS_MAX; offset++) { + circuit = snmp_circuits[offset]; if (circuit != NULL) return circuit; @@ -759,7 +759,7 @@ static int isis_snmp_get_level_match(int is_type, int level) static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len, const oid *idx, size_t idx_len) { - size_t off; + size_t offset; size_t len; /* Oid representation: length followed by bytes */ @@ -774,11 +774,11 @@ static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len, if (idx_len < len + 1) return 0; - for (off = 0; off < len; off++) { - if (idx[off + 1] > 0xff) + for (offset = 0; offset < len; offset++) { + if (idx[offset + 1] > 0xff) return 0; - buf[off] = (uint8_t)(idx[off + 1] & 0xff); + buf[offset] = (uint8_t)(idx[offset + 1] & 0xff); } *out_len = len; @@ -789,7 +789,7 @@ static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len, static int isis_snmp_conv_next(uint8_t *buf, size_t max_len, size_t *out_len, int *try_exact, const oid *idx, size_t idx_len) { - size_t off; + size_t offset; size_t len; size_t cmp_len; @@ -809,15 +809,15 @@ static int isis_snmp_conv_next(uint8_t *buf, size_t max_len, size_t *out_len, if ((idx_len - 1) < cmp_len) cmp_len = idx_len - 1; - for (off = 0; off < cmp_len; off++) { - if (idx[off + 1] > 0xff) { - memset(buf + off, 0xff, len - off); + for (offset = 0; offset < cmp_len; offset++) { + if (idx[offset + 1] > 0xff) { + memset(buf + offset, 0xff, len - off); *out_len = len; *try_exact = 1; return 1; } - buf[off] = (uint8_t)(idx[off + 1] & 0xff); + buf[offset] = (uint8_t)(idx[offset + 1] & 0xff); } if (cmp_len < len) @@ -983,7 +983,7 @@ static int isis_snmp_circuit_lookup_exact(oid *oid_idx, size_t oid_idx_len, static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len, struct isis_circuit **ret_circuit) { - oid off; + oid offset; oid start; struct isis_circuit *circuit; @@ -996,10 +996,10 @@ static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len, start = oid_idx[0]; } - for (off = start; off < SNMP_CIRCUITS_MAX; ++off) { - circuit = snmp_circuits[off]; + for (offset = start; offset < SNMP_CIRCUITS_MAX; ++offset) { + circuit = snmp_circuits[offset]; - if (circuit != NULL && off > start) { + if (circuit != NULL && offset > start) { if (ret_circuit != NULL) *ret_circuit = circuit; @@ -1052,7 +1052,7 @@ static int isis_snmp_circuit_level_lookup_next( oid *oid_idx, size_t oid_idx_len, int check_match, struct isis_circuit **ret_circuit, int *ret_level) { - oid off; + oid offset; oid start; struct isis_circuit *circuit = NULL; int level; @@ -1066,13 +1066,13 @@ static int isis_snmp_circuit_level_lookup_next( start = oid_idx[0]; } - for (off = start; off < SNMP_CIRCUITS_MAX; off++) { - circuit = snmp_circuits[off]; + for (offset = start; offset < SNMP_CIRCUITS_MAX; offset++) { + circuit = snmp_circuits[offset]; if (circuit == NULL) continue; - if (off > start || oid_idx_len < 2) { + if (offset > start || oid_idx_len < 2) { /* Found and can use level 1 */ level = IS_LEVEL_1; break; @@ -1504,7 +1504,7 @@ static uint8_t *isis_snmp_find_man_area(struct variable *v, oid *name, struct iso_address *area_addr = NULL; oid *oid_idx; size_t oid_idx_len; - size_t off = 0; + size_t offset = 0; *write_method = NULL; @@ -1539,8 +1539,8 @@ static uint8_t *isis_snmp_find_man_area(struct variable *v, oid *name, /* Append index */ name[v->namelen] = area_addr->addr_len; - for (off = 0; off < area_addr->addr_len; off++) - name[v->namelen + 1 + off] = area_addr->area_addr[off]; + for (offset = 0; offset < area_addr->addr_len; offset++) + name[v->namelen + 1 + offset] = area_addr->area_addr[offset]; *length = v->namelen + 1 + area_addr->addr_len; } @@ -1628,7 +1628,7 @@ static uint8_t *isis_snmp_find_router(struct variable *v, oid *name, struct isis_dynhn *dyn = NULL; oid *oid_idx; size_t oid_idx_len; - size_t off = 0; + size_t offset = 0; struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); if (isis == NULL) @@ -1729,8 +1729,8 @@ static uint8_t *isis_snmp_find_router(struct variable *v, oid *name, /* Append index */ name[v->namelen] = ISIS_SYS_ID_LEN; - for (off = 0; off < ISIS_SYS_ID_LEN; off++) - name[v->namelen + 1 + off] = dyn->id[off]; + for (offset = 0; offset < ISIS_SYS_ID_LEN; offset++) + name[v->namelen + 1 + off] = dyn->id[offset]; name[v->namelen + 1 + ISIS_SYS_ID_LEN] = (oid)dyn->level; @@ -2803,8 +2803,8 @@ static int isis_snmp_init(struct event_loop *tm) struct isis_func_to_prefix *h2f = isis_func_to_prefix_arr; struct variable *v; - for (size_t off = 0; off < isis_var_count; off++) { - v = &isis_var_arr[off]; + for (size_t offset = 0; offset < isis_var_count; offset++) { + v = &isis_var_arr[offset]; if (v->findVar != h2f->ihtp_func) { /* Next table */ @@ -2858,7 +2858,7 @@ static int isis_snmp_db_overload_update(const struct isis_area *area) { netsnmp_variable_list *notification_vars; long val; - uint32_t off; + uint32_t offset; if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD)) return 0; @@ -2880,8 +2880,8 @@ static int isis_snmp_db_overload_update(const struct isis_area *area) (uint8_t *)&val, sizeof(val)); /* Patch sys_level_state with proper index */ - off = array_size(isis_snmp_trap_data_var_sys_level_state) - 1; - isis_snmp_trap_data_var_sys_level_state[off] = val; + offset = array_size(isis_snmp_trap_data_var_sys_level_state) - 1; + isis_snmp_trap_data_var_sys_level_state[offset] = val; /* Prepare data */ if (area->overload_bit) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 9c32a8447c..5960fef755 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1195,7 +1195,7 @@ end: && !spftree->area->attached_bit_rcv_ignore && (spftree->area->is_type & IS_LEVEL_1) && !isis_level2_adj_up(spftree->area)) { - struct prefix_pair ip_info = { {0} }; + memset(&ip_info, 0, sizeof(ip_info)); if (IS_DEBUG_RTE_EVENTS) zlog_debug("ISIS-Spf (%pLS): add default %s route", lsp->hdr.lsp_id, diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index 95ea36c3a8..fd6a44504c 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -749,11 +749,11 @@ void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup, sra->backup_nexthops = list_new(); for (ALL_LIST_ELEMENTS_RO(nexthops, node, vadj)) { - struct isis_adjacency *adj = vadj->sadj->adj; + struct isis_adjacency *tadj = vadj->sadj->adj; struct mpls_label_stack *label_stack; label_stack = vadj->label_stack; - adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL, + adjinfo2nexthop(family, sra->backup_nexthops, tadj, NULL, label_stack); } } diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 32492ae0c0..cf92ae46e9 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -704,15 +704,15 @@ static int isis_te_export(uint8_t type, void *link_state) switch (type) { case LS_MSG_TYPE_NODE: ls_vertex2msg(&msg, (struct ls_vertex *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(isis_zclient, &msg, NULL); break; case LS_MSG_TYPE_ATTRIBUTES: ls_edge2msg(&msg, (struct ls_edge *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(isis_zclient, &msg, NULL); break; case LS_MSG_TYPE_PREFIX: ls_subnet2msg(&msg, (struct ls_subnet *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(isis_zclient, &msg, NULL); break; default: rc = -1; @@ -1494,7 +1494,7 @@ static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp) /* Clean remaining Orphan Edges or Subnets */ if (IS_EXPORT_TE(mta)) - ls_vertex_clean(ted, vertex, zclient); + ls_vertex_clean(ted, vertex, isis_zclient); else ls_vertex_clean(ted, vertex, NULL); } @@ -1653,7 +1653,7 @@ int isis_te_sync_ted(struct zapi_opaque_reg_info dst) if (IS_MPLS_TE(mta) && IS_EXPORT_TE(mta)) { te_debug(" |- Export TED from area %s", area->area_tag); - rc = ls_sync_ted(mta->ted, zclient, &dst); + rc = ls_sync_ted(mta->ted, isis_zclient, &dst); if (rc != 0) return rc; } diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 8c97dcda2f..41a17dbd1a 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -129,6 +129,7 @@ static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len, struct stream *stream, struct sbuf *log, void *dest, int indent, bool *unpacked_known_tlvs); static void isis_free_subsubtlvs(struct isis_subsubtlvs *subsubtlvs); +static void isis_tlvs_del_asla_free(void *arg); /* For tests/isisd, TLV text requires ipv4-unicast instead of standard */ static const char *isis_mtid2str_fake(uint16_t mtid) @@ -147,6 +148,7 @@ struct isis_ext_subtlvs *isis_alloc_ext_subtlvs(void) init_item_list(&ext->adj_sid); init_item_list(&ext->lan_sid); ext->aslas = list_new(); + ext->aslas->del = isis_tlvs_del_asla_free; init_item_list(&ext->srv6_endx_sid); init_item_list(&ext->srv6_lan_endx_sid); @@ -518,7 +520,7 @@ static void format_item_asla_subtlvs(struct isis_asla_subtlvs *asla, asla->max_rsv_bw); if (IS_SUBTLV(asla, EXT_UNRSV_BW)) { sbuf_push(buf, indent + 2, "Unreserved Bandwidth:\n"); - for (int j = 0; j < MAX_CLASS_TYPE; j += 2) { + for (j = 0; j < MAX_CLASS_TYPE; j += 2) { sbuf_push( buf, indent + 2, "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", @@ -3209,7 +3211,7 @@ static struct isis_item *copy_item_lsp_entry(struct isis_item *i) } static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i, - struct sbuf *buf, struct json_object *json, + struct sbuf *sbuf, struct json_object *json, int indent) { struct isis_lsp_entry *e = (struct isis_lsp_entry *)i; @@ -3229,10 +3231,9 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i, json_object_string_add(lsp_json, "chksum", buf); json_object_int_add(lsp_json, "lifetime", e->checksum); } else - sbuf_push( - buf, indent, - "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n", - sys_id, e->seqno, e->checksum, e->rem_lifetime); + sbuf_push(sbuf, indent, + "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n", + sys_id, e->seqno, e->checksum, e->rem_lifetime); } static void free_item_lsp_entry(struct isis_item *i) @@ -3553,7 +3554,7 @@ static void copy_tlv_protocols_supported(struct isis_protocols_supported *src, } static void format_tlv_protocols_supported(struct isis_protocols_supported *p, - struct sbuf *buf, + struct sbuf *sbuf, struct json_object *json, int indent) { if (!p || !p->count || !p->protocols) @@ -3572,12 +3573,12 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p, nlpid2str(p->protocols[i])); } } else { - sbuf_push(buf, indent, "Protocols Supported: "); + sbuf_push(sbuf, indent, "Protocols Supported: "); for (uint8_t i = 0; i < p->count; i++) { - sbuf_push(buf, 0, "%s%s", nlpid2str(p->protocols[i]), + sbuf_push(sbuf, 0, "%s%s", nlpid2str(p->protocols[i]), (i + 1 < p->count) ? ", " : ""); } - sbuf_push(buf, 0, "\n"); + sbuf_push(sbuf, 0, "\n"); } } @@ -5275,9 +5276,9 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, /* Flex Algo Definitions */ for (int i = 0; i < SR_ALGORITHM_COUNT; i++) { struct isis_router_cap_fad *fad; - size_t subtlv_len; struct admin_group *ag; uint32_t admin_group_length; + size_t j; fad = router_cap->fads[i]; if (!fad) @@ -5315,8 +5316,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, if (admin_group_length) { stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_EXCAG); stream_putc(s, sizeof(uint32_t) * admin_group_length); - for (size_t i = 0; i < admin_group_length; i++) - stream_putl(s, admin_group_get_offset(ag, i)); + for (j = 0; j < admin_group_length; j++) + stream_putl(s, admin_group_get_offset(ag, j)); } ag = &fad->fad.admin_group_include_any; @@ -5324,8 +5325,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, if (admin_group_length) { stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCANYAG); stream_putc(s, sizeof(uint32_t) * admin_group_length); - for (size_t i = 0; i < admin_group_length; i++) - stream_putl(s, admin_group_get_offset(ag, i)); + for (j = 0; j < admin_group_length; j++) + stream_putl(s, admin_group_get_offset(ag, j)); } ag = &fad->fad.admin_group_include_all; @@ -5333,8 +5334,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, if (admin_group_length) { stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCALLAG); stream_putc(s, sizeof(uint32_t) * admin_group_length); - for (size_t i = 0; i < admin_group_length; i++) - stream_putl(s, admin_group_get_offset(ag, i)); + for (j = 0; j < admin_group_length; j++) + stream_putl(s, admin_group_get_offset(ag, j)); } if (fad->fad.flags != 0) { @@ -8137,12 +8138,19 @@ void isis_tlvs_del_srv6_lan_endx_sid(struct isis_ext_subtlvs *exts, UNSET_SUBTLV(exts, EXT_SRV6_LAN_ENDX_SID); } +static void isis_tlvs_del_asla_free(void *arg) +{ + struct isis_asla_subtlvs *asla = arg; + + admin_group_term(&asla->ext_admin_group); + XFREE(MTYPE_ISIS_SUBTLV, asla); +} + void isis_tlvs_del_asla_flex_algo(struct isis_ext_subtlvs *ext, struct isis_asla_subtlvs *asla) { - admin_group_term(&asla->ext_admin_group); listnode_delete(ext->aslas, asla); - XFREE(MTYPE_ISIS_SUBTLV, asla); + isis_tlvs_del_asla_free(asla); } struct isis_asla_subtlvs * diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index c2670143f2..15af9636ca 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -45,7 +45,7 @@ #include "isisd/isis_sr.h" #include "isisd/isis_ldp_sync.h" -struct zclient *zclient; +struct zclient *isis_zclient; static struct zclient *zclient_sync; /* Router-id update message from zebra. */ @@ -254,7 +254,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix, struct zapi_route api; int count = 0; - if (zclient->sock < 0) + if (isis_zclient->sock < 0) return; /* Uninstall the route if it doesn't have any valid nexthop. */ @@ -295,7 +295,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix, return; api.nexthop_num = count; - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, isis_zclient, &api); } void isis_zebra_route_del_route(struct isis *isis, @@ -305,7 +305,7 @@ void isis_zebra_route_del_route(struct isis *isis, { struct zapi_route api; - if (zclient->sock < 0) + if (isis_zclient->sock < 0) return; if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) @@ -321,7 +321,7 @@ void isis_zebra_route_del_route(struct isis *isis, SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX); } - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, isis_zclient, &api); } /** @@ -388,7 +388,7 @@ void isis_zebra_prefix_sid_install(struct isis_area *area, } /* Send message to zebra. */ - (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl); + (void)zebra_send_mpls_labels(isis_zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl); } /** @@ -415,7 +415,7 @@ void isis_zebra_prefix_sid_uninstall(struct isis_area *area, zl.local_label = psid->label; /* Send message to zebra. */ - (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); + (void)zebra_send_mpls_labels(isis_zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); } /** @@ -471,7 +471,7 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra) } } - (void)zebra_send_mpls_labels(zclient, cmd, &zl); + (void)zebra_send_mpls_labels(isis_zclient, cmd, &zl); } static int isis_zebra_read(ZAPI_CALLBACK_ARGS) @@ -523,9 +523,9 @@ void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id, { if (type == DEFAULT_ROUTE) zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - zclient, afi, vrf_id); + isis_zclient, afi, vrf_id); else - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, isis_zclient, afi, type, tableid, vrf_id); } @@ -534,9 +534,9 @@ void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id, { if (type == DEFAULT_ROUTE) zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - zclient, afi, vrf_id); + isis_zclient, afi, vrf_id); else - zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, isis_zclient, afi, type, tableid, vrf_id); } @@ -549,7 +549,7 @@ int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa) struct zapi_rlfa_request zr = {}; int ret; - if (!zclient) + if (!isis_zclient) return 0; zr.igp.vrf_id = area->isis->vrf_id; @@ -565,7 +565,7 @@ int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa) zlog_debug("ISIS-LFA: registering RLFA %pFX@%pI4 with LDP", &rlfa->prefix, &rlfa->pq_address); - ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_REGISTER, + ret = zclient_send_opaque_unicast(isis_zclient, LDP_RLFA_REGISTER, ZEBRA_ROUTE_LDP, 0, 0, (const uint8_t *)&zr, sizeof(zr)); if (ret == ZCLIENT_SEND_FAILURE) { @@ -585,8 +585,8 @@ void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree) struct zapi_rlfa_igp igp = {}; int ret; - if (!zclient || spftree->type != SPF_TYPE_FORWARD - || CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) + if (!isis_zclient || spftree->type != SPF_TYPE_FORWARD || + CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) return; if (IS_DEBUG_LFA) @@ -599,7 +599,7 @@ void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree) igp.isis.spf.level = spftree->level; igp.isis.spf.run_id = spftree->runcount; - ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_UNREGISTER_ALL, + ret = zclient_send_opaque_unicast(isis_zclient, LDP_RLFA_UNREGISTER_ALL, ZEBRA_ROUTE_LDP, 0, 0, (const uint8_t *)&igp, sizeof(igp)); if (ret == ZCLIENT_SEND_FAILURE) @@ -774,27 +774,27 @@ int isis_zebra_label_manager_connect(void) void isis_zebra_vrf_register(struct isis *isis) { - if (!zclient || zclient->sock < 0 || !isis) + if (!isis_zclient || isis_zclient->sock < 0 || !isis) return; if (isis->vrf_id != VRF_UNKNOWN) { if (IS_DEBUG_EVENTS) zlog_debug("%s: Register VRF %s id %u", __func__, isis->name, isis->vrf_id); - zclient_send_reg_requests(zclient, isis->vrf_id); + zclient_send_reg_requests(isis_zclient, isis->vrf_id); } } void isis_zebra_vrf_deregister(struct isis *isis) { - if (!zclient || zclient->sock < 0 || !isis) + if (!isis_zclient || isis_zclient->sock < 0 || !isis) return; if (isis->vrf_id != VRF_UNKNOWN) { if (IS_DEBUG_EVENTS) zlog_debug("%s: Deregister VRF %s id %u", __func__, isis->name, isis->vrf_id); - zclient_send_dereg_requests(zclient, isis->vrf_id); + zclient_send_dereg_requests(isis_zclient, isis->vrf_id); } } @@ -820,9 +820,9 @@ int isis_zebra_ls_register(bool up) int rc; if (up) - rc = ls_register(zclient, true); + rc = ls_register(isis_zclient, true); else - rc = ls_unregister(zclient, true); + rc = ls_unregister(isis_zclient, true); return rc; } @@ -934,7 +934,7 @@ static void isis_zebra_send_localsid(int cmd, const struct in6_addr *sid, memcpy(&api.prefix, &p, sizeof(p)); if (cmd == ZEBRA_ROUTE_DELETE) - return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, + return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, isis_zclient, &api); SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); @@ -952,7 +952,7 @@ static void isis_zebra_send_localsid(int cmd, const struct in6_addr *sid, api.nexthop_num = 1; - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, isis_zclient, &api); } /** @@ -1007,6 +1007,10 @@ void isis_zebra_srv6_sid_install(struct isis_area *area, case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: default: zlog_err( "ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u", @@ -1072,6 +1076,10 @@ void isis_zebra_srv6_sid_uninstall(struct isis_area *area, case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: default: zlog_err( "ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u", @@ -1145,6 +1153,10 @@ void isis_zebra_srv6_adj_sid_install(struct srv6_adjacency *sra) case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: default: zlog_err( "ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u", @@ -1199,6 +1211,10 @@ void isis_zebra_srv6_adj_sid_uninstall(struct srv6_adjacency *sra) case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: default: zlog_err( "ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u", @@ -1372,7 +1388,7 @@ static int isis_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) */ int isis_zebra_srv6_manager_get_locator_chunk(const char *name) { - return srv6_manager_get_locator_chunk(zclient, name); + return srv6_manager_get_locator_chunk(isis_zclient, name); } @@ -1385,7 +1401,7 @@ int isis_zebra_srv6_manager_get_locator_chunk(const char *name) */ int isis_zebra_srv6_manager_release_locator_chunk(const char *name) { - return srv6_manager_release_locator_chunk(zclient, name); + return srv6_manager_release_locator_chunk(isis_zclient, name); } /** @@ -1403,7 +1419,7 @@ int isis_zebra_srv6_manager_get_locator(const char *name) * Send the Get Locator request to the SRv6 Manager and return the * result */ - return srv6_manager_get_locator(zclient, name); + return srv6_manager_get_locator(isis_zclient, name); } /** @@ -1434,7 +1450,7 @@ bool isis_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx, * Send the Get SRv6 SID request to the SRv6 Manager and check the * result */ - ret = srv6_manager_get_sid(zclient, ctx, sid_value, locator_name, NULL); + ret = srv6_manager_get_sid(isis_zclient, ctx, sid_value, locator_name, NULL); if (ret < 0) { zlog_warn("%s: error getting SRv6 SID!", __func__); return false; @@ -1462,7 +1478,7 @@ void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx) * Send the Release SRv6 SID request to the SRv6 Manager and check the * result */ - ret = srv6_manager_release_sid(zclient, ctx); + ret = srv6_manager_release_sid(isis_zclient, ctx); if (ret < 0) { zlog_warn("%s: error releasing SRv6 SID!", __func__); return; @@ -1533,6 +1549,7 @@ static int isis_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS) isis_zebra_srv6_sid_uninstall(area, sid); listnode_delete(area->srv6db.srv6_sids, sid); + isis_srv6_sid_free(sid); } /* Allocate new SRv6 End SID */ @@ -1631,16 +1648,16 @@ static zclient_handler *const isis_handlers[] = { [ZEBRA_SRV6_SID_NOTIFY] = isis_zebra_srv6_sid_notify, }; -void isis_zebra_init(struct event_loop *master, int instance) +void isis_zebra_init(struct event_loop *mst, int instance) { /* Initialize asynchronous zclient. */ - zclient = zclient_new(master, &zclient_options_default, isis_handlers, + isis_zclient = zclient_new(mst, &zclient_options_default, isis_handlers, array_size(isis_handlers)); - zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs); - zclient->zebra_connected = isis_zebra_connected; + zclient_init(isis_zclient, PROTO_TYPE, 0, &isisd_privs); + isis_zclient->zebra_connected = isis_zebra_connected; /* Initialize special zclient for synchronous message exchanges. */ - zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0); + zclient_sync = zclient_new(mst, &zclient_options_sync, NULL, 0); zclient_sync->sock = -1; zclient_sync->redist_default = ZEBRA_ROUTE_ISIS; zclient_sync->instance = instance; @@ -1654,11 +1671,11 @@ void isis_zebra_init(struct event_loop *master, int instance) void isis_zebra_stop(void) { - zclient_unregister_opaque(zclient, LDP_RLFA_LABELS); - zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); - zclient_unregister_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); + zclient_unregister_opaque(isis_zclient, LDP_RLFA_LABELS); + zclient_unregister_opaque(isis_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); + zclient_unregister_opaque(isis_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); zclient_stop(zclient_sync); zclient_free(zclient_sync); - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(isis_zclient); + zclient_free(isis_zclient); } diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index 79da16efac..83a71b7dc9 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -11,7 +11,7 @@ #include "isisd.h" -extern struct zclient *zclient; +extern struct zclient *isis_zclient; struct label_chunk { uint32_t start; diff --git a/isisd/isisd.c b/isisd/isisd.c index a0faf31221..2260ba664f 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -187,12 +187,12 @@ struct isis *isis_lookup_by_sysid(const uint8_t *sysid) return NULL; } -void isis_master_init(struct event_loop *master) +void isis_master_init(struct event_loop *mst) { memset(&isis_master, 0, sizeof(isis_master)); im = &isis_master; im->isis = list_new(); - im->master = master; + im->master = mst; } void isis_master_terminate(void) @@ -694,24 +694,24 @@ static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set) if (type == DEFAULT_ROUTE) { if (set) vrf_bitmap_set( - &zclient->default_information + &isis_zclient->default_information [afi], isis->vrf_id); else vrf_bitmap_unset( - &zclient->default_information + &isis_zclient->default_information [afi], isis->vrf_id); } else { if (set) vrf_bitmap_set( - &zclient->redist + &isis_zclient->redist [afi] [type], isis->vrf_id); else vrf_bitmap_unset( - &zclient->redist + &isis_zclient->redist [afi] [type], isis->vrf_id); diff --git a/ldpd/lde.c b/ldpd/lde.c index 876dd41630..b0f9e5191f 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -538,8 +538,8 @@ static void lde_dispatch_parent(struct event *thread) sizeof(struct ldpd_init)) fatalx("INIT imsg with wrong len"); - memcpy(&init, imsg.data, sizeof(init)); - lde_init(&init); + memcpy(&ldp_init, imsg.data, sizeof(ldp_init)); + lde_init(&ldp_init); break; case IMSG_AGENTX_ENABLED: ldp_agentx_enabled(); diff --git a/ldpd/ldp_snmp.c b/ldpd/ldp_snmp.c index ed391ac600..2e7933f95c 100644 --- a/ldpd/ldp_snmp.c +++ b/ldpd/ldp_snmp.c @@ -620,10 +620,10 @@ static uint8_t *ldpHelloAdjacencyTable(struct variable *v, oid name[], size_t *l memcpy(name, v->name, v->namelen * sizeof(oid)); /* Append index */ - struct in_addr entityLdpId = {.s_addr = 0}; + entityLdpId.s_addr = 0; entityLdpId.s_addr = ldp_rtr_id_get(leconf); - struct in_addr peerLdpId = ctl_adj->id; + peerLdpId = ctl_adj->id; oid_copy_in_addr(name + v->namelen, &entityLdpId); name[v->namelen + 4] = 0; diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index f3bcd1b254..20b60bd373 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -1954,10 +1954,9 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, const char *json) return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, ¶ms)); } -int -ldp_vty_show_capabilities(struct vty *vty, const char *json) +int ldp_vty_show_capabilities(struct vty *vty, const char *use_json) { - if (json) { + if (use_json) { json_object *json; json_object *json_array; json_object *json_cap; diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index df682a1347..cf7ebdff41 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -38,7 +38,7 @@ static int ldp_sync_zebra_send_announce(void); static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS); static void ldp_sync_zebra_init(void); -static struct zclient *zclient; +static struct zclient *ldp_zclient; extern struct zclient *zclient_sync; static bool zebra_registered = false; @@ -100,23 +100,23 @@ pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw) static void ldp_zebra_opaque_register(void) { - zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); - zclient_register_opaque(zclient, LDP_RLFA_REGISTER); - zclient_register_opaque(zclient, LDP_RLFA_UNREGISTER_ALL); + zclient_register_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); + zclient_register_opaque(ldp_zclient, LDP_RLFA_REGISTER); + zclient_register_opaque(ldp_zclient, LDP_RLFA_UNREGISTER_ALL); } static void ldp_zebra_opaque_unregister(void) { - zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); - zclient_unregister_opaque(zclient, LDP_RLFA_REGISTER); - zclient_unregister_opaque(zclient, LDP_RLFA_UNREGISTER_ALL); + zclient_unregister_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); + zclient_unregister_opaque(ldp_zclient, LDP_RLFA_REGISTER); + zclient_unregister_opaque(ldp_zclient, LDP_RLFA_UNREGISTER_ALL); } int ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state) { - if (zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE, + if (zclient_send_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE, (const uint8_t *)state, sizeof(*state)) == ZCLIENT_SEND_FAILURE) return -1; @@ -130,9 +130,9 @@ ldp_sync_zebra_send_announce(void) struct ldp_igp_sync_announce announce; announce.proto = ZEBRA_ROUTE_LDP; - if (zclient_send_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE, - (const uint8_t *)&announce, sizeof(announce)) - == ZCLIENT_SEND_FAILURE) + if (zclient_send_opaque(ldp_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE, + (const uint8_t *)&announce, + sizeof(announce)) == ZCLIENT_SEND_FAILURE) return -1; else return 0; @@ -142,7 +142,7 @@ int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *rlfa_labels) { int ret; - ret = zclient_send_opaque(zclient, LDP_RLFA_LABELS, + ret = zclient_send_opaque(ldp_zclient, LDP_RLFA_LABELS, (const uint8_t *)rlfa_labels, sizeof(*rlfa_labels)); if (ret == ZCLIENT_SEND_FAILURE) { @@ -271,7 +271,7 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr) znh->label_num = 1; znh->labels[0] = kr->remote_label; - if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE) + if (zebra_send_mpls_labels(ldp_zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE) return -1; return 0; @@ -295,7 +295,7 @@ kmpw_add(struct zapi_pw *zpw) debug_zebra_out("pseudowire %s nexthop %s (add)", zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop)); - return zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw) == ZCLIENT_SEND_FAILURE; + return zebra_send_pw(ldp_zclient, ZEBRA_PW_ADD, zpw) == ZCLIENT_SEND_FAILURE; } int @@ -304,7 +304,7 @@ kmpw_del(struct zapi_pw *zpw) debug_zebra_out("pseudowire %s nexthop %s (del)", zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop)); - return zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw) == ZCLIENT_SEND_FAILURE; + return zebra_send_pw(ldp_zclient, ZEBRA_PW_DELETE, zpw) == ZCLIENT_SEND_FAILURE; } int @@ -314,7 +314,7 @@ kmpw_set(struct zapi_pw *zpw) zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop), zpw->local_label, zpw->remote_label); - return zebra_send_pw(zclient, ZEBRA_PW_SET, zpw) == ZCLIENT_SEND_FAILURE; + return zebra_send_pw(ldp_zclient, ZEBRA_PW_SET, zpw) == ZCLIENT_SEND_FAILURE; } int @@ -323,7 +323,7 @@ kmpw_unset(struct zapi_pw *zpw) debug_zebra_out("pseudowire %s nexthop %s (unset)", zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop)); - return zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw) == ZCLIENT_SEND_FAILURE; + return zebra_send_pw(ldp_zclient, ZEBRA_PW_UNSET, zpw) == ZCLIENT_SEND_FAILURE; } void @@ -620,18 +620,18 @@ void ldp_zebra_regdereg_zebra_info(bool want_register) want_register ? "Register" : "De-register"); if (want_register) { - zclient_send_reg_requests(zclient, VRF_DEFAULT); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, + zclient_send_reg_requests(ldp_zclient, VRF_DEFAULT); + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ldp_zclient, AFI_IP, ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ldp_zclient, AFI_IP6, ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT); } else { - zclient_send_dereg_requests(zclient, VRF_DEFAULT); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + zclient_send_dereg_requests(ldp_zclient, VRF_DEFAULT); + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ldp_zclient, AFI_IP, ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT); - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ldp_zclient, AFI_IP6, ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT); } @@ -678,7 +678,7 @@ static zclient_handler *const ldp_handlers[] = { [ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler, }; -void ldp_zebra_init(struct event_loop *master) +void ldp_zebra_init(struct event_loop *mst) { hook_register_prio(if_real, 0, ldp_ifp_create); hook_register_prio(if_up, 0, ldp_ifp_up); @@ -686,12 +686,12 @@ void ldp_zebra_init(struct event_loop *master) hook_register_prio(if_unreal, 0, ldp_ifp_destroy); /* Set default values. */ - zclient = zclient_new(master, &zclient_options_default, ldp_handlers, - array_size(ldp_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs); + ldp_zclient = zclient_new(mst, &zclient_options_default, ldp_handlers, + array_size(ldp_handlers)); + zclient_init(ldp_zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs); /* set callbacks */ - zclient->zebra_connected = ldp_zebra_connected; + ldp_zclient->zebra_connected = ldp_zebra_connected; /* Access list initialize. */ access_list_add_hook(ldp_zebra_filter_update); @@ -702,9 +702,9 @@ void ldp_zebra_destroy(void) { ldp_zebra_opaque_unregister(); - zclient_stop(zclient); - zclient_free(zclient); - zclient = NULL; + zclient_stop(ldp_zclient); + zclient_free(ldp_zclient); + ldp_zclient = NULL; if (zclient_sync == NULL) return; diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 4d38fdcd02..e4e1dc6fec 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -74,7 +74,7 @@ DEFINE_QOBJ_TYPE(ldpd_conf); const char *log_procname; struct ldpd_global global; -struct ldpd_init init; +struct ldpd_init ldp_init; struct ldpd_conf *ldpd_conf, *vty_conf; static struct imsgev *iev_ldpe, *iev_ldpe_sync; @@ -272,8 +272,8 @@ main(int argc, char *argv[]) "%s/" LDPD_SOCK_NAME, optarg); break; case 'n': - init.instance = atoi(optarg); - if (init.instance < 1) + ldp_init.instance = atoi(optarg); + if (ldp_init.instance < 1) exit(0); break; case 'L': @@ -291,11 +291,11 @@ main(int argc, char *argv[]) snprintf(ctl_sock_path, sizeof(ctl_sock_path), "%s/" LDPD_SOCK_NAME, frr_runstatedir); - strlcpy(init.user, ldpd_privs.user, sizeof(init.user)); - strlcpy(init.group, ldpd_privs.group, sizeof(init.group)); - strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path)); - strlcpy(init.zclient_serv_path, frr_zclientpath, - sizeof(init.zclient_serv_path)); + strlcpy(ldp_init.user, ldpd_privs.user, sizeof(ldp_init.user)); + strlcpy(ldp_init.group, ldpd_privs.group, sizeof(ldp_init.group)); + strlcpy(ldp_init.ctl_sock_path, ctl_sock_path, sizeof(ldp_init.ctl_sock_path)); + strlcpy(ldp_init.zclient_serv_path, frr_zclientpath, + sizeof(ldp_init.zclient_serv_path)); argc -= optind; if (argc > 0 || (lflag && eflag)) @@ -428,7 +428,7 @@ main(int argc, char *argv[]) fatal("could not establish imsg links"); main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug, sizeof(ldp_debug)); - main_imsg_compose_both(IMSG_INIT, &init, sizeof(init)); + main_imsg_compose_both(IMSG_INIT, &ldp_init, sizeof(ldp_init)); main_imsg_send_config(ldpd_conf); if (CHECK_FLAG(ldpd_conf->ipv4.flags, F_LDPD_AF_ENABLED)) diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index ad831a6ea3..700c388724 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -739,7 +739,7 @@ struct ctl_ldp_sync { extern struct ldpd_conf *ldpd_conf, *vty_conf; extern struct ldpd_global global; -extern struct ldpd_init init; +extern struct ldpd_init ldp_init; /* parse.y */ struct ldpd_conf *parse_config(char *); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 0a3a03bc38..50875e644d 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -373,8 +373,8 @@ static void ldpe_dispatch_main(struct event *thread) if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct ldpd_init)) fatalx("INIT imsg with wrong len"); - memcpy(&init, imsg.data, sizeof(init)); - ldpe_init(&init); + memcpy(&ldp_init, imsg.data, sizeof(ldp_init)); + ldpe_init(&ldp_init); break; case IMSG_AGENTX_ENABLED: ldp_agentx_enabled(); diff --git a/lib/affinitymap.c b/lib/affinitymap.c index 6ff8e83f91..10b339364b 100644 --- a/lib/affinitymap.c +++ b/lib/affinitymap.c @@ -127,3 +127,12 @@ void affinity_map_set_update_hook(void (*func)(const char *affmap_name, { affinity_map_master.update_hook = func; } + +void affinity_map_terminate(void) +{ + struct affinity_map *map; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(affinity_map_master.maps, node, nnode, map)) + affinity_map_free(map); +} diff --git a/lib/affinitymap.h b/lib/affinitymap.h index ebe2659bf7..efac1d6423 100644 --- a/lib/affinitymap.h +++ b/lib/affinitymap.h @@ -71,7 +71,7 @@ void affinity_map_set_update_hook(void (*func)(const char *affmap_name, uint16_t new_pos)); void affinity_map_init(void); - +void affinity_map_terminate(void); #ifdef __cplusplus } diff --git a/lib/darr.h b/lib/darr.h index 4638b904d1..76743cc946 100644 --- a/lib/darr.h +++ b/lib/darr.h @@ -511,11 +511,11 @@ void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mt); */ #define darr_pop(A) \ ({ \ - uint __len = _darr_len(A); \ - assert(__len); \ - darr_remove(A, __len - 1); \ + uint __poplen = _darr_len(A); \ + assert(__poplen); \ + darr_remove(A, __poplen - 1); \ /* count on fact that we don't resize */ \ - (A)[__len - 1]; \ + (A)[__poplen - 1]; \ }) /** diff --git a/lib/elf_py.c b/lib/elf_py.c index 14012a2173..7609ea59c1 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -518,12 +518,12 @@ static void elfsect_add_relocations(struct elfsect *w, Elf_Scn *rel, relw->es = w; if (relhdr->sh_type == SHT_REL) { - GElf_Rel _rel, *rel; + GElf_Rel _rel, *erel; - rel = gelf_getrel(reldata, i, &_rel); + erel = gelf_getrel(reldata, i, &_rel); relw->rela = &relw->_rela; - relw->rela->r_offset = rel->r_offset; - relw->rela->r_info = rel->r_info; + relw->rela->r_offset = erel->r_offset; + relw->rela->r_info = erel->r_info; relw->rela->r_addend = 0; relw->relative = true; } else @@ -581,14 +581,14 @@ static PyObject *elfsect_wrap(struct elffile *ef, Elf_Scn *scn, size_t idx, elfrelocs_init(&w->relocs); for (i = 0; i < ef->ehdr->e_shnum; i++) { - Elf_Scn *scn = elf_getscn(ef->elf, i); - GElf_Shdr _shdr, *shdr = gelf_getshdr(scn, &_shdr); + Elf_Scn *escn = elf_getscn(ef->elf, i); + GElf_Shdr _shdr, *shdr = gelf_getshdr(escn, &_shdr); if (shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL) continue; if (shdr->sh_info && shdr->sh_info != idx) continue; - elfsect_add_relocations(w, scn, shdr); + elfsect_add_relocations(w, escn, shdr); } return (PyObject *)w; diff --git a/lib/filter_cli.c b/lib/filter_cli.c index b3ad5fb46d..6d8d288d81 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -1400,10 +1400,14 @@ DEFPY_YANG( snprintf(xpath, sizeof(xpath), "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name); if (seq_str == NULL) { - /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath, false); - if (sseq < 0) - return CMD_WARNING_CONFIG_FAILED; + if (plist_is_dup(vty->candidate_config->dnode, &pda)) + sseq = pda.pda_seq; + else { + /* Use XPath to find the next sequence number. */ + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + } snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h index bb751b7071..368ada36ad 100644 --- a/lib/frr_pthread.h +++ b/lib/frr_pthread.h @@ -233,11 +233,13 @@ int frr_pthread_non_controlled_startup(pthread_t thread, const char *name, unused, cleanup(_frr_mtx_unlock))) = _frr_mtx_lock(mutex), \ /* end */ -#define frr_with_mutex(...) \ - for (pthread_mutex_t MACRO_REPEAT(_frr_with_mutex, ##__VA_ARGS__) \ - *_once = NULL; _once == NULL; _once = (void *)1) \ +#define _frr_with_mutex_once(_once, ...) \ + for (pthread_mutex_t MACRO_REPEAT(_frr_with_mutex, ##__VA_ARGS__)*_once = NULL; \ + _once == NULL; _once = (void *)1) \ /* end */ +#define frr_with_mutex(...) _frr_with_mutex_once(NAMECTR(_once_), __VA_ARGS__) + /* variant 2: * (more suitable for long blocks, no extra indentation) * diff --git a/lib/libfrr.c b/lib/libfrr.c index 8a37b51c47..d40624a102 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -1192,9 +1192,10 @@ void frr_detach(void) frr_check_detach(); } -void frr_run(struct event_loop *master) +void frr_run(struct event_loop *loop) { char instanceinfo[64] = ""; + struct event thread; if (!(di->flags & FRR_MANUAL_VTY_START)) frr_vty_serv_start(false); @@ -1212,7 +1213,7 @@ void frr_run(struct event_loop *master) vty_stdio(frr_terminal_close); if (daemon_ctl_sock != -1) { set_nonblocking(daemon_ctl_sock); - event_add_read(master, frr_daemon_ctl, NULL, + event_add_read(loop, frr_daemon_ctl, NULL, daemon_ctl_sock, &daemon_ctl_thread); } } else if (di->daemon_mode) { @@ -1242,8 +1243,7 @@ void frr_run(struct event_loop *master) /* end fixed stderr startup logging */ zlog_startup_end(); - struct event thread; - while (event_fetch(master, &thread)) + while (event_fetch(loop, &thread)) event_call(&thread); } diff --git a/lib/link_state.c b/lib/link_state.c index 3d96c75f6d..27cc2558f5 100644 --- a/lib/link_state.c +++ b/lib/link_state.c @@ -2555,9 +2555,9 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json) if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) { jbw = json_object_new_array(); json_object_object_add(jte, "unreserved-bandwidth", jbw); - for (int i = 0; i < MAX_CLASS_TYPE; i++) { + for (i = 0; i < MAX_CLASS_TYPE; i++) { jobj = json_object_new_object(); - snprintfrr(buf, 13, "class-type-%u", i); + snprintfrr(buf, 13, "class-type-%u", (unsigned int)i); json_object_double_add(jobj, buf, attr->standard.unrsv_bw[i]); json_object_array_add(jbw, jobj); @@ -2599,7 +2599,7 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json) if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) { jsrlg = json_object_new_array(); json_object_object_add(jte, "srlgs", jsrlg); - for (int i = 1; i < attr->srlg_len; i++) { + for (i = 1; i < attr->srlg_len; i++) { jobj = json_object_new_object(); json_object_int_add(jobj, "srlg", attr->srlgs[i]); json_object_array_add(jsrlg, jobj); diff --git a/lib/linklist.h b/lib/linklist.h index f922891df9..d86db36f55 100644 --- a/lib/linklist.h +++ b/lib/linklist.h @@ -67,7 +67,11 @@ struct list { #define listcount(X) ((X)->count) #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL) /* return X->data only if X and X->data are not NULL */ -#define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data) +static inline void *listgetdata(const struct listnode *X) +{ + assert((X != NULL) && ((X)->data != NULL)); + return X->data; +} /* App is going to manage listnode memory */ #define listset_app_node_mem(X) ((X)->flags |= LINKLIST_FLAG_NODE_MEM_BY_APP) #define listnode_init(X, val) ((X)->data = (val)) diff --git a/lib/northbound.c b/lib/northbound.c index f860b83c45..a1e26d2523 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -235,8 +235,9 @@ static int nb_node_validate_cb(const struct nb_node *nb_node, * depends on context (e.g. some daemons might augment "frr-interface" * while others don't). */ - if (!valid && callback_implemented && operation != NB_CB_GET_NEXT - && operation != NB_CB_GET_KEYS && operation != NB_CB_LOOKUP_ENTRY) + if (!valid && callback_implemented && operation != NB_CB_GET_NEXT && + operation != NB_CB_GET_KEYS && operation != NB_CB_LIST_ENTRY_DONE && + operation != NB_CB_LOOKUP_ENTRY) flog_warn(EC_LIB_NB_CB_UNNEEDED, "unneeded '%s' callback for '%s'", nb_cb_operation_name(operation), nb_node->xpath); @@ -283,6 +284,8 @@ static unsigned int nb_node_validate_cbs(const struct nb_node *nb_node) state_optional); error += nb_node_validate_cb(nb_node, NB_CB_GET_KEYS, !!nb_node->cbs.get_keys, state_optional); + error += nb_node_validate_cb(nb_node, NB_CB_LIST_ENTRY_DONE, !!nb_node->cbs.list_entry_done, + true); error += nb_node_validate_cb(nb_node, NB_CB_LOOKUP_ENTRY, !!nb_node->cbs.lookup_entry, state_optional); error += nb_node_validate_cb(nb_node, NB_CB_RPC, !!nb_node->cbs.rpc, @@ -1806,6 +1809,19 @@ int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry, return nb_node->cbs.get_keys(&args); } +void nb_callback_list_entry_done(const struct nb_node *nb_node, const void *parent_list_entry, + const void *list_entry) +{ + if (CHECK_FLAG(nb_node->flags, F_NB_NODE_IGNORE_CFG_CBS) || !nb_node->cbs.list_entry_done) + return; + + DEBUGD(&nb_dbg_cbs_state, + "northbound callback (list_entry_done): node [%s] parent_list_entry [%p] list_entry [%p]", + nb_node->xpath, parent_list_entry, list_entry); + + nb_node->cbs.list_entry_done(parent_list_entry, list_entry); +} + const void *nb_callback_lookup_entry(const struct nb_node *nb_node, const void *parent_list_entry, const struct yang_list_keys *keys) @@ -1943,6 +1959,7 @@ static int nb_callback_configuration(struct nb_context *context, case NB_CB_GET_ELEM: case NB_CB_GET_NEXT: case NB_CB_GET_KEYS: + case NB_CB_LIST_ENTRY_DONE: case NB_CB_LOOKUP_ENTRY: case NB_CB_RPC: case NB_CB_NOTIFY: @@ -2322,6 +2339,7 @@ bool nb_cb_operation_is_valid(enum nb_cb_operation operation, } return true; case NB_CB_GET_KEYS: + case NB_CB_LIST_ENTRY_DONE: case NB_CB_LOOKUP_ENTRY: switch (snode->nodetype) { case LYS_LIST: @@ -2625,6 +2643,8 @@ const char *nb_cb_operation_name(enum nb_cb_operation operation) return "get_next"; case NB_CB_GET_KEYS: return "get_keys"; + case NB_CB_LIST_ENTRY_DONE: + return "list_entry_done"; case NB_CB_LOOKUP_ENTRY: return "lookup_entry"; case NB_CB_RPC: diff --git a/lib/northbound.h b/lib/northbound.h index 0468c58de3..53abf90a9f 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -98,6 +98,7 @@ enum nb_cb_operation { NB_CB_GET_ELEM, NB_CB_GET_NEXT, NB_CB_GET_KEYS, + NB_CB_LIST_ENTRY_DONE, NB_CB_LOOKUP_ENTRY, NB_CB_RPC, NB_CB_NOTIFY, @@ -518,6 +519,24 @@ struct nb_callbacks { /* * Operational data callback for YANG lists. * + * This callback function is called to cleanup any resources that may be + * held by a backend opaque `list_entry` value (e.g., a lock). It is + * called when the northbound code is done using a `list_entry` value it + * obtained using the lookup_entry() callback. It is also called on the + * `list_entry` returned from the get_next() or lookup_next() callbacks + * if the iteration aborts before walking to the end of the list. The + * intention is to allow any resources (e.g., a lock) to now be + * released. + * + * args + * parent_list_entry - pointer to the parent list entry + * list_entry - value returned previously from `lookup_entry()` + */ + void (*list_entry_done)(const void *parent_list_entry, const void *list_entry); + + /* + * Operational data callback for YANG lists. + * * The callback function should return a list entry based on the list * keys given as a parameter. Keyless lists don't need to implement this * callback. @@ -883,6 +902,8 @@ extern int nb_callback_get_keys(const struct nb_node *nb_node, extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node, const void *parent_list_entry, const struct yang_list_keys *keys); +extern void nb_callback_list_entry_done(const struct nb_node *nb_node, + const void *parent_list_entry, const void *list_entry); extern const void *nb_callback_lookup_node_entry(struct lyd_node *node, const void *parent_list_entry); extern const void *nb_callback_lookup_next(const struct nb_node *nb_node, diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c index 626c37082e..0ce9d77259 100644 --- a/lib/northbound_oper.c +++ b/lib/northbound_oper.c @@ -139,6 +139,9 @@ static const void *nb_op_list_get_next(struct nb_op_yield_state *ys, struct nb_n static const void *nb_op_list_lookup_entry(struct nb_op_yield_state *ys, struct nb_node *nb_node, const struct nb_op_node_info *pni, struct lyd_node *node, const struct yang_list_keys *keys); +static void nb_op_list_list_entry_done(struct nb_op_yield_state *ys, struct nb_node *nb_node, + const struct nb_op_node_info *pni, const void *list_entry); +static void ys_pop_inner(struct nb_op_yield_state *ys); /* -------------------- */ /* Function Definitions */ @@ -157,6 +160,7 @@ nb_op_create_yield_state(const char *xpath, struct yang_translator *translator, /* remove trailing '/'s */ while (darr_len(ys->xpath) > 1 && ys->xpath[darr_len(ys->xpath) - 2] == '/') { darr_setlen(ys->xpath, darr_len(ys->xpath) - 1); + assert(darr_last(ys->xpath)); /* quiet clang-analyzer :( */ *darr_last(ys->xpath) = 0; } ys->xpath_orig = darr_strdup(xpath); @@ -188,6 +192,9 @@ static inline void nb_op_free_yield_state(struct nb_op_yield_state *ys, darr_free(ys->non_specific_predicate); darr_free(ys->query_tokstr); darr_free(ys->schema_path); + /* need to cleanup resources, so pop these individually */ + while (darr_len(ys->node_infos)) + ys_pop_inner(ys); darr_free(ys->node_infos); darr_free(ys->xpath_orig); darr_free(ys->xpath); @@ -222,10 +229,20 @@ static void ys_trim_xpath(struct nb_op_yield_state *ys) static void ys_pop_inner(struct nb_op_yield_state *ys) { - uint len = darr_len(ys->node_infos); + struct nb_op_node_info *ni, *pni; + struct nb_node *nb_node; + int i = darr_lasti(ys->node_infos); - assert(len); - darr_setlen(ys->node_infos, len - 1); + pni = i > 0 ? &ys->node_infos[i - 1] : NULL; + ni = &ys->node_infos[i]; + + /* list_entry's propagate so only free the first occurance */ + if (ni->list_entry && (!pni || pni->list_entry != ni->list_entry)) { + nb_node = ni->schema ? ni->schema->priv : NULL; + if (nb_node) + nb_op_list_list_entry_done(ys, nb_node, pni, ni->list_entry); + } + darr_setlen(ys->node_infos, i); ys_trim_xpath(ys); } @@ -872,6 +889,14 @@ static enum nb_error nb_op_list_get_keys(struct nb_op_yield_state *ys, struct nb return 0; } +static void nb_op_list_list_entry_done(struct nb_op_yield_state *ys, struct nb_node *nb_node, + const struct nb_op_node_info *pni, const void *list_entry) +{ + if (CHECK_FLAG(nb_node->flags, F_NB_NODE_HAS_GET_TREE)) + return; + + nb_callback_list_entry_done(nb_node, pni ? pni->list_entry : NULL, list_entry); +} /** * nb_op_add_leaf() - Add leaf data to the get tree results @@ -1153,8 +1178,8 @@ static const struct lysc_node *nb_op_sib_first(struct nb_op_yield_state *ys, * * If the schema path (original query) is longer than our current node * info stack (current xpath location), we are building back up to the - * base of the user query, return the next schema node from the query - * string (schema_path). + * base of the walk at the end of the user query path, return the next + * schema node from the query string (schema_path). */ if (last != NULL) assert(last->schema == parent); @@ -1525,6 +1550,18 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) */ assert(!list_start); is_specific_node = true; + + /* + * Release the entry back to the daemon + */ + assert(ni->list_entry == list_entry); + nb_op_list_list_entry_done(ys, nn, pni, list_entry); + ni->list_entry = NULL; + + /* + * Continue on as we may reap the resulting node + * if empty. + */ list_entry = NULL; } @@ -1605,6 +1642,18 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) } /* + * The walk API is that get/lookup_next returns NULL + * when done, those callbacks are also is responsible + * for releasing any state associated with previous + * list_entry's (e.g., any locks) during the iteration. + * Therefore we need to zero out the last top level + * list_entry so we don't mistakenly call the + * list_entry_done() callback on it. + */ + if (!is_specific_node && !list_start && !list_entry) + ni->list_entry = NULL; + + /* * (FN:A) Reap empty list element? Check to see if we * should reap an empty list element. We do this if the * empty list element exists at or below the query base @@ -1619,17 +1668,15 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) * have no non-key children, check for this condition * and do not reap if true. */ - if (!list_start && ni->inner && - !lyd_child_no_keys(ni->inner) && + if (!list_start && ni->inner && !lyd_child_no_keys(ni->inner) && /* not the top element with a key match */ - !((darr_ilen(ys->node_infos) == - darr_ilen(ys->schema_path) - 1) && + !(darr_ilen(ys->schema_path) && /* quiet clang-analyzer :( */ + (darr_ilen(ys->node_infos) == darr_ilen(ys->schema_path) - 1) && lysc_is_key((*darr_last(ys->schema_path)))) && - /* is this at or below the base? */ - darr_ilen(ys->node_infos) <= ys->query_base_level) + /* is this list entry below the query base? */ + darr_ilen(ys->node_infos) - 1 < ys->query_base_level) ys_free_inner(ys, ni); - if (!list_entry) { /* * List Iteration Done @@ -1724,12 +1771,15 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) ni->xpath_len = len; } + /* Save the new list_entry early so it can be cleaned up on error */ + ni->list_entry = list_entry; + ni->schema = sib; + /* Need to get keys. */ if (!CHECK_FLAG(nn->flags, F_NB_NODE_KEYLESS_LIST)) { ret = nb_op_list_get_keys(ys, nn, list_entry, &ni->keys); if (ret) { - darr_pop(ys->node_infos); ret = NB_ERR_RESOURCE; goto done; } @@ -1764,7 +1814,6 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) .inner, sib, &ni->keys, &node); if (err) { - darr_pop(ys->node_infos); ret = NB_ERR_RESOURCE; goto done; } @@ -1774,8 +1823,7 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume) * Save the new list entry with the list node info */ ni->inner = node; - ni->schema = node->schema; - ni->list_entry = list_entry; + assert(ni->schema == node->schema); ni->niters += 1; ni->nents += 1; diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c index 3f6700c838..12c4dad683 100644 --- a/lib/printf/vfprintf.c +++ b/lib/printf/vfprintf.c @@ -556,23 +556,23 @@ reswitch: switch (ch) { case 'G': if (flags & LONGDBL) { long double arg = GETARG(long double); - char fmt[6] = "%.*L"; - fmt[4] = ch; - fmt[5] = '\0'; + char lfmt[6] = "%.*L"; + lfmt[4] = ch; + lfmt[5] = '\0'; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" - snprintf(buf, sizeof(buf), fmt, prec, arg); + snprintf(buf, sizeof(buf), lfmt, prec, arg); #pragma GCC diagnostic pop } else { double arg = GETARG(double); - char fmt[5] = "%.*"; - fmt[3] = ch; - fmt[4] = '\0'; + char lfmt[5] = "%.*"; + lfmt[3] = ch; + lfmt[4] = '\0'; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" - snprintf(buf, sizeof(buf), fmt, prec, arg); + snprintf(buf, sizeof(buf), lfmt, prec, arg); #pragma GCC diagnostic pop } cp = buf; diff --git a/lib/resolver.c b/lib/resolver.c index 901ccf8132..62b98091ec 100644 --- a/lib/resolver.c +++ b/lib/resolver.c @@ -282,7 +282,7 @@ static void resolver_cb_literal(struct event *t) callback = query->callback; query->callback = NULL; - callback(query, ARES_SUCCESS, 1, &query->literal_addr); + callback(query, NULL, 1, &query->literal_addr); } void resolver_resolve(struct resolver_query *query, int af, vrf_id_t vrf_id, diff --git a/lib/srv6.h b/lib/srv6.h index 467f02a3c9..bd80253b55 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -179,9 +179,11 @@ enum srv6_endpoint_behavior_codepoint { SRV6_ENDPOINT_BEHAVIOR_END_PSP = 0x0002, SRV6_ENDPOINT_BEHAVIOR_END_X = 0x0005, SRV6_ENDPOINT_BEHAVIOR_END_X_PSP = 0x0006, + SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS = 0x000E, SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012, SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013, SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014, + SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED = 0x001B, SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD = 0x001D, SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD = 0x0021, SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID = 0x002B, @@ -193,6 +195,8 @@ enum srv6_endpoint_behavior_codepoint { SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E, SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F, SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040, + SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID = 0x005D, + SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID = 0x005E, SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF, }; @@ -215,6 +219,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav return "End.X"; case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: return "End.X PSP"; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + return "End.B6.Encaps"; case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: return "End.X PSP/USD"; case SRV6_ENDPOINT_BEHAVIOR_END_DT6: @@ -223,6 +229,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav return "End.DT4"; case SRV6_ENDPOINT_BEHAVIOR_END_DT46: return "End.DT46"; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + return "End.B6.Encaps.Red"; case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: return "uN"; case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: @@ -241,6 +249,10 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav return "uDT4"; case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID: return "uDT46"; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + return "uB6.Encaps"; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: + return "uB6.Encaps.Red"; case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: return "Opaque"; } diff --git a/lib/zclient.c b/lib/zclient.c index 3e68e962aa..031f454385 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3014,7 +3014,7 @@ size_t zebra_interface_link_params_write(struct stream *s, size_t w, nb_ext_adm_grp; struct if_link_params *iflp; int i; - + size_t j; if (s == NULL || ifp == NULL) return 0; @@ -3045,8 +3045,8 @@ size_t zebra_interface_link_params_write(struct stream *s, /* Extended Administrative Group */ nb_ext_adm_grp = admin_group_nb_words(&iflp->ext_admin_grp); w += stream_putc(s, nb_ext_adm_grp); - for (size_t i = 0; i < nb_ext_adm_grp; i++) - stream_putl(s, admin_group_get_offset(&iflp->ext_admin_grp, i)); + for (j = 0; j < nb_ext_adm_grp; j++) + stream_putl(s, admin_group_get_offset(&iflp->ext_admin_grp, j)); w += stream_putl(s, iflp->rmt_as); w += stream_put_in_addr(s, &iflp->rmt_ip); diff --git a/mgmtd/mgmt_ds.c b/mgmtd/mgmt_ds.c index dabae4afd1..3a85525d93 100644 --- a/mgmtd/mgmt_ds.c +++ b/mgmtd/mgmt_ds.c @@ -74,8 +74,7 @@ static int mgmt_ds_dump_in_memory(struct mgmt_ds_ctx *ds_ctx, return 0; } -static int mgmt_ds_replace_dst_with_src_ds(struct mgmt_ds_ctx *src, - struct mgmt_ds_ctx *dst) +static int ds_copy(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src) { if (!src || !dst) return -1; @@ -95,8 +94,7 @@ static int mgmt_ds_replace_dst_with_src_ds(struct mgmt_ds_ctx *src, return 0; } -static int mgmt_ds_merge_src_with_dst_ds(struct mgmt_ds_ctx *src, - struct mgmt_ds_ctx *dst) +static int ds_merge(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src) { int ret; @@ -151,9 +149,9 @@ void mgmt_ds_reset_candidate(void) } -int mgmt_ds_init(struct mgmt_master *mm) +int mgmt_ds_init(struct mgmt_master *m) { - if (mgmt_ds_mm || mm->running_ds || mm->candidate_ds || mm->oper_ds) + if (mgmt_ds_mm || m->running_ds || m->candidate_ds || m->oper_ds) assert(!"MGMTD: Call ds_init only once!"); /* Use Running DS from NB module??? */ @@ -178,10 +176,10 @@ int mgmt_ds_init(struct mgmt_master *mm) oper.config_ds = false; oper.ds_id = MGMTD_DS_OPERATIONAL; - mm->running_ds = &running; - mm->candidate_ds = &candidate; - mm->oper_ds = &oper; - mgmt_ds_mm = mm; + m->running_ds = &running; + m->candidate_ds = &candidate; + m->oper_ds = &oper; + mgmt_ds_mm = m; return 0; } @@ -195,16 +193,15 @@ void mgmt_ds_destroy(void) oper.root.dnode_root = NULL; } -struct mgmt_ds_ctx *mgmt_ds_get_ctx_by_id(struct mgmt_master *mm, - Mgmtd__DatastoreId ds_id) +struct mgmt_ds_ctx *mgmt_ds_get_ctx_by_id(struct mgmt_master *m, Mgmtd__DatastoreId ds_id) { switch (ds_id) { case MGMTD_DS_CANDIDATE: - return (mm->candidate_ds); + return (m->candidate_ds); case MGMTD_DS_RUNNING: - return (mm->running_ds); + return (m->running_ds); case MGMTD_DS_OPERATIONAL: - return (mm->oper_ds); + return (m->oper_ds); case MGMTD_DS_NONE: case MGMTD__DATASTORE_ID__STARTUP_DS: case _MGMTD__DATASTORE_ID_IS_INT_SIZE: @@ -251,14 +248,13 @@ void mgmt_ds_unlock(struct mgmt_ds_ctx *ds_ctx) ds_ctx->locked = 0; } -int mgmt_ds_copy_dss(struct mgmt_ds_ctx *src_ds_ctx, - struct mgmt_ds_ctx *dst_ds_ctx, bool updt_cmt_rec) +int mgmt_ds_copy_dss(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src, bool updt_cmt_rec) { - if (mgmt_ds_replace_dst_with_src_ds(src_ds_ctx, dst_ds_ctx) != 0) + if (ds_copy(dst, src) != 0) return -1; - if (updt_cmt_rec && dst_ds_ctx->ds_id == MGMTD_DS_RUNNING) - mgmt_history_new_record(dst_ds_ctx); + if (updt_cmt_rec && dst->ds_id == MGMTD_DS_RUNNING) + mgmt_history_new_record(dst); return 0; } @@ -416,9 +412,9 @@ int mgmt_ds_load_config_from_file(struct mgmt_ds_ctx *dst, parsed.ds_id = dst->ds_id; if (merge) - mgmt_ds_merge_src_with_dst_ds(&parsed, dst); + ds_merge(dst, &parsed); else - mgmt_ds_replace_dst_with_src_ds(&parsed, dst); + ds_copy(dst, &parsed); nb_config_free(parsed.root.cfg_root); diff --git a/mgmtd/mgmt_ds.h b/mgmtd/mgmt_ds.h index b8e77e330a..f7e1d7c5ee 100644 --- a/mgmtd/mgmt_ds.h +++ b/mgmtd/mgmt_ds.h @@ -196,21 +196,19 @@ extern void mgmt_ds_unlock(struct mgmt_ds_ctx *ds_ctx); /* * Copy from source to destination datastore. * - * src_ds - * Source datastore handle (ds to be copied from). - * - * dst_ds + * dst * Destination datastore handle (ds to be copied to). * + * src + * Source datastore handle (ds to be copied from). + * * update_cmd_rec * TRUE if need to update commit record, FALSE otherwise. * * Returns: * 0 on success, -1 on failure. */ -extern int mgmt_ds_copy_dss(struct mgmt_ds_ctx *src_ds_ctx, - struct mgmt_ds_ctx *dst_ds_ctx, - bool update_cmt_rec); +extern int mgmt_ds_copy_dss(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src, bool update_cmt_rec); /* * Fetch northbound configuration for a given datastore context. diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 8d59198803..39686091e1 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -217,12 +217,6 @@ static void mgmt_fe_session_cfg_txn_cleanup(struct mgmt_fe_session_ctx *session) { /* - * Ensure any uncommitted changes in Candidate DS - * is discarded. - */ - mgmt_ds_copy_dss(mm->running_ds, mm->candidate_ds, false); - - /* * Destroy the actual transaction created earlier. */ if (session->cfg_txn_id != MGMTD_TXN_ID_NONE) @@ -1442,7 +1436,6 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, /* Check for yang-library shortcut */ if (nb_oper_is_yang_lib_query(msg->xpath)) { struct lyd_node *ylib = NULL; - LY_ERR err; err = ly_ctx_get_yanglib_data(ly_native_ctx, &ylib, "%u", ly_ctx_get_change_count( diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 483dfab8e8..96ca62c847 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -764,17 +764,15 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn, !txn->commit_cfg_req->req.commit_cfg.rollback); /* - * Successful commit: Merge Src DS into Dst DS if and only if + * Successful commit: Copy Src DS to Dst DS if and only if * this was not a validate-only or abort request. */ if ((txn->session_id && !txn->commit_cfg_req->req.commit_cfg.validate_only && !txn->commit_cfg_req->req.commit_cfg.abort) || txn->commit_cfg_req->req.commit_cfg.rollback) { - mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg - .src_ds_ctx, - txn->commit_cfg_req->req.commit_cfg - .dst_ds_ctx, + mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx, + txn->commit_cfg_req->req.commit_cfg.src_ds_ctx, create_cmt_info_rec); } @@ -783,22 +781,18 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn, * request. */ if (txn->session_id && txn->commit_cfg_req->req.commit_cfg.abort) - mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg - .dst_ds_ctx, - txn->commit_cfg_req->req.commit_cfg - .src_ds_ctx, - false); + mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.src_ds_ctx, + txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx, false); } else { /* * The commit has failied. For implicit commit requests restore - * back the contents of the candidate DS. + * back the contents of the candidate DS. For non-implicit + * commit we want to allow the user to re-commit on the changes + * (whether further modified or not). */ if (txn->commit_cfg_req->req.commit_cfg.implicit) - mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg - .dst_ds_ctx, - txn->commit_cfg_req->req.commit_cfg - .src_ds_ctx, - false); + mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.src_ds_ctx, + txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx, false); } if (txn->commit_cfg_req->req.commit_cfg.rollback) { @@ -1993,17 +1987,17 @@ static void mgmt_txn_register_event(struct mgmt_txn_ctx *txn, } } -int mgmt_txn_init(struct mgmt_master *mm, struct event_loop *tm) +int mgmt_txn_init(struct mgmt_master *m, struct event_loop *loop) { if (mgmt_txn_mm || mgmt_txn_tm) assert(!"MGMTD TXN: Call txn_init() only once"); - mgmt_txn_mm = mm; - mgmt_txn_tm = tm; - mgmt_txns_init(&mm->txn_list); + mgmt_txn_mm = m; + mgmt_txn_tm = loop; + mgmt_txns_init(&m->txn_list); mgmt_txn_hash_init(); - assert(!mm->cfg_txn); - mm->cfg_txn = NULL; + assert(!m->cfg_txn); + m->cfg_txn = NULL; return 0; } diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index fa11980c18..97932795a3 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -1355,6 +1355,11 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb) } break; case NHRP_ROUTE_NBMA_NEXTHOP: + if (hdr->hop_count == 0) { + nhrp_packet_send_error(&pp, NHRP_ERROR_HOP_COUNT_EXCEEDED, 0); + info = "hop count exceeded"; + goto drop; + } nhrp_peer_forward(peer, &pp); break; case NHRP_ROUTE_BLACKHOLE: diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 7adc4a6399..2e4c7b1eec 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -16,7 +16,7 @@ DEFINE_MTYPE_STATIC(NHRPD, NHRP_ROUTE, "NHRP routing entry"); -static struct zclient *zclient; +static struct zclient *nhrp_zclient; static struct route_table *zebra_rib[AFI_MAX]; struct route_info { @@ -95,7 +95,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, struct zapi_route api; struct zapi_nexthop *api_nh; - if (zclient->sock < 0) + if (nhrp_zclient->sock < 0) return; memset(&api, 0, sizeof(api)); @@ -196,7 +196,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, api.metric, api.nexthop_num, ifp ? ifp->name : "none"); } - zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, + zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, nhrp_zclient, &api); } @@ -374,10 +374,10 @@ void nhrp_zebra_init(void) zebra_rib[AFI_IP] = route_table_init(); zebra_rib[AFI_IP6] = route_table_init(); - zclient = zclient_new(master, &zclient_options_default, nhrp_handlers, - array_size(nhrp_handlers)); - zclient->zebra_connected = nhrp_zebra_connected; - zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs); + nhrp_zclient = zclient_new(master, &zclient_options_default, nhrp_handlers, + array_size(nhrp_handlers)); + nhrp_zclient->zebra_connected = nhrp_zebra_connected; + zclient_init(nhrp_zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs); } static void nhrp_table_node_cleanup(struct route_table *table, @@ -393,18 +393,18 @@ void nhrp_send_zebra_configure_arp(struct interface *ifp, int family) { struct stream *s; - if (!zclient || zclient->sock < 0) { + if (!nhrp_zclient || nhrp_zclient->sock < 0) { debugf(NHRP_DEBUG_COMMON, "%s() : zclient not ready", __func__); return; } - s = zclient->obuf; + s = nhrp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_CONFIGURE_ARP, ifp->vrf->vrf_id); stream_putc(s, family); stream_putl(s, ifp->ifindex); stream_putw_at(s, 0, stream_get_endp(s)); - zclient_send_message(zclient); + zclient_send_message(nhrp_zclient); } void nhrp_send_zebra_gre_source_set(struct interface *ifp, @@ -413,7 +413,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp, { struct stream *s; - if (!zclient || zclient->sock < 0) { + if (!nhrp_zclient || nhrp_zclient->sock < 0) { zlog_err("%s : zclient not ready", __func__); return; } @@ -421,7 +421,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp, /* silently ignore */ return; } - s = zclient->obuf; + s = nhrp_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_GRE_SOURCE_SET, ifp->vrf->vrf_id); stream_putl(s, ifp->ifindex); @@ -429,7 +429,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp, stream_putl(s, link_vrf_id); stream_putl(s, 0); /* mtu provisioning */ stream_putw_at(s, 0, stream_get_endp(s)); - zclient_send_message(zclient); + zclient_send_message(nhrp_zclient); } void nhrp_send_zebra_nbr(union sockunion *in, @@ -438,9 +438,9 @@ void nhrp_send_zebra_nbr(union sockunion *in, { struct stream *s; - if (!zclient || zclient->sock < 0) + if (!nhrp_zclient || nhrp_zclient->sock < 0) return; - s = zclient->obuf; + s = nhrp_zclient->obuf; stream_reset(s); zclient_neigh_ip_encode(s, out ? ZEBRA_NEIGH_IP_ADD : ZEBRA_NEIGH_IP_DEL, in, out, ifp, @@ -448,26 +448,26 @@ void nhrp_send_zebra_nbr(union sockunion *in, : ZEBRA_NEIGH_STATE_FAILED, 0); stream_putw_at(s, 0, stream_get_endp(s)); - zclient_send_message(zclient); + zclient_send_message(nhrp_zclient); } int nhrp_send_zebra_gre_request(struct interface *ifp) { - return zclient_send_zebra_gre_request(zclient, ifp); + return zclient_send_zebra_gre_request(nhrp_zclient, ifp); } void nhrp_interface_update_arp(struct interface *ifp, bool arp_enable) { - zclient_interface_set_arp(zclient, ifp, arp_enable); + zclient_interface_set_arp(nhrp_zclient, ifp, arp_enable); } void nhrp_zebra_terminate(void) { - zclient_register_neigh(zclient, VRF_DEFAULT, AFI_IP, false); - zclient_register_neigh(zclient, VRF_DEFAULT, AFI_IP6, false); - zclient_stop(zclient); - zclient_free(zclient); + zclient_register_neigh(nhrp_zclient, VRF_DEFAULT, AFI_IP, false); + zclient_register_neigh(nhrp_zclient, VRF_DEFAULT, AFI_IP6, false); + zclient_stop(nhrp_zclient); + zclient_free(nhrp_zclient); zebra_rib[AFI_IP]->cleanup = nhrp_table_node_cleanup; zebra_rib[AFI_IP6]->cleanup = nhrp_table_node_cleanup; diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 343dfefcec..2cb63d8a29 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -515,8 +515,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, summary->path.origin.id = ADV_ROUTER_IN_PREFIX(&route->prefix); } else { - struct ospf6_lsa *old; - summary->path.origin.type = htons(OSPF6_LSTYPE_INTER_PREFIX); diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index 2ed69cc597..16049427ac 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -123,16 +123,16 @@ struct ospf6_area { #define OSPF6_CMD_AREA_GET(str, oa, ospf6) \ { \ - uint32_t area_id; \ - int format, ret; \ - ret = str2area_id(str, &area_id, &format); \ - if (ret) { \ + uint32_t _area_id; \ + int _format, _ret; \ + _ret = str2area_id(str, &_area_id, &_format); \ + if (_ret) { \ vty_out(vty, "Malformed Area-ID: %s\n", str); \ return CMD_WARNING; \ } \ - oa = ospf6_area_lookup(area_id, ospf6); \ + oa = ospf6_area_lookup(_area_id, ospf6); \ if (oa == NULL) \ - oa = ospf6_area_create(area_id, ospf6, format); \ + oa = ospf6_area_create(_area_id, ospf6, _format); \ } /* prototypes */ diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 8fa85badbe..df2758b081 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1899,7 +1899,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate) break; case DEFAULT_ORIGINATE_ZEBRA: zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - zclient, AFI_IP6, ospf6->vrf_id); + ospf6_zclient, AFI_IP6, ospf6->vrf_id); ospf6_asbr_redistribute_remove(DEFAULT_ROUTE, 0, (struct prefix *)&p, ospf6); @@ -1915,7 +1915,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate) break; case DEFAULT_ORIGINATE_ZEBRA: zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - zclient, AFI_IP6, ospf6->vrf_id); + ospf6_zclient, AFI_IP6, ospf6->vrf_id); break; case DEFAULT_ORIGINATE_ALWAYS: diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index 6379f9d992..0b00558572 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -27,8 +27,6 @@ #include "ospf6_zebra.h" #include "ospf6_bfd.h" -extern struct zclient *zclient; - /* * ospf6_bfd_trigger_event - Neighbor is registered/deregistered with BFD when * neighbor state is changed to/from 2way. @@ -280,7 +278,7 @@ DEFUN (no_ipv6_ospf6_bfd, void ospf6_bfd_init(void) { - bfd_protocol_integration_init(zclient, master); + bfd_protocol_integration_init(ospf6_zclient, master); /* Install BFD command */ install_element(INTERFACE_NODE, &ipv6_ospf6_bfd_cmd); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 8320f11f6c..e94f2a1c47 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -104,9 +104,9 @@ static void __attribute__((noreturn)) ospf6_exit(int status) vrf_terminate(); - if (zclient) { - zclient_stop(zclient); - zclient_free(zclient); + if (ospf6_zclient) { + zclient_stop(ospf6_zclient); + zclient_free(ospf6_zclient); } ospf6_master_delete(); diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 9ac8b6c1af..037ca9bc0b 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -1382,9 +1382,9 @@ static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state, } /* Register OSPFv3-MIB. */ -static int ospf6_snmp_init(struct event_loop *master) +static int ospf6_snmp_init(struct event_loop *mstr) { - smux_init(master); + smux_init(mstr); REGISTER_MIB("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid); return 0; } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index ad487f3565..9755cc44cc 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -142,20 +142,20 @@ static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set) "%s: setting redist vrf %d bitmap for type %d", __func__, ospf6->vrf_id, type); if (set) - vrf_bitmap_set(&zclient->redist[AFI_IP6][type], + vrf_bitmap_set(&ospf6_zclient->redist[AFI_IP6][type], ospf6->vrf_id); else - vrf_bitmap_unset(&zclient->redist[AFI_IP6][type], + vrf_bitmap_unset(&ospf6_zclient->redist[AFI_IP6][type], ospf6->vrf_id); } red_list = ospf6->redist[DEFAULT_ROUTE]; if (red_list) { if (set) - vrf_bitmap_set(&zclient->default_information[AFI_IP6], + vrf_bitmap_set(&ospf6_zclient->default_information[AFI_IP6], ospf6->vrf_id); else - vrf_bitmap_unset(&zclient->default_information[AFI_IP6], + vrf_bitmap_unset(&ospf6_zclient->default_information[AFI_IP6], ospf6->vrf_id); } } @@ -566,13 +566,13 @@ static void ospf6_disable(struct ospf6 *o) } } -void ospf6_master_init(struct event_loop *master) +void ospf6_master_init(struct event_loop *mst) { memset(&ospf6_master, 0, sizeof(ospf6_master)); om6 = &ospf6_master; om6->ospf6 = list_new(); - om6->master = master; + om6->master = mst; } void ospf6_master_delete(void) diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 8288413c10..2b29eeae89 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -231,7 +231,6 @@ DECLARE_QOBJ_TYPE(ospf6); #define OSPF6_STUB_ROUTER 0x02 /* global pointer for OSPF top data structure */ -extern struct ospf6 *ospf6; extern struct ospf6_master *om6; /* prototypes */ diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 466301309f..cfb9bc1c11 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -36,11 +36,11 @@ DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance"); unsigned char conf_debug_ospf6_zebra = 0; /* information about zebra. */ -struct zclient *zclient = NULL; +struct zclient *ospf6_zclient = NULL; void ospf6_zebra_vrf_register(struct ospf6 *ospf6) { - if (!zclient || zclient->sock < 0 || !ospf6) + if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6) return; if (ospf6->vrf_id != VRF_UNKNOWN) { @@ -49,13 +49,13 @@ void ospf6_zebra_vrf_register(struct ospf6 *ospf6) ospf6_vrf_id_to_name(ospf6->vrf_id), ospf6->vrf_id); } - zclient_send_reg_requests(zclient, ospf6->vrf_id); + zclient_send_reg_requests(ospf6_zclient, ospf6->vrf_id); } } void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6) { - if (!zclient || zclient->sock < 0 || !ospf6) + if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6) return; if (ospf6->vrf_id != VRF_DEFAULT && ospf6->vrf_id != VRF_UNKNOWN) { @@ -67,7 +67,7 @@ void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6) } /* Deregister for router-id, interfaces, * redistributed routes. */ - zclient_send_dereg_requests(zclient, ospf6->vrf_id); + zclient_send_dereg_requests(ospf6_zclient, ospf6->vrf_id); } } @@ -98,22 +98,22 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) /* redistribute function */ void ospf6_zebra_redistribute(int type, vrf_id_t vrf_id) { - if (vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id)) + if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id)) return; - vrf_bitmap_set(&zclient->redist[AFI_IP6][type], vrf_id); + vrf_bitmap_set(&ospf6_zclient->redist[AFI_IP6][type], vrf_id); - if (zclient->sock > 0) - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, + if (ospf6_zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ospf6_zclient, AFI_IP6, type, 0, vrf_id); } void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id) { - if (!vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id)) + if (!vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id)) return; - vrf_bitmap_unset(&zclient->redist[AFI_IP6][type], vrf_id); - if (zclient->sock > 0) - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + vrf_bitmap_unset(&ospf6_zclient->redist[AFI_IP6][type], vrf_id); + if (ospf6_zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ospf6_zclient, AFI_IP6, type, 0, vrf_id); } @@ -122,7 +122,7 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg) struct prefix prefix = {}; int command; - if (zclient->sock < 0) { + if (ospf6_zclient->sock < 0) { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug(" Not connected to Zebra"); return; @@ -141,7 +141,7 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg) zserv_command_string(command), &prefix, ospf6->vrf_id); - if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false, + if (zclient_send_rnh(ospf6_zclient, command, &prefix, SAFI_UNICAST, false, true, ospf6->vrf_id) == ZCLIENT_SEND_FAILURE) flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed", @@ -216,7 +216,7 @@ static int ospf6_zebra_gr_update(struct ospf6 *ospf6, int command, { struct zapi_cap api; - if (!zclient || zclient->sock < 0 || !ospf6) + if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6) return 1; memset(&api, 0, sizeof(api)); @@ -224,7 +224,7 @@ static int ospf6_zebra_gr_update(struct ospf6 *ospf6, int command, api.stale_removal_time = stale_time; api.vrf_id = ospf6->vrf_id; - (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, + (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, ospf6_zclient, &api); return 0; @@ -313,7 +313,7 @@ DEFUN(show_zebra, json_object *json_zebra; json_object *json_array; - if (zclient == NULL) { + if (ospf6_zclient == NULL) { vty_out(vty, "Not connected to zebra\n"); return CMD_SUCCESS; } @@ -323,13 +323,13 @@ DEFUN(show_zebra, json_zebra = json_object_new_object(); json_array = json_object_new_array(); - json_object_int_add(json_zebra, "fail", zclient->fail); + json_object_int_add(json_zebra, "fail", ospf6_zclient->fail); json_object_int_add( json_zebra, "redistributeDefault", - vrf_bitmap_check(&zclient->default_information[AFI_IP6], + vrf_bitmap_check(&ospf6_zclient->default_information[AFI_IP6], VRF_DEFAULT)); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (vrf_bitmap_check(&zclient->redist[AFI_IP6][i], + if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][i], VRF_DEFAULT)) json_object_array_add( json_array, @@ -342,13 +342,13 @@ DEFUN(show_zebra, vty_json(vty, json); } else { vty_out(vty, "Zebra Information\n"); - vty_out(vty, " fail: %d\n", zclient->fail); + vty_out(vty, " fail: %d\n", ospf6_zclient->fail); vty_out(vty, " redistribute default: %d\n", - vrf_bitmap_check(&zclient->default_information[AFI_IP6], + vrf_bitmap_check(&ospf6_zclient->default_information[AFI_IP6], VRF_DEFAULT)); vty_out(vty, " redistribute:"); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (vrf_bitmap_check(&zclient->redist[AFI_IP6][i], + if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][i], VRF_DEFAULT)) vty_out(vty, " %s", zebra_route_string(i)); } @@ -403,7 +403,7 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request, zlog_debug("Zebra Send %s route: %pFX", (type == REM ? "remove" : "add"), &request->prefix); - if (zclient->sock < 0) { + if (ospf6_zclient->sock < 0) { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug(" Not connected to Zebra"); return; @@ -487,9 +487,9 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request, ospf6_zebra_append_opaque_attr(request, &api); if (type == REM) - ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + ret = zclient_route_send(ZEBRA_ROUTE_DELETE, ospf6_zclient, &api); else - ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + ret = zclient_route_send(ZEBRA_ROUTE_ADD, ospf6_zclient, &api); if (ret == ZCLIENT_SEND_FAILURE) flog_err(EC_LIB_ZAPI_SOCKET, @@ -552,7 +552,7 @@ void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6) api.prefix = *dest; zapi_route_set_blackhole(&api, BLACKHOLE_NULL); - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, ospf6_zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug("Zebra: Route add discard %pFX", dest); @@ -589,7 +589,7 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request, api.prefix = *dest; zapi_route_set_blackhole(&api, BLACKHOLE_NULL); - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, ospf6_zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug("Zebra: Route delete discard %pFX", dest); @@ -758,14 +758,14 @@ static zclient_handler *const ospf6_handlers[] = { [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route, }; -void ospf6_zebra_init(struct event_loop *master) +void ospf6_zebra_init(struct event_loop *mst) { /* Allocate zebra structure. */ - zclient = zclient_new(master, &zclient_options_default, ospf6_handlers, - array_size(ospf6_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs); - zclient->zebra_connected = ospf6_zebra_connected; - zclient->nexthop_update = ospf6_zebra_import_check_update; + ospf6_zclient = zclient_new(mst, &zclient_options_default, ospf6_handlers, + array_size(ospf6_handlers)); + zclient_init(ospf6_zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs); + ospf6_zclient->zebra_connected = ospf6_zebra_connected; + ospf6_zclient->nexthop_update = ospf6_zebra_import_check_update; /* Install command element for zebra node. */ install_element(VIEW_NODE, &show_ospf6_zebra_cmd); diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h index 7669b5e2c0..0ad86e8c9a 100644 --- a/ospf6d/ospf6_zebra.h +++ b/ospf6d/ospf6_zebra.h @@ -27,7 +27,7 @@ struct ospf6_distance { char *access_list; }; -extern struct zclient *zclient; +extern struct zclient *ospf6_zclient; struct ospf6; extern void ospf6_zebra_route_update_add(struct ospf6_route *request, @@ -38,7 +38,7 @@ extern void ospf6_zebra_route_update_remove(struct ospf6_route *request, extern void ospf6_zebra_redistribute(int, vrf_id_t vrf_id); extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id); #define ospf6_zebra_is_redistribute(type, vrf_id) \ - vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id) + vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id) extern void ospf6_zebra_init(struct event_loop *tm); extern void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg); extern void ospf6_zebra_add_discard(struct ospf6_route *request, diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index e4e0354fc9..ddb8a461d5 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -1408,13 +1408,13 @@ static void install_element_ospf6_debug_event(void) } /* Install ospf related commands. */ -void ospf6_init(struct event_loop *master) +void ospf6_init(struct event_loop *mst) { ospf6_top_init(); ospf6_area_init(); ospf6_interface_init(); ospf6_neighbor_init(); - ospf6_zebra_init(master); + ospf6_zebra_init(mst); ospf6_lsa_init(); ospf6_spf_init(); diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c index 24ff08561d..315da6bb0a 100644 --- a/ospfclient/ospfclient.c +++ b/ospfclient/ospfclient.c @@ -54,7 +54,7 @@ struct zebra_privs_t ospfd_privs = {.user = NULL, struct event_loop *master; /* Global variables */ -struct ospf_apiclient *oclient; +struct ospf_apiclient *g_oclient; char **args; /* Our opaque LSAs have the following format. */ @@ -209,13 +209,13 @@ static void ready_callback(uint8_t lsa_type, uint8_t opaque_type, lsa_type, opaque_type, &addr); /* Schedule opaque LSA originate in 5 secs */ - event_add_timer(master, lsa_inject, oclient, 5, NULL); + event_add_timer(master, lsa_inject, g_oclient, 5, NULL); /* Schedule opaque LSA update with new value */ - event_add_timer(master, lsa_inject, oclient, 10, NULL); + event_add_timer(master, lsa_inject, g_oclient, 10, NULL); /* Schedule delete */ - event_add_timer(master, lsa_delete, oclient, 30, NULL); + event_add_timer(master, lsa_delete, g_oclient, 30, NULL); } static void new_if_callback(struct in_addr ifaddr, struct in_addr area_id) @@ -296,27 +296,27 @@ int main(int argc, char *argv[]) master = event_master_create(NULL); /* Open connection to OSPF daemon */ - oclient = ospf_apiclient_connect(args[1], ASYNCPORT); - if (!oclient) { + g_oclient = ospf_apiclient_connect(args[1], ASYNCPORT); + if (!g_oclient) { printf("Connecting to OSPF daemon on %s failed!\n", args[1]); exit(1); } /* Register callback functions. */ ospf_apiclient_register_callback( - oclient, ready_callback, new_if_callback, del_if_callback, + g_oclient, ready_callback, new_if_callback, del_if_callback, ism_change_callback, nsm_change_callback, lsa_update_callback, lsa_delete_callback); /* Register LSA type and opaque type. */ - ospf_apiclient_register_opaque_type(oclient, atoi(args[2]), + ospf_apiclient_register_opaque_type(g_oclient, atoi(args[2]), atoi(args[3])); /* Synchronize database with OSPF daemon. */ - ospf_apiclient_sync_lsdb(oclient); + ospf_apiclient_sync_lsdb(g_oclient); /* Schedule thread that handles asynchronous messages */ - event_add_read(master, lsa_read, oclient, oclient->fd_async, NULL); + event_add_read(master, lsa_read, g_oclient, g_oclient->fd_async, NULL); /* Now connection is established, run loop */ while (1) { diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index 7d4c7c06b8..ceab63540e 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -312,7 +312,7 @@ DEFUN (no_ip_ospf_bfd, void ospf_bfd_init(struct event_loop *tm) { - bfd_protocol_integration_init(zclient, tm); + bfd_protocol_integration_init(ospf_zclient, tm); /* Install BFD command */ install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index bcb35315d8..6184d1352c 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -33,8 +33,6 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" -extern struct zclient *zclient; - /** @brief Function to refresh type-5 and type-7 DNA * LSAs when we receive an indication LSA. * @param Ospf instance. @@ -172,11 +170,11 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, redist_on = is_default_prefix4(&p) ? vrf_bitmap_check( - &zclient->default_information[AFI_IP], + &ospf_zclient->default_information[AFI_IP], ospf->vrf_id) - : (zclient->mi_redist[AFI_IP][type].enabled || + : (ospf_zclient->mi_redist[AFI_IP][type].enabled || vrf_bitmap_check( - &zclient->redist[AFI_IP][type], + &ospf_zclient->redist[AFI_IP][type], ospf->vrf_id)); // Pending: check for MI above. if (redist_on) { diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index 496ae5b4bd..99f81f5663 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -28,8 +28,6 @@ #include "ospf_dump.h" #include "ospf_ism.h" -extern struct zclient *zclient; - /* * LDP-SYNC msg between IGP and LDP */ @@ -98,8 +96,8 @@ void ospf_ldp_sync_state_req_msg(struct interface *ifp) request.proto = LDP_IGP_SYNC_IF_STATE_REQUEST; request.ifindex = ifp->ifindex; - zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST, - (uint8_t *)&request, sizeof(request)); + zclient_send_opaque(ospf_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST, + (uint8_t *)&request, sizeof(request)); } /* @@ -400,9 +398,9 @@ void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove) */ if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { /* unregister with opaque client to recv LDP-IGP Sync msgs */ - zclient_unregister_opaque(zclient, + zclient_unregister_opaque(ospf_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); - zclient_unregister_opaque(zclient, + zclient_unregister_opaque(ospf_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); /* disable LDP globally */ @@ -754,8 +752,8 @@ DEFPY (ospf_mpls_ldp_sync, } /* register with opaque client to recv LDP-IGP Sync msgs */ - zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); - zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); + zclient_register_opaque(ospf_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); + zclient_register_opaque(ospf_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); if (!CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { SET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index d35f0a1372..13bf947994 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -4055,11 +4055,11 @@ void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) * ignored. */ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && !oi->p2mp_non_broadcast) { - struct ospf_lsa_list_entry *ls_ack_list_entry; + struct ospf_lsa_list_entry *ack_list_entry; struct ospf_lsa *ack_queue_lsa; - frr_each (ospf_lsa_list, &oi->ls_ack_direct, ls_ack_list_entry) { - ack_queue_lsa = ls_ack_list_entry->lsa; + frr_each (ospf_lsa_list, &oi->ls_ack_direct, ack_list_entry) { + ack_queue_lsa = ack_list_entry->lsa; if ((lsa == ack_queue_lsa) || ((lsa->data->type == ack_queue_lsa->data->type) && (lsa->data->id.s_addr == diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index b6f432b1bb..d187485b9f 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -1709,15 +1709,15 @@ static int ospf_te_export(uint8_t type, void *link_state) switch (type) { case LS_MSG_TYPE_NODE: ls_vertex2msg(&msg, (struct ls_vertex *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(ospf_zclient, &msg, NULL); break; case LS_MSG_TYPE_ATTRIBUTES: ls_edge2msg(&msg, (struct ls_edge *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(ospf_zclient, &msg, NULL); break; case LS_MSG_TYPE_PREFIX: ls_subnet2msg(&msg, (struct ls_subnet *)link_state); - rc = ls_send_msg(zclient, &msg, NULL); + rc = ls_send_msg(ospf_zclient, &msg, NULL); break; default: rc = -1; @@ -3113,7 +3113,7 @@ int ospf_te_sync_ted(struct zapi_opaque_reg_info dst) if (!OspfMplsTE.enabled || !OspfMplsTE.export) return rc; - rc = ls_sync_ted(OspfMplsTE.ted, zclient, &dst); + rc = ls_sync_ted(OspfMplsTE.ted, ospf_zclient, &dst); return rc; } @@ -4306,7 +4306,7 @@ DEFUN (ospf_mpls_te_export, VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); if (OspfMplsTE.enabled) { - if (ls_register(zclient, true) != 0) { + if (ls_register(ospf_zclient, true) != 0) { vty_out(vty, "Unable to register Link State\n"); return CMD_WARNING; } @@ -4330,7 +4330,7 @@ DEFUN (no_ospf_mpls_te_export, VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); if (OspfMplsTE.export) { - if (ls_unregister(zclient, true) != 0) { + if (ls_unregister(ospf_zclient, true) != 0) { vty_out(vty, "Unable to unregister Link State\n"); return CMD_WARNING; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 95e8b179d8..3263d0a5f8 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -12308,8 +12308,6 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) else vty_out(vty, " ip ospf"); - char buf[INET_ADDRSTRLEN]; - area_id2str(buf, sizeof(buf), ¶ms->if_area, params->if_area_id_fmt); vty_out(vty, " area %s", buf); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index f45135f44f..cac8a5762f 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -45,7 +45,7 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute"); /* Zebra structure to hold current status. */ -struct zclient *zclient = NULL; +struct zclient *ospf_zclient; /* and for the Synchronous connection to the Label Manager */ struct zclient *zclient_sync; @@ -342,7 +342,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, if (CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA)) ospf_zebra_append_opaque_attr(or, &api); - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, ospf_zclient, &api); } void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, @@ -368,7 +368,7 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, zlog_debug("Zebra: Route delete %pFX(%s)", p, ospf_vrf_id_to_name(ospf->vrf_id)); - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, ospf_zclient, &api); } void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) @@ -390,7 +390,7 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) memcpy(&api.prefix, p, sizeof(*p)); zapi_route_set_blackhole(&api, BLACKHOLE_NULL); - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, ospf_zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Zebra: Route add discard %pFX(%s)", p, @@ -416,7 +416,7 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) memcpy(&api.prefix, p, sizeof(*p)); zapi_route_set_blackhole(&api, BLACKHOLE_NULL); - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, ospf_zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Zebra: Route delete discard %pFX(%s)", p, @@ -695,7 +695,7 @@ void ospf_zebra_update_prefix_sid(const struct sr_prefix *srp) } /* Finally, send message to zebra. */ - (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl); + (void)zebra_send_mpls_labels(ospf_zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl); } /* Remove NHLFE for Prefix-SID */ @@ -722,7 +722,7 @@ void ospf_zebra_delete_prefix_sid(const struct sr_prefix *srp) } /* Send message to zebra. */ - (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); + (void)zebra_send_mpls_labels(ospf_zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); } /* Send MPLS Label entry to Zebra for installation or deletion */ @@ -746,7 +746,7 @@ void ospf_zebra_send_adjacency_sid(int cmd, struct sr_nhlfe nhlfe) znh->label_num = 1; znh->labels[0] = nhlfe.label_out; - (void)zebra_send_mpls_labels(zclient, cmd, &zl); + (void)zebra_send_mpls_labels(ospf_zclient, cmd, &zl); } struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, uint8_t type, @@ -815,14 +815,14 @@ int ospf_is_type_redistributed(struct ospf *ospf, int type, { return (DEFAULT_ROUTE_TYPE(type) ? vrf_bitmap_check( - &zclient->default_information[AFI_IP], + &ospf_zclient->default_information[AFI_IP], ospf->vrf_id) : ((instance && redist_check_instance( - &zclient->mi_redist[AFI_IP][type], + &ospf_zclient->mi_redist[AFI_IP][type], instance)) || (!instance && - vrf_bitmap_check(&zclient->redist[AFI_IP][type], + vrf_bitmap_check(&ospf_zclient->redist[AFI_IP][type], ospf->vrf_id)))); } @@ -861,7 +861,7 @@ int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type, ospf_external_add(ospf, type, instance); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, ospf_zclient, AFI_IP, type, instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) @@ -879,10 +879,10 @@ int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type, int ospf_redistribute_unset(struct ospf *ospf, int type, unsigned short instance) { - if (type == zclient->redist_default && instance == zclient->instance) + if (type == ospf_zclient->redist_default && instance == ospf_zclient->instance) return CMD_SUCCESS; - zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, ospf_zclient, AFI_IP, type, instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) @@ -933,7 +933,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, break; case DEFAULT_ORIGINATE_ZEBRA: zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - zclient, AFI_IP, ospf->vrf_id); + ospf_zclient, AFI_IP, ospf->vrf_id); ospf->redistribute--; break; case DEFAULT_ORIGINATE_ALWAYS: @@ -951,7 +951,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, type_str = "normal"; ospf->redistribute++; zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - zclient, AFI_IP, ospf->vrf_id); + ospf_zclient, AFI_IP, ospf->vrf_id); break; case DEFAULT_ORIGINATE_ALWAYS: type_str = "always"; @@ -1242,7 +1242,7 @@ static int ospf_zebra_gr_update(struct ospf *ospf, int command, { struct zapi_cap api; - if (!zclient || zclient->sock < 0 || !ospf) + if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf) return 1; memset(&api, 0, sizeof(api)); @@ -1250,7 +1250,7 @@ static int ospf_zebra_gr_update(struct ospf *ospf, int command, api.stale_removal_time = stale_time; api.vrf_id = ospf->vrf_id; - (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, + (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, ospf_zclient, &api); return 0; @@ -1495,7 +1495,7 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg) struct prefix prefix = {}; int command; - if (zclient->sock < 0) { + if (ospf_zclient->sock < 0) { if (IS_DEBUG_OSPF(zebra, ZEBRA)) zlog_debug(" Not connected to Zebra vrf: %s", ospf_vrf_id_to_name(ospf->vrf_id)); @@ -1515,7 +1515,7 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg) zserv_command_string(command), &prefix, ospf_vrf_id_to_name(ospf->vrf_id)); - if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false, + if (zclient_send_rnh(ospf_zclient, command, &prefix, SAFI_UNICAST, false, true, ospf->vrf_id) == ZCLIENT_SEND_FAILURE) flog_err(EC_LIB_ZAPI_SOCKET, "%s(%s): zclient_send_rnh() failed", __func__, ospf_vrf_id_to_name(ospf->vrf_id)); @@ -2011,7 +2011,7 @@ uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p, void ospf_zebra_vrf_register(struct ospf *ospf) { - if (!zclient || zclient->sock < 0 || !ospf) + if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf) return; if (ospf->vrf_id != VRF_UNKNOWN) { @@ -2019,13 +2019,13 @@ void ospf_zebra_vrf_register(struct ospf *ospf) zlog_debug("%s: Register VRF %s id %u", __func__, ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id); - zclient_send_reg_requests(zclient, ospf->vrf_id); + zclient_send_reg_requests(ospf_zclient, ospf->vrf_id); } } void ospf_zebra_vrf_deregister(struct ospf *ospf) { - if (!zclient || zclient->sock < 0 || !ospf) + if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf) return; if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) { @@ -2035,7 +2035,7 @@ void ospf_zebra_vrf_deregister(struct ospf *ospf) ospf->vrf_id); /* Deregister for router-id, interfaces, * redistributed routes. */ - zclient_send_dereg_requests(zclient, ospf->vrf_id); + zclient_send_dereg_requests(ospf_zclient, ospf->vrf_id); } } @@ -2230,17 +2230,17 @@ static zclient_handler *const ospf_handlers[] = { [ZEBRA_CLIENT_CLOSE_NOTIFY] = ospf_zebra_client_close_notify, }; -void ospf_zebra_init(struct event_loop *master, unsigned short instance) +void ospf_zebra_init(struct event_loop *mst, unsigned short instance) { /* Allocate zebra structure. */ - zclient = zclient_new(master, &zclient_options_default, ospf_handlers, - array_size(ospf_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs); - zclient->zebra_connected = ospf_zebra_connected; - zclient->nexthop_update = ospf_zebra_import_check_update; + ospf_zclient = zclient_new(mst, &zclient_options_default, ospf_handlers, + array_size(ospf_handlers)); + zclient_init(ospf_zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs); + ospf_zclient->zebra_connected = ospf_zebra_connected; + ospf_zclient->nexthop_update = ospf_zebra_import_check_update; /* Initialize special zclient for synchronous message exchanges. */ - zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0); + zclient_sync = zclient_new(mst, &zclient_options_sync, NULL, 0); zclient_sync->sock = -1; zclient_sync->redist_default = ZEBRA_ROUTE_OSPF; zclient_sync->instance = instance; @@ -2259,5 +2259,5 @@ void ospf_zebra_init(struct event_loop *master, unsigned short instance) void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p) { - zclient_send_neigh_discovery_req(zclient, ifp, p); + zclient_send_neigh_discovery_req(ospf_zclient, ifp, p); } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 90330d368d..1d2078469d 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -59,9 +59,6 @@ struct ospf_master *om; unsigned short ospf_instance; -extern struct zclient *zclient; -extern struct zclient *zclient_sync; - /* OSPF config processing timer thread */ struct event *t_ospf_cfg; @@ -648,8 +645,8 @@ void ospf_terminate(void) * One or more ospf_finish()'s may have deferred shutdown to a timer * thread */ - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(ospf_zclient); + zclient_free(ospf_zclient); zclient_stop(zclient_sync); zclient_free(zclient_sync); @@ -2214,13 +2211,13 @@ void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize, ospf_sock_bufsize_update(ospf, ospf->fd, type); } -void ospf_master_init(struct event_loop *master) +void ospf_master_init(struct event_loop *mst) { memset(&ospf_master, 0, sizeof(ospf_master)); om = &ospf_master; om->ospf = list_new(); - om->master = master; + om->master = mst; } /* Link OSPF instance to VRF. */ @@ -2273,20 +2270,20 @@ static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set) "%s: setting redist vrf %d bitmap for type %d", __func__, ospf->vrf_id, type); if (set) - vrf_bitmap_set(&zclient->redist[AFI_IP][type], + vrf_bitmap_set(&ospf_zclient->redist[AFI_IP][type], ospf->vrf_id); else - vrf_bitmap_unset(&zclient->redist[AFI_IP][type], + vrf_bitmap_unset(&ospf_zclient->redist[AFI_IP][type], ospf->vrf_id); } red_list = ospf->redist[DEFAULT_ROUTE]; if (red_list) { if (set) - vrf_bitmap_set(&zclient->default_information[AFI_IP], + vrf_bitmap_set(&ospf_zclient->default_information[AFI_IP], ospf->vrf_id); else - vrf_bitmap_unset(&zclient->default_information[AFI_IP], + vrf_bitmap_unset(&ospf_zclient->default_information[AFI_IP], ospf->vrf_id); } } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 6051dff709..460ff0f6ae 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -695,7 +695,8 @@ struct ospf_nbr_nbma { extern struct ospf_master *om; extern unsigned short ospf_instance; extern const int ospf_redistributed_proto_max; -extern struct zclient *zclient; +extern struct zclient *ospf_zclient; +extern struct zclient *zclient_sync; extern struct event_loop *master; extern int ospf_zlog; extern struct zebra_privs_t ospfd_privs; diff --git a/pathd/path_cli.c b/pathd/path_cli.c index bf8a9ea028..27236667b1 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -234,7 +234,7 @@ DEFPY_NOSH( /* * XPath: /frr-pathd:pathd/srte/segment-list */ -DEFPY_NOSH( +DEFPY_YANG_NOSH( srte_segment_list, srte_segment_list_cmd, "segment-list WORD$name", @@ -267,7 +267,7 @@ DEFPY_NOSH( return ret; } -DEFPY(srte_no_segment_list, +DEFPY_YANG(srte_no_segment_list, srte_no_segment_list_cmd, "no segment-list WORD$name", NO_STR @@ -463,7 +463,7 @@ int segment_list_has_prefix( * XPath: /frr-pathd:pathd/srte/segment-list/segment */ /* clang-format off */ -DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd, +DEFPY_YANG(srte_segment_list_segment, srte_segment_list_segment_cmd, "index (0-4294967295)$index <[mpls$has_mpls_label label (16-1048575)$label] " "|" "[nai$has_nai <" @@ -527,7 +527,7 @@ DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_segment_list_no_segment, +DEFPY_YANG(srte_segment_list_no_segment, srte_segment_list_no_segment_cmd, "no index (0-4294967295)$index", NO_STR @@ -607,7 +607,7 @@ void cli_show_srte_segment_list_segment(struct vty *vty, /* * XPath: /frr-pathd:pathd/policy */ -DEFPY_NOSH( +DEFPY_YANG_NOSH( srte_policy, srte_policy_cmd, "policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint", @@ -633,7 +633,7 @@ DEFPY_NOSH( return ret; } -DEFPY(srte_no_policy, +DEFPY_YANG(srte_no_policy, srte_no_policy_cmd, "no policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint", NO_STR @@ -670,7 +670,7 @@ void cli_show_srte_policy_end(struct vty *vty, const struct lyd_node *dnode) /* * XPath: /frr-pathd:pathd/srte/policy/name */ -DEFPY(srte_policy_name, +DEFPY_YANG(srte_policy_name, srte_policy_name_cmd, "name WORD$name", "Segment Routing Policy name\n" @@ -681,7 +681,7 @@ DEFPY(srte_policy_name, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_policy_no_name, +DEFPY_YANG(srte_policy_no_name, srte_policy_no_name_cmd, "no name [WORD]", NO_STR @@ -703,7 +703,7 @@ void cli_show_srte_policy_name(struct vty *vty, const struct lyd_node *dnode, /* * XPath: /frr-pathd:pathd/srte/policy/binding-sid */ -DEFPY(srte_policy_binding_sid, +DEFPY_YANG(srte_policy_binding_sid, srte_policy_binding_sid_cmd, "binding-sid (16-1048575)$label", "Segment Routing Policy Binding-SID\n" @@ -714,7 +714,7 @@ DEFPY(srte_policy_binding_sid, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_policy_no_binding_sid, +DEFPY_YANG(srte_policy_no_binding_sid, srte_policy_no_binding_sid_cmd, "no binding-sid [(16-1048575)]", NO_STR @@ -736,7 +736,7 @@ void cli_show_srte_policy_binding_sid(struct vty *vty, /* * XPath: /frr-pathd:pathd/srte/policy/candidate-path */ -DEFPY(srte_policy_candidate_exp, +DEFPY_YANG(srte_policy_candidate_exp, srte_policy_candidate_exp_cmd, "candidate-path preference (0-4294967295)$preference name WORD$name \ explicit segment-list WORD$list_name", @@ -760,7 +760,7 @@ DEFPY(srte_policy_candidate_exp, preference_str); } -DEFPY_NOSH( +DEFPY_YANG_NOSH( srte_policy_candidate_dyn, srte_policy_candidate_dyn_cmd, "candidate-path preference (0-4294967295)$preference name WORD$name dynamic", @@ -791,7 +791,7 @@ DEFPY_NOSH( return ret; } -DEFPY(srte_candidate_bandwidth, +DEFPY_YANG(srte_candidate_bandwidth, srte_candidate_bandwidth_cmd, "bandwidth BANDWIDTH$value [required$required]", "Define a bandwidth constraint\n" @@ -805,7 +805,7 @@ DEFPY(srte_candidate_bandwidth, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_no_bandwidth, +DEFPY_YANG(srte_candidate_no_bandwidth, srte_candidate_no_bandwidth_cmd, "no bandwidth [BANDWIDTH$value] [required$required]", NO_STR @@ -818,7 +818,7 @@ DEFPY(srte_candidate_no_bandwidth, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd, +DEFPY_YANG(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd, "affinity <exclude-any|include-any|include-all>$type BITPATTERN$value", "Affinity constraint\n" "Exclude any matching link\n" @@ -842,7 +842,7 @@ DEFPY(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd, +DEFPY_YANG(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd, "no affinity <exclude-any|include-any|include-all>$type [BITPATTERN$value]", NO_STR "Affinity constraint\n" @@ -858,7 +858,7 @@ DEFPY(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_metric, +DEFPY_YANG(srte_candidate_metric, srte_candidate_metric_cmd, "metric [bound$bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type METRIC$value [required$required] [computed$computed]", "Define a metric constraint\n" @@ -907,7 +907,7 @@ DEFPY(srte_candidate_metric, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_no_metric, +DEFPY_YANG(srte_candidate_no_metric, srte_candidate_no_metric_cmd, "no metric [bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type [METRIC$value] [required$required] [computed$computed]", NO_STR @@ -945,7 +945,7 @@ DEFPY(srte_candidate_no_metric, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_policy_no_candidate, +DEFPY_YANG(srte_policy_no_candidate, srte_policy_no_candidate_cmd, "no candidate-path\ preference (0-4294967295)$preference\ @@ -971,7 +971,7 @@ DEFPY(srte_policy_no_candidate, preference_str); } -DEFPY(srte_candidate_objfun, +DEFPY_YANG(srte_candidate_objfun, srte_candidate_objfun_cmd, "objective-function <mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>$type [required$required]", "Define an objective function constraint\n" @@ -1006,7 +1006,7 @@ DEFPY(srte_candidate_objfun, return nb_cli_apply_changes(vty, NULL); } -DEFPY(srte_candidate_no_objfun, +DEFPY_YANG(srte_candidate_no_objfun, srte_candidate_no_objfun_cmd, "no objective-function [<mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>] [required$required]", NO_STR diff --git a/pathd/path_ted.c b/pathd/path_ted.c index 0f8d3827ff..f9dff1f019 100644 --- a/pathd/path_ted.c +++ b/pathd/path_ted.c @@ -31,7 +31,7 @@ static enum zclient_send_status path_ted_link_state_sync(void); static void path_ted_timer_handler_sync(struct event *thread); static void path_ted_timer_handler_refresh(struct event *thread); -extern struct zclient *zclient; +extern struct zclient *pathd_zclient; struct ted_state ted_state_g = { .dbg = { .conf = "debug pathd mpls-te", .desc = "Pathd TED" } }; @@ -40,9 +40,9 @@ struct ted_state ted_state_g = { .dbg = { .conf = "debug pathd mpls-te", * path_path_ted public API function implementations */ -void path_ted_init(struct event_loop *master) +void path_ted_init(struct event_loop *loop) { - ted_state_g.main = master; + ted_state_g.main = loop; ted_state_g.link_state_delay_interval = TIMER_RETRY_DELAY; ted_state_g.segment_list_refresh_interval = TIMER_RETRY_DELAY; path_ted_register_vty(); @@ -82,7 +82,7 @@ uint32_t path_ted_start_importing_igp(const char *daemon_str) return 1; } - if (ls_register(zclient, false /*client*/) != 0) { + if (ls_register(pathd_zclient, false /*client*/) != 0) { PATH_TED_ERROR("%s: PATHD-TED: Unable to register Link State", __func__); ted_state_g.import = IMPORT_UNKNOWN; @@ -113,7 +113,7 @@ uint32_t path_ted_stop_importing_igp(void) uint32_t status = 0; if (ted_state_g.import != IMPORT_UNKNOWN) { - if (ls_unregister(zclient, false /*client*/) != 0) { + if (ls_unregister(pathd_zclient, false /*client*/) != 0) { PATH_TED_ERROR( "%s: PATHD-TED: Unable to unregister Link State", __func__); @@ -382,7 +382,7 @@ DEFUN (no_path_ted, ted_state_g.enabled = false; PATH_TED_DEBUG("%s: PATHD-TED: ON -> OFF", __func__); ted_state_g.import = IMPORT_UNKNOWN; - if (ls_unregister(zclient, false /*client*/) != 0) { + if (ls_unregister(pathd_zclient, false /*client*/) != 0) { vty_out(vty, "Unable to unregister Link State\n"); return CMD_WARNING; } @@ -538,7 +538,7 @@ enum zclient_send_status path_ted_link_state_sync(void) { enum zclient_send_status status; - status = ls_request_sync(zclient); + status = ls_request_sync(pathd_zclient); if (status == -1) { PATH_TED_ERROR( "%s: PATHD-TED: Opaque error asking for TED sync ", diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c index ba03315c82..1078b37dd6 100644 --- a/pathd/path_zebra.c +++ b/pathd/path_zebra.c @@ -26,7 +26,7 @@ static int path_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS); -struct zclient *zclient; +struct zclient *pathd_zclient; static struct zclient *zclient_sync; /* Event to retry synch zapi setup for label-manager */ @@ -189,7 +189,7 @@ void path_zebra_add_sr_policy(struct srte_policy *policy, segment->sid_value; policy->status = SRTE_POLICY_STATUS_GOING_UP; - (void)zebra_send_sr_policy(zclient, ZEBRA_SR_POLICY_SET, &zp); + (void)zebra_send_sr_policy(pathd_zclient, ZEBRA_SR_POLICY_SET, &zp); } /** @@ -209,7 +209,7 @@ void path_zebra_delete_sr_policy(struct srte_policy *policy) zp.segment_list.label_num = 0; policy->status = SRTE_POLICY_STATUS_DOWN; - (void)zebra_send_sr_policy(zclient, ZEBRA_SR_POLICY_DELETE, &zp); + (void)zebra_send_sr_policy(pathd_zclient, ZEBRA_SR_POLICY_DELETE, &zp); } /** @@ -351,13 +351,13 @@ static zclient_handler *const path_handlers[] = { * * @param master The master thread */ -void path_zebra_init(struct event_loop *master) +void path_zebra_init(struct event_loop *loop) { /* Initialize asynchronous zclient. */ - zclient = zclient_new(master, &zclient_options_default, path_handlers, - array_size(path_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_SRTE, 0, &pathd_privs); - zclient->zebra_connected = path_zebra_connected; + pathd_zclient = zclient_new(loop, &zclient_options_default, path_handlers, + array_size(path_handlers)); + zclient_init(pathd_zclient, ZEBRA_ROUTE_SRTE, 0, &pathd_privs); + pathd_zclient->zebra_connected = path_zebra_connected; /* Initialize special zclient for synchronous message exchanges. */ zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0); @@ -373,8 +373,8 @@ void path_zebra_init(struct event_loop *master) void path_zebra_stop(void) { - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(pathd_zclient); + zclient_free(pathd_zclient); event_cancel(&t_sync_connect); zclient_stop(zclient_sync); zclient_free(zclient_sync); diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index 277271c6b6..dc8cbc56bf 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -35,7 +35,7 @@ DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface"); /* Zebra structure to hold current status. */ -struct zclient *zclient; +struct zclient *pbr_zclient; struct pbr_interface *pbr_if_new(struct interface *ifp) { @@ -272,7 +272,7 @@ static void route_add_helper(struct zapi_route *api, struct nexthop_group nhg, } api->nexthop_num = i; - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, api); + zclient_route_send(ZEBRA_ROUTE_ADD, pbr_zclient, api); } /* @@ -342,17 +342,17 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi) switch (afi) { case AFI_IP: api.prefix.family = AF_INET; - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api); break; case AFI_IP6: api.prefix.family = AF_INET6; - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api); break; case AFI_MAX: api.prefix.family = AF_INET; - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api); api.prefix.family = AF_INET6; - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api); break; case AFI_L2VPN: DEBUGD(&pbr_dbg_zebra, @@ -403,22 +403,22 @@ static zclient_handler *const pbr_handlers[] = { void pbr_zebra_init(void) { - zclient = zclient_new(master, &zclient_options_default, pbr_handlers, - array_size(pbr_handlers)); + pbr_zclient = zclient_new(master, &zclient_options_default, pbr_handlers, + array_size(pbr_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs); - zclient->zebra_connected = zebra_connected; - zclient->nexthop_update = pbr_zebra_nexthop_update; + zclient_init(pbr_zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs); + pbr_zclient->zebra_connected = zebra_connected; + pbr_zclient->nexthop_update = pbr_zebra_nexthop_update; } void pbr_zebra_destroy(void) { - if (zclient == NULL) + if (pbr_zclient == NULL) return; - zclient_stop(zclient); - zclient_free(zclient); - zclient = NULL; + zclient_stop(pbr_zclient); + zclient_free(pbr_zclient); + pbr_zclient = NULL; } void pbr_send_rnh(struct nexthop *nhop, bool reg) @@ -454,7 +454,7 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg) break; } - if (zclient_send_rnh(zclient, command, &p, SAFI_UNICAST, false, false, + if (zclient_send_rnh(pbr_zclient, command, &p, SAFI_UNICAST, false, false, nhop->vrf_id) == ZCLIENT_SEND_FAILURE) { zlog_warn("%s: Failure to send nexthop to zebra", __func__); @@ -608,7 +608,7 @@ bool pbr_send_pbr_map(struct pbr_map_sequence *pbrms, if (!install && !is_installed) return false; - s = zclient->obuf; + s = pbr_zclient->obuf; stream_reset(s); zclient_create_header(s, @@ -621,7 +621,7 @@ bool pbr_send_pbr_map(struct pbr_map_sequence *pbrms, if (pbr_encode_pbr_map_sequence(s, pbrms, pmi->ifp)) { stream_putw_at(s, 0, stream_get_endp(s)); - zclient_send_message(zclient); + zclient_send_message(pbr_zclient); } else { DEBUGD(&pbr_dbg_zebra, "%s: %s seq %u encode failed, skipped", __func__, pbrm->name, pbrms->seqno); diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c index 92a968ef78..d53469e7cd 100644 --- a/pceplib/pcep_pcc.c +++ b/pceplib/pcep_pcc.c @@ -47,11 +47,11 @@ struct cmd_line_args { }; bool pcc_active_ = true; -pcep_session *session = NULL; -struct cmd_line_args *cmd_line_args = NULL; +pcep_session *g_session = NULL; +struct cmd_line_args *g_cmd_line_args = NULL; /* pcep_event callback variables */ bool pcep_event_condition = false; -struct pcep_event *event = NULL; +struct pcep_event *g_event = NULL; pthread_mutex_t pcep_event_mutex; pthread_cond_t pcep_event_cond_var; @@ -180,7 +180,7 @@ void handle_signal_action(int sig_number) if (sig_number == SIGINT) { pcep_log(LOG_INFO, "%s: SIGINT was caught!", __func__); pcc_active_ = false; - if (cmd_line_args->eventpoll == false) { + if (g_cmd_line_args->eventpoll == false) { pthread_mutex_lock(&pcep_event_mutex); pcep_event_condition = true; pthread_cond_signal(&pcep_event_cond_var); @@ -189,12 +189,12 @@ void handle_signal_action(int sig_number) } else if (sig_number == SIGUSR1) { pcep_log(LOG_INFO, "%s: SIGUSR1 was caught, dumping counters", __func__); - dump_pcep_session_counters(session); + dump_pcep_session_counters(g_session); pceplib_memory_dump(); } else if (sig_number == SIGUSR2) { pcep_log(LOG_INFO, "%s: SIGUSR2 was caught, reseting counters", __func__); - reset_pcep_session_counters(session); + reset_pcep_session_counters(g_session); } } @@ -377,7 +377,7 @@ void pcep_event_callback(void *cb_data, pcep_event *e) pcep_log(LOG_NOTICE, "%s: [%ld-%ld] pcep_event_callback", __func__, time(NULL), pthread_self()); pthread_mutex_lock(&pcep_event_mutex); - event = e; + g_event = e; pcep_event_condition = true; pthread_cond_signal(&pcep_event_cond_var); pthread_mutex_unlock(&pcep_event_mutex); @@ -388,14 +388,14 @@ int main(int argc, char **argv) pcep_log(LOG_NOTICE, "%s: [%ld-%ld] starting pcc_pcep example client", __func__, time(NULL), pthread_self()); - cmd_line_args = get_cmdline_args(argc, argv); - if (cmd_line_args == NULL) { + g_cmd_line_args = get_cmdline_args(argc, argv); + if (g_cmd_line_args == NULL) { return -1; } setup_signals(); - if (cmd_line_args->eventpoll == false) { + if (g_cmd_line_args->eventpoll == false) { struct pceplib_infra_config infra_config; memset(&infra_config, 0, sizeof(infra_config)); infra_config.pcep_event_func = pcep_event_callback; @@ -415,31 +415,31 @@ int main(int argc, char **argv) pcep_configuration *config = create_default_pcep_configuration(); config->pcep_msg_versioning->draft_ietf_pce_segment_routing_07 = true; - config->src_pcep_port = cmd_line_args->src_tcp_port; + config->src_pcep_port = g_cmd_line_args->src_tcp_port; config->is_tcp_auth_md5 = true; - strlcpy(config->tcp_authentication_str, cmd_line_args->tcp_md5_str, + strlcpy(config->tcp_authentication_str, g_cmd_line_args->tcp_md5_str, sizeof(config->tcp_authentication_str)); - int af = (cmd_line_args->is_ipv6 ? AF_INET6 : AF_INET); + int af = (g_cmd_line_args->is_ipv6 ? AF_INET6 : AF_INET); struct hostent *host_info = - gethostbyname2(cmd_line_args->dest_ip_str, af); + gethostbyname2(g_cmd_line_args->dest_ip_str, af); if (host_info == NULL) { pcep_log(LOG_ERR, "%s: Error getting IP address.", __func__); return -1; } - if (cmd_line_args->is_ipv6) { + if (g_cmd_line_args->is_ipv6) { struct in6_addr host_address; memcpy(&host_address, host_info->h_addr, host_info->h_length); - session = connect_pce_ipv6(config, &host_address); + g_session = connect_pce_ipv6(config, &host_address); } else { struct in_addr host_address; memcpy(&host_address, host_info->h_addr, host_info->h_length); - session = connect_pce(config, &host_address); + g_session = connect_pce(config, &host_address); } - if (session == NULL) { + if (g_session == NULL) { pcep_log(LOG_WARNING, "%s: Error in connect_pce.", __func__); destroy_pcep_configuration(config); return -1; @@ -447,12 +447,12 @@ int main(int argc, char **argv) sleep(2); - send_pce_report_message(session); + send_pce_report_message(g_session); /*send_pce_path_request_message(session);*/ /* Wait for pcep_event's either by polling the event queue or by * callback */ - if (cmd_line_args->eventpoll == true) { + if (g_cmd_line_args->eventpoll == true) { /* Poll the pcep_event queue*/ while (pcc_active_) { if (event_queue_is_empty() == false) { @@ -479,8 +479,8 @@ int main(int argc, char **argv) /* Check if we have been interrupted by SIGINT */ if (pcc_active_) { - print_queue_event(event); - destroy_pcep_event(event); + print_queue_event(g_event); + destroy_pcep_event(g_event); } pcep_event_condition = false; @@ -492,9 +492,9 @@ int main(int argc, char **argv) } pcep_log(LOG_NOTICE, "%s: Disconnecting from PCE", __func__); - disconnect_pce(session); + disconnect_pce(g_session); destroy_pcep_configuration(config); - free(cmd_line_args); + free(g_cmd_line_args); if (!destroy_pcc()) { pcep_log(LOG_NOTICE, "%s: Error stopping PCC.", __func__); diff --git a/pceplib/pcep_utils_memory.c b/pceplib/pcep_utils_memory.c index c3a2ab90cd..225c058711 100644 --- a/pceplib/pcep_utils_memory.c +++ b/pceplib/pcep_utils_memory.c @@ -44,15 +44,15 @@ void *PCEPLIB_INFRA = &pceplib_infra_mt; void *PCEPLIB_MESSAGES = &pceplib_messages_mt; /* Initialize memory function pointers and memory type pointers */ -bool pceplib_memory_initialize(void *pceplib_infra_mt, - void *pceplib_messages_mt, +bool pceplib_memory_initialize(void *infra_mt, + void *messages_mt, pceplib_malloc_func mf, pceplib_calloc_func cf, pceplib_realloc_func rf, pceplib_strdup_func sf, pceplib_free_func ff) { - PCEPLIB_INFRA = (pceplib_infra_mt ? pceplib_infra_mt : PCEPLIB_INFRA); + PCEPLIB_INFRA = (infra_mt ? infra_mt : PCEPLIB_INFRA); PCEPLIB_MESSAGES = - (pceplib_messages_mt ? pceplib_messages_mt : PCEPLIB_MESSAGES); + (messages_mt ? messages_mt : PCEPLIB_MESSAGES); mfunc = (mf ? mf : mfunc); cfunc = (cf ? cf : cfunc); diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index 8297911828..ad11bb1822 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -999,6 +999,20 @@ DEFPY (interface_no_ipv6_mroute, source_str); } +DEFPY_YANG(interface_ipv6_pim_use_source, + interface_ipv6_pim_use_source_cmd, + "[no] ipv6 pim use-source X:X::X:X$source", + NO_STR + IPV6_STR + PIM_STR + "Configure primary IPv6 address\n" + "Source IPv6 address\n") +{ + nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, no ? "::" : source_str); + + return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv6"); +} + DEFPY (pim6_rp, pim6_rp_cmd, "rp X:X::X:X$rp [X:X::X:X/M]$gp", @@ -2972,6 +2986,8 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_ipv6_mld_limits_cmd); install_element(INTERFACE_NODE, &no_interface_ipv6_mld_limits_cmd); + install_element(INTERFACE_NODE, &interface_ipv6_pim_use_source_cmd); + /* Install BSM command */ install_element(INTERFACE_NODE, &ipv6_pim_bsm_cmd); install_element(INTERFACE_NODE, &no_ipv6_pim_bsm_cmd); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index f838c401e3..2dcea57051 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3181,7 +3181,7 @@ DEFPY (clear_ip_mroute_count, return clear_ip_mroute_count_command(vty, name); } -DEFPY(clear_ip_msdp_peer, clear_ip_msdp_peer_cmd, +DEFPY_YANG(clear_ip_msdp_peer, clear_ip_msdp_peer_cmd, "clear ip msdp peer A.B.C.D$peer [vrf WORD$vrfname]", CLEAR_STR IP_STR @@ -3399,7 +3399,7 @@ DEFPY_NOSH (router_pim, return CMD_SUCCESS; } -DEFPY (no_router_pim, +DEFPY_YANG (no_router_pim, no_router_pim_cmd, "no router pim [vrf NAME]", NO_STR @@ -3424,7 +3424,7 @@ DEFPY (no_router_pim, } -DEFPY (pim_spt_switchover_infinity, +DEFPY_YANG (pim_spt_switchover_infinity, pim_spt_switchover_infinity_cmd, "spt-switchover infinity-and-beyond", "SPT-Switchover\n" @@ -3632,7 +3632,7 @@ DEFPY_ATTR(no_ip_pim_spt_switchover_infinity_plist, return ret; } -DEFPY (pim_register_accept_list, +DEFPY_YANG (pim_register_accept_list, pim_register_accept_list_cmd, "[no] register-accept-list PREFIXLIST4_NAME$word", NO_STR @@ -4237,7 +4237,7 @@ DEFPY (no_ip_igmp_group_watermark, return CMD_SUCCESS; } -DEFPY (pim_v6_secondary, +DEFPY_YANG (pim_v6_secondary, pim_v6_secondary_cmd, "send-v6-secondary", "Send v6 secondary addresses\n") @@ -4297,7 +4297,7 @@ DEFPY_ATTR(ip_pim_v6_secondary, return ret; } -DEFPY (no_pim_v6_secondary, +DEFPY_YANG (no_pim_v6_secondary, no_pim_v6_secondary_cmd, "no send-v6-secondary", NO_STR @@ -4716,7 +4716,7 @@ DEFPY (pim_bsr_candidate_rp_group, return pim_process_bsr_crp_grp_cmd(vty, group_str, no); } -DEFPY (pim_ssm_prefix_list, +DEFPY_YANG (pim_ssm_prefix_list, pim_ssm_prefix_list_cmd, "ssm prefix-list PREFIXLIST4_NAME$plist", "Source Specific Multicast\n" @@ -4776,7 +4776,7 @@ DEFPY_ATTR(ip_pim_ssm_prefix_list, return ret; } -DEFPY (no_pim_ssm_prefix_list, +DEFPY_YANG (no_pim_ssm_prefix_list, no_pim_ssm_prefix_list_cmd, "no ssm prefix-list", NO_STR @@ -4836,7 +4836,7 @@ DEFPY_ATTR(no_ip_pim_ssm_prefix_list, return ret; } -DEFPY (no_pim_ssm_prefix_list_name, +DEFPY_YANG (no_pim_ssm_prefix_list_name, no_pim_ssm_prefix_list_name_cmd, "no ssm prefix-list PREFIXLIST4_NAME$plist", NO_STR @@ -5128,7 +5128,7 @@ DEFPY_ATTR(no_ip_pim_ssmpingd, return ret; } -DEFPY (pim_ecmp, +DEFPY_YANG (pim_ecmp, pim_ecmp_cmd, "ecmp", "Enable PIM ECMP \n") @@ -5183,7 +5183,7 @@ DEFPY_ATTR(ip_pim_ecmp, return ret; } -DEFPY (no_pim_ecmp, +DEFPY_YANG (no_pim_ecmp, no_pim_ecmp_cmd, "no ecmp", NO_STR @@ -5240,7 +5240,7 @@ DEFPY_ATTR(no_ip_pim_ecmp, return ret; } -DEFPY (pim_ecmp_rebalance, +DEFPY_YANG (pim_ecmp_rebalance, pim_ecmp_rebalance_cmd, "ecmp rebalance", "Enable PIM ECMP \n" @@ -5306,7 +5306,7 @@ DEFPY_ATTR(ip_pim_ecmp_rebalance, return ret; } -DEFPY (no_pim_ecmp_rebalance, +DEFPY_YANG (no_pim_ecmp_rebalance, no_pim_ecmp_rebalance_cmd, "no ecmp rebalance", NO_STR @@ -5368,7 +5368,7 @@ DEFPY_ATTR(no_ip_pim_ecmp_rebalance, return ret; } -DEFUN (interface_ip_igmp, +DEFUN_YANG (interface_ip_igmp, interface_ip_igmp_cmd, "ip igmp", IP_STR @@ -5380,7 +5380,7 @@ DEFUN (interface_ip_igmp, "frr-routing:ipv4"); } -DEFUN (interface_no_ip_igmp, +DEFUN_YANG (interface_no_ip_igmp, interface_no_ip_igmp_cmd, "no ip igmp", NO_STR @@ -5464,7 +5464,7 @@ DEFPY_YANG (interface_ip_igmp_static_group, (src_str ? src_str : "0.0.0.0")); } -DEFUN (interface_ip_igmp_query_interval, +DEFUN_YANG (interface_ip_igmp_query_interval, interface_ip_igmp_query_interval_cmd, "ip igmp query-interval (1-65535)", IP_STR @@ -5494,7 +5494,7 @@ DEFUN (interface_ip_igmp_query_interval, "frr-routing:ipv4"); } -DEFUN (interface_no_ip_igmp_query_interval, +DEFUN_YANG (interface_no_ip_igmp_query_interval, interface_no_ip_igmp_query_interval_cmd, "no ip igmp query-interval [(1-65535)]", NO_STR @@ -5509,7 +5509,7 @@ DEFUN (interface_no_ip_igmp_query_interval, "frr-routing:ipv4"); } -DEFUN (interface_ip_igmp_version, +DEFUN_YANG (interface_ip_igmp_version, interface_ip_igmp_version_cmd, "ip igmp version (2-3)", IP_STR @@ -5526,7 +5526,7 @@ DEFUN (interface_ip_igmp_version, "frr-routing:ipv4"); } -DEFUN (interface_no_ip_igmp_version, +DEFUN_YANG (interface_no_ip_igmp_version, interface_no_ip_igmp_version_cmd, "no ip igmp version (2-3)", NO_STR @@ -5541,7 +5541,7 @@ DEFUN (interface_no_ip_igmp_version, "frr-routing:ipv4"); } -DEFPY (interface_ip_igmp_query_max_response_time, +DEFPY_YANG (interface_ip_igmp_query_max_response_time, interface_ip_igmp_query_max_response_time_cmd, "ip igmp query-max-response-time (1-65535)$qmrt", IP_STR @@ -5552,7 +5552,7 @@ DEFPY (interface_ip_igmp_query_max_response_time, return gm_process_query_max_response_time_cmd(vty, qmrt_str); } -DEFUN (interface_no_ip_igmp_query_max_response_time, +DEFUN_YANG (interface_no_ip_igmp_query_max_response_time, interface_no_ip_igmp_query_max_response_time_cmd, "no ip igmp query-max-response-time [(1-65535)]", NO_STR @@ -5564,7 +5564,7 @@ DEFUN (interface_no_ip_igmp_query_max_response_time, return gm_process_no_query_max_response_time_cmd(vty); } -DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec, +DEFUN_YANG_HIDDEN (interface_ip_igmp_query_max_response_time_dsec, interface_ip_igmp_query_max_response_time_dsec_cmd, "ip igmp query-max-response-time-dsec (1-65535)", IP_STR @@ -5594,7 +5594,7 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec, "frr-routing:ipv4"); } -DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec, +DEFUN_YANG_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec, interface_no_ip_igmp_query_max_response_time_dsec_cmd, "no ip igmp query-max-response-time-dsec [(1-65535)]", NO_STR @@ -5904,7 +5904,7 @@ DEFPY (interface_no_ip_pim, } /* boundaries */ -DEFUN(interface_ip_pim_boundary_oil, +DEFUN_YANG(interface_ip_pim_boundary_oil, interface_ip_pim_boundary_oil_cmd, "ip multicast boundary oil WORD", IP_STR @@ -5916,7 +5916,7 @@ DEFUN(interface_ip_pim_boundary_oil, return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg); } -DEFUN(interface_no_ip_pim_boundary_oil, +DEFUN_YANG(interface_no_ip_pim_boundary_oil, interface_no_ip_pim_boundary_oil_cmd, "no ip multicast boundary oil [WORD]", NO_STR @@ -6653,7 +6653,7 @@ DEFUN_NOSH (show_debugging_pim, return CMD_SUCCESS; } -DEFUN (interface_pim_use_source, +DEFUN_YANG (interface_pim_use_source, interface_pim_use_source_cmd, "ip pim use-source A.B.C.D", IP_STR @@ -6668,7 +6668,7 @@ DEFUN (interface_pim_use_source, "frr-routing:ipv4"); } -DEFUN (interface_no_pim_use_source, +DEFUN_YANG (interface_no_pim_use_source, interface_no_pim_use_source_cmd, "no ip pim use-source [A.B.C.D]", NO_STR @@ -6684,7 +6684,7 @@ DEFUN (interface_no_pim_use_source, "frr-routing:ipv4"); } -DEFPY (ip_pim_bfd, +DEFPY_YANG (ip_pim_bfd, ip_pim_bfd_cmd, "ip pim bfd [profile BFDPROF$prof]", IP_STR @@ -6717,7 +6717,7 @@ DEFPY (ip_pim_bfd, "frr-routing:ipv4"); } -DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd, +DEFPY_YANG(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd, "no ip pim bfd profile [BFDPROF]", NO_STR IP_STR @@ -6733,7 +6733,7 @@ DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd, "frr-routing:ipv4"); } -DEFUN (no_ip_pim_bfd, +DEFUN_YANG (no_ip_pim_bfd, no_ip_pim_bfd_cmd, "no ip pim bfd", NO_STR @@ -6748,7 +6748,7 @@ DEFUN (no_ip_pim_bfd, "frr-routing:ipv4"); } -DEFUN (ip_pim_bsm, +DEFUN_YANG (ip_pim_bsm, ip_pim_bsm_cmd, "ip pim bsm", IP_STR @@ -6757,7 +6757,7 @@ DEFUN (ip_pim_bsm, { return pim_process_bsm_cmd(vty); } -DEFUN (no_ip_pim_bsm, +DEFUN_YANG (no_ip_pim_bsm, no_ip_pim_bsm_cmd, "no ip pim bsm", NO_STR @@ -6768,7 +6768,7 @@ DEFUN (no_ip_pim_bsm, return pim_process_no_bsm_cmd(vty); } -DEFUN (ip_pim_ucast_bsm, +DEFUN_YANG (ip_pim_ucast_bsm, ip_pim_ucast_bsm_cmd, "ip pim unicast-bsm", IP_STR @@ -6778,7 +6778,7 @@ DEFUN (ip_pim_ucast_bsm, return pim_process_unicast_bsm_cmd(vty); } -DEFUN (no_ip_pim_ucast_bsm, +DEFUN_YANG (no_ip_pim_ucast_bsm, no_ip_pim_ucast_bsm_cmd, "no ip pim unicast-bsm", NO_STR @@ -6790,7 +6790,7 @@ DEFUN (no_ip_pim_ucast_bsm, } #if HAVE_BFDD > 0 -DEFUN_HIDDEN ( +DEFUN_YANG_HIDDEN ( ip_pim_bfd_param, ip_pim_bfd_param_cmd, "ip pim bfd (2-255) (1-65535) (1-65535)", @@ -6801,7 +6801,7 @@ DEFUN_HIDDEN ( "Required min receive interval\n" "Desired min transmit interval\n") #else - DEFUN( + DEFUN_YANG( ip_pim_bfd_param, ip_pim_bfd_param_cmd, "ip pim bfd (2-255) (1-65535) (1-65535)", @@ -6855,7 +6855,7 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd, "Desired min transmit interval\n") #endif /* !HAVE_BFDD */ -DEFPY(pim_msdp_peer, pim_msdp_peer_cmd, +DEFPY_YANG(pim_msdp_peer, pim_msdp_peer_cmd, "msdp peer A.B.C.D$peer source A.B.C.D$source", CFG_MSDP_STR "Configure MSDP peer\n" @@ -6920,7 +6920,7 @@ DEFPY_ATTR(ip_pim_msdp_peer, return ret; } -DEFPY(msdp_peer_md5, msdp_peer_md5_cmd, +DEFPY_YANG(msdp_peer_md5, msdp_peer_md5_cmd, "msdp peer A.B.C.D$peer password WORD$psk", CFG_MSDP_STR "Configure MSDP peer\n" @@ -6945,7 +6945,7 @@ DEFPY(msdp_peer_md5, msdp_peer_md5_cmd, return nb_cli_apply_changes(vty, "%s", xpath); } -DEFPY(no_msdp_peer_md5, no_msdp_peer_md5_cmd, +DEFPY_YANG(no_msdp_peer_md5, no_msdp_peer_md5_cmd, "no msdp peer A.B.C.D$peer password [WORD]", NO_STR CFG_MSDP_STR @@ -6971,7 +6971,7 @@ DEFPY(no_msdp_peer_md5, no_msdp_peer_md5_cmd, return nb_cli_apply_changes(vty, "%s", xpath); } -DEFPY(pim_msdp_timers, pim_msdp_timers_cmd, +DEFPY_YANG(pim_msdp_timers, pim_msdp_timers_cmd, "msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]", CFG_MSDP_STR "MSDP timers configuration\n" @@ -7046,7 +7046,7 @@ DEFPY_ATTR(ip_pim_msdp_timers, return ret; } -DEFPY(no_pim_msdp_timers, no_pim_msdp_timers_cmd, +DEFPY_YANG(no_pim_msdp_timers, no_pim_msdp_timers_cmd, "no msdp timers [(1-65535) (1-65535) [(1-65535)]]", NO_STR CFG_MSDP_STR @@ -7110,7 +7110,7 @@ DEFPY_ATTR(no_ip_pim_msdp_timers, return ret; } -DEFPY (no_pim_msdp_peer, +DEFPY_YANG (no_pim_msdp_peer, no_pim_msdp_peer_cmd, "no msdp peer A.B.C.D", NO_STR @@ -7172,7 +7172,7 @@ DEFPY_ATTR(no_ip_pim_msdp_peer, return ret; } -DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd, +DEFPY_YANG(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd, "msdp peer A.B.C.D$peer sa-filter ACL_NAME$acl_name <in|out>$dir", CFG_MSDP_STR "Configure MSDP peer\n" @@ -7203,7 +7203,7 @@ DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd, return nb_cli_apply_changes(vty, "%s", xpath); } -DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd, +DEFPY_YANG(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd, "no msdp peer A.B.C.D$peer sa-filter ACL_NAME <in|out>$dir", NO_STR CFG_MSDP_STR @@ -7235,7 +7235,7 @@ DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd, return nb_cli_apply_changes(vty, "%s", xpath); } -DEFPY(pim_msdp_mesh_group_member, +DEFPY_YANG(pim_msdp_mesh_group_member, pim_msdp_mesh_group_member_cmd, "msdp mesh-group WORD$gname member A.B.C.D$maddr", CFG_MSDP_STR @@ -7313,7 +7313,7 @@ DEFPY_ATTR(ip_pim_msdp_mesh_group_member, return ret; } -DEFPY(no_pim_msdp_mesh_group_member, +DEFPY_YANG(no_pim_msdp_mesh_group_member, no_pim_msdp_mesh_group_member_cmd, "no msdp mesh-group WORD$gname member A.B.C.D$maddr", NO_STR @@ -7432,7 +7432,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group_member, return ret; } -DEFPY(pim_msdp_mesh_group_source, +DEFPY_YANG(pim_msdp_mesh_group_source, pim_msdp_mesh_group_source_cmd, "msdp mesh-group WORD$gname source A.B.C.D$saddr", CFG_MSDP_STR @@ -7505,7 +7505,7 @@ DEFPY_ATTR(ip_pim_msdp_mesh_group_source, return ret; } -DEFPY(no_pim_msdp_mesh_group_source, +DEFPY_YANG(no_pim_msdp_mesh_group_source, no_pim_msdp_mesh_group_source_cmd, "no msdp mesh-group WORD$gname source [A.B.C.D]", NO_STR @@ -7593,7 +7593,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group_source, return ret; } -DEFPY(no_pim_msdp_mesh_group, +DEFPY_YANG(no_pim_msdp_mesh_group, no_pim_msdp_mesh_group_cmd, "no msdp mesh-group WORD$gname", NO_STR @@ -7661,7 +7661,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group, return ret; } -DEFPY(msdp_shutdown, +DEFPY_YANG(msdp_shutdown, msdp_shutdown_cmd, "[no] msdp shutdown", NO_STR @@ -7679,7 +7679,7 @@ DEFPY(msdp_shutdown, return nb_cli_apply_changes(vty, NULL); } -DEFPY(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd, +DEFPY_YANG(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd, "[no] msdp peer A.B.C.D$peer sa-limit ![(1-4294967294)$sa_limit]", NO_STR CFG_MSDP_STR @@ -7702,7 +7702,7 @@ DEFPY(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd, return nb_cli_apply_changes(vty, "%s", xpath); } -DEFPY(msdp_originator_id, msdp_originator_id_cmd, +DEFPY_YANG(msdp_originator_id, msdp_originator_id_cmd, "[no] msdp originator-id ![A.B.C.D$originator_id]", NO_STR CFG_MSDP_STR @@ -8448,7 +8448,7 @@ DEFUN (show_ip_msdp_sa_sg_vrf_all, return CMD_SUCCESS; } -DEFPY(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd, +DEFPY_YANG(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd, "[no] msdp log neighbor-events", NO_STR MSDP_STR @@ -8463,7 +8463,7 @@ DEFPY(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(msdp_log_sa_changes, msdp_log_sa_changes_cmd, +DEFPY_YANG(msdp_log_sa_changes, msdp_log_sa_changes_cmd, "[no] msdp log sa-events", NO_STR MSDP_STR @@ -8751,7 +8751,7 @@ DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work, return CMD_SUCCESS; } -DEFPY_HIDDEN (no_pim_mlag, +DEFPY_YANG_HIDDEN (no_pim_mlag, no_pim_mlag_cmd, "no mlag", NO_STR @@ -8808,7 +8808,7 @@ DEFPY_ATTR(no_ip_pim_mlag, return ret; } -DEFPY_HIDDEN (pim_mlag, +DEFPY_YANG_HIDDEN (pim_mlag, pim_mlag_cmd, "mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr", "MLAG\n" diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 877470e461..510ca398ff 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -147,6 +147,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool gm, bool pim, pim_ifp->pim_enable = pim; pim_ifp->pim_passive_enable = false; pim_ifp->gm_enable = gm; + pim_ifp->gm_proxy = false; pim_ifp->gm_join_list = NULL; pim_ifp->static_group_list = NULL; @@ -194,8 +195,17 @@ void pim_if_delete(struct interface *ifp) assert(pim_ifp); pim_ifp->pim->mcast_if_count--; - if (pim_ifp->gm_join_list) + if (pim_ifp->gm_join_list) { pim_if_gm_join_del_all(ifp); + /* + * Sometimes gm_join_del_all does not delete them all + * and as such it's not actually freed. Let's + * just clean this up if it wasn't to prevent + * the problem. + */ + if (pim_ifp->gm_join_list) + list_delete(&pim_ifp->gm_join_list); + } if (pim_ifp->static_group_list) pim_if_static_group_del_all(ifp); @@ -1436,10 +1446,8 @@ int pim_if_gm_join_del(struct interface *ifp, pim_addr group_addr, } listnode_delete(pim_ifp->gm_join_list, ij); gm_join_free(ij); - if (listcount(pim_ifp->gm_join_list) < 1) { + if (listcount(pim_ifp->gm_join_list) < 1) list_delete(&pim_ifp->gm_join_list); - pim_ifp->gm_join_list = 0; - } return 0; } diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c index dcef2d0d33..3b4e71ecf4 100644 --- a/pimd/pim_mlag.c +++ b/pimd/pim_mlag.c @@ -15,7 +15,7 @@ #include "pim_upstream.h" #include "pim_vxlan.h" -extern struct zclient *zclient; +extern struct zclient *pim_zclient; #define PIM_MLAG_METADATA_LEN 4 @@ -925,7 +925,7 @@ static void pim_mlag_register_handler(struct event *thread) { uint32_t bit_mask = 0; - if (!zclient) + if (!pim_zclient) return; SET_FLAG(bit_mask, (1 << MLAG_STATUS_UPDATE)); @@ -942,7 +942,7 @@ static void pim_mlag_register_handler(struct event *thread) zlog_debug("%s: Posting Client Register to MLAG mask: 0x%x", __func__, bit_mask); - zclient_send_mlag_register(zclient, bit_mask); + zclient_send_mlag_register(pim_zclient, bit_mask); } void pim_mlag_register(void) @@ -958,14 +958,14 @@ void pim_mlag_register(void) static void pim_mlag_deregister_handler(struct event *thread) { - if (!zclient) + if (!pim_zclient) return; if (PIM_DEBUG_MLAG) zlog_debug("%s: Posting Client De-Register to MLAG from PIM", __func__); router->connected_to_mlag = false; - zclient_send_mlag_deregister(zclient); + zclient_send_mlag_deregister(pim_zclient); } void pim_mlag_deregister(void) diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 1e9ea24b26..d97b56e4d6 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -780,7 +780,6 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr, */ struct pim_zlookup_nexthop nexthop_tab[router->multipath]; ifindex_t i; - struct interface *ifp = NULL; int num_ifindex; memset(nexthop_tab, 0, sizeof(nexthop_tab)); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index e4603ff946..aed9d2be90 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1624,8 +1624,7 @@ void pim_upstream_set_sptbit(struct pim_upstream *up, if (!starup || up->rpf.source_nexthop .interface != starup->rpf.source_nexthop.interface) { - struct pim_upstream *starup = up->parent; - + starup = up->parent; if (PIM_DEBUG_PIM_TRACE) zlog_debug( "%s: %s RPF_interface(S) != RPF_interface(RP(G))", diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index f0ec3c6b6e..1f7e2b255f 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -38,7 +38,7 @@ #undef PIM_DEBUG_IFADDR_DUMP #define PIM_DEBUG_IFADDR_DUMP -struct zclient *zclient; +struct zclient *pim_zclient; /* Router-id update message from zebra. */ @@ -349,16 +349,16 @@ static void pim_zebra_vxlan_replay(void) struct stream *s = NULL; /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!pim_zclient || pim_zclient->sock < 0) return; - s = zclient->obuf; + s = pim_zclient->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_VXLAN_SG_REPLAY, VRF_DEFAULT); stream_putw_at(s, 0, stream_get_endp(s)); - zclient_send_message(zclient); + zclient_send_message(pim_zclient); } void pim_scan_oil(struct pim_instance *pim) @@ -448,14 +448,14 @@ static zclient_handler *const pim_handlers[] = { void pim_zebra_init(void) { /* Socket for receiving updates from Zebra daemon */ - zclient = zclient_new(router->master, &zclient_options_default, - pim_handlers, array_size(pim_handlers)); + pim_zclient = zclient_new(router->master, &zclient_options_default, + pim_handlers, array_size(pim_handlers)); - zclient->zebra_capabilities = pim_zebra_capabilities; - zclient->zebra_connected = pim_zebra_connected; - zclient->nexthop_update = pim_nexthop_update; + pim_zclient->zebra_capabilities = pim_zebra_capabilities; + pim_zclient->zebra_connected = pim_zebra_connected; + pim_zclient->nexthop_update = pim_nexthop_update; - zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs); + zclient_init(pim_zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs); if (PIM_DEBUG_PIM_TRACE) { zlog_notice("%s: zclient socket initialized", __func__); } @@ -508,8 +508,8 @@ void pim_zebra_zclient_update(struct vty *vty) { vty_out(vty, "Zclient update socket: "); - if (zclient) { - vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail); + if (pim_zclient) { + vty_out(vty, "%d failures=%d\n", pim_zclient->sock, pim_zclient->fail); } else { vty_out(vty, "<null zclient>\n"); } @@ -517,8 +517,8 @@ void pim_zebra_zclient_update(struct vty *vty) struct zclient *pim_zebra_zclient_get(void) { - if (zclient) - return zclient; + if (pim_zclient) + return pim_zclient; else return NULL; } @@ -526,5 +526,5 @@ struct zclient *pim_zebra_zclient_get(void) void pim_zebra_interface_set_master(struct interface *vrf, struct interface *ifp) { - zclient_interface_set_master(zclient, vrf, ifp); + zclient_interface_set_master(pim_zclient, vrf, ifp); } diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 4ffb5bac17..b8f73f9183 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -26,7 +26,7 @@ #include "pim_zlookup.h" #include "pim_addr.h" -static struct zclient *zlookup = NULL; +static struct zclient *pim_zlookup = NULL; struct event *zlookup_read; static void zclient_lookup_sched(struct zclient *zlookup, int delay); @@ -115,25 +115,25 @@ static void zclient_lookup_failed(struct zclient *zlookup) void zclient_lookup_free(void) { EVENT_OFF(zlookup_read); - zclient_stop(zlookup); - zclient_free(zlookup); - zlookup = NULL; + zclient_stop(pim_zlookup); + zclient_free(pim_zlookup); + pim_zlookup = NULL; } void zclient_lookup_new(void) { - zlookup = zclient_new(router->master, &zclient_options_sync, NULL, 0); - if (!zlookup) { + pim_zlookup = zclient_new(router->master, &zclient_options_sync, NULL, 0); + if (!pim_zlookup) { flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure", __func__); return; } - zlookup->sock = -1; - zlookup->t_connect = NULL; - zlookup->privs = &pimd_privs; + pim_zlookup->sock = -1; + pim_zlookup->t_connect = NULL; + pim_zlookup->privs = &pimd_privs; - zclient_lookup_sched_now(zlookup); + zclient_lookup_sched_now(pim_zlookup); zlog_notice("%s: zclient lookup socket initialized", __func__); } @@ -328,11 +328,11 @@ static int zclient_rib_lookup(struct pim_instance *pim, struct pim_zlookup_nexth (safi == SAFI_MULTICAST ? "M" : "U")); /* Check socket. */ - if (zlookup->sock < 0) { + if (pim_zlookup->sock < 0) { flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient lookup socket is not connected", __func__); - zclient_lookup_failed(zlookup); + zclient_lookup_failed(pim_zlookup); return -1; } @@ -346,31 +346,31 @@ static int zclient_rib_lookup(struct pim_instance *pim, struct pim_zlookup_nexth ipaddr.ipa_type = PIM_IPADDR; ipaddr.ipaddr_pim = addr; - s = zlookup->obuf; + s = pim_zlookup->obuf; stream_reset(s); zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP, pim->vrf->vrf_id); stream_put_ipaddr(s, &ipaddr); stream_putc(s, safi); stream_putw_at(s, 0, stream_get_endp(s)); - ret = writen(zlookup->sock, s->data, stream_get_endp(s)); + ret = writen(pim_zlookup->sock, s->data, stream_get_endp(s)); if (ret < 0) { flog_err( EC_LIB_SOCKET, "%s: writen() failure: %d writing to zclient lookup socket", __func__, errno); - zclient_lookup_failed(zlookup); + zclient_lookup_failed(pim_zlookup); return -2; } if (ret == 0) { flog_err_sys(EC_LIB_SOCKET, "%s: connection closed on zclient lookup socket", __func__); - zclient_lookup_failed(zlookup); + zclient_lookup_failed(pim_zlookup); return -3; } - return zclient_read_nexthop(pim, zlookup, nexthop_tab, tab_size, addr); + return zclient_read_nexthop(pim, pim_zlookup, nexthop_tab, tab_size, addr); } static int zclient_lookup_nexthop_once(struct pim_instance *pim, @@ -562,8 +562,8 @@ int zclient_lookup_nexthop(struct pim_instance *pim, struct pim_zlookup_nexthop void pim_zlookup_show_ip_multicast(struct vty *vty) { vty_out(vty, "Zclient lookup socket: "); - if (zlookup) { - vty_out(vty, "%d failures=%d\n", zlookup->sock, zlookup->fail); + if (pim_zlookup) { + vty_out(vty, "%d failures=%d\n", pim_zlookup->sock, pim_zlookup->fail); } else { vty_out(vty, "<null zclient>\n"); } @@ -571,7 +571,7 @@ void pim_zlookup_show_ip_multicast(struct vty *vty) int pim_zlookup_sg_statistics(struct channel_oil *c_oil) { - struct stream *s = zlookup->obuf; + struct stream *s = pim_zlookup->obuf; uint16_t command = 0; unsigned long long lastused; pim_sgaddr sg; @@ -602,7 +602,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) stream_putw_at(s, 0, stream_get_endp(s)); count = stream_get_endp(s); - ret = writen(zlookup->sock, s->data, count); + ret = writen(pim_zlookup->sock, s->data, count); if (ret <= 0) { flog_err( EC_LIB_SOCKET, @@ -611,7 +611,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) return -1; } - s = zlookup->ibuf; + s = pim_zlookup->ibuf; while (command != ZEBRA_IPMR_ROUTE_STATS) { int err; @@ -621,12 +621,12 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) uint8_t version; stream_reset(s); - err = zclient_read_header(s, zlookup->sock, &length, &marker, + err = zclient_read_header(s, pim_zlookup->sock, &length, &marker, &version, &vrf_id, &command); if (err < 0) { flog_err(EC_LIB_ZAPI_MISSMATCH, "%s: zclient_read_header() failed", __func__); - zclient_lookup_failed(zlookup); + zclient_lookup_failed(pim_zlookup); return -1; } } @@ -642,7 +642,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) EC_LIB_ZAPI_MISSMATCH, "%s: Received wrong %pSG(%s) information requested", __func__, &more, c_oil->pim->vrf->name); - zclient_lookup_failed(zlookup); + zclient_lookup_failed(pim_zlookup); return -3; } diff --git a/pimd/pim_zpthread.c b/pimd/pim_zpthread.c index d6b2621ff4..45d8868808 100644 --- a/pimd/pim_zpthread.c +++ b/pimd/pim_zpthread.c @@ -13,7 +13,7 @@ #include "pim_mlag.h" #include "pim_zebra.h" -extern struct zclient *zclient; +extern struct zclient *pim_zclient; #define PIM_MLAG_POST_LIMIT 100 @@ -96,7 +96,7 @@ static void pim_mlag_zebra_flush_buffer(void) } } - zclient_send_mlag_data(zclient, router->mlag_stream); + zclient_send_mlag_data(pim_zclient, router->mlag_stream); stream_failure: stream_reset(router->mlag_stream); mlag_bulk_cnt = 0; diff --git a/ripd/rip_bfd.c b/ripd/rip_bfd.c index b59db11a30..a1529d1360 100644 --- a/ripd/rip_bfd.c +++ b/ripd/rip_bfd.c @@ -15,7 +15,7 @@ DEFINE_MTYPE(RIPD, RIP_BFD_PROFILE, "RIP BFD profile name"); -extern struct zclient *zclient; +extern struct zclient *ripd_zclient; static const char *rip_bfd_interface_profile(struct rip_interface *ri) { @@ -117,5 +117,5 @@ void rip_bfd_instance_update(struct rip *rip) void rip_bfd_init(struct event_loop *tm) { - bfd_protocol_integration_init(zclient, tm); + bfd_protocol_integration_init(ripd_zclient, tm); } diff --git a/ripd/rip_main.c b/ripd/rip_main.c index cfe4a7e437..431e967131 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -94,6 +94,7 @@ static void sigint(void) rip_zclient_stop(); route_map_finish(); + prefix_list_reset(); keychain_terminate(); frr_fini(); diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c index f6a7a82831..118b08e527 100644 --- a/ripd/rip_snmp.c +++ b/ripd/rip_snmp.c @@ -553,11 +553,11 @@ static uint8_t *rip2PeerTable(struct variable *v, oid name[], size_t *length, } /* Register RIPv2-MIB. */ -static int rip_snmp_init(struct event_loop *master) +static int rip_snmp_init(struct event_loop *mstr) { rip_ifaddr_table = route_table_init(); - smux_init(master); + smux_init(mstr); REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid); return 0; } diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index ce94e8e754..4ba63e50e4 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -21,7 +21,7 @@ #include "ripd/rip_interface.h" /* All information about zebra. */ -struct zclient *zclient = NULL; +struct zclient *ripd_zclient = NULL; /* Send ECMP routes to zebra. */ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp, @@ -72,7 +72,7 @@ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp, api.tag = rinfo->tag; } - zclient_route_send(cmd, zclient, &api); + zclient_route_send(cmd, ripd_zclient, &api); if (IS_RIP_DEBUG_ZEBRA) { if (rip->ecmp) @@ -137,14 +137,14 @@ static int rip_zebra_read_route(ZAPI_CALLBACK_ARGS) void rip_redistribute_conf_update(struct rip *rip, int type) { - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripd_zclient, AFI_IP, type, 0, rip->vrf->vrf_id); } void rip_redistribute_conf_delete(struct rip *rip, int type) { - if (zclient->sock > 0) - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + if (ripd_zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripd_zclient, AFI_IP, type, 0, rip->vrf->vrf_id); /* Remove the routes from RIP table. */ @@ -162,7 +162,7 @@ void rip_redistribute_enable(struct rip *rip) if (!rip_redistribute_check(rip, i)) continue; - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripd_zclient, AFI_IP, i, 0, rip->vrf->vrf_id); } } @@ -173,7 +173,7 @@ void rip_redistribute_disable(struct rip *rip) if (!rip_redistribute_check(rip, i)) continue; - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripd_zclient, AFI_IP, i, 0, rip->vrf->vrf_id); } } @@ -181,7 +181,7 @@ void rip_redistribute_disable(struct rip *rip) void rip_show_redistribute_config(struct vty *vty, struct rip *rip) { for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (i == zclient->redist_default + if (i == ripd_zclient->redist_default || !rip_redistribute_check(rip, i)) continue; @@ -198,8 +198,8 @@ void rip_zebra_vrf_register(struct vrf *vrf) zlog_debug("%s: register VRF %s(%u) to zebra", __func__, vrf->name, vrf->vrf_id); - zclient_send_reg_requests(zclient, vrf->vrf_id); - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf->vrf_id); + zclient_send_reg_requests(ripd_zclient, vrf->vrf_id); + bfd_client_sendmsg(ripd_zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf->vrf_id); } void rip_zebra_vrf_deregister(struct vrf *vrf) @@ -211,8 +211,8 @@ void rip_zebra_vrf_deregister(struct vrf *vrf) zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__, vrf->name, vrf->vrf_id); - zclient_send_dereg_requests(zclient, vrf->vrf_id); - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_DEREGISTER, vrf->vrf_id); + zclient_send_dereg_requests(ripd_zclient, vrf->vrf_id); + bfd_client_sendmsg(ripd_zclient, ZEBRA_BFD_CLIENT_DEREGISTER, vrf->vrf_id); } static void rip_zebra_connected(struct zclient *zclient) @@ -233,18 +233,18 @@ static void rip_zebra_capabilities(struct zclient_capabilities *cap) zebra_ecmp_count = MIN(cap->ecmp, zebra_ecmp_count); } -void rip_zclient_init(struct event_loop *master) +void rip_zclient_init(struct event_loop *mst) { /* Set default value to the zebra client structure. */ - zclient = zclient_new(master, &zclient_options_default, rip_handlers, - array_size(rip_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs); - zclient->zebra_connected = rip_zebra_connected; - zclient->zebra_capabilities = rip_zebra_capabilities; + ripd_zclient = zclient_new(mst, &zclient_options_default, rip_handlers, + array_size(rip_handlers)); + zclient_init(ripd_zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs); + ripd_zclient->zebra_connected = rip_zebra_connected; + ripd_zclient->zebra_capabilities = rip_zebra_capabilities; } void rip_zclient_stop(void) { - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(ripd_zclient); + zclient_free(ripd_zclient); } diff --git a/ripd/ripd.c b/ripd/ripd.c index 2d038507ab..c850df52ec 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -282,8 +282,14 @@ struct rip_info *rip_ecmp_replace(struct rip *rip, struct rip_info *rinfo_new) */ struct rip_info *rip_ecmp_delete(struct rip *rip, struct rip_info *rinfo) { - struct route_node *rp = rinfo->rp; - struct list *list = (struct list *)rp->info; + struct route_node *rp; + struct list *list; + + if (rinfo == NULL) + return NULL; + + rp = rinfo->rp; + list = (struct list *)rp->info; EVENT_OFF(rinfo->t_timeout); diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index bb5a880c02..87e275ad0d 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -19,7 +19,7 @@ #include "ripngd/ripng_debug.h" /* All information about zebra. */ -struct zclient *zclient = NULL; +struct zclient *ripng_zclient = NULL; /* Send ECMP routes to zebra. */ static void ripng_zebra_ipv6_send(struct ripng *ripng, struct agg_node *rp, @@ -67,7 +67,7 @@ static void ripng_zebra_ipv6_send(struct ripng *ripng, struct agg_node *rp, api.tag = rinfo->tag; } - zclient_route_send(cmd, zclient, &api); + zclient_route_send(cmd, ripng_zclient, &api); if (IS_RIPNG_DEBUG_ZEBRA) { if (ripng->ecmp) @@ -137,14 +137,14 @@ static int ripng_zebra_read_route(ZAPI_CALLBACK_ARGS) void ripng_redistribute_conf_update(struct ripng *ripng, int type) { - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripng_zclient, AFI_IP6, type, 0, ripng->vrf->vrf_id); } void ripng_redistribute_conf_delete(struct ripng *ripng, int type) { - if (zclient->sock > 0) - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + if (ripng_zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripng_zclient, AFI_IP6, type, 0, ripng->vrf->vrf_id); ripng_redistribute_withdraw(ripng, type); @@ -161,7 +161,7 @@ void ripng_redistribute_enable(struct ripng *ripng) if (!ripng_redistribute_check(ripng, i)) continue; - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripng_zclient, AFI_IP6, i, 0, ripng->vrf->vrf_id); } } @@ -172,7 +172,7 @@ void ripng_redistribute_disable(struct ripng *ripng) if (!ripng_redistribute_check(ripng, i)) continue; - zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripng_zclient, AFI_IP6, i, 0, ripng->vrf->vrf_id); } } @@ -182,7 +182,7 @@ void ripng_redistribute_write(struct vty *vty, struct ripng *ripng) int i; for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (i == zclient->redist_default + if (i == ripng_zclient->redist_default || !ripng_redistribute_check(ripng, i)) continue; @@ -199,7 +199,7 @@ void ripng_zebra_vrf_register(struct vrf *vrf) zlog_debug("%s: register VRF %s(%u) to zebra", __func__, vrf->name, vrf->vrf_id); - zclient_send_reg_requests(zclient, vrf->vrf_id); + zclient_send_reg_requests(ripng_zclient, vrf->vrf_id); } void ripng_zebra_vrf_deregister(struct vrf *vrf) @@ -211,7 +211,7 @@ void ripng_zebra_vrf_deregister(struct vrf *vrf) zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__, vrf->name, vrf->vrf_id); - zclient_send_dereg_requests(zclient, vrf->vrf_id); + zclient_send_dereg_requests(ripng_zclient, vrf->vrf_id); } static void ripng_zebra_connected(struct zclient *zclient) @@ -232,19 +232,19 @@ static void ripng_zebra_capabilities(struct zclient_capabilities *cap) } /* Initialize zebra structure and it's commands. */ -void zebra_init(struct event_loop *master) +void zebra_init(struct event_loop *mst) { /* Allocate zebra structure. */ - zclient = zclient_new(master, &zclient_options_default, ripng_handlers, - array_size(ripng_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs); + ripng_zclient = zclient_new(mst, &zclient_options_default, ripng_handlers, + array_size(ripng_handlers)); + zclient_init(ripng_zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs); - zclient->zebra_connected = ripng_zebra_connected; - zclient->zebra_capabilities = ripng_zebra_capabilities; + ripng_zclient->zebra_connected = ripng_zebra_connected; + ripng_zclient->zebra_capabilities = ripng_zebra_capabilities; } void ripng_zebra_stop(void) { - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(ripng_zclient); + zclient_free(ripng_zclient); } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 4447b69bf6..3a0877f8e8 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -23,7 +23,7 @@ #include "sharp_zebra.h" /* Zebra structure to hold current status. */ -struct zclient *zclient = NULL; +struct zclient *g_zclient = NULL; /* For registering threads. */ extern struct event_loop *master; @@ -34,23 +34,23 @@ extern struct zebra_privs_t sharp_privs; DEFINE_MTYPE_STATIC(SHARPD, ZC, "Test zclients"); /* Struct to hold list of test zclients */ -struct sharp_zclient { - struct sharp_zclient *prev; - struct sharp_zclient *next; +struct sharp_zclient_entry { + struct sharp_zclient_entry *prev; + struct sharp_zclient_entry *next; struct zclient *client; }; /* Head of test zclient list */ -static struct sharp_zclient *sharp_clients_head; +static struct sharp_zclient_entry *sharp_clients_head; static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS); /* Utility to add a test zclient struct to the list */ static void add_zclient(struct zclient *client) { - struct sharp_zclient *node; + struct sharp_zclient_entry *node; - node = XCALLOC(MTYPE_ZC, sizeof(struct sharp_zclient)); + node = XCALLOC(MTYPE_ZC, sizeof(struct sharp_zclient_entry)); node->client = client; @@ -198,7 +198,7 @@ int sharp_install_lsps_helper(bool install_p, bool update_p, cmd = ZEBRA_MPLS_LABELS_DELETE; } - if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE) + if (zebra_send_mpls_labels(g_zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE) return -1; return 0; @@ -291,7 +291,7 @@ static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance, memcpy(api.opaque.data, opaque, api.opaque.length); } - if (zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api) == + if (zclient_route_send(ZEBRA_ROUTE_ADD, g_zclient, &api) == ZCLIENT_SEND_BUFFERED) return true; else @@ -315,7 +315,7 @@ static bool route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance) api.instance = instance; memcpy(&api.prefix, p, sizeof(*p)); - if (zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api) == + if (zclient_route_send(ZEBRA_ROUTE_DELETE, g_zclient, &api) == ZCLIENT_SEND_BUFFERED) return true; else @@ -471,7 +471,7 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) enum zapi_route_notify_owner note; uint32_t table; - if (!zapi_route_notify_decode(zclient->ibuf, &p, &table, ¬e, NULL, + if (!zapi_route_notify_decode(g_zclient->ibuf, &p, &table, ¬e, NULL, NULL)) return -1; @@ -526,7 +526,7 @@ static void zebra_connected(struct zclient *zclient) void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) { - zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); + zclient_send_vrf_label(g_zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); } void nhg_add(uint32_t id, const struct nexthop_group *nhg, @@ -565,7 +565,7 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg, if (sharp_nhgroup_id_is_installed(id)) { zlog_debug("%s: nhg %u: no nexthops, deleting nexthop group", __func__, id); - zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg); + zclient_nhg_send(g_zclient, ZEBRA_NHG_DEL, &api_nhg); return; } zlog_debug("%s: nhg %u not sent: no valid nexthops", __func__, @@ -606,7 +606,7 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg, done: if (is_valid) - zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg); + zclient_nhg_send(g_zclient, ZEBRA_NHG_ADD, &api_nhg); } void nhg_del(uint32_t id) @@ -615,7 +615,7 @@ void nhg_del(uint32_t id) api_nhg.id = id; - zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg); + zclient_nhg_send(g_zclient, ZEBRA_NHG_DEL, &api_nhg); } void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import, bool watch, @@ -629,7 +629,7 @@ void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import, b if (!watch) command = ZEBRA_NEXTHOP_UNREGISTER; - if (zclient_send_rnh(zclient, command, p, safi, connected, false, vrf_id) == + if (zclient_send_rnh(g_zclient, command, p, safi, connected, false, vrf_id) == ZCLIENT_SEND_FAILURE) zlog_warn("%s: Failure to send nexthop to zebra", __func__); } @@ -709,7 +709,7 @@ void sharp_redistribute_vrf(struct vrf *vrf, int type, bool turn_on) { zebra_redistribute_send(turn_on ? ZEBRA_REDISTRIBUTE_ADD : ZEBRA_REDISTRIBUTE_DELETE, - zclient, AFI_IP, type, 0, vrf->vrf_id); + g_zclient, AFI_IP, type, 0, vrf->vrf_id); } static zclient_handler *const sharp_opaque_handlers[] = { @@ -720,7 +720,7 @@ static zclient_handler *const sharp_opaque_handlers[] = { int sharp_zclient_create(uint32_t session_id) { struct zclient *client; - struct sharp_zclient *node; + struct sharp_zclient_entry *node; /* Check for duplicates */ for (node = sharp_clients_head; node != NULL; node = node->next) { @@ -745,7 +745,7 @@ int sharp_zclient_create(uint32_t session_id) /* Delete one of the extra test zclients */ int sharp_zclient_delete(uint32_t session_id) { - struct sharp_zclient *node; + struct sharp_zclient_entry *node; /* Search for session */ for (node = sharp_clients_head; node != NULL; node = node->next) { @@ -848,10 +848,10 @@ void sharp_opaque_send(uint32_t type, uint32_t proto, uint32_t instance, /* Send some messages - broadcast and unicast are supported */ for (i = 0; i < count; i++) { if (proto == 0) - ret = zclient_send_opaque(zclient, type, buf, + ret = zclient_send_opaque(g_zclient, type, buf, sizeof(buf)); else - ret = zclient_send_opaque_unicast(zclient, type, proto, + ret = zclient_send_opaque_unicast(g_zclient, type, proto, instance, session_id, buf, sizeof(buf)); if (ret == ZCLIENT_SEND_FAILURE) { @@ -868,9 +868,9 @@ void sharp_opaque_send(uint32_t type, uint32_t proto, uint32_t instance, void sharp_zebra_opaque_notif_reg(bool is_reg, uint32_t type) { if (is_reg) - zclient_opaque_request_notify(zclient, type); + zclient_opaque_request_notify(g_zclient, type); else - zclient_opaque_drop_notify(zclient, type); + zclient_opaque_drop_notify(g_zclient, type); } /* @@ -881,7 +881,7 @@ void sharp_opaque_reg_send(bool is_reg, uint32_t proto, uint32_t instance, { struct stream *s; - s = zclient->obuf; + s = g_zclient->obuf; stream_reset(s); if (is_reg) @@ -900,22 +900,22 @@ void sharp_opaque_reg_send(bool is_reg, uint32_t proto, uint32_t instance, /* Put length at the first point of the stream. */ stream_putw_at(s, 0, stream_get_endp(s)); - (void)zclient_send_message(zclient); + (void)zclient_send_message(g_zclient); } /* Link State registration */ void sharp_zebra_register_te(void) { /* First register to received Link State Update messages */ - zclient_register_opaque(zclient, LINK_STATE_UPDATE); + zclient_register_opaque(g_zclient, LINK_STATE_UPDATE); /* Then, request initial TED with SYNC message */ - ls_request_sync(zclient); + ls_request_sync(g_zclient); } void sharp_zebra_send_arp(const struct interface *ifp, const struct prefix *p) { - zclient_send_neigh_discovery_req(zclient, ifp, p); + zclient_send_neigh_discovery_req(g_zclient, ifp, p); } static int nhg_notify_owner(ZAPI_CALLBACK_ARGS) @@ -948,12 +948,12 @@ static int nhg_notify_owner(ZAPI_CALLBACK_ARGS) int sharp_zebra_srv6_manager_get_locator_chunk(const char *locator_name) { - return srv6_manager_get_locator_chunk(zclient, locator_name); + return srv6_manager_get_locator_chunk(g_zclient, locator_name); } int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name) { - return srv6_manager_release_locator_chunk(zclient, locator_name); + return srv6_manager_release_locator_chunk(g_zclient, locator_name); } static int sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) @@ -1031,7 +1031,7 @@ int sharp_zebra_send_interface_protodown(struct interface *ifp, bool down) zlog_debug("Sending zebra to set %s protodown %s", ifp->name, down ? "on" : "off"); - if (zclient_send_interface_protodown(zclient, ifp->vrf->vrf_id, ifp, + if (zclient_send_interface_protodown(g_zclient, ifp->vrf->vrf_id, ifp, down) == ZCLIENT_SEND_FAILURE) return -1; @@ -1047,12 +1047,12 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp, #define SHARPD_TC_HANDLE 0x0001 struct stream *s; - s = zclient->obuf; + s = g_zclient->obuf; struct tc_qdisc q = {.ifindex = ifp->ifindex, .kind = TC_QDISC_HTB}; zapi_tc_qdisc_encode(ZEBRA_TC_QDISC_INSTALL, s, &q); - if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE) + if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE) return -1; struct tc_class c = {.ifindex = ifp->ifindex, @@ -1062,7 +1062,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp, .u.htb.rate = rate}; zapi_tc_class_encode(ZEBRA_TC_CLASS_ADD, s, &c); - if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE) + if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE) return -1; struct tc_filter f = {.ifindex = ifp->ifindex, @@ -1090,7 +1090,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp, f.u.flower.classid = SHARPD_TC_HANDLE & 0xffff; zapi_tc_filter_encode(ZEBRA_TC_FILTER_ADD, s, &f); - if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE) + if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE) return -1; return 0; @@ -1098,7 +1098,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp, void sharp_zebra_register_neigh(vrf_id_t vrf_id, afi_t afi, bool reg) { - zclient_register_neigh(zclient, vrf_id, afi, reg); + zclient_register_neigh(g_zclient, vrf_id, afi, reg); } @@ -1124,18 +1124,18 @@ void sharp_zebra_init(void) hook_register_prio(if_down, 0, sharp_ifp_down); hook_register_prio(if_unreal, 0, sharp_ifp_destroy); - zclient = zclient_new(master, &zclient_options_default, sharp_handlers, - array_size(sharp_handlers)); + g_zclient = zclient_new(master, &zclient_options_default, sharp_handlers, + array_size(sharp_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); - zclient->zebra_connected = zebra_connected; - zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready; - zclient->nexthop_update = sharp_nexthop_update; + zclient_init(g_zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); + g_zclient->zebra_connected = zebra_connected; + g_zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready; + g_zclient->nexthop_update = sharp_nexthop_update; } void sharp_zebra_terminate(void) { - struct sharp_zclient *node = sharp_clients_head; + struct sharp_zclient_entry *node = sharp_clients_head; while (node) { sharp_zclient_delete(node->client->session_id); @@ -1143,6 +1143,6 @@ void sharp_zebra_terminate(void) node = sharp_clients_head; } - zclient_stop(zclient); - zclient_free(zclient); + zclient_stop(g_zclient); + zclient_free(g_zclient); } diff --git a/staticd/static_vty.c b/staticd/static_vty.c index ffa90d5352..087df8efa0 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -86,6 +86,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) uint8_t segs_stack_id = 0; char *orig_label = NULL, *orig_seg = NULL; const char *buf_gate_str; + struct ipaddr gate_ip; uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT; route_tag_t tag = 0; uint32_t table_id = 0; @@ -149,22 +150,27 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) if (src.prefixlen) prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix)); - if (args->gateway) + + if (args->gateway) { buf_gate_str = args->gateway; - else + if (str2ipaddr(args->gateway, &gate_ip) != 0) { + vty_out(vty, "%% Invalid gateway address %s\n", args->gateway); + return CMD_WARNING_CONFIG_FAILED; + } + } else buf_gate_str = ""; if (args->gateway == NULL && args->interface_name == NULL) type = STATIC_BLACKHOLE; else if (args->gateway && args->interface_name) { - if (args->afi == AFI_IP) + if (gate_ip.ipa_type == IPADDR_V4) type = STATIC_IPV4_GATEWAY_IFNAME; else type = STATIC_IPV6_GATEWAY_IFNAME; } else if (args->interface_name) type = STATIC_IFNAME; else { - if (args->afi == AFI_IP) + if (gate_ip.ipa_type == IPADDR_V4) type = STATIC_IPV4_GATEWAY; else type = STATIC_IPV6_GATEWAY; @@ -552,7 +558,7 @@ DEFPY_YANG(ip_route_address_interface, ip_route_address_interface_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ - A.B.C.D$gate \ + <A.B.C.D|X:X::X:X>$gate \ <INTERFACE|Null0>$ifname \ [{ \ tag (1-4294967295) \ @@ -571,7 +577,8 @@ DEFPY_YANG(ip_route_address_interface, "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix\n" "IP destination prefix mask\n" - "IP gateway address\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" @@ -624,7 +631,7 @@ DEFPY_YANG(ip_route_address_interface_vrf, ip_route_address_interface_vrf_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ - A.B.C.D$gate \ + <A.B.C.D|X:X::X:X>$gate \ <INTERFACE|Null0>$ifname \ [{ \ tag (1-4294967295) \ @@ -642,7 +649,8 @@ DEFPY_YANG(ip_route_address_interface_vrf, "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix\n" "IP destination prefix mask\n" - "IP gateway address\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" @@ -693,16 +701,16 @@ DEFPY_YANG(ip_route_address_interface_vrf, DEFPY_YANG(ip_route, ip_route_cmd, "[no] ip route\ - <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ - <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - |color (1-4294967295) \ + <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ + <<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \ + [{ \ + tag (1-4294967295) \ + |(1-255)$distance \ + |vrf NAME \ + |label WORD \ + |table (1-4294967295) \ + |nexthop-vrf NAME \ + |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |segments WORD \ }]", @@ -711,7 +719,8 @@ DEFPY_YANG(ip_route, "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix\n" "IP destination prefix mask\n" - "IP gateway address\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" @@ -761,15 +770,15 @@ DEFPY_YANG(ip_route, DEFPY_YANG(ip_route_vrf, ip_route_vrf_cmd, "[no] ip route\ - <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ - <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - |color (1-4294967295) \ + <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ + <<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \ + [{ \ + tag (1-4294967295) \ + |(1-255)$distance \ + |label WORD \ + |table (1-4294967295) \ + |nexthop-vrf NAME \ + |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |segments WORD \ }]", @@ -778,7 +787,8 @@ DEFPY_YANG(ip_route_vrf, "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix\n" "IP destination prefix mask\n" - "IP gateway address\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" @@ -1752,6 +1762,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: vty_out(vty, " behavior End.X PSP"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + vty_out(vty, " behavior End.B6.Encaps"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: vty_out(vty, " behavior End.X PSP/USD"); break; @@ -1764,6 +1777,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool case SRV6_ENDPOINT_BEHAVIOR_END_DT46: vty_out(vty, " behavior End.DT46"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + vty_out(vty, " behavior End.B6.Encaps.Red"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: vty_out(vty, " behavior uN"); break; @@ -1791,6 +1807,12 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID: vty_out(vty, " behavior uDT46"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + vty_out(vty, " behavior uB6.Encaps"); + break; + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: + vty_out(vty, " behavior uB6.Encaps.Red"); + break; case SRV6_ENDPOINT_BEHAVIOR_RESERVED: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: vty_out(vty, " behavior unknown"); diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 3ed525f386..cc09b42836 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -75,7 +75,7 @@ DECLARE_HASH(static_nht_hash, struct static_nht_data, itm, static_nht_data_cmp, static struct static_nht_hash_head static_nht_hash[1]; /* Zebra structure to hold current status. */ -struct zclient *zclient; +struct zclient *static_zclient; uint32_t zebra_ecmp_count = MULTIPATH_NUM; /* Interface addition message from zebra. */ @@ -209,14 +209,10 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched, struct zapi_route *nhr) { struct static_nht_data *nhtd, lookup; - afi_t afi = AFI_IP; - if (zclient->bfd_integration) + if (static_zclient->bfd_integration) bfd_nht_update(matched, nhr); - if (matched->family == AF_INET6) - afi = AFI_IP6; - if (nhr->type == ZEBRA_ROUTE_CONNECT) { if (static_nexthop_is_local(vrf->vrf_id, matched, nhr->prefix.family)) @@ -233,8 +229,12 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched, if (nhtd) { nhtd->nh_num = nhr->nexthop_num; - static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id); - static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi, + /* The tracked nexthop might be used by IPv4 and IPv6 routes */ + static_nht_reset_start(matched, AFI_IP, nhr->safi, nhtd->nh_vrf_id); + static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP, nhr->safi, + nhtd->nh_vrf_id); + static_nht_reset_start(matched, AFI_IP6, nhr->safi, nhtd->nh_vrf_id); + static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP6, nhr->safi, nhtd->nh_vrf_id); } else zlog_err("No nhtd?"); @@ -361,7 +361,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) if (reg) { if (nhtd->nh_num) { /* refresh with existing data */ - afi_t afi = prefix_afi(&lookup.nh); + afi_t afi = prefix_afi(&rn->p); if (nh->state == STATIC_NOT_INSTALLED || nh->state == STATIC_SENT_TO_ZEBRA) @@ -395,7 +395,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) "Unregistering nexthop(%pFX) for %pRN", &lookup.nh, rn); } - if (zclient_send_rnh(zclient, cmd, &lookup.nh, si->safi, false, false, + if (zclient_send_rnh(static_zclient, cmd, &lookup.nh, si->safi, false, false, nh->nh_vrf_id) == ZCLIENT_SEND_FAILURE) zlog_warn("%s: Failure to send nexthop %pFX for %pRN to zebra", __func__, &lookup.nh, rn); @@ -549,7 +549,7 @@ extern void static_zebra_route_add(struct static_path *pn, bool install) zclient_route_send(install ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); + static_zclient, &api); } /** @@ -594,7 +594,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint memcpy(&api.prefix, &p, sizeof(p)); if (cmd == ZEBRA_ROUTE_DELETE) - return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, static_zclient, &api); SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); @@ -611,7 +611,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint api.nexthop_num = 1; - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, static_zclient, &api); } /** @@ -625,8 +625,6 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) struct seg6local_context ctx = {}; struct interface *ifp = NULL; struct vrf *vrf; - struct prefix_ipv6 sid_block = {}; - struct prefix_ipv6 locator_block = {}; struct prefix_ipv6 sid_locator = {}; if (!sid) @@ -732,28 +730,17 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: zlog_warn("unsupported behavior: %u", sid->behavior); break; } - sid_block = sid->addr; - sid_block.prefixlen = sid->locator->block_bits_length; - apply_mask(&sid_block); - - locator_block = sid->locator->prefix; - locator_block.prefixlen = sid->locator->block_bits_length; - apply_mask(&locator_block); - - if (prefix_same(&sid_block, &locator_block)) - ctx.block_len = sid->locator->block_bits_length; - else { - zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block, - &locator_block); - return; - } - + ctx.block_len = sid->locator->block_bits_length; sid_locator = sid->addr; sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length; apply_mask(&sid_locator); @@ -870,6 +857,10 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid) case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: zlog_warn("unsupported behavior: %u", sid->behavior); break; } @@ -915,6 +906,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid) UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA); } +/* Validate if the sid block and locator block are the same */ +static bool static_zebra_sid_locator_block_check(struct static_srv6_sid *sid) +{ + struct prefix_ipv6 sid_block = {}; + struct prefix_ipv6 locator_block = {}; + + sid_block = sid->addr; + sid_block.prefixlen = sid->locator->block_bits_length; + apply_mask(&sid_block); + + locator_block = sid->locator->prefix; + locator_block.prefixlen = sid->locator->block_bits_length; + apply_mask(&locator_block); + + if (!prefix_same(&sid_block, &locator_block)) { + zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block, + &locator_block); + + return false; + } + + return true; +} + extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) { struct srv6_sid_ctx ctx = {}; @@ -922,7 +937,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) struct vrf *vrf; struct interface *ifp; - if (!sid) + if (!sid || !static_zebra_sid_locator_block_check(sid)) return; /* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */ @@ -992,12 +1007,17 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: zlog_warn("unsupported behavior: %u", sid->behavior); return; } /* Request SRv6 SID from SID Manager */ - ret = srv6_manager_get_sid(zclient, &ctx, &sid->addr.prefix, sid->locator->name, NULL); + ret = srv6_manager_get_sid(static_zclient, &ctx, &sid->addr.prefix, sid->locator->name, + NULL); if (ret < 0) zlog_warn("%s: error getting SRv6 SID!", __func__); } @@ -1079,12 +1099,16 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid) case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID: zlog_warn("unsupported behavior: %u", sid->behavior); return; } /* remove the SRv6 SID from the zebra RIB */ - ret = srv6_manager_release_sid(zclient, &ctx); + ret = srv6_manager_release_sid(static_zclient, &ctx); if (ret == ZCLIENT_SEND_FAILURE) flog_err(EC_LIB_ZAPI_SOCKET, "zclient_send_get_srv6_sid() delete failed: %s", safe_strerror(errno)); @@ -1105,7 +1129,7 @@ int static_zebra_srv6_manager_get_locator(const char *name) * Send the Get Locator request to the SRv6 Manager and return the * result */ - return srv6_manager_get_locator(zclient, name); + return srv6_manager_get_locator(static_zclient, name); } static void request_srv6_sids(struct static_srv6_locator *locator) @@ -1360,16 +1384,16 @@ void static_zebra_init(void) hook_register_prio(if_down, 0, static_ifp_down); hook_register_prio(if_unreal, 0, static_ifp_destroy); - zclient = zclient_new(master, &zclient_options_default, static_handlers, - array_size(static_handlers)); + static_zclient = zclient_new(master, &zclient_options_default, static_handlers, + array_size(static_handlers)); - zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs); - zclient->zebra_capabilities = static_zebra_capabilities; - zclient->zebra_connected = zebra_connected; - zclient->nexthop_update = static_zebra_nexthop_update; + zclient_init(static_zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs); + static_zclient->zebra_capabilities = static_zebra_capabilities; + static_zclient->zebra_connected = zebra_connected; + static_zclient->nexthop_update = static_zebra_nexthop_update; static_nht_hash_init(static_nht_hash); - static_bfd_initialize(zclient, master); + static_bfd_initialize(static_zclient, master); } /* static_zebra_stop used by tests/lib/test_grpc.cpp */ @@ -1378,23 +1402,23 @@ void static_zebra_stop(void) static_nht_hash_clear(); static_nht_hash_fini(static_nht_hash); - if (!zclient) + if (!static_zclient) return; - zclient_stop(zclient); - zclient_free(zclient); - zclient = NULL; + zclient_stop(static_zclient); + zclient_free(static_zclient); + static_zclient = NULL; } void static_zebra_vrf_register(struct vrf *vrf) { if (vrf->vrf_id == VRF_DEFAULT) return; - zclient_send_reg_requests(zclient, vrf->vrf_id); + zclient_send_reg_requests(static_zclient, vrf->vrf_id); } void static_zebra_vrf_unregister(struct vrf *vrf) { if (vrf->vrf_id == VRF_DEFAULT) return; - zclient_send_dereg_requests(zclient, vrf->vrf_id); + zclient_send_dereg_requests(static_zclient, vrf->vrf_id); } diff --git a/tests/.gitignore b/tests/.gitignore index 681438f4a5..51909cd81d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -22,6 +22,7 @@ frr_northbound* /lib/cli/test_commands /lib/cli/test_commands_defun.c /lib/northbound/test_oper_data +/lib/northbound/test_oper_exists /lib/cxxcompat /lib/fuzz_zlog /lib/test_assert diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c index e47456965e..e22ee21365 100644 --- a/tests/isisd/test_common.c +++ b/tests/isisd/test_common.c @@ -33,11 +33,11 @@ test_topology_find_node(const struct isis_topology *topology, } const struct isis_topology * -test_topology_find(struct isis_topology *test_topologies, uint16_t number) +test_topology_find(struct isis_topology *topologies, uint16_t number) { - for (size_t i = 0; test_topologies[i].number; i++) - if (test_topologies[i].number == number) - return &test_topologies[i]; + for (size_t i = 0; topologies[i].number; i++) + if (topologies[i].number == number) + return &topologies[i]; return NULL; } diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 48a2caacce..2a8a5bc5d7 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -161,7 +161,7 @@ static int test(FILE *input, FILE *output) struct listnode *node; for (ALL_LIST_ELEMENTS_RO(fragments, node, tlvs)) { stream_reset(s); - int rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false); + rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false); if (rv) { fprintf(output, "Could not pack fragment, too large.\n"); assert(0); diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index a38325173a..7a3618f3bf 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -249,9 +249,10 @@ static enum nb_error frr_test_module_c2cont_c2value_get(const struct nb_node *nb struct lyd_node *parent) { const struct lysc_node *snode = nb_node->snode; - uint32_t value = 0xAB010203; + uint32_t value = htole32(0xAB010203); LY_ERR err; + /* Note that this api expects 'value' to be in little-endian form */ err = lyd_new_term_bin(parent, snode->module, snode->name, &value, sizeof(value), LYD_NEW_PATH_UPDATE, NULL); assert(err == LY_SUCCESS); diff --git a/tests/lib/test_darr.c b/tests/lib/test_darr.c index be319db1c1..d980db505d 100644 --- a/tests/lib/test_darr.c +++ b/tests/lib/test_darr.c @@ -157,12 +157,17 @@ static void test_int(void) assert(!memcmp(da2, a1, sizeof(a1))); - assert(darr_pop(da2) == 4); - assert(darr_pop(da2) == 3); - assert(darr_pop(da2) == 2); + i = darr_pop(da2); + assert(i == 4); + i = darr_pop(da2); + assert(i == 3); + i = darr_pop(da2); + assert(i == 2); assert(darr_len(da2) == 2); - assert(darr_pop(da2) == 1); - assert(darr_pop(da2) == 0); + i = darr_pop(da2); + assert(i == 1); + i = darr_pop(da2); + assert(i == 0); assert(darr_len(da2) == 0); darr_free(da2); @@ -323,38 +328,47 @@ static void test_string(void) char *da2 = NULL; const char **strings = NULL; uint sum = 0; + uint i; - assert(darr_strlen(da1) == 0); + i = darr_strlen(da1); + assert(i == 0); da1 = darr_strdup(src); - assert(darr_strlen(da1) == strlen(da1)); - assert(darr_strlen(da1) == srclen); + i = darr_strlen(da1); + assert(i == strlen(da1)); + i = darr_strlen(da1); + assert(i == srclen); assert(darr_len(da1) == srclen + 1); assert(darr_ilen(da1) == (int)srclen + 1); assert(darr_cap(da1) >= 8); assert(darr_last(da1) == darr_strnul(da1)); - assert(darr_strnul(da1) == da1 + darr_strlen(da1)); + i = darr_strlen(da1); + assert(darr_strnul(da1) == da1 + i); da2 = da1; darr_in_strdup(da1, src); assert(da1 == da2); - assert(darr_strlen(da1) == strlen(da1)); - assert(darr_strlen(da1) == srclen); + i = darr_strlen(da1); + assert(i == strlen(da1)); + assert(i == srclen); assert(darr_len(da1) == srclen + 1); darr_free(da1); assert(da1 == NULL); da1 = darr_strdup_cap(src, 128); - assert(darr_strlen(da1) == srclen); + i = darr_strlen(da1); + assert(i == srclen); assert(darr_cap(da1) >= 128); darr_in_strdup_cap(da1, src, 256); - assert(darr_strlen(da1) == srclen); + i = darr_strlen(da1); + assert(i == srclen); assert(darr_cap(da1) >= 256); darr_free(da1); da1 = darr_strdup_cap(add, 2); - assert(darr_strlen(da1) == addlen); + i = darr_strlen(da1); + assert(i == addlen); assert(darr_cap(da1) >= 8); darr_in_strdup(da1, "ab"); @@ -377,7 +391,8 @@ static void test_string(void) da2 = darr_strdup(add); darr_in_strcat_tail(da1, da2); assert(!strcmp("abHIJ", da1)); - assert(darr_strlen(da1) == 5); + i = darr_strlen(da1); + assert(i == 5); assert(darr_len(da1) == 6); darr_free(da1); darr_free(da2); @@ -386,14 +401,16 @@ static void test_string(void) da2 = darr_strdup(add); darr_in_strcat_tail(da1, da2); assert(!strcmp("abcde", da1)); - assert(darr_strlen(da1) == 5); + i = darr_strlen(da1); + assert(i == 5); assert(darr_len(da1) == 6); darr_free(da1); darr_free(da2); da1 = darr_sprintf("0123456789: %08X", 0xDEADBEEF); assert(!strcmp(da1, "0123456789: DEADBEEF")); - assert(darr_strlen(da1) == 20); + i = darr_strlen(da1); + assert(i == 20); assert(darr_cap(da1) == 128); da2 = da1; darr_in_sprintf(da1, "9876543210: %08x", 0x0BADF00D); @@ -405,11 +422,13 @@ static void test_string(void) da1 = NULL; darr_in_sprintf(da1, "0123456789: %08X", 0xDEADBEEF); assert(!strcmp(da1, "0123456789: DEADBEEF")); - assert(darr_strlen(da1) == 20); + i = darr_strlen(da1); + assert(i == 20); assert(darr_cap(da1) == 128); da1[5] = 0; - assert(darr_strlen_fixup(da1) == 5); + i = darr_strlen_fixup(da1); + assert(i == 5); darr_free(da1); da1 = darr_sprintf("0123456789: %08x", 0xDEADBEEF); diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index a81ebcdbcd..c915587c13 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -107,7 +107,7 @@ static int printchk(const char *ref, const char *fmt, ...) errors++; } - for (size_t i = 0; i < fb.outpos_i; i++) + for (i = 0; i < fb.outpos_i; i++) printf("\t[%zu: %u..%u] = \"%.*s\"\n", i, outpos[i].off_start, outpos[i].off_end, 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 80903b134e..3cecf9d946 100644 --- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py +++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py @@ -38,7 +38,6 @@ from lib.topogen import Topogen, get_topogen from lib.common_config import ( required_linux_kernel_version, ) -from lib.topolog import logger import json import functools @@ -420,9 +419,9 @@ def route_get_nhg_id(route_str): test_func = functools.partial(get_func, route_str) _, nhg_id = topotest.run_and_expect_type(test_func, int, count=30, wait=1) - if nhg_id == None: + if nhg_id is None: fatal_error = "Nexthop Group ID not found for route {}".format(route_str) - assert nhg_id != None, fatal_error + assert nhg_id is not None, fatal_error else: return nhg_id @@ -710,7 +709,8 @@ def test_rip_status(): refTableFile = "{}/r{}/rip_status.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -771,7 +771,8 @@ def test_ripng_status(): refTableFile = "{}/r{}/ripng_status.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -834,7 +835,8 @@ def test_ospfv2_interfaces(): refTableFile = "{}/r{}/show_ip_ospf_interface.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -916,7 +918,8 @@ def test_isis_interfaces(): refTableFile = "{}/r{}/show_isis_interface_detail.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -979,7 +982,8 @@ def test_bgp_summary(): refTableFile = "{}/r{}/show_ip_bgp_summary.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected_original = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected_original = file.read().rstrip() for arguments in [ "", @@ -1152,7 +1156,8 @@ def test_bgp_ipv6_summary(): refTableFile = "{}/r{}/show_bgp_ipv6_summary.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -1244,7 +1249,8 @@ def test_nht(): for i in range(1, 2): nhtFile = "{}/r{}/ip_nht.ref".format(thisDir, i) - expected = open(nhtFile).read().rstrip() + with open(nhtFile) as file: + expected = file.read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( @@ -1266,7 +1272,8 @@ def test_nht(): print("show ip nht is ok\n") nhtFile = "{}/r{}/ipv6_nht.ref".format(thisDir, i) - expected = open(nhtFile).read().rstrip() + with open(nhtFile) as file: + expected = file.read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( @@ -1306,7 +1313,8 @@ def test_bgp_ipv4(): for refTableFile in glob.glob("{}/r{}/show_bgp_ipv4*.ref".format(thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -1377,7 +1385,8 @@ def test_bgp_ipv6(): for refTableFile in glob.glob("{}/r{}/show_bgp_ipv6*.ref".format(thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) @@ -1444,7 +1453,8 @@ def test_route_map(): for i in range(1, 2): refroutemap = "{}/r{}/show_route_map.ref".format(thisDir, i) if os.path.isfile(refroutemap): - expected = open(refroutemap).read().rstrip() + with open(refroutemap) as file: + expected = file.read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( @@ -1649,7 +1659,8 @@ def test_mpls_interfaces(): refTableFile = "{}/r{}/show_mpls_ldp_interface.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file - expected = open(refTableFile).read().rstrip() + with open(refTableFile) as file: + expected = file.read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py index 874ad09264..e2bcd004d4 100644 --- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py +++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py @@ -195,14 +195,14 @@ def test_bgp_administrative_reset_gr(): step("Reset and delay the session establishement for R1") r1.vtysh_cmd( """ - configure terminal" + configure terminal router bgp neighbor 192.168.255.2 timers delayopen 60 """ ) r2.vtysh_cmd( """ - configure terminal" + configure terminal router bgp neighbor 192.168.255.1 timers delayopen 60 """ diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf index 2210f24589..e1c533c1f3 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf @@ -4,6 +4,7 @@ hostname r3 password zebra log stdout notifications log commands +#debug bgp vnc verbose router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 diff --git a/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py b/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py index 7201ac8111..aaa43d5a7e 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py +++ b/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py @@ -91,10 +91,10 @@ luCommand( ) num = "0 exist" -luCommand("r1", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear") -luCommand("r2", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear") -luCommand("r3", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear") -luCommand("r4", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear") +luCommand("r1", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear") +luCommand("r2", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear") +luCommand("r3", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear") +luCommand("r4", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear") luCommand( "r1", diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf index e74fc0b3de..04b10b4d22 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf @@ -4,6 +4,7 @@ hostname r3 password zebra log stdout notifications log commands +#debug bgp vnc verbose router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py index 5b775aa6cb..bdf905feba 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -477,6 +477,121 @@ def test_bgp_ecommunity_rpki(): assert result is None, "Received RPKI extended community" +def test_show_bgp_rpki_as_number(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Check RPKI prefixes for ASN 65531") + + rname = "r2" + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65531 json")) + + # Expected output should show no prefixes for this ASN + expected = {"ipv4PrefixCount": 0, "ipv6PrefixCount": 0, "prefixes": []} + + assert output == expected, "Found unexpected RPKI prefixes for ASN 65531" + + +def test_show_bgp_rpki_as_number_65530(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Check RPKI prefixes for ASN 65530") + + rname = "r2" + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65530 json")) + + expected = { + "prefixes": [ + { + "prefix": "198.51.100.0", + "prefixLenMin": 24, + "prefixLenMax": 24, + "asn": 65530, + }, + { + "prefix": "203.0.113.0", + "prefixLenMin": 24, + "prefixLenMax": 24, + "asn": 65530, + }, + ], + "ipv4PrefixCount": 2, + "ipv6PrefixCount": 0, + } + + assert ( + output == expected + ), "RPKI prefixes for ASN 65530 do not match expected output" + + +def test_rpki_stop_and_check_connection(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Stop RPKI on r2") + rname = "r2" + tgen.gears[rname].vtysh_cmd("rpki stop") + + step("Check RPKI cache connection status") + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki cache-connection json")) + + expected = {"error": "No connection to RPKI cache server."} + assert ( + output == expected + ), "RPKI cache connection status does not show as disconnected" + + +def test_rpki_start_and_check_connection(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Start RPKI on r2") + rname = "r2" + tgen.gears[rname].vtysh_cmd("rpki start") + + def _check_rpki_connection(): + output = json.loads( + tgen.gears[rname].vtysh_cmd("show rpki cache-connection json") + ) + # We expect to see a connected group and at least one connection + return "connectedGroup" in output and "connections" in output + + step("Check RPKI cache connection status") + _, result = topotest.run_and_expect( + _check_rpki_connection, True, count=60, wait=0.5 + ) + assert result, "RPKI cache connection did not establish after start" + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf deleted file mode 100644 index 3459796629..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce1 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf new file mode 100644 index 0000000000..ca28d55409 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf @@ -0,0 +1,18 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:1::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65500 + bgp router-id 1.1.2.1 + no bgp network import-check + neighbor 2001:1::1 remote-as 65500 + address-family ipv6 unicast + network 2011:1::1/64 + neighbor 2001:1::1 activate + exit-address-family +exit + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json index d19e315772..b68f1a1112 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:1::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf deleted file mode 100644 index 665808a0e7..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce1 -! -interface eth0 - ipv6 address 2001:1::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:1::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf deleted file mode 100644 index 8ed9978749..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce2 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf new file mode 100644 index 0000000000..a15c5b48e0 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf @@ -0,0 +1,17 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:2::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65501 + bgp router-id 1.1.20.1 + neighbor 2001:2::1 remote-as 65501 + address-family ipv6 unicast + neighbor 2001:2::1 activate + exit-address-family +exit + + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json index 35ff14efad..51076ee194 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:2::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, @@ -54,5 +53,32 @@ } ] } + ], + "2011:1::/64": [ + { + "prefix": "2011:1::/64", + "protocol": "bgp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 200, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 13, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "active": true + } + ] + } ] } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf deleted file mode 100644 index cc9b90a3b0..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce2 -! -interface eth0 - ipv6 address 2001:2::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:2::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf deleted file mode 100644 index a85d9701c7..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce3 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf new file mode 100644 index 0000000000..947a4a2551 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf @@ -0,0 +1,16 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:3::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65500 + bgp router-id 1.1.3.1 + neighbor 2001:3::1 remote-as 65500 + address-family ipv6 unicast + neighbor 2001:3::1 activate + exit-address-family +exit + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json index 2f2931f80f..6a373a80b8 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:3::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf deleted file mode 100644 index beca0b1211..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce3 -! -interface eth0 - ipv6 address 2001:3::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:3::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf deleted file mode 100644 index 93fb32fd1b..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce4 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf new file mode 100644 index 0000000000..3eaf47961e --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf @@ -0,0 +1,16 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:4::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65501 + bgp router-id 1.1.4.1 + neighbor 2001:4::1 remote-as 65501 + address-family ipv6 unicast + neighbor 2001:4::1 activate + exit-address-family +exit + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json index 8a98768e0d..da6bd55231 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:4::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf deleted file mode 100644 index 7b21074df0..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce4 -! -interface eth0 - ipv6 address 2001:4::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:4::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf deleted file mode 100644 index 2ab6f2d2a7..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce5 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf new file mode 100644 index 0000000000..5adfc7cfeb --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf @@ -0,0 +1,16 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:5::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65500 + bgp router-id 1.1.5.1 + neighbor 2001:5::1 remote-as 65500 + address-family ipv6 unicast + neighbor 2001:5::1 activate + exit-address-family +exit + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json index 80ff52ad6e..f8ab84d17a 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:5::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf deleted file mode 100644 index b5ad48e709..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce5 -! -interface eth0 - ipv6 address 2001:5::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:5::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf deleted file mode 100644 index e0b6540514..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf +++ /dev/null @@ -1,8 +0,0 @@ -frr defaults traditional -! -hostname ce6 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf new file mode 100644 index 0000000000..3870bd84a3 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf @@ -0,0 +1,16 @@ +frr defaults traditional +! +interface eth0 + ipv6 address 2001:6::2/64 +! +ip forwarding +ipv6 forwarding +! +router bgp 65501 + bgp router-id 1.1.6.1 + neighbor 2001:6::1 remote-as 65501 + address-family ipv6 unicast + neighbor 2001:6::1 activate + exit-address-family +exit + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json index ace6136f06..71ca42e396 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json @@ -2,24 +2,23 @@ "::/0": [ { "prefix": "::/0", - "protocol": "static", + "protocol": "bgp", "vrfId": 0, "vrfName": "default", "selected": true, "destSelected": true, - "distance": 1, + "distance": 200, "metric": 0, "installed": true, "table": 254, "internalStatus": 16, - "internalFlags": 73, + "internalFlags": 13, "internalNextHopNum": 1, "internalNextHopActiveNum": 1, "nexthops": [ { "flags": 3, "fib": true, - "ip": "2001:6::1", "afi": "ipv6", "interfaceName": "eth0", "active": true, diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf deleted file mode 100644 index 7d19d9880b..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf +++ /dev/null @@ -1,14 +0,0 @@ -log file zebra.log -! -hostname ce6 -! -interface eth0 - ipv6 address 2001:6::2/64 -! -ip forwarding -ipv6 forwarding -! -ipv6 route ::/0 2001:6::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf new file mode 100644 index 0000000000..ef05460b22 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf @@ -0,0 +1,97 @@ +! debug zebra packet +! debug zebra dplane +! debug zebra kernel +! debug bgp neighbor-events +! debug bgp zebra +! debug bgp vnc verbose +! debug bgp update-groups +! debug bgp updates in +! debug bgp updates out +! debug bgp vpn label +! debug bgp vpn leak-from-vrf +! debug bgp vpn leak-to-vrf +! debug bgp vpn rmap-event +! +interface eth0 + ipv6 address 2001::1/64 +! +interface eth1 vrf vrf10 + ipv6 address 2001:1::1/64 +! +interface eth2 vrf vrf10 + ipv6 address 2001:3::1/64 +! +interface eth3 vrf vrf20 + ipv6 address 2001:5::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix 2001:db8:1:1::/64 func-bits 8 + ! + ! +! +ip forwarding +ipv6 forwarding +! +ipv6 route 2001:db8:2:1::/64 2001::2 +ipv6 route 2001:db8:2:2::/64 2001::2 +ipv6 route 2001:db8:2:3::/64 2001::2 +! +line vty +! +no bgp send-extra-data-zebra +router bgp 65500 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor 2001::2 remote-as 65501 + neighbor 2001::2 timers 3 10 + neighbor 2001::2 timers connect 1 + ! + address-family ipv6 vpn + neighbor 2001::2 activate + exit-address-family + ! + segment-routing srv6 + locator loc1 + ! +! +router bgp 65500 vrf vrf10 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + neighbor 2001:1::2 remote-as 65500 + neighbor 2001:3::2 remote-as 65500 + address-family ipv6 unicast + neighbor 2001:1::2 activate + neighbor 2001:1::2 default-originate + neighbor 2001:3::2 activate + neighbor 2001:3::2 default-originate + sid vpn export auto + rd vpn export 1:10 + rt vpn both 99:99 + import vpn + export vpn + redistribute connected + exit-address-family +! +router bgp 65500 vrf vrf20 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor 2001:5::2 remote-as 65500 + ! + address-family ipv6 unicast + neighbor 2001:5::2 activate + neighbor 2001:5::2 default-originate + sid vpn export auto + rd vpn export 1:20 + rt vpn both 88:88 + import vpn + export vpn + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json index 0fdd3d6dc0..afa713e37f 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "1.1.1.1", "defaultLocPrf": 100, - "localAS": 1, + "localAS": 65500, "routes": { "routeDistinguishers": { "1:10": { @@ -58,6 +58,32 @@ } ] } + ], + "2011:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2011:1::", + "prefixLen": 64, + "network": "2011:1::/64", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "", + "origin": "IGP", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001:1::2", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } ] }, "1:20": { @@ -101,7 +127,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -127,7 +153,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -151,7 +177,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -165,5 +191,7 @@ ] } } - } + }, + "totalRoutes": 7, + "totalPaths": 7 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json index f2df9be49d..a3a5f0438a 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "1.1.1.1", "defaultLocPrf": 100, - "localAS": 1, + "localAS": 65500, "routes": { "routeDistinguishers": { "1:10": { @@ -52,6 +52,29 @@ } ] } + ], + "2011:1::/64": [ + { + "pathFrom": "external", + "prefix": "2011:1::", + "prefixLen": 64, + "network": "2011:1::/64", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "", + "origin": "IGP", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001:1::2", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } ] }, "1:20": { @@ -92,7 +115,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -118,7 +141,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -142,7 +165,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -156,5 +179,7 @@ ] } } - } + }, + "totalRoutes": 7, + "totalPaths": 7 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json index 0fdd3d6dc0..afa713e37f 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "1.1.1.1", "defaultLocPrf": 100, - "localAS": 1, + "localAS": 65500, "routes": { "routeDistinguishers": { "1:10": { @@ -58,6 +58,32 @@ } ] } + ], + "2011:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2011:1::", + "prefixLen": 64, + "network": "2011:1::/64", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "", + "origin": "IGP", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001:1::2", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } ] }, "1:20": { @@ -101,7 +127,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -127,7 +153,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -151,7 +177,7 @@ "metric": 0, "weight": 0, "peerId": "2001::2", - "path": "2", + "path": "65501", "origin": "incomplete", "nexthops": [ { @@ -165,5 +191,7 @@ ] } } - } + }, + "totalRoutes": 7, + "totalPaths": 7 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json index 141c1cb957..aee6905d95 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json @@ -53,8 +53,7 @@ "segs": "2001:db8:2:2:100::" } } - ], - "asPath": "2" + ] } ], "2001:3::/64": [ diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json index e20998061f..0f3c970afe 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json @@ -27,8 +27,7 @@ "segs": "2001:db8:2:2:200::" } } - ], - "asPath": "2" + ] } ], "2001:5::/64": [ @@ -85,8 +84,7 @@ "segs": "2001:db8:2:2:200::" } } - ], - "asPath": "2" + ] } ] } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf deleted file mode 100644 index c84106f2bb..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf +++ /dev/null @@ -1,41 +0,0 @@ -log file zebra.log -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! -! debug zebra packet -! debug zebra dplane -! debug zebra kernel -! -interface eth0 - ipv6 address 2001::1/64 -! -interface eth1 vrf vrf10 - ipv6 address 2001:1::1/64 -! -interface eth2 vrf vrf10 - ipv6 address 2001:3::1/64 -! -interface eth3 vrf vrf20 - ipv6 address 2001:5::1/64 -! -segment-routing - srv6 - locators - locator loc1 - prefix 2001:db8:1:1::/64 func-bits 8 - ! - ! -! -ip forwarding -ipv6 forwarding -! -ipv6 route 2001:db8:2:1::/64 2001::2 -ipv6 route 2001:db8:2:2::/64 2001::2 -ipv6 route 2001:db8:2:3::/64 2001::2 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf new file mode 100644 index 0000000000..1bef01d0b3 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf @@ -0,0 +1,98 @@ +! debug zebra packet +! debug zebra dplane +! debug zebra kernel +! debug bgp neighbor-events +! debug bgp zebra +! debug bgp vnc verbose +! debug bgp update-groups +! debug bgp updates in +! debug bgp updates out +! debug bgp updates +! debug bgp vpn label +! debug bgp vpn leak-from-vrf +! debug bgp vpn leak-to-vrf +! debug bgp vpn rmap-event +! +interface eth0 + ipv6 address 2001::2/64 +! +interface eth1 vrf vrf10 + ipv6 address 2001:2::1/64 +! +interface eth2 vrf vrf20 + ipv6 address 2001:4::1/64 +! +interface eth3 vrf vrf20 + ipv6 address 2001:6::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix 2001:db8:2:2::/64 func-bits 8 + ! + ! +! +ip forwarding +ipv6 forwarding +! +ipv6 route 2001:db8:1:1::/64 2001::1 +ipv6 route 2001:db8:1:2::/64 2001::1 +ipv6 route 2001:db8:1:3::/64 2001::1 +! +line vty +! +no bgp send-extra-data-zebra +router bgp 65501 + bgp router-id 2.2.2.2 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor 2001::1 remote-as 65500 + neighbor 2001::1 timers 3 10 + neighbor 2001::1 timers connect 1 + ! + address-family ipv6 vpn + neighbor 2001::1 activate + exit-address-family + ! + segment-routing srv6 + locator loc1 + ! +! +router bgp 65501 vrf vrf10 + bgp router-id 2.2.2.2 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + neighbor 2001:2::2 remote-as 65501 + address-family ipv6 unicast + neighbor 2001:2::2 activate + neighbor 2001:2::2 default-originate + sid vpn export auto + rd vpn export 2:10 + rt vpn both 99:99 + import vpn + export vpn + redistribute connected + exit-address-family +! +router bgp 65501 vrf vrf20 + bgp router-id 2.2.2.2 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor 2001:4::2 remote-as 65501 + neighbor 2001:6::2 remote-as 65501 + ! + address-family ipv6 unicast + neighbor 2001:4::2 activate + neighbor 2001:4::2 default-originate + neighbor 2001:6::2 activate + neighbor 2001:6::2 default-originate + sid vpn export auto + rd vpn export 2:20 + rt vpn both 88:88 + import vpn + export vpn + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json index 03bbcc008d..e7695281d9 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "2.2.2.2", "defaultLocPrf": 100, - "localAS": 2, + "localAS": 65501, "routes": { "routeDistinguishers": { "1:10": { @@ -19,7 +19,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -43,7 +43,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -54,6 +54,30 @@ } ] } + ], + "2011:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2011:1::", + "prefixLen": 64, + "network": "2011:1::/64", + "metric": 0, + "weight": 0, + "peerId": "2001::1", + "path": "65500", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } ] }, "1:20": { @@ -69,7 +93,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -165,5 +189,7 @@ ] } } - } + }, + "totalRoutes": 7, + "totalPaths": 7 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json index 25cdf031c3..caa5803bfe 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "2.2.2.2", "defaultLocPrf": 100, - "localAS": 2, + "localAS": 65501, "routes": { "routeDistinguishers": { "2:10": { @@ -89,5 +89,7 @@ ] } } - } + }, + "totalRoutes": 3, + "totalPaths": 3 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json index 03bbcc008d..e7695281d9 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json @@ -3,7 +3,7 @@ "vrfName": "default", "routerId": "2.2.2.2", "defaultLocPrf": 100, - "localAS": 2, + "localAS": 65501, "routes": { "routeDistinguishers": { "1:10": { @@ -19,7 +19,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -43,7 +43,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -54,6 +54,30 @@ } ] } + ], + "2011:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2011:1::", + "prefixLen": 64, + "network": "2011:1::/64", + "metric": 0, + "weight": 0, + "peerId": "2001::1", + "path": "65500", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } ] }, "1:20": { @@ -69,7 +93,7 @@ "metric": 0, "weight": 0, "peerId": "2001::1", - "path": "1", + "path": "65500", "origin": "incomplete", "nexthops": [ { @@ -165,5 +189,7 @@ ] } } - } + }, + "totalRoutes": 7, + "totalPaths": 7 } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json index 7f8a930d00..407dfb9fb4 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json @@ -27,8 +27,7 @@ "segs": "2001:db8:1:1:100::" } } - ], - "asPath": "1" + ] } ], "2001:2::/64": [ @@ -85,8 +84,38 @@ "segs": "2001:db8:1:1:100::" } } - ], - "asPath": "1" + ] + } + ], + "2011:1::/64": [ + { + "prefix": "2011:1::/64", + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "2001:db8:1:1:100::" + } + } + ] } ] } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json index 104bdc30d2..90e0413db2 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json @@ -53,8 +53,7 @@ "segs": "2001:db8:1:1:200::" } } - ], - "asPath": "1" + ] } ], "2001:6::/64": [ diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf deleted file mode 100644 index 5c12429ff2..0000000000 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf +++ /dev/null @@ -1,41 +0,0 @@ -log file zebra.log -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! -! debug zebra packet -! debug zebra dplane -! debug zebra kernel -! -interface eth0 - ipv6 address 2001::2/64 -! -interface eth1 vrf vrf10 - ipv6 address 2001:2::1/64 -! -interface eth2 vrf vrf20 - ipv6 address 2001:4::1/64 -! -interface eth3 vrf vrf20 - ipv6 address 2001:6::1/64 -! -segment-routing - srv6 - locators - locator loc1 - prefix 2001:db8:2:2::/64 func-bits 8 - ! - ! -! -ip forwarding -ipv6 forwarding -! -ipv6 route 2001:db8:1:1::/64 2001::1 -ipv6 route 2001:db8:1:2::/64 2001::1 -ipv6 route 2001:db8:1:3::/64 2001::1 -! -line vty -! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py index a6938668ad..c30410d4dc 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py @@ -92,14 +92,8 @@ def setup_module(mod): tgen.start_topology() router_list = tgen.routers() for rname, router in tgen.routers().items(): - if os.path.exists("{}/{}/setup.sh".format(CWD, rname)): - router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) - ) + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) tgen.gears["r1"].run("ip link add vrf10 type vrf table 10") tgen.gears["r1"].run("ip link set vrf10 up") @@ -218,7 +212,7 @@ def test_bgp_locator_unset(): get_topogen().gears["r1"].vtysh_cmd( """ configure terminal - router bgp 1 + router bgp 65500 segment-routing srv6 no locator loc1 """ @@ -233,7 +227,7 @@ def test_bgp_locator_reset(): get_topogen().gears["r1"].vtysh_cmd( """ configure terminal - router bgp 1 + router bgp 65500 segment-routing srv6 locator loc1 """ @@ -248,7 +242,7 @@ def test_bgp_srv6_unset(): get_topogen().gears["r1"].vtysh_cmd( """ configure terminal - router bgp 1 + router bgp 65500 no segment-routing srv6 """ ) @@ -262,7 +256,7 @@ def test_bgp_srv6_reset(): get_topogen().gears["r1"].vtysh_cmd( """ configure terminal - router bgp 1 + router bgp 65500 segment-routing srv6 locator loc1 """ diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf index 3459796629..188ec7a86c 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf @@ -1,8 +1,3 @@ frr defaults traditional -! -hostname ce1 -password zebra -! -log stdout notifications -log commands -log file bgpd.log + + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf index 447d1b40c1..6c9abca36f 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce1 -! interface eth0 ip address 192.168.1.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf index 8ed9978749..05268f8878 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf @@ -1,8 +1,2 @@ frr defaults traditional -! -hostname ce2 -password zebra -! -log stdout notifications -log commands -log file bgpd.log + diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf index 11652252a4..b0e6470307 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce2 -! interface eth0 ip address 192.168.2.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf index a85d9701c7..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce3 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf index 299c6597c7..f0fd4f497a 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce3 -! interface eth0 ip address 192.168.3.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf index 93fb32fd1b..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce4 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf index 30f3736fe3..da745f2bd0 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce4 -! interface eth0 ip address 192.168.4.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf index 2ab6f2d2a7..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce5 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf index 208dcb1a7a..37391ebb49 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce5 -! interface eth0 ip address 192.168.5.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf index e0b6540514..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce6 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf index d68a008e3a..9696993c33 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce6 -! interface eth0 ip address 192.168.6.2/24 ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf index 12b9e8fd00..d4be6c7d6a 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf @@ -1,13 +1,5 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events !debug bgp zebra !debug bgp vnc verbose diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf index f202493c53..64e6af0c1b 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf @@ -1,11 +1,3 @@ -log file zebra.log -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! !debug zebra packet !debug zebra dplane !debug zebra kernel diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf index db36c180a0..5ff570069c 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf @@ -1,13 +1,5 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events !debug bgp zebra !debug bgp vnc verbose diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf index 9dfed4f2d6..22b689d538 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf @@ -1,11 +1,3 @@ -log file zebra.log -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! !debug zebra packet !debug zebra dplane !debug zebra kernel diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf index 3459796629..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce1 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf index 58e851d752..a6eab175f5 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce1 -! interface eth0 ip address 192.168.1.2/24 ipv6 address 2001:1::2/64 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf index 8ed9978749..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce2 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf index 0612c53223..3be205a8c9 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce2 -! interface eth0 ip address 192.168.2.2/24 ipv6 address 2001:2::2/64 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf index a85d9701c7..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce3 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf index d08fdadc3c..2fb86c74de 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce3 -! interface eth0 ip address 192.168.3.2/24 ipv6 address 2001:3::2/64 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf index 93fb32fd1b..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce4 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf index 897ed46c27..3bbbd08558 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce4 -! interface eth0 ip address 192.168.4.2/24 ipv6 address 2001:4::2/64 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf index 2ab6f2d2a7..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce5 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf index e0b6540514..cd72007f46 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf @@ -1,8 +1 @@ frr defaults traditional -! -hostname ce6 -password zebra -! -log stdout notifications -log commands -log file bgpd.log diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf index 5a83e901e8..d39a6a6bcb 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf @@ -1,7 +1,3 @@ -log file zebra.log -! -hostname ce6 -! interface eth0 ip address 192.168.6.2/24 ipv6 address 2001:6::2/64 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf index 57c19e25d7..5e78e5e1a1 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf @@ -1,13 +1,5 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events !debug bgp zebra !debug bgp vnc verbose diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json index 5645540fbb..4e803a0514 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json @@ -9,9 +9,7 @@ "1:10": { "192.168.1.0/24": [ { - "valid": true, - "bestpath": true, - "selectionReason": "First path received", + "multipath": true, "pathFrom": "external", "prefix": "192.168.1.0", "prefixLen": 24, @@ -34,9 +32,7 @@ ], "192.168.3.0/24": [ { - "valid": true, - "bestpath": true, - "selectionReason": "First path received", + "multipath": true, "pathFrom": "external", "prefix": "192.168.3.0", "prefixLen": 24, @@ -61,9 +57,7 @@ "1:20": { "192.168.5.0/24": [ { - "valid": true, - "bestpath": true, - "selectionReason": "First path received", + "multipath": true, "pathFrom": "external", "prefix": "192.168.5.0", "prefixLen": 24, @@ -84,6 +78,82 @@ ] } ] + }, + "2:10": { + "192.168.2.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.2.0", + "prefixLen": 24, + "network": "192.168.2.0/24", + "metric": 0, + "weight": 0, + "peerId": "2001::2", + "path": "2", + "origin": "incomplete", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "2:20": { + "192.168.4.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.4.0", + "prefixLen": 24, + "network": "192.168.4.0/24", + "metric": 0, + "weight": 0, + "peerId": "2001::2", + "path": "2", + "origin": "incomplete", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ], + "192.168.6.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.6.0", + "prefixLen": 24, + "network": "192.168.6.0/24", + "metric": 0, + "weight": 0, + "peerId": "2001::2", + "path": "2", + "origin": "incomplete", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] } } } diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json index 205079574c..d49c357432 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json @@ -6,6 +6,54 @@ "localAS": 1, "routes": { "routeDistinguishers": { + "1:10": { + "192.168.1.0/24": [ + { + "multipath": true, + "pathFrom": "external", + "prefix": "192.168.1.0", + "prefixLen": 24, + "network": "192.168.1.0/24", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ], + "192.168.3.0/24": [ + { + "multipath": true, + "pathFrom": "external", + "prefix": "192.168.3.0", + "prefixLen": 24, + "network": "192.168.3.0/24", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, "1:20": { "192.168.5.0/24": [ { diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json index f2df9be49d..547b262d4b 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json @@ -9,6 +9,7 @@ "1:10": { "2001:1::/64": [ { + "multipath": true, "pathFrom": "external", "prefix": "2001:1::", "prefixLen": 64, @@ -32,6 +33,7 @@ ], "2001:3::/64": [ { + "multipath": true, "pathFrom": "external", "prefix": "2001:3::", "prefixLen": 64, @@ -57,6 +59,7 @@ "1:20": { "2001:5::/64": [ { + "multipath": true, "pathFrom": "external", "prefix": "2001:5::", "prefixLen": 64, @@ -131,7 +134,7 @@ } ], "2001:6::/64": [ - { + { "valid": true, "bestpath": true, "selectionReason": "First path received", diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json index e289df1d44..8cfe223101 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json @@ -6,6 +6,56 @@ "localAS": 1, "routes": { "routeDistinguishers": { + "1:10": { + "2001:1::/64": [ + { + "multipath": true, + "pathFrom": "external", + "prefix": "2001:1::", + "prefixLen": 64, + "network": "2001:1::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ], + "2001:3::/64": [ + { + "multipath": true, + "pathFrom": "external", + "prefix": "2001:3::", + "prefixLen": 64, + "network": "2001:3::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, "1:20": { "2001:5::/64": [ { diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf index dd8a756a6e..a7515e12d3 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf @@ -1,11 +1,3 @@ -log file zebra.log -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! !debug zebra packet !debug zebra dplane !debug zebra kernel diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf index abf4971a9b..bf04fbc7aa 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf @@ -1,13 +1,5 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events !debug bgp zebra !debug bgp vnc verbose diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf index 3c9e4e3b25..27919cc63f 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf @@ -1,11 +1,3 @@ -log file zebra.log -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! !debug zebra packet !debug zebra dplane !debug zebra kernel diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py index 530537646b..9e588d1d71 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py @@ -18,6 +18,7 @@ sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest +from lib.bgp import bgp_vpn_router_json_cmp_exact_filter from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.common_config import required_linux_kernel_version @@ -95,24 +96,29 @@ def open_json_file(filename): assert False, "Could not read file {}".format(filename) -def check_rib(name, cmd, expected_file, count=30, wait=0.5): - def _check(name, dest_addr, match): +def check_rib(name, cmd, expected_file, count=10, wait=0.5): + def _check(router, cmd, expected): logger.info("polling") tgen = get_topogen() - router = tgen.gears[name] output = json.loads(router.vtysh_cmd(cmd)) - expected = open_json_file("{}/{}".format(CWD, expected_file)) return topotest.json_cmp(output, expected) logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() - func = functools.partial(_check, name, cmd, expected_file) + router = tgen.gears[name] + expected = open_json_file("{}/{}".format(CWD, expected_file)) + if "show bgp" in cmd and "vpn" in cmd: + func = functools.partial( + bgp_vpn_router_json_cmp_exact_filter, tgen.gears[name], cmd, expected + ) + else: + func = functools.partial(_check, router, cmd, expected) _, result = topotest.run_and_expect(func, None, count, wait) assert result is None, "Failed" def test_rib(): - check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 120, 1) + check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 10, 1) check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json") check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json") check_rib("r1", "show ip route vrf vrf20 json", "r1/vrf20v4_rib.json") diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf new file mode 100644 index 0000000000..a2f5aef51e --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf @@ -0,0 +1,35 @@ +frr defaults traditional +bgp send-extra-data zebra +!debug bgp neighbor-events +!debug bgp zebra +!debug bgp vnc verbose +!debug bgp update-groups +!debug bgp updates in +!debug bgp updates out +!debug bgp vpn label +!debug bgp vpn leak-from-vrf +!debug bgp vpn leak-to-vrf +!debug bgp vpn rmap-event +! +router bgp 65001 + bgp router-id 1.0.0.1 + no bgp ebgp-requires-policy + !no bgp default ipv4-unicast + neighbor fd01::1 remote-as 1 + neighbor fd01::1 timers 3 10 + neighbor fd01::1 timers connect 1 + neighbor fd01::1 interface eth0 + neighbor fd01::1 update-source fd01::2 + neighbor fd01::1 capability extended-nexthop + ! + address-family ipv4 unicast + network 192.168.1.0 mask 255.255.255.0 + neighbor fd01::1 activate + exit-address-family + ! + address-family ipv6 unicast + network 2001:1::/64 + neighbor fd01::1 activate + exit-address-family + ! +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json new file mode 100644 index 0000000000..352c48b1b2 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json @@ -0,0 +1,59 @@ +{ + "192.168.1.0/24": [ + { + "prefix": "192.168.1.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "dum0", + "active": true, + "weight": 1 + } + ] + } + ], + "192.168.2.0/24": [ + { + "prefix": "192.168.2.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "active": true, + "weight": 1 + } + ], + "asPath": "1 2 65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json new file mode 100644 index 0000000000..fd10ee326f --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json @@ -0,0 +1,59 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "prefixLen": 64, + "protocol": "connected", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "dum0", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "active": true, + "weight": 1 + } + ], + "asPath": "1 2 65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh new file mode 100644 index 0000000000..88bdcbda82 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh @@ -0,0 +1 @@ +ip link add dum0 type dummy diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf new file mode 100644 index 0000000000..16102a055d --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf @@ -0,0 +1,12 @@ +interface eth0 + ipv6 address fd01::2/64 +! +interface dum0 + ip address 192.168.1.1/24 + ipv6 address 2001:1::1/64 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf new file mode 100644 index 0000000000..e6b40c4bfe --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf @@ -0,0 +1,35 @@ +frr defaults traditional +bgp send-extra-data zebra +!debug bgp neighbor-events +!debug bgp zebra +!debug bgp vnc verbose +!debug bgp update-groups +!debug bgp updates in +!debug bgp updates out +!debug bgp vpn label +!debug bgp vpn leak-from-vrf +!debug bgp vpn leak-to-vrf +!debug bgp vpn rmap-event +! +router bgp 65002 + bgp router-id 2.0.0.2 + no bgp ebgp-requires-policy + !no bgp default ipv4-unicast + neighbor fd02::1 remote-as 2 + neighbor fd02::1 timers 3 10 + neighbor fd02::1 timers connect 1 + neighbor fd02::1 interface eth0 + neighbor fd02::1 update-source fd02::2 + neighbor fd02::1 capability extended-nexthop + ! + address-family ipv4 unicast + network 192.168.2.0 mask 255.255.255.0 + neighbor fd02::1 activate + exit-address-family + ! + address-family ipv6 unicast + network 2001:2::/64 + neighbor fd02::1 activate + exit-address-family + ! +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json new file mode 100644 index 0000000000..936f239ea6 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json @@ -0,0 +1,59 @@ +{ + "192.168.1.0/24": [ + { + "prefix": "192.168.1.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "active": true, + "weight": 1 + } + ], + "asPath": "2 1 65001" + } + ], + "192.168.2.0/24": [ + { + "prefix": "192.168.2.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "dum0", + "active": true, + "weight": 1 + } + ] + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json new file mode 100644 index 0000000000..260adbc20c --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json @@ -0,0 +1,59 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "active": true, + "weight": 1 + } + ], + "asPath": "2 1 65001" + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "prefixLen": 64, + "protocol": "connected", + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "dum0", + "active": true, + "weight": 1 + } + ] + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh new file mode 100644 index 0000000000..88bdcbda82 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh @@ -0,0 +1 @@ +ip link add dum0 type dummy diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf new file mode 100644 index 0000000000..f17e96a0da --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf @@ -0,0 +1,12 @@ +interface eth0 + ipv6 address fd02::2/64 +! +interface dum0 + ip address 192.168.2.1/24 + ipv6 address 2001:2::1/64 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/bgpd.conf index 8079bb0c2a..d0be14f007 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/bgpd.conf @@ -1,14 +1,7 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r1 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events +!debug bgp nht !debug bgp zebra !debug bgp vnc verbose !debug bgp update-groups @@ -21,11 +14,16 @@ log commands ! router bgp 1 bgp router-id 1.1.1.1 - no bgp ebgp-requires-policy no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor 2001::2 remote-as 2 neighbor 2001::2 timers 3 10 neighbor 2001::2 timers connect 1 + neighbor 2001::2 capability extended-nexthop + ! + address-family ipv4 vpn + neighbor 2001::2 activate + exit-address-family ! address-family ipv6 vpn neighbor 2001::2 activate @@ -38,28 +36,28 @@ router bgp 1 router bgp 1 vrf vrf10 bgp router-id 1.1.1.1 no bgp ebgp-requires-policy - no bgp default ipv4-unicast + sid vpn per-vrf export auto + neighbor fd01::2 remote-as 65001 + neighbor fd01::2 capability extended-nexthop + neighbor fd01::2 description ce1 + neighbor fd01::2 interface eth1 + neighbor fd01::2 update-source fd01::1 ! - address-family ipv6 unicast - sid vpn export auto + address-family ipv4 unicast + nexthop vpn export 2001::1 rd vpn export 1:10 rt vpn both 99:99 import vpn export vpn - redistribute connected + neighbor fd01::2 activate exit-address-family -! -router bgp 1 vrf vrf20 - bgp router-id 1.1.1.1 - no bgp ebgp-requires-policy - no bgp default ipv4-unicast ! address-family ipv6 unicast - sid vpn export auto - rd vpn export 1:20 - rt vpn both 88:88 + nexthop vpn export 2001::1 + rd vpn export 1:10 + rt vpn both 99:99 import vpn export vpn - redistribute connected + neighbor fd01::2 activate exit-address-family ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh new file mode 100644 index 0000000000..ac1844f733 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh @@ -0,0 +1,4 @@ +sysctl net.vrf.strict_mode=1 +ip link add vrf10 type vrf table 10 +ip link set vrf10 up +ip link set eth1 master vrf10 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json new file mode 100644 index 0000000000..6cdeac2991 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json @@ -0,0 +1,64 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "1.1.1.1", + "defaultLocPrf": 100, + "localAS": 1, + "routes": { + "routeDistinguishers": { + "1:10": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.1.0", + "prefixLen": 24, + "network": "192.168.1.0/24", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "65001", + "origin": "IGP", + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "2:10": { + "192.168.2.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.2.0", + "prefixLen": 24, + "network": "192.168.2.0/24", + "metric": 0, + "weight": 0, + "peerId": "2001::2", + "path": "2 65002", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json new file mode 100644 index 0000000000..77b272de65 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json @@ -0,0 +1,63 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "1.1.1.1", + "defaultLocPrf": 100, + "localAS": 1, + "routes": { + "routeDistinguishers": { + "1:10": { + "2001:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:1::", + "prefixLen": 64, + "network": "2001:1::/64", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "65001", + "origin": "IGP", + "nhVrfName": "vrf10", + "nexthops": [ + { + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "2:10": { + "2001:2::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:2::", + "prefixLen": 64, + "network": "2001:2::/64", + "metric": 0, + "weight": 0, + "peerId": "2001::2", + "path": "2 65002", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json new file mode 100644 index 0000000000..f7da30637b --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json @@ -0,0 +1,62 @@ +{ + "192.168.1.0/24": [ + { + "prefix": "192.168.1.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth1", + "active": true + } + ], + "asPath": "65001" + } + ], + "192.168.2.0/24": [ + { + "prefix": "192.168.2.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "vrf": "default", + "active": true, + "seg6": { + "segs": "2001:db8:2:2:1::" + } + } + ], + "asPath": "2 65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json new file mode 100644 index 0000000000..12e7087060 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json @@ -0,0 +1,63 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth1", + "active": true, + "weight": 1 + } + ], + "asPath": "65001" + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "vrf": "default", + "active": true, + "seg6": { + "segs": "2001:db8:2:2:1::" + } + } + ], + "asPath": "2 65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf new file mode 100644 index 0000000000..42e3f5bd89 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf @@ -0,0 +1,21 @@ +interface eth0 + ipv6 address 2001::1/64 +! +interface eth1 vrf vrf10 + ipv6 address fd01::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix 2001:db8:1:1::/64 + ! + ! +! +ip forwarding +ipv6 forwarding +! +ipv6 route 2001:db8:2:2::/64 2001::2 +! +line vty +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/bgpd.conf index c2e8530273..31cf9f9b5d 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/bgpd.conf @@ -1,20 +1,12 @@ frr defaults traditional -! bgp send-extra-data zebra -! -hostname r2 -password zebra -! -log stdout notifications -log commands -! !debug bgp neighbor-events +!debug bgp nht !debug bgp zebra !debug bgp vnc verbose !debug bgp update-groups !debug bgp updates in !debug bgp updates out -!debug bgp updates !debug bgp vpn label !debug bgp vpn leak-from-vrf !debug bgp vpn leak-to-vrf @@ -22,11 +14,16 @@ log commands ! router bgp 2 bgp router-id 2.2.2.2 - no bgp ebgp-requires-policy no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor 2001::1 remote-as 1 neighbor 2001::1 timers 3 10 neighbor 2001::1 timers connect 1 + neighbor 2001::1 capability extended-nexthop + ! + address-family ipv4 vpn + neighbor 2001::1 activate + exit-address-family ! address-family ipv6 vpn neighbor 2001::1 activate @@ -39,28 +36,28 @@ router bgp 2 router bgp 2 vrf vrf10 bgp router-id 2.2.2.2 no bgp ebgp-requires-policy - no bgp default ipv4-unicast + sid vpn per-vrf export auto + neighbor fd02::2 remote-as 65002 + neighbor fd02::2 capability extended-nexthop + neighbor fd02::2 description ce2 + neighbor fd02::2 interface eth1 + neighbor fd02::2 update-source fd02::1 ! - address-family ipv6 unicast - sid vpn export auto + address-family ipv4 unicast + nexthop vpn export 2001::2 rd vpn export 2:10 rt vpn both 99:99 import vpn export vpn - redistribute connected + neighbor fd02::2 activate exit-address-family -! -router bgp 2 vrf vrf20 - bgp router-id 2.2.2.2 - no bgp ebgp-requires-policy - no bgp default ipv4-unicast ! address-family ipv6 unicast - sid vpn export auto - rd vpn export 2:20 - rt vpn both 88:88 + nexthop vpn export 2001::2 + rd vpn export 2:10 + rt vpn both 99:99 import vpn export vpn - redistribute connected + neighbor fd02::2 activate exit-address-family ! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh new file mode 100644 index 0000000000..ac1844f733 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh @@ -0,0 +1,4 @@ +sysctl net.vrf.strict_mode=1 +ip link add vrf10 type vrf table 10 +ip link set vrf10 up +ip link set eth1 master vrf10 diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json new file mode 100644 index 0000000000..c1f67a771c --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json @@ -0,0 +1,64 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "2.2.2.2", + "defaultLocPrf": 100, + "localAS": 2, + "routes": { + "routeDistinguishers": { + "1:10": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.1.0", + "prefixLen": 24, + "network": "192.168.1.0/24", + "metric": 0, + "weight": 0, + "peerId": "2001::1", + "path": "1 65001", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "2:10": { + "192.168.2.0/24": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "192.168.2.0", + "prefixLen": 24, + "network": "192.168.2.0/24", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "65002", + "origin": "IGP", + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "2001::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json new file mode 100644 index 0000000000..da3ddd0699 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json @@ -0,0 +1,63 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "2.2.2.2", + "defaultLocPrf": 100, + "localAS": 2, + "routes": { + "routeDistinguishers": { + "1:10": { + "2001:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:1::", + "prefixLen": 64, + "network": "2001:1::/64", + "metric": 0, + "weight": 0, + "peerId": "2001::1", + "path": "1 65001", + "origin": "IGP", + "nexthops": [ + { + "ip": "2001::1", + "hostname": "r1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "2:10": { + "2001:2::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:2::", + "prefixLen": 64, + "network": "2001:2::/64", + "metric": 0, + "weight": 0, + "peerId": "(unspec)", + "path": "65002", + "origin": "IGP", + "nhVrfName": "vrf10", + "nexthops": [ + { + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json new file mode 100644 index 0000000000..5cc093fea8 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json @@ -0,0 +1,63 @@ +{ + "192.168.1.0/24": [ + { + "prefix": "192.168.1.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "vrf": "default", + "active": true, + "seg6": { + "segs": "2001:db8:1:1:1::" + } + } + ], + "asPath": "1 65001" + } + ], + "192.168.2.0/24": [ + { + "prefix": "192.168.2.0/24", + "prefixLen": 24, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth1", + "active": true, + "weight": 1 + } + ], + "asPath": "65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json new file mode 100644 index 0000000000..5e8114e17b --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json @@ -0,0 +1,63 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth0", + "vrf": "default", + "active": true, + "seg6": { + "segs": "2001:db8:1:1:1::" + } + } + ], + "asPath": "1 65001" + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "prefixLen": 64, + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth1", + "active": true, + "weight": 1 + } + ], + "asPath": "65002" + } + ] +} diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf new file mode 100644 index 0000000000..551e7d7692 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf @@ -0,0 +1,21 @@ +interface eth0 + ipv6 address 2001::2/64 +! +interface eth1 vrf vrf10 + ipv6 address fd02::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix 2001:db8:2:2::/64 + ! + ! +! +ip forwarding +ipv6 forwarding +! +ipv6 route 2001:db8:1:1::/64 2001::1 +! +line vty +! diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py new file mode 100644 index 0000000000..88bc9847f3 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2025, Onvox LLC +# Authored by Jonathan Voss <jvoss@onvox.net> +# +# Test SRv6 L3VPN with CE BGP peers within a VRF +# + +import os +import re +import sys +import json +import functools +import pytest + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.common_config import required_linux_kernel_version +from lib.checkping import check_ping + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_router("ce1") + tgen.add_router("ce2") + + tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "eth0", "eth0") + tgen.add_link(tgen.gears["ce1"], tgen.gears["r1"], "eth0", "eth1") + tgen.add_link(tgen.gears["ce2"], tgen.gears["r2"], "eth0", "eth1") + + +def setup_module(mod): + result = required_linux_kernel_version("5.14") + if result is not True: + pytest.skip("Kernel requirements are not met") + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + for rname, router in tgen.routers().items(): + if os.path.exists("{}/{}/setup.sh".format(CWD, rname)): + router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def open_json_file(filename): + try: + with open(filename, "r") as f: + return json.load(f) + except IOError: + assert False, "Could not read file {}".format(filename) + + +def check_rib(name, cmd, expected_file, count=30, wait=0.5): + def _check(name, dest_addr, match): + logger.info("polling") + tgen = get_topogen() + router = tgen.gears[name] + output = json.loads(router.vtysh_cmd(cmd)) + expected = open_json_file("{}/{}".format(CWD, expected_file)) + return topotest.json_cmp(output, expected) + + logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) + tgen = get_topogen() + func = functools.partial(_check, name, cmd, expected_file) + _, result = topotest.run_and_expect(func, None, count, wait) + assert result is None, "Failed" + + +def test_rib(): + check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 120, 1) + check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json") + check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json") + check_rib("r2", "show ip route vrf vrf10 json", "r2/vrf10v4_rib.json") + check_rib("ce1", "show ip route json", "ce1/ip_rib.json") + check_rib("ce2", "show ip route json", "ce2/ip_rib.json") + + check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json") + check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json") + check_rib("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10v6_rib.json") + check_rib("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10v6_rib.json") + check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json") + check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json") + + +def test_ping(): + # IPv4 CE1 to CE2 + check_ping("ce1", "192.168.2.1", True, 10, 3, "192.168.1.1") + # IPv4 CE2 to CE1 + check_ping("ce2", "192.168.1.1", True, 10, 3, "192.168.2.1") + # IPv6 CE1 to CE2 + check_ping("ce1", "2001:2::1", True, 10, 3, "2001:1::1") + # IPv6 CE2 to CE1 + check_ping("ce2", "2001:1::1", True, 10, 3, "2001:2::1") + + +def test_ce_neighbor_reset(): + # Clear CE to R peerings and ensure route exports after + # re-established propogate to VPNv4/VPNv6 and function correctly + tgen = get_topogen() + + for router in ["ce1", "ce2"]: + tgen.gears[router].vtysh_cmd("clear bgp *") + + test_ping() + test_rib() + + +def test_pe_neighbor_reset(): + # Clear R to R peering and ensure route exports after + # re-established propogate to VPNv4/VPNv6 and function correctly + tgen = get_topogen() + + tgen.gears["r1"].vtysh_cmd("clear bgp *") + + test_ping() + test_rib() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/high_ecmp/r1/frr.conf b/tests/topotests/high_ecmp/r1/frr.conf index 957e17e914..e64fb2e416 100644 --- a/tests/topotests/high_ecmp/r1/frr.conf +++ b/tests/topotests/high_ecmp/r1/frr.conf @@ -2577,3 +2577,8 @@ interface r1-eth514 ipv6 address 2001:db8:3:5::1/64 no shut ! +router bgp 1001 + timers bgp 5 60 + no bgp ebgp-requires-policy + read-quanta 1 +! diff --git a/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf b/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf index df64a146bc..ad7b9df919 100644 --- a/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf +++ b/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf @@ -1,7 +1,4 @@ router bgp 1001 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor 10.1.1.2 remote-as external neighbor 10.1.2.2 remote-as external neighbor 10.1.3.2 remote-as external diff --git a/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf b/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf index 15137a8715..9f4b961d82 100644 --- a/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf +++ b/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf @@ -1,7 +1,4 @@ router bgp 1001 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor 2001:db8:1:1::2 remote-as external neighbor 2001:db8:1:2::2 remote-as external neighbor 2001:db8:1:3::2 remote-as external diff --git a/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf b/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf index 7985fe6e99..7f83c6a25c 100644 --- a/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf +++ b/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf @@ -1,7 +1,4 @@ router bgp 1001 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor r1-eth0 interface remote-as external neighbor r1-eth1 interface remote-as external neighbor r1-eth2 interface remote-as external @@ -520,3 +517,209 @@ router bgp 1001 address-family ipv4 uni redistribute sharp + +address-family ipv6 unicast + redistribute sharp + neighbor r1-eth0 activate + neighbor r1-eth1 activate + neighbor r1-eth2 activate + neighbor r1-eth3 activate + neighbor r1-eth4 activate + neighbor r1-eth5 activate + neighbor r1-eth6 activate + neighbor r1-eth7 activate + neighbor r1-eth8 activate + neighbor r1-eth9 activate + neighbor r1-eth10 activate + neighbor r1-eth11 activate + neighbor r1-eth12 activate + neighbor r1-eth13 activate + neighbor r1-eth14 activate + neighbor r1-eth15 activate + neighbor r1-eth16 activate + neighbor r1-eth17 activate + neighbor r1-eth18 activate + neighbor r1-eth19 activate + neighbor r1-eth20 activate + neighbor r1-eth21 activate + neighbor r1-eth22 activate + neighbor r1-eth23 activate + neighbor r1-eth24 activate + neighbor r1-eth25 activate + neighbor r1-eth26 activate + neighbor r1-eth27 activate + neighbor r1-eth28 activate + neighbor r1-eth29 activate + neighbor r1-eth30 activate + neighbor r1-eth31 activate + neighbor r1-eth32 activate + neighbor r1-eth33 activate + neighbor r1-eth34 activate + neighbor r1-eth35 activate + neighbor r1-eth36 activate + neighbor r1-eth37 activate + neighbor r1-eth38 activate + neighbor r1-eth39 activate + neighbor r1-eth40 activate + neighbor r1-eth41 activate + neighbor r1-eth42 activate + neighbor r1-eth43 activate + neighbor r1-eth44 activate + neighbor r1-eth45 activate + neighbor r1-eth46 activate + neighbor r1-eth47 activate + neighbor r1-eth48 activate + neighbor r1-eth49 activate + neighbor r1-eth50 activate + neighbor r1-eth51 activate + neighbor r1-eth52 activate + neighbor r1-eth53 activate + neighbor r1-eth54 activate + neighbor r1-eth55 activate + neighbor r1-eth56 activate + neighbor r1-eth57 activate + neighbor r1-eth58 activate + neighbor r1-eth59 activate + neighbor r1-eth60 activate + neighbor r1-eth61 activate + neighbor r1-eth62 activate + neighbor r1-eth63 activate + neighbor r1-eth64 activate + neighbor r1-eth65 activate + neighbor r1-eth66 activate + neighbor r1-eth67 activate + neighbor r1-eth68 activate + neighbor r1-eth69 activate + neighbor r1-eth70 activate + neighbor r1-eth71 activate + neighbor r1-eth72 activate + neighbor r1-eth73 activate + neighbor r1-eth74 activate + neighbor r1-eth75 activate + neighbor r1-eth76 activate + neighbor r1-eth77 activate + neighbor r1-eth78 activate + neighbor r1-eth79 activate + neighbor r1-eth80 activate + neighbor r1-eth81 activate + neighbor r1-eth82 activate + neighbor r1-eth83 activate + neighbor r1-eth84 activate + neighbor r1-eth85 activate + neighbor r1-eth86 activate + neighbor r1-eth87 activate + neighbor r1-eth88 activate + neighbor r1-eth89 activate + neighbor r1-eth90 activate + neighbor r1-eth91 activate + neighbor r1-eth92 activate + neighbor r1-eth93 activate + neighbor r1-eth94 activate + neighbor r1-eth95 activate + neighbor r1-eth96 activate + neighbor r1-eth97 activate + neighbor r1-eth98 activate + neighbor r1-eth99 activate + neighbor r1-eth100 activate + neighbor r1-eth101 activate + neighbor r1-eth102 activate + neighbor r1-eth103 activate + neighbor r1-eth104 activate + neighbor r1-eth105 activate + neighbor r1-eth106 activate + neighbor r1-eth107 activate + neighbor r1-eth108 activate + neighbor r1-eth109 activate + neighbor r1-eth110 activate + neighbor r1-eth111 activate + neighbor r1-eth112 activate + neighbor r1-eth113 activate + neighbor r1-eth114 activate + neighbor r1-eth115 activate + neighbor r1-eth116 activate + neighbor r1-eth117 activate + neighbor r1-eth118 activate + neighbor r1-eth119 activate + neighbor r1-eth120 activate + neighbor r1-eth121 activate + neighbor r1-eth122 activate + neighbor r1-eth123 activate + neighbor r1-eth124 activate + neighbor r1-eth125 activate + neighbor r1-eth126 activate + neighbor r1-eth127 activate + neighbor r1-eth128 activate + neighbor r1-eth129 activate + neighbor r1-eth130 activate + neighbor r1-eth131 activate + neighbor r1-eth132 activate + neighbor r1-eth133 activate + neighbor r1-eth134 activate + neighbor r1-eth135 activate + neighbor r1-eth136 activate + neighbor r1-eth137 activate + neighbor r1-eth138 activate + neighbor r1-eth139 activate + neighbor r1-eth140 activate + neighbor r1-eth141 activate + neighbor r1-eth142 activate + neighbor r1-eth143 activate + neighbor r1-eth144 activate + neighbor r1-eth145 activate + neighbor r1-eth146 activate + neighbor r1-eth147 activate + neighbor r1-eth148 activate + neighbor r1-eth149 activate + neighbor r1-eth150 activate + neighbor r1-eth151 activate + neighbor r1-eth152 activate + neighbor r1-eth153 activate + neighbor r1-eth154 activate + neighbor r1-eth155 activate + neighbor r1-eth156 activate + neighbor r1-eth157 activate + neighbor r1-eth158 activate + neighbor r1-eth159 activate + neighbor r1-eth160 activate + neighbor r1-eth161 activate + neighbor r1-eth162 activate + neighbor r1-eth163 activate + neighbor r1-eth164 activate + neighbor r1-eth165 activate + neighbor r1-eth166 activate + neighbor r1-eth167 activate + neighbor r1-eth168 activate + neighbor r1-eth169 activate + neighbor r1-eth170 activate + neighbor r1-eth171 activate + neighbor r1-eth172 activate + neighbor r1-eth173 activate + neighbor r1-eth174 activate + neighbor r1-eth175 activate + neighbor r1-eth176 activate + neighbor r1-eth177 activate + neighbor r1-eth178 activate + neighbor r1-eth179 activate + neighbor r1-eth180 activate + neighbor r1-eth181 activate + neighbor r1-eth182 activate + neighbor r1-eth183 activate + neighbor r1-eth184 activate + neighbor r1-eth185 activate + neighbor r1-eth186 activate + neighbor r1-eth187 activate + neighbor r1-eth188 activate + neighbor r1-eth189 activate + neighbor r1-eth190 activate + neighbor r1-eth191 activate + neighbor r1-eth192 activate + neighbor r1-eth193 activate + neighbor r1-eth194 activate + neighbor r1-eth195 activate + neighbor r1-eth196 activate + neighbor r1-eth197 activate + neighbor r1-eth198 activate + neighbor r1-eth199 activate + neighbor r1-eth200 activate + exit-address-family +exit
\ No newline at end of file diff --git a/tests/topotests/high_ecmp/r2/frr.conf b/tests/topotests/high_ecmp/r2/frr.conf index 151f6da45c..1e98e31236 100644 --- a/tests/topotests/high_ecmp/r2/frr.conf +++ b/tests/topotests/high_ecmp/r2/frr.conf @@ -2577,3 +2577,8 @@ interface r2-eth514 ipv6 address 2001:db8:3:5::2/64 no shutdown ! +router bgp 1002 + timers bgp 5 60 + no bgp ebgp-requires-policy + read-quanta 1 +! diff --git a/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf b/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf index 48842bbfc2..afc3a30c7d 100644 --- a/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf +++ b/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf @@ -1,7 +1,4 @@ router bgp 1002 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor 10.1.1.1 remote-as external neighbor 10.1.2.1 remote-as external neighbor 10.1.3.1 remote-as external diff --git a/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf b/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf index e3258cabd4..b0728d3069 100644 --- a/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf +++ b/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf @@ -1,7 +1,4 @@ router bgp 1002 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor 2001:db8:1:1::1 remote-as external neighbor 2001:db8:1:2::1 remote-as external neighbor 2001:db8:1:3::1 remote-as external diff --git a/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf b/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf index 23827789fb..9428af3440 100644 --- a/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf +++ b/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf @@ -1,7 +1,4 @@ router bgp 1002 - timers bgp 5 20 - no bgp ebgp-requires-policy - read-quanta 1 neighbor r2-eth0 interface remote-as external neighbor r2-eth1 interface remote-as external neighbor r2-eth2 interface remote-as external @@ -518,3 +515,208 @@ router bgp 1002 neighbor r2-eth513 interface remote-as external neighbor r2-eth514 interface remote-as external + address-family ipv6 unicast + redistribute sharp + neighbor r2-eth0 activate + neighbor r2-eth1 activate + neighbor r2-eth2 activate + neighbor r2-eth3 activate + neighbor r2-eth4 activate + neighbor r2-eth5 activate + neighbor r2-eth6 activate + neighbor r2-eth7 activate + neighbor r2-eth8 activate + neighbor r2-eth9 activate + neighbor r2-eth10 activate + neighbor r2-eth11 activate + neighbor r2-eth12 activate + neighbor r2-eth13 activate + neighbor r2-eth14 activate + neighbor r2-eth15 activate + neighbor r2-eth16 activate + neighbor r2-eth17 activate + neighbor r2-eth18 activate + neighbor r2-eth19 activate + neighbor r2-eth20 activate + neighbor r2-eth21 activate + neighbor r2-eth22 activate + neighbor r2-eth23 activate + neighbor r2-eth24 activate + neighbor r2-eth25 activate + neighbor r2-eth26 activate + neighbor r2-eth27 activate + neighbor r2-eth28 activate + neighbor r2-eth29 activate + neighbor r2-eth30 activate + neighbor r2-eth31 activate + neighbor r2-eth32 activate + neighbor r2-eth33 activate + neighbor r2-eth34 activate + neighbor r2-eth35 activate + neighbor r2-eth36 activate + neighbor r2-eth37 activate + neighbor r2-eth38 activate + neighbor r2-eth39 activate + neighbor r2-eth40 activate + neighbor r2-eth41 activate + neighbor r2-eth42 activate + neighbor r2-eth43 activate + neighbor r2-eth44 activate + neighbor r2-eth45 activate + neighbor r2-eth46 activate + neighbor r2-eth47 activate + neighbor r2-eth48 activate + neighbor r2-eth49 activate + neighbor r2-eth50 activate + neighbor r2-eth51 activate + neighbor r2-eth52 activate + neighbor r2-eth53 activate + neighbor r2-eth54 activate + neighbor r2-eth55 activate + neighbor r2-eth56 activate + neighbor r2-eth57 activate + neighbor r2-eth58 activate + neighbor r2-eth59 activate + neighbor r2-eth60 activate + neighbor r2-eth61 activate + neighbor r2-eth62 activate + neighbor r2-eth63 activate + neighbor r2-eth64 activate + neighbor r2-eth65 activate + neighbor r2-eth66 activate + neighbor r2-eth67 activate + neighbor r2-eth68 activate + neighbor r2-eth69 activate + neighbor r2-eth70 activate + neighbor r2-eth71 activate + neighbor r2-eth72 activate + neighbor r2-eth73 activate + neighbor r2-eth74 activate + neighbor r2-eth75 activate + neighbor r2-eth76 activate + neighbor r2-eth77 activate + neighbor r2-eth78 activate + neighbor r2-eth79 activate + neighbor r2-eth80 activate + neighbor r2-eth81 activate + neighbor r2-eth82 activate + neighbor r2-eth83 activate + neighbor r2-eth84 activate + neighbor r2-eth85 activate + neighbor r2-eth86 activate + neighbor r2-eth87 activate + neighbor r2-eth88 activate + neighbor r2-eth89 activate + neighbor r2-eth90 activate + neighbor r2-eth91 activate + neighbor r2-eth92 activate + neighbor r2-eth93 activate + neighbor r2-eth94 activate + neighbor r2-eth95 activate + neighbor r2-eth96 activate + neighbor r2-eth97 activate + neighbor r2-eth98 activate + neighbor r2-eth99 activate + neighbor r2-eth100 activate + neighbor r2-eth101 activate + neighbor r2-eth102 activate + neighbor r2-eth103 activate + neighbor r2-eth104 activate + neighbor r2-eth105 activate + neighbor r2-eth106 activate + neighbor r2-eth107 activate + neighbor r2-eth108 activate + neighbor r2-eth109 activate + neighbor r2-eth110 activate + neighbor r2-eth111 activate + neighbor r2-eth112 activate + neighbor r2-eth113 activate + neighbor r2-eth114 activate + neighbor r2-eth115 activate + neighbor r2-eth116 activate + neighbor r2-eth117 activate + neighbor r2-eth118 activate + neighbor r2-eth119 activate + neighbor r2-eth120 activate + neighbor r2-eth121 activate + neighbor r2-eth122 activate + neighbor r2-eth123 activate + neighbor r2-eth124 activate + neighbor r2-eth125 activate + neighbor r2-eth126 activate + neighbor r2-eth127 activate + neighbor r2-eth128 activate + neighbor r2-eth129 activate + neighbor r2-eth130 activate + neighbor r2-eth131 activate + neighbor r2-eth132 activate + neighbor r2-eth133 activate + neighbor r2-eth134 activate + neighbor r2-eth135 activate + neighbor r2-eth136 activate + neighbor r2-eth137 activate + neighbor r2-eth138 activate + neighbor r2-eth139 activate + neighbor r2-eth140 activate + neighbor r2-eth141 activate + neighbor r2-eth142 activate + neighbor r2-eth143 activate + neighbor r2-eth144 activate + neighbor r2-eth145 activate + neighbor r2-eth146 activate + neighbor r2-eth147 activate + neighbor r2-eth148 activate + neighbor r2-eth149 activate + neighbor r2-eth150 activate + neighbor r2-eth151 activate + neighbor r2-eth152 activate + neighbor r2-eth153 activate + neighbor r2-eth154 activate + neighbor r2-eth155 activate + neighbor r2-eth156 activate + neighbor r2-eth157 activate + neighbor r2-eth158 activate + neighbor r2-eth159 activate + neighbor r2-eth160 activate + neighbor r2-eth161 activate + neighbor r2-eth162 activate + neighbor r2-eth163 activate + neighbor r2-eth164 activate + neighbor r2-eth165 activate + neighbor r2-eth166 activate + neighbor r2-eth167 activate + neighbor r2-eth168 activate + neighbor r2-eth169 activate + neighbor r2-eth170 activate + neighbor r2-eth171 activate + neighbor r2-eth172 activate + neighbor r2-eth173 activate + neighbor r2-eth174 activate + neighbor r2-eth175 activate + neighbor r2-eth176 activate + neighbor r2-eth177 activate + neighbor r2-eth178 activate + neighbor r2-eth179 activate + neighbor r2-eth180 activate + neighbor r2-eth181 activate + neighbor r2-eth182 activate + neighbor r2-eth183 activate + neighbor r2-eth184 activate + neighbor r2-eth185 activate + neighbor r2-eth186 activate + neighbor r2-eth187 activate + neighbor r2-eth188 activate + neighbor r2-eth189 activate + neighbor r2-eth190 activate + neighbor r2-eth191 activate + neighbor r2-eth192 activate + neighbor r2-eth193 activate + neighbor r2-eth194 activate + neighbor r2-eth195 activate + neighbor r2-eth196 activate + neighbor r2-eth197 activate + neighbor r2-eth198 activate + neighbor r2-eth199 activate + neighbor r2-eth200 activate +exit-address-family +exit diff --git a/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py b/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py index 0947272386..ed6257f72e 100644 --- a/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py +++ b/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py @@ -21,6 +21,12 @@ import re import sys import pytest import json +from time import sleep + +from lib.common_config import ( + kill_router_daemons, + start_router_daemons, +) pytestmark = [pytest.mark.bgpd] @@ -99,6 +105,171 @@ def teardown_module(_mod): tgen.stop_topology() +def test_bgp_route_cleanup(): + failures = 0 + net = get_topogen().net + expected_route_count = 2000 + + # First, extract IPv4 and IPv6 loopback addresses from r1 + lo_output = net["r1"].cmd("vtysh -c 'show interface lo'") + + # Extract IPv4 and IPv6 addresses from the output + ipv4_match = re.search(r"inet (\d+\.\d+\.\d+\.\d+)/\d+", lo_output) + ipv6_match = re.search(r"inet6 ([0-9a-f:]+)/\d+", lo_output) + + if not ipv4_match or not ipv6_match: + assert False, "Could not find IPv4 or IPv6 address on loopback interface" + + ipv4_nexthop = ipv4_match.group(1) + ipv6_nexthop = ipv6_match.group(1) + + print(f"\nUsing nexthops: IPv4={ipv4_nexthop}, IPv6={ipv6_nexthop}") + + # Install IPv4 routes + ipv4_cmd = f"vtysh -c 'sharp install routes 39.99.0.0 nexthop {ipv4_nexthop} {expected_route_count}'" + net["r1"].cmd(ipv4_cmd) + + # Install IPv6 routes + ipv6_cmd = f"vtysh -c 'sharp install routes 2100:cafe:: nexthop {ipv6_nexthop} {expected_route_count}'" + net["r1"].cmd(ipv6_cmd) + + # Initialize actual counts + ipv4_actual_count = 0 + ipv6_actual_count = 0 + max_attempts = 12 # 60 seconds max (12 * 5) + attempt = 0 + + # Wait until both IPv4 and IPv6 routes are installed + while ( + ipv4_actual_count != expected_route_count + or ipv6_actual_count != expected_route_count + ) and attempt < max_attempts: + sleep(5) + attempt += 1 + + # Get current IPv4 route count + ipv4_count_str = ( + net["r2"] + .cmd('vtysh -c "show bgp ipv4 unicast" | grep "39.99" | wc -l') + .rstrip() + ) + + # Get current IPv6 route count + ipv6_count_str = ( + net["r2"] + .cmd('vtysh -c "show bgp ipv6 unicast" | grep "cafe" | wc -l') + .rstrip() + ) + + try: + ipv4_actual_count = int(ipv4_count_str) + except ValueError: + ipv4_actual_count = 0 + + try: + ipv6_actual_count = int(ipv6_count_str) + except ValueError: + ipv6_actual_count = 0 + + print(f"Attempt {attempt}") + print(f"IPv4 Routes found: {ipv4_actual_count} / {expected_route_count}") + print(f"IPv6 Routes found: {ipv6_actual_count} / {expected_route_count}") + + # Verify we have the expected number of routes + if ipv4_actual_count != expected_route_count: + sys.stderr.write( + f"Failed to install expected IPv4 routes: got {ipv4_actual_count}, expected {expected_route_count}\n" + ) + failures += 1 + else: + print("IPv4 routes successfully installed") + + if ipv6_actual_count != expected_route_count: + sys.stderr.write( + f"Failed to install expected IPv6 routes: got {ipv6_actual_count}, expected {expected_route_count}\n" + ) + failures += 1 + else: + print("IPv6 routes successfully installed") + + # Stop bgpd in r1 to trigger deletion of routes in r2 + kill_router_daemons(get_topogen(), "r1", ["bgpd"]) + + # Initialize variables for post-removal check + # Start with the original count + ipv4_final_count = expected_route_count + ipv6_final_count = expected_route_count + expected_final_count = 0 + attempt = 0 + max_removal_attempts = 12 + + # Wait until both IPv4 and IPv6 routes are fully removed + while ( + ipv4_final_count != expected_final_count + or ipv6_final_count != expected_final_count + ) and attempt < max_removal_attempts: + sleep(5) + attempt += 1 + + # Get current IPv4 route count + ipv4_count_str = ( + net["r2"] + .cmd('vtysh -c "show bgp ipv4 unicast" | grep "39.99" | wc -l') + .rstrip() + ) + + # Get current IPv6 route count + ipv6_count_str = ( + net["r2"] + .cmd('vtysh -c "show bgp ipv6 unicast" | grep "cafe" | wc -l') + .rstrip() + ) + + try: + ipv4_final_count = int(ipv4_count_str) + except ValueError: + ipv4_final_count = 0 + + try: + ipv6_final_count = int(ipv6_count_str) + except ValueError: + ipv6_final_count = 0 + + print(f"Route Removal Attempt {attempt}") + print(f"IPv4 Routes remaining: {ipv4_final_count} / {expected_final_count}") + print(f"IPv6 Routes remaining: {ipv6_final_count} / {expected_final_count}") + + # If both are already at expected count, break early + if ( + ipv4_final_count == expected_final_count + and ipv6_final_count == expected_final_count + ): + print("All routes successfully removed") + break + + # Final verification + if ipv4_final_count != expected_final_count: + sys.stderr.write( + f"Failed to remove IPv4 routes after {max_removal_attempts} attempts: " + f"{ipv4_final_count} routes still present\n" + ) + failures += 1 + else: + print("IPv4 routes successfully removed") + + if ipv6_final_count != expected_final_count: + sys.stderr.write( + f"Failed to remove IPv6 routes after {max_removal_attempts} attempts: " + f"{ipv6_final_count} routes still present\n" + ) + failures += 1 + else: + print("IPv6 routes successfully removed") + + start_router_daemons(get_topogen(), "r1", ["bgpd"]) + assert failures == 0, f"Test failed with {failures} failures" + + def test_nothing(): "Do Nothing" tgen = get_topogen() diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 632aa4a10b..01fe2b3714 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -5,6 +5,7 @@ # ("NetDEF") in this file. # +import json import ipaddress import sys import traceback @@ -5658,3 +5659,34 @@ def bgp_configure_prefixes(router, asn, safi, prefixes, vrf=None, update=True): ] logger.debug(f"setting prefix: ipv{ip.version} {safi} {ip}") router.vtysh_cmd("".join(cmd)) + + +# compare exact fields of 'show bgp ipv4 vpn' and related commands +# after having removed some attributes that are not relevant. +def bgp_vpn_router_json_cmp_exact_filter(router, cmd, expected): + output = router.vtysh_cmd(cmd) + logger.info("{}: {}\n{}".format(router.name, cmd, output)) + + json_output = json.loads(output) + + # filter out tableVersion, version and nhVrfID + json_output.pop("tableVersion") + if "totalRoutes" in json_output: + json_output.pop("totalRoutes") + if "totalPaths" in json_output: + json_output.pop("totalPaths") + for rd, data in json_output["routes"]["routeDistinguishers"].items(): + for _, attrs in data.items(): + for attr in attrs: + if "nhVrfId" in attr: + attr.pop("nhVrfId") + if "version" in attr: + attr.pop("version") + + # filter out RD with no data (e.g. "444:3": {}) + json_tmp = deepcopy(json_output) + for rd, data in json_tmp["routes"]["routeDistinguishers"].items(): + if len(data.keys()) == 0: + json_output["routes"]["routeDistinguishers"].pop(rd) + + return topotest.json_cmp(json_output, expected, exact=True) diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index f34c48b890..54142e8526 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -196,7 +196,7 @@ def get_seq_id(obj_type, router, obj_name): return seq_id -def set_seq_id(obj_type, router, id, obj_name): +def set_seq_id(obj_type, router, sequence_id, obj_name): """ Saves sequence number if not auto-generated and given by user Parameters @@ -209,7 +209,7 @@ def set_seq_id(obj_type, router, id, obj_name): obj_data = router_data.setdefault(obj_name, {}) seq_id = obj_data.setdefault("seq_id", 0) - seq_id = int(seq_id) + int(id) + seq_id = int(seq_id) + int(sequence_id) obj_data["seq_id"] = seq_id @@ -2539,10 +2539,10 @@ def create_route_maps(tgen, input_dict, build=False): ) return False if large_comm_list: - id = large_comm_list.setdefault("id", None) + comm_id = large_comm_list.setdefault("id", None) del_comm = large_comm_list.setdefault("delete", None) - if id: - cmd = "set large-comm-list {}".format(id) + if comm_id: + cmd = "set large-comm-list {}".format(comm_id) if del_comm: cmd = "{} delete".format(cmd) @@ -4608,7 +4608,7 @@ class HostApplicationHelper(object): self.init() return self - def __exit__(self, type, value, traceback): + def __exit__(self, exit_type, exit_value, exit_traceback): self.cleanup() def __str__(self): diff --git a/tests/topotests/lib/mcast-tester.py b/tests/topotests/lib/mcast-tester.py index 3645eef25e..ecb99dc82b 100755 --- a/tests/topotests/lib/mcast-tester.py +++ b/tests/topotests/lib/mcast-tester.py @@ -25,28 +25,46 @@ import time # def interface_name_to_index(name): "Gets the interface index using its name. Returns None on failure." - interfaces = json.loads(subprocess.check_output("ip -j link show", shell=True)) + try: + interfaces = json.loads(subprocess.check_output("ip -j link show", shell=True)) + except subprocess.CalledProcessError as err: + print(f"Error executing command: {err}") + return None + except json.JSONDecodeError as err: + print(f"Error decoding JSON: {err}") + return None for interface in interfaces: - if interface["ifname"] == name: - return interface["ifindex"] + if interface.get("ifname") == name: + return interface.get("ifindex") return None def interface_index_to_address(index, iptype="inet"): "Gets the interface main address using its name. Returns None on failure." - interfaces = json.loads(subprocess.check_output("ip -j addr show", shell=True)) + try: + interfaces = json.loads(subprocess.check_output("ip -j addr show", shell=True)) + except subprocess.CalledProcessError as err: + print(f"Error executing command: {err}") + return None + except json.JSONDecodeError as err: + print(f"Error decoding JSON: {err}") + return None for interface in interfaces: - if interface["ifindex"] == index: + if interface.get("ifindex") == index: break + else: + return None - for address in interface["addr_info"]: - if address["family"] == iptype: + for address in interface.get("addr_info"): + if address.get("family") == iptype: break + else: + return None - local_address = ipaddress.ip_address(address["local"]) + local_address = ipaddress.ip_address(address.get("local")) return local_address.packed diff --git a/tests/topotests/static_simple/test_static_simple.py b/tests/topotests/static_simple/test_static_simple.py index afde58fbf7..615d1621f3 100644 --- a/tests/topotests/static_simple/test_static_simple.py +++ b/tests/topotests/static_simple/test_static_simple.py @@ -111,6 +111,7 @@ def do_config_inner( count, add=True, do_ipv6=False, + do_ipv6_nexthop=False, do_sadr=False, via=None, vrf=None, @@ -129,6 +130,8 @@ def do_config_inner( src_prefs = ["2001:db8:1111::/48", "2001:db8:2222::/48"] elif do_ipv6: super_prefs = ["2001::/48", "2002::/48"] + elif do_ipv6_nexthop: + super_prefs = ["11.0.0.0/8", "21.0.0.0/8"] else: super_prefs = ["10.0.0.0/8", "20.0.0.0/8"] @@ -142,11 +145,19 @@ def do_config_inner( matchvia = f"dev {via}" else: if vrf: - via = "2102::2" if do_ipv6 else "102.0.0.2" - matchvia = f"via {via} dev r1-eth1" + via = "2102::2" if do_ipv6 or do_ipv6_nexthop else "102.0.0.2" + matchvia = ( + f"via inet6 {via} dev r1-eth1" + if not do_ipv6 and do_ipv6_nexthop + else f"via {via} dev r1-eth1" + ) else: - via = "2101::2" if do_ipv6 else "101.0.0.2" - matchvia = f"via {via} dev r1-eth0" + via = "2101::2" if do_ipv6 or do_ipv6_nexthop else "101.0.0.2" + matchvia = ( + f"via inet6 {via} dev r1-eth0" + if not do_ipv6 and do_ipv6_nexthop + else f"via {via} dev r1-eth0" + ) vrfdbg = " in vrf {}".format(vrf) if vrf else "" logger.debug("{} {} static {} routes{}".format(optype, count, iptype, vrfdbg)) @@ -201,6 +212,7 @@ def do_config_inner( def do_config(*args, **kwargs): do_config_inner(*args, do_ipv6=False, do_sadr=False, **kwargs) + do_config_inner(*args, do_ipv6=False, do_ipv6_nexthop=True, **kwargs) do_config_inner(*args, do_ipv6=True, do_sadr=False, **kwargs) do_config_inner(*args, do_ipv6=True, do_sadr=True, **kwargs) diff --git a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py index 1ea94c8c07..abf49df046 100755 --- a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py +++ b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py @@ -210,6 +210,36 @@ def test_srv6_static_sids_sid_modify(): check_srv6_static_sids(router, "expected_srv6_sids_sid_modify.json") +def test_srv6_static_sids_wrong_sid_block(): + """ + The purpose of this test is to verify how FRR behaves when the user + provides an invalid configuration. + Add a new static Sid with a mismatch in locator and sid block + to make sure no Sid is allocated by zebra (TBD: Strict verify once show cmd + commit is merged (#16836)) + """ + router = get_topogen().gears["r1"] + router.vtysh_cmd( + """ + configure terminal + segment-routing + srv6 + locators + locator MAIN1 + prefix fcbb:1234:1::/48 block-len 32 node-len 16 func-bits 16 + srv6 + static-sids + sid fcbb:bbbb:1:fe50::/64 locator MAIN1 behavior uA interface sr0 nexthop 2001::3 + """ + ) + + output = json.loads(router.vtysh_cmd("show ipv6 route static json")) + if "fcbb:bbbb:1:fe50::/64" in output: + assert ( + False + ), "Failed. Expected no entry for fcbb:bbbb:1:fe50::/64 since loc and node block dont match" + + def test_srv6_static_sids_sid_delete_all(): """ Remove all static SIDs and verify they get removed diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 048cb8323e..95a00c2b6a 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -1698,6 +1698,7 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del): those commands from lines_to_del. """ lines_to_del_to_del = [] + lines_to_del_to_add = [] for ctx_keys, line in lines_to_del: # The integrated-vtysh-config one is technically "no"able but if we did @@ -1719,10 +1720,31 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del): ): log.info(f'"{ctx_keys[-1]}" cannot be removed') lines_to_del_to_del.append((ctx_keys, line)) + # Handle segment-routing srv6 locators and formats commands + # - Ignore "no formats" and "no locators" command + # - replace "no prefix" under locator XYZ as "no locator XYZ" + elif ( + len(ctx_keys) > 2 + and ctx_keys[0].startswith("segment-routing") + and ctx_keys[1].startswith("srv6") + and ctx_keys[2] in {"locators", "formats"} + ): + is_top_level = len(ctx_keys) == 3 and not line + if ctx_keys[2] == "formats" and is_top_level: + lines_to_del_to_del.append((ctx_keys, line)) + elif ctx_keys[2] == "locators": + if is_top_level: + lines_to_del_to_del.append((ctx_keys, line)) + elif len(ctx_keys) == 4 and line and line.startswith("prefix "): + lines_to_del_to_del.append((ctx_keys, line)) + lines_to_del_to_add.append((ctx_keys[:-1] + (ctx_keys[-1],), None)) for ctx_keys, line in lines_to_del_to_del: lines_to_del.remove((ctx_keys, line)) + for ctx_keys, line in lines_to_del_to_add: + lines_to_del.append((ctx_keys, line)) + return (lines_to_add, lines_to_del) @@ -2113,12 +2135,17 @@ if __name__ == "__main__": help="Use logfmt as log format", default=False, ) + parser.add_argument( + "--logfile", + help="logfile for frr-reload", + default="/var/log/frr/frr-reload.log", + ) args = parser.parse_args() # Logging # For --test log to stdout - # For --reload log to /var/log/frr/frr-reload.log + # For --reload log to --logfile (default: "/var/log/frr/frr-reload.log") # If --logfmt, use the logfmt format formatter = logging.Formatter("%(asctime)s %(levelname)5s: %(message)s") handler = logging.StreamHandler() @@ -2133,9 +2160,9 @@ if __name__ == "__main__": logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING) ) if args.reload: - if not os.path.isdir("/var/log/frr/"): - os.makedirs("/var/log/frr/", mode=0o0755) - handler = logging.FileHandler("/var/log/frr/frr-reload.log") + if not os.path.isdir(os.path.dirname(args.logfile)): + os.makedirs(os.path.dirname(args.logfile), mode=0o0755) + handler = logging.FileHandler(args.logfile) if args.stdout: handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py index 04a374d850..a646e7eea1 100755 --- a/tools/generate_support_bundle.py +++ b/tools/generate_support_bundle.py @@ -32,6 +32,9 @@ def main(): parser.add_argument( "-l", "--log-dir", default="/var/log/frr", help="directory for logfiles" ) + parser.add_argument( + "-N", "--pathspace", help="Insert prefix into config & socket paths" + ) args = parser.parse_args() collecting = False # file format has sentinels (seem superfluous) @@ -69,13 +72,22 @@ def main(): # Spawn a vtysh to fetch each set of commands procs = [] for proc in proc_cmds: - ofn = os.path.join(args.log_dir, proc + "_support_bundle.log") - p = subprocess.Popen( - ["/usr/bin/env", "vtysh", "-t"], - stdin=proc_cmds[proc], - stdout=open_with_backup(ofn), - stderr=subprocess.STDOUT, - ) + if args.pathspace: + ofn = os.path.join(args.log_dir, args.pathspace + "_" + proc + "_support_bundle.log") + p = subprocess.Popen( + ["/usr/bin/env", "vtysh", "-t", "-N", args.pathspace], + stdin=proc_cmds[proc], + stdout=open_with_backup(ofn), + stderr=subprocess.STDOUT, + ) + else: + ofn = os.path.join(args.log_dir, proc + "_support_bundle.log") + p = subprocess.Popen( + ["/usr/bin/env", "vtysh", "-t"], + stdin=proc_cmds[proc], + stdout=open_with_backup(ofn), + stderr=subprocess.STDOUT, + ) procs.append(p) for p in procs: diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index 4406a68f61..5d6cf01936 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -73,14 +73,14 @@ size_t strlcpy(char *__restrict dest, #endif static int testmode = 0; -static int quietmode = 0; +static int g_quietmode = 0; static int exitnodo = 1; static int start = 0; static int stop = 0; static int background = 0; static int mpidfile = 0; -static int signal_nr = 15; -static const char *signal_str = NULL; +static int g_signal_nr = 15; +static const char *g_signal_str = NULL; static int user_id = -1; static int runas_uid = -1; static int runas_gid = -1; @@ -93,7 +93,7 @@ static char *execname = NULL; static char *startas = NULL; static const char *pidfile = NULL; static char what_stop[1024]; -static const char *schedule_str = NULL; +static const char *g_schedule_str = NULL; static const char *progname = ""; static int nicelevel = 0; @@ -438,7 +438,7 @@ static void parse_schedule(const char *schedule_str) if (count == 0) { schedule[0].type = sched_signal; - schedule[0].value = signal_nr; + schedule[0].value = g_signal_nr; parse_schedule_item(schedule_str, &schedule[1]); if (schedule[1].type != sched_timeout) { badusage( @@ -528,10 +528,10 @@ static void parse_options(int argc, char *const *argv) pidfile = optarg; break; case 'q': /* --quiet */ - quietmode = 1; + g_quietmode = 1; break; case 's': /* --signal <signal> */ - signal_str = optarg; + g_signal_str = optarg; break; case 't': /* --test */ testmode = 1; @@ -540,7 +540,7 @@ static void parse_options(int argc, char *const *argv) userspec = optarg; break; case 'v': /* --verbose */ - quietmode = -1; + g_quietmode = -1; break; case 'x': /* --exec <executable> */ execname = optarg; @@ -567,21 +567,21 @@ static void parse_options(int argc, char *const *argv) mpidfile = 1; break; case 'R': /* --retry <schedule>|<timeout> */ - schedule_str = optarg; + g_schedule_str = optarg; break; default: badusage(NULL); /* message printed by getopt */ } } - if (signal_str != NULL) { - if (parse_signal(signal_str, &signal_nr) != 0) + if (g_signal_str != NULL) { + if (parse_signal(g_signal_str, &g_signal_nr) != 0) badusage( "signal value must be numeric or name of signal (KILL, INTR, ...)"); } - if (schedule_str != NULL) { - parse_schedule(schedule_str); + if (g_schedule_str != NULL) { + parse_schedule(g_schedule_str); } if (start == stop) @@ -787,8 +787,8 @@ static int run_stop_schedule(void) n_killed = 0; if (schedule == NULL) { - do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0); - if (n_notkilled > 0 && quietmode <= 0) + do_stop(g_signal_nr, g_quietmode, &n_killed, &n_notkilled, 0); + if (n_notkilled > 0 && g_quietmode <= 0) printf("%d pids were not killed\n", n_notkilled); if (n_killed) anykilled = 1; @@ -806,7 +806,7 @@ static int run_stop_schedule(void) continue; case sched_signal: - do_stop(value, quietmode, &n_killed, &n_notkilled, + do_stop(value, g_quietmode, &n_killed, &n_notkilled, retry_nr++); if (!n_killed) goto x_finished; @@ -899,7 +899,7 @@ static int run_stop_schedule(void) position++; } - if (quietmode <= 0) + if (g_quietmode <= 0) printf("Program %s, %d process(es), refused to die.\n", what_stop, n_killed); @@ -907,7 +907,7 @@ static int run_stop_schedule(void) x_finished: if (!anykilled) { - if (quietmode <= 0) + if (g_quietmode <= 0) printf("No %s found running; none killed.\n", what_stop); return exitnodo; @@ -969,7 +969,7 @@ int main(int argc, char **argv) do_findprocs(); if (found) { - if (quietmode <= 0) + if (g_quietmode <= 0) printf("%s already running.\n", execname); exit(exitnodo); } @@ -992,7 +992,7 @@ int main(int argc, char **argv) printf(".\n"); exit(0); } - if (quietmode < 0) + if (g_quietmode < 0) printf("Starting %s...\n", startas); *--argv = startas; if (changeroot != NULL) { @@ -1013,14 +1013,14 @@ int main(int argc, char **argv) if (background) { /* ok, we need to detach this process */ int i, fd; - if (quietmode < 0) + if (g_quietmode < 0) printf("Detaching to start %s...", startas); i = fork(); if (i < 0) { fatal("Unable to fork.\n"); } if (i) { /* parent */ - if (quietmode < 0) + if (g_quietmode < 0) printf("done.\n"); exit(0); } diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index 009432b217..6b4b3104ea 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -19,7 +19,7 @@ #define VRRP_LOGPFX "[ZEBRA] " -static struct zclient *zclient; +static struct zclient *vrrp_zclient; static void vrrp_zebra_debug_if_state(struct interface *ifp, const char *func) { @@ -161,7 +161,7 @@ void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable) "Requesting Zebra to turn router advertisements %s for %s", r->vr->vrid, enable ? "on" : "off", r->mvl_ifp->name); - zclient_send_interface_radv_req(zclient, r->mvl_ifp->vrf->vrf_id, + zclient_send_interface_radv_req(vrrp_zclient, r->mvl_ifp->vrf->vrf_id, r->mvl_ifp, enable, VRRP_RADV_INT); } @@ -171,7 +171,7 @@ void vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down) VRRP_LOGPFX "Requesting Zebra to set %s protodown %s", ifp->name, down ? "on" : "off"); - zclient_send_interface_protodown(zclient, ifp->vrf->vrf_id, ifp, down); + zclient_send_interface_protodown(vrrp_zclient, ifp->vrf->vrf_id, ifp, down); } static zclient_handler *const vrrp_handlers[] = { @@ -188,12 +188,12 @@ void vrrp_zebra_init(void) hook_register_prio(if_unreal, 0, vrrp_ifp_destroy); /* Socket for receiving updates from Zebra daemon */ - zclient = zclient_new(master, &zclient_options_default, vrrp_handlers, - array_size(vrrp_handlers)); + vrrp_zclient = zclient_new(master, &zclient_options_default, vrrp_handlers, + array_size(vrrp_handlers)); - zclient->zebra_connected = vrrp_zebra_connected; + vrrp_zclient->zebra_connected = vrrp_zebra_connected; - zclient_init(zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs); + zclient_init(vrrp_zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs); zlog_notice("%s: zclient socket initialized", __func__); } diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 31e7ce12ba..fba39526c6 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -44,7 +44,7 @@ DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy"); /* Struct VTY. */ -struct vty *vty; +struct vty *gvty; /* VTY shell pager name. */ char *vtysh_pager_name = NULL; @@ -161,8 +161,8 @@ static int vtysh_reconnect(struct vtysh_client *vclient); static void vclient_close(struct vtysh_client *vclient) { if (vclient->fd >= 0) { - if (vty->of) - vty_out(vty, + if (gvty->of) + vty_out(gvty, "Warning: closing connection to %s because of an I/O error!\n", vclient->name); close(vclient->fd); @@ -282,8 +282,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line, vclient, bufvalid, buf + bufsz - bufvalid - 1, pass_fd); if (nread <= 0) { - if (vty->of) - vty_out(vty, + if (gvty->of) + vty_out(gvty, "vtysh: error reading from %s: %s (%d)", vclient->name, safe_strerror(errno), errno); @@ -357,8 +357,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line, /* eol is at line end now, either \n => \0 or \0\0\0 */ assert(eol && eol <= bufvalid); - if (vty->of) - vty_out(vty, "%s\n", buf); + if (gvty->of) + vty_out(gvty, "%s\n", buf); callback(cbarg, buf); @@ -371,8 +371,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line, /* else if no callback, dump raw */ if (!callback) { - if (vty->of) - vty_out(vty, "%s", buf); + if (gvty->of) + vty_out(gvty, "%s", buf); memmove(buf, buf + textlen, bufvalid - buf - textlen); bufvalid -= textlen; if (end) @@ -431,8 +431,8 @@ static int vtysh_client_run_all(struct vtysh_client *head_client, rc_all = rc; } } - if (wrong_instance && !correct_instance && vty->of) { - vty_out(vty, + if (wrong_instance && !correct_instance && gvty->of) { + vty_out(gvty, "%% [%s]: command ignored as it targets an instance that is not running\n", head_client->name); rc_all = CMD_WARNING_CONFIG_FAILED; @@ -468,7 +468,7 @@ static int vtysh_client_execute_name(const char *name, const char *line) if (idx_client != -1) ret = vtysh_client_execute(&vtysh_client[idx_client], line); else { - vty_out(vty, "Client not found\n"); + vty_out(gvty, "Client not found\n"); ret = CMD_WARNING; } @@ -495,11 +495,11 @@ static void vtysh_client_config(struct vtysh_client *head_client, char *line) return; /* suppress output to user */ - vty->of_saved = vty->of; - vty->of = NULL; + gvty->of_saved = gvty->of; + gvty->of = NULL; vtysh_client_run_all(head_client, line, 1, vtysh_config_parse_line, NULL); - vty->of = vty->of_saved; + gvty->of = gvty->of_saved; } /* Command execution over the vty interface. */ @@ -522,11 +522,11 @@ static int vtysh_execute_func(const char *line, int pager) char ts[48]; (void)frr_timestamp(3, ts, sizeof(ts)); - vty_out(vty, "%% %s\n\n", ts); + vty_out(gvty, "%% %s\n\n", ts); } - saved_ret = ret = cmd_execute(vty, line, &cmd, 1); - saved_node = vty->node; + saved_ret = ret = cmd_execute(gvty, line, &cmd, 1); + saved_node = gvty->node; /* * If command doesn't succeeded in current node, try to walk up in node @@ -536,13 +536,13 @@ static int vtysh_execute_func(const char *line, int pager) while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON && ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED && ret != CMD_ERR_AMBIGUOUS && ret != CMD_ERR_INCOMPLETE - && vty->node > CONFIG_NODE) { - vty->node = node_parent(vty->node); - ret = cmd_execute(vty, line, &cmd, 1); + && gvty->node > CONFIG_NODE) { + gvty->node = node_parent(gvty->node); + ret = cmd_execute(gvty, line, &cmd, 1); tried++; } - vty->node = saved_node; + gvty->node = saved_node; /* * If command succeeded in any other node than current (tried > 0) we @@ -567,17 +567,17 @@ static int vtysh_execute_func(const char *line, int pager) switch (ret) { case CMD_WARNING: case CMD_WARNING_CONFIG_FAILED: - if (vty->type == VTY_FILE) - vty_out(vty, "Warning...\n"); + if (gvty->type == VTY_FILE) + vty_out(gvty, "Warning...\n"); break; case CMD_ERR_AMBIGUOUS: - vty_out(vty, "%% Ambiguous command: %s\n", line); + vty_out(gvty, "%% Ambiguous command: %s\n", line); break; case CMD_ERR_NO_MATCH: - vty_out(vty, "%% Unknown command: %s\n", line); + vty_out(gvty, "%% Unknown command: %s\n", line); break; case CMD_ERR_INCOMPLETE: - vty_out(vty, "%% Command incomplete: %s\n", line); + vty_out(gvty, "%% Command incomplete: %s\n", line); break; case CMD_SUCCESS_DAEMON: { /* @@ -586,7 +586,7 @@ static int vtysh_execute_func(const char *line, int pager) * cause any problem but is really ugly. */ if (pager && strncmp(line, "exit", 4)) - vty_open_pager(vty); + vty_open_pager(gvty); if (!strcmp(cmd->string, "configure")) { for (i = 0; i < array_size(vtysh_client); i++) { @@ -602,17 +602,17 @@ static int vtysh_execute_func(const char *line, int pager) if (vline == NULL) { - if (vty->is_paged) - vty_close_pager(vty); + if (gvty->is_paged) + vty_close_pager(gvty); return CMD_SUCCESS; } - ret = cmd_execute_command(vline, vty, &cmd, 1); + ret = cmd_execute_command(vline, gvty, &cmd, 1); cmd_free_strvec(vline); if (ret != CMD_SUCCESS_DAEMON) break; } else if (cmd->func) { - (*cmd->func)(cmd, vty, 0, NULL); + (*cmd->func)(cmd, gvty, 0, NULL); break; } } @@ -653,11 +653,11 @@ static int vtysh_execute_func(const char *line, int pager) break; if (cmd->func) - (*cmd->func)(cmd, vty, 0, NULL); + (*cmd->func)(cmd, gvty, 0, NULL); } } - if (vty->is_paged) - vty_close_pager(vty); + if (gvty->is_paged) + vty_close_pager(gvty); return cmd_stat; } @@ -980,21 +980,21 @@ static int vtysh_process_questionmark(const char *input, int input_len) } else if (input_len && isspace((unsigned char)input[input_len - 1])) vector_set(vline, NULL); - describe = cmd_describe_command(vline, vty, &ret); + describe = cmd_describe_command(vline, gvty, &ret); /* Ambiguous and no match error. */ switch (ret) { case CMD_ERR_AMBIGUOUS: cmd_free_strvec(vline); vector_free(describe); - vty_out(vty, "%% Ambiguous command.\n"); + vty_out(gvty, "%% Ambiguous command.\n"); rl_on_new_line(); return 0; case CMD_ERR_NO_MATCH: cmd_free_strvec(vline); if (describe) vector_free(describe); - vty_out(vty, "%% There is no matched command.\n"); + vty_out(gvty, "%% There is no matched command.\n"); rl_on_new_line(); return 0; } @@ -1015,9 +1015,9 @@ static int vtysh_process_questionmark(const char *input, int input_len) for (i = 0; i < vector_active(describe); i++) if ((token = vector_slot(describe, i)) != NULL) { if (!token->desc) - vty_out(vty, " %-s\n", token->text); + vty_out(gvty, " %-s\n", token->text); else - vty_out(vty, " %-*s %s\n", width, token->text, + vty_out(gvty, " %-*s %s\n", width, token->text, token->desc); if (IS_VARYING_TOKEN(token->type)) { @@ -1033,7 +1033,7 @@ static int vtysh_process_questionmark(const char *input, int input_len) char *ac = cmd_variable_comp2str( varcomps, cols); - vty_out(vty, "%s\n", ac); + vty_out(gvty, "%s\n", ac); XFREE(MTYPE_TMP, ac); } @@ -1056,7 +1056,7 @@ static int vtysh_rl_describe(int a, int b) { int ret; - vty_out(vty, "\n"); + vty_out(gvty, "\n"); ret = vtysh_process_questionmark(rl_line_buffer, rl_end); rl_on_new_line(); @@ -1116,7 +1116,7 @@ static char *command_generator(const char *text, int state) if (!state) { index = 0; - if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE) + if (gvty->node == AUTH_NODE || gvty->node == AUTH_ENABLE_NODE) return NULL; vline = cmd_make_strvec(rl_line_buffer); @@ -1127,7 +1127,7 @@ static char *command_generator(const char *text, int state) isspace((unsigned char)rl_line_buffer[rl_end - 1])) vector_set(vline, NULL); - matched = cmd_complete_command(vline, vty, &complete_status); + matched = cmd_complete_command(vline, gvty, &complete_status); cmd_free_strvec(vline); } @@ -1672,13 +1672,13 @@ extern struct cmd_node vty_node; /* When '^Z' is received from vty, move down to the enable mode. */ static int vtysh_end(void) { - switch (vty->node) { + switch (gvty->node) { case VIEW_NODE: case ENABLE_NODE: /* Nothing to do. */ break; default: - vty->node = ENABLE_NODE; + gvty->node = ENABLE_NODE; break; } return CMD_SUCCESS; @@ -3627,7 +3627,7 @@ static void show_route_map_send(const char *route_map, bool json) strlcat(command_line, " json", sizeof(command_line)); if (json) - vty_out(vty, "{"); + vty_out(gvty, "{"); for (i = 0; i < array_size(vtysh_client); i++) { const struct vtysh_client *client = &vtysh_client[i]; @@ -3644,18 +3644,18 @@ static void show_route_map_send(const char *route_map, bool json) continue; if (json && !first) - vty_out(vty, ","); + vty_out(gvty, ","); else first = false; if (json) - vty_out(vty, "\"%s\":", vtysh_client[i].name); + vty_out(gvty, "\"%s\":", vtysh_client[i].name); vtysh_client_execute_name(vtysh_client[i].name, command_line); } if (json) - vty_out(vty, "}\n"); + vty_out(gvty, "}\n"); } DEFPY (show_route_map, @@ -3699,7 +3699,7 @@ static void show_prefix_list_send(afi_t afi, const char *prefix_list, strlcat(command_line, " json", sizeof(command_line)); if (json) - vty_out(vty, "{"); + vty_out(gvty, "{"); for (i = 0; i < array_size(vtysh_client); i++) { const struct vtysh_client *client = &vtysh_client[i]; @@ -3716,18 +3716,18 @@ static void show_prefix_list_send(afi_t afi, const char *prefix_list, continue; if (json && !first) - vty_out(vty, ","); + vty_out(gvty, ","); else first = false; if (json) - vty_out(vty, "\"%s\":", vtysh_client[i].name); + vty_out(gvty, "\"%s\":", vtysh_client[i].name); vtysh_client_execute_name(vtysh_client[i].name, command_line); } if (json) - vty_out(vty, "}\n"); + vty_out(gvty, "}\n"); } DEFPY (show_ip_prefix_list, @@ -3842,7 +3842,7 @@ static void show_access_list_send(afi_t afi, const char *access_list, bool json) strlcat(command_line, access_list, sizeof(command_line)); if (json) { strlcat(command_line, " json", sizeof(command_line)); - vty_out(vty, "{"); + vty_out(gvty, "{"); } for (i = 0; i < array_size(vtysh_client); i++) { @@ -3860,18 +3860,18 @@ static void show_access_list_send(afi_t afi, const char *access_list, bool json) continue; if (json && !first) - vty_out(vty, ","); + vty_out(gvty, ","); else first = false; if (json) - vty_out(vty, "\"%s\":", vtysh_client[i].name); + vty_out(gvty, "\"%s\":", vtysh_client[i].name); vtysh_client_execute_name(vtysh_client[i].name, command_line); } if (json) - vty_out(vty, "}\n"); + vty_out(gvty, "}\n"); } DEFPY (show_ip_access_list, @@ -3956,10 +3956,10 @@ static void backup_config_file(const char *fbackup) /* Move current configuration file to backup config file. */ if (unlink(integrate_sav) != 0 && errno != ENOENT) - vty_out(vty, "Unlink failed for %s: %s\n", integrate_sav, + vty_out(gvty, "Unlink failed for %s: %s\n", integrate_sav, strerror(errno)); if (rename(fbackup, integrate_sav) != 0 && errno != ENOENT) - vty_out(vty, "Error renaming %s to %s: %s\n", fbackup, + vty_out(gvty, "Error renaming %s to %s: %s\n", fbackup, integrate_sav, strerror(errno)); free(integrate_sav); } @@ -3981,12 +3981,12 @@ int vtysh_write_config_integrated(void) struct stat st; int err = 0; - vty_out(vty, "Building Configuration...\n"); + vty_out(gvty, "Building Configuration...\n"); backup_config_file(frr_config); fp = fopen(frr_config, "w"); if (fp == NULL) { - vty_out(vty, + vty_out(gvty, "%% Error: failed to open configuration file %s: %s\n", frr_config, safe_strerror(errno)); return CMD_WARNING_CONFIG_FAILED; @@ -3997,10 +3997,10 @@ int vtysh_write_config_integrated(void) vtysh_client_config(&vtysh_client[i], line); vtysh_config_write(); - vty->of_saved = vty->of; - vty->of = fp; + gvty->of_saved = gvty->of; + gvty->of = fp; vtysh_config_dump(); - vty->of = vty->of_saved; + gvty->of = gvty->of_saved; if (fchmod(fd, CONFIGFILE_MASK) != 0) { printf("%% Warning: can't chmod configuration file %s: %s\n", @@ -4964,7 +4964,7 @@ char *vtysh_prompt(void) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" /* prompt formatting has a %s in the cmd_node prompt string. */ - snprintf(buf, sizeof(buf), cmd_prompt(vty->node), cmd_hostname_get()); + snprintf(buf, sizeof(buf), cmd_prompt(gvty->node), cmd_hostname_get()); #pragma GCC diagnostic pop return buf; } @@ -4987,12 +4987,12 @@ static void vtysh_autocomplete(vector comps, struct cmd_token *token) snprintf(accmd, sizeof(accmd), "autocomplete %d %s %s", token->type, token->text, token->varname ? token->varname : "-"); - vty->of_saved = vty->of; - vty->of = NULL; + gvty->of_saved = gvty->of; + gvty->of = NULL; for (i = 0; i < array_size(vtysh_client); i++) vtysh_client_run_all(&vtysh_client[i], accmd, 1, vtysh_ac_line, comps); - vty->of = vty->of_saved; + gvty->of = gvty->of_saved; } static const struct cmd_variable_handler vtysh_var_handler[] = { @@ -5004,8 +5004,8 @@ static const struct cmd_variable_handler vtysh_var_handler[] = { void vtysh_uninit(void) { - if (vty->of != stdout) - fclose(vty->of); + if (gvty->of != stdout) + fclose(gvty->of); } void vtysh_init_vty(void) @@ -5026,12 +5026,12 @@ void vtysh_init_vty(void) stderr_stdout_same = true; /* Make vty structure. */ - vty = vty_new(); - vty->type = VTY_SHELL; - vty->node = VIEW_NODE; + gvty = vty_new(); + gvty->type = VTY_SHELL; + gvty->node = VIEW_NODE; /* set default output */ - vty->of = stdout; + gvty->of = stdout; vtysh_pager_envdef(false); /* Initialize commands. */ diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 3c532b99a8..6d5e559a2f 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -152,7 +152,7 @@ void suid_off(void); /* Child process execution flag. */ extern int execute_flag; -extern struct vty *vty; +extern struct vty *gvty; extern int user_mode; diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 6536e1b376..4f6fc782c2 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -558,19 +558,19 @@ static void configvec_dump(vector vec, bool nested) continue; } - vty_out(vty, "%s\n", config->name); + vty_out(gvty, "%s\n", config->name); for (ALL_LIST_ELEMENTS(config->line, mnode, mnnode, line)) - vty_out(vty, "%s\n", line); + vty_out(gvty, "%s\n", line); configvec_dump(config->nested, true); if (config->exit) - vty_out(vty, "%s\n", config->exit); + vty_out(gvty, "%s\n", config->exit); if (!NO_DELIMITER(i)) - vty_out(vty, "!\n"); + vty_out(gvty, "!\n"); config_del(config); } @@ -579,7 +579,7 @@ static void configvec_dump(vector vec, bool nested) XFREE(MTYPE_VTYSH_CONFIG, configuration); vector_slot(vec, i) = NULL; if (!nested && NO_DELIMITER(i)) - vty_out(vty, "!\n"); + vty_out(gvty, "!\n"); } } @@ -589,11 +589,11 @@ void vtysh_config_dump(void) char *line; for (ALL_LIST_ELEMENTS(config_top, node, nnode, line)) - vty_out(vty, "%s\n", line); + vty_out(gvty, "%s\n", line); list_delete_all_node(config_top); - vty_out(vty, "!\n"); + vty_out(gvty, "!\n"); configvec_dump(configvec, false); } @@ -601,13 +601,13 @@ void vtysh_config_dump(void) /* Read up configuration file from file_name. */ static int vtysh_read_file(FILE *confp, bool dry_run) { - struct vty *vty; + struct vty *lvty; int ret; - vty = vty_new(); - vty->wfd = STDERR_FILENO; - vty->type = VTY_TERM; - vty->node = CONFIG_NODE; + lvty = vty_new(); + lvty->wfd = STDERR_FILENO; + lvty->type = VTY_TERM; + lvty->node = CONFIG_NODE; vtysh_execute_no_pager("enable"); /* @@ -622,7 +622,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run) vtysh_execute_no_pager("XFRR_start_configuration"); /* Execute configuration file. */ - ret = vtysh_config_from_file(vty, confp); + ret = vtysh_config_from_file(lvty, confp); if (!dry_run) vtysh_execute_no_pager("XFRR_end_configuration"); @@ -630,7 +630,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run) vtysh_execute_no_pager("end"); vtysh_execute_no_pager("disable"); - vty_close(vty); + vty_close(lvty); return (ret); } diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 297d87ec41..16e166beac 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -726,7 +726,7 @@ int main(int argc, char **argv, char **env) vtysh_readline_init(); - vty_hello(vty); + vty_hello(gvty); /* Enter into enable node. */ if (!user_mode) diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang index 75af799acc..249d162ffc 100644 --- a/yang/frr-bfdd.yang +++ b/yang/frr-bfdd.yang @@ -49,8 +49,8 @@ module frr-bfdd { (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."; - revision 2019-05-09 { - description "Initial revision."; + revision 2025-03-03 { + description "Add log-session-changes leaf"; reference "RFC 5880: Bidirectional Forwarding Detection (BFD). RFC 5881: Bidirectional Forwarding Detection (BFD) @@ -58,8 +58,8 @@ module frr-bfdd { RFC 5883: Bidirectional Forwarding Detection (BFD) for Multihop Paths."; } - revision 2025-03-03 { - description "Add log-sessio-changes leaf"; + revision 2019-05-09 { + description "Initial revision."; reference "RFC 5880: Bidirectional Forwarding Detection (BFD). RFC 5881: Bidirectional Forwarding Detection (BFD) @@ -71,21 +71,20 @@ module frr-bfdd { * BFD types declaration. */ typedef multiplier { - description "Detection multiplier"; type uint8 { range "1..255"; } + description "Detection multiplier"; } typedef discriminator { - description "BFD session identification"; type uint32 { range "1..4294967295"; } + description "BFD session identification"; } typedef state { - description "BFD session state"; type enumeration { enum admin-down { value 0; @@ -104,10 +103,10 @@ module frr-bfdd { description "Up"; } } + description "BFD session state"; } typedef diagnostic { - description "BFD session diagnostic"; type enumeration { enum ok { value 0; @@ -146,6 +145,7 @@ module frr-bfdd { description "Reverse concatenated path down"; } } + description "BFD session diagnostic"; } typedef profile-name { @@ -272,23 +272,27 @@ module frr-bfdd { } leaf multi-hop { - description - "Use multi hop session instead of single hop."; type boolean; default false; + description + "Use multi hop session instead of single hop."; } leaf profile { + type frr-bfdd:profile-ref; description "BFD pre configured profile."; - type frr-bfdd:profile-ref; } } grouping session-states { + description + "This grouping defines the states of a BFD session."; + /* * Local settings. */ + leaf local-discriminator { type discriminator; description "Local session identifier"; @@ -336,20 +340,18 @@ module frr-bfdd { * Negotiated settings. */ leaf negotiated-transmission-interval { - description "Negotiated transmit interval"; type uint32; units microseconds; + description "Negotiated transmit interval"; } leaf negotiated-receive-interval { - description "Negotiated receive interval"; type uint32; units microseconds; + description "Negotiated receive interval"; } leaf detection-mode { - description "Detection mode"; - type enumeration { enum async-with-echo { value "1"; @@ -368,6 +370,7 @@ module frr-bfdd { description "Demand without echo"; } } + description "Detection mode"; } /* @@ -430,6 +433,9 @@ module frr-bfdd { * BFD operational. */ container bfdd { + description + "This container defines BFD daemon configuration."; + container bfd { presence "Present if the BFD protocol is enabled"; @@ -448,6 +454,9 @@ module frr-bfdd { } container sessions { + description + "This container provides information about sessions."; + list single-hop { key "dest-addr interface vrf"; description "List of single hop sessions"; @@ -483,6 +492,8 @@ module frr-bfdd { container stats { uses session-states; config false; + description + "This container provides statistics for sessions."; } } @@ -516,6 +527,8 @@ module frr-bfdd { container stats { uses session-states; config false; + description + "This container provides statistics for sessions."; } } @@ -577,6 +590,8 @@ module frr-bfdd { container stats { uses session-states; config false; + description + "This container provides statistics for sessions."; } } @@ -644,9 +659,13 @@ module frr-bfdd { container stats { uses session-states; config false; + description + "This container provides statistics for sessions."; } } } + description + "This container defines BFD protocol configuration."; } } } diff --git a/yang/frr-eigrpd.yang b/yang/frr-eigrpd.yang index 8f2ad5be46..931f5f6fee 100644 --- a/yang/frr-eigrpd.yang +++ b/yang/frr-eigrpd.yang @@ -112,7 +112,7 @@ module frr-eigrpd { list instance { key "asn vrf"; description "EIGRP autonomous system instance"; - + must "count(../instance[vrf =current()/vrf]) = 1"; leaf asn { type autonomous-system; description "Autonomous System Number"; diff --git a/yang/frr-pathd.yang b/yang/frr-pathd.yang index 5beda769c1..96eafda9d4 100644 --- a/yang/frr-pathd.yang +++ b/yang/frr-pathd.yang @@ -6,15 +6,9 @@ module frr-pathd { import ietf-inet-types { prefix inet; } - import ietf-yang-types { - prefix yang; - } import ietf-routing-types { prefix rt-types; } - import frr-interface { - prefix frr-interface; - } organization "Free Range Routing"; @@ -27,11 +21,10 @@ module frr-pathd { revision 2018-11-06 { description "Initial revision."; + reference "FRRouting"; } typedef protocol-origin-type { - description - "Indication for the protocol origin of an object."; type enumeration { enum pcep { value 1; @@ -46,6 +39,8 @@ module frr-pathd { description "The object was created through CLI, Yang model via Netconf, gRPC, etc"; } } + description + "Indication for the protocol origin of an object."; } typedef originator-type { @@ -57,7 +52,13 @@ module frr-pathd { } container pathd { + description + "Path properties for Segment Routing TE"; + container srte { + description + "Segment Routing TE properties"; + list segment-list { key "name"; description "Segment-list properties"; @@ -91,9 +92,10 @@ module frr-pathd { } container nai { presence "The segment has a Node or Adjacency Identifier"; + description + "Node or Adjacency Identifier for the segment"; + leaf type { - description "NAI type"; - mandatory true; type enumeration { enum ipv4_node { value 1; @@ -132,42 +134,59 @@ module frr-pathd { description "IPv6 prefix with optional algorithm"; } } + mandatory true; + description "NAI type"; } leaf local-address { type inet:ip-address; mandatory true; + description + "Local address of the NAI"; } leaf local-prefix-len { + when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_algo' or ../type = 'ipv6_algo'"; type uint8; mandatory true; - when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_algo' or ../type = 'ipv6_algo'"; + description + "Prefix length of the local address"; } leaf local-interface { + when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_unnumbered_adjacency'"; type uint32; mandatory true; - when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_unnumbered_adjacency'"; + description + "Local interface ID for the NAI"; } leaf remote-address { + when "../type = 'ipv4_adjacency' or ../type = 'ipv6_adjacency' or ../type = 'ipv4_unnumbered_adjacency'"; type inet:ip-address; - mandatory true; - when "../type = 'ipv4_adjacency' or ../type = 'ipv6_adjacency' or ../type = 'ipv4_unnumbered_adjacency'"; - } - leaf remote-interface { - type uint32; - mandatory true; - when "../type = 'ipv4_unnumbered_adjacency'"; - } + mandatory true; + description + "Remote address of the NAI"; + } + leaf remote-interface { + when "../type = 'ipv4_unnumbered_adjacency'"; + type uint32; + mandatory true; + description + "Remote interface ID for the NAI"; + } leaf algorithm { + when "../type = 'ipv4_algo' or ../type = 'ipv6_algo'"; type uint8; mandatory true; - when "../type = 'ipv4_algo' or ../type = 'ipv6_algo'"; - } + description + "Algorithm to use for the NAI"; } + } } } list policy { key "color endpoint"; unique "name"; + description + "List of SR Policies."; + leaf color { type uint32; description @@ -197,10 +216,10 @@ module frr-pathd { "True if a valid candidate path of this policy is operational in zebra, False otherwise"; } list candidate-path { + key "preference"; unique "name"; description "List of Candidate Paths of the SR Policy."; - key "preference"; leaf preference { type uint32; description @@ -237,17 +256,21 @@ module frr-pathd { description "Candidate path distinguisher"; } leaf type { - description - "Type of the Candidate Path."; - mandatory true; type enumeration { enum explicit { value 1; + description + "Explicit path defined by a segment list"; } enum dynamic { value 2; + description + "Dynamic path computed by a routing protocol"; } } + mandatory true; + description + "Type of the Candidate Path."; } leaf segment-list-name { type leafref { @@ -271,10 +294,12 @@ module frr-pathd { "If the bandwidth limitation is a requirement or only a suggestion"; } leaf value { - mandatory true; type decimal64 { fraction-digits 6; } + mandatory true; + description + "The bandwidth value for the candidate path."; } } container affinity { @@ -298,9 +323,10 @@ module frr-pathd { } list metrics { key "type"; + description + "This list contains the different metrics that can be used to describe a path."; + leaf type { - description - "Type of the metric."; type enumeration { enum igp { value 1; @@ -387,6 +413,8 @@ module frr-pathd { description "Border Node Count metric"; } } + description + "Type of the metric."; } leaf required { type boolean; @@ -405,10 +433,12 @@ module frr-pathd { "Defines if the value has been generated by the originator of the path."; } leaf value { - mandatory true; type decimal64 { fraction-digits 6; } + mandatory true; + description + "Value of the metric."; } } container objective-function { @@ -422,9 +452,6 @@ module frr-pathd { "If an objective function is a requirement, or if it is only a suggestion"; } leaf type { - description - "Type of objective function."; - mandatory true; type enumeration { enum mcp { value 1; @@ -495,6 +522,9 @@ module frr-pathd { description "Minimize the number of Shared Nodes"; } } + mandatory true; + description + "Type of objective function."; } } } diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 72f3f7072e..4dd8e98ddb 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -79,6 +79,9 @@ module frr-zebra { revision 2019-06-01 { description "Initial revision."; + + reference + "FRRouting"; } feature ipv6-router-advertisements { @@ -188,6 +191,8 @@ module frr-zebra { "Multicast PIM-SM."; } } + description + "Type for VTEP flood type."; } /* @@ -317,7 +322,13 @@ module frr-zebra { */ grouping vni-information { + description + "Grouping for VNI information."; + choice type-choice { + description + "Choice between L2 and L3 VNI information."; + case l2 { leaf is-layer2 { type empty; @@ -383,6 +394,9 @@ module frr-zebra { */ grouping vni-l2-detail { + description + "Grouping for VNI L2 details."; + leaf if-index { type uint32; description @@ -402,6 +416,9 @@ module frr-zebra { } list remote-vtep-list { + description + "List of remote VTEPs."; + leaf remote-vtep { type inet:ipv4-address; description @@ -410,6 +427,8 @@ module frr-zebra { leaf vtep-flood { type vni-vtep-flood-type; + description + "VTEP flood type."; } } } @@ -419,6 +438,9 @@ module frr-zebra { */ grouping vni-l3-detail { + description + "Grouping for VNI L3 details."; + leaf svi-interface { type frr-interface:interface-ref; description @@ -459,6 +481,9 @@ module frr-zebra { */ grouping zebra-debugs { + description + "Grouping for Zebra debugging options."; + leaf debug-events { type boolean; description @@ -569,12 +594,19 @@ module frr-zebra { } grouping ribs { + description + "Grouping for RIBs supported by FRR."; + container ribs { config false; description "RIBs supported by FRR."; list rib { key "afi-safi-name table-id"; + + description + "List of RIBs, each with a specific AFI/SAFI name and table ID."; + leaf afi-safi-name { type identityref { base frr-rt:afi-safi-type; @@ -585,13 +617,16 @@ module frr-zebra { leaf table-id { type uint32; - default "254"; description "Routing Table id (default id - 254)."; } list route { key "prefix"; + + description + "List of routes, each with a specific prefix."; + leaf prefix { type inet:ip-prefix; description @@ -600,6 +635,10 @@ module frr-zebra { list route-entry { key "protocol"; + + description + "List of route entries, each owned by a specific protocol."; + leaf protocol { type frr-route-types:frr-route-types; description @@ -647,6 +686,9 @@ module frr-zebra { "Retrieve IPv4 or IPv6 unicast routes."; input { choice ip-type { + description + "Choice between retrieving IPv4 routes and retrieving IPv6 routes."; + case v4 { leaf ipv4 { type empty; @@ -685,6 +727,10 @@ module frr-zebra { } choice vrf-choice { + description + "Choice between retrieving routes in a non-default VRF or | + retrieving routes from all VRFs."; + case single { leaf vrf { type frr-vrf:vrf-ref; @@ -732,6 +778,10 @@ module frr-zebra { } choice detail { + description + "Choice between including detailed information and | + including summary information only."; + case det { leaf include-detail { type empty; @@ -752,11 +802,17 @@ module frr-zebra { // End of input output { choice route-list { + description + "Choice between IPv4 route information and IPv6 route information."; + case v4 { container routes-v4 { description "IPv4 route information."; list route { + description + "List of IPv4 routes."; + uses ip4-route; } } @@ -767,6 +823,9 @@ module frr-zebra { description "IPv6 route information."; list route { + description + "List of IPv6 routes."; + uses ip6-route; } } @@ -783,6 +842,10 @@ module frr-zebra { "Retrieve IPv6 multicast routes."; input { choice vrf-choice { + description + "Choice between retrieving routes in a non-default VRF or | + retrieving routes from all VRFs."; + case single { leaf vrf { type frr-vrf:vrf-ref; @@ -806,6 +869,9 @@ module frr-zebra { description "IPv6 mcast route information."; list route { + description + "List of IPv6 routes."; + uses ip6-route; } } @@ -820,6 +886,10 @@ module frr-zebra { // Note: no input clause. output { list vrf-list { + description + "List of VRF information including name, user configuration status, | + VRF ID, and VRF type."; + leaf name { type frr-vrf:vrf-ref; description @@ -839,6 +909,10 @@ module frr-zebra { } choice vrf-type { + description + "Choice between specifying the VRF as inactive, associated with a net namespace, | + or associated with a table ID."; + case inactive { leaf is-inactive { type empty; @@ -875,6 +949,10 @@ module frr-zebra { // Note: no input clause. output { list vrf-vni-list { + description + "List of VRF VNI information including VRF name, EVPN VNI, VxLAN interface name, | + SVI interface name, router MAC address, and state."; + leaf vrf-name { type frr-vrf:vrf-ref; description @@ -971,6 +1049,10 @@ module frr-zebra { } choice dad-freeze-choice { + description + "Choice between setting duplicate address detection | + freeze to permanent or specifying a timer."; + case freeze-permanent { leaf dad-freeze-perm { type empty; @@ -994,10 +1076,16 @@ module frr-zebra { // End get-evpn-info rpc get-vni-info { + description + "Retrieve information about EVPN VNIs."; + // If no vni is specified, retrieve global list. input { choice vni-choice { default "all-vnis"; + description + "Choice between retrieving information about all VNIs or a specific EVPN VNI."; + case all-vnis { leaf all-vnis { type empty; @@ -1029,6 +1117,9 @@ module frr-zebra { uses vni-information; choice detail-choice { + description + "Choice between detailed L2 or L3 information."; + case l2 { description "Detailed L2 information."; @@ -1053,6 +1144,10 @@ module frr-zebra { input { choice vni-choice { default "all-vnis"; + description + "Choice between retrieving information about all VNIs or | + a specific EVPN VNI and a single RMAC address."; + case all-vnis { leaf all-vnis { type empty; @@ -1079,6 +1174,10 @@ module frr-zebra { output { list rmac-info-list { + description + "List of RMAC information including RMAC address, remote VTEP IP address, | + refcount, and associated IP prefixes."; + leaf rmac { type yang:mac-address; description @@ -1098,6 +1197,9 @@ module frr-zebra { } list prefix-list { + description + "List of IP prefixes associated with the RMAC."; + leaf prefix-item { type inet:ip-prefix; description @@ -1116,6 +1218,10 @@ module frr-zebra { input { choice vni-choice { default "all-vnis"; + description + "Choice between retrieving information about all VNIs or | + a specific EVPN VNI and a single host IP address."; + case all-vnis { leaf all-vnis { type empty; @@ -1142,6 +1248,9 @@ module frr-zebra { output { list nh-info-list { + description + "List of nexthop information including IP address, MAC address, and refcount."; + leaf ip-addr { type inet:ip-address; description @@ -1161,6 +1270,9 @@ module frr-zebra { } list prefix-list { + description + "List of IP prefixes associated with the RMAC."; + leaf prefix-item { type inet:ip-prefix; description @@ -1178,6 +1290,11 @@ module frr-zebra { "Clear duplicate address detection state for one or all VNIs."; input { choice clear-dup-choice { + description + "Choice between clearing all VNIs or | + clearing state for a single EVPN VNI | + and a specific MAC or IP address."; + case all-case { leaf all-vnis { type empty; @@ -1225,6 +1342,11 @@ module frr-zebra { input { choice all-choice { default "all-vni"; + description + "Choice between retrieving information for all VNIs or | + including detailed results, a single VTEP address, or | + showing duplicate addresses."; + case all-vni { leaf all-vnis { type empty; @@ -1233,6 +1355,10 @@ module frr-zebra { } choice all-choices { + description + "Choice between including detailed results, a single VTEP address, | + or showing duplicate addresses."; + case detail-case { leaf all-detail { type empty; @@ -1267,6 +1393,10 @@ module frr-zebra { } choice single-choices { + description + "Choice between including detailed results, a specific MAC address, | + a single VTEP address, or showing duplicate addresses."; + case detail-case { leaf single-detail { type empty; @@ -1305,6 +1435,9 @@ module frr-zebra { // End of input section output { list mac-list { + description + "List of MAC addresses."; + leaf mac-addr { type yang:mac-address; description @@ -1348,6 +1481,9 @@ module frr-zebra { } container dup-detect-started { + description + "Container for duplicate detection process start time and count."; + leaf dup-detect-start { type unix-timestamp; description @@ -1386,6 +1522,9 @@ module frr-zebra { } list neighbor-list { + description + "List of neighbor addresses."; + leaf neighbor-addr { type inet:ip-address; description @@ -1406,6 +1545,9 @@ module frr-zebra { } choice local-rem-choice { + description + "Choice between local interface and VLAN or remote VTEP IP address."; + case local-case { leaf intf { type frr-interface:interface-ref; @@ -1440,6 +1582,8 @@ module frr-zebra { input { choice all-choice { default "all-vni"; + description + "Choice between retrieving information for all VNIs or including detailed results or showing duplicates."; case all-vni { leaf all-vnis { type empty; @@ -1448,6 +1592,9 @@ module frr-zebra { } choice all-choices { + description + "Choice between including detailed results or showing duplicates."; + case detail-case { leaf all-detail { type empty; @@ -1474,6 +1621,9 @@ module frr-zebra { } choice single-choices { + description + "Choice between single VTEP, neighbor address, or show duplicates."; + case vtep-case { leaf single-vtep { type inet:ipv4-address; @@ -1504,6 +1654,9 @@ module frr-zebra { // End input section output { list vni-list { + description + "List of VNI containers."; + container vni-container { description "Information for one VNI."; @@ -1535,6 +1688,9 @@ module frr-zebra { } choice local-remote-choice { + description + "Choice between local and remote entries."; + case local-case { leaf is-local { type empty; @@ -1596,6 +1752,9 @@ module frr-zebra { // End get-evpn-arp-cache rpc get-pbr-ipset { + description + "RPC to retrieve PBR IP set."; + input { leaf name { type string { @@ -1608,6 +1767,9 @@ module frr-zebra { output { list ipset-list { + description + "List of IP sets."; + leaf name { type string { length "1..32"; @@ -1621,24 +1783,26 @@ module frr-zebra { enum "net-net" { value 1; description - ""; + "Network to network IP set type."; } enum "net-port-net" { value 2; description - ""; + "Network to port to network IP set type."; } enum "net-port" { value 3; description - ""; + "Network to port IP set type."; } enum "net" { value 4; description - ""; + "Network IP set type."; } } + description + "Type of IP set."; } leaf src-prefix { @@ -1714,6 +1878,9 @@ module frr-zebra { } container ipset-stats { + description + "Container for IP set statistics."; + leaf is-unique { type empty; description @@ -1739,6 +1906,9 @@ module frr-zebra { // End get-pbr-ipset rpc get-pbr-iptable { + description + "RPC to retrieve PBR iptables."; + input { leaf name { type string { @@ -1751,6 +1921,9 @@ module frr-zebra { output { list iptable-list { + description + "List of iptables entries."; + leaf name { type string { length "1..32"; @@ -1828,6 +2001,9 @@ module frr-zebra { } container dscp-info { + description + "Container for dscp information."; + leaf dscp-value { type uint32; description @@ -1842,6 +2018,9 @@ module frr-zebra { } container fragment-info { + description + "Container for fragment information."; + leaf fragment-val { type uint32; description @@ -1856,16 +2035,19 @@ module frr-zebra { } container iptable-stats { + description + "Container for iptables statistics."; + leaf packet-counter { type uint64; description - ""; + "Number of packets processed by iptables."; } leaf bytes-counter { type uint64; description - ""; + "Number of packets processed by iptables."; } } @@ -1894,6 +2076,9 @@ module frr-zebra { */ rpc get-debugs { + description + "RPC to retrieve debug information."; + output { uses zebra-debugs; } @@ -1905,6 +2090,9 @@ module frr-zebra { description "Extends interface model with Zebra-related parameters."; container zebra { + description + "Container for Zebra-related information."; + list ipv4-addrs { key "ip prefix-length"; description @@ -2079,18 +2267,21 @@ module frr-zebra { description "Legacy mode. Only support standard admin-group (RFC3630/5305/5329)"; leaf legacy-admin-group { - description "Admin-Group value"; type uint32; + description "Admin-Group value"; } } case affinity { container affinities { + description + "Container for affinity information."; + leaf-list affinity { type frr-affinity-map:affinity-map-ref; - max-elements "256"; must '../../affinity-mode != "standard" or /frr-affinity-map:lib/frr-affinity-map:affinity-maps/frr-affinity-map:affinity-map[frr-affinity-map:name=current()]/frr-affinity-map:value < 32' { error-message "Affinity bit-position must be less than 32 when used with standard affinity mode"; } + max-elements "256"; description "Array of Attribute Names"; } @@ -2098,9 +2289,6 @@ module frr-zebra { } } leaf affinity-mode { - description - "Affinity mode"; - default "extended"; type enumeration { enum extended { value 0; @@ -2118,9 +2306,11 @@ module frr-zebra { "Standard and extended Admin-Group"; } } + default "extended"; + description + "Affinity mode"; } container neighbor { - description "Remote ASBR information (RFC 5316 & RFC 5392)"; presence "Activates neighbor information on this interface."; leaf remote-as { type inet:as-number; @@ -2134,6 +2324,8 @@ module frr-zebra { description "IPv4 Remote ASBR ID (RFC 5316 & RFC 5392)"; } + description + "Remote ASBR information (RFC 5316 & RFC 5392)"; } leaf delay { type uint32 { @@ -2143,8 +2335,6 @@ module frr-zebra { "Average Unidirectional Link Delay"; } container min-max-delay { - description - "Min/Max Unidirectional Link Delay"; presence "Activates min/max delay."; leaf delay-min { type uint32 { @@ -2168,6 +2358,8 @@ module frr-zebra { description "Max Delay"; } + description + "Min/Max Unidirectional Link Delay"; } leaf delay-variation { type uint32 { @@ -2192,6 +2384,9 @@ module frr-zebra { choice esi-choice { description "ESI type"; container type-0 { + description + "Container for type-0 information."; + leaf esi { type yang:hex-string { length "29"; @@ -2201,6 +2396,9 @@ module frr-zebra { } } container type-3 { + description + "Container for type-3 information."; + leaf system-mac { type yang:mac-address; description @@ -2680,6 +2878,8 @@ module frr-zebra { leaf vni-id { type vni-id-type; + description + "A VNI id."; } leaf remote-vtep { @@ -2805,10 +3005,10 @@ module frr-zebra { } leaf end { type uint32; - mandatory true; must ". >= ../start" { error-message "End table must be greater than or equal to start table"; } + mandatory true; description "The last table to use."; } @@ -2832,6 +3032,9 @@ module frr-zebra { } augment "/frr-vrf:lib/frr-vrf:vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop" { + description + "Augments the nexthop with operational data."; + uses frr-nh:frr-nexthop-operational; } @@ -2843,10 +3046,10 @@ module frr-zebra { description "Data model for the Zebra daemon."; leaf max-multipath { - config false; type uint16 { range "1..65535"; } + config false; description "The maximum number of nexthops for a route. At this point it is unlikely that a multipath number will ever get larger then @@ -2939,6 +3142,9 @@ module frr-zebra { * Debug options */ container debugs { + description + "This container contains debug information for the zebra daemon."; + uses zebra-debugs; } /* End of debugs */ diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 9f26852d1f..116a697de9 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -587,6 +587,10 @@ static void fpm_read(struct event *t) struct zebra_dplane_ctx *ctx; size_t available_bytes; size_t hdr_available_bytes; + struct dplane_ctx_list_head batch_list; + + /* Initialize the batch list */ + dplane_ctx_q_init(&batch_list); /* Let's ignore the input at the moment. */ rv = stream_read_try(fnc->ibuf, fnc->socket, @@ -627,7 +631,7 @@ static void fpm_read(struct event *t) while (available_bytes) { if (available_bytes < (ssize_t)FPM_MSG_HDR_LEN) { stream_pulldown(fnc->ibuf); - return; + goto send_batch; } fpm.version = stream_getc(fnc->ibuf); @@ -642,7 +646,7 @@ static void fpm_read(struct event *t) __func__, fpm.version, fpm.msg_type); FPM_RECONNECT(fnc); - return; + goto send_batch; } /* @@ -654,7 +658,7 @@ static void fpm_read(struct event *t) "%s: Received message length: %u that does not even fill the FPM header", __func__, fpm.msg_len); FPM_RECONNECT(fnc); - return; + goto send_batch; } /* @@ -665,7 +669,7 @@ static void fpm_read(struct event *t) if (fpm.msg_len > available_bytes) { stream_rewind_getp(fnc->ibuf, FPM_MSG_HDR_LEN); stream_pulldown(fnc->ibuf); - return; + goto send_batch; } available_bytes -= FPM_MSG_HDR_LEN; @@ -715,8 +719,9 @@ static void fpm_read(struct event *t) break; } - /* Parse the route data into a dplane ctx, then - * enqueue it to zebra for processing. + /* + * Parse the route data into a dplane ctx, add to ctx list + * and enqueue the batch of ctx to zebra for processing */ ctx = dplane_ctx_alloc(); dplane_ctx_route_init(ctx, DPLANE_OP_ROUTE_NOTIFY, NULL, @@ -735,7 +740,8 @@ static void fpm_read(struct event *t) * tableid to 0 in order for this to work. */ dplane_ctx_set_vrf(ctx, VRF_UNKNOWN); - dplane_provider_enqueue_to_zebra(ctx); + /* Add to the list for batching */ + dplane_ctx_enqueue_tail(&batch_list, ctx); } else { /* * Let's continue to read other messages @@ -755,6 +761,15 @@ static void fpm_read(struct event *t) } stream_reset(fnc->ibuf); + +send_batch: + /* Send all contexts to zebra in a single batch if we have any */ + if (dplane_ctx_queue_count(&batch_list) > 0) { + if (IS_ZEBRA_DEBUG_FPM) + zlog_debug("%s: Sending batch of %u contexts to zebra", __func__, + dplane_ctx_queue_count(&batch_list)); + dplane_provider_enqueue_ctx_list_to_zebra(&batch_list); + } } static void fpm_write(struct event *t) diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c index 70dcaf91a1..73e9dc2482 100644 --- a/zebra/fpm_listener.c +++ b/zebra/fpm_listener.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <unistd.h> #include <time.h> +#include <signal.h> #ifdef GNU_LINUX #include <stdint.h> @@ -33,13 +34,44 @@ #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <linux/if_link.h> +#include <linux/nexthop.h> #include "rt_netlink.h" #include "fpm/fpm.h" #include "lib/libfrr.h" +#include "zebra/kernel_netlink.h" XREF_SETUP(); +PREDECL_RBTREE_UNIQ(fpm_route); + +/* Route structure to store in RB tree */ +struct fpm_route { + struct prefix prefix; + uint32_t table_id; + uint32_t nhg_id; + struct fpm_route_item rb_item; +}; + +/* Comparison function for routes */ +static int fpm_route_cmp(const struct fpm_route *a, const struct fpm_route *b) +{ + int ret; + + /* First compare table IDs */ + if (a->table_id < b->table_id) + return -1; + if (a->table_id > b->table_id) + return 1; + + /* Then compare prefixes */ + ret = prefix_cmp(&a->prefix, &b->prefix); + return ret; +} + +/* RB tree for storing routes */ +DECLARE_RBTREE_UNIQ(fpm_route, struct fpm_route, rb_item, fpm_route_cmp); + struct glob { int server_sock; int sock; @@ -47,6 +79,8 @@ struct glob { bool reflect_fail_all; bool dump_hex; FILE *output_file; + const char *dump_file; + struct fpm_route_head route_tree; }; struct glob glob_space; @@ -573,6 +607,67 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx) } /* + * parse_nexthop_msg + */ +static int parse_nexthop_msg(struct nlmsghdr *hdr) +{ + struct nhmsg *nhmsg; + struct rtattr *tb[NHA_MAX + 1] = {}; + int len; + uint32_t nhgid = 0; + uint8_t nhg_count = 0; + const char *err_msg = NULL; + char protocol_str[32] = "Unknown"; + + nhmsg = NLMSG_DATA(hdr); + len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*nhmsg)); + if (len < 0) { + fprintf(stderr, "Bad nexthop message length\n"); + return 0; + } + + if (!parse_rtattrs_(RTM_NHA(nhmsg), len, tb, ARRAY_SIZE(tb), &err_msg)) { + fprintf(stderr, "Error parsing nexthop attributes: %s\n", err_msg); + return 0; + } + + /* Get protocol string */ + snprintf(protocol_str, sizeof(protocol_str), "%s(%u)", + netlink_prot_to_s(nhmsg->nh_protocol), nhmsg->nh_protocol); + + /* Get Nexthop Group ID */ + if (tb[NHA_ID]) + nhgid = *(uint32_t *)RTA_DATA(tb[NHA_ID]); + + /* Count nexthops in the group */ + if (tb[NHA_GROUP]) { + struct nexthop_grp *nhg = (struct nexthop_grp *)RTA_DATA(tb[NHA_GROUP]); + size_t count = (RTA_PAYLOAD(tb[NHA_GROUP]) / sizeof(*nhg)); + + if (count > 0 && (count * sizeof(*nhg)) == RTA_PAYLOAD(tb[NHA_GROUP])) + nhg_count = count; + } else if (tb[NHA_OIF] || tb[NHA_GATEWAY]) { + /* Single nexthop case */ + nhg_count = 1; + } + + /* Print blackhole status if applicable */ + if (tb[NHA_BLACKHOLE]) { + fprintf(glob->output_file, + "[%s] %s Nexthop Group ID: %u, Protocol: %s, Type: BLACKHOLE, Family: %u\n", + get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid, + protocol_str, nhmsg->nh_family); + } else { + fprintf(glob->output_file, + "[%s] %s Nexthop Group ID: %u, Protocol: %s, Contains %u nexthops, Family: %u, Scope: %u\n", + get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid, + protocol_str, nhg_count, nhmsg->nh_family, nhmsg->nh_scope); + } + + return 1; +} + +/* * addr_to_s */ static const char * @@ -695,6 +790,64 @@ static void fpm_listener_hexdump(const void *mem, size_t len) } /* + * handle_route_update + * Handles adding or removing a route from the route tree + */ +static void handle_route_update(struct netlink_msg_ctx *ctx, bool is_add) +{ + struct fpm_route *route; + struct fpm_route *existing; + struct fpm_route lookup = { 0 }; + + if (!ctx->dest || !ctx->rtmsg) + return; + + /* Set up lookup key */ + lookup.prefix.family = ctx->rtmsg->rtm_family; + lookup.prefix.prefixlen = ctx->rtmsg->rtm_dst_len; + memcpy(&lookup.prefix.u.prefix, RTA_DATA(ctx->dest), + (ctx->rtmsg->rtm_family == AF_INET) ? 4 : 16); + lookup.table_id = ctx->rtmsg->rtm_table; + lookup.nhg_id = ctx->nhgid ? *ctx->nhgid : 0; + /* Look up existing route */ + existing = fpm_route_find(&glob->route_tree, &lookup); + + if (is_add) { + if (existing) { + /* Route exists, update it */ + existing->prefix = lookup.prefix; + existing->table_id = lookup.table_id; + existing->nhg_id = lookup.nhg_id; + } else { + /* Create new route structure */ + route = calloc(1, sizeof(struct fpm_route)); + if (!route) { + fprintf(stderr, "Failed to allocate route structure\n"); + return; + } + + /* Copy prefix information */ + route->prefix = lookup.prefix; + route->table_id = lookup.table_id; + route->nhg_id = lookup.nhg_id; + + /* Add route to tree */ + if (fpm_route_add(&glob->route_tree, route)) { + fprintf(stderr, "Failed to add route to tree\n"); + free(route); + } + } + } else { + /* Remove route from tree */ + if (existing) { + existing = fpm_route_del(&glob->route_tree, existing); + if (existing) + free(existing); + } + } +} + +/* * parse_netlink_msg */ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm) @@ -726,6 +879,7 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm) } print_netlink_msg_ctx(ctx); + handle_route_update(ctx, hdr->nlmsg_type == RTM_NEWROUTE); if (glob->reflect && hdr->nlmsg_type == RTM_NEWROUTE && ctx->rtmsg->rtm_protocol > RTPROT_STATIC) { @@ -742,6 +896,11 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm) } break; + case RTM_NEWNEXTHOP: + case RTM_DELNEXTHOP: + parse_nexthop_msg(hdr); + break; + default: fprintf(glob->output_file, "[%s] Ignoring netlink message - Type: %s(%d)\n", get_timestamp(), netlink_msg_type_to_s(hdr->nlmsg_type), @@ -786,17 +945,62 @@ static void fpm_serve(void) } } +/* Signal handler for SIGUSR1 */ +static void sigusr1_handler(int signum) +{ + struct fpm_route *route; + char buf[PREFIX_STRLEN]; + FILE *out = glob->output_file; + FILE *dump_fp = NULL; + + if (glob->dump_file) { + dump_fp = fopen(glob->dump_file, "w"); + if (dump_fp) { + out = dump_fp; + setbuf(dump_fp, NULL); + } else + out = glob->output_file; + } + + fprintf(out, "\n=== Route Tree Dump ===\n"); + fprintf(out, "Timestamp: %s\n", get_timestamp()); + fprintf(out, "Total routes: %zu\n", fpm_route_count(&glob->route_tree)); + fprintf(out, "Routes:\n"); + + frr_each (fpm_route, &glob->route_tree, route) { + prefix2str(&route->prefix, buf, sizeof(buf)); + fprintf(out, " Table %u, NHG %u: %s\n", route->table_id, route->nhg_id, buf); + } + fprintf(out, "=====================\n\n"); + fflush(out); + + if (dump_fp) + fclose(dump_fp); +} + int main(int argc, char **argv) { pid_t daemon; int r; bool fork_daemon = false; const char *output_file = NULL; + struct sigaction sa; memset(glob, 0, sizeof(*glob)); glob->output_file = stdout; + fpm_route_init(&glob->route_tree); + + /* Set up signal handler for SIGUSR1 */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sigusr1_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGUSR1, &sa, NULL) < 0) { + fprintf(stderr, "Failed to set up SIGUSR1 handler: %s\n", strerror(errno)); + exit(1); + } - while ((r = getopt(argc, argv, "rfdvo:")) != -1) { + while ((r = getopt(argc, argv, "rfdvo:z:")) != -1) { switch (r) { case 'r': glob->reflect = true; @@ -813,6 +1017,9 @@ int main(int argc, char **argv) case 'o': output_file = optarg; break; + case 'z': + glob->dump_file = optarg; + break; } } diff --git a/zebra/interface.c b/zebra/interface.c index fd1ea380a5..f836b3ab35 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1919,8 +1919,7 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx) if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) interface_vrf_change(op, ifindex, name, tableid, ns_id); } else { - ifindex_t master_ifindex, bridge_ifindex, bond_ifindex, - link_ifindex; + ifindex_t master_ifindex, bridge_ifindex, link_ifindex; enum zebra_slave_iftype zif_slave_type; uint8_t bypass; uint64_t flags; @@ -2730,14 +2729,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) } if (gre_info->ifindex_link && (gre_info->link_nsid != NS_UNKNOWN)) { - struct interface *ifp; + struct interface *nifp; - ifp = if_lookup_by_index_per_ns( - zebra_ns_lookup(gre_info->link_nsid), - gre_info->ifindex_link); + nifp = if_lookup_by_index_per_ns( + zebra_ns_lookup(gre_info->link_nsid), + gre_info->ifindex_link); vty_out(vty, " Link Interface %s\n", - ifp == NULL ? "Unknown" : - ifp->name); + nifp == NULL ? "Unknown" : + nifp->name); } } @@ -3116,14 +3115,13 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, } if (gre_info->ifindex_link && (gre_info->link_nsid != NS_UNKNOWN)) { - struct interface *ifp; + struct interface *nifp; - ifp = if_lookup_by_index_per_ns( + nifp = if_lookup_by_index_per_ns( zebra_ns_lookup(gre_info->link_nsid), gre_info->ifindex_link); json_object_string_add(json_if, "linkInterface", - ifp == NULL ? "Unknown" - : ifp->name); + nifp == NULL ? "Unknown" : nifp->name); } } diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 2dfc027f1d..a0ce919e91 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -217,11 +217,11 @@ void irdp_read_raw(struct event *r) char buf[IRDP_RX_BUF]; int ret, ifindex = 0; - int irdp_sock = EVENT_FD(r); - event_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock, + int irdp_socket = EVENT_FD(r); + event_add_read(zrouter.master, irdp_read_raw, NULL, irdp_socket, &t_irdp_raw); - ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex); + ret = irdp_recvmsg(irdp_socket, (uint8_t *)buf, IRDP_RX_BUF, &ifindex); if (ret < 0) flog_warn(EC_LIB_SOCKET, "IRDP: RX Error length = %d", ret); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 4789cb62f2..8a6bfc45e0 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1054,7 +1054,7 @@ void rtm_read(struct rt_msghdr *rtm) /* * Ignore our own messages. */ - if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) + if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == zebra_pid) return; if (dest.sa.sa_family == AF_INET) { diff --git a/zebra/main.c b/zebra/main.c index 5c169bb839..b23307458b 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -57,7 +57,7 @@ char *zserv_path; /* process id. */ -pid_t pid; +pid_t zebra_pid; /* Pacify zclient.o in libfrr, which expects this variable. */ struct event_loop *master; @@ -247,6 +247,8 @@ void zebra_finalize(struct event *dummy) label_manager_terminate(); + affinity_map_terminate(); + ns_walk_func(zebra_ns_final_shutdown, NULL, NULL); ns_terminate(); @@ -518,7 +520,7 @@ int main(int argc, char **argv) */ /* Needed for BSD routing socket. */ - pid = getpid(); + zebra_pid = getpid(); /* Start dataplane system */ zebra_dplane_start(); diff --git a/zebra/rib.h b/zebra/rib.h index 8484fe1291..fa6ce4447b 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -192,6 +192,12 @@ struct route_entry { struct meta_queue { struct list *subq[MQ_SIZE]; uint32_t size; /* sum of lengths of all subqueues */ + _Atomic uint32_t max_subq[MQ_SIZE]; /* Max size of individual sub queue */ + _Atomic uint32_t max_metaq; /* Max size of the MetaQ */ + _Atomic uint32_t total_subq[MQ_SIZE]; /* Total subq events */ + _Atomic uint32_t total_metaq; /* Total MetaQ events */ + _Atomic uint32_t re_subq[MQ_SIZE]; /* current RE count sub queue */ + _Atomic uint32_t max_re_subq[MQ_SIZE]; /* Max RE in sub queue */ }; /* @@ -462,6 +468,8 @@ extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf); extern int zebra_rib_labeled_unicast(struct route_entry *re); extern struct route_table *rib_table_ipv6; +extern uint32_t zebra_rib_meta_queue_size(void); + extern void rib_unlink(struct route_node *rn, struct route_entry *re); extern int rib_gc_dest(struct route_node *rn); extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter); @@ -472,6 +480,7 @@ extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq, bool rt_delete); extern void rib_update_handle_vrf_all(enum rib_update_event event, int rtype); +int zebra_show_metaq_counter(struct vty *vty, bool uj); /* * rib_find_rn_from_ctx @@ -626,7 +635,7 @@ extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, extern void zebra_vty_init(void); extern uint32_t zebra_rib_dplane_results_count(void); -extern pid_t pid; +extern pid_t zebra_pid; extern uint32_t rt_table_main_id; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 9a60e32b65..a2e7997ab4 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3139,13 +3139,11 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (nh->nh_srv6->seg6local_action != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) { uint32_t action; - uint16_t encap; - struct rtattr *nest; - const struct seg6local_context *ctx; + const struct seg6local_context *ctx6; req->nhm.nh_family = AF_INET6; action = nh->nh_srv6->seg6local_action; - ctx = &nh->nh_srv6->seg6local_ctx; + ctx6 = &nh->nh_srv6->seg6local_ctx; encap = LWTUNNEL_ENCAP_SEG6_LOCAL; if (!nl_attr_put(&req->n, buflen, NHA_ENCAP_TYPE, @@ -3174,7 +3172,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, return 0; if (!nl_attr_put( &req->n, buflen, - SEG6_LOCAL_NH6, &ctx->nh6, + SEG6_LOCAL_NH6, &ctx6->nh6, sizeof(struct in6_addr))) return 0; break; @@ -3187,7 +3185,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (!nl_attr_put32( &req->n, buflen, SEG6_LOCAL_TABLE, - ctx->table)) + ctx6->table)) return 0; break; case SEG6_LOCAL_ACTION_END_DX4: @@ -3198,7 +3196,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, return 0; if (!nl_attr_put( &req->n, buflen, - SEG6_LOCAL_NH4, &ctx->nh4, + SEG6_LOCAL_NH4, &ctx6->nh4, sizeof(struct in_addr))) return 0; break; @@ -3210,7 +3208,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, return 0; if (!nl_attr_put(&req->n, buflen, SEG6_LOCAL_NH6, - &ctx->nh6, + &ctx6->nh6, sizeof(struct in6_addr))) return 0; break; @@ -3223,7 +3221,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (!nl_attr_put32( &req->n, buflen, SEG6_LOCAL_TABLE, - ctx->table)) + ctx6->table)) return 0; break; case SEG6_LOCAL_ACTION_END_DT4: @@ -3235,7 +3233,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (!nl_attr_put32( &req->n, buflen, SEG6_LOCAL_VRFTABLE, - ctx->table)) + ctx6->table)) return 0; break; case SEG6_LOCAL_ACTION_END_DT46: @@ -3247,7 +3245,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (!nl_attr_put32( &req->n, buflen, SEG6_LOCAL_VRFTABLE, - ctx->table)) + ctx6->table)) return 0; break; default: @@ -3268,7 +3266,6 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, !sid_zero(nh->nh_srv6->seg6_segs)) { char tun_buf[4096]; ssize_t tun_len; - struct rtattr *nest; if (!nl_attr_put16(&req->n, buflen, NHA_ENCAP_TYPE, diff --git a/zebra/rtadv.c b/zebra/rtadv.c index a767bda72e..ce3f0320f5 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -1602,8 +1602,6 @@ DEFPY(show_ipv6_nd_ra_if, show_ipv6_nd_ra_if_cmd, struct vrf *vrf; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - struct zebra_vrf *zvrf; - zvrf = vrf->info; if (!zvrf) continue; diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index d4e65eb18c..fc78f87eb1 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3872,12 +3872,13 @@ static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS) static inline void zread_iptable(ZAPI_HANDLER_ARGS) { struct zebra_pbr_iptable *zpi = - XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable)); + XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable)); struct stream *s; s = msg; zpi->interface_name_list = list_new(); + zpi->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free; zpi->sock = client->sock; zpi->vrf_id = zvrf->vrf->vrf_id; STREAM_GETL(s, zpi->unique); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 4344a8d79a..a6d43daa93 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -6590,6 +6590,14 @@ int dplane_provider_work_ready(void) } /* + * Enqueue a context list to zebra main. + */ +void dplane_provider_enqueue_ctx_list_to_zebra(struct dplane_ctx_list_head *batch_list) +{ + (zdplane_info.dg_results_cb)(batch_list); +} + +/* * Enqueue a context directly to zebra main. */ void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx) diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index cabc70c232..1c03a29534 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -1236,6 +1236,9 @@ void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov, /* Enqueue a context directly to zebra main. */ void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx); +/* Enqueue a context list to zebra main. */ +void dplane_provider_enqueue_ctx_list_to_zebra(struct dplane_ctx_list_head *batch_list); + /* Enable collection of extra info about interfaces in route updates; * this allows a provider/plugin to see some extra info in route update * context objects. diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 95207ce75c..34c936155a 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -261,7 +261,7 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd, ri->prefix = rib_dest_prefix(dest); ri->af = rib_dest_af(dest); - ri->nlmsg_pid = pid; + ri->nlmsg_pid = zebra_pid; ri->nlmsg_type = cmd; ri->rtm_protocol = RTPROT_UNSPEC; diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 589196ecb9..a033b3ea50 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1161,11 +1161,32 @@ static void zebra_nhg_handle_uninstall(struct nhg_hash_entry *nhe) zebra_nhg_free(nhe); } +static void nhg_handle_install_one(struct nhg_connected *node) +{ + struct nhg_connected *rb_node_indirect_dep = NULL; + + frr_each_safe (nhg_connected_tree, &node->nhe->nhg_dependents, + rb_node_indirect_dep) { + SET_FLAG(rb_node_indirect_dep->nhe->flags, + NEXTHOP_GROUP_REINSTALL); + + if (IS_ZEBRA_DEBUG_NHG_DETAIL) + zlog_debug("%s nh id %u (flags 0x%x) associated dependents NHG %pNG (flags 0x%x) Re-install", + __func__, node->nhe->id, + node->nhe->flags, + rb_node_indirect_dep->nhe, + rb_node_indirect_dep->nhe->flags); + + zebra_nhg_install_kernel(rb_node_indirect_dep->nhe, + ZEBRA_ROUTE_MAX); + } + +} + static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install) { /* Update validity of groups depending on it */ struct nhg_connected *rb_node_dep; - struct nhg_connected *rb_node_indirect_dep = NULL; frr_each_safe (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) { zebra_nhg_set_valid(rb_node_dep->nhe, true); @@ -1173,19 +1194,7 @@ static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install) if (install) { if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED) && CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_RECURSIVE)) { - frr_each_safe (nhg_connected_tree, &rb_node_dep->nhe->nhg_dependents, - rb_node_indirect_dep) { - SET_FLAG(rb_node_indirect_dep->nhe->flags, - NEXTHOP_GROUP_REINSTALL); - if (IS_ZEBRA_DEBUG_NHG_DETAIL) - zlog_debug("%s nh id %u (flags 0x%x) associated dependents NHG %pNG (flags 0x%x) Re-install", - __func__, rb_node_dep->nhe->id, - rb_node_dep->nhe->flags, - rb_node_indirect_dep->nhe, - rb_node_indirect_dep->nhe->flags); - zebra_nhg_install_kernel(rb_node_indirect_dep->nhe, - ZEBRA_ROUTE_MAX); - } + nhg_handle_install_one(rb_node_dep); } if (IS_ZEBRA_DEBUG_NHG_DETAIL) diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 7f3635702f..49846a00c8 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -23,7 +23,11 @@ /* definitions */ DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list"); -DEFINE_MTYPE(ZEBRA, PBR_OBJ, "PBR"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_RULE, "PBR rule"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET, "PBR ipset"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET_ENTRY, "PBR ipset entry"); +DEFINE_MTYPE(ZEBRA, PBR_IPTABLE, "PBR iptable"); + /* definitions */ static const struct message ipset_type_msg[] = { @@ -151,7 +155,7 @@ void zebra_pbr_rules_free(void *arg) rule = (struct zebra_pbr_rule *)arg; (void)dplane_pbr_rule_delete(rule); - XFREE(MTYPE_PBR_OBJ, rule); + XFREE(MTYPE_PBR_RULE, rule); } uint32_t zebra_pbr_rules_hash_key(const void *arg) @@ -274,7 +278,7 @@ void zebra_pbr_ipset_free(void *arg) ipset = (struct zebra_pbr_ipset *)arg; hook_call(zebra_pbr_ipset_update, 0, ipset); - XFREE(MTYPE_PBR_OBJ, ipset); + XFREE(MTYPE_PBR_IPSET, ipset); } uint32_t zebra_pbr_ipset_hash_key(const void *arg) @@ -318,7 +322,7 @@ void zebra_pbr_ipset_entry_free(void *arg) hook_call(zebra_pbr_ipset_entry_update, 0, ipset); - XFREE(MTYPE_PBR_OBJ, ipset); + XFREE(MTYPE_PBR_IPSET_ENTRY, ipset); } uint32_t zebra_pbr_ipset_entry_hash_key(const void *arg) @@ -379,23 +383,16 @@ bool zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) static void _zebra_pbr_iptable_free_all(void *arg, bool all) { struct zebra_pbr_iptable *iptable; - struct listnode *node, *nnode; - char *name; iptable = (struct zebra_pbr_iptable *)arg; if (all) hook_call(zebra_pbr_iptable_update, 0, iptable); - if (iptable->interface_name_list) { - for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node, - nnode, name)) { - XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); - list_delete_node(iptable->interface_name_list, node); - } + if (iptable->interface_name_list) list_delete(&iptable->interface_name_list); - } - XFREE(MTYPE_PBR_OBJ, iptable); + + XFREE(MTYPE_PBR_IPTABLE, iptable); } void zebra_pbr_iptable_free(void *arg) @@ -477,7 +474,7 @@ static void *pbr_rule_alloc_intern(void *arg) zpr = (struct zebra_pbr_rule *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(*new)); + new = XCALLOC(MTYPE_PBR_RULE, sizeof(*new)); memcpy(new, zpr, sizeof(*zpr)); @@ -491,7 +488,7 @@ static struct zebra_pbr_rule *pbr_rule_free(struct zebra_pbr_rule *hash_data, zebra_neigh_deref(hash_data); hash_release(zrouter.rules_hash, hash_data); if (free_data) { - XFREE(MTYPE_PBR_OBJ, hash_data); + XFREE(MTYPE_PBR_RULE, hash_data); return NULL; } @@ -729,7 +726,7 @@ void zebra_pbr_add_rule(struct zebra_pbr_rule *rule) (void)dplane_pbr_rule_update(found, new); /* release the old hash data */ if (old) - XFREE(MTYPE_PBR_OBJ, old); + XFREE(MTYPE_PBR_RULE, old); } else { if (IS_ZEBRA_DEBUG_PBR) zlog_debug( @@ -897,7 +894,7 @@ static void *pbr_ipset_alloc_intern(void *arg) zpi = (struct zebra_pbr_ipset *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset)); + new = XCALLOC(MTYPE_PBR_IPSET, sizeof(struct zebra_pbr_ipset)); memcpy(new, zpi, sizeof(*zpi)); @@ -918,7 +915,7 @@ void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset) (void)dplane_pbr_ipset_delete(ipset); if (lookup) { hash_release(zrouter.ipset_hash, lookup); - XFREE(MTYPE_PBR_OBJ, lookup); + XFREE(MTYPE_PBR_IPSET, lookup); } else zlog_debug( "%s: IPSet Entry being deleted we know nothing about", @@ -971,7 +968,7 @@ static void *pbr_ipset_entry_alloc_intern(void *arg) zpi = (struct zebra_pbr_ipset_entry *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset_entry)); + new = XCALLOC(MTYPE_PBR_IPSET_ENTRY, sizeof(struct zebra_pbr_ipset_entry)); memcpy(new, zpi, sizeof(*zpi)); @@ -993,12 +990,19 @@ void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset) (void)dplane_pbr_ipset_entry_delete(ipset); if (lookup) { hash_release(zrouter.ipset_entry_hash, lookup); - XFREE(MTYPE_PBR_OBJ, lookup); + XFREE(MTYPE_PBR_IPSET_ENTRY, lookup); } else zlog_debug("%s: IPSet being deleted we know nothing about", __func__); } +void zebra_pbr_iptable_interface_name_list_free(void *arg) +{ + char *name = arg; + + XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); +} + static void *pbr_iptable_alloc_intern(void *arg) { struct zebra_pbr_iptable *zpi; @@ -1008,11 +1012,12 @@ static void *pbr_iptable_alloc_intern(void *arg) zpi = (struct zebra_pbr_iptable *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable)); + new = XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable)); /* Deep structure copy */ memcpy(new, zpi, sizeof(*zpi)); new->interface_name_list = list_new(); + new->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free; if (zpi->interface_name_list) { for (ALL_LIST_ELEMENTS_RO(zpi->interface_name_list, ln, ifname)) @@ -1039,18 +1044,9 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable) lookup = hash_lookup(zrouter.iptable_hash, iptable); (void)dplane_pbr_iptable_delete(iptable); if (lookup) { - struct listnode *node, *nnode; - char *name; - hash_release(zrouter.iptable_hash, lookup); - for (ALL_LIST_ELEMENTS(iptable->interface_name_list, - node, nnode, name)) { - XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); - list_delete_node(iptable->interface_name_list, - node); - } - list_delete(&iptable->interface_name_list); - XFREE(MTYPE_PBR_OBJ, lookup); + list_delete(&lookup->interface_name_list); + XFREE(MTYPE_PBR_IPTABLE, lookup); } else zlog_debug("%s: IPTable being deleted we know nothing about", __func__); diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 1e4b5cd0f3..25868a6c1e 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -21,7 +21,8 @@ extern "C" { #endif /* Memory type for PBR objects. */ -DECLARE_MTYPE(PBR_OBJ); +DECLARE_MTYPE(PBR_IPTABLE); + struct zebra_pbr_action { afi_t afi; @@ -195,6 +196,8 @@ struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(char *ipsetname); void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset); void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset); +void zebra_pbr_iptable_interface_name_list_free(void *arg); + void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable); void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable); void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 20ec25a431..c7dc5e5d07 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -30,6 +30,7 @@ #include "printfrr.h" #include "frrscript.h" #include "frrdistance.h" +#include "lib/termtable.h" #include "zebra/zebra_router.h" #include "zebra/connected.h" @@ -273,6 +274,63 @@ static const char *subqueue2str(enum meta_queue_indexes index) return "Unknown"; } +/* Handler for 'show zebra metaq' */ +int zebra_show_metaq_counter(struct vty *vty, bool uj) +{ + struct meta_queue *mq = zrouter.mq; + struct ttable *tt = NULL; + char *table = NULL; + json_object *json = NULL; + json_object *json_table = NULL; + + if (!mq) + return CMD_WARNING; + + /* Create a table for subqueue details */ + tt = ttable_new(&ttable_styles[TTSTYLE_ASCII]); + ttable_add_row(tt, "SubQ|Current|Max Size|Total"); + + /* Add rows for each subqueue */ + for (uint8_t i = 0; i < MQ_SIZE; i++) { + ttable_add_row(tt, "%s|%u|%u|%u", subqueue2str(i), mq->subq[i]->count, + mq->max_subq[i], mq->total_subq[i]); + } + + /* For a better formatting between the content and separator */ + tt->style.cell.rpad = 2; + tt->style.cell.lpad = 1; + ttable_restyle(tt); + + if (uj) { + json = json_object_new_object(); + /* Add MetaQ summary to the JSON object */ + json_object_int_add(json, "currentSize", mq->size); + json_object_int_add(json, "maxSize", mq->max_metaq); + json_object_int_add(json, "total", mq->total_metaq); + + /* Convert the table to JSON and add it to the main JSON object */ + /* n = name/string, u = unsigned int */ + json_table = ttable_json(tt, "sddd"); + json_object_object_add(json, "subqueues", json_table); + vty_json(vty, json); + } else { + vty_out(vty, "MetaQ Summary\n"); + vty_out(vty, "Current Size\t: %u\n", mq->size); + vty_out(vty, "Max Size\t: %u\n", mq->max_metaq); + vty_out(vty, "Total\t\t: %u\n", mq->total_metaq); + + /* Dump the table */ + table = ttable_dump(tt, "\n"); + vty_out(vty, "%s\n", table); + XFREE(MTYPE_TMP_TTABLE, table); + } + + /* Clean up the table */ + ttable_del(tt); + + return CMD_SUCCESS; +} + printfrr_ext_autoreg_p("ZN", printfrr_zebra_node); static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea, const void *ptr) @@ -317,9 +375,9 @@ static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea, #define rnode_debug(node, vrf_id, msg, ...) \ do { \ - struct vrf *vrf = vrf_lookup_by_id(vrf_id); \ + struct vrf *_vrf = vrf_lookup_by_id(vrf_id); \ zlog_debug("%s: (%s:%pZNt):%pZN: " msg, __func__, \ - VRF_LOGNAME(vrf), node, node, ##__VA_ARGS__); \ + VRF_LOGNAME(_vrf), node, node, ##__VA_ARGS__); \ } while (0) #define rnode_info(node, vrf_id, msg, ...) \ @@ -1225,10 +1283,10 @@ static void rib_process(struct route_node *rn) * will not iterate so we are ok. */ if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - struct route_entry *re = re_list_first(&dest->routes); + struct route_entry *rent = re_list_first(&dest->routes); zlog_debug("%s(%u:%u:%u):%pRN: Processing rn %p", VRF_LOGNAME(vrf), vrf_id, - re->table, safi, rn, rn); + rent->table, safi, rn, rn); } old_fib = dest->selected_fib; @@ -3257,6 +3315,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data) struct route_node *rn = NULL; struct route_entry *re = NULL, *curr_re = NULL; uint8_t qindex = MQ_SIZE, curr_qindex = MQ_SIZE; + uint64_t curr, high; rn = (struct route_node *)data; @@ -3300,18 +3359,40 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data) listnode_add(mq->subq[qindex], rn); route_lock_node(rn); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed); + curr = listcount(mq->subq[qindex]); + high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s", - (void *)rn, subqueue2str(qindex)); + rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s mq size %u", (void *)rn, + subqueue2str(qindex), zrouter.mq->size); return 0; } static int early_label_meta_queue_add(struct meta_queue *mq, void *data) { + uint64_t curr, high; + listnode_add(mq->subq[META_QUEUE_EARLY_LABEL], data); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_LABEL], 1, memory_order_relaxed); + curr = listcount(mq->subq[META_QUEUE_EARLY_LABEL]); + high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], curr, + memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); + return 0; } @@ -3320,6 +3401,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data) struct nhg_ctx *ctx = NULL; uint8_t qindex = META_QUEUE_NHG; struct wq_nhg_wrapper *w; + uint64_t curr, high; ctx = (struct nhg_ctx *)data; @@ -3333,10 +3415,19 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data) listnode_add(mq->subq[qindex], w); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed); + curr = listcount(mq->subq[qindex]); + high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("NHG Context id=%u queued into sub-queue %s", - ctx->id, subqueue2str(qindex)); + zlog_debug("NHG Context id=%u queued into sub-queue %s mq size %u", ctx->id, + subqueue2str(qindex), zrouter.mq->size); return 0; } @@ -3347,6 +3438,7 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data, struct nhg_hash_entry *nhe = NULL; uint8_t qindex = META_QUEUE_NHG; struct wq_nhg_wrapper *w; + uint64_t curr, high; nhe = (struct nhg_hash_entry *)data; @@ -3361,10 +3453,19 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data, listnode_add(mq->subq[qindex], w); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed); + curr = listcount(mq->subq[qindex]); + high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("NHG id=%u queued into sub-queue %s", nhe->id, - subqueue2str(qindex)); + zlog_debug("NHG id=%u queued into sub-queue %s mq size %u", nhe->id, + subqueue2str(qindex), zrouter.mq->size); return 0; } @@ -3381,8 +3482,19 @@ static int rib_meta_queue_nhg_del(struct meta_queue *mq, void *data) static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data) { + uint64_t curr, high; + listnode_add(mq->subq[META_QUEUE_EVPN], data); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EVPN], 1, memory_order_relaxed); + curr = listcount(mq->subq[META_QUEUE_EVPN]); + high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EVPN], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[META_QUEUE_EVPN], curr, memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); return 0; } @@ -3410,6 +3522,11 @@ static int mq_add_handler(void *data, return mq_add_func(zrouter.mq, data); } +uint32_t zebra_rib_meta_queue_size(void) +{ + return zrouter.mq->size; +} + void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type, struct prefix *prefix, uint8_t route_type, uint8_t route_instance) @@ -4222,11 +4339,22 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data) { + uint64_t curr, high; + listnode_add(mq->subq[META_QUEUE_GR_RUN], data); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_GR_RUN], 1, memory_order_relaxed); + curr = listcount(mq->subq[META_QUEUE_GR_RUN]); + high = atomic_load_explicit(&mq->max_subq[META_QUEUE_GR_RUN], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[META_QUEUE_GR_RUN], curr, memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("Graceful Run adding"); + zlog_debug("Graceful Run adding mq size %u", zrouter.mq->size); return 0; } @@ -4234,17 +4362,27 @@ static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data) static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data) { struct zebra_early_route *ere = data; + uint64_t curr, high; listnode_add(mq->subq[META_QUEUE_EARLY_ROUTE], data); mq->size++; + atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_ROUTE], 1, memory_order_relaxed); + curr = listcount(mq->subq[META_QUEUE_EARLY_ROUTE]); + high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], curr, + memory_order_relaxed); + high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed); + if (mq->size > high) + atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { struct vrf *vrf = vrf_lookup_by_id(ere->re->vrf_id); - zlog_debug("Route %pFX(%s) (%s) queued for processing into sub-queue %s", - &ere->p, VRF_LOGNAME(vrf), - ere->deletion ? "delete" : "add", - subqueue2str(META_QUEUE_EARLY_ROUTE)); + zlog_debug("Route %pFX(%s) (%s) queued for processing into sub-queue %s mq size %u", + &ere->p, VRF_LOGNAME(vrf), ere->deletion ? "delete" : "add", + subqueue2str(META_QUEUE_EARLY_ROUTE), zrouter.mq->size); } return 0; diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 4b4f523253..06a9c0debe 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -418,11 +418,11 @@ static void get_fwtable_route_node(struct variable *v, oid objid[], objid[v->namelen + 5] = policy; { - struct nexthop *nexthop; + struct nexthop *nh; - nexthop = (*re)->nhe->nhg.nexthop; - if (nexthop) { - pnt = (uint8_t *)&nexthop->gate.ipv4; + nh = (*re)->nhe->nhg.nexthop; + if (nh) { + pnt = (uint8_t *)&nh->gate.ipv4; for (i = 0; i < 4; i++) objid[i + v->namelen + 6] = *pnt++; } diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index ebfd5c0908..ee0d6c41c6 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -36,6 +36,8 @@ DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB, DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID, "SRv6 SID"); DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_CTX, "SRv6 SID context"); +static struct zebra_srv6 g_srv6; + /* Prototypes */ static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, uint32_t sid_func); @@ -705,8 +707,6 @@ void zebra_notify_srv6_locator_delete(struct srv6_locator *locator) } } -struct zebra_srv6 srv6; - struct zebra_srv6 *zebra_srv6_get_default(void) { static bool first_execution = true; @@ -715,11 +715,11 @@ struct zebra_srv6 *zebra_srv6_get_default(void) if (first_execution) { first_execution = false; - srv6.locators = list_new(); + g_srv6.locators = list_new(); /* Initialize list of SID formats */ - srv6.sid_formats = list_new(); - srv6.sid_formats->del = delete_srv6_sid_format; + g_srv6.sid_formats = list_new(); + g_srv6.sid_formats->del = delete_srv6_sid_format; /* Create SID format `usid-f3216` */ format_usidf3216 = create_srv6_sid_format_usid_f3216(); @@ -730,14 +730,14 @@ struct zebra_srv6 *zebra_srv6_get_default(void) srv6_sid_format_register(format_uncompressed); /* Init list to store SRv6 SIDs */ - srv6.sids = list_new(); - srv6.sids->del = delete_zebra_srv6_sid_ctx; + g_srv6.sids = list_new(); + g_srv6.sids->del = delete_zebra_srv6_sid_ctx; /* Init list to store SRv6 SID blocks */ - srv6.sid_blocks = list_new(); - srv6.sid_blocks->del = delete_zebra_srv6_sid_block; + g_srv6.sid_blocks = list_new(); + g_srv6.sid_blocks->del = delete_zebra_srv6_sid_block; } - return &srv6; + return &g_srv6; } /** @@ -2455,51 +2455,51 @@ void zebra_srv6_terminate(void) struct zebra_srv6_sid_block *block; struct zebra_srv6_sid_ctx *sid_ctx; - if (srv6.locators) { - while (listcount(srv6.locators)) { - locator = listnode_head(srv6.locators); + if (g_srv6.locators) { + while (listcount(g_srv6.locators)) { + locator = listnode_head(g_srv6.locators); - listnode_delete(srv6.locators, locator); + listnode_delete(g_srv6.locators, locator); srv6_locator_free(locator); } - list_delete(&srv6.locators); + list_delete(&g_srv6.locators); } /* Free SRv6 SIDs */ - if (srv6.sids) { - while (listcount(srv6.sids)) { - sid_ctx = listnode_head(srv6.sids); + if (g_srv6.sids) { + while (listcount(g_srv6.sids)) { + sid_ctx = listnode_head(g_srv6.sids); - listnode_delete(srv6.sids, sid_ctx); + listnode_delete(g_srv6.sids, sid_ctx); zebra_srv6_sid_ctx_free(sid_ctx); } - list_delete(&srv6.sids); + list_delete(&g_srv6.sids); } /* Free SRv6 SID blocks */ - if (srv6.sid_blocks) { - while (listcount(srv6.sid_blocks)) { - block = listnode_head(srv6.sid_blocks); + if (g_srv6.sid_blocks) { + while (listcount(g_srv6.sid_blocks)) { + block = listnode_head(g_srv6.sid_blocks); - listnode_delete(srv6.sid_blocks, block); + listnode_delete(g_srv6.sid_blocks, block); zebra_srv6_sid_block_free(block); } - list_delete(&srv6.sid_blocks); + list_delete(&g_srv6.sid_blocks); } /* Free SRv6 SID formats */ - if (srv6.sid_formats) { - while (listcount(srv6.sid_formats)) { - format = listnode_head(srv6.sid_formats); + if (g_srv6.sid_formats) { + while (listcount(g_srv6.sid_formats)) { + format = listnode_head(g_srv6.sid_formats); srv6_sid_format_unregister(format); srv6_sid_format_free(format); } - list_delete(&srv6.sid_formats); + list_delete(&g_srv6.sid_formats); } } diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 22ba9386d9..3d5a76ff38 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -210,7 +210,7 @@ DEFUN (show_srv6_locator_detail, } for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { - struct listnode *node; + struct listnode *nnode; struct srv6_locator_chunk *chunk; if (strcmp(locator->name, locator_name) != 0) @@ -247,8 +247,7 @@ DEFUN (show_srv6_locator_detail, } vty_out(vty, "Chunks:\n"); - for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, - chunk)) { + for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, nnode, chunk)) { prefix2str(&chunk->prefix, str, sizeof(str)); vty_out(vty, "- prefix: %s, owner: %s\n", str, zebra_route_string(chunk->proto)); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index a1731712d3..9e4db11989 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1490,8 +1490,6 @@ DEFPY(show_nexthop_group, struct vrf *vrf; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - struct zebra_vrf *zvrf; - zvrf = vrf->info; if (!zvrf) continue; @@ -4049,6 +4047,20 @@ DEFUN (zebra_show_routing_tables_summary, return CMD_SUCCESS; } +/* Display Zebra MetaQ counters */ +DEFUN (show_zebra_metaq_counters, + show_zebra_metaq_counters_cmd, + "show zebra metaq [json]", + SHOW_STR + ZEBRA_STR + "Zebra MetaQ counters\n" + JSON_STR) +{ + bool uj = use_json(argc, argv); + + return zebra_show_metaq_counter(vty, uj); +} + /* IPForwarding configuration write function. */ static int config_write_forwarding(struct vty *vty) { @@ -4338,6 +4350,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_dataplane_providers_cmd); install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd); install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd); + install_element(VIEW_NODE, &show_zebra_metaq_counters_cmd); #ifdef HAVE_NETLINK install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd); diff --git a/zebra/zserv.c b/zebra/zserv.c index d477cd051f..aab1bd0062 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -530,6 +530,12 @@ static void zserv_process_messages(struct event *thread) struct stream_fifo *cache = stream_fifo_new(); uint32_t p2p = zrouter.packets_to_process; bool need_resched = false; + uint32_t meta_queue_size = zebra_rib_meta_queue_size(); + + if (meta_queue_size < p2p) + p2p = p2p - meta_queue_size; + else + p2p = 0; frr_with_mutex (&client->ibuf_mtx) { uint32_t i; |
