diff options
468 files changed, 5057 insertions, 3676 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 103ac3a478..837ec75b8d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -12,3 +12,10 @@ ac4d0be5874fafd14212d6007fff7495edc9b152 d62a17aedeb0eebdba98238874bb13d62c48dbf9 c14777c6bfd0a446c85243d3a9835054a259c276 996c93142d3abfab0f6d6c800474e22a8cfbdbc5 +# require semicolon after macro XYZ +67b0f40c98aeb9bbc95370fe2be29e56a00a8748 +80413c2073a20774b264ab04f7a4ea4515699790 +960b9a53837d1aefa16bd531c7087f800dbe147b +96244aca23adec551c29b78f26605f8af8eea53e +8451921b70044a2c1075e7ba391f095fabee2550 +bf8d3d6aca3f20255a621ed1c148fd05b3a8ae5c diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 85d79bdc3b..41391c51ac 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -42,7 +42,7 @@ THE SOFTWARE. #include "xroute.h" #include "babel_errors.h" -DEFINE_MTYPE_STATIC(BABELD, BABEL_IF, "Babel Interface") +DEFINE_MTYPE_STATIC(BABELD, BABEL_IF, "Babel Interface"); #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0) diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 14e583a35c..71ac356585 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -153,7 +153,7 @@ FRR_DAEMON_INFO(babeld, BABELD, .yang_modules = babeld_yang_modules, .n_yang_modules = array_size(babeld_yang_modules), - ) +); int main(int argc, char **argv) diff --git a/babeld/babeld.c b/babeld/babeld.c index a907daf6c2..72080bd7eb 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -46,8 +46,8 @@ THE SOFTWARE. #include "babel_zebra.h" #include "babel_errors.h" -DEFINE_MGROUP(BABELD, "babeld") -DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure") +DEFINE_MGROUP(BABELD, "babeld"); +DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure"); static int babel_init_routing_process(struct thread *thread); static void babel_get_myid(void); diff --git a/babeld/babeld.h b/babeld/babeld.h index 752cc8620a..4487aae99f 100644 --- a/babeld/babeld.h +++ b/babeld/babeld.h @@ -41,20 +41,6 @@ THE SOFTWARE. #define MAX(x,y) ((x)<=(y)?(y):(x)) #define MIN(x,y) ((x)<=(y)?(x):(y)) -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -/* nothing */ -#elif defined(__GNUC__) -#define inline __inline -#if (__GNUC__ >= 3) -#define restrict __restrict -#else -#define restrict /**/ -#endif -#else -#define inline /**/ -#define restrict /**/ -#endif - #if defined(__GNUC__) && (__GNUC__ >= 3) #define ATTRIBUTE(x) __attribute__ (x) #define LIKELY(_x) __builtin_expect(!!(_x), 1) diff --git a/babeld/util.h b/babeld/util.h index 9310040571..037ebe3666 100644 --- a/babeld/util.h +++ b/babeld/util.h @@ -29,7 +29,7 @@ THE SOFTWARE. #include "log.h" #include "memory.h" -DECLARE_MGROUP(BABELD) +DECLARE_MGROUP(BABELD); #if defined(i386) || defined(__mc68020__) || defined(__x86_64__) #define DO_NTOHS(_d, _s) do{ _d = ntohs(*(const unsigned short*)(_s)); }while(0) @@ -129,13 +129,7 @@ extern const unsigned char v4prefix[16]; vararg macros are not portable. */ #if defined NO_DEBUG -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L #define debugf(...) do {} while(0) -#elif defined __GNUC__ -#define debugf(_args...) do {} while(0) -#else -static inline void debugf(int level, const char *format, ...) { return; } -#endif #else /* NO_DEBUG */ @@ -148,19 +142,10 @@ static inline void debugf(int level, const char *format, ...) { return; } #define BABEL_DEBUG_ROUTE (1 << 5) #define BABEL_DEBUG_ALL (0xFFFF) -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L #define debugf(level, ...) \ do { \ if(UNLIKELY(debug & level)) zlog_debug(__VA_ARGS__); \ } while(0) -#elif defined __GNUC__ -#define debugf(level, _args...) \ -do { \ -if(UNLIKELY(debug & level)) zlog_debug(_args); \ -} while(0) -#else -static inline void debugf(int level, const char *format, ...) { return; } -#endif #endif /* NO_DEBUG */ diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 9e5bc20a49..234fc6d397 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -32,10 +32,10 @@ #include "bfd.h" -DEFINE_MTYPE_STATIC(BFDD, BFDD_CONFIG, "long-lived configuration memory") -DEFINE_MTYPE_STATIC(BFDD, BFDD_PROFILE, "long-lived profile memory") -DEFINE_MTYPE_STATIC(BFDD, BFDD_SESSION_OBSERVER, "Session observer") -DEFINE_MTYPE_STATIC(BFDD, BFDD_VRF, "BFD VRF") +DEFINE_MTYPE_STATIC(BFDD, BFDD_CONFIG, "long-lived configuration memory"); +DEFINE_MTYPE_STATIC(BFDD, BFDD_PROFILE, "long-lived profile memory"); +DEFINE_MTYPE_STATIC(BFDD, BFDD_SESSION_OBSERVER, "Session observer"); +DEFINE_MTYPE_STATIC(BFDD, BFDD_VRF, "BFD VRF"); /* * Prototypes diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 503b5ca7d6..a86c1bb9f3 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -41,9 +41,9 @@ #define BFDD_JSON_CONV_OPTIONS (0) #endif -DECLARE_MGROUP(BFDD) -DECLARE_MTYPE(BFDD_CONTROL) -DECLARE_MTYPE(BFDD_NOTIFICATION) +DECLARE_MGROUP(BFDD); +DECLARE_MTYPE(BFDD_CONTROL); +DECLARE_MTYPE(BFDD_NOTIFICATION); struct bfd_timers { uint32_t desired_min_tx; diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index 0cac990108..7a2c3cc3aa 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -41,9 +41,9 @@ /* * FRR related code. */ -DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon") -DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory") -DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data") +DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon"); +DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory"); +DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data"); /* Master of threads. */ struct thread_master *master; @@ -134,7 +134,8 @@ FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617, .signals = bfd_signals, .n_signals = array_size(bfd_signals), .privs = &bglobal.bfdd_privs, .yang_modules = bfdd_yang_modules, - .n_yang_modules = array_size(bfdd_yang_modules)) + .n_yang_modules = array_size(bfdd_yang_modules), +); #define OPTION_CTLSOCK 1001 #define OPTION_DPLANEADDR 2000 diff --git a/bfdd/config.c b/bfdd/config.c index a97caf137e..22ec912359 100644 --- a/bfdd/config.c +++ b/bfdd/config.c @@ -30,7 +30,7 @@ #include "bfd.h" -DEFINE_MTYPE_STATIC(BFDD, BFDD_LABEL, "long-lived label memory") +DEFINE_MTYPE_STATIC(BFDD, BFDD_LABEL, "long-lived label memory"); /* * Definitions diff --git a/bfdd/dplane.c b/bfdd/dplane.c index 9cb0b0ea85..6fb301d46a 100644 --- a/bfdd/dplane.c +++ b/bfdd/dplane.c @@ -46,7 +46,8 @@ #include "lib/openbsd-queue.h" -DEFINE_MTYPE_STATIC(BFDD, BFDD_DPLANE_CTX, "Data plane client allocated memory") +DEFINE_MTYPE_STATIC(BFDD, BFDD_DPLANE_CTX, + "Data plane client allocated memory"); /** Data plane client socket buffer size. */ #define BFD_DPLANE_CLIENT_BUF_SIZE 8192 diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h index 745a0dffce..ef4f626111 100644 --- a/bgpd/bgp_advertise.h +++ b/bgpd/bgp_advertise.h @@ -23,7 +23,7 @@ #include "lib/typesafe.h" -PREDECL_DLIST(bgp_adv_fifo) +PREDECL_DLIST(bgp_adv_fifo); struct update_subgroup; @@ -60,7 +60,7 @@ struct bgp_advertise { struct bgp_path_info *pathi; }; -DECLARE_DLIST(bgp_adv_fifo, struct bgp_advertise, fifo) +DECLARE_DLIST(bgp_adv_fifo, struct bgp_advertise, fifo); /* BGP adjacency out. */ struct bgp_adj_out { diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 11e9344d1c..f1bdcc8bb4 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -29,6 +29,7 @@ #include "thread.h" #include "buffer.h" #include "stream.h" +#include "vrf.h" #include "zclient.h" #include "bfd.h" #include "lib/json.h" @@ -40,667 +41,391 @@ #include "bgpd/bgp_debug.h" #include "bgpd/bgp_vty.h" +DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data"); + extern struct zclient *zclient; -/* - * bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group - * template - * to peer. - */ -void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer) +static void bfd_session_status_update(struct bfd_session_params *bsp, + const struct bfd_session_status *bss, + void *arg) { - struct bfd_info *bfd_info; - struct bfd_info *conf_bfd_info; - - if (!conf->bfd_info) - return; - - conf_bfd_info = (struct bfd_info *)conf->bfd_info; - if (!peer->bfd_info) - peer->bfd_info = bfd_info_create(); - - bfd_info = (struct bfd_info *)peer->bfd_info; + struct peer *peer = arg; + + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug("%s: neighbor %s vrf %s(%u) bfd state %s -> %s", + __func__, peer->conf_if ? peer->conf_if : peer->host, + bfd_sess_vrf(bsp), bfd_sess_vrf_id(bsp), + bfd_get_status_str(bss->previous_state), + bfd_get_status_str(bss->state)); + + if (bss->state == BSS_DOWN && bss->previous_state == BSS_UP) { + if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE) + && bfd_sess_cbit(bsp) && !bss->remote_cbit) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_info( + "%s BFD DOWN message ignored in the process of graceful restart when C bit is cleared", + peer->host); + return; + } + peer->last_reset = PEER_DOWN_BFD_DOWN; + BGP_EVENT_ADD(peer, BGP_Stop); + } - /* Copy BFD parameter values */ - bfd_info->required_min_rx = conf_bfd_info->required_min_rx; - bfd_info->desired_min_tx = conf_bfd_info->desired_min_tx; - bfd_info->detect_mult = conf_bfd_info->detect_mult; - bfd_info->type = conf_bfd_info->type; + if (bss->state == BSS_UP && bss->previous_state != BSS_UP + && peer->status != Established) { + if (!BGP_PEER_START_SUPPRESSED(peer)) { + bgp_fsm_nht_update(peer, true); + BGP_EVENT_ADD(peer, BGP_Start); + } + } } -/* - * bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single - * hop. - */ -bool bgp_bfd_is_peer_multihop(struct peer *peer) +void bgp_peer_config_apply(struct peer *p, struct peer_group *pg) { - struct bfd_info *bfd_info; + struct listnode *n; + struct peer *pn; + struct peer *gconfig; + + /* When called on a group, apply to all peers. */ + if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) { + for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn)) + bgp_peer_config_apply(pn, pg); + return; + } - bfd_info = (struct bfd_info *)peer->bfd_info; + /* No group, just use current configuration. */ + if (pg == NULL || pg->conf->bfd_config == NULL) { + bfd_sess_set_timers(p->bfd_config->session, + p->bfd_config->detection_multiplier, + p->bfd_config->min_rx, + p->bfd_config->min_tx); + bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit); + bfd_sess_set_profile(p->bfd_config->session, + p->bfd_config->profile); + bfd_sess_install(p->bfd_config->session); + return; + } - if (!bfd_info) - return false; + /* + * Check if the group configuration was overwritten or apply group + * configuration. + */ + gconfig = pg->conf; + + /* + * If using default control plane independent configuration, + * then prefer group's (e.g. it means it wasn't manually configured). + */ + if (!p->bfd_config->cbit) + bfd_sess_set_cbit(p->bfd_config->session, + gconfig->bfd_config->cbit); + else + bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit); - if ((bfd_info->type == BFD_TYPE_MULTIHOP) - || ((peer->sort == BGP_PEER_IBGP) && !peer->shared_network) - || is_ebgp_multihop_configured(peer)) - return true; + /* If no profile was specified in peer, then use the group profile. */ + if (p->bfd_config->profile[0] == 0) + bfd_sess_set_profile(p->bfd_config->session, + gconfig->bfd_config->profile); else - return false; + bfd_sess_set_profile(p->bfd_config->session, + p->bfd_config->profile); + + /* If no specific timers were configured, then use the group timers. */ + if (p->bfd_config->detection_multiplier == BFD_DEF_DETECT_MULT + || p->bfd_config->min_rx == BFD_DEF_MIN_RX + || p->bfd_config->min_tx == BFD_DEF_MIN_TX) + bfd_sess_set_timers(p->bfd_config->session, + gconfig->bfd_config->detection_multiplier, + gconfig->bfd_config->min_rx, + gconfig->bfd_config->min_tx); + else + bfd_sess_set_timers(p->bfd_config->session, + p->bfd_config->detection_multiplier, + p->bfd_config->min_rx, + p->bfd_config->min_tx); + + bfd_sess_install(p->bfd_config->session); } -/* - * bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister - * command to Zebra to be forwarded to BFD - */ -static void bgp_bfd_peer_sendmsg(struct peer *peer, int command) +void bgp_peer_bfd_update_source(struct peer *p) { - struct bfd_session_arg arg = {}; - struct bfd_info *bfd_info; - int multihop; - vrf_id_t vrf_id; - size_t addrlen; - - /* - * XXX: some pointers are dangling during shutdown, so instead of - * trying to send a message during signal handlers lets just wait BGP - * to terminate zebra's connection and BFD will automatically find - * out that we are no longer expecting notifications. - * - * The pointer that is causing a crash here is `peer->nexthop.ifp`. - * That happens because at this point of the shutdown all interfaces are - * already `free()`d. - */ - if (bm->terminating) + struct bfd_session_params *session = p->bfd_config->session; + bool changed = false; + int family; + union { + struct in_addr v4; + struct in6_addr v6; + } src, dst; + + /* Nothing to do for groups. */ + if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) return; - bfd_info = (struct bfd_info *)peer->bfd_info; + /* Update peer's source/destination addresses. */ + bfd_sess_addresses(session, &family, &src.v6, &dst.v6); + if (family == AF_INET) { + if ((p->su_local + && p->su_local->sin.sin_addr.s_addr != src.v4.s_addr) + || p->su.sin.sin_addr.s_addr != dst.v4.s_addr) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug( + "%s: address [%pI4->%pI4] to [%pI4->%pI4]", + __func__, &src.v4, &dst.v4, + p->su_local ? &p->su_local->sin.sin_addr + : &src.v4, + &p->su.sin.sin_addr); + + bfd_sess_set_ipv4_addrs( + session, + p->su_local ? &p->su_local->sin.sin_addr : NULL, + &p->su.sin.sin_addr); + changed = true; + } + } else { + if ((p->su_local + && memcmp(&p->su_local->sin6, &src.v6, sizeof(src.v6))) + || memcmp(&p->su.sin6, &dst.v6, sizeof(dst.v6))) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug( + "%s: address [%pI6->%pI6] to [%pI6->%pI6]", + __func__, &src.v6, &dst.v6, + p->su_local + ? &p->su_local->sin6.sin6_addr + : &src.v6, + &p->su.sin6.sin6_addr); + + bfd_sess_set_ipv6_addrs( + session, + p->su_local ? &p->su_local->sin6.sin6_addr + : NULL, + &p->su.sin6.sin6_addr); + changed = true; + } + } - vrf_id = peer->bgp->vrf_id; + /* Update interface. */ + if (p->nexthop.ifp && bfd_sess_interface(session) == NULL) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug("%s: interface none to %s", __func__, + p->nexthop.ifp->name); - if (command == ZEBRA_BFD_DEST_DEREGISTER) { - multihop = - CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP); - UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP); - } else { - multihop = bgp_bfd_is_peer_multihop(peer); - if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop) - SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP); + bfd_sess_set_interface(session, p->nexthop.ifp->name); + changed = true; } - /* while graceful restart with fwd path preserved - * and bfd controlplane check not configured is not kept - * keep bfd independent controlplane bit set to 1 + + /* + * Update TTL. + * + * Two cases: + * - We detected that the peer is a hop away from us (remove multi hop). + * (this happens when `p->shared_network` is set to `true`) + * - eBGP multi hop / TTL security changed. */ - if (!CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GRACEFUL_RESTART) - && !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD) - && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) - SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON); - - /* Set all message arguments. */ - arg.family = peer->su.sa.sa_family; - addrlen = arg.family == AF_INET ? sizeof(struct in_addr) - : sizeof(struct in6_addr); - - if (arg.family == AF_INET) - memcpy(&arg.dst, &peer->su.sin.sin_addr, addrlen); - else - memcpy(&arg.dst, &peer->su.sin6.sin6_addr, addrlen); + if (!PEER_IS_MULTIHOP(p) && bfd_sess_hop_count(session) > 1) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug("%s: TTL %d to 1", __func__, + bfd_sess_hop_count(session)); - if (peer->su_local) { - if (arg.family == AF_INET) - memcpy(&arg.src, &peer->su_local->sin.sin_addr, - addrlen); - else - memcpy(&arg.src, &peer->su_local->sin6.sin6_addr, - addrlen); + bfd_sess_set_hop_count(session, 1); + changed = true; } + if (PEER_IS_MULTIHOP(p) && p->ttl != bfd_sess_hop_count(session)) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug("%s: TTL %d to %d", __func__, + bfd_sess_hop_count(session), p->ttl); - if (peer->nexthop.ifp) { - arg.ifnamelen = strlen(peer->nexthop.ifp->name); - strlcpy(arg.ifname, peer->nexthop.ifp->name, - sizeof(arg.ifname)); + bfd_sess_set_hop_count(session, p->ttl); + changed = true; } - if (bfd_info->profile[0]) { - arg.profilelen = strlen(bfd_info->profile); - strlcpy(arg.profile, bfd_info->profile, sizeof(arg.profile)); + /* Update VRF. */ + if (bfd_sess_vrf_id(session) != p->bgp->vrf_id) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug( + "%s: VRF %s(%d) to %s(%d)", __func__, + bfd_sess_vrf(session), bfd_sess_vrf_id(session), + vrf_id_to_name(p->bgp->vrf_id), p->bgp->vrf_id); + + bfd_sess_set_vrf(session, p->bgp->vrf_id); + changed = true; } - arg.set_flag = 1; - arg.mhop = multihop; - arg.ttl = peer->ttl; - arg.vrf_id = vrf_id; - arg.command = command; - arg.bfd_info = bfd_info; - arg.min_tx = bfd_info->desired_min_tx; - arg.min_rx = bfd_info->required_min_rx; - arg.detection_multiplier = bfd_info->detect_mult; - arg.cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON); - - /* Send message. */ - zclient_bfd_command(zclient, &arg); + if (changed) + bfd_sess_install(session); } -/* - * bgp_bfd_register_peer - register a peer with BFD through zebra - * for monitoring the peer rechahability. +/** + * Reset BFD configuration data structure to its defaults settings. */ -void bgp_bfd_register_peer(struct peer *peer) +static void bgp_peer_bfd_reset(struct peer *p) { - struct bfd_info *bfd_info; - - if (!peer->bfd_info) - return; - bfd_info = (struct bfd_info *)peer->bfd_info; - - /* Check if BFD is enabled and peer has already been registered with BFD - */ - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) - return; - - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); + /* Set defaults. */ + p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT; + p->bfd_config->min_rx = BFD_DEF_MIN_RX; + p->bfd_config->min_tx = BFD_DEF_MIN_TX; + p->bfd_config->cbit = false; + p->bfd_config->profile[0] = 0; } -/** - * bgp_bfd_deregister_peer - deregister a peer with BFD through zebra - * for stopping the monitoring of the peer - * rechahability. - */ -void bgp_bfd_deregister_peer(struct peer *peer) +void bgp_peer_configure_bfd(struct peer *p, bool manual) { - struct bfd_info *bfd_info; + /* Groups should not call this. */ + assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)); - if (!peer->bfd_info) - return; - bfd_info = (struct bfd_info *)peer->bfd_info; + /* Already configured, skip it. */ + if (p->bfd_config) { + /* If manually active update flag. */ + if (!p->bfd_config->manual) + p->bfd_config->manual = manual; - /* Check if BFD is eanbled and peer has not been registered */ - if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) return; + } - bfd_info->status = BFD_STATUS_DOWN; - bfd_info->last_update = bgp_clock(); - - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); -} - -/* - * bgp_bfd_update_peer - update peer with BFD with new BFD paramters - * through zebra. - */ -static void bgp_bfd_update_peer(struct peer *peer) -{ - struct bfd_info *bfd_info; + /* Allocate memory for configuration overrides. */ + p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config)); + p->bfd_config->manual = manual; - if (!peer->bfd_info) - return; - bfd_info = (struct bfd_info *)peer->bfd_info; + /* Create new session and assign callback. */ + p->bfd_config->session = bfd_sess_new(bfd_session_status_update, p); + bgp_peer_bfd_reset(p); - /* Check if the peer has been registered with BFD*/ - if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) - return; + /* Configure session with basic BGP peer data. */ + if (p->su.sa.sa_family == AF_INET) + bfd_sess_set_ipv4_addrs(p->bfd_config->session, + p->su_local ? &p->su_local->sin.sin_addr + : NULL, + &p->su.sin.sin_addr); + else + bfd_sess_set_ipv6_addrs( + p->bfd_config->session, + p->su_local ? &p->su_local->sin6.sin6_addr : NULL, + &p->su.sin6.sin6_addr); - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE); -} + bfd_sess_set_vrf(p->bfd_config->session, p->bgp->vrf_id); + bfd_sess_set_hop_count(p->bfd_config->session, + PEER_IS_MULTIHOP(p) ? p->ttl : 1); -/** - * bgp_bfd_reset_peer - reinitialise bfd - * ensures that bfd state machine is restarted - * to be synced with remote bfd - */ -void bgp_bfd_reset_peer(struct peer *peer) -{ - if (!peer->bfd_info) - return; + if (p->nexthop.ifp) + bfd_sess_set_interface(p->bfd_config->session, + p->nexthop.ifp->name); - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); + bfd_sess_enable(p->bfd_config->session, true); } -/* - * bgp_bfd_update_type - update session type with BFD through zebra. - */ -static void bgp_bfd_update_type(struct peer *peer) +static void bgp_peer_remove_bfd(struct peer *p) { - struct bfd_info *bfd_info; - int multihop; - - if (!peer->bfd_info) - return; - bfd_info = (struct bfd_info *)peer->bfd_info; + /* Groups should not call this. */ + assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)); - /* Check if the peer has been registered with BFD*/ - if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) + /* + * Peer configuration was removed, however we must check if there + * is still a group configuration to keep this running. + */ + if (p->group && p->group->conf->bfd_config) { + p->bfd_config->manual = false; + bgp_peer_bfd_reset(p); + bgp_peer_config_apply(p, p->group); return; - - if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED) { - multihop = bgp_bfd_is_peer_multihop(peer); - if ((multihop - && !CHECK_FLAG(bfd_info->flags, - BFD_FLAG_BFD_TYPE_MULTIHOP)) - || (!multihop && CHECK_FLAG(bfd_info->flags, - BFD_FLAG_BFD_TYPE_MULTIHOP))) { - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); - } - } else { - if ((bfd_info->type == BFD_TYPE_MULTIHOP - && !CHECK_FLAG(bfd_info->flags, - BFD_FLAG_BFD_TYPE_MULTIHOP)) - || (bfd_info->type == BFD_TYPE_SINGLEHOP - && CHECK_FLAG(bfd_info->flags, - BFD_FLAG_BFD_TYPE_MULTIHOP))) { - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); - bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); - } } -} - -/* - * bgp_bfd_dest_replay - Replay all the peers that have BFD enabled - * to zebra - */ -static int bgp_bfd_dest_replay(ZAPI_CALLBACK_ARGS) -{ - struct listnode *mnode, *node, *nnode; - struct bgp *bgp; - struct peer *peer; - - if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Zebra: BFD Dest replay request"); - - /* Send the client registration */ - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf_id); - - /* Replay the peer, if BFD is enabled in BGP */ - for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp)) - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - bgp_bfd_update_peer(peer); - } - - return 0; + bfd_sess_free(&p->bfd_config->session); + XFREE(MTYPE_BFD_CONFIG, p->bfd_config); } -/* - * bgp_bfd_peer_status_update - Update the BFD status if it has changed. Bring - * down the peer if the BFD session went down from - * * up. - */ -static void bgp_bfd_peer_status_update(struct peer *peer, int status, - int remote_cbit) +static void bgp_group_configure_bfd(struct peer *p) { - struct bfd_info *bfd_info; - int old_status; + struct listnode *n; + struct peer *pn; - bfd_info = (struct bfd_info *)peer->bfd_info; + /* Peers should not call this. */ + assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)); - if (bfd_info->status == status) + /* Already allocated: do nothing. */ + if (p->bfd_config) return; - old_status = bfd_info->status; - BFD_SET_CLIENT_STATUS(bfd_info->status, status); + p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config)); - bfd_info->last_update = bgp_clock(); + /* Set defaults. */ + p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT; + p->bfd_config->min_rx = BFD_DEF_MIN_RX; + p->bfd_config->min_tx = BFD_DEF_MIN_TX; - if (status != old_status) { - if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS)) - zlog_debug("[%s]: BFD %s", peer->host, - bfd_get_status_str(status)); - } - if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) { - if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE) && - CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE) && - !remote_cbit) { - zlog_info("%s BFD DOWN message ignored in the process of graceful restart when C bit is cleared", - peer->host); - return; - } - peer->last_reset = PEER_DOWN_BFD_DOWN; - BGP_EVENT_ADD(peer, BGP_Stop); - } - if ((status == BFD_STATUS_UP) && (old_status == BFD_STATUS_DOWN) - && peer->status != Established) { - if (!BGP_PEER_START_SUPPRESSED(peer)) { - bgp_fsm_nht_update(peer, true); - BGP_EVENT_ADD(peer, BGP_Start); - } - } + for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn)) + bgp_peer_configure_bfd(pn, false); } -/* - * bgp_bfd_dest_update - Find the peer for which the BFD status - * has changed and bring down the peer - * connectivity if the BFD session went down. - */ -static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS) +static void bgp_group_remove_bfd(struct peer *p) { - struct interface *ifp; - struct prefix dp; - struct prefix sp; - int status; - int remote_cbit; + struct listnode *n; + struct peer *pn; - ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, - &remote_cbit, vrf_id); + /* Peers should not call this. */ + assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)); - if (BGP_DEBUG(zebra, ZEBRA)) { - struct vrf *vrf; + /* Already freed: do nothing. */ + if (p->bfd_config == NULL) + return; - vrf = vrf_lookup_by_id(vrf_id); + /* Free configuration and point to `NULL`. */ + XFREE(MTYPE_BFD_CONFIG, p->bfd_config); - if (ifp) - zlog_debug( - "Zebra: vrf %s(%u) interface %s bfd destination %pFX %s %s", - VRF_LOGNAME(vrf), vrf_id, ifp->name, &dp, - bfd_get_status_str(status), - remote_cbit ? "(cbit on)" : ""); + /* Now that it is `NULL` recalculate configuration for all peers. */ + for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn)) { + if (pn->bfd_config->manual) + bgp_peer_config_apply(pn, NULL); else - zlog_debug( - "Zebra: vrf %s(%u) source %pFX bfd destination %pFX %s %s", - VRF_LOGNAME(vrf), vrf_id, &sp, &dp, - bfd_get_status_str(status), - remote_cbit ? "(cbit on)" : ""); - } - - /* Bring the peer down if BFD is enabled in BGP */ - { - struct listnode *mnode, *node, *nnode; - struct bgp *bgp; - struct peer *peer; - - for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp)) - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (!peer->bfd_info) - continue; - - if ((dp.family == AF_INET) - && (peer->su.sa.sa_family == AF_INET)) { - if (dp.u.prefix4.s_addr - != peer->su.sin.sin_addr.s_addr) - continue; - } else if ((dp.family == AF_INET6) - && (peer->su.sa.sa_family - == AF_INET6)) { - if (memcmp(&dp.u.prefix6, - &peer->su.sin6.sin6_addr, - sizeof(struct in6_addr))) - continue; - } else - continue; - - if (ifp && (ifp == peer->nexthop.ifp)) { - bgp_bfd_peer_status_update(peer, - status, - remote_cbit); - } else { - if (!peer->su_local) - continue; - - if ((sp.family == AF_INET) - && (peer->su_local->sa.sa_family - == AF_INET)) { - if (sp.u.prefix4.s_addr - != peer->su_local->sin - .sin_addr.s_addr) - continue; - } else if ((sp.family == AF_INET6) - && (peer->su_local->sa - .sa_family - == AF_INET6)) { - if (memcmp(&sp.u.prefix6, - &peer->su_local->sin6 - .sin6_addr, - sizeof(struct - in6_addr))) - continue; - } else - continue; - - if ((vrf_id != VRF_DEFAULT) - && (peer->bgp->vrf_id != vrf_id)) - continue; - - bgp_bfd_peer_status_update(peer, - status, - remote_cbit); - } - } - } - - return 0; -} - -/* - * bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer. - */ -static int bgp_bfd_peer_param_set(struct peer *peer, uint32_t min_rx, - uint32_t min_tx, uint8_t detect_mult, - int defaults) -{ - struct bfd_info *bi; - struct peer_group *group; - struct listnode *node, *nnode; - int command = 0; - - bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx, - detect_mult, NULL, defaults, &command); - - /* This command overrides profile if it was previously applied. */ - bi = peer->bfd_info; - bi->profile[0] = 0; - - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - group = peer->group; - for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - command = 0; - bfd_set_param((struct bfd_info **)&(peer->bfd_info), - min_rx, min_tx, detect_mult, NULL, - defaults, &command); - - /* - * This command overrides profile if it was previously - * applied. - */ - bi = peer->bfd_info; - bi->profile[0] = 0; - - if ((peer->status == Established) - && (command == ZEBRA_BFD_DEST_REGISTER)) - bgp_bfd_register_peer(peer); - else if (command == ZEBRA_BFD_DEST_UPDATE) - bgp_bfd_update_peer(peer); - } - } else { - if ((peer->status == Established) - && (command == ZEBRA_BFD_DEST_REGISTER)) - bgp_bfd_register_peer(peer); - else if (command == ZEBRA_BFD_DEST_UPDATE) - bgp_bfd_update_peer(peer); - } - return 0; -} - -/* - * bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for - * peer. - */ -static int bgp_bfd_peer_param_unset(struct peer *peer) -{ - struct peer_group *group; - struct listnode *node, *nnode; - - if (!peer->bfd_info) - return 0; - - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - bfd_info_free(&(peer->bfd_info)); - group = peer->group; - for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - bgp_bfd_deregister_peer(peer); - bfd_info_free(&(peer->bfd_info)); - } - } else { - bgp_bfd_deregister_peer(peer); - bfd_info_free(&(peer->bfd_info)); + bgp_peer_remove_bfd(pn); } - return 0; } -/* - * bgp_bfd_peer_param_type_set - set the BFD session type (multihop or - * singlehop) - */ -static int bgp_bfd_peer_param_type_set(struct peer *peer, - enum bfd_sess_type type) +void bgp_peer_remove_bfd_config(struct peer *p) { - struct peer_group *group; - struct listnode *node, *nnode; - int command = 0; - struct bfd_info *bfd_info; - - if (!peer->bfd_info) - bfd_set_param((struct bfd_info **)&(peer->bfd_info), - BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, NULL, 1, &command); - - bfd_info = (struct bfd_info *)peer->bfd_info; - bfd_info->type = type; - - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - group = peer->group; - for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - command = 0; - if (!peer->bfd_info) - bfd_set_param( - (struct bfd_info **)&(peer->bfd_info), - BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, NULL, 1, &command); - - bfd_info = (struct bfd_info *)peer->bfd_info; - bfd_info->type = type; - - if (peer->status == Established) { - if (command == ZEBRA_BFD_DEST_REGISTER) - bgp_bfd_register_peer(peer); - else - bgp_bfd_update_type(peer); - } - } - } else { - if (peer->status == Established) { - if (command == ZEBRA_BFD_DEST_REGISTER) - bgp_bfd_register_peer(peer); - else - bgp_bfd_update_type(peer); - } - } - - return 0; -} - -#if HAVE_BFDD > 0 -/** - * Set peer BFD profile configuration. - */ -static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile) -{ - struct peer_group *group; - struct listnode *node, *nnode; - int command = 0; - struct bfd_info *bfd_info; - - bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX, - BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, NULL, 1, &command); - - bfd_info = (struct bfd_info *)peer->bfd_info; - - /* If profile was specified, then copy string. */ - if (profile) - strlcpy(bfd_info->profile, profile, sizeof(bfd_info->profile)); - else /* Otherwise just initialize it empty. */ - bfd_info->profile[0] = 0; - - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - group = peer->group; - for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - command = 0; - bfd_set_param((struct bfd_info **)&(peer->bfd_info), - BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, NULL, 1, &command); - - bfd_info = (struct bfd_info *)peer->bfd_info; - - /* If profile was specified, then copy string. */ - if (profile) - strlcpy(bfd_info->profile, profile, - sizeof(bfd_info->profile)); - else /* Otherwise just initialize it empty. */ - bfd_info->profile[0] = 0; - - if (peer->status == Established - && command == ZEBRA_BFD_DEST_REGISTER) - bgp_bfd_register_peer(peer); - else if (command == ZEBRA_BFD_DEST_UPDATE) - bgp_bfd_update_peer(peer); - } - } else { - if (peer->status == Established - && command == ZEBRA_BFD_DEST_REGISTER) - bgp_bfd_register_peer(peer); - else if (command == ZEBRA_BFD_DEST_UPDATE) - bgp_bfd_update_peer(peer); - } - - return 0; + if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) + bgp_group_remove_bfd(p); + else + bgp_peer_remove_bfd(p); } -#endif /* * bgp_bfd_peer_config_write - Write the peer BFD configuration. */ -void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr) +void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer, + const char *addr) { - struct bfd_info *bfd_info; - - if (!peer->bfd_info) - return; - - bfd_info = (struct bfd_info *)peer->bfd_info; - - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) + /* + * Always show group BFD configuration, but peer only when explicitly + * configured. + */ + if ((!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) + && peer->bfd_config->manual) + || CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { #if HAVE_BFDD > 0 vty_out(vty, " neighbor %s bfd\n", addr); #else vty_out(vty, " neighbor %s bfd %d %d %d\n", addr, - bfd_info->detect_mult, bfd_info->required_min_rx, - bfd_info->desired_min_tx); + peer->bfd_config->detection_multiplier, + peer->bfd_config->min_rx, peer->bfd_config->min_tx); #endif /* HAVE_BFDD */ - - if (bfd_info->type != BFD_TYPE_NOT_CONFIGURED) - vty_out(vty, " neighbor %s bfd %s\n", addr, - (bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop" - : "singlehop"); - - if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG) - && (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)) { - vty_out(vty, " neighbor %s bfd", addr); - if (bfd_info->profile[0]) - vty_out(vty, " profile %s", bfd_info->profile); - vty_out(vty, "\n"); } - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) - vty_out(vty, " neighbor %s bfd check-control-plane-failure\n", addr); + if (peer->bfd_config->profile[0]) + vty_out(vty, " neighbor %s bfd profile %s\n", addr, + peer->bfd_config->profile); + + if (peer->bfd_config->cbit) + vty_out(vty, " neighbor %s bfd check-control-plane-failure\n", + addr); } /* * bgp_bfd_show_info - Show the peer BFD information. */ -void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json, +void bgp_bfd_show_info(struct vty *vty, const struct peer *peer, json_object *json_neigh) { - bfd_show_info(vty, (struct bfd_info *)peer->bfd_info, - bgp_bfd_is_peer_multihop(peer), 0, use_json, json_neigh); + if (peer->bfd_config->session) + bfd_sess_show(vty, json_neigh, peer->bfd_config->session); } DEFUN (neighbor_bfd, @@ -712,16 +437,17 @@ DEFUN (neighbor_bfd, { int idx_peer = 1; struct peer *peer; - int ret; peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - ret = bgp_bfd_peer_param_set(peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1); - if (ret != 0) - return bgp_vty_return(vty, ret); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_configure_bfd(peer); + else + bgp_peer_configure_bfd(peer, true); + + bgp_peer_config_apply(peer, peer->group); return CMD_SUCCESS; } @@ -745,89 +471,30 @@ DEFUN( int idx_number_1 = 3; int idx_number_2 = 4; int idx_number_3 = 5; + long detection_multiplier, min_rx, min_tx; struct peer *peer; - uint32_t rx_val; - uint32_t tx_val; - uint8_t dm_val; - int ret; peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - if ((ret = bfd_validate_param( - vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg, - argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val)) - != CMD_SUCCESS) - return ret; - - ret = bgp_bfd_peer_param_set(peer, rx_val, tx_val, dm_val, 0); - if (ret != 0) - return bgp_vty_return(vty, ret); - - return CMD_SUCCESS; -} - -DEFUN_HIDDEN (neighbor_bfd_type, - neighbor_bfd_type_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Enables BFD support\n" - "Multihop session\n" - "Single hop session\n") -{ - int idx_peer = 1; - int idx_hop = 3; - struct peer *peer; - enum bfd_sess_type type; - int ret; - - peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; + detection_multiplier = strtol(argv[idx_number_1]->arg, NULL, 10); + min_rx = strtol(argv[idx_number_2]->arg, NULL, 10); + min_tx = strtol(argv[idx_number_3]->arg, NULL, 10); - if (strmatch(argv[idx_hop]->text, "singlehop")) - type = BFD_TYPE_SINGLEHOP; - else if (strmatch(argv[idx_hop]->text, "multihop")) - type = BFD_TYPE_MULTIHOP; + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_configure_bfd(peer); else - return CMD_WARNING_CONFIG_FAILED; - - ret = bgp_bfd_peer_param_type_set(peer, type); - if (ret != 0) - return bgp_vty_return(vty, ret); + bgp_peer_configure_bfd(peer, true); - return CMD_SUCCESS; -} - -static int bgp_bfd_set_check_controlplane_failure_peer(struct vty *vty, struct peer *peer, - const char *no) -{ - struct bfd_info *bfd_info; + peer->bfd_config->detection_multiplier = detection_multiplier; + peer->bfd_config->min_rx = min_rx; + peer->bfd_config->min_tx = min_tx; + bgp_peer_config_apply(peer, peer->group); - if (!peer->bfd_info) { - if (no) - return CMD_SUCCESS; - vty_out(vty, "%% Specify bfd command first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - bfd_info = (struct bfd_info *)peer->bfd_info; - if (!no) { - if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) { - SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE); - bgp_bfd_update_peer(peer); - } - } else { - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) { - UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE); - bgp_bfd_update_peer(peer); - } - } return CMD_SUCCESS; } - DEFUN (neighbor_bfd_check_controlplane_failure, neighbor_bfd_check_controlplane_failure_cmd, "[no] neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure", @@ -840,9 +507,6 @@ DEFUN (neighbor_bfd_check_controlplane_failure, const char *no = strmatch(argv[0]->text, "no") ? "no" : NULL; int idx_peer = 0; struct peer *peer; - struct peer_group *group; - struct listnode *node, *nnode; - int ret = CMD_SUCCESS; if (no) idx_peer = 2; @@ -853,19 +517,16 @@ DEFUN (neighbor_bfd_check_controlplane_failure, vty_out(vty, "%% Specify remote-as or peer-group commands first\n"); return CMD_WARNING_CONFIG_FAILED; } - if (!peer->bfd_info) { - if (no) - return CMD_SUCCESS; - vty_out(vty, "%% Specify bfd command first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - group = peer->group; - for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) - ret = bgp_bfd_set_check_controlplane_failure_peer(vty, peer, no); - } else - ret = bgp_bfd_set_check_controlplane_failure_peer(vty, peer, no); - return ret; + + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_configure_bfd(peer); + else + bgp_peer_configure_bfd(peer, true); + + peer->bfd_config->cbit = no == NULL; + bgp_peer_config_apply(peer, peer->group); + + return CMD_SUCCESS; } DEFUN (no_neighbor_bfd, @@ -888,44 +549,15 @@ DEFUN (no_neighbor_bfd, { int idx_peer = 2; struct peer *peer; - int ret; peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - ret = bgp_bfd_peer_param_unset(peer); - if (ret != 0) - return bgp_vty_return(vty, ret); - - return CMD_SUCCESS; -} - - -DEFUN_HIDDEN (no_neighbor_bfd_type, - no_neighbor_bfd_type_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Disables BFD support\n" - "Multihop session\n" - "Singlehop session\n") -{ - int idx_peer = 2; - struct peer *peer; - int ret; - - peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; - - if (!peer->bfd_info) - return 0; - - ret = bgp_bfd_peer_param_type_set(peer, BFD_TYPE_NOT_CONFIGURED); - if (ret != 0) - return bgp_vty_return(vty, ret); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_remove_bfd(peer); + else + bgp_peer_remove_bfd(peer); return CMD_SUCCESS; } @@ -941,15 +573,19 @@ DEFUN(neighbor_bfd_profile, neighbor_bfd_profile_cmd, { int idx_peer = 1, idx_prof = 4; struct peer *peer; - int ret; peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - ret = bgp_bfd_peer_set_profile(peer, argv[idx_prof]->arg); - if (ret != 0) - return bgp_vty_return(vty, ret); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_configure_bfd(peer); + else + bgp_peer_configure_bfd(peer, true); + + strlcpy(peer->bfd_config->profile, argv[idx_prof]->arg, + sizeof(peer->bfd_config->profile)); + bgp_peer_config_apply(peer, peer->group); return CMD_SUCCESS; } @@ -965,38 +601,33 @@ DEFUN(no_neighbor_bfd_profile, no_neighbor_bfd_profile_cmd, { int idx_peer = 2; struct peer *peer; - int ret; peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - if (!peer->bfd_info) - return 0; + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + bgp_group_configure_bfd(peer); + else + bgp_peer_configure_bfd(peer, true); - ret = bgp_bfd_peer_set_profile(peer, NULL); - if (ret != 0) - return bgp_vty_return(vty, ret); + peer->bfd_config->profile[0] = 0; + bgp_peer_config_apply(peer, peer->group); return CMD_SUCCESS; } #endif /* HAVE_BFDD */ -void bgp_bfd_init(void) +void bgp_bfd_init(struct thread_master *tm) { - bfd_gbl_init(); - /* Initialize BFD client functions */ - zclient->interface_bfd_dest_update = bgp_bfd_dest_update; - zclient->bfd_dest_replay = bgp_bfd_dest_replay; + bfd_protocol_integration_init(zclient, tm); /* "neighbor bfd" commands. */ install_element(BGP_NODE, &neighbor_bfd_cmd); install_element(BGP_NODE, &neighbor_bfd_param_cmd); - install_element(BGP_NODE, &neighbor_bfd_type_cmd); install_element(BGP_NODE, &neighbor_bfd_check_controlplane_failure_cmd); install_element(BGP_NODE, &no_neighbor_bfd_cmd); - install_element(BGP_NODE, &no_neighbor_bfd_type_cmd); #if HAVE_BFDD > 0 install_element(BGP_NODE, &neighbor_bfd_profile_cmd); diff --git a/bgpd/bgp_bfd.h b/bgpd/bgp_bfd.h index f2fa959b45..9dca48a437 100644 --- a/bgpd/bgp_bfd.h +++ b/bgpd/bgp_bfd.h @@ -23,22 +23,58 @@ #ifndef _QUAGGA_BGP_BFD_H #define _QUAGGA_BGP_BFD_H -extern void bgp_bfd_init(void); +#define PEER_IS_MULTIHOP(peer) \ + ((((peer)->sort == BGP_PEER_IBGP) && !(peer)->shared_network) \ + || is_ebgp_multihop_configured((peer))) -extern void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer); +extern void bgp_bfd_init(struct thread_master *tm); -extern void bgp_bfd_register_peer(struct peer *peer); +extern void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer, + const char *addr); -extern void bgp_bfd_deregister_peer(struct peer *peer); +/** + * Show BFD information helper. + * + * \param vty the VTY pointer. + * \param peer the BGP configuration pointer. + * \param use_json unused. + * \param json_neigh JSON object when called as JSON command. + */ +extern void bgp_bfd_show_info(struct vty *vty, const struct peer *peer, + json_object *json_neigh); -extern void bgp_bfd_reset_peer(struct peer *peer); +/** + * When called on a group it applies configuration to all peers in that group, + * otherwise just applies the configuration to a single peer. + * + * This function should be called when configuration changes either on group + * or peer. + * + * \param p the BGP peer pointer. + * \param pg the BGP group to copy configuration from (it is usually + * `p->group` exception when copying new group configuration + * see `peer_group2peer_config_copy` function case). + */ +extern void bgp_peer_config_apply(struct peer *p, struct peer_group *pg); -extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, - char *addr); +/** + * Allocates and configure BFD session for peer. If it is already configured, + * then it does nothing. + * + * Always call `bgp_peer_config_apply` afterwards if you need the changes + * immediately applied. + */ +extern void bgp_peer_configure_bfd(struct peer *p, bool manual); -extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json, - json_object *json_neigh); +/** + * Removes BFD configuration from either peer or peer group. + */ +extern void bgp_peer_remove_bfd_config(struct peer *p); -extern bool bgp_bfd_is_peer_multihop(struct peer *peer); +/** + * Special function to handle the case of changing source address. This + * happens when the peer/group is configured with `neigbor X update-source Y`. + */ +extern void bgp_peer_bfd_update_source(struct peer *p); #endif /* _QUAGGA_BGP_BFD_H */ diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 4102d102e6..0e5f506b3a 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -59,21 +59,21 @@ static struct bmp_bgp_peer *bmp_bgp_peer_get(struct peer *peer); static void bmp_active_disconnected(struct bmp_active *ba); static void bmp_active_put(struct bmp_active *ba); -DEFINE_MGROUP(BMP, "BMP (BGP Monitoring Protocol)") - -DEFINE_MTYPE_STATIC(BMP, BMP_CONN, "BMP connection state") -DEFINE_MTYPE_STATIC(BMP, BMP_TARGETS, "BMP targets") -DEFINE_MTYPE_STATIC(BMP, BMP_TARGETSNAME, "BMP targets name") -DEFINE_MTYPE_STATIC(BMP, BMP_LISTENER, "BMP listener") -DEFINE_MTYPE_STATIC(BMP, BMP_ACTIVE, "BMP active connection config") -DEFINE_MTYPE_STATIC(BMP, BMP_ACLNAME, "BMP access-list name") -DEFINE_MTYPE_STATIC(BMP, BMP_QUEUE, "BMP update queue item") -DEFINE_MTYPE_STATIC(BMP, BMP, "BMP instance state") -DEFINE_MTYPE_STATIC(BMP, BMP_MIRRORQ, "BMP route mirroring buffer") -DEFINE_MTYPE_STATIC(BMP, BMP_PEER, "BMP per BGP peer data") -DEFINE_MTYPE_STATIC(BMP, BMP_OPEN, "BMP stored BGP OPEN message") - -DEFINE_QOBJ_TYPE(bmp_targets) +DEFINE_MGROUP(BMP, "BMP (BGP Monitoring Protocol)"); + +DEFINE_MTYPE_STATIC(BMP, BMP_CONN, "BMP connection state"); +DEFINE_MTYPE_STATIC(BMP, BMP_TARGETS, "BMP targets"); +DEFINE_MTYPE_STATIC(BMP, BMP_TARGETSNAME, "BMP targets name"); +DEFINE_MTYPE_STATIC(BMP, BMP_LISTENER, "BMP listener"); +DEFINE_MTYPE_STATIC(BMP, BMP_ACTIVE, "BMP active connection config"); +DEFINE_MTYPE_STATIC(BMP, BMP_ACLNAME, "BMP access-list name"); +DEFINE_MTYPE_STATIC(BMP, BMP_QUEUE, "BMP update queue item"); +DEFINE_MTYPE_STATIC(BMP, BMP, "BMP instance state"); +DEFINE_MTYPE_STATIC(BMP, BMP_MIRRORQ, "BMP route mirroring buffer"); +DEFINE_MTYPE_STATIC(BMP, BMP_PEER, "BMP per BGP peer data"); +DEFINE_MTYPE_STATIC(BMP, BMP_OPEN, "BMP stored BGP OPEN message"); + +DEFINE_QOBJ_TYPE(bmp_targets); static int bmp_bgp_cmp(const struct bmp_bgp *a, const struct bmp_bgp *b) { @@ -89,7 +89,7 @@ static uint32_t bmp_bgp_hash(const struct bmp_bgp *e) return jhash(&e->bgp, sizeof(e->bgp), 0x55aa5a5a); } -DECLARE_HASH(bmp_bgph, struct bmp_bgp, bbi, bmp_bgp_cmp, bmp_bgp_hash) +DECLARE_HASH(bmp_bgph, struct bmp_bgp, bbi, bmp_bgp_cmp, bmp_bgp_hash); struct bmp_bgph_head bmp_bgph; @@ -109,11 +109,11 @@ static uint32_t bmp_bgp_peer_hash(const struct bmp_bgp_peer *e) } DECLARE_HASH(bmp_peerh, struct bmp_bgp_peer, bpi, - bmp_bgp_peer_cmp, bmp_bgp_peer_hash) + bmp_bgp_peer_cmp, bmp_bgp_peer_hash); struct bmp_peerh_head bmp_peerh; -DECLARE_LIST(bmp_mirrorq, struct bmp_mirrorq, bmi) +DECLARE_LIST(bmp_mirrorq, struct bmp_mirrorq, bmi); /* listener management */ @@ -132,7 +132,8 @@ static int bmp_listener_cmp(const struct bmp_listener *a, return 0; } -DECLARE_SORTLIST_UNIQ(bmp_listeners, struct bmp_listener, bli, bmp_listener_cmp) +DECLARE_SORTLIST_UNIQ(bmp_listeners, struct bmp_listener, bli, + bmp_listener_cmp); static int bmp_targets_cmp(const struct bmp_targets *a, const struct bmp_targets *b) @@ -140,11 +141,11 @@ static int bmp_targets_cmp(const struct bmp_targets *a, return strcmp(a->name, b->name); } -DECLARE_SORTLIST_UNIQ(bmp_targets, struct bmp_targets, bti, bmp_targets_cmp) +DECLARE_SORTLIST_UNIQ(bmp_targets, struct bmp_targets, bti, bmp_targets_cmp); -DECLARE_LIST(bmp_session, struct bmp, bsi) +DECLARE_LIST(bmp_session, struct bmp, bsi); -DECLARE_DLIST(bmp_qlist, struct bmp_queue_entry, bli) +DECLARE_DLIST(bmp_qlist, struct bmp_queue_entry, bli); static int bmp_qhash_cmp(const struct bmp_queue_entry *a, const struct bmp_queue_entry *b) @@ -189,7 +190,7 @@ static uint32_t bmp_qhash_hkey(const struct bmp_queue_entry *e) } DECLARE_HASH(bmp_qhash, struct bmp_queue_entry, bhi, - bmp_qhash_cmp, bmp_qhash_hkey) + bmp_qhash_cmp, bmp_qhash_hkey); static int bmp_active_cmp(const struct bmp_active *a, const struct bmp_active *b) @@ -206,7 +207,7 @@ static int bmp_active_cmp(const struct bmp_active *a, return 0; } -DECLARE_SORTLIST_UNIQ(bmp_actives, struct bmp_active, bai, bmp_active_cmp) +DECLARE_SORTLIST_UNIQ(bmp_actives, struct bmp_active, bai, bmp_active_cmp); static struct bmp *bmp_new(struct bmp_targets *bt, int bmp_sock) { @@ -2443,4 +2444,5 @@ static int bgp_bmp_module_init(void) FRR_MODULE_SETUP(.name = "bgpd_bmp", .version = FRR_VERSION, .description = "bgpd BMP module", - .init = bgp_bmp_module_init) + .init = bgp_bmp_module_init, +); diff --git a/bgpd/bgp_bmp.h b/bgpd/bgp_bmp.h index 2c3ba570ee..899840e582 100644 --- a/bgpd/bgp_bmp.h +++ b/bgpd/bgp_bmp.h @@ -66,8 +66,8 @@ * always happens from the front of the queue.) */ -PREDECL_DLIST(bmp_qlist) -PREDECL_HASH(bmp_qhash) +PREDECL_DLIST(bmp_qlist); +PREDECL_HASH(bmp_qhash); struct bmp_queue_entry { struct bmp_qlist_item bli; @@ -92,7 +92,7 @@ struct bmp_queue_entry { * with a size limit. Refcount works the same as for monitoring above. */ -PREDECL_LIST(bmp_mirrorq) +PREDECL_LIST(bmp_mirrorq); struct bmp_mirrorq { struct bmp_mirrorq_item bmi; @@ -112,7 +112,7 @@ enum { BMP_AFI_LIVE, }; -PREDECL_LIST(bmp_session) +PREDECL_LIST(bmp_session); struct bmp_active; struct bmp_targets; @@ -166,7 +166,7 @@ struct bmp { * succeeds, "bmp" is set up. */ -PREDECL_SORTLIST_UNIQ(bmp_actives) +PREDECL_SORTLIST_UNIQ(bmp_actives); #define BMP_DFLT_MINRETRY 30000 #define BMP_DFLT_MAXRETRY 720000 @@ -191,7 +191,7 @@ struct bmp_active { }; /* config & state for passive / listening sockets */ -PREDECL_SORTLIST_UNIQ(bmp_listeners) +PREDECL_SORTLIST_UNIQ(bmp_listeners); struct bmp_listener { struct bmp_listeners_item bli; @@ -209,7 +209,7 @@ struct bmp_listener { * bmp_active items. If they have the same config, BMP session should be * put in the same targets since that's a bit more effective. */ -PREDECL_SORTLIST_UNIQ(bmp_targets) +PREDECL_SORTLIST_UNIQ(bmp_targets); struct bmp_targets { struct bmp_targets_item bti; @@ -245,13 +245,13 @@ struct bmp_targets { uint64_t cnt_accept, cnt_aclrefused; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(bmp_targets) +DECLARE_QOBJ_TYPE(bmp_targets); /* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand, * deleted in peer_backward hook. */ -PREDECL_HASH(bmp_peerh) +PREDECL_HASH(bmp_peerh); struct bmp_bgp_peer { struct bmp_peerh_item bpi; @@ -267,7 +267,7 @@ struct bmp_bgp_peer { }; /* per struct bgp * data */ -PREDECL_HASH(bmp_bgph) +PREDECL_HASH(bmp_bgph); #define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00 @@ -309,6 +309,6 @@ enum { BMP_STATS_FRR_NH_INVALID = 65531, }; -DECLARE_MGROUP(BMP) +DECLARE_MGROUP(BMP); #endif /*_BGP_BMP_H_*/ diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 3afa6eaf09..ce1b7b552b 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -21,6 +21,7 @@ #include <zebra.h> #include <lib/version.h> +#include "lib/bfd.h" #include "lib/printfrr.h" #include "prefix.h" #include "linklist.h" @@ -67,6 +68,7 @@ unsigned long conf_bgp_debug_labelpool; unsigned long conf_bgp_debug_pbr; unsigned long conf_bgp_debug_graceful_restart; unsigned long conf_bgp_debug_evpn_mh; +unsigned long conf_bgp_debug_bfd; unsigned long term_bgp_debug_as4; unsigned long term_bgp_debug_neighbor_events; @@ -86,6 +88,7 @@ unsigned long term_bgp_debug_labelpool; unsigned long term_bgp_debug_pbr; unsigned long term_bgp_debug_graceful_restart; unsigned long term_bgp_debug_evpn_mh; +unsigned long term_bgp_debug_bfd; struct list *bgp_debug_neighbor_events_peers = NULL; struct list *bgp_debug_keepalive_peers = NULL; @@ -2093,6 +2096,31 @@ DEFUN (no_debug_bgp_labelpool, return CMD_SUCCESS; } +DEFPY(debug_bgp_bfd, debug_bgp_bfd_cmd, + "[no] debug bgp bfd", + NO_STR + DEBUG_STR + BGP_STR + "Bidirection Forwarding Detection\n") +{ + if (vty->node == CONFIG_NODE) { + if (no) { + DEBUG_OFF(bfd, BFD_LIB); + bfd_protocol_integration_set_debug(false); + } else { + DEBUG_ON(bfd, BFD_LIB); + bfd_protocol_integration_set_debug(true); + } + } else { + if (no) + TERM_DEBUG_OFF(bfd, BFD_LIB); + else + TERM_DEBUG_ON(bfd, BFD_LIB); + } + + return CMD_SUCCESS; +} + DEFUN (no_debug_bgp, no_debug_bgp_cmd, "no debug bgp", @@ -2136,6 +2164,7 @@ DEFUN (no_debug_bgp, TERM_DEBUG_OFF(graceful_restart, GRACEFUL_RESTART); TERM_DEBUG_OFF(evpn_mh, EVPN_MH_ES); TERM_DEBUG_OFF(evpn_mh, EVPN_MH_RT); + TERM_DEBUG_OFF(bfd, BFD_LIB); vty_out(vty, "All possible debugging has been turned off\n"); @@ -2225,6 +2254,9 @@ DEFUN_NOSH (show_debugging_bgp, if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) vty_out(vty, " BGP EVPN-MH route debugging is on\n"); + if (BGP_DEBUG(bfd, BFD_LIB)) + vty_out(vty, " BGP BFD library debugging is on\n"); + vty_out(vty, "\n"); return CMD_SUCCESS; } @@ -2350,6 +2382,11 @@ static int bgp_config_write_debug(struct vty *vty) write++; } + if (CONF_BGP_DEBUG(bfd, BFD_LIB)) { + vty_out(vty, "debug bgp bfd\n"); + write++; + } + return write; } @@ -2478,6 +2515,10 @@ void bgp_debug_init(void) install_element(ENABLE_NODE, &debug_bgp_evpn_mh_cmd); install_element(CONFIG_NODE, &debug_bgp_evpn_mh_cmd); + + /* debug bgp bfd */ + install_element(ENABLE_NODE, &debug_bgp_bfd_cmd); + install_element(CONFIG_NODE, &debug_bgp_bfd_cmd); } /* Return true if this prefix is on the per_prefix_list of prefixes to debug diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index f16cfee4f2..fa8da1c345 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -78,6 +78,7 @@ extern unsigned long conf_bgp_debug_labelpool; extern unsigned long conf_bgp_debug_pbr; extern unsigned long conf_bgp_debug_graceful_restart; extern unsigned long conf_bgp_debug_evpn_mh; +extern unsigned long conf_bgp_debug_bfd; extern unsigned long term_bgp_debug_as4; extern unsigned long term_bgp_debug_neighbor_events; @@ -95,6 +96,7 @@ extern unsigned long term_bgp_debug_labelpool; extern unsigned long term_bgp_debug_pbr; extern unsigned long term_bgp_debug_graceful_restart; extern unsigned long term_bgp_debug_evpn_mh; +extern unsigned long term_bgp_debug_bfd; extern struct list *bgp_debug_neighbor_events_peers; extern struct list *bgp_debug_keepalive_peers; @@ -139,6 +141,8 @@ struct bgp_debug_filter { #define BGP_DEBUG_GRACEFUL_RESTART 0x01 +#define BGP_DEBUG_BFD_LIB 0x01 + #define CONF_DEBUG_ON(a, b) (conf_bgp_debug_ ## a |= (BGP_DEBUG_ ## b)) #define CONF_DEBUG_OFF(a, b) (conf_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b)) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 7b29f1e4c9..cebc1c4d22 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -57,8 +57,8 @@ /* * Definitions and external declarations. */ -DEFINE_QOBJ_TYPE(bgpevpn) -DEFINE_QOBJ_TYPE(bgp_evpn_es) +DEFINE_QOBJ_TYPE(bgpevpn); +DEFINE_QOBJ_TYPE(bgp_evpn_es); /* @@ -2235,6 +2235,8 @@ int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) int ret; struct prefix_evpn p; + update_type1_routes_for_evi(bgp, vpn); + /* Update and advertise the type-3 route (only one) followed by the * locally learnt type-2 routes (MACIP) - for this VNI. * @@ -3136,7 +3138,7 @@ static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) return ret; ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_AD_ROUTE, - 1); + 0); if (ret) return ret; diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 123c46f12f..826de21b9d 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -970,6 +970,48 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, return 0; } +/* + * This function is called when the export RT for a VNI changes. + * Update all type-1 local routes for this VNI from VNI/ES tables and the global + * table and advertise these routes to peers. + */ + +void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn) +{ + struct prefix_evpn p; + struct bgp_evpn_es *es; + struct bgp_evpn_es_evi *es_evi; + struct bgp_evpn_es_evi *es_evi_next; + + RB_FOREACH_SAFE(es_evi, bgp_es_evi_rb_head, + &vpn->es_evi_rb_tree, es_evi_next) { + es = es_evi->es; + + /* Update EAD-ES */ + if (CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { + build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, + &es->esi, es->originator_ip); + if (bgp_evpn_type1_route_update(bgp, es, NULL, &p)) + flog_err(EC_BGP_EVPN_ROUTE_CREATE, + "%u: EAD-ES route update failure for ESI %s VNI %u", + bgp->vrf_id, es->esi_str, + es_evi->vpn->vni); + } + + /* Update EAD-EVI */ + if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI)) { + build_evpn_type1_prefix(&p, BGP_EVPN_AD_EVI_ETH_TAG, + &es->esi, es->originator_ip); + if (bgp_evpn_type1_route_update(bgp, es, es_evi->vpn, + &p)) + flog_err(EC_BGP_EVPN_ROUTE_DELETE, + "%u: EAD-EVI route update failure for ESI %s VNI %u", + bgp->vrf_id, es->esi_str, + es_evi->vpn->vni); + } + } +} + /* Delete local Type-1 route */ static int bgp_evpn_type1_es_route_delete(struct bgp *bgp, struct bgp_evpn_es *es, struct prefix_evpn *p) diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h index e5186619ff..8c66e391b6 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h @@ -125,9 +125,9 @@ struct bgp_evpn_es { /* preference config for BUM-DF election. advertised via the ESR. */ uint16_t df_pref; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(bgp_evpn_es) +DECLARE_QOBJ_TYPE(bgp_evpn_es); RB_HEAD(bgp_es_rb_head, bgp_evpn_es); RB_PROTOTYPE(bgp_es_rb_head, bgp_evpn_es, rb_node, bgp_es_rb_cmp); @@ -335,6 +335,7 @@ extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, afi_t afi, safi_t safi, struct prefix_evpn *evp, struct bgp_path_info *pi, int install); +extern void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn); int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi, struct attr *attr, uint8_t *pfx, int psize, uint32_t addpath_id); diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 77b3746344..ff4970af41 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -112,10 +112,10 @@ struct bgpevpn { /* List of local ESs */ struct list *local_es_evi_list; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(bgpevpn) +DECLARE_QOBJ_TYPE(bgpevpn); /* Mapping of Import RT to VNIs. * The Import RTs of all VNIs are maintained in a hash table with each diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 6abba18418..45a856a459 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -57,8 +57,8 @@ #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_vty.h" -DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer)) -DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer)) +DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer)); +DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer)); /* Definition of display strings corresponding to FSM events. This should be * kept consistent with the events defined in bgpd.h @@ -1215,8 +1215,9 @@ int bgp_stop(struct peer *peer) peer->nsf_af_count = 0; /* deregister peer */ - if (peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE) - bgp_bfd_deregister_peer(peer); + if (peer->bfd_config + && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE) + bfd_sess_uninstall(peer->bfd_config->session); if (peer_dynamic_neighbor(peer) && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) { @@ -2122,7 +2123,10 @@ static int bgp_establish(struct peer *peer) hash_release(peer->bgp->peerhash, peer); hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); - bgp_bfd_reset_peer(peer); + /* Start BFD peer if not already running. */ + if (peer->bfd_config) + bgp_peer_bfd_update_source(peer); + return ret; } diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index bf4966c839..bcf697e153 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -155,8 +155,8 @@ extern void bgp_start_routeadv(struct bgp *); extern void bgp_adjust_routeadv(struct peer *); #include "hook.h" -DECLARE_HOOK(peer_backward_transition, (struct peer *peer), (peer)) -DECLARE_HOOK(peer_established, (struct peer *peer), (peer)) +DECLARE_HOOK(peer_backward_transition, (struct peer *peer), (peer)); +DECLARE_HOOK(peer_established, (struct peer *peer), (peer)); int bgp_gr_update_all(struct bgp *bgp, int global_gr_cmd); int bgp_neighbor_graceful_restart(struct peer *peer, int peer_gr_cmd); diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index 001340be35..fcb2df9d6f 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -50,10 +50,10 @@ static struct labelpool *lp; /* request this many labels at a time from zebra */ #define LP_CHUNK_SIZE 50 -DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CHUNK, "BGP Label Chunk") -DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_FIFO, "BGP Label FIFO item") -DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CB, "BGP Dynamic Label Assignment") -DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CBQ, "BGP Dynamic Label Callback") +DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CHUNK, "BGP Label Chunk"); +DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_FIFO, "BGP Label FIFO item"); +DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CB, "BGP Dynamic Label Assignment"); +DEFINE_MTYPE_STATIC(BGPD, BGP_LABEL_CBQ, "BGP Dynamic Label Callback"); struct lp_chunk { uint32_t first; @@ -80,7 +80,7 @@ struct lp_fifo { struct lp_lcb lcb; }; -DECLARE_LIST(lp_fifo, struct lp_fifo, fifo) +DECLARE_LIST(lp_fifo, struct lp_fifo, fifo); struct lp_cbq_item { int (*cbfunc)(mpls_label_t label, void *lblid, bool alloc); diff --git a/bgpd/bgp_labelpool.h b/bgpd/bgp_labelpool.h index d9f64acfe4..d6a8eec84d 100644 --- a/bgpd/bgp_labelpool.h +++ b/bgpd/bgp_labelpool.h @@ -31,7 +31,7 @@ #define LP_TYPE_VRF 0x00000001 #define LP_TYPE_BGP_LU 0x00000002 -PREDECL_LIST(lp_fifo) +PREDECL_LIST(lp_fifo); struct labelpool { struct skiplist *ledger; /* all requests */ diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 3cb3d06217..2ddafd9a0c 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -162,6 +162,9 @@ __attribute__((__noreturn__)) void sigint(void) assert(bm->terminating == false); bm->terminating = true; /* global flag that shutting down */ + /* Disable BFD events to avoid wasting processing. */ + bfd_protocol_integration_set_shutdown(true); + bgp_terminate(); bgp_exit(0); @@ -394,7 +397,8 @@ FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT, .signals = bgp_signals, .n_signals = array_size(bgp_signals), .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules, - .n_yang_modules = array_size(bgpd_yang_modules), ) + .n_yang_modules = array_size(bgpd_yang_modules), +); #define DEPRECATED_OPTIONS "" diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index 0013eb2df2..9a4eb5d3bd 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -28,112 +28,112 @@ /* this file is temporary in nature; definitions should be moved to the * files they're used in */ -DEFINE_MGROUP(BGPD, "bgpd") -DEFINE_MTYPE(BGPD, BGP, "BGP instance") -DEFINE_MTYPE(BGPD, BGP_LISTENER, "BGP listen socket details") -DEFINE_MTYPE(BGPD, BGP_PEER, "BGP peer") -DEFINE_MTYPE(BGPD, BGP_PEER_HOST, "BGP peer hostname") -DEFINE_MTYPE(BGPD, BGP_PEER_IFNAME, "BGP peer ifname") -DEFINE_MTYPE(BGPD, PEER_GROUP, "Peer group") -DEFINE_MTYPE(BGPD, PEER_GROUP_HOST, "BGP Peer group hostname") -DEFINE_MTYPE(BGPD, PEER_DESC, "Peer description") -DEFINE_MTYPE(BGPD, PEER_PASSWORD, "Peer password string") -DEFINE_MTYPE(BGPD, BGP_PEER_AF, "BGP peer af") -DEFINE_MTYPE(BGPD, BGP_UPDGRP, "BGP update group") -DEFINE_MTYPE(BGPD, BGP_UPD_SUBGRP, "BGP update subgroup") -DEFINE_MTYPE(BGPD, BGP_PACKET, "BGP packet") -DEFINE_MTYPE(BGPD, ATTR, "BGP attribute") -DEFINE_MTYPE(BGPD, AS_PATH, "BGP aspath") -DEFINE_MTYPE(BGPD, AS_SEG, "BGP aspath seg") -DEFINE_MTYPE(BGPD, AS_SEG_DATA, "BGP aspath segment data") -DEFINE_MTYPE(BGPD, AS_STR, "BGP aspath str") - -DEFINE_MTYPE(BGPD, BGP_TABLE, "BGP table") -DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node") -DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route") -DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA, "BGP ancillary route info") -DEFINE_MTYPE(BGPD, BGP_CONN, "BGP connected") -DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static") -DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr") -DEFINE_MTYPE(BGPD, BGP_ADVERTISE, "BGP adv") -DEFINE_MTYPE(BGPD, BGP_SYNCHRONISE, "BGP synchronise") -DEFINE_MTYPE(BGPD, BGP_ADJ_IN, "BGP adj in") -DEFINE_MTYPE(BGPD, BGP_ADJ_OUT, "BGP adj out") -DEFINE_MTYPE(BGPD, BGP_MPATH_INFO, "BGP multipath info") - -DEFINE_MTYPE(BGPD, AS_LIST, "BGP AS list") -DEFINE_MTYPE(BGPD, AS_FILTER, "BGP AS filter") -DEFINE_MTYPE(BGPD, AS_FILTER_STR, "BGP AS filter str") - -DEFINE_MTYPE(BGPD, COMMUNITY, "community") -DEFINE_MTYPE(BGPD, COMMUNITY_VAL, "community val") -DEFINE_MTYPE(BGPD, COMMUNITY_STR, "community str") - -DEFINE_MTYPE(BGPD, ECOMMUNITY, "extcommunity") -DEFINE_MTYPE(BGPD, ECOMMUNITY_VAL, "extcommunity val") -DEFINE_MTYPE(BGPD, ECOMMUNITY_STR, "extcommunity str") - -DEFINE_MTYPE(BGPD, COMMUNITY_LIST, "community-list") -DEFINE_MTYPE(BGPD, COMMUNITY_LIST_NAME, "community-list name") -DEFINE_MTYPE(BGPD, COMMUNITY_LIST_ENTRY, "community-list entry") -DEFINE_MTYPE(BGPD, COMMUNITY_LIST_CONFIG, "community-list config") -DEFINE_MTYPE(BGPD, COMMUNITY_LIST_HANDLER, "community-list handler") - -DEFINE_MTYPE(BGPD, CLUSTER, "Cluster list") -DEFINE_MTYPE(BGPD, CLUSTER_VAL, "Cluster list val") - -DEFINE_MTYPE(BGPD, BGP_PROCESS_QUEUE, "BGP Process queue") -DEFINE_MTYPE(BGPD, BGP_CLEAR_NODE_QUEUE, "BGP node clear queue") - -DEFINE_MTYPE(BGPD, TRANSIT, "BGP transit attr") -DEFINE_MTYPE(BGPD, TRANSIT_VAL, "BGP transit val") - -DEFINE_MTYPE(BGPD, BGP_DEBUG_FILTER, "BGP debug filter") -DEFINE_MTYPE(BGPD, BGP_DEBUG_STR, "BGP debug filter string") - -DEFINE_MTYPE(BGPD, BGP_DISTANCE, "BGP distance") -DEFINE_MTYPE(BGPD, BGP_NEXTHOP_CACHE, "BGP nexthop") -DEFINE_MTYPE(BGPD, BGP_CONFED_LIST, "BGP confed list") -DEFINE_MTYPE(BGPD, PEER_UPDATE_SOURCE, "BGP peer update interface") -DEFINE_MTYPE(BGPD, PEER_CONF_IF, "BGP peer config interface") -DEFINE_MTYPE(BGPD, BGP_DAMP_INFO, "Dampening info") -DEFINE_MTYPE(BGPD, BGP_DAMP_ARRAY, "BGP Dampening array") -DEFINE_MTYPE(BGPD, BGP_DAMP_REUSELIST, "BGP Dampening reuse list") -DEFINE_MTYPE(BGPD, BGP_REGEXP, "BGP regexp") -DEFINE_MTYPE(BGPD, BGP_AGGREGATE, "BGP aggregate") -DEFINE_MTYPE(BGPD, BGP_ADDR, "BGP own address") -DEFINE_MTYPE(BGPD, TIP_ADDR, "BGP own tunnel-ip address") - -DEFINE_MTYPE(BGPD, BGP_REDIST, "BGP redistribution") -DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information") -DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information") -DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV") - -DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options") -DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value") - -DEFINE_MTYPE(BGPD, LCOMMUNITY, "Large Community") -DEFINE_MTYPE(BGPD, LCOMMUNITY_STR, "Large Community display string") -DEFINE_MTYPE(BGPD, LCOMMUNITY_VAL, "Large Community value") - -DEFINE_MTYPE(BGPD, BGP_EVPN, "BGP EVPN Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_MH_INFO, "BGP EVPN MH Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_ES_VTEP, "BGP EVPN ES VTEP") -DEFINE_MTYPE(BGPD, BGP_EVPN_PATH_ES_INFO, "BGP EVPN PATH ES Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_ES_EVI_VTEP, "BGP EVPN ES-EVI VTEP") -DEFINE_MTYPE(BGPD, BGP_EVPN_ES, "BGP EVPN ESI Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_ES_EVI, "BGP EVPN ES-per-EVI Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_ES_VRF, "BGP EVPN ES-per-VRF Information") -DEFINE_MTYPE(BGPD, BGP_EVPN_IMPORT_RT, "BGP EVPN Import RT") -DEFINE_MTYPE(BGPD, BGP_EVPN_VRF_IMPORT_RT, "BGP EVPN VRF Import RT") -DEFINE_MTYPE(BGPD, BGP_EVPN_MACIP, "BGP EVPN MAC IP") - -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC, "BGP flowspec") -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE, "BGP flowspec rule") -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE_STR, "BGP flowspec rule str") -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_COMPILED, "BGP flowspec compiled") -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_NAME, "BGP flowspec name") -DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_INDEX, "BGP flowspec index") - -DEFINE_MTYPE(BGPD, BGP_SRV6_L3VPN, "BGP prefix-sid srv6 l3vpn servcie") -DEFINE_MTYPE(BGPD, BGP_SRV6_VPN, "BGP prefix-sid srv6 vpn service") +DEFINE_MGROUP(BGPD, "bgpd"); +DEFINE_MTYPE(BGPD, BGP, "BGP instance"); +DEFINE_MTYPE(BGPD, BGP_LISTENER, "BGP listen socket details"); +DEFINE_MTYPE(BGPD, BGP_PEER, "BGP peer"); +DEFINE_MTYPE(BGPD, BGP_PEER_HOST, "BGP peer hostname"); +DEFINE_MTYPE(BGPD, BGP_PEER_IFNAME, "BGP peer ifname"); +DEFINE_MTYPE(BGPD, PEER_GROUP, "Peer group"); +DEFINE_MTYPE(BGPD, PEER_GROUP_HOST, "BGP Peer group hostname"); +DEFINE_MTYPE(BGPD, PEER_DESC, "Peer description"); +DEFINE_MTYPE(BGPD, PEER_PASSWORD, "Peer password string"); +DEFINE_MTYPE(BGPD, BGP_PEER_AF, "BGP peer af"); +DEFINE_MTYPE(BGPD, BGP_UPDGRP, "BGP update group"); +DEFINE_MTYPE(BGPD, BGP_UPD_SUBGRP, "BGP update subgroup"); +DEFINE_MTYPE(BGPD, BGP_PACKET, "BGP packet"); +DEFINE_MTYPE(BGPD, ATTR, "BGP attribute"); +DEFINE_MTYPE(BGPD, AS_PATH, "BGP aspath"); +DEFINE_MTYPE(BGPD, AS_SEG, "BGP aspath seg"); +DEFINE_MTYPE(BGPD, AS_SEG_DATA, "BGP aspath segment data"); +DEFINE_MTYPE(BGPD, AS_STR, "BGP aspath str"); + +DEFINE_MTYPE(BGPD, BGP_TABLE, "BGP table"); +DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node"); +DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA, "BGP ancillary route info"); +DEFINE_MTYPE(BGPD, BGP_CONN, "BGP connected"); +DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static"); +DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr"); +DEFINE_MTYPE(BGPD, BGP_ADVERTISE, "BGP adv"); +DEFINE_MTYPE(BGPD, BGP_SYNCHRONISE, "BGP synchronise"); +DEFINE_MTYPE(BGPD, BGP_ADJ_IN, "BGP adj in"); +DEFINE_MTYPE(BGPD, BGP_ADJ_OUT, "BGP adj out"); +DEFINE_MTYPE(BGPD, BGP_MPATH_INFO, "BGP multipath info"); + +DEFINE_MTYPE(BGPD, AS_LIST, "BGP AS list"); +DEFINE_MTYPE(BGPD, AS_FILTER, "BGP AS filter"); +DEFINE_MTYPE(BGPD, AS_FILTER_STR, "BGP AS filter str"); + +DEFINE_MTYPE(BGPD, COMMUNITY, "community"); +DEFINE_MTYPE(BGPD, COMMUNITY_VAL, "community val"); +DEFINE_MTYPE(BGPD, COMMUNITY_STR, "community str"); + +DEFINE_MTYPE(BGPD, ECOMMUNITY, "extcommunity"); +DEFINE_MTYPE(BGPD, ECOMMUNITY_VAL, "extcommunity val"); +DEFINE_MTYPE(BGPD, ECOMMUNITY_STR, "extcommunity str"); + +DEFINE_MTYPE(BGPD, COMMUNITY_LIST, "community-list"); +DEFINE_MTYPE(BGPD, COMMUNITY_LIST_NAME, "community-list name"); +DEFINE_MTYPE(BGPD, COMMUNITY_LIST_ENTRY, "community-list entry"); +DEFINE_MTYPE(BGPD, COMMUNITY_LIST_CONFIG, "community-list config"); +DEFINE_MTYPE(BGPD, COMMUNITY_LIST_HANDLER, "community-list handler"); + +DEFINE_MTYPE(BGPD, CLUSTER, "Cluster list"); +DEFINE_MTYPE(BGPD, CLUSTER_VAL, "Cluster list val"); + +DEFINE_MTYPE(BGPD, BGP_PROCESS_QUEUE, "BGP Process queue"); +DEFINE_MTYPE(BGPD, BGP_CLEAR_NODE_QUEUE, "BGP node clear queue"); + +DEFINE_MTYPE(BGPD, TRANSIT, "BGP transit attr"); +DEFINE_MTYPE(BGPD, TRANSIT_VAL, "BGP transit val"); + +DEFINE_MTYPE(BGPD, BGP_DEBUG_FILTER, "BGP debug filter"); +DEFINE_MTYPE(BGPD, BGP_DEBUG_STR, "BGP debug filter string"); + +DEFINE_MTYPE(BGPD, BGP_DISTANCE, "BGP distance"); +DEFINE_MTYPE(BGPD, BGP_NEXTHOP_CACHE, "BGP nexthop"); +DEFINE_MTYPE(BGPD, BGP_CONFED_LIST, "BGP confed list"); +DEFINE_MTYPE(BGPD, PEER_UPDATE_SOURCE, "BGP peer update interface"); +DEFINE_MTYPE(BGPD, PEER_CONF_IF, "BGP peer config interface"); +DEFINE_MTYPE(BGPD, BGP_DAMP_INFO, "Dampening info"); +DEFINE_MTYPE(BGPD, BGP_DAMP_ARRAY, "BGP Dampening array"); +DEFINE_MTYPE(BGPD, BGP_DAMP_REUSELIST, "BGP Dampening reuse list"); +DEFINE_MTYPE(BGPD, BGP_REGEXP, "BGP regexp"); +DEFINE_MTYPE(BGPD, BGP_AGGREGATE, "BGP aggregate"); +DEFINE_MTYPE(BGPD, BGP_ADDR, "BGP own address"); +DEFINE_MTYPE(BGPD, TIP_ADDR, "BGP own tunnel-ip address"); + +DEFINE_MTYPE(BGPD, BGP_REDIST, "BGP redistribution"); +DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information"); +DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information"); +DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV"); + +DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options"); +DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value"); + +DEFINE_MTYPE(BGPD, LCOMMUNITY, "Large Community"); +DEFINE_MTYPE(BGPD, LCOMMUNITY_STR, "Large Community display string"); +DEFINE_MTYPE(BGPD, LCOMMUNITY_VAL, "Large Community value"); + +DEFINE_MTYPE(BGPD, BGP_EVPN, "BGP EVPN Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_MH_INFO, "BGP EVPN MH Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_ES_VTEP, "BGP EVPN ES VTEP"); +DEFINE_MTYPE(BGPD, BGP_EVPN_PATH_ES_INFO, "BGP EVPN PATH ES Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_ES_EVI_VTEP, "BGP EVPN ES-EVI VTEP"); +DEFINE_MTYPE(BGPD, BGP_EVPN_ES, "BGP EVPN ESI Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_ES_EVI, "BGP EVPN ES-per-EVI Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_ES_VRF, "BGP EVPN ES-per-VRF Information"); +DEFINE_MTYPE(BGPD, BGP_EVPN_IMPORT_RT, "BGP EVPN Import RT"); +DEFINE_MTYPE(BGPD, BGP_EVPN_VRF_IMPORT_RT, "BGP EVPN VRF Import RT"); +DEFINE_MTYPE(BGPD, BGP_EVPN_MACIP, "BGP EVPN MAC IP"); + +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC, "BGP flowspec"); +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE, "BGP flowspec rule"); +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE_STR, "BGP flowspec rule str"); +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_COMPILED, "BGP flowspec compiled"); +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_NAME, "BGP flowspec name"); +DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_INDEX, "BGP flowspec index"); + +DEFINE_MTYPE(BGPD, BGP_SRV6_L3VPN, "BGP prefix-sid srv6 l3vpn servcie"); +DEFINE_MTYPE(BGPD, BGP_SRV6_VPN, "BGP prefix-sid srv6 vpn service"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 63998e95ac..7b839f1d4c 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -24,115 +24,115 @@ #include "memory.h" -DECLARE_MGROUP(BGPD) -DECLARE_MTYPE(BGP) -DECLARE_MTYPE(BGP_LISTENER) -DECLARE_MTYPE(BGP_PEER) -DECLARE_MTYPE(BGP_PEER_HOST) -DECLARE_MTYPE(BGP_PEER_IFNAME) -DECLARE_MTYPE(PEER_GROUP) -DECLARE_MTYPE(PEER_GROUP_HOST) -DECLARE_MTYPE(PEER_DESC) -DECLARE_MTYPE(PEER_PASSWORD) -DECLARE_MTYPE(BGP_PEER_AF) -DECLARE_MTYPE(BGP_UPDGRP) -DECLARE_MTYPE(BGP_UPD_SUBGRP) -DECLARE_MTYPE(BGP_PACKET) -DECLARE_MTYPE(ATTR) -DECLARE_MTYPE(AS_PATH) -DECLARE_MTYPE(AS_SEG) -DECLARE_MTYPE(AS_SEG_DATA) -DECLARE_MTYPE(AS_STR) - -DECLARE_MTYPE(BGP_TABLE) -DECLARE_MTYPE(BGP_NODE) -DECLARE_MTYPE(BGP_ROUTE) -DECLARE_MTYPE(BGP_ROUTE_EXTRA) -DECLARE_MTYPE(BGP_CONN) -DECLARE_MTYPE(BGP_STATIC) -DECLARE_MTYPE(BGP_ADVERTISE_ATTR) -DECLARE_MTYPE(BGP_ADVERTISE) -DECLARE_MTYPE(BGP_SYNCHRONISE) -DECLARE_MTYPE(BGP_ADJ_IN) -DECLARE_MTYPE(BGP_ADJ_OUT) -DECLARE_MTYPE(BGP_MPATH_INFO) - -DECLARE_MTYPE(AS_LIST) -DECLARE_MTYPE(AS_FILTER) -DECLARE_MTYPE(AS_FILTER_STR) - -DECLARE_MTYPE(COMMUNITY) -DECLARE_MTYPE(COMMUNITY_VAL) -DECLARE_MTYPE(COMMUNITY_STR) - -DECLARE_MTYPE(ECOMMUNITY) -DECLARE_MTYPE(ECOMMUNITY_VAL) -DECLARE_MTYPE(ECOMMUNITY_STR) - -DECLARE_MTYPE(COMMUNITY_LIST) -DECLARE_MTYPE(COMMUNITY_LIST_NAME) -DECLARE_MTYPE(COMMUNITY_LIST_ENTRY) -DECLARE_MTYPE(COMMUNITY_LIST_CONFIG) -DECLARE_MTYPE(COMMUNITY_LIST_HANDLER) - -DECLARE_MTYPE(CLUSTER) -DECLARE_MTYPE(CLUSTER_VAL) - -DECLARE_MTYPE(BGP_PROCESS_QUEUE) -DECLARE_MTYPE(BGP_CLEAR_NODE_QUEUE) - -DECLARE_MTYPE(TRANSIT) -DECLARE_MTYPE(TRANSIT_VAL) - -DECLARE_MTYPE(BGP_DEBUG_FILTER) -DECLARE_MTYPE(BGP_DEBUG_STR) - -DECLARE_MTYPE(BGP_DISTANCE) -DECLARE_MTYPE(BGP_NEXTHOP_CACHE) -DECLARE_MTYPE(BGP_CONFED_LIST) -DECLARE_MTYPE(PEER_UPDATE_SOURCE) -DECLARE_MTYPE(PEER_CONF_IF) -DECLARE_MTYPE(BGP_DAMP_INFO) -DECLARE_MTYPE(BGP_DAMP_ARRAY) -DECLARE_MTYPE(BGP_DAMP_REUSELIST) -DECLARE_MTYPE(BGP_REGEXP) -DECLARE_MTYPE(BGP_AGGREGATE) -DECLARE_MTYPE(BGP_ADDR) -DECLARE_MTYPE(TIP_ADDR) - -DECLARE_MTYPE(BGP_REDIST) -DECLARE_MTYPE(BGP_FILTER_NAME) -DECLARE_MTYPE(BGP_DUMP_STR) -DECLARE_MTYPE(ENCAP_TLV) - -DECLARE_MTYPE(BGP_TEA_OPTIONS) -DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE) - -DECLARE_MTYPE(LCOMMUNITY) -DECLARE_MTYPE(LCOMMUNITY_STR) -DECLARE_MTYPE(LCOMMUNITY_VAL) - -DECLARE_MTYPE(BGP_EVPN_MH_INFO) -DECLARE_MTYPE(BGP_EVPN_ES) -DECLARE_MTYPE(BGP_EVPN_ES_EVI) -DECLARE_MTYPE(BGP_EVPN_ES_VRF) -DECLARE_MTYPE(BGP_EVPN_ES_VTEP) -DECLARE_MTYPE(BGP_EVPN_PATH_ES_INFO) -DECLARE_MTYPE(BGP_EVPN_ES_EVI_VTEP) - -DECLARE_MTYPE(BGP_EVPN) -DECLARE_MTYPE(BGP_EVPN_IMPORT_RT) -DECLARE_MTYPE(BGP_EVPN_VRF_IMPORT_RT) -DECLARE_MTYPE(BGP_EVPN_MACIP) - -DECLARE_MTYPE(BGP_FLOWSPEC) -DECLARE_MTYPE(BGP_FLOWSPEC_RULE) -DECLARE_MTYPE(BGP_FLOWSPEC_RULE_STR) -DECLARE_MTYPE(BGP_FLOWSPEC_COMPILED) -DECLARE_MTYPE(BGP_FLOWSPEC_NAME) -DECLARE_MTYPE(BGP_FLOWSPEC_INDEX) - -DECLARE_MTYPE(BGP_SRV6_L3VPN) -DECLARE_MTYPE(BGP_SRV6_VPN) +DECLARE_MGROUP(BGPD); +DECLARE_MTYPE(BGP); +DECLARE_MTYPE(BGP_LISTENER); +DECLARE_MTYPE(BGP_PEER); +DECLARE_MTYPE(BGP_PEER_HOST); +DECLARE_MTYPE(BGP_PEER_IFNAME); +DECLARE_MTYPE(PEER_GROUP); +DECLARE_MTYPE(PEER_GROUP_HOST); +DECLARE_MTYPE(PEER_DESC); +DECLARE_MTYPE(PEER_PASSWORD); +DECLARE_MTYPE(BGP_PEER_AF); +DECLARE_MTYPE(BGP_UPDGRP); +DECLARE_MTYPE(BGP_UPD_SUBGRP); +DECLARE_MTYPE(BGP_PACKET); +DECLARE_MTYPE(ATTR); +DECLARE_MTYPE(AS_PATH); +DECLARE_MTYPE(AS_SEG); +DECLARE_MTYPE(AS_SEG_DATA); +DECLARE_MTYPE(AS_STR); + +DECLARE_MTYPE(BGP_TABLE); +DECLARE_MTYPE(BGP_NODE); +DECLARE_MTYPE(BGP_ROUTE); +DECLARE_MTYPE(BGP_ROUTE_EXTRA); +DECLARE_MTYPE(BGP_CONN); +DECLARE_MTYPE(BGP_STATIC); +DECLARE_MTYPE(BGP_ADVERTISE_ATTR); +DECLARE_MTYPE(BGP_ADVERTISE); +DECLARE_MTYPE(BGP_SYNCHRONISE); +DECLARE_MTYPE(BGP_ADJ_IN); +DECLARE_MTYPE(BGP_ADJ_OUT); +DECLARE_MTYPE(BGP_MPATH_INFO); + +DECLARE_MTYPE(AS_LIST); +DECLARE_MTYPE(AS_FILTER); +DECLARE_MTYPE(AS_FILTER_STR); + +DECLARE_MTYPE(COMMUNITY); +DECLARE_MTYPE(COMMUNITY_VAL); +DECLARE_MTYPE(COMMUNITY_STR); + +DECLARE_MTYPE(ECOMMUNITY); +DECLARE_MTYPE(ECOMMUNITY_VAL); +DECLARE_MTYPE(ECOMMUNITY_STR); + +DECLARE_MTYPE(COMMUNITY_LIST); +DECLARE_MTYPE(COMMUNITY_LIST_NAME); +DECLARE_MTYPE(COMMUNITY_LIST_ENTRY); +DECLARE_MTYPE(COMMUNITY_LIST_CONFIG); +DECLARE_MTYPE(COMMUNITY_LIST_HANDLER); + +DECLARE_MTYPE(CLUSTER); +DECLARE_MTYPE(CLUSTER_VAL); + +DECLARE_MTYPE(BGP_PROCESS_QUEUE); +DECLARE_MTYPE(BGP_CLEAR_NODE_QUEUE); + +DECLARE_MTYPE(TRANSIT); +DECLARE_MTYPE(TRANSIT_VAL); + +DECLARE_MTYPE(BGP_DEBUG_FILTER); +DECLARE_MTYPE(BGP_DEBUG_STR); + +DECLARE_MTYPE(BGP_DISTANCE); +DECLARE_MTYPE(BGP_NEXTHOP_CACHE); +DECLARE_MTYPE(BGP_CONFED_LIST); +DECLARE_MTYPE(PEER_UPDATE_SOURCE); +DECLARE_MTYPE(PEER_CONF_IF); +DECLARE_MTYPE(BGP_DAMP_INFO); +DECLARE_MTYPE(BGP_DAMP_ARRAY); +DECLARE_MTYPE(BGP_DAMP_REUSELIST); +DECLARE_MTYPE(BGP_REGEXP); +DECLARE_MTYPE(BGP_AGGREGATE); +DECLARE_MTYPE(BGP_ADDR); +DECLARE_MTYPE(TIP_ADDR); + +DECLARE_MTYPE(BGP_REDIST); +DECLARE_MTYPE(BGP_FILTER_NAME); +DECLARE_MTYPE(BGP_DUMP_STR); +DECLARE_MTYPE(ENCAP_TLV); + +DECLARE_MTYPE(BGP_TEA_OPTIONS); +DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE); + +DECLARE_MTYPE(LCOMMUNITY); +DECLARE_MTYPE(LCOMMUNITY_STR); +DECLARE_MTYPE(LCOMMUNITY_VAL); + +DECLARE_MTYPE(BGP_EVPN_MH_INFO); +DECLARE_MTYPE(BGP_EVPN_ES); +DECLARE_MTYPE(BGP_EVPN_ES_EVI); +DECLARE_MTYPE(BGP_EVPN_ES_VRF); +DECLARE_MTYPE(BGP_EVPN_ES_VTEP); +DECLARE_MTYPE(BGP_EVPN_PATH_ES_INFO); +DECLARE_MTYPE(BGP_EVPN_ES_EVI_VTEP); + +DECLARE_MTYPE(BGP_EVPN); +DECLARE_MTYPE(BGP_EVPN_IMPORT_RT); +DECLARE_MTYPE(BGP_EVPN_VRF_IMPORT_RT); +DECLARE_MTYPE(BGP_EVPN_MACIP); + +DECLARE_MTYPE(BGP_FLOWSPEC); +DECLARE_MTYPE(BGP_FLOWSPEC_RULE); +DECLARE_MTYPE(BGP_FLOWSPEC_RULE_STR); +DECLARE_MTYPE(BGP_FLOWSPEC_COMPILED); +DECLARE_MTYPE(BGP_FLOWSPEC_NAME); +DECLARE_MTYPE(BGP_FLOWSPEC_INDEX); + +DECLARE_MTYPE(BGP_SRV6_L3VPN); +DECLARE_MTYPE(BGP_SRV6_VPN); #endif /* _QUAGGA_BGP_MEMORY_H */ diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index 721ce5b5c6..0d2f84bfc4 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -32,20 +32,20 @@ #include "bgpd/bgp_io.h" #include "bgpd/bgp_damp.h" -DEFINE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp)) +DEFINE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp)); FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, { .val_ulong = 10, .match_profile = "datacenter", }, { .val_ulong = 120 }, -) +); FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME, { .val_ulong = 9, .match_profile = "datacenter", }, { .val_ulong = 180 }, -) +); FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, { .val_ulong = 3, .match_profile = "datacenter", }, { .val_ulong = 60 }, -) +); int routing_control_plane_protocols_name_validate( struct nb_cb_create_args *args) @@ -3146,8 +3146,7 @@ int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify( return NB_OK; str2sockunion(peer_str, &su); - ret = peer_remote_as(bgp, &su, NULL, &as, as_type, AFI_IP, - SAFI_UNICAST); + ret = peer_remote_as(bgp, &su, NULL, &as, as_type); if (bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret) < 0) return NB_ERR_INCONSISTENCY; @@ -3202,8 +3201,7 @@ int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify( as = yang_dnode_get_uint32(args->dnode, NULL); str2sockunion(peer_str, &su); - ret = peer_remote_as(bgp, &su, NULL, &as, as_type, AFI_IP, - SAFI_UNICAST); + ret = peer_remote_as(bgp, &su, NULL, &as, as_type); if (bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret) < 0) return NB_ERR_INCONSISTENCY; @@ -4370,8 +4368,7 @@ int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args) "./neighbor-remote-as/remote-as"); } - if (peer_conf_interface_create(bgp, peer_str, AFI_IP, - SAFI_UNICAST, v6_only, + if (peer_conf_interface_create(bgp, peer_str, v6_only, peer_grp_str, as_type, as, args->errmsg, args->errmsg_len)) return NB_ERR_INCONSISTENCY; @@ -4440,9 +4437,9 @@ int bgp_neighbors_unnumbered_neighbor_v6only_modify( v6_only = yang_dnode_get_bool(args->dnode, NULL); - if (peer_conf_interface_create( - bgp, peer_str, AFI_IP, SAFI_UNICAST, v6_only, NULL, - AS_UNSPECIFIED, 0, args->errmsg, args->errmsg_len)) + if (peer_conf_interface_create(bgp, peer_str, v6_only, NULL, + AS_UNSPECIFIED, 0, args->errmsg, + args->errmsg_len)) return NB_ERR_INCONSISTENCY; break; @@ -5174,8 +5171,6 @@ void bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_apply_finish( int ret; as_t as = 0; struct peer *peer = NULL; - afi_t afi = AFI_IP; - safi_t safi = SAFI_UNICAST; bgp = nb_running_get_entry(args->dnode, NULL, true); peer_str = yang_dnode_get_string(args->dnode, "../interface"); @@ -5185,7 +5180,7 @@ void bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_apply_finish( peer = peer_lookup_by_conf_if(bgp, peer_str); - ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi, safi); + ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type); if (ret < 0 && !peer) { snprintf(args->errmsg, args->errmsg_len, diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 03ff27c7ca..4821ce8ddb 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -544,7 +544,7 @@ static int bgp_accept(struct thread *thread) peer1->host); peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as, - peer1->as, peer1->as_type, 0, 0, NULL); + peer1->as, peer1->as_type, NULL); hash_release(peer->bgp->peerhash, peer); hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index c6fa37fa8d..9c8d7878c5 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -194,6 +194,16 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, bnc->srte_color, bnc->bgp->name_pretty, peer); } + } else { + if (BGP_DEBUG(nht, NHT)) { + char buf[PREFIX2STR_BUFFER]; + + zlog_debug( + "Found existing bnc %s(%s) flags 0x%x ifindex %d #paths %d peer %p", + bnc_str(bnc, buf, PREFIX2STR_BUFFER), + bnc->bgp->name_pretty, bnc->flags, bnc->ifindex, + bnc->path_count, bnc->nht_info); + } } if (is_bgp_static_route) { @@ -237,6 +247,11 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); } + if (peer && (bnc->ifindex != ifindex)) { + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + bnc->ifindex = ifindex; + } if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW) { SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); @@ -454,17 +469,21 @@ static void bgp_nht_ifp_table_handle(struct bgp *bgp, bnc->last_update = bgp_clock(); bnc->change_flags = 0; + /* + * For interface based routes ( ala the v6 LL routes + * that this was written for ) the metric received + * for the connected route is 0 not 1. + */ + bnc->metric = 0; if (up) { SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); SET_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED); - bnc->metric = 1; bnc->nexthop_num = 1; } else { UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED); UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); SET_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED); bnc->nexthop_num = 0; - bnc->metric = 0; } evaluate_paths(bnc); @@ -502,6 +521,11 @@ static int bgp_nht_ifp_initial(struct thread *thread) if (!ifp) return 0; + if (BGP_DEBUG(nht, NHT)) + zlog_debug( + "Handle NHT initial update for Intf %s(%d) status %s", + ifp->name, ifp->ifindex, if_is_up(ifp) ? "up" : "down"); + if (if_is_up(ifp)) bgp_nht_ifp_up(ifp); else diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index e08f19fb45..24df324633 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -68,12 +68,12 @@ DEFINE_HOOK(bgp_packet_dump, (struct peer *peer, uint8_t type, bgp_size_t size, struct stream *s), - (peer, type, size, s)) + (peer, type, size, s)); DEFINE_HOOK(bgp_packet_send, (struct peer *peer, uint8_t type, bgp_size_t size, struct stream *s), - (peer, type, size, s)) + (peer, type, size, s)); /** * Sets marker and type fields for a BGP message. diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h index d32f091d0c..d69c862304 100644 --- a/bgpd/bgp_packet.h +++ b/bgpd/bgp_packet.h @@ -26,12 +26,12 @@ DECLARE_HOOK(bgp_packet_dump, (struct peer *peer, uint8_t type, bgp_size_t size, struct stream *s), - (peer, type, size, s)) + (peer, type, size, s)); DECLARE_HOOK(bgp_packet_send, (struct peer *peer, uint8_t type, bgp_size_t size, struct stream *s), - (peer, type, size, s)) + (peer, type, size, s)); #define BGP_NLRI_LENGTH 1U #define BGP_TOTAL_ATTR_LEN 2U diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 171522f8ae..2c6c2c3861 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -37,12 +37,12 @@ #include "bgpd/bgp_flowspec_private.h" #include "bgpd/bgp_errors.h" -DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH_ENTRY, "PBR match entry") -DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH, "PBR match") -DEFINE_MTYPE_STATIC(BGPD, PBR_ACTION, "PBR action") -DEFINE_MTYPE_STATIC(BGPD, PBR_RULE, "PBR rule") -DEFINE_MTYPE_STATIC(BGPD, PBR, "BGP PBR Context") -DEFINE_MTYPE_STATIC(BGPD, PBR_VALMASK, "BGP PBR Val Mask Value") +DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH_ENTRY, "PBR match entry"); +DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH, "PBR match"); +DEFINE_MTYPE_STATIC(BGPD, PBR_ACTION, "PBR action"); +DEFINE_MTYPE_STATIC(BGPD, PBR_RULE, "PBR rule"); +DEFINE_MTYPE_STATIC(BGPD, PBR, "BGP PBR Context"); +DEFINE_MTYPE_STATIC(BGPD, PBR_VALMASK, "BGP PBR Val Mask Value"); /* chain strings too long to fit in one line */ #define FSPEC_ACTION_EXCEED_LIMIT "flowspec actions exceeds limit" diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 87fd5f28ca..124a477248 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -95,12 +95,12 @@ DEFINE_HOOK(bgp_snmp_update_stats, (struct bgp_node *rn, struct bgp_path_info *pi, bool added), - (rn, pi, added)) + (rn, pi, added)); DEFINE_HOOK(bgp_rpki_prefix_status, (struct peer *peer, struct attr *attr, const struct prefix *prefix), - (peer, attr, prefix)) + (peer, attr, prefix)); /* Extern from bgp_dump.c */ extern const char *bgp_origin_str[]; @@ -126,7 +126,7 @@ static const struct message bgp_pmsi_tnltype_str[] = { DEFINE_HOOK(bgp_process, (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn, struct peer *peer, bool withdraw), - (bgp, afi, safi, bn, peer, withdraw)) + (bgp, afi, safi, bn, peer, withdraw)); /** Test if path is suppressed. */ static bool bgp_path_suppressed(struct bgp_path_info *pi) diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 766e5ade92..1dec99f085 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -550,7 +550,7 @@ static inline bool bgp_check_advertise(struct bgp *bgp, struct bgp_dest *dest) DECLARE_HOOK(bgp_process, (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn, struct peer *peer, bool withdraw), - (bgp, afi, safi, bn, peer, withdraw)) + (bgp, afi, safi, bn, peer, withdraw)); /* BGP show options */ #define BGP_SHOW_OPT_JSON (1 << 0) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 42951efb01..9344384956 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -60,8 +60,8 @@ #include "bgpd/bgp_rpki_clippy.c" #endif -DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server") -DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group") +DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server"); +DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group"); #define RPKI_VALID 1 #define RPKI_NOTFOUND 2 @@ -1471,4 +1471,5 @@ static void install_cli_commands(void) FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6", .description = "Enable RPKI support for FRR.", - .init = bgp_rpki_module_init) + .init = bgp_rpki_module_init, +); diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c index 71868abc5f..bc26314b50 100644 --- a/bgpd/bgp_snmp.c +++ b/bgpd/bgp_snmp.c @@ -914,4 +914,5 @@ static int bgp_snmp_module_init(void) FRR_MODULE_SETUP(.name = "bgpd_snmp", .version = FRR_VERSION, .description = "bgpd AgentX SNMP module", - .init = bgp_snmp_module_init) + .init = bgp_snmp_module_init, +); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4b012430d9..a016265d6e 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -86,49 +86,49 @@ FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK, .match_version = "< 7.4", }, { .val_bool = true }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_SHOW_NEXTHOP_HOSTNAME, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_DETERMINISTIC_MED, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, { .val_ulong = 10, .match_profile = "datacenter", }, { .val_ulong = 120 }, -) +); FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME, { .val_ulong = 9, .match_profile = "datacenter", }, { .val_ulong = 180 }, -) +); FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, { .val_ulong = 3, .match_profile = "datacenter", }, { .val_ulong = 60 }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_EBGP_REQUIRES_POLICY, { .val_bool = false, .match_profile = "datacenter", }, { .val_bool = false, .match_version = "< 7.4", }, { .val_bool = true }, -) +); FRR_CFG_DEFAULT_BOOL(BGP_SUPPRESS_DUPLICATES, { .val_bool = false, .match_version = "< 7.6", }, { .val_bool = true }, -) +); DEFINE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), - (bgp, vty)) -DEFINE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp)) + (bgp, vty)); +DEFINE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp)); #define GR_NO_OPER \ "The Graceful Restart No Operation was executed as cmd same as previous one." @@ -3727,6 +3727,29 @@ DEFPY (no_bgp_bestpath_bw, return CMD_SUCCESS; } +/* "no bgp default ipv6-unicast". */ +DEFUN(no_bgp_default_ipv6_unicast, no_bgp_default_ipv6_unicast_cmd, + "no bgp default ipv6-unicast", NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "Activate ipv6-unicast for a peer by default\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + UNSET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6); + return CMD_SUCCESS; +} + +DEFUN(bgp_default_ipv6_unicast, bgp_default_ipv6_unicast_cmd, + "bgp default ipv6-unicast", + "BGP specific commands\n" + "Configure BGP defaults\n" + "Activate ipv6-unicast for a peer by default\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + SET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6); + return CMD_SUCCESS; +} + /* "no bgp default ipv4-unicast". */ DEFUN (no_bgp_default_ipv4_unicast, no_bgp_default_ipv4_unicast_cmd, @@ -4368,10 +4391,10 @@ DEFUN_YANG(neighbor_remote_as, return nb_cli_apply_changes(vty, base_xpath); } -int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, afi_t afi, - safi_t safi, bool v6only, - const char *peer_group_name, int as_type, - as_t as, char *errmsg, size_t errmsg_len) +int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, + bool v6only, const char *peer_group_name, + int as_type, as_t as, char *errmsg, + size_t errmsg_len) { struct peer *peer; struct peer_group *group; @@ -4388,16 +4411,10 @@ int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, afi_t afi, peer = peer_lookup_by_conf_if(bgp, conf_if); if (peer) { if (as_type != AS_UNSPECIFIED) - ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type, - afi, safi); + ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type); } else { - if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4) - && afi == AFI_IP && safi == SAFI_UNICAST) - peer = peer_create(NULL, conf_if, bgp, bgp->as, as, - as_type, 0, 0, NULL); - else - peer = peer_create(NULL, conf_if, bgp, bgp->as, as, - as_type, afi, safi, NULL); + peer = peer_create(NULL, conf_if, bgp, bgp->as, as, as_type, + NULL); if (!peer) { snprintf(errmsg, errmsg_len, @@ -6139,10 +6156,28 @@ DEFUN_YANG (neighbor_send_community, "Send Community attribute to this neighbor\n") { int idx_peer = 1; + char *peer_str = argv[idx_peer]->arg; + char base_xpath[XPATH_MAXLEN]; + char af_xpath[XPATH_MAXLEN]; + char std_xpath[XPATH_MAXLEN]; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); - return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty), - bgp_node_safi(vty), - PEER_FLAG_SEND_COMMUNITY); + snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, + yang_afi_safi_value2identity(afi, safi)); + + if (peer_and_group_lookup_nb(vty, peer_str, base_xpath, + sizeof(base_xpath), af_xpath) + < 0) + return CMD_WARNING_CONFIG_FAILED; + + snprintf(std_xpath, sizeof(std_xpath), + "./%s/send-community/send-community", + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, std_xpath, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(neighbor_send_community, neighbor_send_community_hidden_cmd, @@ -6159,10 +6194,28 @@ DEFUN_YANG (no_neighbor_send_community, "Send Community attribute to this neighbor\n") { int idx_peer = 2; + char *peer_str = argv[idx_peer]->arg; + char base_xpath[XPATH_MAXLEN]; + char af_xpath[XPATH_MAXLEN]; + char std_xpath[XPATH_MAXLEN]; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); - return peer_af_flag_unset_vty(vty, argv[idx_peer]->arg, - bgp_node_afi(vty), bgp_node_safi(vty), - PEER_FLAG_SEND_COMMUNITY); + snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, + yang_afi_safi_value2identity(afi, safi)); + + if (peer_and_group_lookup_nb(vty, peer_str, base_xpath, + sizeof(base_xpath), af_xpath) + < 0) + return CMD_WARNING_CONFIG_FAILED; + + snprintf(std_xpath, sizeof(std_xpath), + "./%s/send-community/send-community", + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, std_xpath, NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(no_neighbor_send_community, no_neighbor_send_community_hidden_cmd, @@ -14358,7 +14411,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, "\n"); /* BFD information. */ - bgp_bfd_show_info(vty, p, use_json, json_neigh); + if (p->bfd_config) + bgp_bfd_show_info(vty, p, json_neigh); if (use_json) { if (p->conf_if) /* Configured interface name. */ @@ -16765,11 +16819,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, peer->rtt_expected, peer->rtt_keepalive_conf); /* bfd */ - if (peer->bfd_info) { - if (!peer_group_active(peer) || !g_peer->bfd_info) { - bgp_bfd_peer_config_write(vty, peer, addr); - } - } + if (peer->bfd_config) + bgp_bfd_peer_config_write(vty, peer, addr); /* password */ if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD)) @@ -16966,18 +17017,36 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, } } else { if (peer->afc[afi][safi]) { - if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { - if (CHECK_FLAG(bgp->flags, - BGP_FLAG_NO_DEFAULT_IPV4)) { + if ((afi == AFI_IP || afi == AFI_IP6) + && safi == SAFI_UNICAST) { + if (afi == AFI_IP + && CHECK_FLAG(bgp->flags, + BGP_FLAG_NO_DEFAULT_IPV4)) { + vty_out(vty, " neighbor %s activate\n", + addr); + } else if (afi == AFI_IP6 + && !CHECK_FLAG( + bgp->flags, + BGP_FLAG_DEFAULT_IPV6)) { vty_out(vty, " neighbor %s activate\n", addr); } - } else + } else { vty_out(vty, " neighbor %s activate\n", addr); + } } else { - if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { - if (!CHECK_FLAG(bgp->flags, - BGP_FLAG_NO_DEFAULT_IPV4)) { + if ((afi == AFI_IP || afi == AFI_IP6) + && safi == SAFI_UNICAST) { + if (afi == AFI_IP + && !CHECK_FLAG(bgp->flags, + BGP_FLAG_NO_DEFAULT_IPV4)) { + vty_out(vty, + " no neighbor %s activate\n", + addr); + } else if (afi == AFI_IP6 + && CHECK_FLAG( + bgp->flags, + BGP_FLAG_DEFAULT_IPV6)) { vty_out(vty, " no neighbor %s activate\n", addr); @@ -17411,6 +17480,10 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4)) vty_out(vty, " no bgp default ipv4-unicast\n"); + /* BGP default ipv6-unicast. */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6)) + vty_out(vty, " bgp default ipv6-unicast\n"); + /* BGP default local-preference. */ if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) vty_out(vty, " bgp default local-preference %u\n", @@ -18081,6 +18154,10 @@ void bgp_vty_init(void) install_element(BGP_NODE, &no_bgp_default_ipv4_unicast_cmd); install_element(BGP_NODE, &bgp_default_ipv4_unicast_cmd); + /* "no bgp default ipv6-unicast" commands. */ + install_element(BGP_NODE, &no_bgp_default_ipv6_unicast_cmd); + install_element(BGP_NODE, &bgp_default_ipv6_unicast_cmd); + /* "bgp network import-check" commands. */ install_element(BGP_NODE, &bgp_network_import_check_cmd); install_element(BGP_NODE, &bgp_network_import_check_exact_cmd); diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 85619dd074..251bdc3fe3 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -205,9 +205,9 @@ extern int peer_local_interface_cfg(struct bgp *bgp, const char *ip_str, const char *str, char *errmsg, size_t errmsg_len); extern int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, - afi_t afi, safi_t safi, bool v6only, - const char *peer_group_name, int as_type, - as_t as, char *errmsg, size_t errmsg_len); + bool v6only, const char *peer_group_name, + int as_type, as_t as, char *errmsg, + size_t errmsg_len); extern int peer_flag_modify_nb(struct bgp *bgp, const char *ip_str, struct peer *peer, uint32_t flag, bool set, char *errmsg, size_t errmsg_len); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index c554332255..0a12e719ce 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -69,7 +69,7 @@ struct zclient *zclient = NULL; /* hook to indicate vrf status change for SNMP */ DEFINE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp), - (bgp, ifp)) + (bgp, ifp)); /* Can we install into zebra? */ static inline bool bgp_install_info_to_zebra(struct bgp *bgp) @@ -283,20 +283,9 @@ static int bgp_ifp_down(struct interface *ifp) if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) { for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { -#if defined(HAVE_CUMULUS) - /* Take down directly connected EBGP peers as well as - * 1-hop BFD - * tracked (directly connected) IBGP peers. - */ - if ((peer->ttl != BGP_DEFAULT_TTL) - && (peer->gtsm_hops != BGP_GTSM_HOPS_CONNECTED) - && (!peer->bfd_info - || bgp_bfd_is_peer_multihop(peer))) -#else - /* Take down directly connected EBGP peers */ + /* Take down directly connected peers. */ if ((peer->ttl != BGP_DEFAULT_TTL) && (peer->gtsm_hops != BGP_GTSM_HOPS_CONNECTED)) -#endif continue; if (ifp == peer->nexthop.ifp) { diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d51ce817d1..d37b9fa48c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -93,10 +93,10 @@ DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)"); DEFINE_MTYPE_STATIC(BGPD, BGP_EVPN_INFO, "BGP EVPN instance information"); -DEFINE_QOBJ_TYPE(bgp_master) -DEFINE_QOBJ_TYPE(bgp) -DEFINE_QOBJ_TYPE(peer) -DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)) +DEFINE_QOBJ_TYPE(bgp_master); +DEFINE_QOBJ_TYPE(bgp); +DEFINE_QOBJ_TYPE(peer); +DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)); /* BGP process wide configuration. */ static struct bgp_master bgp_master; @@ -1161,7 +1161,9 @@ static void peer_free(struct peer *peer) XFREE(MTYPE_PEER_CONF_IF, peer->conf_if); - bfd_info_free(&(peer->bfd_info)); + /* Remove BFD configuration. */ + if (peer->bfd_config) + bgp_peer_remove_bfd_config(peer); FOREACH_AFI_SAFI (afi, safi) bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE); @@ -1468,8 +1470,10 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src) for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) { paf = peer_src->peer_af_array[afidx]; - if (paf != NULL) - peer_af_create(peer_dst, paf->afi, paf->safi); + if (paf != NULL) { + if (!peer_af_find(peer_dst, paf->afi, paf->safi)) + peer_af_create(peer_dst, paf->afi, paf->safi); + } } /* update-source apply */ @@ -1683,12 +1687,13 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp) */ struct peer *peer_create(union sockunion *su, const char *conf_if, struct bgp *bgp, as_t local_as, as_t remote_as, - int as_type, afi_t afi, safi_t safi, - struct peer_group *group) + int as_type, struct peer_group *group) { int active; struct peer *peer; char buf[SU_ADDRSTRLEN]; + afi_t afi; + safi_t safi; peer = peer_new(bgp); if (conf_if) { @@ -1747,9 +1752,23 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); - if (afi && safi) { - peer->afc[afi][safi] = 1; - peer_af_create(peer, afi, safi); + /* If address family is IPv4 and `bgp default ipv4-unicast` (default), + * then activate the neighbor for this AF. + * If address family is IPv6 and `bgp default ipv6-unicast` + * (non-default), then activate the neighbor for this AF. + */ + FOREACH_AFI_SAFI (afi, safi) { + if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) { + if ((afi == AFI_IP + && !CHECK_FLAG(bgp->flags, + BGP_FLAG_NO_DEFAULT_IPV4)) + || (afi == AFI_IP6 + && CHECK_FLAG(bgp->flags, + BGP_FLAG_DEFAULT_IPV6))) { + peer->afc[afi][safi] = 1; + peer_af_create(peer, afi, safi); + } + } } /* auto shutdown if configured */ @@ -1878,7 +1897,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified) /* If peer does not exist, create new one. If peer already exists, set AS number to the peer. */ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if, - as_t *as, int as_type, afi_t afi, safi_t safi) + as_t *as, int as_type) { struct peer *peer; as_t local_as; @@ -1946,16 +1965,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if, else local_as = bgp->as; - /* If this is IPv4 unicast configuration and "no bgp default - ipv4-unicast" is specified. */ - - if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4) - && afi == AFI_IP && safi == SAFI_UNICAST) - peer_create(su, conf_if, bgp, local_as, *as, as_type, 0, - 0, NULL); - else - peer_create(su, conf_if, bgp, local_as, *as, as_type, - afi, safi, NULL); + peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL); } return 0; @@ -2386,7 +2396,9 @@ int peer_delete(struct peer *peer) SET_FLAG(peer->flags, PEER_FLAG_DELETE); - bgp_bfd_deregister_peer(peer); + /* Remove BFD settings. */ + if (peer->bfd_config) + bgp_peer_remove_bfd_config(peer); /* Delete peer route flap dampening configuration. This needs to happen * before removing the peer from peer groups. @@ -2562,6 +2574,8 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name) group->conf = peer_new(bgp); if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4)) group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; + if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6)) + group->conf->afc[AFI_IP6][SAFI_UNICAST] = 1; XFREE(MTYPE_BGP_PEER_HOST, group->conf->host); group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name); group->conf->group = group; @@ -2668,7 +2682,11 @@ static void peer_group2peer_config_copy(struct peer_group *group, /* Update GR flags for the peer. */ bgp_peer_gr_flags_update(peer); - bgp_bfd_peer_group2peer_copy(conf, peer); + /* Apply BFD settings from group to peer if it exists. */ + if (conf->bfd_config) { + bgp_peer_configure_bfd(peer, false); + bgp_peer_config_apply(peer, group); + } } /* Peer group's remote AS configuration. */ @@ -2758,7 +2776,8 @@ int peer_group_delete(struct peer_group *group) XFREE(MTYPE_PEER_GROUP_HOST, group->name); group->name = NULL; - bfd_info_free(&(group->conf->bfd_info)); + if (group->conf->bfd_config) + bgp_peer_remove_bfd_config(group->conf); group->conf->group = NULL; peer_delete(group->conf); @@ -2996,7 +3015,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, } peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as, - group->conf->as_type, 0, 0, group); + group->conf->as_type, group); peer = peer_lock(peer); /* group->peer list reference */ listnode_add(group->peer, peer); @@ -3008,7 +3027,10 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, FOREACH_AFI_SAFI (afi, safi) { if (group->conf->afc[afi][safi]) { peer->afc[afi][safi] = 1; - peer_af_create(peer, afi, safi); + + if (!peer_af_find(peer, afi, safi)) + peer_af_create(peer, afi, safi); + peer_group2peer_config_copy_af(group, peer, afi, safi); } else if (peer->afc[afi][safi]) @@ -3807,7 +3829,7 @@ struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp, /* Create peer first; we've already checked group config is valid. */ peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as, - group->conf->as_type, 0, 0, group); + group->conf->as_type, group); if (!peer) return NULL; @@ -7687,7 +7709,7 @@ void bgp_init(unsigned short instance) bgp_clist = community_list_init(); /* BFD init */ - bgp_bfd_init(); + bgp_bfd_init(bm->master); bgp_lp_vty_init(); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 3f5ec07796..6270542178 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -45,6 +45,8 @@ #include "bgp_nexthop.h" #include "bgp_damp.h" +#include "lib/bfd.h" + #define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */ #define BGP_PEER_MAX_HASH_SIZE 16384 @@ -175,9 +177,9 @@ struct bgp_master { #define BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA (1 << 1) bool terminating; /* global flag that sigint terminate seen */ - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(bgp_master) +DECLARE_QOBJ_TYPE(bgp_master); /* BGP route-map structure. */ struct bgp_rmap { @@ -477,6 +479,7 @@ struct bgp { #define BGP_FLAG_SHUTDOWN (1 << 27) #define BGP_FLAG_SUPPRESS_FIB_PENDING (1 << 28) #define BGP_FLAG_SUPPRESS_DUPLICATES (1 << 29) +#define BGP_FLAG_DEFAULT_IPV6 (1 << 30) enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE] [BGP_GLOBAL_GR_EVENT_CMD]; @@ -710,14 +713,14 @@ struct bgp { /* BGP route flap dampening configuration */ struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(bgp) +DECLARE_QOBJ_TYPE(bgp); -DECLARE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)) +DECLARE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)); DECLARE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), - (bgp, vty)) + (bgp, vty)); /* Thread callback information */ struct afi_safi_info { @@ -1557,8 +1560,29 @@ struct peer { #define PEER_RMAP_TYPE_EXPORT (1U << 7) /* neighbor route-map export */ #define PEER_RMAP_TYPE_AGGREGATE (1U << 8) /* aggregate-address route-map */ - /* peer specific BFD information */ - struct bfd_info *bfd_info; + /** Peer overwrite configuration. */ + struct bfd_session_config { + /** + * Manual configuration bit. + * + * This flag only makes sense for real peers (and not groups), + * it keeps track if the user explicitly configured BFD for a + * peer. + */ + bool manual; + /** Control Plane Independent. */ + bool cbit; + /** Detection multiplier. */ + uint8_t detection_multiplier; + /** Minimum required RX interval. */ + uint32_t min_rx; + /** Minimum required TX interval. */ + uint32_t min_tx; + /** Profile name. */ + char profile[BFD_PROFILE_NAME_LEN]; + /** Peer BFD session */ + struct bfd_session_params *session; + } * bfd_config; /* hostname and domainname advertised by host */ char *hostname; @@ -1574,9 +1598,9 @@ struct peer { bool advmap_config_change[AFI_MAX][SAFI_MAX]; bool advmap_table_change; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(peer) +DECLARE_QOBJ_TYPE(peer); /* Inherit peer attribute from peer-group. */ #define PEER_ATTR_INHERIT(peer, group, attr) \ @@ -1922,8 +1946,7 @@ extern bool peer_active(struct peer *); extern bool peer_active_nego(struct peer *); extern void bgp_recalculate_all_bestpaths(struct bgp *bgp); extern struct peer *peer_create(union sockunion *, const char *, struct bgp *, - as_t, as_t, int, afi_t, safi_t, - struct peer_group *); + as_t, as_t, int, struct peer_group *); extern struct peer *peer_create_accept(struct bgp *); extern void peer_xfer_config(struct peer *dst, struct peer *src); extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, @@ -1991,7 +2014,7 @@ extern bool bgp_update_delay_configured(struct bgp *); extern int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi); extern void peer_as_change(struct peer *, as_t, int); extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *, - int, afi_t, safi_t); + int); extern int peer_group_remote_as(struct bgp *, const char *, as_t *, int); extern int peer_delete(struct peer *peer); extern void peer_notify_unconfig(struct peer *peer); @@ -2364,17 +2387,17 @@ extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, /* Hooks */ DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp), - (bgp, ifp)) -DECLARE_HOOK(peer_status_changed, (struct peer *peer), (peer)) -DECLARE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp)) -DECLARE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp)) + (bgp, ifp)); +DECLARE_HOOK(peer_status_changed, (struct peer *peer), (peer)); +DECLARE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp)); +DECLARE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp)); DECLARE_HOOK(bgp_snmp_update_stats, (struct bgp_node *rn, struct bgp_path_info *pi, bool added), - (rn, pi, added)) + (rn, pi, added)); DECLARE_HOOK(bgp_rpki_prefix_status, (struct peer * peer, struct attr *attr, const struct prefix *prefix), - (peer, attr, prefix)) + (peer, attr, prefix)); void peer_nsf_stop(struct peer *peer); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 88c92f7954..cc64261388 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -52,36 +52,36 @@ #undef BGP_VNC_DEBUG_MATCH_GROUP -DEFINE_MGROUP(RFAPI, "rfapi") -DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic") -DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor") -DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap") -DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop") -DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option") -DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option") -DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw") -DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName") -DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data") -DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info") -DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address") -DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag") -DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra") -DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info") -DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr") -DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue") -DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route") -DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option") -DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet") - -DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg) -DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg) +DEFINE_MGROUP(RFAPI, "rfapi"); +DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration"); +DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration"); +DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration"); +DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration"); +DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic"); +DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor"); +DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table"); +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN"); +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap"); +DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop"); +DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option"); +DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option"); +DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw"); +DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName"); +DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data"); +DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info"); +DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address"); +DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag"); +DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra"); +DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info"); +DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr"); +DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue"); +DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route"); +DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option"); +DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix"); +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet"); + +DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg); +DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg); /*********************************************************************** * RFAPI Support ***********************************************************************/ diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h index f1548a6173..ef97419c4d 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.h +++ b/bgpd/rfapi/bgp_rfapi_cfg.h @@ -35,9 +35,9 @@ struct rfapi_l2_group_cfg { struct ecommunity *rt_export_list; void *rfp_cfg; /* rfp owned group config */ - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg) +DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg); typedef enum { RFAPI_GROUP_CFG_NVE = 1, @@ -108,9 +108,9 @@ struct rfapi_nve_group_cfg { /* for VRF type groups */ uint32_t label; struct rfapi_descriptor *rfd; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg) +DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg); struct rfapi_rfg_name { struct rfapi_nve_group_cfg *rfg; diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h index af56367955..e7825e8bfc 100644 --- a/bgpd/rfapi/rfapi_private.h +++ b/bgpd/rfapi/rfapi_private.h @@ -367,33 +367,33 @@ extern int rfapi_extract_l2o( */ extern time_t rfapi_time(time_t *t); -DECLARE_MGROUP(RFAPI) -DECLARE_MTYPE(RFAPI_CFG) -DECLARE_MTYPE(RFAPI_GROUP_CFG) -DECLARE_MTYPE(RFAPI_L2_CFG) -DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG) -DECLARE_MTYPE(RFAPI) -DECLARE_MTYPE(RFAPI_DESC) -DECLARE_MTYPE(RFAPI_IMPORTTABLE) -DECLARE_MTYPE(RFAPI_MONITOR) -DECLARE_MTYPE(RFAPI_MONITOR_ENCAP) -DECLARE_MTYPE(RFAPI_NEXTHOP) -DECLARE_MTYPE(RFAPI_VN_OPTION) -DECLARE_MTYPE(RFAPI_UN_OPTION) -DECLARE_MTYPE(RFAPI_WITHDRAW) -DECLARE_MTYPE(RFAPI_RFG_NAME) -DECLARE_MTYPE(RFAPI_ADB) -DECLARE_MTYPE(RFAPI_ETI) -DECLARE_MTYPE(RFAPI_NVE_ADDR) -DECLARE_MTYPE(RFAPI_PREFIX_BAG) -DECLARE_MTYPE(RFAPI_IT_EXTRA) -DECLARE_MTYPE(RFAPI_INFO) -DECLARE_MTYPE(RFAPI_ADDR) -DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE) -DECLARE_MTYPE(RFAPI_RECENT_DELETE) -DECLARE_MTYPE(RFAPI_L2ADDR_OPT) -DECLARE_MTYPE(RFAPI_AP) -DECLARE_MTYPE(RFAPI_MONITOR_ETH) +DECLARE_MGROUP(RFAPI); +DECLARE_MTYPE(RFAPI_CFG); +DECLARE_MTYPE(RFAPI_GROUP_CFG); +DECLARE_MTYPE(RFAPI_L2_CFG); +DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG); +DECLARE_MTYPE(RFAPI); +DECLARE_MTYPE(RFAPI_DESC); +DECLARE_MTYPE(RFAPI_IMPORTTABLE); +DECLARE_MTYPE(RFAPI_MONITOR); +DECLARE_MTYPE(RFAPI_MONITOR_ENCAP); +DECLARE_MTYPE(RFAPI_NEXTHOP); +DECLARE_MTYPE(RFAPI_VN_OPTION); +DECLARE_MTYPE(RFAPI_UN_OPTION); +DECLARE_MTYPE(RFAPI_WITHDRAW); +DECLARE_MTYPE(RFAPI_RFG_NAME); +DECLARE_MTYPE(RFAPI_ADB); +DECLARE_MTYPE(RFAPI_ETI); +DECLARE_MTYPE(RFAPI_NVE_ADDR); +DECLARE_MTYPE(RFAPI_PREFIX_BAG); +DECLARE_MTYPE(RFAPI_IT_EXTRA); +DECLARE_MTYPE(RFAPI_INFO); +DECLARE_MTYPE(RFAPI_ADDR); +DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE); +DECLARE_MTYPE(RFAPI_RECENT_DELETE); +DECLARE_MTYPE(RFAPI_L2ADDR_OPT); +DECLARE_MTYPE(RFAPI_AP); +DECLARE_MTYPE(RFAPI_MONITOR_ETH); /* diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 4614363bf0..3991f7d1ed 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -220,7 +220,7 @@ bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(US bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS) bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c bgpd/bgp_mplsvpn_snmp.c -bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 bgpd_bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic bgpd_bgpd_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/configure.ac b/configure.ac index b034fab50c..f9516e559f 100755 --- a/configure.ac +++ b/configure.ac @@ -288,11 +288,17 @@ if test "$enable_clang_coverage" = "yes"; then fi if test "$enable_scripting" = "yes"; then - AX_PROG_LUA([5.3]) - AX_LUA_HEADERS + AX_PROG_LUA([5.3], [5.4], [], [ + AC_MSG_ERROR([Lua 5.3 is required to build with Lua support. No other version is supported.]) + ]) + AX_LUA_HEADERS([], [ + AC_MSG_ERROR([Lua 5.3 headers are required to build with Lua support. No other version is supported.]) + ]) AX_LUA_LIBS([ - AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting]) - LIBS="$LIBS $LUA_LIB" + AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting]) + LIBS="$LIBS $LUA_LIB" + ], [ + AC_MSG_ERROR([Lua 5.3 libraries are required to build with Lua support. No other version is supported.]) ]) fi @@ -301,6 +307,7 @@ if test "$enable_dev_build" = "yes"; then if test "$orig_cflags" = ""; then AC_C_FLAG([-g3]) AC_C_FLAG([-O0]) + AC_C_FLAG([-ggdb3]) fi else if test "$orig_cflags" = ""; then @@ -308,6 +315,7 @@ else AC_C_FLAG([-O2]) fi fi + AM_CONDITIONAL([DEV_BUILD], [test "$enable_dev_build" = "yes"]) dnl always want these CFLAGS diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst index ffc05a6841..58d72e2891 100644 --- a/doc/developer/building-frr-for-ubuntu2004.rst +++ b/doc/developer/building-frr-for-ubuntu2004.rst @@ -27,7 +27,7 @@ ubuntu apt repositories; in order to install it: .. code-block:: shell - curl https://bootstrap.pypa.io/2.7/get-pip.py --output get-pip.py + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py sudo python2 ./get-pip.py # And verify the installation diff --git a/doc/developer/hooks.rst b/doc/developer/hooks.rst index 10fe6b9c43..b37a4aeea7 100644 --- a/doc/developer/hooks.rst +++ b/doc/developer/hooks.rst @@ -15,13 +15,13 @@ Example: :caption: mydaemon.h #include "hook.h" - DECLARE_HOOK(some_update_event, (struct eventinfo *info), (info)) + DECLARE_HOOK(some_update_event, (struct eventinfo *info), (info)); .. code-block:: c :caption: mydaemon.c #include "mydaemon.h" - DEFINE_HOOK(some_update_event, (struct eventinfo *info), (info)) + DEFINE_HOOK(some_update_event, (struct eventinfo *info), (info)); ... hook_call(some_update_event, info); @@ -110,9 +110,9 @@ Definition .. code-block:: c - DECLARE_HOOK(foo, (), ()) - DECLARE_HOOK(bar, (int arg), (arg)) - DECLARE_HOOK(baz, (const void *x, in_addr_t y), (x, y)) + DECLARE_HOOK(foo, (), ()); + DECLARE_HOOK(bar, (int arg), (arg)); + DECLARE_HOOK(baz, (const void *x, in_addr_t y), (x, y)); .. c:macro:: DEFINE_HOOK(name, arglist, passlist) diff --git a/doc/developer/lists.rst b/doc/developer/lists.rst index 28b21533c0..86db788c0e 100644 --- a/doc/developer/lists.rst +++ b/doc/developer/lists.rst @@ -140,7 +140,7 @@ The common setup pattern will look like this: #include <typesafe.h> - PREDECL_XXX(Z) + PREDECL_XXX(Z); struct item { int otherdata; struct Z_item mylistitem; @@ -149,20 +149,20 @@ The common setup pattern will look like this: struct Z_head mylisthead; /* unsorted: */ - DECLARE_XXX(Z, struct item, mylistitem) + DECLARE_XXX(Z, struct item, mylistitem); /* sorted, items that compare as equal cannot be added to list */ int compare_func(const struct item *a, const struct item *b); - DECLARE_XXX_UNIQ(Z, struct item, mylistitem, compare_func) + DECLARE_XXX_UNIQ(Z, struct item, mylistitem, compare_func); /* sorted, items that compare as equal can be added to list */ int compare_func(const struct item *a, const struct item *b); - DECLARE_XXX_NONUNIQ(Z, struct item, mylistitem, compare_func) + DECLARE_XXX_NONUNIQ(Z, struct item, mylistitem, compare_func); /* hash tables: */ int compare_func(const struct item *a, const struct item *b); uint32_t hash_func(const struct item *a); - DECLARE_XXX(Z, struct item, mylistitem, compare_func, hash_func) + DECLARE_XXX(Z, struct item, mylistitem, compare_func, hash_func); ``XXX`` is replaced with the name of the data structure, e.g. ``SKIPLIST`` or ``ATOMLIST``. The ``DECLARE_XXX`` invocation can either occur in a `.h` diff --git a/doc/developer/memtypes.rst b/doc/developer/memtypes.rst index 952b316ea0..08dad7fb68 100644 --- a/doc/developer/memtypes.rst +++ b/doc/developer/memtypes.rst @@ -15,15 +15,15 @@ Example: .. code-block:: c :caption: mydaemon.h - DECLARE_MGROUP(MYDAEMON) - DECLARE_MTYPE(MYNEIGHBOR) + DECLARE_MGROUP(MYDAEMON); + DECLARE_MTYPE(MYNEIGHBOR); .. code-block:: c :caption: mydaemon.c - DEFINE_MGROUP( MYDAEMON, "My daemon's memory") - DEFINE_MTYPE( MYDAEMON, MYNEIGHBOR, "Neighbor entry") - DEFINE_MTYPE_STATIC(MYDAEMON, MYNEIGHBORNAME, "Neighbor name") + DEFINE_MGROUP( MYDAEMON, "My daemon's memory"); + DEFINE_MTYPE( MYDAEMON, MYNEIGHBOR, "Neighbor entry"); + DEFINE_MTYPE_STATIC(MYDAEMON, MYNEIGHBORNAME, "Neighbor name"); struct neigh *neighbor_new(const char *name) { diff --git a/doc/developer/modules.rst b/doc/developer/modules.rst index 02330ddfe4..e95f8a1b4a 100644 --- a/doc/developer/modules.rst +++ b/doc/developer/modules.rst @@ -76,7 +76,7 @@ Basic boilerplate: .version = "0.0", .description = "my module", .init = module_init, - ) + ); The ``frr_late_init`` hook will be called after the daemon has finished its other startup and is about to enter the main event loop; this is the diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index e684b9c8a8..2a6d2dda34 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -60,6 +60,7 @@ following steps will get you there on Ubuntu 20.04. .. code:: shell + apt install libsnmp-dev apt install snmpd snmp apt install snmp-mibs-downloader download-mibs diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index 7d136b183e..6f797f7cc1 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -313,6 +313,11 @@ The following commands are available inside the interface configuration node. a new neighbor is found a BFD peer is created to monitor the link status for fast convergence. +.. clicmd:: ip ospf bfd profile BFDPROF + + Same as command ``ip ospf bfd``, but applies the BFD profile to the sessions + it creates or that already exist. + .. _bfd-ospf6-peer-config: diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 3f8dafa09d..61ed4d3e09 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1087,6 +1087,9 @@ IPv6 Support be used in a setup with two upstreams where each of the upstreams should only receive either IPv4 or IPv6 annocuments. + Using the ``bgp default ipv6-unicast`` configuration, IPv6 unicast + address family is enabled by default for all new neighbors. + .. _bgp-route-aggregation: @@ -1417,6 +1420,12 @@ Configuring Peers This command is deprecated and may be removed in a future release. Its use should be avoided. +.. clicmd:: neighbor PEER interface remote-as <internal|external|ASN> + + Configure an unnumbered BGP peer. ``PEER`` should be an interface name. The + session will be established via IPv6 link locals. Use ``internal`` for iBGP + and ``external`` for eBGP sessions, or specify an ASN if you wish. + .. clicmd:: neighbor PEER next-hop-self [all] This command specifies an announced route's nexthop as being equivalent to @@ -1576,6 +1585,12 @@ Configuring Peers on by default or not. This command defaults to on and is not displayed. The `no bgp default ipv4-unicast` form of the command is displayed. +.. clicmd:: bgp default ipv6-unicast + + This command allows the user to specify that v6 peering is turned + on by default or not. This command defaults to off and is not displayed. + The `bgp default ipv6-unicast` form of the command is displayed. + .. clicmd:: bgp default show-hostname This command shows the hostname of the peer in certain BGP commands @@ -2907,6 +2922,12 @@ Debugging Display Listen sockets and the vrf that created them. Useful for debugging of when listen is not working and this is considered a developer debug statement. +.. clicmd:: debug bgp bfd + + Enable or disable debugging for BFD events. This will show BFD integration + library messages and BGP BFD integration messages that are mostly state + transitions and validation problems. + .. clicmd:: debug bgp neighbor-events Enable or disable debugging for neighbor events. This provides general diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index 00571487d7..607acd3706 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -229,7 +229,6 @@ Showing OSPF6 information Interface name can also be given. JSON output can be obtained by appending 'json' to the end of command. -.. index:: show ipv6 ospf6 spf tree [json] .. clicmd:: show ipv6 ospf6 spf tree [json] This commands shows the spf tree from the recent spf calculation with the @@ -237,7 +236,7 @@ Showing OSPF6 information tree in JSON format. Each area that the router belongs to has it's own JSON object, with each router having "cost", "isLeafNode" and "children" as arguments. - + OSPF6 Configuration Examples ============================ diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index 8689bc4ccb..af9a7844a2 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -390,6 +390,27 @@ Areas Prevents an *ospfd* ABR from injecting inter-area summaries into the specified stub area. +.. clicmd:: area A.B.C.D nssa + +.. clicmd:: area (0-4294967295) nssa + + Configure the area to be a NSSA (Not-So-Stubby Area). This is an area that + allows OSPF to import external routes into a stub area via a new LSA type + (type 7). An NSSA autonomous system boundary router (ASBR) will generate this + type of LSA. The area border router (ABR) translates the LSA type 7 into LSA + type 5, which is propagated into the OSPF domain. NSSA areas are defined in + RFC 3101. + +.. clicmd:: area A.B.C.D nssa suppress-fa + +.. clicmd:: area (0-4294967295) nssa suppress-fa + + Configure the router to set the forwarding address to 0.0.0.0 in all LSA type 5 + translated from LSA type 7. The router needs to be elected the translator of the + area for this command to take effect. This feature causes routers that are + configured not to advertise forwarding addresses into the backbone to direct + forwarded traffic to the NSSA ABR translator. + .. clicmd:: area A.B.C.D default-cost (0-16777215) @@ -733,23 +754,25 @@ Showing Information Json o/p of this command covers base route information i.e all LSAs except opaque lsa info. -.. clicmd:: show ip ospf database [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database [json] + +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database (asbr-summary|external|network|router|summary) self-originate [json] -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database max-age [json] -.. clicmd:: show ip ospf database max-age [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] database self-originate [json] -.. clicmd:: show ip ospf database self-originate [json] + Show the OSPF database summary. .. clicmd:: show ip ospf route [json] @@ -780,17 +803,17 @@ Opaque LSA extensions that are used with MPLS-TE; it does not support a complete RSVP-TE solution. -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID adv-router ADV-ROUTER +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) adv-router ADV-ROUTER +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID self-originate +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) LINK-STATE-ID self-originate -.. clicmd:: show ip ospf database (opaque-link|opaque-area|opaque-external) self-originate +.. clicmd:: show ip ospf [vrf <NAME|all>] database (opaque-link|opaque-area|opaque-external) self-originate Show Opaque LSA from the database. @@ -966,6 +989,12 @@ TI-LFA requires a proper Segment Routing configuration. Debugging OSPF ============== +.. clicmd:: debug ospf bfd + + Enable or disable debugging for BFD events. This will show BFD integration + library messages and OSPF BFD integration messages that are mostly state + transitions and validation problems. + .. clicmd:: debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail] diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index c77a6fc1b1..8f80b78d20 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -57,7 +57,6 @@ #include "eigrpd/eigrp_const.h" #include "eigrpd/eigrp_filter.h" #include "eigrpd/eigrp_packet.h" -#include "eigrpd/eigrp_memory.h" /* * Distribute-list update functions. diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index bb7a930e6d..02e943043f 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -52,12 +52,14 @@ #include "eigrpd/eigrp_vty.h" #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_metric.h" +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF, "EIGRP interface"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF_INFO, "EIGRP Interface Information"); + struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) { diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index b1a6498cbc..0ed7e94968 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -155,7 +155,8 @@ FRR_DAEMON_INFO(eigrpd, EIGRP, .vty_port = EIGRP_VTY_PORT, .n_signals = array_size(eigrp_signals), .privs = &eigrpd_privs, .yang_modules = eigrpd_yang_modules, - .n_yang_modules = array_size(eigrpd_yang_modules), ) + .n_yang_modules = array_size(eigrpd_yang_modules), +); /* EIGRPd main routine. */ int main(int argc, char **argv, char **envp) diff --git a/eigrpd/eigrp_memory.c b/eigrpd/eigrp_memory.c deleted file mode 100644 index 57ca785340..0000000000 --- a/eigrpd/eigrp_memory.c +++ /dev/null @@ -1,42 +0,0 @@ -/* eigrpd memory type definitions - * - * Copyright (C) 2017 Donald Sharp - * - * This file is part of FRR - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eigrp_memory.h" - -DEFINE_MGROUP(EIGRPD, "eigrpd") -DEFINE_MTYPE(EIGRPD, EIGRP_TOP, "EIGRP structure") -DEFINE_MTYPE(EIGRPD, EIGRP_IF, "EIGRP interface") -DEFINE_MTYPE(EIGRPD, EIGRP_NEIGHBOR, "EIGRP neighbor") -DEFINE_MTYPE(EIGRPD, EIGRP_IF_PARAMS, "EIGRP Interface Parameters") -DEFINE_MTYPE(EIGRPD, EIGRP_IF_INFO, "EIGRP Interface Information") -DEFINE_MTYPE(EIGRPD, EIGRP_FIFO, "EIGRP FIFO") -DEFINE_MTYPE(EIGRPD, EIGRP_PACKET, "EIGRP Packet") -DEFINE_MTYPE(EIGRPD, EIGRP_IPV4_INT_TLV, "EIGRP IPv4 TLV") -DEFINE_MTYPE(EIGRPD, EIGRP_SEQ_TLV, "EIGRP SEQ TLV") -DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_TLV, "EIGRP AUTH TLV") -DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_SHA256_TLV, "EIGRP SHA TLV") -DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_DESCRIPTOR, "EIGRP Prefix") -DEFINE_MTYPE(EIGRPD, EIGRP_ROUTE_DESCRIPTOR, "EIGRP Nexthop Entry") -DEFINE_MTYPE(EIGRPD, EIGRP_FSM_MSG, "EIGRP FSM Message") diff --git a/eigrpd/eigrp_memory.h b/eigrpd/eigrp_memory.h deleted file mode 100644 index 21ecba2aae..0000000000 --- a/eigrpd/eigrp_memory.h +++ /dev/null @@ -1,43 +0,0 @@ -/* eigrpd memory type declarations - * - * Copyright (C) 2017 Donald Sharp - * - * This file is part of FRR. - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _FRR_EIGRP_MEMORY_H -#define _FRR_EIGRP_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(EIGRPD) -DECLARE_MTYPE(EIGRP_TOP) -DECLARE_MTYPE(EIGRP_IF) -DECLARE_MTYPE(EIGRP_NEIGHBOR) -DECLARE_MTYPE(EIGRP_IF_PARAMS) -DECLARE_MTYPE(EIGRP_IF_INFO) -DECLARE_MTYPE(EIGRP_FIFO) -DECLARE_MTYPE(EIGRP_PACKET) -DECLARE_MTYPE(EIGRP_IPV4_INT_TLV) -DECLARE_MTYPE(EIGRP_SEQ_TLV) -DECLARE_MTYPE(EIGRP_AUTH_TLV) -DECLARE_MTYPE(EIGRP_AUTH_SHA256_TLV) -DECLARE_MTYPE(EIGRP_PREFIX_DESCRIPTOR) -DECLARE_MTYPE(EIGRP_ROUTE_DESCRIPTOR) -DECLARE_MTYPE(EIGRP_FSM_MSG) - -#endif /* _FRR_EIGRP_MEMORY_H */ diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 1da2f7a108..f2d5217eb0 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -52,9 +52,10 @@ #include "eigrpd/eigrp_vty.h" #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_errors.h" +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_NEIGHBOR, "EIGRP neighbor"); + struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei) { struct eigrp_neighbor *nbr; diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 7eee254627..0b37733990 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -56,9 +56,15 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_errors.h" +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_FIFO, "EIGRP FIFO"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_PACKET, "EIGRP Packet"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IPV4_INT_TLV, "EIGRP IPv4 TLV"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_SEQ_TLV, "EIGRP SEQ TLV"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_AUTH_TLV, "EIGRP AUTH TLV"); +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_AUTH_SHA256_TLV, "EIGRP SHA TLV"); + /* Packet Type String. */ const struct message eigrp_packet_type_str[] = { {EIGRP_OPC_UPDATE, "Update"}, diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 0ab7b59dbb..c8769fb11f 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -52,7 +52,6 @@ #include "eigrpd/eigrp_macros.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" uint32_t eigrp_query_send_all(struct eigrp *eigrp) { diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index d16482173c..015daa768f 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -58,7 +58,6 @@ #include "eigrpd/eigrp_macros.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_errors.h" void eigrp_send_reply(struct eigrp_neighbor *nbr, diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index 027700fe11..9c2a8c9d84 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -52,7 +52,6 @@ #include "eigrpd/eigrp_macros.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" /*EIGRP SIA-QUERY read function*/ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index 590b224d68..2d298c20bf 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -51,7 +51,6 @@ #include "eigrpd/eigrp_macros.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" /*EIGRP SIA-REPLY read function*/ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 0d8bb29964..eb4a91cb64 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -126,9 +126,9 @@ struct eigrp { /* distribute_ctx */ struct distribute_ctx *distribute_ctx; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(eigrp) +DECLARE_QOBJ_TYPE(eigrp); struct eigrp_if_params { uint8_t passive_interface; diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 6da7756f84..846e211622 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -51,9 +51,11 @@ #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_metric.h" +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_ROUTE_DESCRIPTOR, "EIGRP Nexthop Entry"); +DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_DESCRIPTOR, "EIGRP Prefix"); + static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *rd1, struct eigrp_route_descriptor *rd2); diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h index 26fa1a11b0..d7f79057ab 100644 --- a/eigrpd/eigrp_topology.h +++ b/eigrpd/eigrp_topology.h @@ -32,6 +32,10 @@ #ifndef _ZEBRA_EIGRP_TOPOLOGY_H #define _ZEBRA_EIGRP_TOPOLOGY_H +#include "memory.h" + +DECLARE_MTYPE(EIGRP_PREFIX_DESCRIPTOR); + /* EIGRP Topology table related functions. */ extern struct route_table *eigrp_topology_new(void); extern void eigrp_topology_init(struct route_table *table); diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 91f3b3218b..0dc509706c 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -62,7 +62,6 @@ #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_network.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_metric.h" bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei, diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 5002630796..1030154907 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -55,10 +55,13 @@ #include "eigrpd/eigrp_packet.h" #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" -#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_filter.h" -DEFINE_QOBJ_TYPE(eigrp) +DEFINE_MGROUP(EIGRPD, "eigrpd"); + +DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_TOP, "EIGRP structure"); + +DEFINE_QOBJ_TYPE(eigrp); static struct eigrp_master eigrp_master; diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index 01173768ba..949fe682c7 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -32,6 +32,9 @@ #include "filter.h" #include "log.h" +#include "memory.h" + +DECLARE_MGROUP(EIGRPD); /* Set EIGRP version is "classic" - wide metrics comes next */ #define EIGRP_MAJOR_VERSION 1 diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 13c9f7f8ae..ba9445acb9 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -24,7 +24,6 @@ eigrpd_libeigrp_a_SOURCES = \ eigrpd/eigrp_fsm.c \ eigrpd/eigrp_hello.c \ eigrpd/eigrp_interface.c \ - eigrpd/eigrp_memory.c \ eigrpd/eigrp_metric.c \ eigrpd/eigrp_neighbor.c \ eigrpd/eigrp_network.c \ @@ -63,7 +62,6 @@ noinst_HEADERS += \ eigrpd/eigrp_fsm.h \ eigrpd/eigrp_interface.h \ eigrpd/eigrp_macros.h \ - eigrpd/eigrp_memory.h \ eigrpd/eigrp_metric.h \ eigrpd/eigrp_neighbor.h \ eigrpd/eigrp_network.h \ diff --git a/isisd/fabricd.c b/isisd/fabricd.c index 57e9e91c15..20651706d3 100644 --- a/isisd/fabricd.c +++ b/isisd/fabricd.c @@ -22,7 +22,6 @@ #include <zebra.h> #include "isisd/fabricd.h" #include "isisd/isisd.h" -#include "isisd/isis_memory.h" #include "isisd/isis_circuit.h" #include "isisd/isis_misc.h" #include "isisd/isis_adjacency.h" @@ -33,9 +32,9 @@ #include "isisd/isis_tx_queue.h" #include "isisd/isis_csm.h" -DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric") -DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry") -DEFINE_MTYPE_STATIC(ISISD, FABRICD_FLOODING_INFO, "ISIS OpenFabric Flooding Log") +DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric"); +DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry"); +DEFINE_MTYPE_STATIC(ISISD, FABRICD_FLOODING_INFO, "ISIS OpenFabric Flooding Log"); /* Tracks initial synchronization as per section 2.4 * diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 3c3a68764e..c1f5e49eca 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -49,6 +49,9 @@ #include "isisd/fabricd.h" #include "isisd/isis_nb.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_ADJACENCY, "ISIS adjacency"); +DEFINE_MTYPE(ISISD, ISIS_ADJACENCY_INFO, "ISIS adjacency info"); + static struct isis_adjacency *adj_alloc(struct isis_circuit *circuit, const uint8_t *id) { @@ -146,7 +149,7 @@ struct isis_adjacency *isis_adj_find(const struct isis_area *area, int level, return NULL; } -DEFINE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)) +DEFINE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)); void isis_delete_adj(void *arg) { @@ -260,22 +263,26 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, adj->threeway_state = next_tw_state; } -void isis_log_adj_change(struct isis_adjacency *adj, - enum isis_adj_state old_state, - enum isis_adj_state new_state, const char *reason) +const char *isis_adj_name(const struct isis_adjacency *adj) { - const char *adj_name; + if (!adj) + return "NONE"; + struct isis_dynhn *dyn; dyn = dynhn_find_by_id(adj->sysid); if (dyn) - adj_name = dyn->hostname; + return dyn->hostname; else - adj_name = sysid_print(adj->sysid); - + return sysid_print(adj->sysid); +} +void isis_log_adj_change(struct isis_adjacency *adj, + enum isis_adj_state old_state, + enum isis_adj_state new_state, const char *reason) +{ zlog_info( "%%ADJCHANGE: Adjacency to %s (%s) for %s changed from %s to %s, %s", - adj_name, adj->circuit->interface->name, + isis_adj_name(adj), adj->circuit->interface->name, adj_level2string(adj->level), adj_state2string(old_state), adj_state2string(new_state), reason ? reason : "unspecified"); } @@ -462,11 +469,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, struct isis_dynhn *dyn; int level; - dyn = dynhn_find_by_id(adj->sysid); - if (dyn) - vty_out(vty, " %-20s", dyn->hostname); - else - vty_out(vty, " %-20s", sysid_print(adj->sysid)); + vty_out(vty, " %-20s", isis_adj_name(adj)); if (detail == ISIS_UI_LEVEL_BRIEF) { if (adj->circuit) diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h index 3afb7209f3..754345c008 100644 --- a/isisd/isis_adjacency.h +++ b/isisd/isis_adjacency.h @@ -27,6 +27,8 @@ #include "isisd/isis_tlvs.h" +DECLARE_MTYPE(ISIS_ADJACENCY_INFO); + enum isis_adj_usage { ISIS_ADJ_NONE, ISIS_ADJ_LEVEL1, @@ -123,11 +125,11 @@ void isis_delete_adj(void *adj); void isis_adj_process_threeway(struct isis_adjacency *adj, struct isis_threeway_adj *tw_adj, enum isis_adj_usage adj_usage); -DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)) +DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)); DECLARE_HOOK(isis_adj_ip_enabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)) + (struct isis_adjacency *adj, int family), (adj, family)); DECLARE_HOOK(isis_adj_ip_disabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)) + (struct isis_adjacency *adj, int family), (adj, family)); void isis_log_adj_change(struct isis_adjacency *adj, enum isis_adj_state old_state, enum isis_adj_state new_state, const char *reason); @@ -142,5 +144,6 @@ void isis_adj_build_neigh_list(struct list *adjdb, struct list *list); void isis_adj_build_up_list(struct list *adjdb, struct list *list); int isis_adj_usage2levels(enum isis_adj_usage usage); int isis_bfd_startup_timer(struct thread *thread); +const char *isis_adj_name(const struct isis_adjacency *adj); #endif /* ISIS_ADJACENCY_H */ diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index 4fac73511b..89f1ed0ba3 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -32,7 +32,7 @@ #include "isisd/isisd.h" #include "isisd/fabricd.h" -DEFINE_MTYPE_STATIC(ISISD, BFD_SESSION, "ISIS BFD Session") +DEFINE_MTYPE_STATIC(ISISD, BFD_SESSION, "ISIS BFD Session"); struct bfd_session { int family; @@ -92,22 +92,42 @@ static bool bfd_session_same(const struct bfd_session *session, int family, static void bfd_adj_event(struct isis_adjacency *adj, struct prefix *dst, int new_status) { - if (!adj->bfd_session) + if (!adj->bfd_session) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update for adjacency with %s, could not find bfd session on the adjacency", + isis_adj_name(adj)); return; + } - if (adj->bfd_session->family != dst->family) + if (adj->bfd_session->family != dst->family) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update for adjacency with %s, address family does not match the family on the adjacency", + isis_adj_name(adj)); return; + } switch (adj->bfd_session->family) { case AF_INET: if (!IPV4_ADDR_SAME(&adj->bfd_session->dst_ip.ipv4, - &dst->u.prefix4)) + &dst->u.prefix4)) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update for adjacency with %s, IPv4 address does not match", + isis_adj_name(adj)); return; + } break; case AF_INET6: if (!IPV6_ADDR_SAME(&adj->bfd_session->dst_ip.ipv6, - &dst->u.prefix6)) + &dst->u.prefix6)) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update for adjacency with %s, IPv6 address does not match", + isis_adj_name(adj)); return; + } break; default: flog_err(EC_LIB_DEVELOPMENT, "%s: unknown address-family: %u", @@ -119,8 +139,13 @@ static void bfd_adj_event(struct isis_adjacency *adj, struct prefix *dst, BFD_SET_CLIENT_STATUS(adj->bfd_session->status, new_status); - if (old_status == new_status) + if (old_status == new_status) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update for adjacency with %s, new status matches current known status", + isis_adj_name(adj)); return; + } if (IS_DEBUG_BFD) { char dst_str[INET6_ADDRSTRLEN]; @@ -166,8 +191,12 @@ static int isis_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) struct isis_circuit *circuit = circuit_scan_by_ifp(ifp); - if (!circuit) + if (!circuit) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: Ignoring update, could not find circuit"); return 0; + } if (circuit->circ_type == CIRCUIT_T_BROADCAST) { for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) { @@ -326,15 +355,26 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command) struct list *local_ips; struct prefix *local_ip; - if (!circuit->bfd_info) + if (!circuit->bfd_info) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: skipping BFD initialization on adjacency with %s because there is no bfd_info in the circuit", + isis_adj_name(adj)); goto out; + } /* If IS-IS IPv6 is configured wait for IPv6 address to be programmed * before starting up BFD */ - if ((circuit->ipv6_router && listcount(circuit->ipv6_link) == 0) - || adj->ipv6_address_count == 0) + if (circuit->ipv6_router + && (listcount(circuit->ipv6_link) == 0 + || adj->ipv6_address_count == 0)) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: skipping BFD initialization on adjacency with %s because IPv6 is enabled but not ready", + isis_adj_name(adj)); return; + } /* * If IS-IS is enabled for both IPv4 and IPv6 on the circuit, prefer @@ -344,16 +384,24 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command) family = AF_INET6; dst_ip.ipv6 = adj->ipv6_addresses[0]; local_ips = circuit->ipv6_link; - if (!local_ips || list_isempty(local_ips)) + if (!local_ips || list_isempty(local_ips)) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: skipping BFD initialization: IPv6 enabled and no local IPv6 addresses"); goto out; + } local_ip = listgetdata(listhead(local_ips)); src_ip.ipv6 = local_ip->u.prefix6; } else if (circuit->ip_router && adj->ipv4_address_count) { family = AF_INET; dst_ip.ipv4 = adj->ipv4_addresses[0]; local_ips = fabricd_ip_addrs(adj->circuit); - if (!local_ips || list_isempty(local_ips)) + if (!local_ips || list_isempty(local_ips)) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: skipping BFD initialization: IPv4 enabled and no local IPv4 addresses"); goto out; + } local_ip = listgetdata(listhead(local_ips)); src_ip.ipv4 = local_ip->u.prefix4; } else @@ -365,8 +413,13 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command) bfd_handle_adj_down(adj); } - if (!adj->bfd_session) + if (!adj->bfd_session) { + if (IS_DEBUG_BFD) + zlog_debug( + "ISIS-BFD: creating BFD session for adjacency with %s", + isis_adj_name(adj)); adj->bfd_session = bfd_session_new(family, &dst_ip, &src_ip); + } bfd_debug(adj->bfd_session->family, &adj->bfd_session->dst_ip, &adj->bfd_session->src_ip, circuit->interface->name, command); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 62822cbf89..a637429e84 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -61,9 +61,11 @@ #include "isisd/isis_nb.h" #include "isisd/isis_ldp_sync.h" -DEFINE_QOBJ_TYPE(isis_circuit) +DEFINE_MTYPE_STATIC(ISISD, ISIS_CIRCUIT, "ISIS circuit"); -DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp)) +DEFINE_QOBJ_TYPE(isis_circuit); + +DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp)); /* * Prototypes. @@ -308,7 +310,7 @@ struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp) } DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit), - (circuit)) + (circuit)); void isis_circuit_add_addr(struct isis_circuit *circuit, struct connected *connected) @@ -1085,7 +1087,7 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, #ifdef FABRICD DEFINE_HOOK(isis_circuit_config_write, (struct isis_circuit *circuit, struct vty *vty), - (circuit, vty)) + (circuit, vty)); static int isis_interface_config_write(struct vty *vty) { diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 15d58bd736..cbe4040b64 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -174,9 +174,9 @@ struct isis_circuit { */ struct list *snmp_adj_list; /* List in id order */ - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(isis_circuit) +DECLARE_QOBJ_TYPE(isis_circuit); void isis_circuit_init(void); struct isis_circuit *isis_circuit_new(struct isis *isis); @@ -231,10 +231,10 @@ int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, #ifdef FABRICD DECLARE_HOOK(isis_circuit_config_write, (struct isis_circuit *circuit, struct vty *vty), - (circuit, vty)) + (circuit, vty)); #endif DECLARE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit), - (circuit)) + (circuit)); #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index fb9721e8b3..b108210686 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -136,10 +136,10 @@ void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode, vrf = yang_dnode_get_string(dnode, "./vrf"); vty_out(vty, "!\n"); - vty_out(vty, "router isis %s ", + vty_out(vty, "router isis %s", yang_dnode_get_string(dnode, "./area-tag")); if (!strmatch(vrf, VRF_DEFAULT_NAME)) - vty_out(vty, "vrf %s", yang_dnode_get_string(dnode, "./vrf")); + vty_out(vty, " vrf %s", yang_dnode_get_string(dnode, "./vrf")); vty_out(vty, "\n"); } @@ -392,10 +392,10 @@ void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode, if (!yang_dnode_get_bool(dnode, NULL)) vty_out(vty, " no"); - vty_out(vty, " ip router isis %s ", + vty_out(vty, " ip router isis %s", yang_dnode_get_string(dnode, "../area-tag")); if (!strmatch(vrf, VRF_DEFAULT_NAME)) - vty_out(vty, "vrf %s", vrf); + vty_out(vty, " vrf %s", vrf); vty_out(vty, "\n"); } @@ -408,10 +408,10 @@ void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode, if (!yang_dnode_get_bool(dnode, NULL)) vty_out(vty, " no"); - vty_out(vty, " ipv6 router isis %s ", + vty_out(vty, " ipv6 router isis %s", yang_dnode_get_string(dnode, "../area-tag")); if (!strmatch(vrf, VRF_DEFAULT_NAME)) - vty_out(vty, "vrf %s", vrf); + vty_out(vty, " vrf %s", vrf); vty_out(vty, "\n"); } diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c index d2c5d93e25..decd3e8922 100644 --- a/isisd/isis_dynhn.c +++ b/isisd/isis_dynhn.c @@ -40,6 +40,8 @@ #include "isisd/isis_misc.h" #include "isisd/isis_constants.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname"); + extern struct host host; struct list *dyn_cache = NULL; diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c index 3ebac8aaa9..085177b943 100644 --- a/isisd/isis_lfa.c +++ b/isisd/isis_lfa.c @@ -46,6 +46,7 @@ DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_NODE, "ISIS SPF Node"); DEFINE_MTYPE_STATIC(ISISD, ISIS_LFA_TIEBREAKER, "ISIS LFA Tiebreaker"); DEFINE_MTYPE_STATIC(ISISD, ISIS_LFA_EXCL_IFACE, "ISIS LFA Excluded Interface"); DEFINE_MTYPE_STATIC(ISISD, ISIS_RLFA, "ISIS Remote LFA"); +DEFINE_MTYPE(ISISD, ISIS_NEXTHOP_LABELS, "ISIS nexthop MPLS labels"); static inline int isis_spf_node_compare(const struct isis_spf_node *a, const struct isis_spf_node *b) diff --git a/isisd/isis_lfa.h b/isisd/isis_lfa.h index 65891cae44..9db03a3a19 100644 --- a/isisd/isis_lfa.h +++ b/isisd/isis_lfa.h @@ -22,9 +22,12 @@ #include "lib/typesafe.h" #include "lib/zclient.h" +#include "lib/memory.h" -PREDECL_RBTREE_UNIQ(lfa_tiebreaker_tree) -PREDECL_RBTREE_UNIQ(rlfa_tree) +DECLARE_MTYPE(ISIS_NEXTHOP_LABELS); + +PREDECL_RBTREE_UNIQ(lfa_tiebreaker_tree); +PREDECL_RBTREE_UNIQ(rlfa_tree); enum lfa_tiebreaker_type { LFA_TIEBREAKER_DOWNSTREAM = 0, @@ -41,7 +44,7 @@ struct lfa_tiebreaker { int lfa_tiebreaker_cmp(const struct lfa_tiebreaker *a, const struct lfa_tiebreaker *b); DECLARE_RBTREE_UNIQ(lfa_tiebreaker_tree, struct lfa_tiebreaker, entry, - lfa_tiebreaker_cmp) + lfa_tiebreaker_cmp); struct rlfa { struct rlfa_tree_item entry; @@ -50,7 +53,7 @@ struct rlfa { struct in_addr pq_address; }; int rlfa_cmp(const struct rlfa *a, const struct rlfa *b); -DECLARE_RBTREE_UNIQ(rlfa_tree, struct rlfa, entry, rlfa_cmp) +DECLARE_RBTREE_UNIQ(rlfa_tree, struct rlfa, entry, rlfa_cmp); enum isis_tilfa_sid_type { TILFA_SID_PREFIX = 1, diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 06a5a69e3f..056e29e8de 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -60,6 +60,8 @@ #include "isisd/isis_tx_queue.h" #include "isisd/isis_nb.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_LSP, "ISIS LSP"); + static int lsp_refresh(struct thread *thread); static int lsp_l1_refresh_pseudo(struct thread *thread); static int lsp_l2_refresh_pseudo(struct thread *thread); @@ -1561,18 +1563,28 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level, /* * Schedule LSP refresh ASAP */ - timeout = 0; - if (area->bfd_signalled_down) { sched_debug( - "ISIS (%s): Scheduling immediately due to BDF 'down' message.", + "ISIS (%s): Scheduling immediately due to BFD 'down' message.", area->area_tag); area->bfd_signalled_down = false; area->bfd_force_spf_refresh = true; + timeout = 0; } else { - sched_debug( - "ISIS (%s): Last generation was more than lsp_gen_interval ago. Scheduling for execution now.", - area->area_tag); + int64_t time_since_last = monotime_since( + &area->last_lsp_refresh_event[lvl - 1], + NULL); + timeout = time_since_last < 100000L + ? (100000L - time_since_last)/1000 + : 0; + if (timeout > 0) + sched_debug( + "ISIS (%s): Last generation was more than lsp_gen_interval ago. Scheduling for execution in %ld ms due to the instability timer.", + area->area_tag, timeout); + else + sched_debug( + "ISIS (%s): Last generation was more than lsp_gen_interval ago. Scheduling for execution now.", + area->area_tag); } } diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 896d957607..f3d9f61bcf 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -27,7 +27,7 @@ #include "lib/typesafe.h" #include "isisd/isis_pdu.h" -PREDECL_RBTREE_UNIQ(lspdb) +PREDECL_RBTREE_UNIQ(lspdb); struct isis; /* Structure for isis_lsp, this structure will only support the fixed @@ -61,7 +61,7 @@ struct isis_lsp { }; extern int lspdb_compare(const struct isis_lsp *a, const struct isis_lsp *b); -DECLARE_RBTREE_UNIQ(lspdb, struct isis_lsp, dbe, lspdb_compare) +DECLARE_RBTREE_UNIQ(lspdb, struct isis_lsp, dbe, lspdb_compare); void lsp_db_init(struct lspdb_head *head); void lsp_db_fini(struct lspdb_head *head); diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 1b04f4f7a0..c03cedb187 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -193,7 +193,8 @@ FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT, .n_signals = array_size(isisd_signals), .privs = &isisd_privs, .yang_modules = isisd_yang_modules, - .n_yang_modules = array_size(isisd_yang_modules), ) + .n_yang_modules = array_size(isisd_yang_modules), +); /* * Main routine of isisd. Parse arguments and handle IS-IS state machine. diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c deleted file mode 100644 index f716e060cd..0000000000 --- a/isisd/isis_memory.c +++ /dev/null @@ -1,49 +0,0 @@ -/* isisd memory type definitions - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "isis_memory.h" - -DEFINE_MGROUP(ISISD, "isisd") -DEFINE_MTYPE(ISISD, ISIS, "ISIS") -DEFINE_MTYPE(ISISD, ISIS_TMP, "ISIS TMP") -DEFINE_MTYPE(ISISD, ISIS_CIRCUIT, "ISIS circuit") -DEFINE_MTYPE(ISISD, ISIS_LSP, "ISIS LSP") -DEFINE_MTYPE(ISISD, ISIS_ADJACENCY, "ISIS adjacency") -DEFINE_MTYPE(ISISD, ISIS_ADJACENCY_INFO, "ISIS adjacency info") -DEFINE_MTYPE(ISISD, ISIS_AREA, "ISIS area") -DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address") -DEFINE_MTYPE(ISISD, ISIS_DYNHN, "ISIS dyn hostname") -DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree") -DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex") -DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info") -DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop") -DEFINE_MTYPE(ISISD, ISIS_NEXTHOP_LABELS, "ISIS nexthop MPLS labels") -DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary") -DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node") -DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") -DEFINE_MTYPE(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info") -DEFINE_MTYPE(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters") -DEFINE_MTYPE(ISISD, ISIS_ACL_NAME, "ISIS access-list name") -DEFINE_MTYPE(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name") diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h deleted file mode 100644 index 5bcd2a3983..0000000000 --- a/isisd/isis_memory.h +++ /dev/null @@ -1,50 +0,0 @@ -/* isisd memory type declarations - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QUAGGA_ISIS_MEMORY_H -#define _QUAGGA_ISIS_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(ISISD) -DECLARE_MTYPE(ISIS) -DECLARE_MTYPE(ISIS_TMP) -DECLARE_MTYPE(ISIS_CIRCUIT) -DECLARE_MTYPE(ISIS_LSP) -DECLARE_MTYPE(ISIS_ADJACENCY) -DECLARE_MTYPE(ISIS_ADJACENCY_INFO) -DECLARE_MTYPE(ISIS_AREA) -DECLARE_MTYPE(ISIS_AREA_ADDR) -DECLARE_MTYPE(ISIS_DYNHN) -DECLARE_MTYPE(ISIS_SPFTREE) -DECLARE_MTYPE(ISIS_VERTEX) -DECLARE_MTYPE(ISIS_ROUTE_INFO) -DECLARE_MTYPE(ISIS_NEXTHOP) -DECLARE_MTYPE(ISIS_NEXTHOP_LABELS) -DECLARE_MTYPE(ISIS_DICT) -DECLARE_MTYPE(ISIS_DICT_NODE) -DECLARE_MTYPE(ISIS_EXT_ROUTE) -DECLARE_MTYPE(ISIS_EXT_INFO) -DECLARE_MTYPE(ISIS_MPLS_TE) -DECLARE_MTYPE(ISIS_ACL_NAME) -DECLARE_MTYPE(ISIS_PLIST_NAME) - -#endif /* _QUAGGA_ISIS_MEMORY_H */ diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 9465c5e75c..c024549fcc 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -21,7 +21,6 @@ */ #include <zebra.h> #include "isisd/isisd.h" -#include "isisd/isis_memory.h" #include "isisd/isis_circuit.h" #include "isisd/isis_adjacency.h" #include "isisd/isis_misc.h" @@ -29,9 +28,9 @@ #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" -DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting") -DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting") -DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info") +DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting"); +DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting"); +DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info"); bool isis_area_ipv6_dstsrc_enabled(struct isis_area *area) { diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index f0663c691c..c8ad816b58 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -48,12 +48,14 @@ #include "isisd/isis_spf.h" #include "isisd/isis_spf_private.h" #include "isisd/isis_te.h" -#include "isisd/isis_memory.h" #include "isisd/isis_mt.h" #include "isisd/isis_redist.h" #include "isisd/isis_ldp_sync.h" #include "isisd/isis_dr.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name"); + extern struct zclient *zclient; /* @@ -131,7 +133,7 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args) switch (args->event) { case NB_EV_VALIDATE: - area = nb_running_get_entry(args->dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, false); if (area == NULL) return NB_ERR_VALIDATION; addr.addr_len = dotformat2buff(buff, net_title); diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index 856c47b9b7..c33d56e625 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -24,7 +24,6 @@ #include "if.h" #include "linklist.h" #include "memory.h" -#include "isis_memory.h" #include "prefix.h" #include "routemap.h" #include "stream.h" @@ -42,6 +41,10 @@ #include "isisd/isis_route.h" #include "isisd/isis_zebra.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_RMAP_NAME, "ISIS redistribute route-map name"); + static int redist_protocol(int family) { if (family == AF_INET) @@ -327,13 +330,13 @@ static void isis_redist_routemap_set(struct isis_redist *redist, const char *routemap) { if (redist->map_name) { - XFREE(MTYPE_ISIS, redist->map_name); + XFREE(MTYPE_ISIS_RMAP_NAME, redist->map_name); route_map_counter_decrement(redist->map); redist->map = NULL; } if (routemap && strlen(routemap)) { - redist->map_name = XSTRDUP(MTYPE_ISIS, routemap); + redist->map_name = XSTRDUP(MTYPE_ISIS_RMAP_NAME, routemap); redist->map = route_map_lookup_by_name(routemap); route_map_counter_increment(redist->map); } @@ -507,7 +510,7 @@ void isis_redist_area_finish(struct isis_area *area) redist = &area->redist_settings[protocol][type] [level]; redist->redist = 0; - XFREE(MTYPE_ISIS, redist->map_name); + XFREE(MTYPE_ISIS_RMAP_NAME, redist->map_name); } route_table_finish(area->ext_reach[protocol][level]); } diff --git a/isisd/isis_route.c b/isisd/isis_route.c index e1baf351f4..eb534a543a 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -50,10 +50,13 @@ #include "isis_route.h" #include "isis_zebra.h" +DEFINE_MTYPE_STATIC(ISISD, ISIS_NEXTHOP, "ISIS nexthop"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_ROUTE_INFO, "ISIS route info"); + DEFINE_HOOK(isis_route_update_hook, (struct isis_area * area, struct prefix *prefix, struct isis_route_info *route_info), - (area, prefix, route_info)) + (area, prefix, route_info)); static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family, union g_addr *ip, ifindex_t ifindex); diff --git a/isisd/isis_route.h b/isisd/isis_route.h index d6763ec76c..0e206d08f4 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -52,7 +52,7 @@ struct isis_route_info { DECLARE_HOOK(isis_route_update_hook, (struct isis_area * area, struct prefix *prefix, struct isis_route_info *route_info), - (area, prefix, route_info)) + (area, prefix, route_info)); void isis_nexthop_delete(struct isis_nexthop *nexthop); void adjinfo2nexthop(int family, struct list *nexthops, diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c index 50dc0f2a1c..522026dde4 100644 --- a/isisd/isis_snmp.c +++ b/isisd/isis_snmp.c @@ -3452,6 +3452,9 @@ static int isis_snmp_module_init(void) return 0; } -FRR_MODULE_SETUP(.name = "isis_snmp", .version = FRR_VERSION, - .description = "isis AgentX SNMP module", - .init = isis_snmp_module_init, ) +FRR_MODULE_SETUP( + .name = "isis_snmp", + .version = FRR_VERSION, + .description = "isis AgentX SNMP module", + .init = isis_snmp_module_init, +); diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 7bcc6fea90..3e8ec8817e 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -60,8 +60,10 @@ #include "fabricd.h" #include "isis_spf_private.h" -DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); -DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_ADJ, "ISIS SPF Adjacency"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_SPFTREE, "ISIS SPFtree"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_ADJ, "ISIS SPF Adjacency"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_VERTEX, "ISIS vertex"); DEFINE_MTYPE_STATIC(ISISD, ISIS_VERTEX_ADJ, "ISIS SPF Vertex Adjacency"); static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, @@ -248,6 +250,20 @@ static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree, return vertex; } +void isis_vertex_del(struct isis_vertex *vertex) +{ + list_delete(&vertex->Adj_N); + list_delete(&vertex->parents); + if (vertex->firsthops) { + hash_clean(vertex->firsthops, NULL); + hash_free(vertex->firsthops); + vertex->firsthops = NULL; + } + + memset(vertex, 0, sizeof(struct isis_vertex)); + XFREE(MTYPE_ISIS_VERTEX, vertex); +} + struct isis_vertex_adj * isis_vertex_adj_add(struct isis_spftree *spftree, struct isis_vertex *vertex, struct list *vadj_list, struct isis_spf_adj *sadj, diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h index 79dfa3e164..07d4ff5a0e 100644 --- a/isisd/isis_spf_private.h +++ b/isisd/isis_spf_private.h @@ -179,20 +179,7 @@ static void isis_vertex_queue_init(struct isis_vertex_queue *queue, isis_vertex_queue_hash_cmp, name); } -__attribute__((__unused__)) -static void isis_vertex_del(struct isis_vertex *vertex) -{ - list_delete(&vertex->Adj_N); - list_delete(&vertex->parents); - if (vertex->firsthops) { - hash_clean(vertex->firsthops, NULL); - hash_free(vertex->firsthops); - vertex->firsthops = NULL; - } - - memset(vertex, 0, sizeof(struct isis_vertex)); - XFREE(MTYPE_ISIS_VERTEX, vertex); -} +void isis_vertex_del(struct isis_vertex *vertex); bool isis_vertex_adj_exists(const struct isis_spftree *spftree, const struct isis_vertex *vertex, diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index 21f534641c..c4024772f5 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -49,7 +49,7 @@ #include "isisd/isis_errors.h" /* Local variables and functions */ -DEFINE_MTYPE_STATIC(ISISD, ISIS_SR_INFO, "ISIS segment routing information") +DEFINE_MTYPE_STATIC(ISISD, ISIS_SR_INFO, "ISIS segment routing information"); static void sr_local_block_delete(struct isis_area *area); static int sr_local_block_init(struct isis_area *area); @@ -73,7 +73,7 @@ static inline int sr_prefix_sid_cfg_compare(const struct sr_prefix_cfg *a, return prefix_cmp(&a->prefix, &b->prefix); } DECLARE_RBTREE_UNIQ(srdb_prefix_cfg, struct sr_prefix_cfg, entry, - sr_prefix_sid_cfg_compare) + sr_prefix_sid_cfg_compare); /** * Find SRGB associated to a System ID. diff --git a/isisd/isis_sr.h b/isisd/isis_sr.h index b012dfb00a..a933f366eb 100644 --- a/isisd/isis_sr.h +++ b/isisd/isis_sr.h @@ -57,7 +57,7 @@ #define SRLB_UPPER_BOUND 15999 /* Segment Routing Data Base (SRDB) RB-Tree structure */ -PREDECL_RBTREE_UNIQ(srdb_prefix_cfg) +PREDECL_RBTREE_UNIQ(srdb_prefix_cfg); /* * Segment Routing Prefix-SID information. diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a97c19a8bc..47fd684eb3 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -33,7 +33,6 @@ #include "network.h" #include "isisd/isisd.h" -#include "isisd/isis_memory.h" #include "isisd/isis_tlvs.h" #include "isisd/isis_common.h" #include "isisd/isis_mt.h" @@ -45,9 +44,9 @@ #include "isisd/isis_te.h" #include "isisd/isis_sr.h" -DEFINE_MTYPE_STATIC(ISISD, ISIS_TLV, "ISIS TLVs") -DEFINE_MTYPE(ISISD, ISIS_SUBTLV, "ISIS Sub-TLVs") -DEFINE_MTYPE_STATIC(ISISD, ISIS_MT_ITEM_LIST, "ISIS MT Item Lists") +DEFINE_MTYPE_STATIC(ISISD, ISIS_TLV, "ISIS TLVs"); +DEFINE_MTYPE(ISISD, ISIS_SUBTLV, "ISIS Sub-TLVs"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_MT_ITEM_LIST, "ISIS MT Item Lists"); typedef int (*unpack_tlv_func)(enum isis_tlv_context context, uint8_t tlv_type, uint8_t tlv_len, struct stream *s, @@ -4488,9 +4487,9 @@ static void tlvs_protocols_supported_to_adj(struct isis_tlvs *tlvs, } DEFINE_HOOK(isis_adj_ip_enabled_hook, (struct isis_adjacency *adj, int family), - (adj, family)) + (adj, family)); DEFINE_HOOK(isis_adj_ip_disabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)) + (struct isis_adjacency *adj, int family), (adj, family)); static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj, diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 037f91f0b8..0438d13ae0 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -28,7 +28,7 @@ #include "openbsd-tree.h" #include "prefix.h" -DECLARE_MTYPE(ISIS_SUBTLV) +DECLARE_MTYPE(ISIS_SUBTLV); struct lspdb_head; struct isis_subtlvs; diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c index 5c87e39157..c7266152b7 100644 --- a/isisd/isis_tx_queue.c +++ b/isisd/isis_tx_queue.c @@ -25,15 +25,14 @@ #include "jhash.h" #include "isisd/isisd.h" -#include "isisd/isis_memory.h" #include "isisd/isis_flags.h" #include "isisd/isis_circuit.h" #include "isisd/isis_lsp.h" #include "isisd/isis_misc.h" #include "isisd/isis_tx_queue.h" -DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue") -DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry") +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue"); +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry"); struct isis_tx_queue { struct isis_circuit *circuit; diff --git a/isisd/isisd.c b/isisd/isisd.c index 487a902c06..714961c177 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -81,7 +81,15 @@ unsigned long debug_sr; unsigned long debug_ldp_sync; unsigned long debug_lfa; -DEFINE_QOBJ_TYPE(isis_area) +DEFINE_MGROUP(ISISD, "isisd"); + +DEFINE_MTYPE_STATIC(ISISD, ISIS, "ISIS process"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_NAME, "ISIS process name"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_AREA, "ISIS area"); +DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address"); +DEFINE_MTYPE(ISISD, ISIS_ACL_NAME, "ISIS access-list name"); + +DEFINE_QOBJ_TYPE(isis_area); /* ISIS process wide configuration. */ static struct isis_master isis_master; @@ -198,10 +206,10 @@ struct isis *isis_new(const char *vrf_name) if (vrf) { isis->vrf_id = vrf->vrf_id; isis_vrf_link(isis, vrf); - isis->name = XSTRDUP(MTYPE_ISIS, vrf->name); + isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf->name); } else { isis->vrf_id = VRF_UNKNOWN; - isis->name = XSTRDUP(MTYPE_ISIS, vrf_name); + isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name); } if (IS_DEBUG_EVENTS) @@ -565,7 +573,7 @@ static int isis_vrf_enable(struct vrf *vrf) isis = isis_lookup_by_vrfname(vrf->name); if (isis) { if (isis->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) { - XFREE(MTYPE_ISIS, isis->name); + XFREE(MTYPE_ISIS_NAME, isis->name); isis->name = NULL; } old_vrf_id = isis->vrf_id; @@ -631,7 +639,7 @@ void isis_finish(struct isis *isis) vrf = vrf_lookup_by_name(isis->name); if (vrf) isis_vrf_unlink(isis, vrf); - XFREE(MTYPE_ISIS, isis->name); + XFREE(MTYPE_ISIS_NAME, isis->name); } else { vrf = vrf_lookup_by_id(VRF_DEFAULT); if (vrf) diff --git a/isisd/isisd.h b/isisd/isisd.h index 1b0ec2b4f0..a2e821ad2f 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -24,6 +24,7 @@ #define ISISD_H #include "vty.h" +#include "memory.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -34,10 +35,11 @@ #include "isis_flags.h" #include "isis_lsp.h" #include "isis_lfa.h" -#include "isis_memory.h" #include "qobj.h" #include "ldp_sync.h" +DECLARE_MGROUP(ISISD); + #ifdef FABRICD static const bool fabricd = true; #define PROTO_TYPE ZEBRA_ROUTE_OPENFABRIC @@ -236,11 +238,14 @@ struct isis_area { uint64_t id_len_mismatches[2]; uint64_t lsp_error_counter[2]; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(isis_area) +DECLARE_QOBJ_TYPE(isis_area); + +DECLARE_MTYPE(ISIS_ACL_NAME); /* isis_area->spf_prefix_prioritites */ +DECLARE_MTYPE(ISIS_AREA_ADDR); /* isis_area->area_addrs */ -DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area)) +DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area)); void isis_terminate(void); void isis_finish(struct isis *isis); diff --git a/isisd/subdir.am b/isisd/subdir.am index 98674a6881..4cefe6e10b 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -57,7 +57,6 @@ noinst_HEADERS += \ isisd/isis_ldp_sync.h \ isisd/isis_lfa.h \ isisd/isis_lsp.h \ - isisd/isis_memory.h \ isisd/isis_misc.h \ isisd/isis_mt.h \ isisd/isis_nb.h \ @@ -92,7 +91,6 @@ LIBISIS_SOURCES = \ isisd/isis_ldp_sync.c \ isisd/isis_lfa.c \ isisd/isis_lsp.c \ - isisd/isis_memory.c \ isisd/isis_misc.c \ isisd/isis_mt.c \ isisd/isis_pdu.c \ @@ -142,7 +140,7 @@ nodist_isisd_isisd_SOURCES = \ # end isisd_isisd_snmp_la_SOURCES = isisd/isis_snmp.c -isisd_isisd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +isisd_isisd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 isisd_isisd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic isisd_isisd_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/ldpd/ldp_snmp.c b/ldpd/ldp_snmp.c index 97dde616a7..3f59d18aa8 100644 --- a/ldpd/ldp_snmp.c +++ b/ldpd/ldp_snmp.c @@ -1239,6 +1239,9 @@ static int ldp_snmp_module_init(void) return 0; } -FRR_MODULE_SETUP(.name = "ldp_snmp", .version = FRR_VERSION, - .description = "ldp AgentX SNMP module", - .init = ldp_snmp_module_init, ) +FRR_MODULE_SETUP( + .name = "ldp_snmp", + .version = FRR_VERSION, + .description = "ldp AgentX SNMP module", + .init = ldp_snmp_module_init, +); diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 14235a0f1f..d69a4dcd3c 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -69,13 +69,13 @@ static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *); static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *, struct l2vpn *); -DEFINE_QOBJ_TYPE(iface) -DEFINE_QOBJ_TYPE(tnbr) -DEFINE_QOBJ_TYPE(nbr_params) -DEFINE_QOBJ_TYPE(l2vpn_if) -DEFINE_QOBJ_TYPE(l2vpn_pw) -DEFINE_QOBJ_TYPE(l2vpn) -DEFINE_QOBJ_TYPE(ldpd_conf) +DEFINE_QOBJ_TYPE(iface); +DEFINE_QOBJ_TYPE(tnbr); +DEFINE_QOBJ_TYPE(nbr_params); +DEFINE_QOBJ_TYPE(l2vpn_if); +DEFINE_QOBJ_TYPE(l2vpn_pw); +DEFINE_QOBJ_TYPE(l2vpn); +DEFINE_QOBJ_TYPE(ldpd_conf); struct ldpd_global global; struct ldpd_init init; @@ -88,7 +88,7 @@ static pid_t lde_pid; static struct frr_daemon_info ldpd_di; -DEFINE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm)) +DEFINE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm)); static void ldp_load_module(const char *name) { @@ -218,7 +218,7 @@ FRR_DAEMON_INFO(ldpd, LDP, .yang_modules = ldpd_yang_modules, .n_yang_modules = array_size(ldpd_yang_modules), -) +); static int ldp_config_fork_apply(struct thread *t) { diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index 73c81349ce..8fdc16fc7b 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -362,11 +362,11 @@ struct iface { struct iface_af ipv4; struct iface_af ipv6; struct iface_ldp_sync ldp_sync; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(iface_head, iface); RB_PROTOTYPE(iface_head, iface, entry, iface_compare); -DECLARE_QOBJ_TYPE(iface) +DECLARE_QOBJ_TYPE(iface); /* source of targeted hellos */ struct tnbr { @@ -379,11 +379,11 @@ struct tnbr { uint16_t pw_count; uint32_t rlfa_count; uint8_t flags; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(tnbr_head, tnbr); RB_PROTOTYPE(tnbr_head, tnbr, entry, tnbr_compare); -DECLARE_QOBJ_TYPE(tnbr) +DECLARE_QOBJ_TYPE(tnbr); #define F_TNBR_CONFIGURED 0x01 #define F_TNBR_DYNAMIC 0x02 @@ -405,11 +405,11 @@ struct nbr_params { uint8_t md5key_len; } auth; uint8_t flags; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(nbrp_head, nbr_params); RB_PROTOTYPE(nbrp_head, nbr_params, entry, nbr_params_compare); -DECLARE_QOBJ_TYPE(nbr_params) +DECLARE_QOBJ_TYPE(nbr_params); #define F_NBRP_KEEPALIVE 0x01 #define F_NBRP_GTSM 0x02 #define F_NBRP_GTSM_HOPS 0x04 @@ -463,11 +463,11 @@ struct l2vpn_if { ifindex_t ifindex; int operative; uint8_t mac[ETH_ALEN]; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(l2vpn_if_head, l2vpn_if); RB_PROTOTYPE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare); -DECLARE_QOBJ_TYPE(l2vpn_if) +DECLARE_QOBJ_TYPE(l2vpn_if); struct l2vpn_pw { RB_ENTRY(l2vpn_pw) entry; @@ -485,11 +485,11 @@ struct l2vpn_pw { uint32_t remote_status; uint8_t flags; uint8_t reason; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(l2vpn_pw_head, l2vpn_pw); RB_PROTOTYPE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare); -DECLARE_QOBJ_TYPE(l2vpn_pw) +DECLARE_QOBJ_TYPE(l2vpn_pw); #define F_PW_STATUSTLV_CONF 0x01 /* status tlv configured */ #define F_PW_STATUSTLV 0x02 /* status tlv negotiated */ #define F_PW_CWORD_CONF 0x04 /* control word configured */ @@ -513,11 +513,11 @@ struct l2vpn { struct l2vpn_if_head if_tree; struct l2vpn_pw_head pw_tree; struct l2vpn_pw_head pw_inactive_tree; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(l2vpn_head, l2vpn); RB_PROTOTYPE(l2vpn_head, l2vpn, entry, l2vpn_compare); -DECLARE_QOBJ_TYPE(l2vpn) +DECLARE_QOBJ_TYPE(l2vpn); #define L2VPN_TYPE_VPWS 1 #define L2VPN_TYPE_VPLS 2 @@ -584,9 +584,9 @@ struct ldpd_conf { int flags; time_t config_change_time; struct ldp_entity_stats stats; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(ldpd_conf) +DECLARE_QOBJ_TYPE(ldpd_conf); #define F_LDPD_NO_FIB_UPDATE 0x0001 #define F_LDPD_DS_CISCO_INTEROP 0x0002 #define F_LDPD_ENABLED 0x0004 @@ -915,7 +915,7 @@ int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response * (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_INTFACELOCAL)) #endif -DECLARE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm)) +DECLARE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm)); extern void ldp_agentx_enabled(void); diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h index 9572f1ac12..880722424e 100644 --- a/ldpd/ldpe.h +++ b/ldpd/ldpe.h @@ -321,6 +321,7 @@ void ldpe_l2vpn_exit(struct l2vpn *); void ldpe_l2vpn_pw_init(struct l2vpn_pw *); void ldpe_l2vpn_pw_exit(struct l2vpn_pw *); -DECLARE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), (nbr, old_state)) +DECLARE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), + (nbr, old_state)); #endif /* _LDPE_H_ */ diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index 23c67ec1ca..e884b3ebfc 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -26,7 +26,8 @@ #include "lde.h" #include "log.h" -DEFINE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), (nbr, old_state)) +DEFINE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), + (nbr, old_state)); static __inline int nbr_id_compare(const struct nbr *, const struct nbr *); static __inline int nbr_addr_compare(const struct nbr *, diff --git a/ldpd/subdir.am b/ldpd/subdir.am index b01d414de8..aa9b751bcc 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -65,6 +65,6 @@ ldpd_ldpd_SOURCES = ldpd/ldpd.c ldpd_ldpd_LDADD = ldpd/libldp.a lib/libfrr.la $(LIBCAP) ldpd_ldpd_snmp_la_SOURCES = ldpd/ldp_snmp.c -ldpd_ldpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +ldpd_ldpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 ldpd_ldpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic ldpd_ldpd_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/lib/agentx.c b/lib/agentx.c index c1ff7a61b1..b5a035ee2b 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -34,9 +34,9 @@ #include "lib_errors.h" #include "xref.h" -XREF_SETUP() +XREF_SETUP(); -DEFINE_HOOK(agentx_enabled, (), ()) +DEFINE_HOOK(agentx_enabled, (), ()); static int agentx_enabled = 0; diff --git a/lib/atomlist.h b/lib/atomlist.h index 5ca19cbcd4..c795128a34 100644 --- a/lib/atomlist.h +++ b/lib/atomlist.h @@ -123,15 +123,16 @@ struct atomlist_head { /* use as: * - * PREDECL_ATOMLIST(namelist) + * PREDECL_ATOMLIST(namelist); * struct name { * struct namelist_item nlitem; * } - * DECLARE_ATOMLIST(namelist, struct name, nlitem) + * DECLARE_ATOMLIST(namelist, struct name, nlitem); */ #define PREDECL_ATOMLIST(prefix) \ struct prefix ## _head { struct atomlist_head ah; }; \ -struct prefix ## _item { struct atomlist_item ai; }; +struct prefix ## _item { struct atomlist_item ai; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_ATOMLIST(var) { } @@ -171,7 +172,7 @@ macro_inline void prefix ## _fini(struct prefix##_head *h) \ assert(prefix ## _count(h) == 0); \ memset(h, 0, sizeof(*h)); \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ /* add_head: * - contention on ->first pointer @@ -221,7 +222,8 @@ struct atomsort_head { #define _PREDECL_ATOMSORT(prefix) \ struct prefix ## _head { struct atomsort_head ah; }; \ -struct prefix ## _item { struct atomsort_item ai; }; +struct prefix ## _item { struct atomsort_item ai; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_ATOMSORT_UNIQ(var) { } #define INIT_ATOMSORT_NONUNIQ(var) { } @@ -298,7 +300,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ struct atomsort_item *p = atomsort_pop(&h->ah); \ return p ? container_of(p, type, field.ai) : NULL; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_ATOMSORT_UNIQ(prefix) \ _PREDECL_ATOMSORT(prefix) @@ -312,7 +314,7 @@ macro_inline int prefix ## __cmp(const struct atomsort_item *a, \ } \ \ _DECLARE_ATOMSORT(prefix, type, field, \ - prefix ## __cmp, prefix ## __cmp) \ + prefix ## __cmp, prefix ## __cmp); \ \ atomic_find_warn \ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ @@ -325,7 +327,7 @@ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ return NULL; \ return p; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_ATOMSORT_NONUNIQ(prefix) \ _PREDECL_ATOMSORT(prefix) @@ -352,8 +354,8 @@ macro_inline int prefix ## __cmp_uq(const struct atomsort_item *a, \ } \ \ _DECLARE_ATOMSORT(prefix, type, field, \ - prefix ## __cmp, prefix ## __cmp_uq) \ -/* ... */ + prefix ## __cmp, prefix ## __cmp_uq); \ +MACRO_REQUIRE_SEMICOLON() /* end */ struct atomsort_item *atomsort_add(struct atomsort_head *h, struct atomsort_item *item, int (*cmpfn)( @@ -27,12 +27,13 @@ #include "prefix.h" #include "thread.h" #include "stream.h" +#include "vrf.h" #include "zclient.h" #include "table.h" #include "vty.h" #include "bfd.h" -DEFINE_MTYPE_STATIC(LIB, BFD_INFO, "BFD info") +DEFINE_MTYPE_STATIC(LIB, BFD_INFO, "BFD info"); static int bfd_debug = 0; static struct bfd_gbl bfd_gbl; @@ -568,3 +569,640 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args) return 0; } + +/** + * BFD protocol integration configuration. + */ + +/** Events definitions. */ +enum bfd_session_event { + /** Remove the BFD session configuration. */ + BSE_UNINSTALL, + /** Install the BFD session configuration. */ + BSE_INSTALL, +}; + +/** + * Data structure to do the necessary tricks to hide the BFD protocol + * integration internals. + */ +struct bfd_session_params { + /** Contains the session parameters and more. */ + struct bfd_session_arg args; + /** Contains the session state. */ + struct bfd_session_status bss; + /** Protocol implementation status update callback. */ + bsp_status_update updatecb; + /** Protocol implementation custom data pointer. */ + void *arg; + + /** + * Next event. + * + * This variable controls what action to execute when the command batch + * finishes. Normally we'd use `thread_add_event` value, however since + * that function is going to be called multiple times and the value + * might be different we'll use this variable to keep track of it. + */ + enum bfd_session_event lastev; + /** + * BFD session configuration event. + * + * Multiple actions might be asked during a command batch (either via + * configuration load or northbound batch), so we'll use this to + * install/uninstall the BFD session parameters only once. + */ + struct thread *installev; + + /** BFD session installation state. */ + bool installed; + /** BFD session enabled. */ + bool enabled; + + /** Global BFD paramaters list. */ + TAILQ_ENTRY(bfd_session_params) entry; +}; + +struct bfd_sessions_global { + /** + * Global BFD session parameters list for (re)installation and update + * without code duplication among daemons. + */ + TAILQ_HEAD(bsplist, bfd_session_params) bsplist; + + /** Pointer to FRR's event manager. */ + struct thread_master *tm; + /** Pointer to zebra client data structure. */ + struct zclient *zc; + + /** Debugging state. */ + bool debugging; + /** Is shutting down? */ + bool shutting_down; +}; + +/** Global configuration variable. */ +static struct bfd_sessions_global bsglobal; + +/** Global empty address for IPv4/IPv6. */ +static const struct in6_addr i6a_zero; + +struct bfd_session_params *bfd_sess_new(bsp_status_update updatecb, void *arg) +{ + struct bfd_session_params *bsp; + + bsp = XCALLOC(MTYPE_BFD_INFO, sizeof(*bsp)); + + /* Save application data. */ + bsp->updatecb = updatecb; + bsp->arg = arg; + + /* Set defaults. */ + bsp->args.detection_multiplier = BFD_DEF_DETECT_MULT; + bsp->args.ttl = BFD_SINGLE_HOP_TTL; + bsp->args.min_rx = BFD_DEF_MIN_RX; + bsp->args.min_tx = BFD_DEF_MIN_TX; + bsp->args.vrf_id = VRF_DEFAULT; + + /* Register in global list. */ + TAILQ_INSERT_TAIL(&bsglobal.bsplist, bsp, entry); + + return bsp; +} + +static bool _bfd_sess_valid(const struct bfd_session_params *bsp) +{ + /* Peer/local address not configured. */ + if (bsp->args.family == 0) + return false; + + /* Address configured but invalid. */ + if (bsp->args.family != AF_INET && bsp->args.family != AF_INET6) { + if (bsglobal.debugging) + zlog_debug("%s: invalid session family: %d", __func__, + bsp->args.family); + return false; + } + + /* Invalid address. */ + if (memcmp(&bsp->args.dst, &i6a_zero, sizeof(i6a_zero)) == 0) { + if (bsglobal.debugging) { + if (bsp->args.family == AF_INET) + zlog_debug("%s: invalid address: %pI4", + __func__, + (struct in_addr *)&bsp->args.dst); + else + zlog_debug("%s: invalid address: %pI6", + __func__, &bsp->args.dst); + } + return false; + } + + /* Multi hop requires local address. */ + if (bsp->args.mhop + && memcmp(&i6a_zero, &bsp->args.src, sizeof(i6a_zero)) == 0) { + if (bsglobal.debugging) + zlog_debug( + "%s: multi hop but no local address provided", + __func__); + return false; + } + + /* Check VRF ID. */ + if (bsp->args.vrf_id == VRF_UNKNOWN) { + if (bsglobal.debugging) + zlog_debug("%s: asked for unknown VRF", __func__); + return false; + } + + return true; +} + +static int _bfd_sess_send(struct thread *t) +{ + struct bfd_session_params *bsp = THREAD_ARG(t); + int rv; + + /* Validate configuration before trying to send bogus data. */ + if (!_bfd_sess_valid(bsp)) + return 0; + + if (bsp->lastev == BSE_INSTALL) { + bsp->args.command = bsp->installed ? ZEBRA_BFD_DEST_UPDATE + : ZEBRA_BFD_DEST_REGISTER; + } else + bsp->args.command = ZEBRA_BFD_DEST_DEREGISTER; + + /* If not installed and asked for uninstall, do nothing. */ + if (!bsp->installed && bsp->args.command == ZEBRA_BFD_DEST_DEREGISTER) + return 0; + + rv = zclient_bfd_command(bsglobal.zc, &bsp->args); + /* Command was sent successfully. */ + if (rv == 0) { + /* Update installation status. */ + if (bsp->args.command == ZEBRA_BFD_DEST_DEREGISTER) + bsp->installed = false; + else if (bsp->args.command == ZEBRA_BFD_DEST_REGISTER) + bsp->installed = true; + } + + return 0; +} + +static void _bfd_sess_remove(struct bfd_session_params *bsp) +{ + /* Not installed, nothing to do. */ + if (!bsp->installed) + return; + + /* Cancel any pending installation request. */ + THREAD_OFF(bsp->installev); + + /* Send request to remove any session. */ + bsp->lastev = BSE_UNINSTALL; + thread_execute(bsglobal.tm, _bfd_sess_send, bsp, 0); +} + +void bfd_sess_free(struct bfd_session_params **bsp) +{ + if (*bsp == NULL) + return; + + /* Remove any installed session. */ + _bfd_sess_remove(*bsp); + + /* Remove from global list. */ + TAILQ_REMOVE(&bsglobal.bsplist, (*bsp), entry); + + /* Free the memory and point to NULL. */ + XFREE(MTYPE_BFD_INFO, (*bsp)); +} + +void bfd_sess_enable(struct bfd_session_params *bsp, bool enable) +{ + /* Remove the session when disabling. */ + if (!enable) + _bfd_sess_remove(bsp); + + bsp->enabled = enable; +} + +void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, + struct in_addr *src, struct in_addr *dst) +{ + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + bsp->args.family = AF_INET; + + /* Clean memory, set zero value and avoid static analyser warnings. */ + memset(&bsp->args.src, 0, sizeof(bsp->args.src)); + memset(&bsp->args.dst, 0, sizeof(bsp->args.dst)); + + /* Copy the equivalent of IPv4 to arguments structure. */ + if (src) + memcpy(&bsp->args.src, src, sizeof(struct in_addr)); + + assert(dst); + memcpy(&bsp->args.dst, dst, sizeof(struct in_addr)); +} + +void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, + struct in6_addr *src, struct in6_addr *dst) +{ + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + bsp->args.family = AF_INET6; + + /* Clean memory, set zero value and avoid static analyser warnings. */ + memset(&bsp->args.src, 0, sizeof(bsp->args.src)); + + if (src) + bsp->args.src = *src; + + assert(dst); + bsp->args.dst = *dst; +} + +void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname) +{ + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + if (ifname == NULL) { + bsp->args.ifname[0] = 0; + bsp->args.ifnamelen = 0; + return; + } + + if (strlcpy(bsp->args.ifname, ifname, sizeof(bsp->args.ifname)) + > sizeof(bsp->args.ifname)) + zlog_warn("%s: interface name truncated: %s", __func__, ifname); + + bsp->args.ifnamelen = strlen(bsp->args.ifname); +} + +void bfd_sess_set_profile(struct bfd_session_params *bsp, const char *profile) +{ + if (profile == NULL) { + bsp->args.profile[0] = 0; + bsp->args.profilelen = 0; + return; + } + + if (strlcpy(bsp->args.profile, profile, sizeof(bsp->args.profile)) + > sizeof(bsp->args.profile)) + zlog_warn("%s: profile name truncated: %s", __func__, profile); + + bsp->args.profilelen = strlen(bsp->args.profile); +} + +void bfd_sess_set_vrf(struct bfd_session_params *bsp, vrf_id_t vrf_id) +{ + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + bsp->args.vrf_id = vrf_id; +} + +void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl) +{ + assert(min_ttl != 0); + + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + /* Invert TTL value: protocol expects number of hops. */ + min_ttl = (BFD_SINGLE_HOP_TTL + 1) - min_ttl; + bsp->args.ttl = min_ttl; + bsp->args.mhop = (min_ttl > 1); +} + +void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t min_ttl) +{ + /* If already installed, remove the old setting. */ + _bfd_sess_remove(bsp); + + bsp->args.ttl = min_ttl; + bsp->args.mhop = (min_ttl > 1); +} + + +void bfd_sess_set_cbit(struct bfd_session_params *bsp, bool enable) +{ + bsp->args.cbit = enable; +} + +void bfd_sess_set_timers(struct bfd_session_params *bsp, + uint8_t detection_multiplier, uint32_t min_rx, + uint32_t min_tx) +{ + bsp->args.detection_multiplier = detection_multiplier; + bsp->args.min_rx = min_rx; + bsp->args.min_tx = min_tx; +} + +void bfd_sess_install(struct bfd_session_params *bsp) +{ + /* Don't attempt to install/update when disabled. */ + if (!bsp->enabled) + return; + + bsp->lastev = BSE_INSTALL; + thread_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev); +} + +void bfd_sess_uninstall(struct bfd_session_params *bsp) +{ + bsp->lastev = BSE_UNINSTALL; + thread_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev); +} + +enum bfd_session_state bfd_sess_status(const struct bfd_session_params *bsp) +{ + return bsp->bss.state; +} + +uint8_t bfd_sess_minimum_ttl(const struct bfd_session_params *bsp) +{ + return ((BFD_SINGLE_HOP_TTL + 1) - bsp->args.ttl); +} + +uint8_t bfd_sess_hop_count(const struct bfd_session_params *bsp) +{ + return bsp->args.ttl; +} + +const char *bfd_sess_profile(const struct bfd_session_params *bsp) +{ + return bsp->args.profilelen ? bsp->args.profile : NULL; +} + +void bfd_sess_addresses(const struct bfd_session_params *bsp, int *family, + struct in6_addr *src, struct in6_addr *dst) +{ + *family = bsp->args.family; + if (src) + *src = bsp->args.src; + if (dst) + *dst = bsp->args.dst; +} + +const char *bfd_sess_interface(const struct bfd_session_params *bsp) +{ + if (bsp->args.ifnamelen) + return bsp->args.ifname; + + return NULL; +} + +const char *bfd_sess_vrf(const struct bfd_session_params *bsp) +{ + return vrf_id_to_name(bsp->args.vrf_id); +} + +vrf_id_t bfd_sess_vrf_id(const struct bfd_session_params *bsp) +{ + return bsp->args.vrf_id; +} + +bool bfd_sess_cbit(const struct bfd_session_params *bsp) +{ + return bsp->args.cbit; +} + +void bfd_sess_timers(const struct bfd_session_params *bsp, + uint8_t *detection_multiplier, uint32_t *min_rx, + uint32_t *min_tx) +{ + *detection_multiplier = bsp->args.detection_multiplier; + *min_rx = bsp->args.min_rx; + *min_tx = bsp->args.min_tx; +} + +void bfd_sess_show(struct vty *vty, struct json_object *json, + struct bfd_session_params *bsp) +{ + json_object *json_bfd = NULL; + char time_buf[64]; + + /* Show type. */ + if (json) { + json_bfd = json_object_new_object(); + if (bsp->args.mhop) + json_object_string_add(json_bfd, "type", "multi hop"); + else + json_object_string_add(json_bfd, "type", "single hop"); + } else + vty_out(vty, " BFD: Type: %s\n", + bsp->args.mhop ? "multi hop" : "single hop"); + + /* Show configuration. */ + if (json) { + json_object_int_add(json_bfd, "detectMultiplier", + bsp->args.detection_multiplier); + json_object_int_add(json_bfd, "rxMinInterval", + bsp->args.min_rx); + json_object_int_add(json_bfd, "txMinInterval", + bsp->args.min_tx); + } else { + vty_out(vty, + " Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n", + bsp->args.detection_multiplier, bsp->args.min_rx, + bsp->args.min_tx); + } + + bfd_last_update(bsp->bss.last_event, time_buf, sizeof(time_buf)); + if (json) { + json_object_string_add(json_bfd, "status", + bfd_get_status_str(bsp->bss.state)); + json_object_string_add(json_bfd, "lastUpdate", time_buf); + } else + vty_out(vty, " Status: %s, Last update: %s\n", + bfd_get_status_str(bsp->bss.state), time_buf); + + if (json) + json_object_object_add(json, "peerBfdInfo", json_bfd); + else + vty_out(vty, "\n"); +} + +/* + * Zebra communication related. + */ + +/** + * Callback for reinstallation of all registered BFD sessions. + * + * Use this as `zclient` `bfd_dest_replay` callback. + */ +static int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS) +{ + struct bfd_session_params *bsp; + + /* Do nothing when shutting down. */ + if (bsglobal.shutting_down) + return 0; + + if (bsglobal.debugging) + zlog_debug("%s: sending all sessions registered", __func__); + + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf_id); + + /* Replay all activated peers. */ + TAILQ_FOREACH (bsp, &bsglobal.bsplist, entry) { + /* Skip disabled sessions. */ + if (!bsp->enabled) + continue; + + /* We are reconnecting, so we must send installation. */ + bsp->installed = false; + + /* Cancel any pending installation request. */ + THREAD_OFF(bsp->installev); + + /* Ask for installation. */ + bsp->lastev = BSE_INSTALL; + thread_execute(bsglobal.tm, _bfd_sess_send, bsp, 0); + } + + return 0; +} + +static int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS) +{ + struct bfd_session_params *bsp; + size_t sessions_updated = 0; + struct interface *ifp; + int remote_cbit = false; + int state = BFD_STATUS_UNKNOWN; + time_t now; + size_t addrlen; + struct prefix dp; + struct prefix sp; + char ifstr[128], cbitstr[32]; + + /* Do nothing when shutting down. */ + if (bsglobal.shutting_down) + return 0; + + ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &state, &remote_cbit, + vrf_id); + + if (bsglobal.debugging) { + ifstr[0] = 0; + if (ifp) + snprintf(ifstr, sizeof(ifstr), " (interface %s)", + ifp->name); + + snprintf(cbitstr, sizeof(cbitstr), " (CPI bit %s)", + remote_cbit ? "yes" : "no"); + + zlog_debug("%s: %pFX -> %pFX%s VRF %s(%u)%s: %s", __func__, &sp, + &dp, ifstr, vrf_id_to_name(vrf_id), vrf_id, cbitstr, + bfd_get_status_str(state)); + } + + switch (dp.family) { + case AF_INET: + addrlen = sizeof(struct in_addr); + break; + case AF_INET6: + addrlen = sizeof(struct in6_addr); + break; + + default: + /* Unexpected value. */ + assert(0); + break; + } + + /* Cache current time to avoid multiple monotime clock calls. */ + now = monotime(NULL); + + /* Notify all matching sessions about update. */ + TAILQ_FOREACH (bsp, &bsglobal.bsplist, entry) { + /* Skip disabled or not installed entries. */ + if (!bsp->enabled || !bsp->installed) + continue; + /* Skip different VRFs. */ + if (bsp->args.vrf_id != vrf_id) + continue; + /* Skip different families. */ + if (bsp->args.family != dp.family) + continue; + /* Skip different interface. */ + if (bsp->args.ifnamelen && ifp + && strcmp(bsp->args.ifname, ifp->name) != 0) + continue; + /* Skip non matching destination addresses. */ + if (memcmp(&bsp->args.dst, &dp.u, addrlen) != 0) + continue; + /* + * Source comparison test: + * We will only compare source if BFD daemon provided the + * source address and the protocol set a source address in + * the configuration otherwise we'll just skip it. + */ + if (sp.family && memcmp(&bsp->args.src, &i6a_zero, addrlen) != 0 + && memcmp(&sp.u, &i6a_zero, addrlen) != 0 + && memcmp(&bsp->args.src, &sp.u, addrlen) != 0) + continue; + /* No session state change. */ + if ((int)bsp->bss.state == state) + continue; + + bsp->bss.last_event = now; + bsp->bss.previous_state = bsp->bss.state; + bsp->bss.state = state; + bsp->bss.remote_cbit = remote_cbit; + bsp->updatecb(bsp, &bsp->bss, bsp->arg); + sessions_updated++; + } + + if (bsglobal.debugging) + zlog_debug("%s: sessions updated: %zu", __func__, + sessions_updated); + + return 0; +} + +void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm) +{ + /* Initialize data structure. */ + TAILQ_INIT(&bsglobal.bsplist); + + /* Copy pointers. */ + bsglobal.zc = zc; + bsglobal.tm = tm; + + /* Install our callbacks. */ + zc->interface_bfd_dest_update = zclient_bfd_session_update; + zc->bfd_dest_replay = zclient_bfd_session_reply; + + /* Send the client registration */ + bfd_client_sendmsg(zc, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT); +} + +void bfd_protocol_integration_set_debug(bool enable) +{ + bsglobal.debugging = enable; +} + +void bfd_protocol_integration_set_shutdown(bool enable) +{ + bsglobal.shutting_down = enable; +} + +bool bfd_protocol_integration_debug(void) +{ + return bsglobal.debugging; +} + +bool bfd_protocol_integration_shutting_down(void) +{ + return bsglobal.shutting_down; +} @@ -128,6 +128,305 @@ extern void bfd_gbl_exit(void); * BFD new API. */ +/* Forward declaration of argument struct. */ +struct bfd_session_params; + +/** Session state definitions. */ +enum bfd_session_state { + /** Session state is unknown or not initialized. */ + BSS_UNKNOWN = BFD_STATUS_UNKNOWN, + /** Local or remote peer administratively shutdown the session. */ + BSS_ADMIN_DOWN = BFD_STATUS_ADMIN_DOWN, + /** Session is down. */ + BSS_DOWN = BFD_STATUS_DOWN, + /** Session is up and working correctly. */ + BSS_UP = BFD_STATUS_UP, +}; + +/** BFD session status information */ +struct bfd_session_status { + /** Current session state. */ + enum bfd_session_state state; + /** Previous session state. */ + enum bfd_session_state previous_state; + /** Remote Control Plane Independent bit state. */ + bool remote_cbit; + /** Last event occurrence. */ + time_t last_event; +}; + +/** + * Session status update callback. + * + * \param bsp BFD session parameters. + * \param bss BFD session status. + * \param arg application independent data. + */ +typedef void (*bsp_status_update)(struct bfd_session_params *bsp, + const struct bfd_session_status *bss, + void *arg); + +/** + * Allocates and initializes the session parameters. + * + * \param updatedb status update notification callback. + * \param args application independent data. + * + * \returns pointer to configuration storage. + */ +struct bfd_session_params *bfd_sess_new(bsp_status_update updatecb, void *args); + +/** + * Uninstall session if installed and free resources allocated by the + * parameters. Already sets pointer to `NULL` to avoid dangling references. + * + * \param bsp session parameters. + */ +void bfd_sess_free(struct bfd_session_params **bsp); + +/** + * Enable/disable session installation. + * + * \param bsp session parameters. + * \param enable knob variable. + */ +void bfd_sess_enable(struct bfd_session_params *bsp, bool enable); + +/** + * Set the local and peer address of the BFD session. + * + * \param bsp BFD session parameters. + * \param src local address (optional, can be `NULL`). + * \param dst remote address (mandatory). + */ +void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, + struct in_addr *src, struct in_addr *dst); + +/** + * Set the local and peer address of the BFD session. + * + * \param bsp BFD session parameters. + * \param src local address (optional, can be `NULL`). + * \param dst remote address (mandatory). + */ +void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, + struct in6_addr *src, struct in6_addr *dst); + +/** + * Configure the BFD session interface. + * + * \param bsp BFD session parameters. + * \param ifname interface name (or `NULL` to remove it). + */ +void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname); + +/** + * Configure the BFD session profile name. + * + * \param bsp BFD session parameters. + * \param profile profile name (or `NULL` to remove it). + */ +void bfd_sess_set_profile(struct bfd_session_params *bsp, const char *profile); + +/** + * Configure the BFD session VRF. + * + * \param bsp BFD session parameters. + * \param vrf_id the VRF identification number. + */ +void bfd_sess_set_vrf(struct bfd_session_params *bsp, vrf_id_t vrf_id); + +/** + * Configure the BFD session single/multi hop setting. + * + * \param bsp BFD session parameters. + * \param min_ttl minimum TTL value expected (255 for single hop, 254 for + * multi hop with single hop, 253 for multi hop with two hops + * and so on). See `BFD_SINGLE_HOP_TTL` and + * `BFD_MULTI_HOP_MIN_TTL` for defaults. + * + * To simplify things if your protocol only knows the amount of hops it is + * better to use `bfd_sess_set_hops` instead. + */ +void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl); + +/** To use single hop the minimum TTL must be set to this. */ +#define BFD_SINGLE_HOP_TTL 255 +/** To use multi hop the minimum TTL must be set to this or less. */ +#define BFD_MULTI_HOP_MIN_TTL 254 + +/** + * This function is the inverted version of `bfd_sess_set_minimum_ttl`. + * Instead of receiving the minimum expected TTL, it receives the amount of + * hops the protocol will jump. + * + * \param bsp BFD session parameters. + * \param min_ttl minimum amount of hops expected (1 for single hop, 2 or + * more for multi hop). + */ +void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t min_ttl); + +/** + * Configure the BFD session to set the Control Plane Independent bit. + * + * \param bsp BFD session parameters. + * \param enable BFD Control Plane Independent state. + */ +void bfd_sess_set_cbit(struct bfd_session_params *bsp, bool enable); + +/** + * DEPRECATED: please avoid using timers directly and use profiles instead. + * + * Configures the BFD session timers to use. This is specially useful with + * `ptm-bfd` which does not support timers. + * + * \param bsp BFD session parameters. + * \param detection_multiplier the detection multiplier value. + * \param min_rx minimum required receive period. + * \param min_tx minimum required transmission period. + */ +void bfd_sess_set_timers(struct bfd_session_params *bsp, + uint8_t detection_multiplier, uint32_t min_rx, + uint32_t min_tx); + +/** + * Installs or updates the BFD session based on the saved session arguments. + * + * \param bsp session parameters. + */ +void bfd_sess_install(struct bfd_session_params *bsp); + +/** + * Uninstall the BFD session based on the saved session arguments. + * + * \param bsp session parameters. + */ +void bfd_sess_uninstall(struct bfd_session_params *bsp); + +/** + * Get BFD session current status. + * + * \param bsp session parameters. + * + * \returns BFD session status data structure. + */ +enum bfd_session_state bfd_sess_status(const struct bfd_session_params *bsp); + +/** + * Get BFD session minimum TTL configured value. + * + * \param bsp session parameters. + * + * \returns configured minimum TTL. + */ +uint8_t bfd_sess_minimum_ttl(const struct bfd_session_params *bsp); + +/** + * Inverted version of `bfd_sess_minimum_ttl`. Gets the amount of hops in the + * way to the peer. + * + * \param bsp session parameters. + * + * \returns configured amount of hops. + */ +uint8_t bfd_sess_hop_count(const struct bfd_session_params *bsp); + +/** + * Get BFD session profile configured value. + * + * \param bsp session parameters. + * + * \returns configured profile name (or `NULL` if empty). + */ +const char *bfd_sess_profile(const struct bfd_session_params *bsp); + +/** + * Get BFD session addresses. + * + * \param bsp session parameters. + * \param family the address family being used (AF_INET or AF_INET6). + * \param src source address (optional, may be `NULL`). + * \param dst peer address (optional, may be `NULL`). + */ +void bfd_sess_addresses(const struct bfd_session_params *bsp, int *family, + struct in6_addr *src, struct in6_addr *dst); +/** + * Get BFD session interface name. + * + * \param bsp session parameters. + * + * \returns `NULL` if not set otherwise the interface name. + */ +const char *bfd_sess_interface(const struct bfd_session_params *bsp); + +/** + * Get BFD session VRF name. + * + * \param bsp session parameters. + * + * \returns the VRF name. + */ +const char *bfd_sess_vrf(const struct bfd_session_params *bsp); + +/** + * Get BFD session VRF ID. + * + * \param bsp session parameters. + * + * \returns the VRF name. + */ +vrf_id_t bfd_sess_vrf_id(const struct bfd_session_params *bsp); + +/** + * Get BFD session control plane independent bit configuration state. + * + * \param bsp session parameters. + * + * \returns `true` if enabled otherwise `false`. + */ +bool bfd_sess_cbit(const struct bfd_session_params *bsp); + +/** + * DEPRECATED: please avoid using timers directly and use profiles instead. + * + * Gets the configured timers. + * + * \param bsp BFD session parameters. + * \param detection_multiplier the detection multiplier value. + * \param min_rx minimum required receive period. + * \param min_tx minimum required transmission period. + */ +void bfd_sess_timers(const struct bfd_session_params *bsp, + uint8_t *detection_multiplier, uint32_t *min_rx, + uint32_t *min_tx); + +/** + * Show BFD session configuration and status. If `json` is provided (e.g. not + * `NULL`) then information will be inserted in object, otherwise printed to + * `vty`. + * + * \param vty Pointer to `vty` for outputting text. + * \param json (optional) JSON object pointer. + * \param bsp session parameters. + */ +void bfd_sess_show(struct vty *vty, struct json_object *json, + struct bfd_session_params *bsp); + +/** + * Initializes the BFD integration library. This function executes the + * following actions: + * + * - Copy the `struct thread_master` pointer to use as "thread" to execute + * the BFD session parameters installation. + * - Copy the `struct zclient` pointer to install its callbacks. + * - Initializes internal data structures. + * + * \param tm normally the daemon main thread event manager. + * \param zc the zebra client of the daemon. + */ +void bfd_protocol_integration_init(struct zclient *zc, + struct thread_master *tm); + /** * BFD session registration arguments. */ @@ -205,6 +504,34 @@ struct bfd_session_arg { */ extern int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *arg); +/** + * Enables or disables BFD protocol integration API debugging. + * + * \param enable new API debug state. + */ +extern void bfd_protocol_integration_set_debug(bool enable); + +/** + * Sets shutdown mode so no more events are processed. + * + * This is useful to avoid the event storm that happens caused by network, + * interfaces or VRFs removal. It should also avoid some crashes due hanging + * pointers left overs by protocol. + * + * \param enable new API shutdown state. + */ +extern void bfd_protocol_integration_set_shutdown(bool enable); + +/** + * Get API debugging state. + */ +extern bool bfd_protocol_integration_debug(void); + +/** + * Get API shutdown state. + */ +extern bool bfd_protocol_integration_shutting_down(void); + #ifdef __cplusplus } #endif diff --git a/lib/buffer.c b/lib/buffer.c index 42796faae8..7929b3709d 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -29,8 +29,8 @@ #include <stddef.h> -DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer") -DEFINE_MTYPE_STATIC(LIB, BUFFER_DATA, "Buffer data") +DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer"); +DEFINE_MTYPE_STATIC(LIB, BUFFER_DATA, "Buffer data"); /* Buffer master. */ struct buffer { diff --git a/lib/command.c b/lib/command.c index 6a4d504b2f..770e2fc5ac 100644 --- a/lib/command.c +++ b/lib/command.c @@ -51,8 +51,8 @@ #include "frrscript.h" -DEFINE_MTYPE_STATIC(LIB, HOST, "Host config") -DEFINE_MTYPE(LIB, COMPLETION, "Completion item") +DEFINE_MTYPE_STATIC(LIB, HOST, "Host config"); +DEFINE_MTYPE(LIB, COMPLETION, "Completion item"); #define item(x) \ { \ diff --git a/lib/command.h b/lib/command.h index 71abb20b05..14e51486ea 100644 --- a/lib/command.h +++ b/lib/command.h @@ -34,7 +34,7 @@ extern "C" { #endif -DECLARE_MTYPE(COMPLETION) +DECLARE_MTYPE(COMPLETION); /* * From RFC 1123 (Requirements for Internet Hosts), Section 2.1 on hostnames: diff --git a/lib/command_graph.c b/lib/command_graph.c index d30d9ab702..c6c3840455 100644 --- a/lib/command_graph.c +++ b/lib/command_graph.c @@ -26,11 +26,11 @@ #include "command_graph.h" -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") -DEFINE_MTYPE_STATIC(LIB, CMD_DESC, "Command Token Text") -DEFINE_MTYPE_STATIC(LIB, CMD_TEXT, "Command Token Help") -DEFINE_MTYPE(LIB, CMD_ARG, "Command Argument") -DEFINE_MTYPE_STATIC(LIB, CMD_VAR, "Command Argument Name") +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens"); +DEFINE_MTYPE_STATIC(LIB, CMD_DESC, "Command Token Text"); +DEFINE_MTYPE_STATIC(LIB, CMD_TEXT, "Command Token Help"); +DEFINE_MTYPE(LIB, CMD_ARG, "Command Argument"); +DEFINE_MTYPE_STATIC(LIB, CMD_VAR, "Command Argument Name"); struct cmd_token *cmd_token_new(enum cmd_token_type type, uint8_t attr, const char *text, const char *desc) diff --git a/lib/command_graph.h b/lib/command_graph.h index 86715410ce..2754dca67d 100644 --- a/lib/command_graph.h +++ b/lib/command_graph.h @@ -37,7 +37,7 @@ extern "C" { #endif -DECLARE_MTYPE(CMD_ARG) +DECLARE_MTYPE(CMD_ARG); struct vty; diff --git a/lib/command_match.c b/lib/command_match.c index 801b05f157..e9e8466ffd 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -26,7 +26,7 @@ #include "command_match.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack") +DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack"); #ifdef TRACE_MATCHER #define TM 1 diff --git a/lib/command_parse.y b/lib/command_parse.y index 8135d02b4b..5ebc19b278 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -54,7 +54,7 @@ #include "command_graph.h" #include "log.h" - DECLARE_MTYPE(LEX) + DECLARE_MTYPE(LEX); #define YYSTYPE CMD_YYSTYPE #define YYLTYPE CMD_YYLTYPE @@ -376,7 +376,7 @@ selector: '[' selector_seq_seq ']' varname_token #undef scanner -DEFINE_MTYPE(LIB, LEX, "Lexer token (temporary)") +DEFINE_MTYPE(LIB, LEX, "Lexer token (temporary)"); void cmd_graph_parse (struct graph *graph, const struct cmd_element *cmd) diff --git a/lib/compiler.h b/lib/compiler.h index 70ef8e9bc8..b7a142bdee 100644 --- a/lib/compiler.h +++ b/lib/compiler.h @@ -21,6 +21,21 @@ extern "C" { #endif +#ifdef __cplusplus +# if __cplusplus < 201103L +# error FRRouting headers must be compiled in C++11 mode or newer +# endif +/* C++ defines static_assert(), but not _Static_assert(). C defines + * _Static_assert() and has static_assert() in <assert.h>. However, we mess + * with assert() in zassert.h so let's not include <assert.h> here. + */ +# define _Static_assert static_assert +#else +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L +# error FRRouting must be compiled with min. -std=gnu11 (GNU ISO C11 dialect) +# endif +#endif + /* function attributes, use like * void prototype(void) __attribute__((_CONSTRUCTOR(100))); */ @@ -121,6 +136,24 @@ extern "C" { #define macro_inline static inline __attribute__((unused)) #define macro_pure static inline __attribute__((unused, pure)) +/* if the macro ends with a function definition */ +#define MACRO_REQUIRE_SEMICOLON() \ + _Static_assert(1, "please add a semicolon after this macro") + +#if CONFDATE < 20210601 +#ifdef ENABLE_BGP_VNC +/* temporarily disabled for transition for LabN CI + * NB: it's not possible to generate a deprecation warning for this, hence + * the shortened transition period (since otherwise new uses of the old syntax + * may creep in without errors) + */ +#undef MACRO_REQUIRE_SEMICOLON +#define MACRO_REQUIRE_SEMICOLON() \ + /* nothing */ +#endif /* ENABLE_BGP_VNC */ +#else /* CONFDATE >= 20210601 */ +CPP_NOTICE("time to remove this CONFDATE block") +#endif /* variadic macros, use like: * #define V_0() ... @@ -357,10 +390,8 @@ typedef signed long long _int64_t; /* if this breaks, 128-bit machines may have entered reality (or <long long> * is something weird) */ -#if __STDC_VERSION__ >= 201112L _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8, "nobody expects the spanish intquisition"); -#endif /* since we redefined int64_t, we also need to redefine PRI*64 */ #undef PRIu64 diff --git a/lib/debug.c b/lib/debug.c index 3248ceb13b..e2ba4cd4ef 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -24,7 +24,7 @@ static struct debug_cb_list_head cb_head; -DECLARE_LIST(debug_cb_list, struct debug_callbacks, item) +DECLARE_LIST(debug_cb_list, struct debug_callbacks, item); /* All code in this section should be reentrant and MT-safe */ diff --git a/lib/debug.h b/lib/debug.h index f25cd42691..a72657bdaf 100644 --- a/lib/debug.h +++ b/lib/debug.h @@ -84,7 +84,7 @@ struct debug { const char *desc; }; -PREDECL_LIST(debug_cb_list) +PREDECL_LIST(debug_cb_list); /* * Callback set for debugging code. * diff --git a/lib/defaults.h b/lib/defaults.h index 20ef28db31..55250f0f81 100644 --- a/lib/defaults.h +++ b/lib/defaults.h @@ -98,7 +98,8 @@ struct frr_default { static void _dfltinit_##varname(void) \ { \ frr_default_add(&_dflt_##varname); \ - } + } \ + MACRO_REQUIRE_SEMICOLON() /* end */ /* use: * FRR_CFG_DEFAULT_LONG(SHARP_BLUNTNESS, diff --git a/lib/distribute.c b/lib/distribute.c index 3ea60c8772..60bd0a47bb 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -27,10 +27,10 @@ #include "distribute.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx") -DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list") -DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname") -DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name") +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx"); +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list"); +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname"); +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name"); static struct list *dist_ctx_list; diff --git a/lib/elf_py.c b/lib/elf_py.c index 0d8ad76e1c..d26e443b82 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -100,7 +100,7 @@ static PyObject *refuse_new(PyTypeObject *type, PyObject *args, PyObject *kwds) struct elfreloc; struct elfsect; -PREDECL_HASH(elfrelocs) +PREDECL_HASH(elfrelocs); /* ELFFile and ELFSection intentionally share some behaviour, particularly * subscript[123:456] access to file data. This is because relocatables @@ -200,7 +200,7 @@ static int elfreloc_cmp(const struct elfreloc *a, const struct elfreloc *b); static uint32_t elfreloc_hash(const struct elfreloc *reloc); DECLARE_HASH(elfrelocs, struct elfreloc, elfrelocs_item, - elfreloc_cmp, elfreloc_hash) + elfreloc_cmp, elfreloc_hash); static Elf_Scn *elf_find_addr(struct elffile *ef, uint64_t addr, size_t *idx); static PyObject *elffile_secbyidx(struct elffile *w, Elf_Scn *scn, size_t idx); diff --git a/lib/ferr.c b/lib/ferr.c index 691da495cf..513ef5ebec 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -35,7 +35,7 @@ #include "linklist.h" #include "frr_pthread.h" -DEFINE_MTYPE_STATIC(LIB, ERRINFO, "error information") +DEFINE_MTYPE_STATIC(LIB, ERRINFO, "error information"); /* * Thread-specific key for temporary storage of allocated ferr. diff --git a/lib/filter.c b/lib/filter.c index f5ae9ee2b7..83423ba321 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -31,9 +31,9 @@ #include "libfrr.h" #include "northbound_cli.h" -DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST, "Access List") -DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST_STR, "Access List Str") -DEFINE_MTYPE_STATIC(LIB, ACCESS_FILTER, "Access Filter") +DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST, "Access List"); +DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST_STR, "Access List Str"); +DEFINE_MTYPE_STATIC(LIB, ACCESS_FILTER, "Access Filter"); /* Static structure for mac access_list's master. */ static struct access_master access_master_mac = { diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index 3f0179fbc1..03359f4d18 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -30,8 +30,8 @@ #include "zlog.h" #include "libfrr_trace.h" -DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread") -DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives") +DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread"); +DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives"); /* default frr_pthread start/stop routine prototypes */ static void *fpt_run(void *arg); diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 33adcd7b80..05f0fce5fc 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -26,7 +26,7 @@ #include "log.h" #include "lib_errors.h" -DEFINE_MTYPE_STATIC(LIB, ZEROMQ_CB, "ZeroMQ callback") +DEFINE_MTYPE_STATIC(LIB, ZEROMQ_CB, "ZeroMQ callback"); /* libzmq's context */ void *frrzmq_context = NULL; diff --git a/lib/frrcu.c b/lib/frrcu.c index 7e6475b648..0e717a98a5 100644 --- a/lib/frrcu.c +++ b/lib/frrcu.c @@ -54,12 +54,12 @@ #include "seqlock.h" #include "atomlist.h" -DEFINE_MTYPE_STATIC(LIB, RCU_THREAD, "RCU thread") -DEFINE_MTYPE_STATIC(LIB, RCU_NEXT, "RCU sequence barrier") +DEFINE_MTYPE_STATIC(LIB, RCU_THREAD, "RCU thread"); +DEFINE_MTYPE_STATIC(LIB, RCU_NEXT, "RCU sequence barrier"); -DECLARE_ATOMLIST(rcu_heads, struct rcu_head, head) +DECLARE_ATOMLIST(rcu_heads, struct rcu_head, head); -PREDECL_ATOMLIST(rcu_threads) +PREDECL_ATOMLIST(rcu_threads); struct rcu_thread { struct rcu_threads_item head; @@ -70,7 +70,7 @@ struct rcu_thread { /* only accessed by thread itself, not atomic */ unsigned depth; }; -DECLARE_ATOMLIST(rcu_threads, struct rcu_thread, head) +DECLARE_ATOMLIST(rcu_threads, struct rcu_thread, head); static const struct rcu_action rcua_next = { .type = RCUA_NEXT }; static const struct rcu_action rcua_end = { .type = RCUA_END }; diff --git a/lib/frrcu.h b/lib/frrcu.h index 47751ae7df..3808259040 100644 --- a/lib/frrcu.h +++ b/lib/frrcu.h @@ -116,7 +116,7 @@ struct rcu_action { }; /* RCU cleanup function queue item */ -PREDECL_ATOMLIST(rcu_heads) +PREDECL_ATOMLIST(rcu_heads); struct rcu_head { struct rcu_heads_item head; const struct rcu_action *action; diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index a40b815caa..209765bd6f 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -34,7 +34,7 @@ #define GRAMMAR_STR "CLI grammar sandbox\n" -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc"); /** headers **/ void grammar_sandbox_init(void); diff --git a/lib/graph.c b/lib/graph.c index 128e45c570..1cbe1b90f9 100644 --- a/lib/graph.c +++ b/lib/graph.c @@ -25,8 +25,8 @@ #include "memory.h" #include "buffer.h" -DEFINE_MTYPE_STATIC(LIB, GRAPH, "Graph") -DEFINE_MTYPE_STATIC(LIB, GRAPH_NODE, "Graph Node") +DEFINE_MTYPE_STATIC(LIB, GRAPH, "Graph"); +DEFINE_MTYPE_STATIC(LIB, GRAPH_NODE, "Graph Node"); struct graph *graph_new(void) { struct graph *graph = XCALLOC(MTYPE_GRAPH, sizeof(struct graph)); diff --git a/lib/hash.c b/lib/hash.c index ec616ee724..e9132f7907 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -31,9 +31,9 @@ #include "frr_pthread.h" #include "libfrr_trace.h" -DEFINE_MTYPE_STATIC(LIB, HASH, "Hash") -DEFINE_MTYPE_STATIC(LIB, HASH_BUCKET, "Hash Bucket") -DEFINE_MTYPE_STATIC(LIB, HASH_INDEX, "Hash Index") +DEFINE_MTYPE_STATIC(LIB, HASH, "Hash"); +DEFINE_MTYPE_STATIC(LIB, HASH_BUCKET, "Hash Bucket"); +DEFINE_MTYPE_STATIC(LIB, HASH_INDEX, "Hash Index"); static pthread_mutex_t _hashes_mtx = PTHREAD_MUTEX_INITIALIZER; static struct list *_hashes; diff --git a/lib/hook.c b/lib/hook.c index 5a8ad00d66..895243aad7 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -23,7 +23,7 @@ #include "memory.h" #include "hook.h" -DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry") +DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry"); void _hook_register(struct hook *hook, struct hookent *stackent, void *funcptr, void *arg, bool has_arg, struct frrmod_runtime *module, diff --git a/lib/hook.h b/lib/hook.h index bef5351e90..ff3ef29fa3 100644 --- a/lib/hook.h +++ b/lib/hook.h @@ -35,10 +35,10 @@ extern "C" { * * mydaemon.h: * #include "hook.h" - * DECLARE_HOOK (some_update_event, (struct eventinfo *info), (info)) + * DECLARE_HOOK (some_update_event, (struct eventinfo *info), (info)); * * mydaemon.c: - * DEFINE_HOOK (some_update_event, (struct eventinfo *info), (info)) + * DEFINE_HOOK (some_update_event, (struct eventinfo *info), (info)); * ... * hook_call (some_update_event, info) * @@ -184,7 +184,7 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, #define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__) /* use in header file - declares the hook and its arguments - * usage: DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2)) + * usage: DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2)); * as above, "passlist" must use the same order and same names as "arglist" * * theoretically passlist is not neccessary, but let's keep things simple and @@ -201,7 +201,9 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, int(*funcptr) HOOK_ADDDEF arglist) \ { \ return (void *)funcptr; \ - } + } \ + MACRO_REQUIRE_SEMICOLON() /* end */ + #define DECLARE_KOOH(hookname, arglist, passlist) \ DECLARE_HOOK(hookname, arglist, passlist) @@ -230,7 +232,8 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, hooksum += hookp.farg HOOK_ADDARG passlist; \ } \ return hooksum; \ - } + } \ + MACRO_REQUIRE_SEMICOLON() /* end */ #define DEFINE_HOOK(hookname, arglist, passlist) \ DEFINE_HOOK_INT(hookname, arglist, passlist, false) diff --git a/lib/id_alloc.c b/lib/id_alloc.c index 95096fa5f0..9179dc4299 100644 --- a/lib/id_alloc.c +++ b/lib/id_alloc.c @@ -29,13 +29,14 @@ #include <inttypes.h> -DEFINE_MTYPE_STATIC(LIB, IDALLOC_ALLOCATOR, "ID Number Allocator") -DEFINE_MTYPE_STATIC(LIB, IDALLOC_ALLOCATOR_NAME, "ID Number Allocator Name") -DEFINE_MTYPE_STATIC(LIB, IDALLOC_DIRECTORY, "ID Number Allocator Directory") +DEFINE_MTYPE_STATIC(LIB, IDALLOC_ALLOCATOR, "ID Number Allocator"); +DEFINE_MTYPE_STATIC(LIB, IDALLOC_ALLOCATOR_NAME, "ID Number Allocator Name"); +DEFINE_MTYPE_STATIC(LIB, IDALLOC_DIRECTORY, "ID Number Allocator Directory"); DEFINE_MTYPE_STATIC(LIB, IDALLOC_SUBDIRECTORY, - "ID Number Allocator Subdirectory") -DEFINE_MTYPE_STATIC(LIB, IDALLOC_PAGE, "ID Number Allocator Page") -DEFINE_MTYPE_STATIC(LIB, IDALLOC_POOL, "ID Number temporary holding pool entry") + "ID Number Allocator Subdirectory"); +DEFINE_MTYPE_STATIC(LIB, IDALLOC_PAGE, "ID Number Allocator Page"); +DEFINE_MTYPE_STATIC(LIB, IDALLOC_POOL, + "ID Number temporary holding pool entry"); #if UINT_MAX >= UINT32_MAX #define FFS32(x) ffs(x) @@ -39,11 +39,11 @@ #include "lib/if_clippy.c" #endif -DEFINE_MTYPE_STATIC(LIB, IF, "Interface") -DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected") -DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected") -DEFINE_MTYPE(LIB, CONNECTED_LABEL, "Connected interface label") -DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters") +DEFINE_MTYPE_STATIC(LIB, IF, "Interface"); +DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected"); +DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected"); +DEFINE_MTYPE(LIB, CONNECTED_LABEL, "Connected interface label"); +DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters"); static struct interface *if_lookup_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id); @@ -53,10 +53,10 @@ static int if_cmp_index_func(const struct interface *ifp1, RB_GENERATE(if_name_head, interface, name_entry, if_cmp_func); RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func); -DEFINE_QOBJ_TYPE(interface) +DEFINE_QOBJ_TYPE(interface); -DEFINE_HOOK(if_add, (struct interface * ifp), (ifp)) -DEFINE_KOOH(if_del, (struct interface * ifp), (ifp)) +DEFINE_HOOK(if_add, (struct interface * ifp), (ifp)); +DEFINE_KOOH(if_del, (struct interface * ifp), (ifp)); static struct interface_master{ int (*create_hook)(struct interface *ifp); @@ -31,7 +31,7 @@ extern "C" { #endif -DECLARE_MTYPE(CONNECTED_LABEL) +DECLARE_MTYPE(CONNECTED_LABEL); /* Interface link-layer type, if known. Derived from: * @@ -301,14 +301,14 @@ struct interface { */ bool configured; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(if_name_head, interface); RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func) RB_HEAD(if_index_head, interface); RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_index_func) -DECLARE_QOBJ_TYPE(interface) +DECLARE_QOBJ_TYPE(interface); #define IFNAME_RB_INSERT(vrf, ifp) \ ({ \ @@ -378,8 +378,8 @@ DECLARE_QOBJ_TYPE(interface) * can use 1000+ so they run after the daemon has initialised daemon-specific * interface data */ -DECLARE_HOOK(if_add, (struct interface * ifp), (ifp)) -DECLARE_KOOH(if_del, (struct interface * ifp), (ifp)) +DECLARE_HOOK(if_add, (struct interface * ifp), (ifp)); +DECLARE_KOOH(if_del, (struct interface * ifp), (ifp)); #define METRIC_MAX (~0) diff --git a/lib/if_rmap.c b/lib/if_rmap.c index 1973d40be4..8282e476df 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -26,10 +26,11 @@ #include "if.h" #include "if_rmap.h" -DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container") -DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME, "Interface route map container name") -DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map") -DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name") +DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container"); +DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME, + "Interface route map container name"); +DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map"); +DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name"); static struct list *if_rmap_ctx_list; diff --git a/lib/keychain.c b/lib/keychain.c index 82fd6a65f2..db5c23b1ba 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -25,11 +25,11 @@ #include "linklist.h" #include "keychain.h" -DEFINE_MTYPE_STATIC(LIB, KEY, "Key") -DEFINE_MTYPE_STATIC(LIB, KEYCHAIN, "Key chain") +DEFINE_MTYPE_STATIC(LIB, KEY, "Key"); +DEFINE_MTYPE_STATIC(LIB, KEYCHAIN, "Key chain"); -DEFINE_QOBJ_TYPE(keychain) -DEFINE_QOBJ_TYPE(key) +DEFINE_QOBJ_TYPE(keychain); +DEFINE_QOBJ_TYPE(key); /* Master list of key chain. */ static struct list *keychain_list; diff --git a/lib/keychain.h b/lib/keychain.h index e5cf39f7c6..eb6d2f175e 100644 --- a/lib/keychain.h +++ b/lib/keychain.h @@ -32,9 +32,9 @@ struct keychain { struct list *key; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(keychain) +DECLARE_QOBJ_TYPE(keychain); struct key_range { time_t start; @@ -51,9 +51,9 @@ struct key { struct key_range send; struct key_range accept; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(key) +DECLARE_QOBJ_TYPE(key); extern void keychain_init(void); extern struct keychain *keychain_lookup(const char *); diff --git a/lib/ldp_sync.c b/lib/ldp_sync.c index c9d7eb37cf..8912d15589 100644 --- a/lib/ldp_sync.c +++ b/lib/ldp_sync.c @@ -31,7 +31,7 @@ #include "ldp_sync.h" /* Library code */ -DEFINE_MTYPE_STATIC(LIB, LDP_SYNC_INFO, "LDP SYNC info") +DEFINE_MTYPE_STATIC(LIB, LDP_SYNC_INFO, "LDP SYNC info"); /* * ldp_sync_info_create - Allocate the LDP_SYNC information diff --git a/lib/libfrr.c b/lib/libfrr.c index 51b97369c9..5b0a523fb5 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -45,10 +45,10 @@ #include "defaults.h" #include "frrscript.h" -DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm)) -DEFINE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm)) -DEFINE_KOOH(frr_early_fini, (), ()) -DEFINE_KOOH(frr_fini, (), ()) +DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm)); +DEFINE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm)); +DEFINE_KOOH(frr_early_fini, (), ()); +DEFINE_KOOH(frr_fini, (), ()); const char frr_sysconfdir[] = SYSCONFDIR; char frr_vtydir[256]; diff --git a/lib/libfrr.h b/lib/libfrr.h index 825f502bdf..db0f364986 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -124,8 +124,8 @@ struct frr_daemon_info { __VA_ARGS__}; \ FRR_COREMOD_SETUP(.name = #execname, \ .description = #execname " daemon", \ - .version = FRR_VERSION, ) \ -/* end */ + .version = FRR_VERSION, ); \ + MACRO_REQUIRE_SEMICOLON() /* end */ extern void frr_init_vtydir(void); extern void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv); @@ -141,8 +141,8 @@ extern enum frr_cli_mode frr_get_cli_mode(void); extern uint32_t frr_get_fd_limit(void); extern bool frr_is_startup_fd(int fd); -DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm)) -DECLARE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm)) +DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm)); +DECLARE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm)); extern void frr_config_fork(void); extern void frr_run(struct thread_master *master); @@ -153,10 +153,10 @@ extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, /* these two are before the protocol daemon does its own shutdown * it's named this way being the counterpart to frr_late_init */ -DECLARE_KOOH(frr_early_fini, (), ()) +DECLARE_KOOH(frr_early_fini, (), ()); extern void frr_early_fini(void); /* and these two are after the daemon did its own cleanup */ -DECLARE_KOOH(frr_fini, (), ()) +DECLARE_KOOH(frr_fini, (), ()); extern void frr_fini(void); extern char config_default[512]; diff --git a/lib/link_state.c b/lib/link_state.c index ecf0d0698d..7f0d2a1245 100644 --- a/lib/link_state.c +++ b/lib/link_state.c @@ -36,7 +36,7 @@ #include "link_state.h" /* Link State Memory allocation */ -DEFINE_MTYPE_STATIC(LIB, LS_DB, "Link State Database") +DEFINE_MTYPE_STATIC(LIB, LS_DB, "Link State Database"); /** * Link State Node management functions diff --git a/lib/link_state.h b/lib/link_state.h index 93669f5b23..f9eb59b76a 100644 --- a/lib/link_state.h +++ b/lib/link_state.h @@ -324,7 +324,7 @@ extern int ls_attributes_same(struct ls_attributes *a1, */ /* Link State Vertex structure */ -PREDECL_RBTREE_UNIQ(vertices) +PREDECL_RBTREE_UNIQ(vertices); struct ls_vertex { struct vertices_item entry; /* Entry in RB Tree */ uint64_t key; /* Unique Key identifier */ @@ -335,7 +335,7 @@ struct ls_vertex { }; /* Link State Edge structure */ -PREDECL_RBTREE_UNIQ(edges) +PREDECL_RBTREE_UNIQ(edges); struct ls_edge { struct edges_item entry; /* Entry in RB tree */ uint64_t key; /* Unique Key identifier */ @@ -345,7 +345,7 @@ struct ls_edge { }; /* Link State Subnet structure */ -PREDECL_RBTREE_UNIQ(subnets) +PREDECL_RBTREE_UNIQ(subnets); struct ls_subnet { struct subnets_item entry; /* Entry in RB tree */ struct prefix key; /* Unique Key identifier */ @@ -359,21 +359,21 @@ macro_inline int vertex_cmp(const struct ls_vertex *node1, { return (node1->key - node2->key); } -DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp) +DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp); macro_inline int edge_cmp(const struct ls_edge *edge1, const struct ls_edge *edge2) { return (edge1->key - edge2->key); } -DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp) +DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp); macro_inline int subnet_cmp(const struct ls_subnet *a, const struct ls_subnet *b) { return prefix_cmp(&a->key, &b->key); } -DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp) +DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp); /* Link State TED Structure */ struct ls_ted { diff --git a/lib/linklist.c b/lib/linklist.c index 43c2002231..5de6c8a817 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -25,8 +25,8 @@ #include "memory.h" #include "libfrr_trace.h" -DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List") -DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node") +DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List"); +DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node"); struct list *list_new(void) { diff --git a/lib/log_vty.c b/lib/log_vty.c index d1dcac2340..c26621ae99 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -33,7 +33,7 @@ #define ZLOG_MAXLVL(a, b) MAX(a, b) -DEFINE_HOOK(zlog_rotate, (), ()) +DEFINE_HOOK(zlog_rotate, (), ()); static const int log_default_lvl = LOG_DEBUG; @@ -532,6 +532,28 @@ DEFUN (no_config_log_timestamp_precision, return CMD_SUCCESS; } +DEFPY (config_log_ec, + config_log_ec_cmd, + "[no] log error-category", + NO_STR + "Logging control\n" + "Prefix log message text with [EC 9999] code\n") +{ + zlog_set_prefix_ec(!no); + return CMD_SUCCESS; +} + +DEFPY (config_log_xid, + config_log_xid_cmd, + "[no] log unique-id", + NO_STR + "Logging control\n" + "Prefix log message text with [XXXXX-XXXXX] identifier\n") +{ + zlog_set_prefix_xid(!no); + return CMD_SUCCESS; +} + DEFPY (config_log_filterfile, config_log_filterfile_cmd, "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]", @@ -699,6 +721,11 @@ void log_config_write(struct vty *vty) if (zt_file.ts_subsec > 0) vty_out(vty, "log timestamp precision %d\n", zt_file.ts_subsec); + + if (!zlog_get_prefix_ec()) + vty_out(vty, "no log error-category\n"); + if (!zlog_get_prefix_xid()) + vty_out(vty, "no log unique-id\n"); } static int log_vty_init(const char *progname, const char *protoname, @@ -707,6 +734,9 @@ static int log_vty_init(const char *progname, const char *protoname, zlog_progname = progname; zlog_protoname = protoname; + zlog_set_prefix_ec(true); + zlog_set_prefix_xid(true); + zlog_filterfile_init(&zt_filterfile); zlog_file_set_fd(&zt_stdout, STDOUT_FILENO); @@ -737,6 +767,8 @@ void log_cmd_init(void) install_element(CONFIG_NODE, &no_config_log_record_priority_cmd); install_element(CONFIG_NODE, &config_log_timestamp_precision_cmd); install_element(CONFIG_NODE, &no_config_log_timestamp_precision_cmd); + install_element(CONFIG_NODE, &config_log_ec_cmd); + install_element(CONFIG_NODE, &config_log_xid_cmd); install_element(VIEW_NODE, &show_log_filter_cmd); install_element(CONFIG_NODE, &log_filter_cmd); diff --git a/lib/log_vty.h b/lib/log_vty.h index 16c4475467..f0fb7d3dba 100644 --- a/lib/log_vty.h +++ b/lib/log_vty.h @@ -34,7 +34,7 @@ extern void log_config_write(struct vty *vty); extern int log_level_match(const char *s); extern void log_show_syslog(struct vty *vty); -DECLARE_HOOK(zlog_rotate, (), ()) +DECLARE_HOOK(zlog_rotate, (), ()); extern void zlog_rotate(void); #ifdef __cplusplus diff --git a/lib/memory.c b/lib/memory.c index a377d3b945..0dc8e90524 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -34,8 +34,8 @@ static struct memgroup *mg_first = NULL; struct memgroup **mg_insert = &mg_first; -DEFINE_MGROUP(LIB, "libfrr") -DEFINE_MTYPE(LIB, TMP, "Temporary memory") +DEFINE_MGROUP(LIB, "libfrr"); +DEFINE_MTYPE(LIB, TMP, "Temporary memory"); static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr) { diff --git a/lib/memory.h b/lib/memory.h index e9db12fce2..c95602f485 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -56,20 +56,20 @@ struct memgroup { /* macro usage: * * mydaemon.h - * DECLARE_MGROUP(MYDAEMON) - * DECLARE_MTYPE(MYDAEMON_COMMON) + * DECLARE_MGROUP(MYDAEMON); + * DECLARE_MTYPE(MYDAEMON_COMMON); * * mydaemon.c - * DEFINE_MGROUP(MYDAEMON, "my daemon memory") + * DEFINE_MGROUP(MYDAEMON, "my daemon memory"); * DEFINE_MTYPE(MYDAEMON, MYDAEMON_COMMON, - * "this mtype is used in multiple files in mydaemon") + * "this mtype is used in multiple files in mydaemon"); * foo = qmalloc(MTYPE_MYDAEMON_COMMON, sizeof(*foo)) * * mydaemon_io.c * bar = qmalloc(MTYPE_MYDAEMON_COMMON, sizeof(*bar)) * * DEFINE_MTYPE_STATIC(MYDAEMON, MYDAEMON_IO, - * "this mtype is used only in this file") + * "this mtype is used only in this file"); * baz = qmalloc(MTYPE_MYDAEMON_IO, sizeof(*baz)) * * Note: Naming conventions (MGROUP_ and MTYPE_ prefixes are enforced @@ -78,7 +78,7 @@ struct memgroup { * but MGROUP_* aren't. */ -#define DECLARE_MGROUP(name) extern struct memgroup _mg_##name; +#define DECLARE_MGROUP(name) extern struct memgroup _mg_##name #define _DEFINE_MGROUP(mname, desc, ...) \ struct memgroup _mg_##mname \ __attribute__((section(".data.mgroups"))) = { \ @@ -104,7 +104,7 @@ struct memgroup { _mg_##mname.next->ref = _mg_##mname.ref; \ *_mg_##mname.ref = _mg_##mname.next; \ } \ - /* end */ + MACRO_REQUIRE_SEMICOLON() /* end */ #define DEFINE_MGROUP(mname, desc) \ _DEFINE_MGROUP(mname, desc, ) @@ -112,7 +112,7 @@ struct memgroup { _DEFINE_MGROUP(mname, desc, .active_at_exit = true) #define DECLARE_MTYPE(name) \ - extern struct memtype MTYPE_##name[1]; \ + extern struct memtype MTYPE_##name[1] \ /* end */ #define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \ @@ -140,7 +140,7 @@ struct memgroup { MTYPE_##mname->next->ref = MTYPE_##mname->ref; \ *MTYPE_##mname->ref = MTYPE_##mname->next; \ } \ - /* end */ + MACRO_REQUIRE_SEMICOLON() /* end */ #define DEFINE_MTYPE(group, name, desc) \ DEFINE_MTYPE_ATTR(group, name, , desc) \ @@ -150,8 +150,8 @@ struct memgroup { DEFINE_MTYPE_ATTR(group, name, static, desc) \ /* end */ -DECLARE_MGROUP(LIB) -DECLARE_MTYPE(TMP) +DECLARE_MGROUP(LIB); +DECLARE_MTYPE(TMP); extern void *qmalloc(struct memtype *mt, size_t size) diff --git a/lib/module.c b/lib/module.c index 3d299a6a2e..d2491a3479 100644 --- a/lib/module.c +++ b/lib/module.c @@ -27,8 +27,8 @@ #include "memory.h" #include "version.h" -DEFINE_MTYPE_STATIC(LIB, MODULE_LOADNAME, "Module loading name") -DEFINE_MTYPE_STATIC(LIB, MODULE_LOADARGS, "Module loading arguments") +DEFINE_MTYPE_STATIC(LIB, MODULE_LOADNAME, "Module loading name"); +DEFINE_MTYPE_STATIC(LIB, MODULE_LOADARGS, "Module loading arguments"); static struct frrmod_info frrmod_default_info = { .name = "libfrr", @@ -43,7 +43,7 @@ union _frrmod_runtime_u frrmod_default = { }, }; -XREF_SETUP() +XREF_SETUP(); // if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE) // union _frrmod_runtime_u _frrmod_this_module diff --git a/lib/module.h b/lib/module.h index 5d8d9cfbcc..6275877cb3 100644 --- a/lib/module.h +++ b/lib/module.h @@ -79,12 +79,13 @@ extern union _frrmod_runtime_u _frrmod_this_module; NULL, \ &_frrmod_info, \ }}; \ - XREF_SETUP() \ - /* end */ + XREF_SETUP(); \ + MACRO_REQUIRE_SEMICOLON() /* end */ #define FRR_MODULE_SETUP(...) \ - FRR_COREMOD_SETUP(__VA_ARGS__) \ - DSO_SELF struct frrmod_runtime *frr_module = &_frrmod_this_module.r; + FRR_COREMOD_SETUP(__VA_ARGS__); \ + DSO_SELF struct frrmod_runtime *frr_module = &_frrmod_this_module.r; \ + MACRO_REQUIRE_SEMICOLON() /* end */ extern struct frrmod_runtime *frrmod_list; diff --git a/lib/netns_linux.c b/lib/netns_linux.c index c688433983..cde842b88c 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -40,8 +40,8 @@ #include "vrf.h" #include "lib_errors.h" -DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context") -DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name") +DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context"); +DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name"); static inline int ns_compare(const struct ns *ns, const struct ns *ns2); static struct ns *ns_lookup_name_internal(const char *name); diff --git a/lib/netns_other.c b/lib/netns_other.c index 3fc4b8df4b..b6570d3b9e 100644 --- a/lib/netns_other.c +++ b/lib/netns_other.c @@ -26,8 +26,8 @@ #include "log.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context") -DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name") +DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context"); +DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name"); static inline int ns_compare(const struct ns *ns, const struct ns *ns2); diff --git a/lib/nexthop.c b/lib/nexthop.c index dd8c108205..17ef95c687 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -34,8 +34,8 @@ #include "vrf.h" #include "nexthop_group.h" -DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop") -DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label") +DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop"); +DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label"); static int _nexthop_labels_cmp(const struct nexthop *nh1, const struct nexthop *nh2) diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index dee98ad8d7..4fee9bde3c 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -32,7 +32,7 @@ #include "lib/nexthop_group_clippy.c" #endif -DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group") +DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group"); /* * Internal struct used to hold nhg config strings @@ -620,7 +620,7 @@ static void nhgc_delete(struct nexthop_group_cmd *nhgc) XFREE(MTYPE_TMP, nhgc); } -DEFINE_QOBJ_TYPE(nexthop_group_cmd) +DEFINE_QOBJ_TYPE(nexthop_group_cmd); DEFUN_NOSH(nexthop_group, nexthop_group_cmd, "nexthop-group NHGNAME", "Enter into the nexthop-group submode\n" diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 5f7bde0def..8e75e5c6ac 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -97,12 +97,12 @@ struct nexthop_group_cmd { struct list *nhg_list; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(nhgc_entry_head, nexthp_group_cmd); RB_PROTOTYPE(nhgc_entry_head, nexthop_group_cmd, nhgc_entry, nexthop_group_cmd_compare) -DECLARE_QOBJ_TYPE(nexthop_group_cmd) +DECLARE_QOBJ_TYPE(nexthop_group_cmd); /* * Initialize nexthop_groups. If you are interested in when diff --git a/lib/northbound.c b/lib/northbound.c index b6d3518285..34ad5dbfa9 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -32,9 +32,9 @@ #include "northbound_db.h" #include "frrstr.h" -DEFINE_MTYPE_STATIC(LIB, NB_NODE, "Northbound Node") -DEFINE_MTYPE_STATIC(LIB, NB_CONFIG, "Northbound Configuration") -DEFINE_MTYPE_STATIC(LIB, NB_CONFIG_ENTRY, "Northbound Configuration Entry") +DEFINE_MTYPE_STATIC(LIB, NB_NODE, "Northbound Node"); +DEFINE_MTYPE_STATIC(LIB, NB_CONFIG, "Northbound Configuration"); +DEFINE_MTYPE_STATIC(LIB, NB_CONFIG_ENTRY, "Northbound Configuration Entry"); /* Running configuration - shouldn't be modified directly. */ struct nb_config *running_config; @@ -1260,27 +1260,36 @@ static int nb_callback_configuration(struct nb_context *context, } if (ret != NB_OK) { - int priority; - enum lib_log_refs ref; - yang_dnode_get_path(dnode, xpath, sizeof(xpath)); switch (event) { case NB_EV_VALIDATE: - priority = LOG_WARNING; - ref = EC_LIB_NB_CB_CONFIG_VALIDATE; + flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE, + "error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]%s%s", + nb_err_name(ret), nb_event_name(event), + nb_operation_name(operation), xpath, + errmsg[0] ? " message: " : "", errmsg); break; case NB_EV_PREPARE: - priority = LOG_WARNING; - ref = EC_LIB_NB_CB_CONFIG_PREPARE; + flog_warn(EC_LIB_NB_CB_CONFIG_PREPARE, + "error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]%s%s", + nb_err_name(ret), nb_event_name(event), + nb_operation_name(operation), xpath, + errmsg[0] ? " message: " : "", errmsg); break; case NB_EV_ABORT: - priority = LOG_WARNING; - ref = EC_LIB_NB_CB_CONFIG_ABORT; + flog_warn(EC_LIB_NB_CB_CONFIG_ABORT, + "error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]%s%s", + nb_err_name(ret), nb_event_name(event), + nb_operation_name(operation), xpath, + errmsg[0] ? " message: " : "", errmsg); break; case NB_EV_APPLY: - priority = LOG_ERR; - ref = EC_LIB_NB_CB_CONFIG_APPLY; + flog_err(EC_LIB_NB_CB_CONFIG_APPLY, + "error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]%s%s", + nb_err_name(ret), nb_event_name(event), + nb_operation_name(operation), xpath, + errmsg[0] ? " message: " : "", errmsg); break; default: flog_err(EC_LIB_DEVELOPMENT, @@ -1288,15 +1297,6 @@ static int nb_callback_configuration(struct nb_context *context, event, xpath); exit(1); } - - flog(priority, ref, - "error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", - nb_err_name(ret), nb_event_name(event), - nb_operation_name(operation), xpath); - if (strlen(errmsg) > 0) - flog(priority, ref, - "error processing configuration change: %s", - errmsg); } return ret; diff --git a/lib/northbound.h b/lib/northbound.h index 3e1342f985..21aad64a09 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -677,9 +677,9 @@ typedef int (*nb_oper_data_cb)(const struct lys_node *snode, /* Hooks. */ DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments), - (xpath, arguments)) -DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty)) -DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set)) + (xpath, arguments)); +DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty)); +DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set)); /* Northbound debugging records */ extern struct debug nb_dbg_cbs_config; diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c index 8acba9fd2b..3d8771ffbc 100644 --- a/lib/northbound_confd.c +++ b/lib/northbound_confd.c @@ -32,7 +32,7 @@ #include <confd_dp.h> #include <confd_maapi.h> -DEFINE_MTYPE_STATIC(LIB, CONFD, "ConfD module") +DEFINE_MTYPE_STATIC(LIB, CONFD, "ConfD module"); static struct debug nb_dbg_client_confd = {0, "Northbound client: ConfD"}; @@ -1483,4 +1483,5 @@ static int frr_confd_module_init(void) FRR_MODULE_SETUP(.name = "frr_confd", .version = FRR_VERSION, .description = "FRR ConfD integration module", - .init = frr_confd_module_init, ) + .init = frr_confd_module_init, +); diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp index abdae993b1..d042e15dad 100644 --- a/lib/northbound_grpc.cpp +++ b/lib/northbound_grpc.cpp @@ -1412,4 +1412,5 @@ static int frr_grpc_module_init(void) FRR_MODULE_SETUP(.name = "frr_grpc", .version = FRR_VERSION, .description = "FRR gRPC northbound module", - .init = frr_grpc_module_init, ) + .init = frr_grpc_module_init, +); diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c index c027f4de72..9fc640ceea 100644 --- a/lib/northbound_sysrepo.c +++ b/lib/northbound_sysrepo.c @@ -32,7 +32,7 @@ #include <sysrepo/values.h> #include <sysrepo/xpath.h> -DEFINE_MTYPE_STATIC(LIB, SYSREPO, "Sysrepo module") +DEFINE_MTYPE_STATIC(LIB, SYSREPO, "Sysrepo module"); static struct debug nb_dbg_client_sysrepo = {0, "Northbound client: Sysrepo"}; @@ -768,4 +768,5 @@ static int frr_sr_module_init(void) FRR_MODULE_SETUP(.name = "frr_sysrepo", .version = FRR_VERSION, .description = "FRR sysrepo integration module", - .init = frr_sr_module_init, ) + .init = frr_sr_module_init, +); diff --git a/lib/plist.c b/lib/plist.c index fe4689becd..92c8b8ee55 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -33,10 +33,10 @@ #include "plist_int.h" -DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List") -DEFINE_MTYPE_STATIC(LIB, MPREFIX_LIST_STR, "Prefix List Str") -DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_ENTRY, "Prefix List Entry") -DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_TRIE, "Prefix List Trie Table") +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List"); +DEFINE_MTYPE_STATIC(LIB, MPREFIX_LIST_STR, "Prefix List Str"); +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_ENTRY, "Prefix List Entry"); +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_TRIE, "Prefix List Trie Table"); /* not currently changeable, code assumes bytes further down */ #define PLC_BITS 8 diff --git a/lib/prefix.c b/lib/prefix.c index 5e5c2d89a8..afc4d3d5c2 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -32,8 +32,8 @@ #include "printfrr.h" #include "vxlan.h" -DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") -DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec") +DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix"); +DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec"); /* Maskbit. */ static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, diff --git a/lib/printfrr.h b/lib/printfrr.h index a775e1517b..418e839d97 100644 --- a/lib/printfrr.h +++ b/lib/printfrr.h @@ -160,6 +160,30 @@ void printfrr_ext_reg(const struct printfrr_ext *); } \ /* end */ +/* fbuf helper functions */ + +static inline ssize_t bputs(struct fbuf *buf, const char *str) +{ + size_t len = strlen(str); + size_t ncopy; + + if (!buf) + return len; + + ncopy = MIN(len, (size_t)(buf->buf + buf->len - buf->pos)); + memcpy(buf->pos, str, ncopy); + buf->pos += ncopy; + + return len; +} + +static inline ssize_t bputch(struct fbuf *buf, char ch) +{ + if (buf && buf->pos < buf->buf + buf->len) + *buf->pos++ = ch; + return 1; +} + #ifdef __cplusplus } #endif diff --git a/lib/privs.c b/lib/privs.c index 5ca3c0d886..49761af871 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -28,7 +28,7 @@ #include "lib_errors.h" #include "lib/queue.h" -DEFINE_MTYPE_STATIC(LIB, PRIVS, "Privilege information") +DEFINE_MTYPE_STATIC(LIB, PRIVS, "Privilege information"); /* * Different capabilities/privileges apis have different characteristics: some diff --git a/lib/pullwr.c b/lib/pullwr.c index 0c326f29d4..15563d2471 100644 --- a/lib/pullwr.c +++ b/lib/pullwr.c @@ -48,8 +48,8 @@ struct pullwr { int64_t maxspin; /* PULLWR_MAXSPIN */ }; -DEFINE_MTYPE_STATIC(LIB, PULLWR_HEAD, "pull-driven write controller") -DEFINE_MTYPE_STATIC(LIB, PULLWR_BUF, "pull-driven write buffer") +DEFINE_MTYPE_STATIC(LIB, PULLWR_HEAD, "pull-driven write controller"); +DEFINE_MTYPE_STATIC(LIB, PULLWR_BUF, "pull-driven write buffer"); static int pullwr_run(struct thread *t); diff --git a/lib/qobj.c b/lib/qobj.c index cb3254cbe9..c6cb36c058 100644 --- a/lib/qobj.c +++ b/lib/qobj.c @@ -43,7 +43,7 @@ static int qobj_cmp(const struct qobj_node *na, const struct qobj_node *nb) } DECLARE_HASH(qobj_nodes, struct qobj_node, nodehash, - qobj_cmp, qobj_hash) + qobj_cmp, qobj_hash); static pthread_rwlock_t nodes_lock; static struct qobj_nodes_head nodes = { }; diff --git a/lib/qobj.h b/lib/qobj.h index 400ae0151c..5012c98d74 100644 --- a/lib/qobj.h +++ b/lib/qobj.h @@ -83,7 +83,7 @@ struct qobj_nodetype { RESERVED_SPACE_STRUCT(qobj_nodetype_capnp, capnp, 256) }; -PREDECL_HASH(qobj_nodes) +PREDECL_HASH(qobj_nodes); /* anchor to be embedded somewhere in the object's struct */ struct qobj_node { @@ -92,7 +92,7 @@ struct qobj_node { const struct qobj_nodetype *type; }; -#define QOBJ_FIELDS struct qobj_node qobj_node; +#define QOBJ_FIELDS struct qobj_node qobj_node /* call these at the end of any _create function (QOBJ_REG) * and beginning of any _destroy function (QOBJ_UNREG) */ @@ -118,16 +118,19 @@ void *qobj_get_typed(uint64_t id, const struct qobj_nodetype *type); /* type declarations */ #define DECLARE_QOBJ_TYPE(structname) \ - extern const struct qobj_nodetype qobj_t_##structname; + extern const struct qobj_nodetype qobj_t_##structname \ + /* end */ #define DEFINE_QOBJ_TYPE(structname) \ const struct qobj_nodetype qobj_t_##structname = { \ .node_member_offset = \ - (ptrdiff_t)offsetof(struct structname, qobj_node)}; + (ptrdiff_t)offsetof(struct structname, qobj_node)} \ + /* end */ #define DEFINE_QOBJ_TYPE_INIT(structname, ...) \ const struct qobj_nodetype qobj_t_##structname = { \ .node_member_offset = \ (ptrdiff_t)offsetof(struct structname, qobj_node), \ - __VA_ARGS__}; + __VA_ARGS__} \ + /* end */ /* ID dereference with typecheck. * will return NULL if id not found or wrong type. */ diff --git a/lib/resolver.c b/lib/resolver.c index c01284e29e..c2153e0a5e 100644 --- a/lib/resolver.c +++ b/lib/resolver.c @@ -21,7 +21,7 @@ #include "command.h" #include "xref.h" -XREF_SETUP() +XREF_SETUP(); struct resolver_state { ares_channel channel; diff --git a/lib/ringbuf.c b/lib/ringbuf.c index 26c4e744b4..49221e7cb3 100644 --- a/lib/ringbuf.c +++ b/lib/ringbuf.c @@ -22,7 +22,7 @@ #include "ringbuf.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, RINGBUFFER, "Ring buffer") +DEFINE_MTYPE_STATIC(LIB, RINGBUFFER, "Ring buffer"); struct ringbuf *ringbuf_new(size_t size) { diff --git a/lib/routemap.c b/lib/routemap.c index 7714086672..b836b55aad 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -33,17 +33,17 @@ #include "lib_errors.h" #include "table.h" -DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP, "Route map") -DEFINE_MTYPE(LIB, ROUTE_MAP_NAME, "Route map name") -DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_INDEX, "Route map index") -DEFINE_MTYPE(LIB, ROUTE_MAP_RULE, "Route map rule") -DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_RULE_STR, "Route map rule str") -DEFINE_MTYPE(LIB, ROUTE_MAP_COMPILED, "Route map compiled") -DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP, "Route map dependency") -DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP_DATA, "Route map dependency data") - -DEFINE_QOBJ_TYPE(route_map_index) -DEFINE_QOBJ_TYPE(route_map) +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP, "Route map"); +DEFINE_MTYPE(LIB, ROUTE_MAP_NAME, "Route map name"); +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_INDEX, "Route map index"); +DEFINE_MTYPE(LIB, ROUTE_MAP_RULE, "Route map rule"); +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_RULE_STR, "Route map rule str"); +DEFINE_MTYPE(LIB, ROUTE_MAP_COMPILED, "Route map compiled"); +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP, "Route map dependency"); +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP_DATA, "Route map dependency data"); + +DEFINE_QOBJ_TYPE(route_map_index); +DEFINE_QOBJ_TYPE(route_map); #define IPv4_PREFIX_LIST "ip address prefix-list" #define IPv6_PREFIX_LIST "ipv6 address prefix-list" diff --git a/lib/routemap.h b/lib/routemap.h index 3e208c8cb5..bad3ca6d3d 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -32,9 +32,9 @@ extern "C" { #endif -DECLARE_MTYPE(ROUTE_MAP_NAME) -DECLARE_MTYPE(ROUTE_MAP_RULE) -DECLARE_MTYPE(ROUTE_MAP_COMPILED) +DECLARE_MTYPE(ROUTE_MAP_NAME); +DECLARE_MTYPE(ROUTE_MAP_RULE); +DECLARE_MTYPE(ROUTE_MAP_COMPILED); /* Route map's type. */ enum route_map_type { RMAP_PERMIT, RMAP_DENY, RMAP_ANY }; @@ -190,9 +190,9 @@ struct route_map_index { /* List of match/sets contexts. */ TAILQ_HEAD(, routemap_hook_context) rhclist; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(route_map_index) +DECLARE_QOBJ_TYPE(route_map_index); /* Route map list structure. */ struct route_map { @@ -225,9 +225,9 @@ struct route_map { struct route_table *ipv4_prefix_table; struct route_table *ipv6_prefix_table; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(route_map) +DECLARE_QOBJ_TYPE(route_map); /* Prototypes. */ extern void route_map_init(void); diff --git a/lib/routing_nb.h b/lib/routing_nb.h index ffba631a10..bdd12b262b 100644 --- a/lib/routing_nb.h +++ b/lib/routing_nb.h @@ -24,7 +24,7 @@ int routing_control_plane_protocols_control_plane_protocol_destroy( * callbacks for routing to handle configuration events * based on the control plane protocol */ -DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args)) +DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args)); void routing_control_plane_protocols_register_vrf_dependency(void); diff --git a/lib/routing_nb_config.c b/lib/routing_nb_config.c index 17698d2b87..f66f32015d 100644 --- a/lib/routing_nb_config.c +++ b/lib/routing_nb_config.c @@ -24,7 +24,7 @@ #include "routing_nb.h" -DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args)) +DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args)); /* * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol diff --git a/lib/skiplist.c b/lib/skiplist.c index b79dfa6772..fc42857418 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -63,8 +63,8 @@ #include "lib_errors.h" #include "network.h" -DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List") -DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node") +DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List"); +DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node"); #define BitsInRandom 31 diff --git a/lib/smux.h b/lib/smux.h index 57128b7928..c063833e41 100644 --- a/lib/smux.h +++ b/lib/smux.h @@ -157,7 +157,7 @@ extern void oid_copy_int(oid oid[], int *val); extern void oid2string(oid oid[], int len, char *string); extern void oid_copy_str(oid oid[], const char *string, int len); -DECLARE_HOOK(agentx_enabled, (), ()) +DECLARE_HOOK(agentx_enabled, (), ()); #ifdef __cplusplus } diff --git a/lib/sockunion.c b/lib/sockunion.c index c701da1e03..d65235b41c 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -29,7 +29,7 @@ #include "lib_errors.h" #include "printfrr.h" -DEFINE_MTYPE_STATIC(LIB, SOCKUNION, "Socket union") +DEFINE_MTYPE_STATIC(LIB, SOCKUNION, "Socket union"); const char *inet_sutop(const union sockunion *su, char *str) { diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c index ac6dd29f06..a273e93463 100644 --- a/lib/spf_backoff.c +++ b/lib/spf_backoff.c @@ -33,8 +33,8 @@ #include "thread.h" #include "vty.h" -DEFINE_MTYPE_STATIC(LIB, SPF_BACKOFF, "SPF backoff") -DEFINE_MTYPE_STATIC(LIB, SPF_BACKOFF_NAME, "SPF backoff name") +DEFINE_MTYPE_STATIC(LIB, SPF_BACKOFF, "SPF backoff"); +DEFINE_MTYPE_STATIC(LIB, SPF_BACKOFF_NAME, "SPF backoff name"); static bool debug_spf_backoff = false; #define backoff_debug(...) \ diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index ef82b7ac01..a115507192 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -30,7 +30,7 @@ #include "table.h" #include "printfrr.h" -DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node") +DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node"); /* ----- functions to manage rnodes _with_ srcdest table ----- */ struct srcdest_rnode { diff --git a/lib/stream.c b/lib/stream.c index ef73c2fdc9..904ee73b10 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -31,8 +31,8 @@ #include "frr_pthread.h" #include "lib_errors.h" -DEFINE_MTYPE_STATIC(LIB, STREAM, "Stream") -DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") +DEFINE_MTYPE_STATIC(LIB, STREAM, "Stream"); +DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO"); /* Tests whether a position is valid */ #define GETP_VALID(S, G) ((G) <= (S)->endp) diff --git a/lib/strlcat.c b/lib/strlcat.c index 39773d9ac8..a046822a94 100644 --- a/lib/strlcat.c +++ b/lib/strlcat.c @@ -64,10 +64,8 @@ size_t strlcat(char *__restrict dest, (which the static_assert checks), then by the pigeonhole principle, the two input strings must overlap, which is undefined. */ -#if __STDC_VERSION__ >= 201112L _Static_assert(sizeof(uintptr_t) == sizeof(size_t), "theoretical maximum object size covers address space"); -#endif return dest_length + src_length; } #endif /* HAVE_STRLCAT */ diff --git a/lib/subdir.am b/lib/subdir.am index 38d1a3f773..bfd367b134 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -313,7 +313,7 @@ if SNMP lib_LTLIBRARIES += lib/libfrrsnmp.la endif -lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 lib_libfrrsnmp_la_LDFLAGS = -version-info 0:0:0 lib_libfrrsnmp_la_LIBADD = $(SNMP_LIBS) lib_libfrrsnmp_la_SOURCES = \ diff --git a/lib/table.c b/lib/table.c index 89e32182b5..dfd92c6189 100644 --- a/lib/table.c +++ b/lib/table.c @@ -29,8 +29,8 @@ #include "sockunion.h" #include "libfrr_trace.h" -DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table") -DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node") +DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table"); +DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node"); static void route_table_free(struct route_table *); @@ -41,7 +41,7 @@ static int route_table_hash_cmp(const struct route_node *a, } DECLARE_HASH(rn_hash_node, struct route_node, nodehash, route_table_hash_cmp, - prefix_hash_key) + prefix_hash_key); /* * route_table_init_with_delegate */ diff --git a/lib/table.h b/lib/table.h index 5d620d332b..7e383dce80 100644 --- a/lib/table.h +++ b/lib/table.h @@ -31,7 +31,7 @@ extern "C" { #endif -DECLARE_MTYPE(ROUTE_NODE) +DECLARE_MTYPE(ROUTE_NODE); /* * Forward declarations. @@ -59,7 +59,7 @@ struct route_table_delegate_t_ { route_table_destroy_node_func_t destroy_node; }; -PREDECL_HASH(rn_hash_node) +PREDECL_HASH(rn_hash_node); /* Routing table top structure. */ struct route_table { diff --git a/lib/termtable.c b/lib/termtable.c index b22a1ad387..ddf8822853 100644 --- a/lib/termtable.c +++ b/lib/termtable.c @@ -24,7 +24,7 @@ #include "memory.h" #include "termtable.h" -DEFINE_MTYPE_STATIC(LIB, TTABLE, "ASCII table") +DEFINE_MTYPE_STATIC(LIB, TTABLE, "ASCII table"); /* clang-format off */ const struct ttable_style ttable_styles[] = { diff --git a/lib/thread.c b/lib/thread.c index af01c75a44..866090341e 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -38,12 +38,12 @@ #include "libfrr_trace.h" #include "libfrr.h" -DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread") -DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master") -DEFINE_MTYPE_STATIC(LIB, THREAD_POLL, "Thread Poll Info") -DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") +DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread"); +DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master"); +DEFINE_MTYPE_STATIC(LIB, THREAD_POLL, "Thread Poll Info"); +DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats"); -DECLARE_LIST(thread_list, struct thread, threaditem) +DECLARE_LIST(thread_list, struct thread, threaditem); struct cancel_req { int flags; @@ -68,7 +68,7 @@ static int thread_timer_cmp(const struct thread *a, const struct thread *b) return 0; } -DECLARE_HEAP(thread_timer_list, struct thread, timeritem, thread_timer_cmp) +DECLARE_HEAP(thread_timer_list, struct thread, timeritem, thread_timer_cmp); #if defined(__APPLE__) #include <mach/mach.h> diff --git a/lib/thread.h b/lib/thread.h index cdef531ad4..af68331131 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -41,8 +41,8 @@ struct rusage_t { #define GETRUSAGE(X) thread_getrusage(X) -PREDECL_LIST(thread_list) -PREDECL_HEAP(thread_timer_list) +PREDECL_LIST(thread_list); +PREDECL_HEAP(thread_timer_list); struct fd_handler { /* number of pfd that fit in the allocated space of pfds. This is a diff --git a/lib/typerb.h b/lib/typerb.h index fca45e20d1..60e6d09016 100644 --- a/lib/typerb.h +++ b/lib/typerb.h @@ -65,7 +65,8 @@ struct typed_rb_entry *typed_rb_next(const struct typed_rb_entry *rbe); #define _PREDECL_RBTREE(prefix) \ struct prefix ## _head { struct typed_rb_root rr; }; \ -struct prefix ## _item { struct typed_rb_entry re; }; +struct prefix ## _item { struct typed_rb_entry re; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_RBTREE_UNIQ(var) { } #define INIT_RBTREE_NONUNIQ(var) { } @@ -140,7 +141,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->rr.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_RBTREE_UNIQ(prefix) \ _PREDECL_RBTREE(prefix) @@ -161,8 +162,8 @@ macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ } \ TYPESAFE_FIND(prefix, type) \ \ -_DECLARE_RBTREE(prefix, type, field, prefix ## __cmp, prefix ## __cmp) \ -/* ... */ +_DECLARE_RBTREE(prefix, type, field, prefix ## __cmp, prefix ## __cmp); \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_RBTREE_NONUNIQ(prefix) \ _PREDECL_RBTREE(prefix) @@ -188,8 +189,8 @@ macro_inline int prefix ## __cmp_uq(const struct typed_rb_entry *a, \ return 0; \ } \ \ -_DECLARE_RBTREE(prefix, type, field, prefix ## __cmp, prefix ## __cmp_uq) \ -/* ... */ +_DECLARE_RBTREE(prefix, type, field, prefix ## __cmp, prefix ## __cmp_uq); \ +MACRO_REQUIRE_SEMICOLON() /* end */ #ifdef __cplusplus } diff --git a/lib/typesafe.c b/lib/typesafe.c index 69796e2d81..76705fad0d 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -25,9 +25,9 @@ #include "memory.h" #include "network.h" -DEFINE_MTYPE_STATIC(LIB, TYPEDHASH_BUCKET, "Typed-hash bucket") -DEFINE_MTYPE_STATIC(LIB, SKIPLIST_OFLOW, "Skiplist overflow") -DEFINE_MTYPE_STATIC(LIB, HEAP_ARRAY, "Typed-heap array") +DEFINE_MTYPE_STATIC(LIB, TYPEDHASH_BUCKET, "Typed-hash bucket"); +DEFINE_MTYPE_STATIC(LIB, SKIPLIST_OFLOW, "Skiplist overflow"); +DEFINE_MTYPE_STATIC(LIB, HEAP_ARRAY, "Typed-heap array"); #if 0 static void hash_consistency_check(struct thash_head *head) diff --git a/lib/typesafe.h b/lib/typesafe.h index e134316dd9..27e7be1286 100644 --- a/lib/typesafe.h +++ b/lib/typesafe.h @@ -105,15 +105,16 @@ static inline void typesafe_list_add(struct slist_head *head, /* use as: * - * PREDECL_LIST(namelist) + * PREDECL_LIST(namelist); * struct name { * struct namelist_item nlitem; * } - * DECLARE_LIST(namelist, struct name, nlitem) + * DECLARE_LIST(namelist, struct name, nlitem); */ #define PREDECL_LIST(prefix) \ struct prefix ## _head { struct slist_head sh; }; \ -struct prefix ## _item { struct slist_item si; }; +struct prefix ## _item { struct slist_item si; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_LIST(var) { .sh = { .last_next = &var.sh.first, }, } @@ -191,7 +192,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->sh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ /* don't use these structs directly */ struct dlist_item { @@ -218,7 +219,8 @@ static inline void typesafe_dlist_add(struct dlist_head *head, */ #define PREDECL_DLIST(prefix) \ struct prefix ## _head { struct dlist_head dh; }; \ -struct prefix ## _item { struct dlist_item di; }; +struct prefix ## _item { struct dlist_item di; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_DLIST(var) { .dh = { \ .hitem = { &var.dh.hitem, &var.dh.hitem }, }, } @@ -295,7 +297,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->dh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ /* note: heap currently caps out at 4G items */ @@ -319,7 +321,8 @@ struct heap_head { #define PREDECL_HEAP(prefix) \ struct prefix ## _head { struct heap_head hh; }; \ -struct prefix ## _item { struct heap_item hi; }; +struct prefix ## _item { struct heap_item hi; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_HEAP(var) { } @@ -402,7 +405,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->hh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ extern void typesafe_heap_resize(struct heap_head *head, bool grow); extern void typesafe_heap_pushdown(struct heap_head *head, uint32_t index, @@ -438,7 +441,8 @@ struct ssort_head { */ #define _PREDECL_SORTLIST(prefix) \ struct prefix ## _head { struct ssort_head sh; }; \ -struct prefix ## _item { struct ssort_item si; }; +struct prefix ## _item { struct ssort_item si; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_SORTLIST_UNIQ(var) { } #define INIT_SORTLIST_NONUNIQ(var) { } @@ -537,10 +541,10 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->sh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define DECLARE_SORTLIST_UNIQ(prefix, type, field, cmpfn) \ - _DECLARE_SORTLIST(prefix, type, field, cmpfn, cmpfn) \ + _DECLARE_SORTLIST(prefix, type, field, cmpfn, cmpfn); \ \ macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ const type *item) \ @@ -555,7 +559,7 @@ macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ return container_of(sitem, type, field.si); \ } \ TYPESAFE_FIND(prefix, type) \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define DECLARE_SORTLIST_NONUNIQ(prefix, type, field, cmpfn) \ macro_inline int _ ## prefix ## _cmp(const type *a, const type *b) \ @@ -569,8 +573,8 @@ macro_inline int _ ## prefix ## _cmp(const type *a, const type *b) \ return 1; \ return 0; \ } \ - _DECLARE_SORTLIST(prefix, type, field, cmpfn, _ ## prefix ## _cmp) \ -/* ... */ + _DECLARE_SORTLIST(prefix, type, field, cmpfn, _ ## prefix ## _cmp); \ +MACRO_REQUIRE_SEMICOLON() /* end */ /* hash, "sorted" by hash value @@ -616,7 +620,8 @@ extern void typesafe_hash_shrink(struct thash_head *head); */ #define PREDECL_HASH(prefix) \ struct prefix ## _head { struct thash_head hh; }; \ -struct prefix ## _item { struct thash_item hi; }; +struct prefix ## _item { struct thash_item hi; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_HASH(var) { } @@ -734,7 +739,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->hh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ /* skiplist, sorted. * can be used as priority queue with add / pop @@ -769,7 +774,8 @@ struct sskip_head { */ #define _PREDECL_SKIPLIST(prefix) \ struct prefix ## _head { struct sskip_head sh; }; \ -struct prefix ## _item { struct sskip_item si; }; +struct prefix ## _item { struct sskip_item si; }; \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define INIT_SKIPLIST_UNIQ(var) { } #define INIT_SKIPLIST_NONUNIQ(var) { } @@ -840,7 +846,7 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ { \ return h->sh.count; \ } \ -/* ... */ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_SKIPLIST_UNIQ(prefix) \ _PREDECL_SKIPLIST(prefix) @@ -862,8 +868,8 @@ macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ TYPESAFE_FIND(prefix, type) \ \ _DECLARE_SKIPLIST(prefix, type, field, \ - prefix ## __cmp, prefix ## __cmp) \ -/* ... */ + prefix ## __cmp, prefix ## __cmp); \ +MACRO_REQUIRE_SEMICOLON() /* end */ #define PREDECL_SKIPLIST_NONUNIQ(prefix) \ _PREDECL_SKIPLIST(prefix) @@ -890,8 +896,8 @@ macro_inline int prefix ## __cmp_uq(const struct sskip_item *a, \ } \ \ _DECLARE_SKIPLIST(prefix, type, field, \ - prefix ## __cmp, prefix ## __cmp_uq) \ -/* ... */ + prefix ## __cmp, prefix ## __cmp_uq); \ +MACRO_REQUIRE_SEMICOLON() /* end */ extern struct sskip_item *typesafe_skiplist_add(struct sskip_head *head, diff --git a/lib/vector.c b/lib/vector.c index 0631e836f6..565c49fd59 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -23,8 +23,8 @@ #include "vector.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector") -DEFINE_MTYPE_STATIC(LIB, VECTOR_INDEX, "Vector index") +DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector"); +DEFINE_MTYPE_STATIC(LIB, VECTOR_INDEX, "Vector index"); /* Initialize vector : allocate memory and return vector. */ vector vector_init(unsigned int size) @@ -42,10 +42,10 @@ /* default VRF name value used when VRF backend is not NETNS */ #define VRF_DEFAULT_NAME_INTERNAL "default" -DEFINE_MTYPE_STATIC(LIB, VRF, "VRF") -DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") +DEFINE_MTYPE_STATIC(LIB, VRF, "VRF"); +DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map"); -DEFINE_QOBJ_TYPE(vrf) +DEFINE_QOBJ_TYPE(vrf); static __inline int vrf_id_compare(const struct vrf *, const struct vrf *); static __inline int vrf_name_compare(const struct vrf *, const struct vrf *); @@ -95,13 +95,13 @@ struct vrf { /* Back pointer to namespace context */ void *ns_ctxt; - QOBJ_FIELDS + QOBJ_FIELDS; }; RB_HEAD(vrf_id_head, vrf); RB_PROTOTYPE(vrf_id_head, vrf, id_entry, vrf_id_compare) RB_HEAD(vrf_name_head, vrf); RB_PROTOTYPE(vrf_name_head, vrf, name_entry, vrf_name_compare) -DECLARE_QOBJ_TYPE(vrf) +DECLARE_QOBJ_TYPE(vrf); /* Allow VRF with netns as backend */ enum vrf_backend_type { @@ -56,9 +56,9 @@ #include "lib/vty_clippy.c" #endif -DEFINE_MTYPE_STATIC(LIB, VTY, "VTY") -DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer") -DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history") +DEFINE_MTYPE_STATIC(LIB, VTY, "VTY"); +DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer"); +DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history"); /* Vty events */ enum event { diff --git a/lib/wheel.c b/lib/wheel.c index 5bdd6292f9..1a0469b256 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -24,8 +24,8 @@ #include "wheel.h" #include "log.h" -DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL, "Timer Wheel") -DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL_LIST, "Timer Wheel Slot List") +DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL, "Timer Wheel"); +DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL_LIST, "Timer Wheel Slot List"); static int debug_timer_wheel = 0; diff --git a/lib/workqueue.c b/lib/workqueue.c index 8eabdf52e7..2a8326c056 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -28,9 +28,9 @@ #include "command.h" #include "log.h" -DEFINE_MTYPE(LIB, WORK_QUEUE, "Work queue") -DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_ITEM, "Work queue item") -DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_NAME, "Work queue name string") +DEFINE_MTYPE(LIB, WORK_QUEUE, "Work queue"); +DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_ITEM, "Work queue item"); +DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_NAME, "Work queue name string"); /* master list of work_queues */ static struct list _work_queues; diff --git a/lib/workqueue.h b/lib/workqueue.h index 7c610f5dd6..b076ed0d28 100644 --- a/lib/workqueue.h +++ b/lib/workqueue.h @@ -30,7 +30,7 @@ extern "C" { #endif -DECLARE_MTYPE(WORK_QUEUE) +DECLARE_MTYPE(WORK_QUEUE); /* Hold time for the initial schedule of a queue run, in millisec */ #define WORK_QUEUE_DEFAULT_HOLD 50 diff --git a/lib/xref.c b/lib/xref.c index 40efe51363..a41f91a228 100644 --- a/lib/xref.c +++ b/lib/xref.c @@ -93,8 +93,6 @@ static void xref_add_one(const struct xref *xref) q = memrchr(filename, '/', p - filename); if (q) filename = q + 1; - else - filename = p + 1; } SHA256_Init(&sha); diff --git a/lib/xref.h b/lib/xref.h index b3243fa058..b1cb172b41 100644 --- a/lib/xref.h +++ b/lib/xref.h @@ -162,7 +162,7 @@ extern const struct xref * const __stop_xref_array[1] DSO_LOCAL; xref_block_add(&_xref_block); \ } \ asm(XREF_NOTE); \ - /* end */ + MACRO_REQUIRE_SEMICOLON() /* end */ /* the following blurb emits an ELF note indicating start and end of the xref * array in the binary. This is technically the "correct" entry point for diff --git a/lib/yang.c b/lib/yang.c index 383dc9f5eb..df3b07fb09 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -27,8 +27,8 @@ #include <libyang/user_types.h> -DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module") -DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure") +DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module"); +DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure"); /* libyang container. */ struct ly_ctx *ly_native_ctx; diff --git a/lib/yang_translator.c b/lib/yang_translator.c index 1f64675d6a..5b1d96f24c 100644 --- a/lib/yang_translator.c +++ b/lib/yang_translator.c @@ -26,9 +26,9 @@ #include "yang_translator.h" #include "frrstr.h" -DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR, "YANG Translator") -DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR_MODULE, "YANG Translator Module") -DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR_MAPPING, "YANG Translator Mapping") +DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR, "YANG Translator"); +DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR_MODULE, "YANG Translator Module"); +DEFINE_MTYPE_STATIC(LIB, YANG_TRANSLATOR_MAPPING, "YANG Translator Mapping"); /* Generate the yang_translators tree. */ static inline int yang_translator_compare(const struct yang_translator *a, diff --git a/lib/zassert.h b/lib/zassert.h index e6b254ee8d..527282c4f2 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -28,14 +28,7 @@ extern void _zlog_assert_failed(const char *assertion, const char *file, __attribute__((noreturn)); #undef __ASSERT_FUNCTION - -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __ASSERT_FUNCTION __func__ -#elif defined(__GNUC__) -#define __ASSERT_FUNCTION __FUNCTION__ -#else -#define __ASSERT_FUNCTION NULL -#endif #define zassert(EX) \ ((void)((EX) ? 0 : (_zlog_assert_failed(#EX, __FILE__, __LINE__, \ diff --git a/lib/zclient.c b/lib/zclient.c index c5e844933c..c78937c1ec 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -42,8 +42,8 @@ #include "srte.h" #include "printfrr.h" -DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") -DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs") +DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient"); +DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs"); /* Zebra client events. */ enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT }; diff --git a/lib/zebra.h b/lib/zebra.h index ded44ac636..5c3d91ba74 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -80,21 +80,6 @@ /* misc include group */ #include <stdarg.h> -#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -/* Not C99; do we need to define va_copy? */ -#ifndef va_copy -#ifdef __va_copy -#define va_copy(DST,SRC) __va_copy(DST,SRC) -#else -/* Now we are desperate; this should work on many typical platforms. - But this is slightly dangerous, because the standard does not require - va_copy to be a macro. */ -#define va_copy(DST,SRC) memcpy(&(DST), &(SRC), sizeof(va_list)) -#warning "Not C99 and no va_copy macro available, falling back to memcpy" -#endif /* __va_copy */ -#endif /* !va_copy */ -#endif /* !C99 */ - #ifdef HAVE_LCAPS #include <sys/capability.h> diff --git a/lib/zlog.c b/lib/zlog.c index 51509e24f4..f546709328 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -54,20 +54,22 @@ #include "zlog.h" #include "libfrr_trace.h" -DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message") -DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer") +DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message"); +DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer"); DEFINE_HOOK(zlog_init, (const char *progname, const char *protoname, unsigned short instance, uid_t uid, gid_t gid), - (progname, protoname, instance, uid, gid)) -DEFINE_KOOH(zlog_fini, (), ()) + (progname, protoname, instance, uid, gid)); +DEFINE_KOOH(zlog_fini, (), ()); DEFINE_HOOK(zlog_aux_init, (const char *prefix, int prio_min), - (prefix, prio_min)) + (prefix, prio_min)); char zlog_prefix[128]; size_t zlog_prefixsz; int zlog_tmpdirfd = -1; +static atomic_bool zlog_ec = true, zlog_xid = true; + /* these are kept around because logging is initialized (and directories * & files created) before zprivs code switches to the FRR user; therefore * we need to chown() things so we don't get permission errors later when @@ -530,12 +532,54 @@ const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen) { if (!msg->text) { va_list args; + bool do_xid, do_ec; + size_t need = 0, hdrlen; + struct fbuf fb = { + .buf = msg->stackbuf, + .pos = msg->stackbuf, + .len = msg->stackbufsz, + }; + + do_ec = atomic_load_explicit(&zlog_ec, memory_order_relaxed); + do_xid = atomic_load_explicit(&zlog_xid, memory_order_relaxed); + + if (msg->xref && do_xid && msg->xref->xref.xrefdata->uid[0]) { + need += bputch(&fb, '['); + need += bputs(&fb, msg->xref->xref.xrefdata->uid); + need += bputch(&fb, ']'); + } + if (msg->xref && do_ec && msg->xref->ec) + need += bprintfrr(&fb, "[EC %u]", msg->xref->ec); + if (need) + need += bputch(&fb, ' '); + + hdrlen = need; + assert(hdrlen < msg->stackbufsz); va_copy(args, msg->args); - msg->text = vasnprintfrr(MTYPE_LOG_MESSAGE, msg->stackbuf, - msg->stackbufsz, msg->fmt, args); - msg->textlen = strlen(msg->text); + need += vbprintfrr(&fb, msg->fmt, args); va_end(args); + + msg->textlen = need; + need += bputch(&fb, '\0'); + + if (need <= msg->stackbufsz) + msg->text = msg->stackbuf; + else { + msg->text = XMALLOC(MTYPE_LOG_MESSAGE, need); + + memcpy(msg->text, msg->stackbuf, hdrlen); + + fb.buf = msg->text; + fb.len = need; + fb.pos = msg->text + hdrlen; + + va_copy(args, msg->args); + vbprintfrr(&fb, msg->fmt, args); + va_end(args); + + bputch(&fb, '\0'); + } } if (textlen) *textlen = msg->textlen; @@ -619,6 +663,26 @@ size_t zlog_msg_ts(struct zlog_msg *msg, char *out, size_t outsz, } } +void zlog_set_prefix_ec(bool enable) +{ + atomic_store_explicit(&zlog_ec, enable, memory_order_relaxed); +} + +bool zlog_get_prefix_ec(void) +{ + return atomic_load_explicit(&zlog_ec, memory_order_relaxed); +} + +void zlog_set_prefix_xid(bool enable) +{ + atomic_store_explicit(&zlog_xid, enable, memory_order_relaxed); +} + +bool zlog_get_prefix_xid(void) +{ + return atomic_load_explicit(&zlog_xid, memory_order_relaxed); +} + /* setup functions */ struct zlog_target *zlog_target_clone(struct memtype *mt, diff --git a/lib/zlog.h b/lib/zlog.h index 4fdb47bb95..66d8f1e5d7 100644 --- a/lib/zlog.h +++ b/lib/zlog.h @@ -85,31 +85,6 @@ static inline void zlog_ref(const struct xref_logmsg *xref, va_end(ap); } -#define _zlog_ref(prio, msg, ...) \ - do { \ - static struct xrefdata _xrefdata = { \ - .xref = NULL, \ - .uid = {}, \ - .hashstr = (msg), \ - .hashu32 = {(prio), 0}, \ - }; \ - static const struct xref_logmsg _xref __attribute__( \ - (used)) = { \ - .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata, __func__), \ - .fmtstring = (msg), \ - .priority = (prio), \ - .args = (#__VA_ARGS__), \ - }; \ - XREF_LINK(_xref.xref); \ - zlog_ref(&_xref, (msg), ##__VA_ARGS__); \ - } while (0) - -#define zlog_err(...) _zlog_ref(LOG_ERR, __VA_ARGS__) -#define zlog_warn(...) _zlog_ref(LOG_WARNING, __VA_ARGS__) -#define zlog_info(...) _zlog_ref(LOG_INFO, __VA_ARGS__) -#define zlog_notice(...) _zlog_ref(LOG_NOTICE, __VA_ARGS__) -#define zlog_debug(...) _zlog_ref(LOG_DEBUG, __VA_ARGS__) - #define _zlog_ecref(ec_, prio, msg, ...) \ do { \ static struct xrefdata _xrefdata = { \ @@ -127,18 +102,22 @@ static inline void zlog_ref(const struct xref_logmsg *xref, .args = (#__VA_ARGS__), \ }; \ XREF_LINK(_xref.xref); \ - zlog_ref(&_xref, "[EC %u] " msg, ec_, ##__VA_ARGS__); \ + zlog_ref(&_xref, (msg), ##__VA_ARGS__); \ } while (0) +#define zlog_err(...) _zlog_ecref(0, LOG_ERR, __VA_ARGS__) +#define zlog_warn(...) _zlog_ecref(0, LOG_WARNING, __VA_ARGS__) +#define zlog_info(...) _zlog_ecref(0, LOG_INFO, __VA_ARGS__) +#define zlog_notice(...) _zlog_ecref(0, LOG_NOTICE, __VA_ARGS__) +#define zlog_debug(...) _zlog_ecref(0, LOG_DEBUG, __VA_ARGS__) + #define flog_err(ferr_id, format, ...) \ _zlog_ecref(ferr_id, LOG_ERR, format, ## __VA_ARGS__) #define flog_warn(ferr_id, format, ...) \ _zlog_ecref(ferr_id, LOG_WARNING, format, ## __VA_ARGS__) #define flog_err_sys(ferr_id, format, ...) \ - flog_err(ferr_id, format, ##__VA_ARGS__) -#define flog(priority, ferr_id, format, ...) \ - zlog(priority, "[EC %u] " format, ferr_id, ##__VA_ARGS__) + _zlog_ecref(ferr_id, LOG_ERR, format, ## __VA_ARGS__) extern void zlog_sigsafe(const char *text, size_t len); @@ -203,7 +182,7 @@ extern size_t zlog_msg_ts(struct zlog_msg *msg, char *out, size_t outsz, * additional options. It MUST be the first field in that larger struct. */ -PREDECL_ATOMLIST(zlog_targets) +PREDECL_ATOMLIST(zlog_targets); struct zlog_target { struct zlog_targets_item head; @@ -247,17 +226,22 @@ extern void zlog_init(const char *progname, const char *protoname, unsigned short instance, uid_t uid, gid_t gid); DECLARE_HOOK(zlog_init, (const char *progname, const char *protoname, unsigned short instance, uid_t uid, gid_t gid), - (progname, protoname, instance, uid, gid)) + (progname, protoname, instance, uid, gid)); extern void zlog_fini(void); -DECLARE_KOOH(zlog_fini, (), ()) +DECLARE_KOOH(zlog_fini, (), ()); + +extern void zlog_set_prefix_ec(bool enable); +extern bool zlog_get_prefix_ec(void); +extern void zlog_set_prefix_xid(bool enable); +extern bool zlog_get_prefix_xid(void); /* for tools & test programs, i.e. anything not a daemon. * (no cleanup needed at exit) */ extern void zlog_aux_init(const char *prefix, int prio_min); DECLARE_HOOK(zlog_aux_init, (const char *prefix, int prio_min), - (prefix, prio_min)) + (prefix, prio_min)); extern void zlog_startup_end(void); diff --git a/lib/zlog_targets.c b/lib/zlog_targets.c index 8f4c2a46a8..f258a8fbbd 100644 --- a/lib/zlog_targets.c +++ b/lib/zlog_targets.c @@ -31,13 +31,13 @@ * absolute end. */ -DECLARE_MGROUP(LOG) -DEFINE_MGROUP_ACTIVEATEXIT(LOG, "logging subsystem") +DECLARE_MGROUP(LOG); +DEFINE_MGROUP_ACTIVEATEXIT(LOG, "logging subsystem"); -DEFINE_MTYPE_STATIC(LOG, LOG_FD, "log file target") -DEFINE_MTYPE_STATIC(LOG, LOG_FD_NAME, "log file name") -DEFINE_MTYPE_STATIC(LOG, LOG_FD_ROTATE, "log file rotate helper") -DEFINE_MTYPE_STATIC(LOG, LOG_SYSL, "syslog target") +DEFINE_MTYPE_STATIC(LOG, LOG_FD, "log file target"); +DEFINE_MTYPE_STATIC(LOG, LOG_FD_NAME, "log file name"); +DEFINE_MTYPE_STATIC(LOG, LOG_FD_ROTATE, "log file rotate helper"); +DEFINE_MTYPE_STATIC(LOG, LOG_SYSL, "syslog target"); struct zlt_fd { struct zlog_target zt; diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 index d383ad5c6d..b7872d9870 100644 --- a/m4/ax_pthread.m4 +++ b/m4/ax_pthread.m4 @@ -219,7 +219,7 @@ for flag in $ax_pthread_flags; do # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> - static void routine(void *a) { a = 0; } + static void routine(void *a) { if (a) a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); diff --git a/nhrpd/debug.h b/nhrpd/debug.h index db4bac7916..e9428fa90a 100644 --- a/nhrpd/debug.h +++ b/nhrpd/debug.h @@ -18,26 +18,8 @@ extern unsigned int debug_flags; -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L - #define debugf(level, ...) \ do { \ if (unlikely(debug_flags & level)) \ zlog_debug(__VA_ARGS__); \ } while (0) - -#elif defined __GNUC__ - -#define debugf(level, _args...) \ - do { \ - if (unlikely(debug_flags & level)) \ - zlog_debug(_args); \ - } while (0) - -#else - -static inline void debugf(int level, const char *format, ...) -{ -} - -#endif diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c index cb298b1a09..4de8e220ce 100644 --- a/nhrpd/nhrp_cache.c +++ b/nhrpd/nhrp_cache.c @@ -15,8 +15,8 @@ #include "netlink.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE, "NHRP cache entry") -DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE_CONFIG, "NHRP cache config entry") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE, "NHRP cache entry"); +DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE_CONFIG, "NHRP cache config entry"); unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES]; diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index b348cc0def..a64708d88e 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -21,7 +21,7 @@ #include "os.h" #include "netlink.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface"); static void nhrp_interface_update_cache_config(struct interface *ifp, bool available, diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index 49a4900bf8..5c819017f4 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -29,7 +29,7 @@ #include "netlink.h" #include "nhrp_errors.h" -DEFINE_MGROUP(NHRPD, "NHRP") +DEFINE_MGROUP(NHRPD, "NHRP"); unsigned int debug_flags = 0; @@ -128,7 +128,8 @@ FRR_DAEMON_INFO(nhrpd, NHRP, .vty_port = NHRP_VTY_PORT, .signals = sighandlers, .n_signals = array_size(sighandlers), .privs = &nhrpd_privs, .yang_modules = nhrpd_yang_modules, - .n_yang_modules = array_size(nhrpd_yang_modules), ) + .n_yang_modules = array_size(nhrpd_yang_modules), +); int main(int argc, char **argv) { diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index ae5737d736..1689facbcf 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -14,8 +14,8 @@ #include "nhrpd.h" #include "nhrp_protocol.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_NHS, "NHRP next hop server") -DEFINE_MTYPE_STATIC(NHRPD, NHRP_REGISTRATION, "NHRP registration entries") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_NHS, "NHRP next hop server"); +DEFINE_MTYPE_STATIC(NHRPD, NHRP_REGISTRATION, "NHRP registration entries"); static int nhrp_nhs_resolve(struct thread *t); static int nhrp_reg_send_req(struct thread *t); diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 0d589e3056..af352c68ee 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -22,7 +22,7 @@ #include "nhrp_protocol.h" #include "os.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_PEER, "NHRP peer entry") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_PEER, "NHRP peer entry"); struct ipv6hdr { uint8_t priority_version; diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 737772dbc7..7a4c57b5d4 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -18,7 +18,7 @@ #include "log.h" #include "zclient.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_ROUTE, "NHRP routing entry") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_ROUTE, "NHRP routing entry"); static struct zclient *zclient; static struct route_table *zebra_rib[AFI_MAX]; diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index ef3be82ca9..8ce19cd4a3 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -18,7 +18,7 @@ #include "log.h" #include "nhrp_protocol.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_SHORTCUT, "NHRP shortcut") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_SHORTCUT, "NHRP shortcut"); static struct route_table *shortcut_rib[AFI_MAX]; diff --git a/nhrpd/nhrp_vc.c b/nhrpd/nhrp_vc.c index d538163e90..b3b657f3fa 100644 --- a/nhrpd/nhrp_vc.c +++ b/nhrpd/nhrp_vc.c @@ -17,7 +17,7 @@ #include "nhrpd.h" #include "os.h" -DEFINE_MTYPE_STATIC(NHRPD, NHRP_VC, "NHRP virtual connection") +DEFINE_MTYPE_STATIC(NHRPD, NHRP_VC, "NHRP virtual connection"); struct child_sa { uint32_t id; diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index 3655463152..9c8c293b9e 100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h @@ -18,7 +18,7 @@ #include "memory.h" #include "resolver.h" -DECLARE_MGROUP(NHRPD) +DECLARE_MGROUP(NHRPD); #define NHRPD_DEFAULT_HOLDTIME 7200 diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c index 7f1475cc69..a78d827ea5 100644 --- a/nhrpd/zbuf.c +++ b/nhrpd/zbuf.c @@ -21,7 +21,7 @@ #define ERRNO_IO_RETRY(EN) (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR)) -DEFINE_MTYPE_STATIC(NHRPD, ZBUF_DATA, "NHRPD zbuf data") +DEFINE_MTYPE_STATIC(NHRPD, ZBUF_DATA, "NHRPD zbuf data"); struct zbuf *zbuf_alloc(size_t size) { diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index cf33069c9f..6bf61b4804 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -46,7 +46,8 @@ #include "ospf6d.h" #include "lib/json.h" -DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name") +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AREA, "OSPF6 area"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name"); int ospf6_area_cmp(void *va, void *vb) { diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 977d810be5..3497b26656 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -49,6 +49,10 @@ #include "ospf6d.h" #include "lib/json.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DIST_ARGS, "OSPF6 Distribute arguments"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_REDISTRIBUTE, "OSPF6 Redistribute arguments"); + static void ospf6_asbr_redistribute_set(int type, vrf_id_t vrf_id); static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6, struct ospf6_redist *red, int type); diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 2d896546fa..5f4815fec1 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -463,6 +463,19 @@ static void ospf6_flood_process(struct ospf6_neighbor *from, struct ospf6_area *oa; for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) { + + /* If unknown LSA and U-bit clear, treat as link local + * flooding scope + */ + if (!OSPF6_LSA_IS_KNOWN(lsa->header->type) + && !(ntohs(lsa->header->type) & OSPF6_LSTYPE_UBIT_MASK) + && (oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)) { + + if (IS_OSPF6_DEBUG_FLOODING) + zlog_debug("Unknown LSA, do not flood"); + continue; + } + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA && oa != OSPF6_AREA(lsa->lsdb->data)) continue; diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index a5d9138743..158b8dc483 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -45,11 +45,12 @@ #include "ospf6_zebra.h" #include "lib/json.h" -DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names") -DEFINE_QOBJ_TYPE(ospf6_interface) +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface"); +DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names"); +DEFINE_QOBJ_TYPE(ospf6_interface); DEFINE_HOOK(ospf6_interface_change, (struct ospf6_interface * oi, int state, int old_state), - (oi, state, old_state)) + (oi, state, old_state)); unsigned char conf_debug_ospf6_interface = 0; @@ -1449,6 +1450,12 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix, return CMD_WARNING; } + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { + vty_out(vty, "Interface %s not attached to area\n", + argv[idx_ifname]->arg); + return CMD_WARNING; + } + ospf6_route_table_show(vty, idx_prefix, argc, argv, oi->route_connected, uj); @@ -1482,7 +1489,7 @@ DEFUN (show_ipv6_ospf6_interface_prefix, FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; - if (oi == NULL) + if (oi == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) continue; ospf6_route_table_show(vty, idx_prefix, argc, argv, diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index 6e4692920c..2a5a9ba4a2 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -134,9 +134,9 @@ struct ospf6_interface { uint32_t ls_ack_out; uint32_t discarded; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(ospf6_interface) +DECLARE_QOBJ_TYPE(ospf6_interface); /* interface state */ #define OSPF6_INTERFACE_NONE 0 @@ -199,6 +199,6 @@ extern void install_element_ospf6_debug_interface(void); DECLARE_HOOK(ospf6_interface_change, (struct ospf6_interface * oi, int state, int old_state), - (oi, state, old_state)) + (oi, state, old_state)); #endif /* OSPF6_INTERFACE_H */ diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index e1c3b4038c..b4f0c30f12 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -43,6 +43,10 @@ #include "ospf6_flood.h" #include "ospf6d.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary"); + vector ospf6_lsa_handler_vector; struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa) @@ -657,27 +661,29 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, vty_out(vty, "\n"); } +struct ospf6_lsa *ospf6_lsa_alloc(size_t lsa_length) +{ + struct ospf6_lsa *lsa; + + lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa)); + lsa->header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, lsa_length); + + return lsa; +} + /* OSPFv3 LSA creation/deletion function */ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header) { struct ospf6_lsa *lsa = NULL; - struct ospf6_lsa_header *new_header = NULL; uint16_t lsa_size = 0; /* size of the entire LSA */ lsa_size = ntohs(header->length); /* XXX vulnerable */ - /* allocate memory for this LSA */ - new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, lsa_size); + lsa = ospf6_lsa_alloc(lsa_size); /* copy LSA from original header */ - memcpy(new_header, header, lsa_size); - - /* LSA information structure */ - /* allocate memory */ - lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa)); - - lsa->header = new_header; + memcpy(lsa->header, header, lsa_size); /* dump string */ ospf6_lsa_printbuf(lsa, lsa->name, sizeof(lsa->name)); @@ -691,20 +697,11 @@ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header) struct ospf6_lsa *ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header) { struct ospf6_lsa *lsa = NULL; - struct ospf6_lsa_header *new_header = NULL; - - /* allocate memory for this LSA */ - new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, - sizeof(struct ospf6_lsa_header)); - /* copy LSA from original header */ - memcpy(new_header, header, sizeof(struct ospf6_lsa_header)); + lsa = ospf6_lsa_alloc(sizeof(struct ospf6_lsa_header)); - /* LSA information structure */ - /* allocate memory */ - lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa)); + memcpy(lsa->header, header, sizeof(struct ospf6_lsa_header)); - lsa->header = new_header; SET_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY); /* dump string */ @@ -856,11 +853,12 @@ int ospf6_lsa_refresh(struct thread *thread) void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6) { - struct listnode *node; + struct listnode *node, *nnode; struct ospf6_area *oa; struct ospf6_lsa *lsa; const struct route_node *end = NULL; uint32_t type, adv_router; + struct ospf6_interface *oi; ospf6->inst_shutdown = 1; @@ -875,6 +873,19 @@ void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6) lsa = ospf6_lsdb_next(end, lsa); } + + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { + end = ospf6_lsdb_head(oi->lsdb_self, 0, 0, + ospf6->router_id, &lsa); + while (lsa) { + /* RFC 2328 (14.1): Set MAXAGE */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + /* Flood MAXAGE LSA*/ + ospf6_flood(NULL, lsa); + + lsa = ospf6_lsdb_next(end, lsa); + } + } } type = htons(OSPF6_LSTYPE_AS_EXTERNAL); diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 7fa9c5fe40..c4d0290c0c 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -217,6 +217,7 @@ extern void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa, extern void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, json_object *json, bool use_json); +extern struct ospf6_lsa *ospf6_lsa_alloc(size_t lsa_length); extern struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header); extern struct ospf6_lsa * ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header); diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index 9636e1a230..18f121e3a2 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -34,6 +34,8 @@ #include "ospf6d.h" #include "bitfield.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database"); + struct ospf6_lsdb *ospf6_lsdb_create(void *data) { struct ospf6_lsdb *lsdb; diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 69424f4b46..c601693a7e 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -182,7 +182,8 @@ FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT, .n_signals = array_size(ospf6_signals), .privs = &ospf6d_privs, .yang_modules = ospf6d_yang_modules, - .n_yang_modules = array_size(ospf6d_yang_modules), ) + .n_yang_modules = array_size(ospf6d_yang_modules), +); /* Main routine of ospf6d. Treatment of argument and starting ospf finite state machine is handled here. */ diff --git a/ospf6d/ospf6_memory.c b/ospf6d/ospf6_memory.c deleted file mode 100644 index 6585fc1580..0000000000 --- a/ospf6d/ospf6_memory.c +++ /dev/null @@ -1,47 +0,0 @@ -/* ospf6d memory type definitions - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "ospf6_memory.h" - -DEFINE_MGROUP(OSPF6D, "ospf6d") -DEFINE_MTYPE(OSPF6D, OSPF6_TOP, "OSPF6 top") -DEFINE_MTYPE(OSPF6D, OSPF6_AREA, "OSPF6 area") -DEFINE_MTYPE(OSPF6D, OSPF6_IF, "OSPF6 interface") -DEFINE_MTYPE(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor") -DEFINE_MTYPE(OSPF6D, OSPF6_ROUTE, "OSPF6 route") -DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix") -DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message") -DEFINE_MTYPE(OSPF6D, OSPF6_LSA, "OSPF6 LSA") -DEFINE_MTYPE(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header") -DEFINE_MTYPE(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary") -DEFINE_MTYPE(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database") -DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex") -DEFINE_MTYPE(OSPF6D, OSPF6_SPFTREE, "OSPF6 SPF tree") -DEFINE_MTYPE(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop") -DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info") -DEFINE_MTYPE(OSPF6D, OSPF6_PATH, "OSPF6 Path") -DEFINE_MTYPE(OSPF6D, OSPF6_DIST_ARGS, "OSPF6 Distribute arguments") -DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other") -DEFINE_MTYPE(OSPF6D, OSPF6_REDISTRIBUTE, "OSPF6 Redistribute arguments") diff --git a/ospf6d/ospf6_memory.h b/ospf6d/ospf6_memory.h deleted file mode 100644 index 57f0abd9a8..0000000000 --- a/ospf6d/ospf6_memory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* ospf6d memory type declarations - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QUAGGA_OSPF6_MEMORY_H -#define _QUAGGA_OSPF6_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(OSPF6D) -DECLARE_MTYPE(OSPF6_TOP) -DECLARE_MTYPE(OSPF6_AREA) -DECLARE_MTYPE(OSPF6_IF) -DECLARE_MTYPE(OSPF6_NEIGHBOR) -DECLARE_MTYPE(OSPF6_ROUTE) -DECLARE_MTYPE(OSPF6_PREFIX) -DECLARE_MTYPE(OSPF6_MESSAGE) -DECLARE_MTYPE(OSPF6_LSA) -DECLARE_MTYPE(OSPF6_LSA_HEADER) -DECLARE_MTYPE(OSPF6_LSA_SUMMARY) -DECLARE_MTYPE(OSPF6_LSDB) -DECLARE_MTYPE(OSPF6_VERTEX) -DECLARE_MTYPE(OSPF6_SPFTREE) -DECLARE_MTYPE(OSPF6_NEXTHOP) -DECLARE_MTYPE(OSPF6_EXTERNAL_INFO) -DECLARE_MTYPE(OSPF6_PATH) -DECLARE_MTYPE(OSPF6_DIST_ARGS) -DECLARE_MTYPE(OSPF6_REDISTRIBUTE) -DECLARE_MTYPE(OSPF6_OTHER) - -#endif /* _QUAGGA_OSPF6_MEMORY_H */ diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index aebe43b9ec..7aedd3df45 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -49,6 +49,8 @@ #include <netinet/ip6.h> +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_MESSAGE, "OSPF6 message"); + unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; static const struct message ospf6_message_type_str[] = { {OSPF6_MESSAGE_TYPE_HELLO, "Hello"}, diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 7a1b96c2b3..485bde4b7b 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -46,9 +46,11 @@ #include "ospf6_zebra.h" #include "lib/json.h" +DEFINE_MTYPE(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor"); + DEFINE_HOOK(ospf6_neighbor_change, (struct ospf6_neighbor * on, int state, int next_state), - (on, state, next_state)) + (on, state, next_state)); unsigned char conf_debug_ospf6_neighbor = 0; diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h index 94300ff2ba..f45b340507 100644 --- a/ospf6d/ospf6_neighbor.h +++ b/ospf6d/ospf6_neighbor.h @@ -166,6 +166,6 @@ extern void install_element_ospf6_debug_neighbor(void); DECLARE_HOOK(ospf6_neighbor_change, (struct ospf6_neighbor * on, int state, int next_state), - (on, state, next_state)) + (on, state, next_state)); #endif /* OSPF6_NEIGHBOR_H */ diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index b77f968179..9770dd0444 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -38,6 +38,10 @@ #include "ospf6d.h" #include "ospf6_zebra.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE, "OSPF6 route"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop"); +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PATH, "OSPF6 Path"); + unsigned char conf_debug_ospf6_route = 0; static char *ospf6_route_table_name(struct ospf6_route_table *table) diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 51a3bff2a3..b9d413c3df 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -1418,4 +1418,5 @@ static int ospf6_snmp_module_init(void) FRR_MODULE_SETUP(.name = "ospf6d_snmp", .version = FRR_VERSION, .description = "ospf6d AgentX SNMP module", - .init = ospf6_snmp_module_init, ) + .init = ospf6_snmp_module_init, +); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 121e846843..7652d71c59 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -43,6 +43,8 @@ #include "ospf6d.h" #include "ospf6_abr.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex"); + unsigned char conf_debug_ospf6_spf = 0; static void ospf6_spf_copy_nexthops_to_route(struct ospf6_route *rt, @@ -86,7 +88,7 @@ static int ospf6_vertex_cmp(const struct ospf6_vertex *va, return 0; } DECLARE_SKIPLIST_NONUNIQ(vertex_pqueue, struct ospf6_vertex, pqi, - ospf6_vertex_cmp) + ospf6_vertex_cmp); static int ospf6_vertex_id_cmp(void *a, void *b) { @@ -1021,13 +1023,8 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, return NULL; } - /* Allocate memory for this LSA */ - new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, total_lsa_length); - - /* LSA information structure */ - lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa)); - - lsa->header = (struct ospf6_lsa_header *)new_header; + lsa = ospf6_lsa_alloc(total_lsa_length); + new_header = (uint8_t *)lsa->header; lsa->lsdb = area->temp_router_lsa_lsdb; diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h index 36e2b27912..523b318d5b 100644 --- a/ospf6d/ospf6_spf.h +++ b/ospf6d/ospf6_spf.h @@ -35,7 +35,7 @@ extern unsigned char conf_debug_ospf6_spf; #define IS_OSPF6_DEBUG_SPF(level) \ (conf_debug_ospf6_spf & OSPF6_DEBUG_SPF_##level) -PREDECL_SKIPLIST_NONUNIQ(vertex_pqueue) +PREDECL_SKIPLIST_NONUNIQ(vertex_pqueue); /* Transit Vertex */ struct ospf6_vertex { /* type of this vertex */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 3f72ec828e..a38f1cbc45 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -53,12 +53,14 @@ #include "ospf6d.h" #include "lib/json.h" -DEFINE_QOBJ_TYPE(ospf6) +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_TOP, "OSPF6 top"); + +DEFINE_QOBJ_TYPE(ospf6); FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); /* global ospf6d variable */ static struct ospf6_master ospf6_master; @@ -809,7 +811,8 @@ DEFUN (no_ospf6_interface_area, /* Verify Area */ if (oi->area == NULL) { - vty_out(vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg); + vty_out(vty, "%s not attached to area %s\n", + oi->interface->name, oi->area->name); return CMD_SUCCESS; } @@ -830,7 +833,6 @@ DEFUN (no_ospf6_interface_area, UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE); ospf6_abr_disable_area(oa); } - ospf6_interface_delete(oi); return CMD_SUCCESS; } diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 75dff86cd7..7980659e68 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -132,9 +132,9 @@ struct ospf6 { */ uint16_t max_multipath; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(ospf6) +DECLARE_QOBJ_TYPE(ospf6); #define OSPF6_DISABLED 0x01 #define OSPF6_STUB_ROUTER 0x02 diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 9b9453ce24..8d5e0f0a39 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -42,7 +42,7 @@ #include "ospf6_area.h" #include "lib/json.h" -DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance") +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance"); unsigned char conf_debug_ospf6_zebra = 0; diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index 8d9c85fd08..91d427c78c 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -46,6 +46,8 @@ #include "ospf6_bfd.h" #include "lib/json.h" +DEFINE_MGROUP(OSPF6D, "ospf6d"); + struct route_node *route_prev(struct route_node *node) { struct route_node *end; diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index d85ff40f32..3f9461c7f0 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -23,8 +23,9 @@ #include "libospf.h" #include "thread.h" +#include "memory.h" -#include "ospf6_memory.h" +DECLARE_MGROUP(OSPF6D); /* global variables */ extern struct thread_master *master; diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index ec6e593533..82d880cca8 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -40,7 +40,6 @@ ospf6d_libospf6_a_SOURCES = \ ospf6d/ospf6_intra.c \ ospf6d/ospf6_lsa.c \ ospf6d/ospf6_lsdb.c \ - ospf6d/ospf6_memory.c \ ospf6d/ospf6_message.c \ ospf6d/ospf6_neighbor.c \ ospf6d/ospf6_network.c \ @@ -62,7 +61,6 @@ noinst_HEADERS += \ ospf6d/ospf6_intra.h \ ospf6d/ospf6_lsa.h \ ospf6d/ospf6_lsdb.h \ - ospf6d/ospf6_memory.h \ ospf6d/ospf6_message.h \ ospf6d/ospf6_neighbor.h \ ospf6d/ospf6_network.h \ @@ -80,6 +78,6 @@ ospf6d_ospf6d_SOURCES = \ # end ospf6d_ospf6d_snmp_la_SOURCES = ospf6d/ospf6_snmp.c -ospf6d_ospf6d_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +ospf6d_ospf6d_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 ospf6d_ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic ospf6d_ospf6d_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c index 1b9b66d745..29f1c0807d 100644 --- a/ospfclient/ospf_apiclient.c +++ b/ospfclient/ospf_apiclient.c @@ -58,10 +58,10 @@ #include "ospfd/ospf_dump_api.c" #include "ospfd/ospf_api.c" -XREF_SETUP() +XREF_SETUP(); -DEFINE_MGROUP(OSPFCLIENT, "libospfapiclient") -DEFINE_MTYPE_STATIC(OSPFCLIENT, OSPF_APICLIENT, "OSPF-API client") +DEFINE_MGROUP(OSPFCLIENT, "libospfapiclient"); +DEFINE_MTYPE_STATIC(OSPFCLIENT, OSPF_APICLIENT, "OSPF-API client"); /* Backlog for listen */ #define BACKLOG 5 diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index f3c4798906..b5c97eda3c 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -675,7 +675,8 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) * originate translated LSA */ - if (ospf_translated_nssa_originate(area->ospf, lsa) == NULL) { + if (ospf_translated_nssa_originate(area->ospf, lsa, old) + == NULL) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( "ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5", diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index a9bc9069d2..b202cd01f1 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -23,6 +23,7 @@ #include <zebra.h> #include "command.h" +#include "json.h" #include "linklist.h" #include "memory.h" #include "prefix.h" @@ -44,48 +45,7 @@ #include "ospf_dump.h" #include "ospf_vty.h" -extern struct zclient *zclient; - -/* - * ospf_bfd_info_free - Free BFD info structure - */ -void ospf_bfd_info_free(void **bfd_info) -{ - bfd_info_free((struct bfd_info **)bfd_info); -} - -/* - * ospf_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through - * zebra for starting/stopping the monitoring of - * the neighbor rechahability. - */ -static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command) -{ - struct ospf_interface *oi = nbr->oi; - struct interface *ifp = oi->ifp; - struct ospf_if_params *params; - struct bfd_info *bfd_info; - int cbit; - - /* Check if BFD is enabled */ - params = IF_DEF_PARAMS(ifp); - - /* Check if BFD is enabled */ - if (!params->bfd_info) - return; - bfd_info = (struct bfd_info *)params->bfd_info; - - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("%s nbr (%pI4) with BFD. OSPF vrf %s", - bfd_get_command_dbg_str(command), - &nbr->src, - ospf_vrf_id_to_name(oi->ospf->vrf_id)); - - cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON); - - bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name, - 0, 0, cbit, command, 0, oi->ospf->vrf_id); -} +DEFINE_MTYPE_STATIC(OSPFD, BFD_CONFIG, "BFD configuration data"); /* * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when @@ -94,293 +54,155 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command) void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state) { if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay)) - ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER); + bfd_sess_install(nbr->bfd_session); else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay)) - ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER); + bfd_sess_uninstall(nbr->bfd_session); } -/* - * ospf_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated - * with a interface with BFD through - * zebra for starting/stopping the monitoring of - * the neighbor rechahability. - */ -static int ospf_bfd_reg_dereg_all_nbr(struct interface *ifp, int command) +static void ospf_bfd_session_change(struct bfd_session_params *bsp, + const struct bfd_session_status *bss, + void *arg) { - struct ospf_interface *oi; - struct route_table *nbrs; - struct ospf_neighbor *nbr; - struct route_node *irn; - struct route_node *nrn; - - for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) { - if ((oi = irn->info) == NULL) - continue; + struct ospf_neighbor *nbr = arg; - if ((nbrs = oi->nbrs) == NULL) - continue; - - for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) { - if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self) - continue; - - if (command != ZEBRA_BFD_DEST_DEREGISTER) - ospf_bfd_info_nbr_create(oi, nbr); - else - bfd_info_free( - (struct bfd_info **)&nbr->bfd_info); - - if (nbr->state < NSM_TwoWay) - continue; + /* BFD peer went down. */ + if (bss->state == BFD_STATUS_DOWN + && bss->previous_state == BFD_STATUS_UP) { + if (IS_DEBUG_OSPF(bfd, BFD_LIB)) + zlog_debug("%s: NSM[%s:%pI4]: BFD Down", __func__, + IF_NAME(nbr->oi), &nbr->address.u.prefix4); - ospf_bfd_reg_dereg_nbr(nbr, command); - } + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); } - return 0; + /* BFD peer went up. */ + if (bss->state == BSS_UP && bss->previous_state == BSS_DOWN) + if (IS_DEBUG_OSPF(bfd, BFD_LIB)) + zlog_debug("%s: NSM[%s:%pI4]: BFD Up", __func__, + IF_NAME(nbr->oi), &nbr->address.u.prefix4); } -/* - * ospf_bfd_nbr_replay - Replay all the neighbors that have BFD enabled - * to zebra - */ -static int ospf_bfd_nbr_replay(ZAPI_CALLBACK_ARGS) +void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr) { - struct listnode *inode, *node, *onode; - struct ospf *ospf; - struct ospf_interface *oi; - struct route_table *nbrs; - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf_if_params *params; + struct ospf_interface *oi = nbr->oi; + struct ospf_if_params *oip = IF_DEF_PARAMS(oi->ifp); - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { - zlog_debug("Zebra: BFD Dest replay request"); + /* BFD configuration was removed. */ + if (oip->bfd_config == NULL) { + bfd_sess_free(&nbr->bfd_session); + return; } - /* Send the client registration */ - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf_id); - - /* Replay the neighbor, if BFD is enabled in OSPF */ - for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) { - for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) { - if ((nbrs = oi->nbrs) == NULL) - continue; - - params = IF_DEF_PARAMS(oi->ifp); - if (!params->bfd_info) - continue; - - for (rn = route_top(nbrs); rn; rn = route_next(rn)) { - if ((nbr = rn->info) == NULL - || nbr == oi->nbr_self) - continue; + /* New BFD session. */ + if (nbr->bfd_session == NULL) { + nbr->bfd_session = bfd_sess_new(ospf_bfd_session_change, nbr); + bfd_sess_set_ipv4_addrs(nbr->bfd_session, NULL, &nbr->src); + bfd_sess_set_interface(nbr->bfd_session, oi->ifp->name); + bfd_sess_set_vrf(nbr->bfd_session, oi->ospf->vrf_id); + bfd_sess_enable(nbr->bfd_session, true); + } - if (nbr->state < NSM_TwoWay) - continue; + /* Set new configuration. */ + bfd_sess_set_timers(nbr->bfd_session, + oip->bfd_config->detection_multiplier, + oip->bfd_config->min_rx, oip->bfd_config->min_tx); + bfd_sess_set_profile(nbr->bfd_session, oip->bfd_config->profile); - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("Replaying nbr (%pI4) to BFD", - &nbr->src); + /* Don't start sessions on down OSPF sessions. */ + if (nbr->state < NSM_TwoWay) + return; - ospf_bfd_reg_dereg_nbr(nbr, - ZEBRA_BFD_DEST_UPDATE); - } - } - } - return 0; + bfd_sess_install(nbr->bfd_session); } -/* - * ospf_bfd_interface_dest_update - Find the neighbor for which the BFD status - * has changed and bring down the neighbor - * connectivity if the BFD status changed to - * down. - */ -static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) +static void ospf_interface_bfd_apply(struct interface *ifp) { - struct interface *ifp; struct ospf_interface *oi; - struct ospf_if_params *params; - struct ospf_neighbor *nbr = NULL; - struct route_node *node; - struct route_node *n_node; - struct prefix p, src_p; - int status; - int old_status; - struct bfd_info *bfd_info; - struct timeval tv; - - ifp = bfd_get_peer_info(zclient->ibuf, &p, &src_p, &status, NULL, - vrf_id); - - if ((ifp == NULL) || (p.family != AF_INET)) - return 0; - - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("Zebra: interface %s bfd destination %pFX %s", - ifp->name, &p, bfd_get_status_str(status)); - - params = IF_DEF_PARAMS(ifp); - if (!params->bfd_info) - return 0; - - for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) { - if ((oi = node->info) == NULL) - continue; - - /* walk the neighbor list for point-to-point network */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) { - for (n_node = route_top(oi->nbrs); n_node; - n_node = route_next(n_node)) { - nbr = n_node->info; - if (nbr) { - /* skip myself */ - if (nbr == oi->nbr_self) { - nbr = NULL; - continue; - } - - /* Found the matching neighbor */ - if (nbr->src.s_addr == - p.u.prefix4.s_addr) - break; - } - } - } else { - nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &p.u.prefix4); - } + struct route_table *nbrs; + struct ospf_neighbor *nbr; + struct route_node *irn; + struct route_node *nrn; - if (!nbr || !nbr->bfd_info) + /* Iterate over all interfaces and set neighbors BFD session. */ + for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) { + if ((oi = irn->info) == NULL) continue; - - bfd_info = (struct bfd_info *)nbr->bfd_info; - if (bfd_info->status == status) + if ((nbrs = oi->nbrs) == NULL) continue; + for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) { + if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self) + continue; - old_status = bfd_info->status; - BFD_SET_CLIENT_STATUS(bfd_info->status, status); - monotime(&tv); - bfd_info->last_update = tv.tv_sec; - - if ((status == BFD_STATUS_DOWN) - && (old_status == BFD_STATUS_UP)) { - if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) - zlog_debug("NSM[%s:%pI4]: BFD Down", - IF_NAME(nbr->oi), - &nbr->address.u.prefix4); - - OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); - } - if ((status == BFD_STATUS_UP) - && (old_status == BFD_STATUS_DOWN)) { - if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) - zlog_debug("NSM[%s:%pI4]: BFD Up", - IF_NAME(nbr->oi), - &nbr->address.u.prefix4); + ospf_neighbor_bfd_apply(nbr); } } - - return 0; } -/* - * ospf_bfd_info_nbr_create - Create/update BFD information for a neighbor. - */ -void ospf_bfd_info_nbr_create(struct ospf_interface *oi, - struct ospf_neighbor *nbr) +static void ospf_interface_enable_bfd(struct interface *ifp) { - struct bfd_info *oi_bfd_info; - struct bfd_info *nbr_bfd_info; - struct interface *ifp = oi->ifp; - struct ospf_if_params *params; - - /* Check if BFD is enabled */ - params = IF_DEF_PARAMS(ifp); + struct ospf_if_params *oip = IF_DEF_PARAMS(ifp); - /* Check if BFD is enabled */ - if (!params->bfd_info) + if (oip->bfd_config) return; - oi_bfd_info = (struct bfd_info *)params->bfd_info; - if (!nbr->bfd_info) - nbr->bfd_info = bfd_info_create(); + /* Allocate memory for configurations and set defaults. */ + oip->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*oip->bfd_config)); + oip->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT; + oip->bfd_config->min_rx = BFD_DEF_MIN_RX; + oip->bfd_config->min_tx = BFD_DEF_MIN_TX; +} - nbr_bfd_info = (struct bfd_info *)nbr->bfd_info; - nbr_bfd_info->detect_mult = oi_bfd_info->detect_mult; - nbr_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx; - nbr_bfd_info->required_min_rx = oi_bfd_info->required_min_rx; +void ospf_interface_disable_bfd(struct interface *ifp, + struct ospf_if_params *oip) +{ + XFREE(MTYPE_BFD_CONFIG, oip->bfd_config); + ospf_interface_bfd_apply(ifp); } /* * ospf_bfd_write_config - Write the interface BFD configuration. */ -void ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params) - +void ospf_bfd_write_config(struct vty *vty, const struct ospf_if_params *params + __attribute__((unused))) { #if HAVE_BFDD == 0 - struct bfd_info *bfd_info; -#endif /* ! HAVE_BFDD */ - - if (!params->bfd_info) - return; - -#if HAVE_BFDD == 0 - bfd_info = (struct bfd_info *)params->bfd_info; - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) - vty_out(vty, " ip ospf bfd %d %d %d\n", bfd_info->detect_mult, - bfd_info->required_min_rx, bfd_info->desired_min_tx); + vty_out(vty, " ip ospf bfd %d %d %d\n", + params->bfd_config->detection_multiplier, + params->bfd_config->min_rx, params->bfd_config->min_tx); else #endif /* ! HAVE_BFDD */ vty_out(vty, " ip ospf bfd\n"); -} -/* - * ospf_bfd_show_info - Show BFD info structure - */ -void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - bool use_json, int param_only) -{ - if (param_only) - bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, - json_obj); - else - bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json, - json_obj); + if (params->bfd_config->profile[0]) + vty_out(vty, " ip ospf bfd profile %s\n", + params->bfd_config->profile); } -/* - * ospf_bfd_interface_show - Show the interface BFD configuration. - */ -void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, - json_object *json_interface_sub, bool use_json) +void ospf_interface_bfd_show(struct vty *vty, const struct interface *ifp, + struct json_object *json) { - struct ospf_if_params *params; - - params = IF_DEF_PARAMS(ifp); + struct ospf_if_params *params = IF_DEF_PARAMS(ifp); + struct bfd_configuration *bfd_config = params->bfd_config; + struct json_object *json_bfd; - ospf_bfd_show_info(vty, params->bfd_info, json_interface_sub, use_json, - 1); -} - -/* - * ospf_bfd_if_param_set - Set the configured BFD paramter values for - * interface. - */ -static void ospf_bfd_if_param_set(struct interface *ifp, uint32_t min_rx, - uint32_t min_tx, uint8_t detect_mult, - int defaults) -{ - struct ospf_if_params *params; - int command = 0; - - params = IF_DEF_PARAMS(ifp); + if (bfd_config == NULL) + return; - bfd_set_param((struct bfd_info **)&(params->bfd_info), min_rx, min_tx, - detect_mult, NULL, defaults, &command); - if (command) - ospf_bfd_reg_dereg_all_nbr(ifp, command); + if (json) { + json_bfd = json_object_new_object(); + json_object_int_add(json_bfd, "detectionMultiplier", + bfd_config->detection_multiplier); + json_object_int_add(json_bfd, "rxMinInterval", + bfd_config->min_rx); + json_object_int_add(json_bfd, "txMinInterval", + bfd_config->min_tx); + json_object_object_add(json, "peerBfdInfo", json_bfd); + } else + vty_out(vty, + " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n", + bfd_config->detection_multiplier, bfd_config->min_rx, + bfd_config->min_tx); } DEFUN (ip_ospf_bfd, @@ -391,17 +213,8 @@ DEFUN (ip_ospf_bfd, "Enables BFD support\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf_if_params *params; - struct bfd_info *bfd_info; - - assert(ifp); - params = IF_DEF_PARAMS(ifp); - bfd_info = params->bfd_info; - - if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) - ospf_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1); - + ospf_interface_enable_bfd(ifp); + ospf_interface_bfd_apply(ifp); return CMD_SUCCESS; } @@ -421,23 +234,63 @@ DEFUN( "Desired min transmit interval\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; int idx_number = 3; int idx_number_2 = 4; int idx_number_3 = 5; - uint32_t rx_val; - uint32_t tx_val; - uint8_t dm_val; - int ret; - assert(ifp); + ospf_interface_enable_bfd(ifp); + + params = IF_DEF_PARAMS(ifp); + params->bfd_config->detection_multiplier = + strtol(argv[idx_number]->arg, NULL, 10); + params->bfd_config->min_rx = strtol(argv[idx_number_2]->arg, NULL, 10); + params->bfd_config->min_tx = strtol(argv[idx_number_3]->arg, NULL, 10); + + ospf_interface_bfd_apply(ifp); + + return CMD_SUCCESS; +} - if ((ret = bfd_validate_param( - vty, argv[idx_number]->arg, argv[idx_number_2]->arg, - argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val)) - != CMD_SUCCESS) - return ret; +DEFUN (ip_ospf_bfd_prof, + ip_ospf_bfd_prof_cmd, + "ip ospf bfd profile BFDPROF", + "IP Information\n" + "OSPF interface commands\n" + "Enables BFD support\n" + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; + int idx_prof = 4; - ospf_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0); + ospf_interface_enable_bfd(ifp); + params = IF_DEF_PARAMS(ifp); + strlcpy(params->bfd_config->profile, argv[idx_prof]->arg, + sizeof(params->bfd_config->profile)); + ospf_interface_bfd_apply(ifp); + + return CMD_SUCCESS; +} + +DEFUN (no_ip_ospf_bfd_prof, + no_ip_ospf_bfd_prof_cmd, + "no ip ospf bfd profile [BFDPROF]", + NO_STR + "IP Information\n" + "OSPF interface commands\n" + "Enables BFD support\n" + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; + + ospf_interface_enable_bfd(ifp); + params = IF_DEF_PARAMS(ifp); + params->bfd_config->profile[0] = 0; + ospf_interface_bfd_apply(ifp); return CMD_SUCCESS; } @@ -461,29 +314,18 @@ DEFUN (no_ip_ospf_bfd, ) { VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf_if_params *params; - - assert(ifp); - - params = IF_DEF_PARAMS(ifp); - if (params->bfd_info) { - ospf_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER); - bfd_info_free(&(params->bfd_info)); - } - + ospf_interface_disable_bfd(ifp, IF_DEF_PARAMS(ifp)); return CMD_SUCCESS; } -void ospf_bfd_init(void) +void ospf_bfd_init(struct thread_master *tm) { - bfd_gbl_init(); - - /* Initialize BFD client functions */ - zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update; - zclient->bfd_dest_replay = ospf_bfd_nbr_replay; + bfd_protocol_integration_init(zclient, tm); /* Install BFD command */ install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd); install_element(INTERFACE_NODE, &ip_ospf_bfd_param_cmd); + install_element(INTERFACE_NODE, &ip_ospf_bfd_prof_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_bfd_prof_cmd); install_element(INTERFACE_NODE, &no_ip_ospf_bfd_cmd); } diff --git a/ospfd/ospf_bfd.h b/ospfd/ospf_bfd.h index 74385d3268..9393c839f5 100644 --- a/ospfd/ospf_bfd.h +++ b/ospfd/ospf_bfd.h @@ -23,27 +23,34 @@ #ifndef _ZEBRA_OSPF_BFD_H #define _ZEBRA_OSPF_BFD_H +#include "ospfd/ospf_interface.h" #include "json.h" -extern void ospf_bfd_init(void); +extern void ospf_bfd_init(struct thread_master *tm); extern void ospf_bfd_write_config(struct vty *vty, - struct ospf_if_params *params); + const struct ospf_if_params *params); extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state); -extern void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, - json_object *json_interface_sub, - bool use_json); - -extern void ospf_bfd_info_nbr_create(struct ospf_interface *oi, - struct ospf_neighbor *nbr); +/** + * Legacy information: it is the peers who actually have this information + * and the protocol should not need to know about timers. + */ +extern void ospf_interface_bfd_show(struct vty *vty, + const struct interface *ifp, + struct json_object *json); -extern void ospf_bfd_show_info(struct vty *vty, void *bfd_info, - json_object *json_obj, bool use_json, - int param_only); +/** + * Disables interface BFD configuration and remove settings from all peers. + */ +extern void ospf_interface_disable_bfd(struct interface *ifp, + struct ospf_if_params *oip); -extern void ospf_bfd_info_free(void **bfd_info); +/** + * Create/update BFD session for this OSPF neighbor. + */ +extern void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr); #endif /* _ZEBRA_OSPF_BFD_H */ diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 19829d4546..2442f2e781 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -21,6 +21,7 @@ #include <zebra.h> +#include "lib/bfd.h" #include "monotime.h" #include "linklist.h" #include "thread.h" @@ -60,6 +61,7 @@ unsigned long conf_debug_ospf_ti_lfa = 0; unsigned long conf_debug_ospf_defaultinfo = 0; unsigned long conf_debug_ospf_ldp_sync = 0; unsigned long conf_debug_ospf_gr = 0; +unsigned long conf_debug_ospf_bfd; /* Enable debug option variables -- valid only session. */ unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; @@ -76,6 +78,7 @@ unsigned long term_debug_ospf_ti_lfa = 0; unsigned long term_debug_ospf_defaultinfo; unsigned long term_debug_ospf_ldp_sync; unsigned long term_debug_ospf_gr = 0; +unsigned long term_debug_ospf_bfd; const char *ospf_redist_string(unsigned int route_type) { @@ -1563,6 +1566,31 @@ DEFPY (debug_ospf_gr, return CMD_SUCCESS; } +DEFPY(debug_ospf_bfd, debug_ospf_bfd_cmd, + "[no] debug ospf bfd", + NO_STR + DEBUG_STR + OSPF_STR + "Bidirection Forwarding Detection\n") +{ + if (vty->node == CONFIG_NODE) { + if (no) { + bfd_protocol_integration_set_debug(false); + CONF_DEBUG_OFF(bfd, BFD_LIB); + } else { + bfd_protocol_integration_set_debug(true); + CONF_DEBUG_ON(bfd, BFD_LIB); + } + } + + if (no) + TERM_DEBUG_OFF(bfd, BFD_LIB); + else + TERM_DEBUG_ON(bfd, BFD_LIB); + + return CMD_SUCCESS; +} + DEFUN (no_debug_ospf, no_debug_ospf_cmd, "no debug ospf", @@ -1594,6 +1622,10 @@ DEFUN (no_debug_ospf, DEBUG_OFF(defaultinfo, DEFAULTINFO); DEBUG_OFF(ldp_sync, LDP_SYNC); + /* BFD debugging is two parts: OSPF and library. */ + DEBUG_OFF(bfd, BFD_LIB); + bfd_protocol_integration_set_debug(false); + for (i = 0; i < 5; i++) DEBUG_PACKET_OFF(i, flag); } @@ -1621,6 +1653,7 @@ DEFUN (no_debug_ospf, TERM_DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE); TERM_DEBUG_OFF(defaultinfo, DEFAULTINFO); TERM_DEBUG_OFF(ldp_sync, LDP_SYNC); + TERM_DEBUG_OFF(bfd, BFD_LIB); return CMD_SUCCESS; } @@ -1730,6 +1763,10 @@ static int show_debugging_ospf_common(struct vty *vty) if (IS_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) vty_out(vty, " OSPF Graceful Restart Helper debugging is on\n"); + if (IS_DEBUG_OSPF(bfd, BFD_LIB) == OSPF_DEBUG_BFD_LIB) + vty_out(vty, + " OSPF BFD integration library debugging is on\n"); + vty_out(vty, "\n"); return CMD_SUCCESS; @@ -1917,6 +1954,11 @@ static int config_write_debug(struct vty *vty) write = 1; } + if (IS_CONF_DEBUG_OSPF(bfd, BFD_LIB) == OSPF_DEBUG_BFD_LIB) { + vty_out(vty, "debug ospf%s bfd\n", str); + write = 1; + } + return write; } @@ -1949,6 +1991,7 @@ void ospf_debug_init(void) install_element(ENABLE_NODE, &no_debug_ospf_default_info_cmd); install_element(ENABLE_NODE, &no_debug_ospf_ldp_sync_cmd); install_element(ENABLE_NODE, &debug_ospf_gr_cmd); + install_element(ENABLE_NODE, &debug_ospf_bfd_cmd); install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd); install_element(ENABLE_NODE, &debug_ospf_packet_cmd); @@ -1992,6 +2035,7 @@ void ospf_debug_init(void) install_element(CONFIG_NODE, &no_debug_ospf_default_info_cmd); install_element(CONFIG_NODE, &no_debug_ospf_ldp_sync_cmd); install_element(CONFIG_NODE, &debug_ospf_gr_cmd); + install_element(CONFIG_NODE, &debug_ospf_bfd_cmd); install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd); install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd); diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index c4c5606663..b1c1d02a51 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -67,6 +67,8 @@ #define OSPF_DEBUG_GR_HELPER 0x01 #define OSPF_DEBUG_GR 0x03 +#define OSPF_DEBUG_BFD_LIB 0x01 + /* Macro for setting debug option. */ #define CONF_DEBUG_PACKET_ON(a, b) conf_debug_ospf_packet[a] |= (b) #define CONF_DEBUG_PACKET_OFF(a, b) conf_debug_ospf_packet[a] &= ~(b) @@ -140,6 +142,7 @@ extern unsigned long term_debug_ospf_ti_lfa; extern unsigned long term_debug_ospf_defaultinfo; extern unsigned long term_debug_ospf_ldp_sync; extern unsigned long term_debug_ospf_gr; +extern unsigned long term_debug_ospf_bfd; /* Message Strings. */ extern char *ospf_lsa_type_str[]; diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 51599ccc8a..d494f0fbce 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -35,6 +35,7 @@ #include "ldp_sync.h" #include "ospfd/ospfd.h" +#include "ospfd/ospf_bfd.h" #include "ospfd/ospf_spf.h" #include "ospfd/ospf_interface.h" #include "ospfd/ospf_ism.h" @@ -49,11 +50,11 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_ldp_sync.h" -DEFINE_QOBJ_TYPE(ospf_interface) -DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)) -DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)) -DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) -DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) +DEFINE_QOBJ_TYPE(ospf_interface); +DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)); +DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)); +DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)); +DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)); int ospf_interface_neighbor_count(struct ospf_interface *oi) { @@ -545,10 +546,11 @@ static struct ospf_if_params *ospf_new_if_params(void) return oip; } -void ospf_del_if_params(struct ospf_if_params *oip) +static void ospf_del_if_params(struct interface *ifp, + struct ospf_if_params *oip) { list_delete(&oip->auth_crypt); - bfd_info_free(&(oip->bfd_info)); + ospf_interface_disable_bfd(ifp, oip); ldp_sync_info_free(&(oip->ldp_sync_info)); XFREE(MTYPE_OSPF_IF_PARAMS, oip); } @@ -582,7 +584,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) && !OSPF_IF_PARAM_CONFIGURED(oip, if_area) && listcount(oip->auth_crypt) == 0) { - ospf_del_if_params(oip); + ospf_del_if_params(ifp, oip); rn->info = NULL; route_unlock_node(rn); } @@ -696,10 +698,10 @@ static int ospf_if_delete_hook(struct interface *ifp) for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) if (rn->info) - ospf_del_if_params(rn->info); + ospf_del_if_params(ifp, rn->info); route_table_finish(IF_OIFS_PARAMS(ifp)); - ospf_del_if_params((struct ospf_if_params *)IF_DEF_PARAMS(ifp)); + ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp)); XFREE(MTYPE_OSPF_IF_INFO, ifp->info); return rc; diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index bf59af16c2..a9534f543d 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -22,6 +22,7 @@ #ifndef _ZEBRA_OSPF_INTERFACE_H #define _ZEBRA_OSPF_INTERFACE_H +#include "lib/bfd.h" #include "qobj.h" #include "hook.h" #include "ospfd/ospf_packet.h" @@ -104,7 +105,16 @@ struct ospf_if_params { uint32_t network_lsa_seqnum; /* Network LSA seqnum */ /* BFD configuration */ - struct bfd_info *bfd_info; + struct bfd_configuration { + /** BFD session detection multiplier. */ + uint8_t detection_multiplier; + /** BFD session minimum required receive interval. */ + uint32_t min_rx; + /** BFD session minimum required transmission interval. */ + uint32_t min_tx; + /** BFD profile. */ + char profile[BFD_PROFILE_NAME_LEN]; + } *bfd_config; /* MPLS LDP-IGP Sync configuration */ struct ldp_sync_info *ldp_sync_info; @@ -252,9 +262,9 @@ struct ospf_interface { uint32_t full_nbrs; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(ospf_interface) +DECLARE_QOBJ_TYPE(ospf_interface); /* Prototypes. */ extern char *ospf_if_name(struct ospf_interface *); @@ -285,7 +295,6 @@ extern struct ospf_if_params *ospf_lookup_if_params(struct interface *, struct in_addr); extern struct ospf_if_params *ospf_get_if_params(struct interface *, struct in_addr); -extern void ospf_del_if_params(struct ospf_if_params *); extern void ospf_free_if_params(struct interface *, struct in_addr); extern void ospf_if_update_params(struct interface *, struct in_addr); @@ -329,10 +338,10 @@ extern void ospf_if_set_multicast(struct ospf_interface *); extern void ospf_if_interface(struct interface *ifp); -DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)) -DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)) +DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)); +DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)); -DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) -DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) +DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)); +DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)); #endif /* _ZEBRA_OSPF_INTERFACE_H */ diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 36e97f8779..1850d946b8 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -45,7 +45,7 @@ DEFINE_HOOK(ospf_ism_change, (struct ospf_interface * oi, int state, int oldstate), - (oi, state, oldstate)) + (oi, state, oldstate)); /* elect DR and BDR. Refer to RFC2319 section 9.4 */ static struct ospf_neighbor *ospf_dr_election_sub(struct list *routers) diff --git a/ospfd/ospf_ism.h b/ospfd/ospf_ism.h index c41ba6c843..5d0f95aed1 100644 --- a/ospfd/ospf_ism.h +++ b/ospfd/ospf_ism.h @@ -97,6 +97,6 @@ extern int ospf_dr_election(struct ospf_interface *oi); DECLARE_HOOK(ospf_ism_change, (struct ospf_interface * oi, int state, int oldstate), - (oi, state, oldstate)) + (oi, state, oldstate)); #endif /* _ZEBRA_OSPF_ISM_H */ diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 6bde5467b2..cb1c565d37 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1765,7 +1765,14 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf, /* copy over Type-7 data to new */ extnew->e[0].tos = ext->e[0].tos; extnew->e[0].route_tag = ext->e[0].route_tag; - extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr; + if (type7->area->suppress_fa) { + extnew->e[0].fwd_addr.s_addr = 0; + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_lsa_translated_nssa_new(): Suppress forwarding address for %pI4", + &ei.p.prefix); + } else + extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr; new->data->ls_seqnum = type7->data->ls_seqnum; /* add translated flag, checksum and lock new lsa */ @@ -1777,7 +1784,8 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf, /* Originate Translated Type-5 for supplied Type-7 NSSA LSA */ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, - struct ospf_lsa *type7) + struct ospf_lsa *type7, + struct ospf_lsa *type5) { struct ospf_lsa *new; struct as_external_lsa *extnew; @@ -1796,6 +1804,10 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, extnew = (struct as_external_lsa *)new->data; + /* Update LSA sequence number from translated Type-5 LSA */ + if (type5) + new->data->ls_seqnum = lsa_seqnum_increment(type5); + if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) { flog_warn(EC_OSPF_LSA_INSTALL_FAILURE, "%s: Could not install LSA id %pI4", __func__, @@ -1823,6 +1835,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, struct ospf_lsa *type5) { struct ospf_lsa *new = NULL; + struct as_external_lsa *extold = NULL; + uint32_t ls_seqnum = 0; /* Sanity checks. */ assert(type7 || type5); @@ -1887,6 +1901,12 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, return NULL; } + extold = (struct as_external_lsa *)type5->data; + if (type7->area->suppress_fa == 1) { + if (extold->e[0].fwd_addr.s_addr == 0) + ls_seqnum = ntohl(type5->data->ls_seqnum); + } + /* Delete LSA from neighbor retransmit-list. */ ospf_ls_retransmit_delete_nbr_as(ospf, type5); @@ -1899,6 +1919,11 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, return NULL; } + if (type7->area->suppress_fa == 1) { + if (extold->e[0].fwd_addr.s_addr == 0) + new->data->ls_seqnum = htonl(ls_seqnum + 1); + } + if (!(new = ospf_lsa_install(ospf, NULL, new))) { flog_warn( EC_OSPF_LSA_INSTALL_FAILURE, diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index f2a0d36e7e..3c1f94e628 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -341,11 +341,12 @@ extern char link_info_set(struct stream **s, struct in_addr id, extern struct in_addr ospf_get_nssa_ip(struct ospf_area *); extern int ospf_translated_nssa_compare(struct ospf_lsa *, struct ospf_lsa *); -extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *, - struct ospf_lsa *, - struct ospf_lsa *); -extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *, - struct ospf_lsa *); +extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, + struct ospf_lsa *type7, + struct ospf_lsa *type5); +extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, + struct ospf_lsa *type7, + struct ospf_lsa *type5); extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, int type); #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 6a90dbff11..d23dea0ca1 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -22,6 +22,7 @@ #include <zebra.h> #include <lib/version.h> +#include "bfd.h" #include "getopt.h" #include "thread.h" #include "prefix.h" @@ -98,6 +99,7 @@ static void sighup(void) static void sigint(void) { zlog_notice("Terminating on signal"); + bfd_protocol_integration_set_shutdown(true); ospf_terminate(); exit(0); } @@ -141,7 +143,8 @@ FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT, .signals = ospf_signals, .n_signals = array_size(ospf_signals), .privs = &ospfd_privs, .yang_modules = ospfd_yang_modules, - .n_yang_modules = array_size(ospfd_yang_modules), ) + .n_yang_modules = array_size(ospfd_yang_modules), +); /* OSPFd main routine. */ int main(int argc, char **argv) @@ -213,7 +216,7 @@ int main(int argc, char **argv) ospf_vty_clear_init(); /* OSPF BFD init */ - ospf_bfd_init(); + ospf_bfd_init(master); /* OSPF LDP IGP Sync init */ ospf_ldp_sync_init(); diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index f4fb68cbdf..2838443892 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -25,38 +25,38 @@ #include "ospf_memory.h" -DEFINE_MGROUP(OSPFD, "ospfd") -DEFINE_MTYPE(OSPFD, OSPF_TOP, "OSPF top") -DEFINE_MTYPE(OSPFD, OSPF_AREA, "OSPF area") -DEFINE_MTYPE(OSPFD, OSPF_AREA_RANGE, "OSPF area range") -DEFINE_MTYPE(OSPFD, OSPF_NETWORK, "OSPF network") -DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR_STATIC, "OSPF static nbr") -DEFINE_MTYPE(OSPFD, OSPF_IF, "OSPF interface") -DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR, "OSPF neighbor") -DEFINE_MTYPE(OSPFD, OSPF_ROUTE, "OSPF route") -DEFINE_MTYPE(OSPFD, OSPF_TMP, "OSPF tmp mem") -DEFINE_MTYPE(OSPFD, OSPF_LSA, "OSPF LSA") -DEFINE_MTYPE(OSPFD, OSPF_LSA_DATA, "OSPF LSA data") -DEFINE_MTYPE(OSPFD, OSPF_LSDB, "OSPF LSDB") -DEFINE_MTYPE(OSPFD, OSPF_PACKET, "OSPF packet") -DEFINE_MTYPE(OSPFD, OSPF_FIFO, "OSPF FIFO queue") -DEFINE_MTYPE(OSPFD, OSPF_VERTEX, "OSPF vertex") -DEFINE_MTYPE(OSPFD, OSPF_VERTEX_PARENT, "OSPF vertex parent") -DEFINE_MTYPE(OSPFD, OSPF_NEXTHOP, "OSPF nexthop") -DEFINE_MTYPE(OSPFD, OSPF_PATH, "OSPF path") -DEFINE_MTYPE(OSPFD, OSPF_VL_DATA, "OSPF VL data") -DEFINE_MTYPE(OSPFD, OSPF_CRYPT_KEY, "OSPF crypt key") -DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_INFO, "OSPF ext. info") -DEFINE_MTYPE(OSPFD, OSPF_DISTANCE, "OSPF distance") -DEFINE_MTYPE(OSPFD, OSPF_IF_INFO, "OSPF if info") -DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params") -DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message") -DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters") -DEFINE_MTYPE(OSPFD, OSPF_ROUTER_INFO, "OSPF Router Info parameters") -DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") -DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters") -DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters") -DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper") -DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation") -DEFINE_MTYPE(OSPFD, OSPF_P_SPACE, "OSPF TI-LFA P-Space") -DEFINE_MTYPE(OSPFD, OSPF_Q_SPACE, "OSPF TI-LFA Q-Space") +DEFINE_MGROUP(OSPFD, "ospfd"); +DEFINE_MTYPE(OSPFD, OSPF_TOP, "OSPF top"); +DEFINE_MTYPE(OSPFD, OSPF_AREA, "OSPF area"); +DEFINE_MTYPE(OSPFD, OSPF_AREA_RANGE, "OSPF area range"); +DEFINE_MTYPE(OSPFD, OSPF_NETWORK, "OSPF network"); +DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR_STATIC, "OSPF static nbr"); +DEFINE_MTYPE(OSPFD, OSPF_IF, "OSPF interface"); +DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR, "OSPF neighbor"); +DEFINE_MTYPE(OSPFD, OSPF_ROUTE, "OSPF route"); +DEFINE_MTYPE(OSPFD, OSPF_TMP, "OSPF tmp mem"); +DEFINE_MTYPE(OSPFD, OSPF_LSA, "OSPF LSA"); +DEFINE_MTYPE(OSPFD, OSPF_LSA_DATA, "OSPF LSA data"); +DEFINE_MTYPE(OSPFD, OSPF_LSDB, "OSPF LSDB"); +DEFINE_MTYPE(OSPFD, OSPF_PACKET, "OSPF packet"); +DEFINE_MTYPE(OSPFD, OSPF_FIFO, "OSPF FIFO queue"); +DEFINE_MTYPE(OSPFD, OSPF_VERTEX, "OSPF vertex"); +DEFINE_MTYPE(OSPFD, OSPF_VERTEX_PARENT, "OSPF vertex parent"); +DEFINE_MTYPE(OSPFD, OSPF_NEXTHOP, "OSPF nexthop"); +DEFINE_MTYPE(OSPFD, OSPF_PATH, "OSPF path"); +DEFINE_MTYPE(OSPFD, OSPF_VL_DATA, "OSPF VL data"); +DEFINE_MTYPE(OSPFD, OSPF_CRYPT_KEY, "OSPF crypt key"); +DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_INFO, "OSPF ext. info"); +DEFINE_MTYPE(OSPFD, OSPF_DISTANCE, "OSPF distance"); +DEFINE_MTYPE(OSPFD, OSPF_IF_INFO, "OSPF if info"); +DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params"); +DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message"); +DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters"); +DEFINE_MTYPE(OSPFD, OSPF_ROUTER_INFO, "OSPF Router Info parameters"); +DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters"); +DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters"); +DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters"); +DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper"); +DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation"); +DEFINE_MTYPE(OSPFD, OSPF_P_SPACE, "OSPF TI-LFA P-Space"); +DEFINE_MTYPE(OSPFD, OSPF_Q_SPACE, "OSPF TI-LFA Q-Space"); diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index 42bc8d7b77..9bd0a844af 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -24,40 +24,40 @@ #include "memory.h" -DECLARE_MGROUP(OSPFD) -DECLARE_MTYPE(OSPF_TOP) -DECLARE_MTYPE(OSPF_AREA) -DECLARE_MTYPE(OSPF_AREA_RANGE) -DECLARE_MTYPE(OSPF_NETWORK) -DECLARE_MTYPE(OSPF_NEIGHBOR_STATIC) -DECLARE_MTYPE(OSPF_IF) -DECLARE_MTYPE(OSPF_NEIGHBOR) -DECLARE_MTYPE(OSPF_ROUTE) -DECLARE_MTYPE(OSPF_TMP) -DECLARE_MTYPE(OSPF_LSA) -DECLARE_MTYPE(OSPF_LSA_DATA) -DECLARE_MTYPE(OSPF_LSDB) -DECLARE_MTYPE(OSPF_PACKET) -DECLARE_MTYPE(OSPF_FIFO) -DECLARE_MTYPE(OSPF_VERTEX) -DECLARE_MTYPE(OSPF_VERTEX_PARENT) -DECLARE_MTYPE(OSPF_NEXTHOP) -DECLARE_MTYPE(OSPF_PATH) -DECLARE_MTYPE(OSPF_VL_DATA) -DECLARE_MTYPE(OSPF_CRYPT_KEY) -DECLARE_MTYPE(OSPF_EXTERNAL_INFO) -DECLARE_MTYPE(OSPF_DISTANCE) -DECLARE_MTYPE(OSPF_IF_INFO) -DECLARE_MTYPE(OSPF_IF_PARAMS) -DECLARE_MTYPE(OSPF_MESSAGE) -DECLARE_MTYPE(OSPF_MPLS_TE) -DECLARE_MTYPE(OSPF_ROUTER_INFO) -DECLARE_MTYPE(OSPF_PCE_PARAMS) -DECLARE_MTYPE(OSPF_SR_PARAMS) -DECLARE_MTYPE(OSPF_EXT_PARAMS) -DECLARE_MTYPE(OSPF_GR_HELPER) -DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR) -DECLARE_MTYPE(OSPF_P_SPACE) -DECLARE_MTYPE(OSPF_Q_SPACE) +DECLARE_MGROUP(OSPFD); +DECLARE_MTYPE(OSPF_TOP); +DECLARE_MTYPE(OSPF_AREA); +DECLARE_MTYPE(OSPF_AREA_RANGE); +DECLARE_MTYPE(OSPF_NETWORK); +DECLARE_MTYPE(OSPF_NEIGHBOR_STATIC); +DECLARE_MTYPE(OSPF_IF); +DECLARE_MTYPE(OSPF_NEIGHBOR); +DECLARE_MTYPE(OSPF_ROUTE); +DECLARE_MTYPE(OSPF_TMP); +DECLARE_MTYPE(OSPF_LSA); +DECLARE_MTYPE(OSPF_LSA_DATA); +DECLARE_MTYPE(OSPF_LSDB); +DECLARE_MTYPE(OSPF_PACKET); +DECLARE_MTYPE(OSPF_FIFO); +DECLARE_MTYPE(OSPF_VERTEX); +DECLARE_MTYPE(OSPF_VERTEX_PARENT); +DECLARE_MTYPE(OSPF_NEXTHOP); +DECLARE_MTYPE(OSPF_PATH); +DECLARE_MTYPE(OSPF_VL_DATA); +DECLARE_MTYPE(OSPF_CRYPT_KEY); +DECLARE_MTYPE(OSPF_EXTERNAL_INFO); +DECLARE_MTYPE(OSPF_DISTANCE); +DECLARE_MTYPE(OSPF_IF_INFO); +DECLARE_MTYPE(OSPF_IF_PARAMS); +DECLARE_MTYPE(OSPF_MESSAGE); +DECLARE_MTYPE(OSPF_MPLS_TE); +DECLARE_MTYPE(OSPF_ROUTER_INFO); +DECLARE_MTYPE(OSPF_PCE_PARAMS); +DECLARE_MTYPE(OSPF_SR_PARAMS); +DECLARE_MTYPE(OSPF_EXT_PARAMS); +DECLARE_MTYPE(OSPF_GR_HELPER); +DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR); +DECLARE_MTYPE(OSPF_P_SPACE); +DECLARE_MTYPE(OSPF_Q_SPACE); #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index 2fa43923ab..a1b35b2fcd 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -21,6 +21,7 @@ #include <zebra.h> +#include "lib/bfd.h" #include "linklist.h" #include "prefix.h" #include "memory.h" @@ -99,8 +100,6 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi) nbr->crypt_seqnum = 0; - ospf_bfd_info_nbr_create(oi, nbr); - /* Initialize GR Helper info*/ nbr->gr_helper_info.recvd_grace_period = 0; nbr->gr_helper_info.actual_grace_period = 0; @@ -149,7 +148,7 @@ void ospf_nbr_free(struct ospf_neighbor *nbr) /* Cancel all events. */ /* Thread lookup cost would be negligible. */ thread_cancel_event(master, nbr); - ospf_bfd_info_free(&nbr->bfd_info); + bfd_sess_free(&nbr->bfd_session); OSPF_NSM_TIMER_OFF(nbr->gr_helper_info.t_grace_timer); @@ -458,6 +457,9 @@ static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi, if (ntohs(ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC) nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; + /* Configure BFD if interface has it. */ + ospf_neighbor_bfd_apply(nbr); + if (IS_DEBUG_OSPF_EVENT) zlog_debug("NSM[%s:%pI4]: start", IF_NAME(oi), &nbr->router_id); diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h index 758693e289..2ce6d6755c 100644 --- a/ospfd/ospf_neighbor.h +++ b/ospfd/ospf_neighbor.h @@ -88,7 +88,7 @@ struct ospf_neighbor { uint32_t state_change; /* NSM state change counter */ /* BFD information */ - void *bfd_info; + struct bfd_session_params *bfd_session; /* ospf graceful restart HELPER info */ struct ospf_helper_info gr_helper_info; diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 26e7855e8c..006c4888ae 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -53,7 +53,7 @@ DEFINE_HOOK(ospf_nsm_change, (struct ospf_neighbor * on, int state, int oldstate), - (on, state, oldstate)) + (on, state, oldstate)); static void nsm_clear_adj(struct ospf_neighbor *); @@ -761,7 +761,8 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) if (state == NSM_Down) nbr->crypt_seqnum = 0; - ospf_bfd_trigger_event(nbr, old_state, state); + if (nbr->bfd_session) + ospf_bfd_trigger_event(nbr, old_state, state); /* Preserve old status? */ } diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h index 24cf05009c..e8573c6301 100644 --- a/ospfd/ospf_nsm.h +++ b/ospfd/ospf_nsm.h @@ -78,6 +78,6 @@ extern void ospf_db_summary_clear(struct ospf_neighbor *); extern int nsm_should_adj(struct ospf_neighbor *nbr); DECLARE_HOOK(ospf_nsm_change, (struct ospf_neighbor * on, int state, int oldstate), - (on, state, oldstate)) + (on, state, oldstate)); #endif /* _ZEBRA_OSPF_NSM_H */ diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 3939b5479f..ae9ab48d4a 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -56,9 +56,9 @@ #include "ospfd/ospf_ext.h" #include "ospfd/ospf_errors.h" -DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table") -DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info") -DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info") +DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table"); +DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info"); +DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info"); /*------------------------------------------------------------------------* * Followings are initialize/terminate functions for Opaque-LSAs handling. diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 3f4ca44b05..8418bbf2b9 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -2565,4 +2565,5 @@ static int ospf_snmp_module_init(void) FRR_MODULE_SETUP(.name = "ospfd_snmp", .version = FRR_VERSION, .description = "ospfd AgentX SNMP module", - .init = ospf_snmp_module_init, ) + .init = ospf_snmp_module_init, +); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 6cd6a47098..1e0814764b 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -89,7 +89,7 @@ static int vertex_cmp(const struct vertex *v1, const struct vertex *v2) } return 0; } -DECLARE_SKIPLIST_NONUNIQ(vertex_pqueue, struct vertex, pqi, vertex_cmp) +DECLARE_SKIPLIST_NONUNIQ(vertex_pqueue, struct vertex, pqi, vertex_cmp); static void lsdb_clean_stat(struct ospf_lsdb *lsdb) { diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 66555be4b7..835caab288 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -33,7 +33,7 @@ /* The "root" is the node running the SPF calculation */ -PREDECL_SKIPLIST_NONUNIQ(vertex_pqueue) +PREDECL_SKIPLIST_NONUNIQ(vertex_pqueue); /* A router or network in an area */ struct vertex { struct vertex_pqueue_item pqi; diff --git a/ospfd/ospf_ti_lfa.c b/ospfd/ospf_ti_lfa.c index 4a0186bfb9..59b3b624e3 100644 --- a/ospfd/ospf_ti_lfa.c +++ b/ospfd/ospf_ti_lfa.c @@ -37,9 +37,9 @@ DECLARE_RBTREE_UNIQ(p_spaces, struct p_space, p_spaces_item, - p_spaces_compare_func) + p_spaces_compare_func); DECLARE_RBTREE_UNIQ(q_spaces, struct q_space, q_spaces_item, - q_spaces_compare_func) + q_spaces_compare_func); static void ospf_ti_lfa_generate_p_space(struct ospf_area *area, struct vertex *child, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 2ff59ccf49..d634853b3e 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -60,7 +60,7 @@ FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, -) +); static const char *const ospf_network_type_str[] = { "Null", "POINTOPOINT", "BROADCAST", "NBMA", "POINTOMULTIPOINT", @@ -1574,6 +1574,58 @@ DEFUN (ospf_area_nssa, return ospf_area_nssa_cmd_handler(vty, argc, argv, 0, 0); } +DEFUN(ospf_area_nssa_suppress_fa, ospf_area_nssa_suppress_fa_cmd, + "area <A.B.C.D|(0-4294967295)> nssa suppress-fa", + "OSPF area parameters\n" + "OSPF area ID in IP address format\n" + "OSPF area ID as a decimal value\n" + "Configure OSPF area as nssa\n" + "Suppress forwarding address\n") +{ + int idx_ipv4_number = 1; + struct in_addr area_id; + int format; + + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, + argv[idx_ipv4_number]->arg); + + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); + ospf_area_nssa_suppress_fa_set(ospf, area_id); + + ospf_schedule_abr_task(ospf); + + return CMD_SUCCESS; +} + +DEFUN(no_ospf_area_nssa_suppress_fa, no_ospf_area_nssa_suppress_fa_cmd, + "no area <A.B.C.D|(0-4294967295)> nssa suppress-fa", + NO_STR + "OSPF area parameters\n" + "OSPF area ID in IP address format\n" + "OSPF area ID as a decimal value\n" + "Configure OSPF area as nssa\n" + "Suppress forwarding address\n") +{ + int idx_ipv4_number = 2; + struct in_addr area_id; + int format; + + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + VTY_GET_OSPF_AREA_ID_NO_BB("nssa", area_id, format, + argv[idx_ipv4_number]->arg); + + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); + ospf_area_nssa_suppress_fa_unset(ospf, area_id); + + ospf_schedule_abr_task(ospf); + + return CMD_SUCCESS; +} + DEFUN (ospf_area_nssa_no_summary, ospf_area_nssa_no_summary_cmd, "area <A.B.C.D|(0-4294967295)> nssa no-summary", @@ -3776,7 +3828,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, " Neighbor Count is %d, Adjacent neighbor count is %d\n", ospf_nbr_count(oi, 0), ospf_nbr_count(oi, NSM_Full)); - ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json); + + ospf_interface_bfd_show(vty, ifp, json_interface_sub); /* OSPF Authentication information */ ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); @@ -5282,7 +5335,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, .helper_exit_reason)); } - ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0); + bfd_sess_show(vty, json_neigh, nbr->bfd_session); if (use_json) json_object_array_add(json_neigh_array, json_neigh); @@ -7109,14 +7162,14 @@ DEFUN (show_ip_ospf_database_max, return ret; } -DEFUN (show_ip_ospf_instance_database, - show_ip_ospf_instance_database_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]", +ALIAS (show_ip_ospf_database_max, + show_ip_ospf_database_cmd, + "show ip ospf [vrf <NAME|all>] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]", SHOW_STR IP_STR "OSPF information\n" - "Instance ID\n" VRF_CMD_HELP_STR + "All VRFs\n" "Database summary\n" OSPF_LSA_TYPES_DESC "Link State ID (as an IP address)\n" @@ -7124,78 +7177,6 @@ DEFUN (show_ip_ospf_instance_database, "Advertising Router link states\n" "Advertising Router (as an IP address)\n" JSON_STR) -{ - struct ospf *ospf; - unsigned short instance = 0; - struct listnode *node = NULL; - char *vrf_name = NULL; - bool all_vrf = false; - int ret = CMD_SUCCESS; - int inst = 0; - int idx = 0; - uint8_t use_vrf = 0; - bool uj = use_json(argc, argv); - json_object *json = NULL; - - if (uj) - json = json_object_new_object(); - - if (argv_find(argv, argc, "(1-65535)", &idx)) { - instance = strtoul(argv[idx]->arg, NULL, 10); - if (instance != ospf_instance) - return CMD_NOT_MY_INSTANCE; - - ospf = ospf_lookup_instance(instance); - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; - - return (show_ip_ospf_database_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); - } else if (argv_find(argv, argc, "vrf", &idx)) { - vrf_name = argv[++idx]->arg; - all_vrf = strmatch(vrf_name, "all"); - } - - if (vrf_name) { - use_vrf = 1; - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { - if (!ospf->oi_running) - continue; - ret = (show_ip_ospf_database_common( - vty, ospf, idx ? 2 : 0, argc, argv, - use_vrf, json, uj)); - } - } else { - ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if ((ospf == NULL) || !ospf->oi_running) { - vty_out(vty, "%% OSPF instance not found\n"); - return CMD_SUCCESS; - } - - ret = (show_ip_ospf_database_common( - vty, ospf, idx ? 2 : 0, argc, argv, use_vrf, - json, uj)); - } - } else { - /* Display default ospf (instance 0) info */ - ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL || !ospf->oi_running) { - vty_out(vty, "%% OSPF instance not found\n"); - return CMD_SUCCESS; - } - - ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv, - use_vrf, json, uj)); - } - - if (uj) { - vty_out(vty, "%s\n", json_object_to_json_string(json)); - json_object_free(json); - } - - return ret; -} DEFUN (show_ip_ospf_instance_database_max, show_ip_ospf_instance_database_max_cmd, @@ -7238,6 +7219,20 @@ DEFUN (show_ip_ospf_instance_database_max, return CMD_SUCCESS; } +ALIAS (show_ip_ospf_instance_database_max, + show_ip_ospf_instance_database_cmd, + "show ip ospf (1-65535) database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Link State ID (as an IP address)\n" + "Self-originated link states\n" + "Advertising Router link states\n" + "Advertising Router (as an IP address)\n" + JSON_STR) static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, struct ospf *ospf, @@ -7327,14 +7322,14 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, return CMD_SUCCESS; } -DEFUN (show_ip_ospf_instance_database_type_adv_router, - show_ip_ospf_instance_database_type_adv_router_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]", +DEFUN (show_ip_ospf_database_type_adv_router, + show_ip_ospf_database_type_adv_router_cmd, + "show ip ospf [vrf <NAME|all>] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" - "Instance ID\n" VRF_CMD_HELP_STR + "All VRFs\n" "Database summary\n" OSPF_LSA_TYPES_DESC "Advertising Router link states\n" @@ -7343,7 +7338,6 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, JSON_STR) { struct ospf *ospf = NULL; - unsigned short instance = 0; struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = false; @@ -7357,19 +7351,6 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, if (uj) json = json_object_new_object(); - if (argv_find(argv, argc, "(1-65535)", &idx)) { - instance = strtoul(argv[idx]->arg, NULL, 10); - if (instance != ospf_instance) - return CMD_NOT_MY_INSTANCE; - - ospf = ospf_lookup_instance(instance); - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; - - return (show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); - } - OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (vrf_name) { @@ -7416,8 +7397,50 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } return ret; - /*return (show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv));*/ +} + +DEFUN (show_ip_ospf_instance_database_type_adv_router, + show_ip_ospf_instance_database_type_adv_router_cmd, + "show ip ospf (1-65535) database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Advertising Router link states\n" + "Advertising Router (as an IP address)\n" + "Self-originated link states\n" + JSON_STR) +{ + int idx_number = 3; + struct ospf *ospf; + unsigned short instance = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); + + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; + + show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv, + 0, json, uj); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return CMD_SUCCESS; } DEFUN (ip_ospf_authentication_args, @@ -11716,7 +11739,7 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) } /* bfd print. */ - if (params && params->bfd_info) + if (params && params->bfd_config) ospf_bfd_write_config(vty, params); /* MTU ignore print. */ @@ -11852,6 +11875,10 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) vty_out(vty, " area %s nssa no-summary\n", buf); + if (area->suppress_fa) + vty_out(vty, + " area %s nssa suppress-fa\n", + buf); } if (area->default_cost != 1) @@ -12375,8 +12402,10 @@ void ospf_vty_show_init(void) install_element(VIEW_NODE, &show_ip_ospf_instance_cmd); /* "show ip ospf database" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_database_cmd); install_element(VIEW_NODE, &show_ip_ospf_database_max_cmd); - + install_element(VIEW_NODE, + &show_ip_ospf_database_type_adv_router_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_database_cmd); @@ -12711,6 +12740,8 @@ void ospf_vty_init(void) install_element(OSPF_NODE, &ospf_area_nssa_translate_cmd); install_element(OSPF_NODE, &ospf_area_nssa_no_summary_cmd); install_element(OSPF_NODE, &no_ospf_area_nssa_no_summary_cmd); + install_element(OSPF_NODE, &ospf_area_nssa_suppress_fa_cmd); + install_element(OSPF_NODE, &no_ospf_area_nssa_suppress_fa_cmd); install_element(OSPF_NODE, &no_ospf_area_nssa_cmd); install_element(OSPF_NODE, &ospf_area_default_cost_cmd); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index a2fbd01ab8..56b2f8d660 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -53,9 +53,9 @@ #include "ospfd/ospf_sr.h" #include "ospfd/ospf_ldp_sync.h" -DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table") -DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute") -DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments") +DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table"); +DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute"); +DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments"); /* Zebra structure to hold current status. */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 9590a9c73b..f126577aeb 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -42,6 +42,7 @@ #include "ldp_sync.h" #include "ospfd/ospfd.h" +#include "ospfd/ospf_bfd.h" #include "ospfd/ospf_network.h" #include "ospfd/ospf_interface.h" #include "ospfd/ospf_ism.h" @@ -62,7 +63,7 @@ #include "ospfd/ospf_gr_helper.h" -DEFINE_QOBJ_TYPE(ospf) +DEFINE_QOBJ_TYPE(ospf); /* OSPF process wide configuration. */ static struct ospf_master ospf_master; @@ -111,7 +112,7 @@ int q_spaces_compare_func(const struct q_space *a, const struct q_space *b) } DECLARE_RBTREE_UNIQ(p_spaces, struct p_space, p_spaces_item, - p_spaces_compare_func) + p_spaces_compare_func); void ospf_process_refresh_data(struct ospf *ospf, bool reset) { @@ -1671,6 +1672,7 @@ int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id) /* set NSSA area defaults */ area->no_summary = 0; + area->suppress_fa = 0; area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; area->NSSATranslatorStabilityInterval = @@ -1692,6 +1694,7 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc) ospf->anyNSSA--; /* set NSSA area defaults */ area->no_summary = 0; + area->suppress_fa = 0; area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; area->NSSATranslatorStabilityInterval = @@ -1707,6 +1710,32 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc) return 1; } +int ospf_area_nssa_suppress_fa_set(struct ospf *ospf, struct in_addr area_id) +{ + struct ospf_area *area; + + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; + + area->suppress_fa = 1; + + return 1; +} + +int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf, struct in_addr area_id) +{ + struct ospf_area *area; + + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; + + area->suppress_fa = 0; + + return 1; +} + int ospf_area_nssa_translator_role_set(struct ospf *ospf, struct in_addr area_id, int role) { @@ -1931,6 +1960,9 @@ static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma, nbr_nbma->nbr = nbr; + /* Configure BFD if interface has it. */ + ospf_neighbor_bfd_apply(nbr); + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start); } } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 5148bf555c..a3f78b074e 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -386,9 +386,9 @@ struct ospf { bool ti_lfa_enabled; enum protection_type ti_lfa_protection_type; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(ospf) +DECLARE_QOBJ_TYPE(ospf); enum ospf_ti_lfa_p_q_space_adjacency { OSPF_TI_LFA_P_Q_SPACE_ADJACENT, @@ -424,7 +424,7 @@ struct protected_resource { struct in_addr router_id; }; -PREDECL_RBTREE_UNIQ(q_spaces) +PREDECL_RBTREE_UNIQ(q_spaces); struct q_space { struct vertex *root; struct list *vertex_list; @@ -436,7 +436,7 @@ struct q_space { struct q_spaces_item q_spaces_item; }; -PREDECL_RBTREE_UNIQ(p_spaces) +PREDECL_RBTREE_UNIQ(p_spaces); struct p_space { struct vertex *root; struct protected_resource *protected_resource; @@ -476,7 +476,7 @@ struct ospf_area { int shortcut_capability; /* Other ABRs agree on S-bit */ uint32_t default_cost; /* StubDefaultCost. */ int auth_type; /* Authentication type. */ - + int suppress_fa; /* Suppress forwarding address in NSSA ABR */ uint8_t NSSATranslatorRole; /* NSSA configured role */ #define OSPF_NSSA_ROLE_NEVER 0 @@ -668,6 +668,10 @@ extern int ospf_area_no_summary_set(struct ospf *, struct in_addr); extern int ospf_area_no_summary_unset(struct ospf *, struct in_addr); extern int ospf_area_nssa_set(struct ospf *, struct in_addr); extern int ospf_area_nssa_unset(struct ospf *, struct in_addr, int); +extern int ospf_area_nssa_suppress_fa_set(struct ospf *ospf, + struct in_addr area_id); +extern int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf, + struct in_addr area_id); extern int ospf_area_nssa_translator_role_set(struct ospf *, struct in_addr, int); extern int ospf_area_export_list_set(struct ospf *, struct ospf_area *, diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 28d58452df..25ddef358f 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -113,7 +113,7 @@ ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM) ospfd_ospfd_SOURCES = ospfd/ospf_main.c ospfd_ospfd_snmp_la_SOURCES = ospfd/ospf_snmp.c -ospfd_ospfd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +ospfd_ospfd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 ospfd_ospfd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic ospfd_ospfd_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/pathd/path_cli.c b/pathd/path_cli.c index 8beb428135..cf14aa8c61 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -20,6 +20,7 @@ #include <math.h> #include <zebra.h> +#include "memory.h" #include "log.h" #include "command.h" #include "mpls.h" @@ -28,7 +29,6 @@ #include "pathd/pathd.h" #include "pathd/path_nb.h" -#include "pathd/path_memory.h" #ifndef VTYSH_EXTRACT_PL #include "pathd/path_cli_clippy.c" #endif @@ -46,7 +46,7 @@ static int config_write_traffic_eng(struct vty *vty); static int config_write_segment_lists(struct vty *vty); static int config_write_sr_policies(struct vty *vty); -DEFINE_MTYPE_STATIC(PATHD, PATH_CLI, "Client") +DEFINE_MTYPE_STATIC(PATHD, PATH_CLI, "Client"); /* Vty node structures. */ static struct cmd_node segment_routing_node = { diff --git a/pathd/path_main.c b/pathd/path_main.c index 8b7d4aba48..f54ab736c4 100644 --- a/pathd/path_main.c +++ b/pathd/path_main.c @@ -114,7 +114,8 @@ FRR_DAEMON_INFO(pathd, PATH, .vty_port = PATH_VTY_PORT, .signals = path_signals, .n_signals = array_size(path_signals), .privs = &pathd_privs, .yang_modules = pathd_yang_modules, - .n_yang_modules = array_size(pathd_yang_modules), ) + .n_yang_modules = array_size(pathd_yang_modules), +); int main(int argc, char **argv, char **envp) { diff --git a/pathd/path_memory.c b/pathd/path_memory.c deleted file mode 100644 index ad4904a298..0000000000 --- a/pathd/path_memory.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2020 NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include <memory.h> - -#include "pathd/path_memory.h" - -DEFINE_MGROUP(PATHD, "pathd") diff --git a/pathd/path_memory.h b/pathd/path_memory.h deleted file mode 100644 index e2f6787f66..0000000000 --- a/pathd/path_memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2020 NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _FRR_PATH_MEMORY_H_ -#define _FRR_PATH_MEMORY_H_ - -#include "memory.h" - -DECLARE_MGROUP(PATHD) - -#endif /* _FRR_PATH_MEMORY_H_ */ diff --git a/pathd/path_nb_config.c b/pathd/path_nb_config.c index 669db169ae..af54f5bce2 100644 --- a/pathd/path_nb_config.c +++ b/pathd/path_nb_config.c @@ -302,7 +302,6 @@ int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args *args) struct srte_policy *policy; mpls_label_t binding_sid; - policy = nb_running_get_entry(args->dnode, NULL, true); binding_sid = yang_dnode_get_uint32(args->dnode, NULL); switch (args->event) { @@ -315,6 +314,7 @@ int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args *args) case NB_EV_ABORT: break; case NB_EV_APPLY: + policy = nb_running_get_entry(args->dnode, NULL, true); srte_policy_update_binding_sid(policy, binding_sid); SET_FLAG(policy->flags, F_POLICY_MODIFIED); break; @@ -668,12 +668,12 @@ int pathd_srte_policy_candidate_path_segment_list_name_modify( struct srte_candidate *candidate; const char *segment_list_name; - candidate = nb_running_get_entry(args->dnode, NULL, true); - segment_list_name = yang_dnode_get_string(args->dnode, NULL); - if (args->event != NB_EV_APPLY) return NB_OK; + candidate = nb_running_get_entry(args->dnode, NULL, true); + segment_list_name = yang_dnode_get_string(args->dnode, NULL); + candidate->segment_list = srte_segment_list_find(segment_list_name); candidate->lsp->segment_list = candidate->segment_list; assert(candidate->segment_list); diff --git a/pathd/path_pcep.c b/pathd/path_pcep.c index 8b5ca8aff3..d6cd48ecdb 100644 --- a/pathd/path_pcep.c +++ b/pathd/path_pcep.c @@ -19,6 +19,7 @@ #include <zebra.h> #include "pceplib/pcep_utils_counters.h" +#include "memory.h" #include "log.h" #include "command.h" #include "libfrr.h" @@ -31,13 +32,13 @@ #include "pathd/pathd.h" #include "pathd/path_errors.h" -#include "pathd/path_pcep_memory.h" #include "pathd/path_pcep.h" #include "pathd/path_pcep_cli.h" #include "pathd/path_pcep_controller.h" #include "pathd/path_pcep_lib.h" #include "pathd/path_pcep_config.h" +DEFINE_MTYPE(PATHD, PCEP, "PCEP module"); /* * Globals. @@ -317,4 +318,5 @@ int pcep_module_init(void) FRR_MODULE_SETUP(.name = "frr_pathd_pcep", .version = FRR_VERSION, .description = "FRR pathd PCEP module", - .init = pcep_module_init) + .init = pcep_module_init, +); diff --git a/pathd/path_pcep.h b/pathd/path_pcep.h index b131b31445..654d089cbc 100644 --- a/pathd/path_pcep.h +++ b/pathd/path_pcep.h @@ -22,11 +22,13 @@ #include <stdbool.h> #include <debug.h> #include <netinet/tcp.h> +#include "memory.h" #include "pceplib/pcep_utils_logging.h" #include "pceplib/pcep_pcc_api.h" #include "mpls.h" #include "pathd/pathd.h" -#include "pathd/path_pcep_memory.h" + +DECLARE_MTYPE(PCEP); #define PCEP_DEFAULT_PORT 4189 #define MAX_PCC 32 diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c index 7bbed9464d..14404b1d08 100644 --- a/pathd/path_pcep_cli.c +++ b/pathd/path_pcep_cli.c @@ -33,7 +33,6 @@ #include "pathd/pathd.h" #include "pathd/path_errors.h" -#include "pathd/path_pcep_memory.h" #include "pathd/path_pcep.h" #include "pathd/path_pcep_cli.h" #include "pathd/path_pcep_controller.h" @@ -1046,7 +1045,7 @@ static int path_pcep_cli_pcc_pcc_peer(struct vty *vty, const char *peer_name, XMALLOC(MTYPE_PCEP, sizeof(struct pcc_opts)); memcpy(&pcc_opts_copy->addr, &pce_opts_cli->pce_opts.config_opts.source_ip, - sizeof(struct pcc_opts)); + sizeof(pcc_opts_copy->addr)); pcc_opts_copy->msd = pcc_msd_g; pcc_opts_copy->port = pce_opts_cli->pce_opts.config_opts.source_port; if (pcep_ctrl_update_pcc_options(pcep_g->fpt, pcc_opts_copy)) { diff --git a/pathd/path_pcep_lib.c b/pathd/path_pcep_lib.c index 1d2f25889e..e9d699de47 100644 --- a/pathd/path_pcep_lib.c +++ b/pathd/path_pcep_lib.c @@ -18,15 +18,18 @@ #include <zebra.h> +#include "memory.h" + #include <debug.h> #include "pceplib/pcep_utils_counters.h" #include "pceplib/pcep_timers.h" #include "pathd/path_errors.h" -#include "pathd/path_memory.h" #include "pathd/path_pcep.h" #include "pathd/path_pcep_lib.h" #include "pathd/path_pcep_debug.h" -#include "pathd/path_pcep_memory.h" + +DEFINE_MTYPE_STATIC(PATHD, PCEPLIB_INFRA, "PCEPlib Infrastructure"); +DEFINE_MTYPE_STATIC(PATHD, PCEPLIB_MESSAGES, "PCEPlib PCEP Messages"); #define CLASS_TYPE(CLASS, TYPE) (((CLASS) << 16) | (TYPE)) #define DEFAULT_LSAP_SETUP_PRIO 4 diff --git a/pathd/path_pcep_memory.c b/pathd/path_pcep_memory.c deleted file mode 100644 index 8f608090a6..0000000000 --- a/pathd/path_pcep_memory.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2020 NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include <memory.h> - -#include "pathd/path_pcep_memory.h" - -DEFINE_MTYPE(PATHD, PCEP, "PCEP module") -DEFINE_MTYPE(PATHD, PCEPLIB_INFRA, "PCEPlib Infrastructure") -DEFINE_MTYPE(PATHD, PCEPLIB_MESSAGES, "PCEPlib PCEP Messages") diff --git a/pathd/path_pcep_memory.h b/pathd/path_pcep_memory.h deleted file mode 100644 index 05c5e2d82b..0000000000 --- a/pathd/path_pcep_memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _FRR_PATH_PCEP_MEMORY_H_ -#define _FRR_PATH_PCEP_MEMORY_H_ - -#include "pathd/path_memory.h" - -DECLARE_MTYPE(PCEP) -DECLARE_MTYPE(PCEPLIB_INFRA) -DECLARE_MTYPE(PCEPLIB_MESSAGES) - -#endif /* _FRR_PATH_PCEP_MEMORY_H_ */ diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 899ce805fe..a2c1e7cd4c 100644 --- a/pathd/path_pcep_pcc.c +++ b/pathd/path_pcep_pcc.c @@ -41,7 +41,6 @@ #include "pathd/pathd.h" #include "pathd/path_zebra.h" #include "pathd/path_errors.h" -#include "pathd/path_pcep_memory.h" #include "pathd/path_pcep.h" #include "pathd/path_pcep_controller.h" #include "pathd/path_pcep_lib.h" @@ -147,10 +146,10 @@ static uint32_t req_map_hash(const struct req_map_data *e); /* Data Structure Declarations */ DECLARE_HASH(plspid_map, struct plspid_map_data, mi, plspid_map_cmp, - plspid_map_hash) + plspid_map_hash); DECLARE_HASH(nbkey_map, struct nbkey_map_data, mi, nbkey_map_cmp, - nbkey_map_hash) -DECLARE_HASH(req_map, struct req_map_data, mi, req_map_cmp, req_map_hash) + nbkey_map_hash); +DECLARE_HASH(req_map, struct req_map_data, mi, req_map_cmp, req_map_hash); static inline int req_entry_compare(const struct req_entry *a, const struct req_entry *b) diff --git a/pathd/path_pcep_pcc.h b/pathd/path_pcep_pcc.h index c07a6ae541..ceac6f3278 100644 --- a/pathd/path_pcep_pcc.h +++ b/pathd/path_pcep_pcc.h @@ -30,9 +30,9 @@ enum pcc_status { PCEP_PCC_OPERATING }; -PREDECL_HASH(plspid_map) -PREDECL_HASH(nbkey_map) -PREDECL_HASH(req_map) +PREDECL_HASH(plspid_map); +PREDECL_HASH(nbkey_map); +PREDECL_HASH(req_map); struct plspid_map_data { struct plspid_map_item mi; diff --git a/pathd/pathd.c b/pathd/pathd.c index 14f5167bff..ae82186315 100644 --- a/pathd/pathd.c +++ b/pathd/pathd.c @@ -24,22 +24,23 @@ #include "network.h" #include "pathd/pathd.h" -#include "pathd/path_memory.h" #include "pathd/path_zebra.h" #include "pathd/path_debug.h" #define HOOK_DELAY 3 -DEFINE_MTYPE_STATIC(PATHD, PATH_SEGMENT_LIST, "Segment List") -DEFINE_MTYPE_STATIC(PATHD, PATH_SR_POLICY, "SR Policy") -DEFINE_MTYPE_STATIC(PATHD, PATH_SR_CANDIDATE, "SR Policy candidate path") +DEFINE_MGROUP(PATHD, "pathd"); + +DEFINE_MTYPE_STATIC(PATHD, PATH_SEGMENT_LIST, "Segment List"); +DEFINE_MTYPE_STATIC(PATHD, PATH_SR_POLICY, "SR Policy"); +DEFINE_MTYPE_STATIC(PATHD, PATH_SR_CANDIDATE, "SR Policy candidate path"); DEFINE_HOOK(pathd_candidate_created, (struct srte_candidate * candidate), - (candidate)) + (candidate)); DEFINE_HOOK(pathd_candidate_updated, (struct srte_candidate * candidate), - (candidate)) + (candidate)); DEFINE_HOOK(pathd_candidate_removed, (struct srte_candidate * candidate), - (candidate)) + (candidate)); static void trigger_pathd_candidate_created(struct srte_candidate *candidate); static int trigger_pathd_candidate_created_timer(struct thread *thread); diff --git a/pathd/pathd.h b/pathd/pathd.h index 4879239db8..9c4d256cef 100644 --- a/pathd/pathd.h +++ b/pathd/pathd.h @@ -19,11 +19,14 @@ #ifndef _FRR_PATHD_H_ #define _FRR_PATHD_H_ +#include "lib/memory.h" #include "lib/mpls.h" #include "lib/ipaddr.h" #include "lib/srte.h" #include "lib/hook.h" +DECLARE_MGROUP(PATHD); + enum srte_protocol_origin { SRTE_ORIGIN_UNDEFINED = 0, SRTE_ORIGIN_PCEP = 1, @@ -338,11 +341,11 @@ RB_HEAD(srte_policy_head, srte_policy); RB_PROTOTYPE(srte_policy_head, srte_policy, entry, srte_policy_compare) DECLARE_HOOK(pathd_candidate_created, (struct srte_candidate * candidate), - (candidate)) + (candidate)); DECLARE_HOOK(pathd_candidate_updated, (struct srte_candidate * candidate), - (candidate)) + (candidate)); DECLARE_HOOK(pathd_candidate_removed, (struct srte_candidate * candidate), - (candidate)) + (candidate)); extern struct srte_segment_list_head srte_segment_lists; extern struct srte_policy_head srte_policies; diff --git a/pathd/subdir.am b/pathd/subdir.am index 452d824669..b4501214bf 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -23,7 +23,6 @@ pathd_libpath_a_SOURCES = \ pathd/path_debug.c \ pathd/path_errors.c \ pathd/path_main.c \ - pathd/path_memory.c \ pathd/path_nb.c \ pathd/path_nb_config.c \ pathd/path_nb_state.c \ @@ -39,14 +38,12 @@ clippy_scan += \ noinst_HEADERS += \ pathd/path_debug.h \ pathd/path_errors.h \ - pathd/path_memory.h \ pathd/path_nb.h \ pathd/path_pcep.h \ pathd/path_pcep_cli.h \ pathd/path_pcep_controller.h \ pathd/path_pcep_debug.h \ pathd/path_pcep_lib.h \ - pathd/path_pcep_memory.h \ pathd/path_pcep_config.h \ pathd/path_pcep_pcc.h \ pathd/path_zebra.h \ @@ -65,7 +62,6 @@ pathd_pathd_pcep_la_SOURCES = \ pathd/path_pcep_controller.c \ pathd/path_pcep_debug.c \ pathd/path_pcep_lib.c \ - pathd/path_pcep_memory.c \ pathd/path_pcep_config.c \ pathd/path_pcep_pcc.c \ # end diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c index 01c52f24e5..1badaf95bd 100644 --- a/pbrd/pbr_main.c +++ b/pbrd/pbr_main.c @@ -131,7 +131,8 @@ FRR_DAEMON_INFO(pbrd, PBR, .vty_port = PBR_VTY_PORT, .privs = &pbr_privs, .yang_modules = pbrd_yang_modules, - .n_yang_modules = array_size(pbrd_yang_modules), ) + .n_yang_modules = array_size(pbrd_yang_modules), +); int main(int argc, char **argv, char **envp) { diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c index 5b851988f6..053b7363a3 100644 --- a/pbrd/pbr_map.c +++ b/pbrd/pbr_map.c @@ -37,9 +37,9 @@ #include "pbr_debug.h" #include "pbr_vrf.h" -DEFINE_MTYPE_STATIC(PBRD, PBR_MAP, "PBR Map") -DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_SEQNO, "PBR Map Sequence") -DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_INTERFACE, "PBR Map Interface") +DEFINE_MTYPE_STATIC(PBRD, PBR_MAP, "PBR Map"); +DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_SEQNO, "PBR Map Sequence"); +DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_INTERFACE, "PBR Map Interface"); static uint32_t pbr_map_sequence_unique; @@ -51,7 +51,7 @@ RB_GENERATE(pbr_map_entry_head, pbr_map, pbr_map_entry, pbr_map_compare) struct pbr_map_entry_head pbr_maps = RB_INITIALIZER(&pbr_maps); -DEFINE_QOBJ_TYPE(pbr_map_sequence) +DEFINE_QOBJ_TYPE(pbr_map_sequence); static inline int pbr_map_compare(const struct pbr_map *pbrmap1, const struct pbr_map *pbrmap2) diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h index ad2db146b7..caeadb0644 100644 --- a/pbrd/pbr_map.h +++ b/pbrd/pbr_map.h @@ -149,10 +149,10 @@ struct pbr_map_sequence { #define PBR_MAP_INVALID_VRF (1 << 5) uint64_t reason; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(pbr_map_sequence) +DECLARE_QOBJ_TYPE(pbr_map_sequence); extern struct pbr_map_entry_head pbr_maps; diff --git a/pbrd/pbr_memory.c b/pbrd/pbr_memory.c index febe406ca7..5531d41935 100644 --- a/pbrd/pbr_memory.c +++ b/pbrd/pbr_memory.c @@ -24,4 +24,4 @@ #include "pbrd/pbr_memory.h" -DEFINE_MGROUP(PBRD, "pbrd") +DEFINE_MGROUP(PBRD, "pbrd"); diff --git a/pbrd/pbr_memory.h b/pbrd/pbr_memory.h index a87d519099..eb13d5d9d1 100644 --- a/pbrd/pbr_memory.h +++ b/pbrd/pbr_memory.h @@ -19,6 +19,6 @@ */ #ifndef __PBR_MEMORY_H__ -DECLARE_MGROUP(PBRD) +DECLARE_MGROUP(PBRD); #endif diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index ba9ad97ab8..e127999b0b 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -35,7 +35,7 @@ #include "pbrd/pbr_memory.h" #include "pbrd/pbr_debug.h" -DEFINE_MTYPE_STATIC(PBRD, PBR_NHG, "PBR Nexthop Groups") +DEFINE_MTYPE_STATIC(PBRD, PBR_NHG, "PBR Nexthop Groups"); struct hash *pbr_nhg_hash; static struct hash *pbr_nhrc_hash; diff --git a/pbrd/pbr_vrf.c b/pbrd/pbr_vrf.c index 3284607406..1b69e23ce3 100644 --- a/pbrd/pbr_vrf.c +++ b/pbrd/pbr_vrf.c @@ -28,7 +28,7 @@ #include "pbr_nht.h" #include "pbr_zebra.h" -DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF") +DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF"); static struct pbr_vrf *pbr_vrf_alloc(void) { diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index 467bbc8f72..4b73e13c27 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -41,7 +41,7 @@ #include "pbr_debug.h" #include "pbr_vrf.h" -DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface") +DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface"); /* Zebra structure to hold current status. */ struct zclient *zclient; diff --git a/pceplib/pcep_msg_messages_encoding.c b/pceplib/pcep_msg_messages_encoding.c index 23ccef480c..7c8e1b3a1f 100644 --- a/pceplib/pcep_msg_messages_encoding.c +++ b/pceplib/pcep_msg_messages_encoding.c @@ -129,7 +129,7 @@ void pcep_encode_message(struct pcep_message *message, message_length += pcep_encode_object(node->data, versioning, message_buffer + message_length); - if (message_length > PCEP_MESSAGE_LENGTH) { + if (message_length >= PCEP_MESSAGE_LENGTH) { message->encoded_message = NULL; message->encoded_message_length = 0; return; @@ -295,6 +295,14 @@ struct pcep_message *pcep_decode_message(const uint8_t *msg_buf) msg_length = pcep_decode_msg_header(msg_buf, &msg_version, &msg_flags, &msg_type); + if (msg_length == 0) { + pcep_log(LOG_INFO, "%s: Discarding empty message", __func__); + return NULL; + } + if (msg_length >= PCEP_MESSAGE_LENGTH) { + pcep_log(LOG_INFO, "%s: Discarding message too big", __func__); + return NULL; + } struct pcep_message *msg = pceplib_calloc(PCEPLIB_MESSAGES, sizeof(struct pcep_message)); diff --git a/pceplib/pcep_msg_objects_encoding.c b/pceplib/pcep_msg_objects_encoding.c index d40b840869..c4089ba5ec 100644 --- a/pceplib/pcep_msg_objects_encoding.c +++ b/pceplib/pcep_msg_objects_encoding.c @@ -1668,7 +1668,7 @@ struct pcep_object_header *pcep_decode_obj_ro(struct pcep_object_header *hdr, ipv6 = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(struct in6_addr)); - decode_ipv6(uint32_ptr + LENGTH_4WORDS, ipv6); + decode_ipv6(uint32_ptr + 4, ipv6); dll_append(sr_subobj->nai_list, ipv6); read_count += LENGTH_8WORDS; @@ -1684,17 +1684,17 @@ struct pcep_object_header *pcep_decode_obj_ro(struct pcep_object_header *hdr, struct in_addr *ipv4 = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(struct in_addr)); - ipv4->s_addr = uint32_ptr[LENGTH_4WORDS]; + ipv4->s_addr = uint32_ptr[4]; dll_append(sr_subobj->nai_list, ipv4); ipv6 = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(struct in6_addr)); - decode_ipv6(uint32_ptr + LENGTH_5WORDS, ipv6); + decode_ipv6(uint32_ptr + 5, ipv6); dll_append(sr_subobj->nai_list, ipv6); ipv4 = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(struct in_addr)); - ipv4->s_addr = uint32_ptr[LENGTH_9WORDS]; + ipv4->s_addr = uint32_ptr[9]; dll_append(sr_subobj->nai_list, ipv4); read_count += LENGTH_10WORDS; diff --git a/pceplib/pcep_msg_tlvs.c b/pceplib/pcep_msg_tlvs.c index 890da9517f..9c84e71ee1 100644 --- a/pceplib/pcep_msg_tlvs.c +++ b/pceplib/pcep_msg_tlvs.c @@ -401,7 +401,7 @@ pcep_tlv_create_srpag_pol_name(const char *pol_name, uint16_t pol_name_length) (normalize_pcep_tlv_length(pol_name_length) > MAX_POLICY_NAME) ? MAX_POLICY_NAME : pol_name_length; - memcpy(tlv->name, pol_name, pol_name_length); + memcpy(tlv->name, pol_name, length); tlv->name_length = length; return tlv; @@ -456,7 +456,7 @@ pcep_tlv_create_tlv_arbitrary(const char *data, uint16_t data_length, uint16_t length = (data_length > MAX_ARBITRARY_SIZE) ? MAX_ARBITRARY_SIZE : data_length; - memcpy(tlv->data, data, data_length); + memcpy(tlv->data, data, length); tlv->data_length = length; tlv->arbitraty_type = tlv_id; diff --git a/pceplib/pcep_msg_tlvs_encoding.c b/pceplib/pcep_msg_tlvs_encoding.c index 3322663dc3..967f138143 100644 --- a/pceplib/pcep_msg_tlvs_encoding.c +++ b/pceplib/pcep_msg_tlvs_encoding.c @@ -1135,7 +1135,7 @@ struct pcep_object_tlv_header *pcep_decode_tlv_path_setup_type_capability( uint16_t buf_index = normalize_pcep_tlv_length( TLV_HEADER_LENGTH + LENGTH_1WORD + num_psts); while ((tlv->header.encoded_tlv_length - buf_index) > TLV_HEADER_LENGTH - && num_iterations++ > MAX_ITERATIONS) { + && num_iterations++ < MAX_ITERATIONS) { struct pcep_object_tlv_header *sub_tlv = pcep_decode_tlv(tlv_body_buf + buf_index); if (sub_tlv == NULL) { diff --git a/pceplib/pcep_msg_tools.c b/pceplib/pcep_msg_tools.c index 1d157ec3f5..e190d2a850 100644 --- a/pceplib/pcep_msg_tools.c +++ b/pceplib/pcep_msg_tools.c @@ -93,11 +93,11 @@ static const char *object_class_strs[] = {"NOT_IMPLEMENTED0", double_linked_list *pcep_msg_read(int sock_fd) { int ret; - uint8_t buffer[PCEP_MAX_SIZE] = {0}; + uint8_t buffer[PCEP_MESSAGE_LENGTH] = {0}; uint16_t buffer_read = 0; - ret = read(sock_fd, &buffer, PCEP_MAX_SIZE); + ret = read(sock_fd, &buffer, PCEP_MESSAGE_LENGTH); if (ret < 0) { pcep_log( @@ -114,13 +114,13 @@ double_linked_list *pcep_msg_read(int sock_fd) double_linked_list *msg_list = dll_initialize(); struct pcep_message *msg = NULL; - while ((ret - buffer_read) >= MESSAGE_HEADER_LENGTH) { + while (((uint16_t)ret - buffer_read) >= MESSAGE_HEADER_LENGTH) { /* Get the Message header, validate it, and return the msg * length */ - int32_t msg_hdr_length = + int32_t msg_length = pcep_decode_validate_msg_header(buffer + buffer_read); - if (msg_hdr_length < 0) { + if (msg_length < 0 || msg_length > PCEP_MESSAGE_LENGTH) { /* If the message header is invalid, we cant keep * reading since the length may be invalid */ pcep_log( @@ -130,17 +130,26 @@ double_linked_list *pcep_msg_read(int sock_fd) return msg_list; } - /* Check if the msg_hdr_length is longer than what was read, + /* Check if the msg_length is longer than what was read, * in which case, we need to read the rest of the message. */ - if ((ret - buffer_read) < msg_hdr_length) { - int read_len = (msg_hdr_length - (ret - buffer_read)); + if ((ret - buffer_read) < msg_length) { + int read_len = (msg_length - (ret - buffer_read)); int read_ret = 0; pcep_log( LOG_INFO, "%s: pcep_msg_read: Message not fully read! Trying to read %d bytes more, fd [%d]", __func__, read_len, sock_fd); - read_ret = read(sock_fd, &buffer[ret], read_len); + if (PCEP_MESSAGE_LENGTH - ret - buffer_read >= read_len ) + read_ret = + read(sock_fd, &buffer[ret], read_len); + else { + pcep_log( + LOG_ERR, + "%s: Trying to read size (%d) offset (%d) in a buff of size (%d)", + __func__, read_len, ret, PCEP_MESSAGE_LENGTH); + return msg_list; + } if (read_ret != read_len) { pcep_log( @@ -152,7 +161,7 @@ double_linked_list *pcep_msg_read(int sock_fd) } msg = pcep_decode_message(buffer + buffer_read); - buffer_read += msg_hdr_length; + buffer_read += msg_length; if (msg == NULL) { return msg_list; @@ -459,7 +468,12 @@ int pcep_msg_send(int sock_fd, struct pcep_message *msg) if (msg == NULL) { return 0; } + int msg_length = ntohs(msg->encoded_message_length); + if (msg_length > PCEP_MESSAGE_LENGTH) { + pcep_log(LOG_ERR, "%s: Not sended, size(% d) exceed max(% d) ", + __func__, msg_length, PCEP_MESSAGE_LENGTH); + return 0; + } - return write(sock_fd, msg->encoded_message, - ntohs(msg->encoded_message_length)); + return write(sock_fd, msg->encoded_message, msg_length); } diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c index 2171f883cd..1a702a8b63 100644 --- a/pceplib/pcep_pcc.c +++ b/pceplib/pcep_pcc.c @@ -273,6 +273,7 @@ void send_pce_report_message(pcep_session *session) pcep_log(LOG_WARNING, "%s: send_pce_report_message SRP object was NULL", __func__); + dll_destroy_with_data(report_list); return; } dll_append(report_list, obj); @@ -313,6 +314,7 @@ void send_pce_report_message(pcep_session *session) pcep_log(LOG_WARNING, "%s: send_pce_report_message LSP object was NULL", __func__); + dll_destroy_with_data(report_list); return; } dll_append(report_list, obj); @@ -349,6 +351,7 @@ void send_pce_report_message(pcep_session *session) pcep_log(LOG_WARNING, "%s: send_pce_report_message ERO object was NULL", __func__); + dll_destroy_with_data(report_list); return; } dll_append(report_list, obj); diff --git a/pceplib/pcep_session_logic.c b/pceplib/pcep_session_logic.c index 5e4dae4900..52655914c6 100644 --- a/pceplib/pcep_session_logic.c +++ b/pceplib/pcep_session_logic.c @@ -61,7 +61,6 @@ static bool run_session_logic_common() memset(session_logic_handle_, 0, sizeof(pcep_session_logic_handle)); session_logic_handle_->active = true; - session_logic_handle_->session_logic_condition = false; session_logic_handle_->session_list = ordered_list_initialize(pointer_compare_function); session_logic_handle_->session_event_queue = queue_initialize(); @@ -91,6 +90,11 @@ static bool run_session_logic_common() return false; } + pthread_mutex_lock(&(session_logic_handle_->session_logic_mutex)); + session_logic_handle_->session_logic_condition = true; + pthread_cond_signal(&(session_logic_handle_->session_logic_cond_var)); + pthread_mutex_unlock(&(session_logic_handle_->session_logic_mutex)); + if (pthread_mutex_init(&(session_logic_handle_->session_list_mutex), NULL) != 0) { @@ -574,24 +578,20 @@ struct pcep_message *create_pcep_open(pcep_session *session) dll_append( tlv_list, pcep_tlv_create_stateful_pce_capability( + /* U flag */ session->pcc_config - .support_stateful_pce_lsp_update, /* U - flag - */ - session->pcc_config - .support_include_db_version, /* S flag - */ - session->pcc_config - .support_lsp_triggered_resync, /* T flag - */ - session->pcc_config - .support_lsp_delta_sync, /* D flag */ - session->pcc_config - .support_pce_triggered_initial_sync, /* F flag */ + .support_stateful_pce_lsp_update, + /* S flag */ + session->pcc_config.support_include_db_version, + /* I flag */ session->pcc_config - .support_pce_lsp_instantiation)); /* I - flag - */ + .support_pce_lsp_instantiation, + /* T flag */ + session->pcc_config.support_lsp_triggered_resync, + /* D flag */ + session->pcc_config.support_lsp_delta_sync, + /* F flag */ + session->pcc_config.support_pce_triggered_initial_sync)); } if (session->pcc_config.support_include_db_version) { diff --git a/pceplib/pcep_session_logic_loop.c b/pceplib/pcep_session_logic_loop.c index 5705ff2000..269aa1e07e 100644 --- a/pceplib/pcep_session_logic_loop.c +++ b/pceplib/pcep_session_logic_loop.c @@ -98,6 +98,7 @@ int session_logic_msg_ready_handler(void *data, int socket_fd) } else if (msg_list->num_entries == 0) { /* Invalid message received */ increment_unknown_message(session); + dll_destroy_with_data(msg_list); } else { /* Just logging the first of potentially several messages * received */ diff --git a/pceplib/pcep_session_logic_states.c b/pceplib/pcep_session_logic_states.c index e2c3c29591..3beceefad0 100644 --- a/pceplib/pcep_session_logic_states.c +++ b/pceplib/pcep_session_logic_states.c @@ -24,6 +24,7 @@ #include <stdbool.h> #include <stdio.h> #include <string.h> +#include <assert.h> #include "pcep_msg_encoding.h" #include "pcep_session_logic.h" @@ -461,6 +462,8 @@ void send_reconciled_pcep_open(pcep_session *session, struct pcep_object_open *open_obj = (struct pcep_object_open *)pcep_obj_get(open_msg->obj_list, PCEP_OBJ_CLASS_OPEN); + // open_msg can not have empty obj_list + assert(open_obj != NULL); if (error_open_obj->open_deadtimer != session->pce_config.dead_timer_seconds) { diff --git a/pceplib/pcep_socket_comm_loop.c b/pceplib/pcep_socket_comm_loop.c index 8346c93025..d58409c4f3 100644 --- a/pceplib/pcep_socket_comm_loop.c +++ b/pceplib/pcep_socket_comm_loop.c @@ -26,6 +26,7 @@ #include <stddef.h> #include <string.h> #include <unistd.h> +#include <assert.h> #include "pcep_socket_comm_internals.h" #include "pcep_socket_comm_loop.h" @@ -129,6 +130,9 @@ int build_fd_sets(pcep_socket_comm_handle *socket_comm_handle) comm_session = (pcep_socket_comm_session *)node->data; if (comm_session->socket_fd > max_fd) { max_fd = comm_session->socket_fd; + } else if (comm_session->socket_fd < 0) { + pcep_log(LOG_ERR, "%s: Negative fd", __func__); + assert(comm_session->socket_fd > 0); } /*pcep_log(LOG_DEBUG, ld] socket_comm::build_fdSets set @@ -147,6 +151,9 @@ int build_fd_sets(pcep_socket_comm_handle *socket_comm_handle) comm_session = (pcep_socket_comm_session *)node->data; if (comm_session->socket_fd > max_fd) { max_fd = comm_session->socket_fd; + } else if (comm_session->socket_fd < 0) { + pcep_log(LOG_ERR, "%s: Negative fd", __func__); + assert(comm_session->socket_fd > 0); } /*pcep_log(LOG_DEBUG, "%s: [%ld] socket_comm::build_fdSets set diff --git a/pceplib/test/pcep_msg_messages_test.c b/pceplib/test/pcep_msg_messages_test.c index 10b678bcec..b8984a42bc 100644 --- a/pceplib/test/pcep_msg_messages_test.c +++ b/pceplib/test/pcep_msg_messages_test.c @@ -111,7 +111,7 @@ void test_pcep_msg_create_request() /* Test IPv4 */ struct pcep_object_rp *rp_obj = pcep_obj_create_rp(0, false, false, false, false, 10, NULL); - struct in_addr src_addr, dst_addr; + struct in_addr src_addr={}, dst_addr={}; struct pcep_object_endpoints_ipv4 *ipv4_obj = pcep_obj_create_endpoint_ipv4(&src_addr, &dst_addr); message = pcep_msg_create_request(rp_obj, ipv4_obj, NULL); @@ -375,6 +375,10 @@ void test_pcep_msg_create_update() /* Should return NULL if obj_list is empty */ message = pcep_msg_create_update(obj_list); CU_ASSERT_PTR_NULL(message); + if (message != NULL) { + pcep_msg_free_message(message); + message = NULL; + } struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL); struct pcep_object_lsp *lsp = @@ -390,6 +394,10 @@ void test_pcep_msg_create_update() CU_ASSERT_PTR_NULL(message); dll_append(obj_list, ero); + if (message != NULL) { + pcep_msg_free_message(message); + message = NULL; + } message = pcep_msg_create_update(obj_list); CU_ASSERT_PTR_NOT_NULL(message); pcep_encode_message(message, versioning); @@ -416,6 +424,10 @@ void test_pcep_msg_create_initiate() /* Should return NULL if obj_list is empty */ struct pcep_message *message = pcep_msg_create_initiate(NULL); CU_ASSERT_PTR_NULL(message); + if (message != NULL) { + pcep_msg_free_message(message); + message = NULL; + } struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL); struct pcep_object_lsp *lsp = @@ -428,6 +440,10 @@ void test_pcep_msg_create_initiate() dll_append(obj_list, srp); message = pcep_msg_create_initiate(obj_list); CU_ASSERT_PTR_NULL(message); + if (message != NULL) { + pcep_msg_free_message(message); + message = NULL; + } dll_append(obj_list, lsp); dll_append(obj_list, ero); diff --git a/pceplib/test/pcep_msg_tlvs_test.c b/pceplib/test/pcep_msg_tlvs_test.c index 878e4d62af..6b650f6823 100644 --- a/pceplib/test/pcep_msg_tlvs_test.c +++ b/pceplib/test/pcep_msg_tlvs_test.c @@ -106,6 +106,10 @@ void test_pcep_tlv_create_speaker_entity_id() double_linked_list *list = dll_initialize(); tlv = pcep_tlv_create_speaker_entity_id(list); CU_ASSERT_PTR_NULL(tlv); + if (tlv != NULL) { + pceplib_free(PCEPLIB_INFRA, tlv); + tlv = NULL; + } uint32_t *speaker_entity = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint32_t)); @@ -172,16 +176,28 @@ void test_pcep_tlv_create_path_setup_type_capability() double_linked_list *pst_list = dll_initialize(); tlv = pcep_tlv_create_path_setup_type_capability(pst_list, NULL); CU_ASSERT_PTR_NULL(tlv); + if (tlv != NULL) { + pcep_obj_free_tlv(&tlv->header); + tlv = NULL; + } /* Should still return NULL if pst_list is NULL */ double_linked_list *sub_tlv_list = dll_initialize(); tlv = pcep_tlv_create_path_setup_type_capability(NULL, sub_tlv_list); CU_ASSERT_PTR_NULL(tlv); + if (tlv != NULL) { + pcep_obj_free_tlv(&tlv->header); + tlv = NULL; + } /* Should still return NULL if pst_list is empty */ tlv = pcep_tlv_create_path_setup_type_capability(pst_list, sub_tlv_list); CU_ASSERT_PTR_NULL(tlv); + if (tlv != NULL) { + pcep_obj_free_tlv(&tlv->header); + tlv = NULL; + } /* Test only populating the pst list */ uint8_t *pst1 = pceplib_malloc(PCEPLIB_MESSAGES, 1); @@ -196,6 +212,10 @@ void test_pcep_tlv_create_path_setup_type_capability() tlv = pcep_tlv_create_path_setup_type_capability(pst_list, sub_tlv_list); CU_ASSERT_PTR_NOT_NULL(tlv); + if (tlv == NULL) { + CU_ASSERT_TRUE(tlv != NULL); + return; + } pcep_encode_tlv(&tlv->header, versioning, tlv_buf); CU_ASSERT_EQUAL(tlv->header.type, diff --git a/pceplib/test/pcep_msg_tools_test.c b/pceplib/test/pcep_msg_tools_test.c index a1260b1186..ff5fc62390 100644 --- a/pceplib/test/pcep_msg_tools_test.c +++ b/pceplib/test/pcep_msg_tools_test.c @@ -24,6 +24,9 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + #include <CUnit/CUnit.h> @@ -164,7 +167,15 @@ void pcep_tools_test_teardown(void) int convert_hexstrs_to_binary(const char *hexbyte_strs[], uint16_t hexbyte_strs_length) { - int fd = fileno(tmpfile()); + mode_t oldumask; + oldumask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); + /* Set umask before anything for security */ + umask(0027); + char tmpfile[] = "/tmp/pceplib_XXXXXX"; + int fd = mkstemp(tmpfile); + umask(oldumask); + if (fd == -1) + return -1; int i = 0; for (; i < hexbyte_strs_length; i++) { @@ -192,6 +203,10 @@ void test_pcep_msg_read_pcep_initiate() { int fd = convert_hexstrs_to_binary(pcep_initiate_hexbyte_strs, pcep_initiate_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -287,6 +302,10 @@ void test_pcep_msg_read_pcep_initiate2() { int fd = convert_hexstrs_to_binary(pcep_initiate2_hexbyte_strs, pcep_initiate2_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -370,6 +389,10 @@ void test_pcep_msg_read_pcep_open() { int fd = convert_hexstrs_to_binary(pcep_open_odl_hexbyte_strs, pcep_open_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -410,6 +433,10 @@ void test_pcep_msg_read_pcep_update() { int fd = convert_hexstrs_to_binary(pcep_update_hexbyte_strs, pcep_update_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -488,6 +515,10 @@ void test_pcep_msg_read_pcep_open_initiate() int fd = convert_hexstrs_to_binary( pcep_open_initiate_odl_hexbyte_strs, pcep_open_initiate_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 2); @@ -513,6 +544,10 @@ void test_pcep_msg_read_pcep_open_cisco_pce() int fd = convert_hexstrs_to_binary( pcep_open_cisco_pce_hexbyte_strs, pcep_open_cisco_pce_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -571,6 +606,10 @@ void test_pcep_msg_read_pcep_update_cisco_pce() int fd = convert_hexstrs_to_binary( pcep_update_cisco_pce_hexbyte_strs, pcep_update_cisco_pce_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -708,6 +747,10 @@ void test_pcep_msg_read_pcep_report_cisco_pcc() int fd = convert_hexstrs_to_binary( pcep_report_cisco_pcc_hexbyte_strs, pcep_report_cisco_pcc_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); @@ -863,6 +906,10 @@ void test_pcep_msg_read_pcep_initiate_cisco_pcc() int fd = convert_hexstrs_to_binary( pcep_initiate_cisco_pcc_hexbyte_strs, pcep_initiate_cisco_pcc_hexbyte_strs_length); + if(fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } double_linked_list *msg_list = pcep_msg_read(fd); CU_ASSERT_PTR_NOT_NULL(msg_list); CU_ASSERT_EQUAL(msg_list->num_entries, 1); diff --git a/pceplib/test/pcep_session_logic_loop_test.c b/pceplib/test/pcep_session_logic_loop_test.c index 38fabd4ccd..3a40f59bb9 100644 --- a/pceplib/test/pcep_session_logic_loop_test.c +++ b/pceplib/test/pcep_session_logic_loop_test.c @@ -25,6 +25,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> #include <CUnit/CUnit.h> @@ -70,7 +72,6 @@ void pcep_session_logic_loop_test_setup() PCEPLIB_INFRA, sizeof(pcep_session_logic_handle)); memset(session_logic_handle_, 0, sizeof(pcep_session_logic_handle)); session_logic_handle_->active = true; - session_logic_handle_->session_logic_condition = false; session_logic_handle_->session_list = ordered_list_initialize(pointer_compare_function); session_logic_handle_->session_event_queue = queue_initialize(); @@ -79,6 +80,11 @@ void pcep_session_logic_loop_test_setup() pthread_mutex_init(&(session_logic_handle_->session_logic_mutex), NULL); pthread_mutex_init(&(session_logic_handle_->session_list_mutex), NULL); + pthread_mutex_lock(&(session_logic_handle_->session_logic_mutex)); + session_logic_handle_->session_logic_condition = true; + pthread_cond_signal(&(session_logic_handle_->session_logic_cond_var)); + pthread_mutex_unlock(&(session_logic_handle_->session_logic_mutex)); + session_logic_event_queue_ = pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_event_queue)); memset(session_logic_event_queue_, 0, sizeof(pcep_event_queue)); @@ -128,7 +134,17 @@ void test_session_logic_msg_ready_handler() /* Read from an empty file should return 0, thus * session_logic_msg_ready_handler returns -1 */ - int fd = fileno(tmpfile()); + mode_t oldumask; + oldumask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); + /* Set umask before anything for security */ + umask(0027); + char tmpfile[] = "/tmp/pceplib_XXXXXX"; + int fd = mkstemp(tmpfile); + umask(oldumask); + if (fd == -1){ + CU_ASSERT_TRUE(fd>=0); + return; + } pcep_session session; memset(&session, 0, sizeof(pcep_session)); session.session_id = 100; diff --git a/pceplib/test/pcep_timers_event_loop_test.c b/pceplib/test/pcep_timers_event_loop_test.c index 9fcacaf0f2..ae63601df2 100644 --- a/pceplib/test/pcep_timers_event_loop_test.c +++ b/pceplib/test/pcep_timers_event_loop_test.c @@ -130,7 +130,9 @@ void test_walk_and_process_timers_timer_expired() timer->data = timer; // Set the timer to expire 10 seconds ago timer->expire_time = time(NULL) - 10; + pthread_mutex_lock(&test_timers_context->timer_list_lock); timer->timer_id = TEST_EVENT_LOOP_TIMER_ID; + pthread_mutex_unlock(&test_timers_context->timer_list_lock); ordered_list_add_node(test_timers_context->timer_list, timer); walk_and_process_timers(test_timers_context); diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index e873af5759..f43a31fde2 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -42,10 +42,10 @@ static inline void pim_g2rp_timer_restart(struct bsm_rpinfo *bsrp, int hold_time); /* Memory Types */ -DEFINE_MTYPE_STATIC(PIMD, PIM_BSGRP_NODE, "PIM BSR advertised grp info") -DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_NODE, "PIM BSR advertised RP info") -DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_INFO, "PIM BSM Info") -DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_PKT_VAR_MEM, "PIM BSM Packet") +DEFINE_MTYPE_STATIC(PIMD, PIM_BSGRP_NODE, "PIM BSR advertised grp info"); +DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_NODE, "PIM BSR advertised RP info"); +DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_INFO, "PIM BSM Info"); +DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_PKT_VAR_MEM, "PIM BSM Packet"); /* All bsm packets forwarded shall be fit within ip mtu less iphdr(max) */ #define MAX_IP_HDR_LEN 24 diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index ae5b7940e9..4bbe7d35f0 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1094,6 +1094,8 @@ static void pim_show_interfaces_single(struct pim_instance *pim, json_object_int_add(json_row, "helloPeriod", pim_ifp->pim_hello_period); + json_object_int_add(json_row, "holdTime", + PIM_IF_DEFAULT_HOLDTIME(pim_ifp)); json_object_string_add(json_row, "helloTimer", hello_timer); json_object_string_add(json_row, "helloStatStart", @@ -1243,6 +1245,8 @@ static void pim_show_interfaces_single(struct pim_instance *pim, vty_out(vty, "------\n"); vty_out(vty, "Period : %d\n", pim_ifp->pim_hello_period); + vty_out(vty, "HoldTime : %d\n", + PIM_IF_DEFAULT_HOLDTIME(pim_ifp)); vty_out(vty, "Timer : %s\n", hello_timer); vty_out(vty, "StatStart : %s\n", stat_uptime); vty_out(vty, "Receive : %d\n", @@ -8987,7 +8991,7 @@ DEFUN (interface_ip_pim_hello, DEFUN (interface_no_ip_pim_hello, interface_no_ip_pim_hello_cmd, - "no ip pim hello [(1-180) (1-180)]", + "no ip pim hello [(1-180) [(1-180)]]", NO_STR IP_STR PIM_STR diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 5a09e7a8ee..70c233848a 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -92,7 +92,8 @@ FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT, .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/, .privs = &pimd_privs, .yang_modules = pimd_yang_modules, - .n_yang_modules = array_size(pimd_yang_modules), ) + .n_yang_modules = array_size(pimd_yang_modules), +); int main(int argc, char **argv, char **envp) diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c index 6bc8062c4b..1d811d9001 100644 --- a/pimd/pim_memory.c +++ b/pimd/pim_memory.c @@ -25,31 +25,31 @@ #include "pim_memory.h" -DEFINE_MGROUP(PIMD, "pimd") -DEFINE_MTYPE(PIMD, PIM_CHANNEL_OIL, "PIM SSM (S,G) channel OIL") -DEFINE_MTYPE(PIMD, PIM_INTERFACE, "PIM interface") -DEFINE_MTYPE(PIMD, PIM_IGMP_JOIN, "PIM interface IGMP static join") -DEFINE_MTYPE(PIMD, PIM_IGMP_SOCKET, "PIM interface IGMP socket") -DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP, "PIM interface IGMP group") -DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP_SOURCE, "PIM interface IGMP source") -DEFINE_MTYPE(PIMD, PIM_NEIGHBOR, "PIM interface neighbor") -DEFINE_MTYPE(PIMD, PIM_IFCHANNEL, "PIM interface (S,G) state") -DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state") -DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket") -DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route") -DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info") -DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info") -DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info") -DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer") -DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name") -DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache") -DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group") -DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr") -DEFINE_MTYPE(PIMD, PIM_SEC_ADDR, "PIM secondary address") -DEFINE_MTYPE(PIMD, PIM_JP_AGG_GROUP, "PIM JP AGG Group") -DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE, "PIM JP AGG Source") -DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE, "PIM global state") -DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE, "PIM nexthop cache state") -DEFINE_MTYPE(PIMD, PIM_SSM_INFO, "PIM SSM configuration") -DEFINE_MTYPE(PIMD, PIM_PLIST_NAME, "PIM Prefix List Names") -DEFINE_MTYPE(PIMD, PIM_VXLAN_SG, "PIM VxLAN mroute cache") +DEFINE_MGROUP(PIMD, "pimd"); +DEFINE_MTYPE(PIMD, PIM_CHANNEL_OIL, "PIM SSM (S,G) channel OIL"); +DEFINE_MTYPE(PIMD, PIM_INTERFACE, "PIM interface"); +DEFINE_MTYPE(PIMD, PIM_IGMP_JOIN, "PIM interface IGMP static join"); +DEFINE_MTYPE(PIMD, PIM_IGMP_SOCKET, "PIM interface IGMP socket"); +DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP, "PIM interface IGMP group"); +DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP_SOURCE, "PIM interface IGMP source"); +DEFINE_MTYPE(PIMD, PIM_NEIGHBOR, "PIM interface neighbor"); +DEFINE_MTYPE(PIMD, PIM_IFCHANNEL, "PIM interface (S,G) state"); +DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state"); +DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket"); +DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route"); +DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info"); +DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info"); +DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info"); +DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer"); +DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name"); +DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache"); +DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group"); +DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr"); +DEFINE_MTYPE(PIMD, PIM_SEC_ADDR, "PIM secondary address"); +DEFINE_MTYPE(PIMD, PIM_JP_AGG_GROUP, "PIM JP AGG Group"); +DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE, "PIM JP AGG Source"); +DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE, "PIM global state"); +DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE, "PIM nexthop cache state"); +DEFINE_MTYPE(PIMD, PIM_SSM_INFO, "PIM SSM configuration"); +DEFINE_MTYPE(PIMD, PIM_PLIST_NAME, "PIM Prefix List Names"); +DEFINE_MTYPE(PIMD, PIM_VXLAN_SG, "PIM VxLAN mroute cache"); diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h index 6beeb60075..4e5fcde7dd 100644 --- a/pimd/pim_memory.h +++ b/pimd/pim_memory.h @@ -24,33 +24,33 @@ #include "memory.h" -DECLARE_MGROUP(PIMD) -DECLARE_MTYPE(PIM_CHANNEL_OIL) -DECLARE_MTYPE(PIM_INTERFACE) -DECLARE_MTYPE(PIM_IGMP_JOIN) -DECLARE_MTYPE(PIM_IGMP_SOCKET) -DECLARE_MTYPE(PIM_IGMP_GROUP) -DECLARE_MTYPE(PIM_IGMP_GROUP_SOURCE) -DECLARE_MTYPE(PIM_NEIGHBOR) -DECLARE_MTYPE(PIM_IFCHANNEL) -DECLARE_MTYPE(PIM_UPSTREAM) -DECLARE_MTYPE(PIM_SSMPINGD) -DECLARE_MTYPE(PIM_STATIC_ROUTE) -DECLARE_MTYPE(PIM_BR) -DECLARE_MTYPE(PIM_RP) -DECLARE_MTYPE(PIM_FILTER_NAME) -DECLARE_MTYPE(PIM_MSDP_PEER) -DECLARE_MTYPE(PIM_MSDP_MG_NAME) -DECLARE_MTYPE(PIM_MSDP_SA) -DECLARE_MTYPE(PIM_MSDP_MG) -DECLARE_MTYPE(PIM_MSDP_MG_MBR) -DECLARE_MTYPE(PIM_SEC_ADDR) -DECLARE_MTYPE(PIM_JP_AGG_GROUP) -DECLARE_MTYPE(PIM_JP_AGG_SOURCE) -DECLARE_MTYPE(PIM_PIM_INSTANCE) -DECLARE_MTYPE(PIM_NEXTHOP_CACHE) -DECLARE_MTYPE(PIM_SSM_INFO) +DECLARE_MGROUP(PIMD); +DECLARE_MTYPE(PIM_CHANNEL_OIL); +DECLARE_MTYPE(PIM_INTERFACE); +DECLARE_MTYPE(PIM_IGMP_JOIN); +DECLARE_MTYPE(PIM_IGMP_SOCKET); +DECLARE_MTYPE(PIM_IGMP_GROUP); +DECLARE_MTYPE(PIM_IGMP_GROUP_SOURCE); +DECLARE_MTYPE(PIM_NEIGHBOR); +DECLARE_MTYPE(PIM_IFCHANNEL); +DECLARE_MTYPE(PIM_UPSTREAM); +DECLARE_MTYPE(PIM_SSMPINGD); +DECLARE_MTYPE(PIM_STATIC_ROUTE); +DECLARE_MTYPE(PIM_BR); +DECLARE_MTYPE(PIM_RP); +DECLARE_MTYPE(PIM_FILTER_NAME); +DECLARE_MTYPE(PIM_MSDP_PEER); +DECLARE_MTYPE(PIM_MSDP_MG_NAME); +DECLARE_MTYPE(PIM_MSDP_SA); +DECLARE_MTYPE(PIM_MSDP_MG); +DECLARE_MTYPE(PIM_MSDP_MG_MBR); +DECLARE_MTYPE(PIM_SEC_ADDR); +DECLARE_MTYPE(PIM_JP_AGG_GROUP); +DECLARE_MTYPE(PIM_JP_AGG_SOURCE); +DECLARE_MTYPE(PIM_PIM_INSTANCE); +DECLARE_MTYPE(PIM_NEXTHOP_CACHE); +DECLARE_MTYPE(PIM_SSM_INFO); DECLARE_MTYPE(PIM_PLIST_NAME); -DECLARE_MTYPE(PIM_VXLAN_SG) +DECLARE_MTYPE(PIM_VXLAN_SG); #endif /* _QUAGGA_PIM_MEMORY_H */ diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index b613937f59..9c3cdb2711 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -35,6 +35,8 @@ #include "pim_msdp.h" #include "pim_msdp_socket.h" +#include "sockopt.h" + /* increase socket send buffer size */ static void pim_msdp_update_sock_send_buffer_size(int fd) { @@ -194,6 +196,12 @@ int pim_msdp_sock_listen(struct pim_instance *pim) return rc; } + /* Set socket DSCP byte */ + if (setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL)) { + zlog_warn("can't set sockopt IP_TOS to MSDP socket %d: %s", + sock, safe_strerror(errno)); + } + /* add accept thread */ listener->fd = sock; memcpy(&listener->su, &sin, socklen); @@ -272,6 +280,12 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) return rc; } + /* Set socket DSCP byte */ + if (setsockopt_ipv4_tos(mp->fd, IPTOS_PREC_INTERNETCONTROL)) { + zlog_warn("can't set sockopt IP_TOS to MSDP socket %d: %s", + mp->fd, safe_strerror(errno)); + } + /* Connect to the remote mp. */ return (sockunion_connect(mp->fd, &mp->su_peer, htons(PIM_MSDP_TCP_PORT), 0)); diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index a7d7551cbd..475e393cf0 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1830,6 +1830,7 @@ int lib_interface_pim_hello_interval_modify(struct nb_cb_modify_args *args) pim_ifp = ifp->info; pim_ifp->pim_hello_period = yang_dnode_get_uint8(args->dnode, NULL); + pim_ifp->pim_default_holdtime = -1; break; } @@ -2394,13 +2395,6 @@ int lib_interface_pim_address_family_mroute_oif_modify( struct ipaddr group_addr; const struct lyd_node *if_dnode; - iif = nb_running_get_entry(args->dnode, NULL, true); - pim_iifp = iif->info; - pim = pim_iifp->pim; - - oifname = yang_dnode_get_string(args->dnode, NULL); - oif = if_lookup_by_name(oifname, pim->vrf_id); - switch (args->event) { case NB_EV_VALIDATE: if_dnode = yang_dnode_get_parent(args->dnode, "interface"); @@ -2411,6 +2405,17 @@ int lib_interface_pim_address_family_mroute_oif_modify( } #ifdef PIM_ENFORCE_LOOPFREE_MFC + iif = nb_running_get_entry(args->dnode, NULL, false); + if (!iif) { + return NB_OK; + } + + pim_iifp = iif->info; + pim = pim_iifp->pim; + + oifname = yang_dnode_get_string(args->dnode, NULL); + oif = if_lookup_by_name(oifname, pim->vrf_id); + if (oif && (iif->ifindex == oif->ifindex)) { strlcpy(args->errmsg, "% IIF same as OIF and loopfree enforcement is enabled; rejecting", @@ -2423,6 +2428,12 @@ int lib_interface_pim_address_family_mroute_oif_modify( case NB_EV_ABORT: break; case NB_EV_APPLY: + iif = nb_running_get_entry(args->dnode, NULL, true); + pim_iifp = iif->info; + pim = pim_iifp->pim; + + oifname = yang_dnode_get_string(args->dnode, NULL); + oif = if_lookup_by_name(oifname, pim->vrf_id); if (!oif) { snprintf(args->errmsg, args->errmsg_len, "No such interface name %s", diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 8a808afa73..b0aa2b17c5 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -90,7 +90,7 @@ struct channel_counts { installed: indicate if this entry is installed in the kernel. */ -PREDECL_RBTREE_UNIQ(rb_pim_oil) +PREDECL_RBTREE_UNIQ(rb_pim_oil); struct channel_oil { struct pim_instance *pim; @@ -112,7 +112,7 @@ struct channel_oil { extern int pim_channel_oil_compare(const struct channel_oil *c1, const struct channel_oil *c2); DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb, - pim_channel_oil_compare) + pim_channel_oil_compare); extern struct list *pim_channel_oil_list; diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 8030835fb2..adea3cd9ef 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -373,7 +373,7 @@ void join_timer_start(struct pim_upstream *up); int pim_upstream_compare(const struct pim_upstream *up1, const struct pim_upstream *up2); DECLARE_RBTREE_UNIQ(rb_pim_upstream, struct pim_upstream, upstream_rb, - pim_upstream_compare) + pim_upstream_compare); void pim_upstream_register_reevaluate(struct pim_instance *pim); diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 89e7e5dc17..1ef64ff0de 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -43,10 +43,10 @@ #include "ripd/rip_debug.h" #include "ripd/rip_interface.h" -DEFINE_MTYPE_STATIC(RIPD, RIP_INTERFACE, "RIP interface") -DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String") -DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)) -DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)) +DEFINE_MTYPE_STATIC(RIPD, RIP_INTERFACE, "RIP interface"); +DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String"); +DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)); +DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)); /* static prototypes */ static void rip_enable_apply(struct interface *); diff --git a/ripd/rip_interface.h b/ripd/rip_interface.h index 715daf2e50..fe26a78bdc 100644 --- a/ripd/rip_interface.h +++ b/ripd/rip_interface.h @@ -23,7 +23,7 @@ #include "memory.h" #include "zclient.h" -DECLARE_MTYPE(RIP_INTERFACE_STRING) +DECLARE_MTYPE(RIP_INTERFACE_STRING); extern int rip_interface_down(int, struct zclient *, zebra_size_t, vrf_id_t); extern int rip_interface_up(int, struct zclient *, zebra_size_t, vrf_id_t); diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 7e381887fc..2e5eec9844 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -128,7 +128,8 @@ FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT, .signals = ripd_signals, .n_signals = array_size(ripd_signals), .privs = &ripd_privs, .yang_modules = ripd_yang_modules, - .n_yang_modules = array_size(ripd_yang_modules), ) + .n_yang_modules = array_size(ripd_yang_modules), +); #define DEPRECATED_OPTIONS "" diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index 776f121d59..4034fe8424 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -29,7 +29,7 @@ #include "ripd/ripd.h" -DEFINE_MTYPE_STATIC(RIPD, RIP_OFFSET_LIST, "RIP offset list") +DEFINE_MTYPE_STATIC(RIPD, RIP_OFFSET_LIST, "RIP offset list"); #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIP_OFFSET_LIST_IN].alist_name) #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_IN].metric) diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c index 23599f0877..63493e2539 100644 --- a/ripd/rip_peer.c +++ b/ripd/rip_peer.c @@ -29,7 +29,7 @@ #include "ripd/ripd.h" -DEFINE_MTYPE_STATIC(RIPD, RIP_PEER, "RIP peer") +DEFINE_MTYPE_STATIC(RIPD, RIP_PEER, "RIP peer"); static struct rip_peer *rip_peer_new(void) { diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c index 4e6ed1400f..37bce7484c 100644 --- a/ripd/rip_snmp.c +++ b/ripd/rip_snmp.c @@ -589,4 +589,5 @@ static int rip_snmp_module_init(void) FRR_MODULE_SETUP(.name = "ripd_snmp", .version = FRR_VERSION, .description = "ripd AgentX SNMP module", - .init = rip_snmp_module_init, ) + .init = rip_snmp_module_init, +); diff --git a/ripd/ripd.c b/ripd/ripd.c index 4a56efb6f8..1c23575bf3 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -56,11 +56,11 @@ /* UDP receive buffer size */ #define RIP_UDP_RCV_BUF 41600 -DEFINE_MGROUP(RIPD, "ripd") -DEFINE_MTYPE_STATIC(RIPD, RIP, "RIP structure") -DEFINE_MTYPE_STATIC(RIPD, RIP_VRF_NAME, "RIP VRF name") -DEFINE_MTYPE_STATIC(RIPD, RIP_INFO, "RIP route info") -DEFINE_MTYPE_STATIC(RIPD, RIP_DISTANCE, "RIP distance") +DEFINE_MGROUP(RIPD, "ripd"); +DEFINE_MTYPE_STATIC(RIPD, RIP, "RIP structure"); +DEFINE_MTYPE_STATIC(RIPD, RIP_VRF_NAME, "RIP VRF name"); +DEFINE_MTYPE_STATIC(RIPD, RIP_INFO, "RIP route info"); +DEFINE_MTYPE_STATIC(RIPD, RIP_DISTANCE, "RIP distance"); /* Prototypes. */ static void rip_output_process(struct connected *, struct sockaddr_in *, int, diff --git a/ripd/ripd.h b/ripd/ripd.h index 99718f7b9e..85aac985f5 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -97,7 +97,7 @@ #define RIP_INSTANCE "/frr-ripd:ripd/instance" #define RIP_IFACE "/frr-interface:lib/interface/frr-ripd:rip" -DECLARE_MGROUP(RIPD) +DECLARE_MGROUP(RIPD); /* RIP structure. */ struct rip { @@ -529,7 +529,7 @@ extern struct rip_instance_head rip_instances; /* Master thread strucutre. */ extern struct thread_master *master; -DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)) -DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)) +DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)); +DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)); #endif /* _ZEBRA_RIP_H */ diff --git a/ripd/subdir.am b/ripd/subdir.am index 875239e871..09d5590329 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -57,6 +57,6 @@ nodist_ripd_ripd_SOURCES = \ # end ripd_ripd_snmp_la_SOURCES = ripd/rip_snmp.c -ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 ripd_ripd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic ripd_ripd_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 115d7a6b99..11a8fdff87 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -49,7 +49,7 @@ #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP #endif -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_IF, "ripng interface") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_IF, "ripng interface"); /* Static utility function. */ static void ripng_enable_apply(struct interface *); diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 010bac851b..a5d837aa55 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -131,7 +131,8 @@ FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT, .privs = &ripngd_privs, .yang_modules = ripngd_yang_modules, - .n_yang_modules = array_size(ripngd_yang_modules), ) + .n_yang_modules = array_size(ripngd_yang_modules), +); #define DEPRECATED_OPTIONS "" diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c index ba6e52fdda..3e9fa90938 100644 --- a/ripngd/ripng_nexthop.c +++ b/ripngd/ripng_nexthop.c @@ -39,7 +39,7 @@ #include "ripngd/ripng_debug.h" #include "ripngd/ripng_nexthop.h" -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_RTE_DATA, "RIPng rte data") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_RTE_DATA, "RIPng rte data"); #define DEBUG 1 diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c index 0094c993ad..efce8a0926 100644 --- a/ripngd/ripng_offset.c +++ b/ripngd/ripng_offset.c @@ -33,7 +33,7 @@ #include "ripngd/ripngd.h" -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst"); #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name) #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric) diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c index 0ac489c67e..479fcaeb54 100644 --- a/ripngd/ripng_peer.c +++ b/ripngd/ripng_peer.c @@ -34,7 +34,7 @@ #include "ripngd/ripngd.h" #include "ripngd/ripng_nexthop.h" -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_PEER, "RIPng peer") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_PEER, "RIPng peer"); static struct ripng_peer *ripng_peer_new(void) { diff --git a/ripngd/ripng_route.c b/ripngd/ripng_route.c index ed9d77a378..1eb1d0f31d 100644 --- a/ripngd/ripng_route.c +++ b/ripngd/ripng_route.c @@ -30,7 +30,7 @@ #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate"); static struct ripng_aggregate *ripng_aggregate_new(void) { diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 37e23046e8..749feaca6c 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -44,10 +44,10 @@ #include "ripngd/ripng_debug.h" #include "ripngd/ripng_nexthop.h" -DEFINE_MGROUP(RIPNGD, "ripngd") -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG, "RIPng structure") -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_VRF_NAME, "RIPng VRF name") -DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_ROUTE, "RIPng route info") +DEFINE_MGROUP(RIPNGD, "ripngd"); +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG, "RIPng structure"); +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_VRF_NAME, "RIPng VRF name"); +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_ROUTE, "RIPng route info"); enum { ripng_all_route, ripng_changed_route, diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 14ac29b3fe..12e5a6d4ac 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -86,7 +86,7 @@ #define RIPNG_INSTANCE "/frr-ripngd:ripngd/instance" #define RIPNG_IFACE "/frr-interface:lib/interface/frr-ripngd:ripng" -DECLARE_MGROUP(RIPNGD) +DECLARE_MGROUP(RIPNGD); /* RIPng structure. */ struct ripng { diff --git a/sharpd/sharp_globals.h b/sharpd/sharp_globals.h index 52561fd451..ecb7053fd6 100644 --- a/sharpd/sharp_globals.h +++ b/sharpd/sharp_globals.h @@ -22,7 +22,7 @@ #ifndef __SHARP_GLOBAL_H__ #define __SHARP_GLOBAL_H__ -DECLARE_MGROUP(SHARPD) +DECLARE_MGROUP(SHARPD); struct sharp_routes { /* The original prefix for route installation */ diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index fe7f9851f9..a1216247c0 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -49,7 +49,7 @@ #include "sharp_globals.h" #include "sharp_nht.h" -DEFINE_MGROUP(SHARPD, "sharpd") +DEFINE_MGROUP(SHARPD, "sharpd"); zebra_capabilities_t _caps_p[] = { }; @@ -129,7 +129,8 @@ FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT, .n_signals = array_size(sharp_signals), .privs = &sharp_privs, .yang_modules = sharpd_yang_modules, - .n_yang_modules = array_size(sharpd_yang_modules), ) + .n_yang_modules = array_size(sharpd_yang_modules), +); struct sharp_global sg; diff --git a/sharpd/sharp_nht.c b/sharpd/sharp_nht.c index bed0ebfa27..a90387186e 100644 --- a/sharpd/sharp_nht.c +++ b/sharpd/sharp_nht.c @@ -32,8 +32,8 @@ #include "sharp_globals.h" #include "sharp_zebra.h" -DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker") -DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group") +DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker"); +DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group"); struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p) { diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 0095aed547..73bbaf0bc0 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -685,7 +685,8 @@ static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS) return 0; } - zlog_debug("Received update for %pFX", &nhr.prefix); + zlog_debug("Received update for %pFX metric: %u", &nhr.prefix, + nhr.metric); nht = sharp_nh_tracker_get(&nhr.prefix); nht->nhop_num = nhr.nexthop_num; diff --git a/staticd/static_main.c b/staticd/static_main.c index 560814771d..1561b91efb 100644 --- a/staticd/static_main.c +++ b/staticd/static_main.c @@ -129,7 +129,7 @@ FRR_DAEMON_INFO(staticd, STATIC, .vty_port = STATIC_VTY_PORT, .privs = &static_privs, .yang_modules = staticd_yang_modules, .n_yang_modules = array_size(staticd_yang_modules), -) +); int main(int argc, char **argv, char **envp) { diff --git a/staticd/static_memory.c b/staticd/static_memory.c deleted file mode 100644 index 122cc9fce1..0000000000 --- a/staticd/static_memory.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * static memory code. - * Copyright (C) 2018 Cumulus Networks, Inc. - * Donald Sharp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> - -#include <memory.h> - -#include "staticd/static_memory.h" - -DEFINE_MGROUP(STATIC, "staticd") - -DEFINE_MTYPE(STATIC, STATIC_NEXTHOP, "Static Nexthop"); diff --git a/staticd/static_memory.h b/staticd/static_memory.h deleted file mode 100644 index 077cd0f32b..0000000000 --- a/staticd/static_memory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * static memory code. - * Copyright (C) 2018 Cumulus Networks, Inc. - * Donald Sharp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __STATIC_MEMORY_H__ - -#include "memory.h" - -DECLARE_MGROUP(STATIC) - -DECLARE_MTYPE(STATIC_ROUTE); -DECLARE_MTYPE(STATIC_NEXTHOP); -DECLARE_MTYPE(STATIC_PATH); - -#endif diff --git a/staticd/static_routes.c b/staticd/static_routes.c index 9f7e19660d..739c08b09e 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -31,12 +31,71 @@ #include "static_vrf.h" #include "static_routes.h" -#include "static_memory.h" #include "static_zebra.h" #include "static_debug.h" -DEFINE_MTYPE(STATIC, STATIC_ROUTE, "Static Route Info"); -DEFINE_MTYPE(STATIC, STATIC_PATH, "Static Path"); +DEFINE_MGROUP(STATIC, "staticd"); + +DEFINE_MTYPE_STATIC(STATIC, STATIC_ROUTE, "Static Route Info"); +DEFINE_MTYPE_STATIC(STATIC, STATIC_PATH, "Static Path"); +DEFINE_MTYPE_STATIC(STATIC, STATIC_NEXTHOP, "Static Nexthop"); + +void zebra_stable_node_cleanup(struct route_table *table, + struct route_node *node) +{ + struct static_nexthop *nh; + struct static_path *pn; + struct static_route_info *si; + struct route_table *src_table; + struct route_node *src_node; + struct static_path *src_pn; + struct static_route_info *src_si; + + si = node->info; + + if (si) { + frr_each_safe(static_path_list, &si->path_list, pn) { + frr_each_safe(static_nexthop_list, &pn->nexthop_list, + nh) { + static_nexthop_list_del(&pn->nexthop_list, nh); + XFREE(MTYPE_STATIC_NEXTHOP, nh); + } + static_path_list_del(&si->path_list, pn); + XFREE(MTYPE_STATIC_PATH, pn); + } + + /* clean up for dst table */ + src_table = srcdest_srcnode_table(node); + if (src_table) { + /* This means the route_node is part of the top + * hierarchy and refers to a destination prefix. + */ + for (src_node = route_top(src_table); src_node; + src_node = route_next(src_node)) { + src_si = src_node->info; + + frr_each_safe(static_path_list, + &src_si->path_list, src_pn) { + frr_each_safe(static_nexthop_list, + &src_pn->nexthop_list, + nh) { + static_nexthop_list_del( + &src_pn->nexthop_list, + nh); + XFREE(MTYPE_STATIC_NEXTHOP, nh); + } + static_path_list_del(&src_si->path_list, + src_pn); + XFREE(MTYPE_STATIC_PATH, src_pn); + } + + XFREE(MTYPE_STATIC_ROUTE, src_node->info); + } + } + + XFREE(MTYPE_STATIC_ROUTE, node->info); + } +} /* Install static path into rib. */ void static_install_path(struct route_node *rn, struct static_path *pn, diff --git a/staticd/static_routes.h b/staticd/static_routes.h index 0fbf0674d7..f64a40329d 100644 --- a/staticd/static_routes.h +++ b/staticd/static_routes.h @@ -22,6 +22,9 @@ #include "lib/mpls.h" #include "table.h" +#include "memory.h" + +DECLARE_MGROUP(STATIC); /* Static route label information */ struct static_nh_label { @@ -198,6 +201,9 @@ extern bool static_add_nexthop_validate(const char *nh_vrf_name, extern struct stable_info *static_get_stable_info(struct route_node *rn); extern void static_route_info_init(struct static_route_info *si); +extern void zebra_stable_node_cleanup(struct route_table *table, + struct route_node *node); + /* * Max string return via API static_get_nh_str in size_t */ diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c index 2133093bb3..ba1367b877 100644 --- a/staticd/static_vrf.c +++ b/staticd/static_vrf.c @@ -24,7 +24,6 @@ #include "table.h" #include "srcdest_table.h" -#include "static_memory.h" #include "static_vrf.h" #include "static_routes.h" #include "static_zebra.h" @@ -32,63 +31,6 @@ DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info"); -static void zebra_stable_node_cleanup(struct route_table *table, - struct route_node *node) -{ - struct static_nexthop *nh; - struct static_path *pn; - struct static_route_info *si; - struct route_table *src_table; - struct route_node *src_node; - struct static_path *src_pn; - struct static_route_info *src_si; - - si = node->info; - - if (si) { - frr_each_safe(static_path_list, &si->path_list, pn) { - frr_each_safe(static_nexthop_list, &pn->nexthop_list, - nh) { - static_nexthop_list_del(&pn->nexthop_list, nh); - XFREE(MTYPE_STATIC_NEXTHOP, nh); - } - static_path_list_del(&si->path_list, pn); - XFREE(MTYPE_STATIC_PATH, pn); - } - - /* clean up for dst table */ - src_table = srcdest_srcnode_table(node); - if (src_table) { - /* This means the route_node is part of the top - * hierarchy and refers to a destination prefix. - */ - for (src_node = route_top(src_table); src_node; - src_node = route_next(src_node)) { - src_si = src_node->info; - - frr_each_safe(static_path_list, - &src_si->path_list, src_pn) { - frr_each_safe(static_nexthop_list, - &src_pn->nexthop_list, - nh) { - static_nexthop_list_del( - &src_pn->nexthop_list, - nh); - XFREE(MTYPE_STATIC_NEXTHOP, nh); - } - static_path_list_del(&src_si->path_list, - src_pn); - XFREE(MTYPE_STATIC_PATH, src_pn); - } - - XFREE(MTYPE_STATIC_ROUTE, src_node->info); - } - } - - XFREE(MTYPE_STATIC_ROUTE, node->info); - } -} - static struct static_vrf *static_vrf_alloc(void) { struct route_table *table; diff --git a/staticd/static_vty.c b/staticd/static_vty.c index dd03f83778..33a2728cd0 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -33,7 +33,6 @@ #include "northbound_cli.h" #include "static_vrf.h" -#include "static_memory.h" #include "static_vty.h" #include "static_routes.h" #include "static_debug.h" diff --git a/staticd/subdir.am b/staticd/subdir.am index 9c630e8f5f..a0ae2569cb 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -13,7 +13,6 @@ endif staticd_libstatic_a_SOURCES = \ staticd/static_debug.c \ - staticd/static_memory.c \ staticd/static_nht.c \ staticd/static_routes.c \ staticd/static_zebra.c \ @@ -25,7 +24,6 @@ staticd_libstatic_a_SOURCES = \ noinst_HEADERS += \ staticd/static_debug.h \ - staticd/static_memory.h \ staticd/static_nht.h \ staticd/static_zebra.h \ staticd/static_routes.h \ diff --git a/tests/lib/cxxcompat.c b/tests/lib/cxxcompat.c index 391ccd9268..fde0d6af52 100644 --- a/tests/lib/cxxcompat.c +++ b/tests/lib/cxxcompat.c @@ -107,7 +107,7 @@ #include "lib/zassert.h" #include "lib/zclient.h" -PREDECL_RBTREE_UNIQ(footree) +PREDECL_RBTREE_UNIQ(footree); struct foo { int dummy; struct footree_item item; @@ -116,7 +116,7 @@ static int foocmp(const struct foo *a, const struct foo *b) { return memcmp(&a->dummy, &b->dummy, sizeof(a->dummy)); } -DECLARE_RBTREE_UNIQ(footree, struct foo, item, foocmp) +DECLARE_RBTREE_UNIQ(footree, struct foo, item, foocmp); int main(int argc, char **argv) { diff --git a/tests/lib/test_atomlist.c b/tests/lib/test_atomlist.c index 40837b4722..83dd9f2c59 100644 --- a/tests/lib/test_atomlist.c +++ b/tests/lib/test_atomlist.c @@ -41,18 +41,18 @@ static struct seqlock sqlo; -PREDECL_ATOMLIST(alist) -PREDECL_ATOMSORT_UNIQ(asort) +PREDECL_ATOMLIST(alist); +PREDECL_ATOMSORT_UNIQ(asort); struct item { uint64_t val1; struct alist_item chain; struct asort_item sortc; uint64_t val2; }; -DECLARE_ATOMLIST(alist, struct item, chain) +DECLARE_ATOMLIST(alist, struct item, chain); static int icmp(const struct item *a, const struct item *b); -DECLARE_ATOMSORT_UNIQ(asort, struct item, sortc, icmp) +DECLARE_ATOMSORT_UNIQ(asort, struct item, sortc, icmp); static int icmp(const struct item *a, const struct item *b) { diff --git a/tests/lib/test_heavy_wq.c b/tests/lib/test_heavy_wq.c index cffd52ee02..00aa7b80dd 100644 --- a/tests/lib/test_heavy_wq.c +++ b/tests/lib/test_heavy_wq.c @@ -37,9 +37,9 @@ #include "tests.h" -DEFINE_MGROUP(TEST_HEAVYWQ, "heavy-wq test") -DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE, "heavy_wq_node") -DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE_STR, "heavy_wq_node->str") +DEFINE_MGROUP(TEST_HEAVYWQ, "heavy-wq test"); +DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE, "heavy_wq_node"); +DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE_STR, "heavy_wq_node->str"); extern struct thread_master *master; static struct work_queue *heavy_wq; diff --git a/tests/lib/test_memory.c b/tests/lib/test_memory.c index 84be9cb769..9f04304a2b 100644 --- a/tests/lib/test_memory.c +++ b/tests/lib/test_memory.c @@ -19,8 +19,8 @@ #include <zebra.h> #include <memory.h> -DEFINE_MGROUP(TEST_MEMORY, "memory test") -DEFINE_MTYPE_STATIC(TEST_MEMORY, TEST, "generic test mtype") +DEFINE_MGROUP(TEST_MEMORY, "memory test"); +DEFINE_MTYPE_STATIC(TEST_MEMORY, TEST, "generic test mtype"); /* Memory torture tests * diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h index f86cadd398..32331c14a0 100644 --- a/tests/lib/test_typelist.h +++ b/tests/lib/test_typelist.h @@ -47,7 +47,7 @@ #define REALTYPE TYPE #endif -PREDECL(REALTYPE, list) +PREDECL(REALTYPE, list); struct item { uint64_t val; struct list_item itm; @@ -59,7 +59,7 @@ static int list_cmp(const struct item *a, const struct item *b); #if IS_HASH(REALTYPE) static uint32_t list_hash(const struct item *a); -DECLARE(REALTYPE, list, struct item, itm, list_cmp, list_hash) +DECLARE(REALTYPE, list, struct item, itm, list_cmp, list_hash); static uint32_t list_hash(const struct item *a) { @@ -72,7 +72,7 @@ static uint32_t list_hash(const struct item *a) } #else -DECLARE(REALTYPE, list, struct item, itm, list_cmp) +DECLARE(REALTYPE, list, struct item, itm, list_cmp); #endif static int list_cmp(const struct item *a, const struct item *b) @@ -85,7 +85,7 @@ static int list_cmp(const struct item *a, const struct item *b) } #else /* !IS_SORTED */ -DECLARE(REALTYPE, list, struct item, itm) +DECLARE(REALTYPE, list, struct item, itm); #endif #define NITEM 10000 diff --git a/tests/lib/test_xref.c b/tests/lib/test_xref.c index 700950de1f..aa179141af 100644 --- a/tests/lib/test_xref.c +++ b/tests/lib/test_xref.c @@ -127,7 +127,7 @@ bool (*tests[])(void) = { test_logcall, }; -XREF_SETUP() +XREF_SETUP(); int main(int argc, char **argv) { diff --git a/tests/lib/test_zmq.c b/tests/lib/test_zmq.c index fe330d98d4..65195aa3e1 100644 --- a/tests/lib/test_zmq.c +++ b/tests/lib/test_zmq.c @@ -22,8 +22,8 @@ #include "sigevent.h" #include "frr_zmq.h" -DEFINE_MTYPE_STATIC(LIB, TESTBUF, "zmq test buffer") -DEFINE_MTYPE_STATIC(LIB, ZMQMSG, "zmq message") +DEFINE_MTYPE_STATIC(LIB, TESTBUF, "zmq test buffer"); +DEFINE_MTYPE_STATIC(LIB, ZMQMSG, "zmq message"); static struct thread_master *master; diff --git a/tests/ospfd/test_ospf_spf.c b/tests/ospfd/test_ospf_spf.c index a85f7e14ec..7808c3d47d 100644 --- a/tests/ospfd/test_ospf_spf.c +++ b/tests/ospfd/test_ospf_spf.c @@ -23,9 +23,9 @@ #include "common.h" DECLARE_RBTREE_UNIQ(p_spaces, struct p_space, p_spaces_item, - p_spaces_compare_func) + p_spaces_compare_func); DECLARE_RBTREE_UNIQ(q_spaces, struct q_space, q_spaces_item, - q_spaces_compare_func) + q_spaces_compare_func); static struct ospf *test_init(struct ospf_test_node *root) { diff --git a/tests/topotests/bfd-profiles-topo1/r1/bfd-peers-initial.json b/tests/topotests/bfd-profiles-topo1/r1/bfd-peers-initial.json index bab24c4fa0..86a7e5139c 100644 --- a/tests/topotests/bfd-profiles-topo1/r1/bfd-peers-initial.json +++ b/tests/topotests/bfd-profiles-topo1/r1/bfd-peers-initial.json @@ -6,14 +6,14 @@ "interface": "r1-eth1", "multihop": false, "peer": "172.16.100.2", - "receive-interval": 300, + "receive-interval": 800, "remote-detect-multiplier": 3, "remote-diagnostic": "ok", "remote-id": "*", "remote-receive-interval": 300, "remote-transmit-interval": 300, "status": "up", - "transmit-interval": 300, + "transmit-interval": 800, "uptime": "*", "vrf": "default" }, diff --git a/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf b/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf index 4798d17c40..fcea5d48fc 100644 --- a/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf +++ b/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf @@ -2,7 +2,7 @@ interface r1-eth1 ip ospf area 0 ip ospf hello-interval 2 ip ospf dead-interval 10 - ip ospf bfd + ip ospf bfd profile slowtx ! router ospf ospf router-id 10.254.254.1 diff --git a/tests/topotests/bfd-profiles-topo1/r6/bfd-peers-initial.json b/tests/topotests/bfd-profiles-topo1/r6/bfd-peers-initial.json index 4e6fa869ba..ec973eb365 100644 --- a/tests/topotests/bfd-profiles-topo1/r6/bfd-peers-initial.json +++ b/tests/topotests/bfd-profiles-topo1/r6/bfd-peers-initial.json @@ -10,8 +10,8 @@ "remote-detect-multiplier": 3, "remote-diagnostic": "ok", "remote-id": "*", - "remote-receive-interval": 300, - "remote-transmit-interval": 300, + "remote-receive-interval": 800, + "remote-transmit-interval": 800, "status": "up", "transmit-interval": 300, "uptime": "*", diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/__init__.py b/tests/topotests/bgp-default-ipv4-ipv6-unicast/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/__init__.py diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/bgpd.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/bgpd.conf new file mode 100644 index 0000000000..bf39152ea8 --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/bgpd.conf @@ -0,0 +1,3 @@ +! +router bgp 65001 +! diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/zebra.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/zebra.conf new file mode 100644 index 0000000000..697765168d --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r1/zebra.conf @@ -0,0 +1,7 @@ +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! + diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/bgpd.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/bgpd.conf new file mode 100644 index 0000000000..abbd1b86fa --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/bgpd.conf @@ -0,0 +1,5 @@ +! +router bgp 65001 + no bgp default ipv4-unicast + bgp default ipv6-unicast +! diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/zebra.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/bgpd.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/bgpd.conf new file mode 100644 index 0000000000..a405c047ca --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/bgpd.conf @@ -0,0 +1,4 @@ +! +router bgp 65001 + bgp default ipv6-unicast +! diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/zebra.conf b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/zebra.conf new file mode 100644 index 0000000000..e9fdfb70c5 --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/r3/zebra.conf @@ -0,0 +1,6 @@ +! +interface r3-eth0 + ip address 192.168.255.3/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py b/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py new file mode 100644 index 0000000000..c1dbf0ebec --- /dev/null +++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if `bgp default ipv4-unicast` and `bgp default ipv6-unicast` +commands work as expected. + +STEP 1: 'Check if neighbor 192.168.255.254 is enabled for ipv4 address-family only' +STEP 2: 'Check if neighbor 192.168.255.254 is enabled for ipv6 address-family only' +STEP 3: 'Check if neighbor 192.168.255.254 is enabled for ipv4 and ipv6 address-families' +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo +from lib.common_config import step + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r4"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + 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 test_bgp_default_ipv4_ipv6_unicast(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Check if neighbor 192.168.255.254 is enabled for ipv4 address-family only") + + def _bgp_neighbor_ipv4_af_only(): + tgen.gears["r1"].vtysh_cmd( + "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external" + ) + + output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp summary json")) + + if "ipv4Unicast" in output and "ipv6Unicast" not in output: + return True + return False + + assert _bgp_neighbor_ipv4_af_only() == True + + step("Check if neighbor 192.168.255.254 is enabled for ipv6 address-family only") + + def _bgp_neighbor_ipv6_af_only(): + tgen.gears["r2"].vtysh_cmd( + "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external" + ) + + output = json.loads(tgen.gears["r2"].vtysh_cmd("show bgp summary json")) + + if "ipv4Unicast" not in output and "ipv6Unicast" in output: + return True + return False + + assert _bgp_neighbor_ipv6_af_only() == True + + step( + "Check if neighbor 192.168.255.254 is enabled for ipv4 and ipv6 address-families" + ) + + def _bgp_neighbor_ipv4_and_ipv6_af(): + tgen.gears["r3"].vtysh_cmd( + "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external" + ) + + output = json.loads(tgen.gears["r3"].vtysh_cmd("show bgp summary json")) + + if "ipv4Unicast" in output and "ipv6Unicast" in output: + return True + return False + + assert _bgp_neighbor_ipv4_and_ipv6_af() == True + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py index ac7ee44b25..464d6eb475 100644 --- a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py +++ b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py @@ -115,7 +115,7 @@ sys.path.append(os.path.join(CWD, "../lib/")) # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen from mininet.topo import Topo - +from lib.topotest import iproute2_is_vrf_capable from lib.common_config import ( step, verify_rib, @@ -215,6 +215,10 @@ def setup_module(mod): if result is not True: pytest.skip("Kernel requirements are not met") + # iproute2 needs to support VRFs for this suite to run. + if not iproute2_is_vrf_capable(): + pytest.skip("Installed iproute2 version does not support VRFs") + testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) logger.info("=" * 40) diff --git a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py index c6e1792e84..10cf1c6ae8 100644 --- a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py +++ b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py @@ -71,7 +71,7 @@ sys.path.append(os.path.join(CWD, "../lib/")) # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen from mininet.topo import Topo - +from lib.topotest import iproute2_is_vrf_capable from lib.common_config import ( step, verify_rib, @@ -164,6 +164,10 @@ def setup_module(mod): if result is not True: pytest.skip("Kernel requirements are not met") + # iproute2 needs to support VRFs for this suite to run. + if not iproute2_is_vrf_capable(): + pytest.skip("Installed iproute2 version does not support VRFs") + testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) logger.info("=" * 40) diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py index 6ab78c385e..ae904ba69e 100644 --- a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -40,6 +40,8 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from lib.topotest import iproute2_is_vrf_capable +from lib.common_config import required_linux_kernel_version from mininet.topo import Topo @@ -193,18 +195,21 @@ def test_isis_route_installation(): def test_isis_linux_route_installation(): - - dist = platform.dist() - - if dist[1] == "16.04": - pytest.skip("Kernel not supported for vrf") - "Check whether all expected routes are present and installed in the OS" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.15") + if result is not True: + pytest.skip("Kernel requirements are not met") + + # iproute2 needs to support VRFs for this suite to run. + if not iproute2_is_vrf_capable(): + pytest.skip("Installed iproute2 version does not support VRFs") + logger.info("Checking routers for installed ISIS vrf routes in OS") # Check for routes in `ip route show vrf {}-cust1` for rname, router in tgen.routers().items(): @@ -236,18 +241,21 @@ def test_isis_route6_installation(): def test_isis_linux_route6_installation(): - - dist = platform.dist() - - if dist[1] == "16.04": - pytest.skip("Kernel not supported for vrf") - "Check whether all expected routes are present and installed in the OS" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.15") + if result is not True: + pytest.skip("Kernel requirements are not met") + + # iproute2 needs to support VRFs for this suite to run. + if not iproute2_is_vrf_capable(): + pytest.skip("Installed iproute2 version does not support VRFs") + logger.info("Checking routers for installed ISIS vrf IPv6 routes in OS") # Check for routes in `ip -6 route show vrf {}-cust1` for rname, router in tgen.routers().items(): diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 55b11dab3c..867831e114 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -43,6 +43,7 @@ from lib.common_config import ( run_frr_cmd, FRRCFG_FILE, retry, + get_ipv6_linklocal_address ) LOGDIR = "/tmp/topotests/" @@ -446,7 +447,7 @@ def __create_bgp_unicast_neighbor( cmd = "redistribute {}".format(redistribute["redist_type"]) redist_attr = redistribute.setdefault("attribute", None) if redist_attr: - if isinstance(redist_attr, dict): + if type(redist_attr) is dict: for key, value in redist_attr.items(): cmd = "{} {} {}".format(cmd, key, value) else: @@ -528,7 +529,7 @@ def __create_l2vpn_evpn_address_family( if advertise_data: for address_type, unicast_type in advertise_data.items(): - if isinstance(unicast_type, dict): + if type(unicast_type) is dict: for key, value in unicast_type.items(): cmd = "advertise {} {}".format(address_type, key) @@ -555,7 +556,7 @@ def __create_l2vpn_evpn_address_family( "ipv4" ].split("/")[0] - if isinstance(action, dict): + if type(action) is dict: next_hop_self = action.setdefault("next_hop_self", None) route_maps = action.setdefault("route_maps", {}) @@ -977,10 +978,6 @@ def modify_bgp_config_when_bgpd_down(tgen, topo, input_dict): router_list[router].run(cmd) except Exception as e: - # handle any exception - logger.error("Error %s occured. Arguments %s.", e.message, e.args) - - # Traceback errormsg = traceback.format_exc() logger.error(errormsg) return errormsg @@ -1085,10 +1082,10 @@ def verify_bgp_convergence(tgen, topo, dut=None): logger.debug("Entering lib API: verify_bgp_convergence()") for router, rnode in tgen.routers().items(): - if "bgp" not in topo["routers"][router]: + if dut is not None and dut != router: continue - if dut is not None and dut != router: + if "bgp" not in topo["routers"][router]: continue logger.info("Verifying BGP Convergence on router %s:", router) @@ -1114,59 +1111,7 @@ def verify_bgp_convergence(tgen, topo, dut=None): # To find neighbor ip type bgp_addr_type = bgp_data["address_family"] - if "l2vpn" in bgp_addr_type: - total_evpn_peer = 0 - - if "neighbor" not in bgp_addr_type["l2vpn"]["evpn"]: - continue - - bgp_neighbors = bgp_addr_type["l2vpn"]["evpn"]["neighbor"] - total_evpn_peer += len(bgp_neighbors) - - no_of_evpn_peer = 0 - for bgp_neighbor, peer_data in bgp_neighbors.items(): - for _addr_type, dest_link_dict in peer_data.items(): - data = topo["routers"][bgp_neighbor]["links"] - for dest_link in dest_link_dict.keys(): - if dest_link in data: - peer_details = peer_data[_addr_type][dest_link] - - neighbor_ip = data[dest_link][_addr_type].split("/")[0] - nh_state = None - - if ( - "ipv4Unicast" in show_bgp_json[vrf] - or "ipv6Unicast" in show_bgp_json[vrf] - ): - errormsg = ( - "[DUT: %s] VRF: %s, " - "ipv4Unicast/ipv6Unicast" - " address-family present" - " under l2vpn" % (router, vrf) - ) - return errormsg - - l2VpnEvpn_data = show_bgp_json[vrf]["l2VpnEvpn"][ - "peers" - ] - nh_state = l2VpnEvpn_data[neighbor_ip]["state"] - - if nh_state == "Established": - no_of_evpn_peer += 1 - - if no_of_evpn_peer == total_evpn_peer: - logger.info( - "[DUT: %s] VRF: %s, BGP is Converged for " "epvn peers", - router, - vrf, - ) - else: - errormsg = ( - "[DUT: %s] VRF: %s, BGP is not converged " - "for evpn peers" % (router, vrf) - ) - return errormsg - else: + if "ipv4" in bgp_addr_type or "ipv6" in bgp_addr_type: for addr_type in bgp_addr_type.keys(): if not check_address_types(addr_type): continue @@ -1216,32 +1161,102 @@ def verify_bgp_convergence(tgen, topo, dut=None): nh_state = None if addr_type == "ipv4": - ipv4_data = show_bgp_json[vrf]["ipv4Unicast"][ - "peers" - ] - nh_state = ipv4_data[neighbor_ip]["state"] + if "ipv4Unicast" in show_bgp_json[vrf]: + ipv4_data = show_bgp_json[vrf]["ipv4Unicast"][ + "peers" + ] + nh_state = ipv4_data[neighbor_ip]["state"] else: - ipv6_data = show_bgp_json[vrf]["ipv6Unicast"][ - "peers" - ] - nh_state = ipv6_data[neighbor_ip]["state"] - + if "ipv6Unicast" in show_bgp_json[vrf]: + ipv6_data = show_bgp_json[vrf]["ipv6Unicast"][ + "peers" + ] + nh_state = ipv6_data[neighbor_ip]["state"] if nh_state == "Established": no_of_peer += 1 - if no_of_peer == total_peer: - logger.info( - "[DUT: %s] VRF: %s, BGP is Converged for %s address-family", - router, - vrf, - addr_type, - ) + if "l2vpn" in bgp_addr_type: + if "neighbor" not in bgp_addr_type["l2vpn"]["evpn"]: + if no_of_peer == total_peer: + logger.info( + "[DUT: %s] VRF: %s, BGP is Converged for %s address-family", + router, + vrf, + addr_type, + ) + else: + errormsg = ( + "[DUT: %s] VRF: %s, BGP is not converged for %s address-family" + % (router, vrf, addr_type) + ) + return errormsg else: - errormsg = ( - "[DUT: %s] VRF: %s, BGP is not converged for %s address-family" - % (router, vrf, addr_type) - ) - return errormsg + if no_of_peer == total_peer: + logger.info( + "[DUT: %s] VRF: %s, BGP is Converged for %s address-family", + router, + vrf, + addr_type, + ) + else: + errormsg = ( + "[DUT: %s] VRF: %s, BGP is not converged for %s address-family" + % (router, vrf, addr_type) + ) + return errormsg + + if "l2vpn" in bgp_addr_type: + total_evpn_peer = 0 + + if "neighbor" not in bgp_addr_type["l2vpn"]["evpn"]: + continue + + bgp_neighbors = bgp_addr_type["l2vpn"]["evpn"]["neighbor"] + total_evpn_peer += len(bgp_neighbors) + + no_of_evpn_peer = 0 + for bgp_neighbor, peer_data in bgp_neighbors.items(): + for _addr_type, dest_link_dict in peer_data.items(): + data = topo["routers"][bgp_neighbor]["links"] + for dest_link in dest_link_dict.keys(): + if dest_link in data: + peer_details = peer_data[_addr_type][dest_link] + + neighbor_ip = data[dest_link][_addr_type].split("/")[0] + nh_state = None + + if ( + "ipv4Unicast" in show_bgp_json[vrf] + or "ipv6Unicast" in show_bgp_json[vrf] + ): + errormsg = ( + "[DUT: %s] VRF: %s, " + "ipv4Unicast/ipv6Unicast" + " address-family present" + " under l2vpn" % (router, vrf) + ) + return errormsg + + l2VpnEvpn_data = show_bgp_json[vrf]["l2VpnEvpn"][ + "peers" + ] + nh_state = l2VpnEvpn_data[neighbor_ip]["state"] + + if nh_state == "Established": + no_of_evpn_peer += 1 + + if no_of_evpn_peer == total_evpn_peer: + logger.info( + "[DUT: %s] VRF: %s, BGP is Converged for " "epvn peers", + router, + vrf, + ) + else: + errormsg = ( + "[DUT: %s] VRF: %s, BGP is not converged " + "for evpn peers" % (router, vrf) + ) + return errormsg logger.debug("Exiting API: verify_bgp_convergence()") return True @@ -1400,10 +1415,6 @@ def modify_as_number(tgen, topo, input_dict): create_router_bgp(tgen, new_topo) except Exception as e: - # handle any exception - logger.error("Error %s occured. Arguments %s.", e.message, e.args) - - # Traceback errormsg = traceback.format_exc() logger.error(errormsg) return errormsg @@ -2621,7 +2632,7 @@ def verify_bgp_rib( found_routes.append(st_rt) if next_hop and multi_nh and st_found: - if not isinstance(next_hop, list): + if type(next_hop) is not list: next_hop = [next_hop] list1 = next_hop @@ -2661,7 +2672,7 @@ def verify_bgp_rib( nh_found = True elif next_hop and multi_nh is None: - if not isinstance(next_hop, list): + if type(next_hop) is not list: next_hop = [next_hop] list1 = next_hop found_hops = [ @@ -4092,7 +4103,7 @@ def verify_attributes_for_evpn_routes( errormsg = ( "[DUT: %s] RD: %s, Route : %s " "is not present in cli json " - "output " % (dut, route) + "output " % (dut, _rd, route) ) return errormsg @@ -4170,7 +4181,7 @@ def verify_evpn_routes( return errormsg for key, route_data_json in evpn_value_json.items(): - if isinstance(route_data_json, dict): + if type(route_data_json) is dict: rd_keys += 1 if prefix not in route_data_json: missing_routes[key] = prefix @@ -4184,7 +4195,7 @@ def verify_evpn_routes( return errormsg for key, route_data_json in evpn_value_json.items(): - if isinstance(route_data_json, dict): + if type(route_data_json) is dict: if prefix not in route_data_json: continue diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 9174389bea..a4c98924b6 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -1373,13 +1373,13 @@ def generate_ips(network, no_of_ips): if start_ip == "0.0.0.0" and mask == 0 and no_of_ips == 1: ipaddress_list.append("{}/{}".format(start_ip, mask)) return ipaddress_list - start_ip = ipaddress.IPv4Address(unicode(start_ip)) + start_ip = ipaddress.IPv4Address(frr_unicode(start_ip)) step = 2 ** (32 - mask) elif addr_type == "ipv6": if start_ip == "0::0" and mask == 0 and no_of_ips == 1: ipaddress_list.append("{}/{}".format(start_ip, mask)) return ipaddress_list - start_ip = ipaddress.IPv6Address(unicode(start_ip)) + start_ip = ipaddress.IPv6Address(frr_unicode(start_ip)) step = 2 ** (128 - mask) else: return [] @@ -1480,10 +1480,6 @@ def interface_status(tgen, topo, input_dict): load_config_to_router(tgen, router) except Exception as e: - # handle any exception - logger.error("Error %s occured. Arguments %s.", e.message, e.args) - - # Traceback errormsg = traceback.format_exc() logger.error(errormsg) return errormsg @@ -2442,51 +2438,6 @@ def shutdown_bringup_interface(tgen, dut, intf_name, ifaceaction=False): interface_set_status(router_list[dut], intf_name, ifaceaction) -def stop_router(tgen, router): - """ - Router's current config would be saved to /tmp/topotest/<suite>/<router> - for each daemon and router and its daemons would be stopped. - - * `tgen` : topogen object - * `router`: Device under test - """ - - router_list = tgen.routers() - - # Saving router config to /etc/frr, which will be loaded to router - # when it starts - router_list[router].vtysh_cmd("write memory") - - # Stop router - router_list[router].stop() - - -def start_router(tgen, router): - """ - Router will be started and config would be loaded from - /tmp/topotest/<suite>/<router> for each daemon - - * `tgen` : topogen object - * `router`: Device under test - """ - - logger.debug("Entering lib API: start_router") - - try: - router_list = tgen.routers() - - # Router and its daemons would be started and config would - # be loaded to router for each daemon from /etc/frr - router_list[router].start() - - except Exception as e: - errormsg = traceback.format_exc() - logger.error(errormsg) - return errormsg - - logger.debug("Exiting lib API: start_router()") - - def addKernelRoute( tgen, router, intf, group_addr_range, next_hop=None, src=None, del_action=None ): @@ -3754,6 +3705,43 @@ def verify_bgp_community(tgen, addr_type, router, network, input_dict=None): return True +def get_ipv6_linklocal_address(topo, node, intf): + """ + API to get the link local ipv6 address of a perticular interface + + Parameters + ---------- + * `node`: node on which link local ip to be fetched. + * `intf` : interface for which link local ip needs to be returned. + * `topo` : base topo + + Usage + ----- + result = get_ipv6_linklocal_address(topo, 'r1', 'r2') + + Returns link local ip of interface between r1 and r2. + + Returns + ------- + 1) link local ipv6 address from the interface + 2) errormsg - when link local ip not found + """ + tgen = get_topogen() + ext_nh = tgen.net[node].get_ipv6_linklocal() + req_nh = topo[node]['links'][intf]['interface'] + llip = None + for llips in ext_nh: + if llips[0] == req_nh: + llip = llips[1] + logger.info("Link local ip found = %s", llip) + return llip + + errormsg = "Failed: Link local ip not found on router {}, "\ + "interface {}".format(node, intf) + + return errormsg + + def verify_create_community_list(tgen, input_dict): """ API is to verify if large community list is created for any given DUT in diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 79e4d97448..9f642411b5 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -344,10 +344,9 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config= for lnk in input_dict[router]["links"].keys(): if "ospf" not in input_dict[router]["links"][lnk]: logger.debug( - "Router %s: ospf configs is not present in" - "input_dict, passed input_dict", - router, - input_dict, + "Router %s: ospf config is not present in" + "input_dict", + router ) continue ospf_data = input_dict[router]["links"][lnk]["ospf"] @@ -724,7 +723,7 @@ def verify_ospf6_neighbor(tgen, topo): nh_state = neighbor["state"] break else: - return "[DUT: {}] OSPF6 peer {} missing".format(router, data_rid) + return "[DUT: {}] OSPF6 peer {} missing".format(router, ospf_nbr_rid) if nh_state == "Full": no_of_peer += 1 diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 7f768f5b89..104b215078 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -518,6 +518,44 @@ def normalize_text(text): return text +def is_linux(): + """ + Parses unix name output to check if running on GNU/Linux. + + Returns True if running on Linux, returns False otherwise. + """ + + if os.uname()[0] == "Linux": + return True + return False + + +def iproute2_is_vrf_capable(): + """ + Checks if the iproute2 version installed on the system is capable of + handling VRFs by interpreting the output of the 'ip' utility found in PATH. + + Returns True if capability can be detected, returns False otherwise. + """ + + if is_linux(): + try: + subp = subprocess.Popen( + ["ip", "route", "show", "vrf"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + encoding="utf-8" + ) + iproute2_err = subp.communicate()[1].splitlines()[0].split()[0] + + if iproute2_err != "Error:": + return True + except Exception: + pass + return False + + def module_present_linux(module, load): """ Returns whether `module` is present. diff --git a/tests/topotests/ospf_suppress_fa/__init__.py b/tests/topotests/ospf_suppress_fa/__init__.py new file mode 100755 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/__init__.py diff --git a/tests/topotests/ospf_suppress_fa/r1/ospfd.conf b/tests/topotests/ospf_suppress_fa/r1/ospfd.conf new file mode 100644 index 0000000000..c02be35b14 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r1/ospfd.conf @@ -0,0 +1,9 @@ +! +interface r1-eth0 + ip ospf network point-to-point + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! +router ospf + network 10.0.12.0/24 area 0 +! diff --git a/tests/topotests/ospf_suppress_fa/r1/zebra.conf b/tests/topotests/ospf_suppress_fa/r1/zebra.conf new file mode 100644 index 0000000000..c1e31fb474 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r1/zebra.conf @@ -0,0 +1,4 @@ +! +interface r1-eth0 + ip address 10.0.12.1/24 +! diff --git a/tests/topotests/ospf_suppress_fa/r2/ospfd.conf b/tests/topotests/ospf_suppress_fa/r2/ospfd.conf new file mode 100644 index 0000000000..ebc7d252fd --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r2/ospfd.conf @@ -0,0 +1,16 @@ +! +interface r2-eth0 + ip ospf network point-to-point + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! +interface r2-eth1 + ip ospf network point-to-point + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! +router ospf + network 10.0.12.0/24 area 0 + network 10.0.23.0/24 area 1 + area 1 nssa +! diff --git a/tests/topotests/ospf_suppress_fa/r2/zebra.conf b/tests/topotests/ospf_suppress_fa/r2/zebra.conf new file mode 100644 index 0000000000..9f1a26349e --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r2/zebra.conf @@ -0,0 +1,7 @@ +! +interface r2-eth0 + ip address 10.0.12.2/24 +! +interface r2-eth1 + ip address 10.0.23.2/24 +! diff --git a/tests/topotests/ospf_suppress_fa/r3/ospfd.conf b/tests/topotests/ospf_suppress_fa/r3/ospfd.conf new file mode 100644 index 0000000000..08be11a7b7 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r3/ospfd.conf @@ -0,0 +1,11 @@ +! +interface r3-eth0 + ip ospf network point-to-point + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! +router ospf + redistribute static + network 10.0.23.0/24 area 1 + area 1 nssa +! diff --git a/tests/topotests/ospf_suppress_fa/r3/zebra.conf b/tests/topotests/ospf_suppress_fa/r3/zebra.conf new file mode 100644 index 0000000000..f76cbf74d2 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/r3/zebra.conf @@ -0,0 +1,8 @@ +! +ip route 3.3.1.1/32 Null0 +ip route 3.3.2.2/32 Null0 +ip route 3.3.3.3/32 Null0 +! +interface r3-eth0 + ip address 10.0.23.3/24 +! diff --git a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot new file mode 100644 index 0000000000..1036658f1a --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot @@ -0,0 +1,66 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph ospf_topo1 { + label="ospf suppress-fa"; + + # Routers + r1 [ + label="r1\nrtr-id 10.0.12.1", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r2 [ + label="r2 (ABR)\nrtr-id 10.0.23.2", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r3 [ + label="r3 (ASBR)\nrtr-id 10.0.23.3", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + + # Switches + s1 [ + label="s1\n10.0.12.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s2 [ + label="s2\n10.0.23.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + subgraph cluster0 { + label="area 0" + r1 -- s1 [label="eth1\n.1"]; + r2 -- s1 [label="eth1\n.2"]; + } + + subgraph cluster1 { + label="area 1\nNSSA" + r2 -- s2 [label="eth2\n.2"]; + r3 -- s2 [label="eth1\n.3"]; + } + + { rank=same; r1; r2; r3; } +} diff --git a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot.jpg b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot.jpg Binary files differnew file mode 100644 index 0000000000..2907d799f5 --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.dot.jpg diff --git a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py new file mode 100644 index 0000000000..74d609c57e --- /dev/null +++ b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python + +# +# test_ospf_suppres_fa.py +# Carles Kishimoto +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_ospf_suppres_fa.py: Test OSPF suppress-fa feature +- Topology: r1 --- R2 (ABR) --- R3 (redistribute static) + +test_ospf_set_suppress_fa() + 1) R1: Get a dict[LSA_ID] = fwd_addr for all type 5 LSA + 2) R2: Configure: area 1 nssa suppress-fa + 3) R1: Get a dict[LSA_ID] and compare fwd_address with 0.0.0.0 + +test_ospf_unset_suppress_fa() + 4) R2: Configure: no area 1 nssa suppress-fa + 5) R1: Get a dict[LSA_ID] = fwd_addr and compare it with the dict obtained in 1) +""" + +import os +import sys +import re +import pytest + +# Save the Current Working Directory to find configuration files. +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 + +# Required to instantiate the topology builder class. +from mininet.topo import Topo + + +class NetworkTopo(Topo): + "OSPF topology builder" + + def build(self, *_args, **_opts): + "Build function" + + tgen = get_topogen(self) + + # Create routers + for router in range(1, 4): + tgen.add_router("r{}".format(router)) + + # R1-R2 backbone area + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + # R2-R3 NSSA area + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(NetworkTopo, mod.__name__) + tgen.start_topology() + + # This is a sample of configuration loading. + router_list = tgen.routers() + + # For all registred routers, load the zebra and ospf configuration file + for rname, router in router_list.items(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) + ) + + tgen.start_router() + +def teardown_module(_mod): + "Teardown the pytest environment" + + tgen = get_topogen() + tgen.stop_topology() + +def test_converge_protocols(): + "Wait for protocol convergence" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + topotest.sleep(10, "Waiting for OSPF convergence") + +def ospf_configure_suppress_fa(router_name, area): + "Configure OSPF suppress-fa in router_name" + + tgen = get_topogen() + router = tgen.gears[router_name] + router.vtysh_cmd("conf t\nrouter ospf\narea {} nssa suppress-fa\nexit\n".format(area)) + +def ospf_unconfigure_suppress_fa(router_name, area): + "Remove OSPF suppress-fa in router_name" + + tgen = get_topogen() + router = tgen.gears[router_name] + router.vtysh_cmd("conf t\nrouter ospf\nno area {} nssa suppress-fa\nexit\n".format(area)) + +def ospf_get_lsa_type5(router_name): + "Return a dict with link state id as key and forwarding addresses as value" + + result = dict() + tgen = get_topogen() + router = tgen.gears[router_name] + cmd = "show ip ospf database external\n" + output = topotest.normalize_text(router.vtysh_cmd(cmd)) + for line in output.splitlines(): + re0 = re.match(r"\s+Link State ID: (\S+) \(External Network Number\)", line) + if re0: + lsa = re0.group(1) + re1 = re.match(r"\s+Forward Address: (\S+)", line) + if re1: + result[lsa] = re1.group(1) + return result + +@pytest.fixture(scope='module', name='original') +def test_ospf_set_suppress_fa(): + "Test OSPF area [x] nssa suppress-fa" + + # Get current forwarding address for each LSA type-5 in r1 + initial = ospf_get_lsa_type5("r1") + + # Configure suppres-fa in r2 area 1 + ospf_configure_suppress_fa("r2", "1") + topotest.sleep(10, "Waiting for OSPF convergence") + + # Check forwarding address on r1 for all statics is 0.0.0.0 + assertmsg = "Forwarding address is not 0.0.0.0 after enabling OSPF suppress-fa" + suppress = ospf_get_lsa_type5("r1") + for prefix in suppress: + assert suppress[prefix] == "0.0.0.0", assertmsg + + # Return the original forwarding addresses so we can compare them + # in the test_ospf_unset_supress_fa + return initial + +def test_ospf_unset_supress_fa(original): + "Test OSPF no area [x] nssa suppress-fa" + + # Remove suppress-fa in r2 area 1 + ospf_unconfigure_suppress_fa("r2", "1") + topotest.sleep(10, "Waiting for OSPF convergence") + + # Check forwarding address is the original value on r1 for all statics + assertmsg = "Forwarding address is not correct after removing OSPF suppress-fa" + restore = ospf_get_lsa_type5("r1") + for prefix in restore: + assert restore[prefix] == original[prefix], assertmsg + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in index 3dbc6a1b43..2d925dbac3 100644 --- a/tools/frrcommon.sh.in +++ b/tools/frrcommon.sh.in @@ -149,6 +149,10 @@ daemon_prep() { daemon_start() { local dmninst daemon inst args instopt wrap bin + + all=false + [ "$1" = "--all" ] && { all=true; shift; } + daemon_inst "$1" ulimit -n $MAX_FDS > /dev/null 2> /dev/null @@ -165,7 +169,11 @@ daemon_start() { if eval "$all_wrap $wrap $bin $nsopt -d $frr_global_options $instopt $args"; then log_success_msg "Started $dmninst" - vtysh_b "$daemon" + if $all; then + debug "Skipping startup of vtysh until all have started" + else + vtysh_b "$daemon" + fi else log_failure_msg "Failed to start $dmninst!" fi @@ -237,8 +245,9 @@ print_status() { all_start() { daemon_list daemons for dmninst in $daemons; do - daemon_start "$dmninst" + daemon_start --all "$dmninst" done + vtysh_b } all_stop() { diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index f4f489c3dd..775611b3e3 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -40,8 +40,8 @@ #define VRRP_LOGPFX "[CORE] " -DEFINE_MTYPE_STATIC(VRRPD, VRRP_IP, "VRRP IP address") -DEFINE_MTYPE_STATIC(VRRPD, VRRP_RTR, "VRRP Router") +DEFINE_MTYPE_STATIC(VRRPD, VRRP_IP, "VRRP IP address"); +DEFINE_MTYPE_STATIC(VRRPD, VRRP_RTR, "VRRP Router"); /* statics */ struct hash *vrrp_vrouters_hash; diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h index 502d7b82b6..c181c2159b 100644 --- a/vrrpd/vrrp.h +++ b/vrrpd/vrrp.h @@ -58,7 +58,7 @@ /* User compatibility constant */ #define CS2MS 10 -DECLARE_MGROUP(VRRPD) +DECLARE_MGROUP(VRRPD); /* Northbound */ extern const struct frr_yang_module_info frr_vrrpd_info; diff --git a/vrrpd/vrrp_main.c b/vrrpd/vrrp_main.c index 94f10757a2..a5ad37aa0c 100644 --- a/vrrpd/vrrp_main.c +++ b/vrrpd/vrrp_main.c @@ -40,7 +40,7 @@ #include "vrrp_vty.h" #include "vrrp_zebra.h" -DEFINE_MGROUP(VRRPD, "vrrpd") +DEFINE_MGROUP(VRRPD, "vrrpd"); char backup_config_file[256]; @@ -128,7 +128,7 @@ FRR_DAEMON_INFO(vrrpd, VRRP, .vty_port = VRRP_VTY_PORT, .privs = &vrrp_privs, .yang_modules = vrrp_yang_modules, .n_yang_modules = array_size(vrrp_yang_modules), -) +); int main(int argc, char **argv, char **envp) { diff --git a/vrrpd/vrrp_packet.c b/vrrpd/vrrp_packet.c index 3cb13bd71b..991c030196 100644 --- a/vrrpd/vrrp_packet.c +++ b/vrrpd/vrrp_packet.c @@ -30,7 +30,7 @@ #include "vrrp_debug.h" #include "vrrp_packet.h" -DEFINE_MTYPE_STATIC(VRRPD, VRRP_PKT, "VRRP packet") +DEFINE_MTYPE_STATIC(VRRPD, VRRP_PKT, "VRRP packet"); /* clang-format off */ static const char *const vrrp_packet_names[16] = { diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 81c9770e55..4855c23f4b 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -42,7 +42,7 @@ sub scan_file { $cppadd = $fabricd ? "-DFABRICD=1" : ""; - open (FH, "@CPP@ -P -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ $cppadd $file |"); + open (FH, "@CPP@ -P -std=gnu11 -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ $cppadd $file |"); local $/; undef $/; $line = <FH>; if (!close (FH)) { diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 6e809a0713..62d9c255ad 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -48,7 +48,7 @@ #include "json.h" #include "ferr.h" -DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy") +DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy"); /* Struct VTY. */ struct vty *vty; @@ -2851,7 +2851,7 @@ DEFUN (vtysh_show_error_code, } /* Northbound. */ -DEFUN (show_config_running, +DEFUN_HIDDEN (show_config_running, show_config_running_cmd, "show configuration running\ [<json|xml> [translate WORD]]\ diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 20e1e1b0e9..7c8d9315e1 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -22,7 +22,7 @@ #define VTYSH_H #include "memory.h" -DECLARE_MGROUP(MVTYSH) +DECLARE_MGROUP(MVTYSH); #define VTYSH_ZEBRA 0x00001 #define VTYSH_RIPD 0x00002 diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 47f426b5e0..498d3e5f67 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -28,9 +28,9 @@ #include "vtysh/vtysh.h" #include "vtysh/vtysh_user.h" -DEFINE_MGROUP(MVTYSH, "vtysh") -DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG, "Vtysh configuration") -DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line") +DEFINE_MGROUP(MVTYSH, "vtysh"); +DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG, "Vtysh configuration"); +DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line"); vector configvec; @@ -91,9 +91,9 @@ static uint32_t config_hash(const struct config *c) return string_hash_make(c->name); } -DECLARE_LIST(config_master, struct config, rbt_item) +DECLARE_LIST(config_master, struct config, rbt_item); DECLARE_HASH(config_master_hash, struct config, hash_item, config_cmp, - config_hash) + config_hash); /* * The config_master_head is a list for order of receipt diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index 5f4d564507..faf1777d7f 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -61,8 +61,8 @@ #define PING_TOKEN "PING" -DEFINE_MGROUP(WATCHFRR, "watchfrr") -DEFINE_MTYPE_STATIC(WATCHFRR, WATCHFRR_DAEMON, "watchfrr daemon entry") +DEFINE_MGROUP(WATCHFRR, "watchfrr"); +DEFINE_MTYPE_STATIC(WATCHFRR, WATCHFRR_DAEMON, "watchfrr daemon entry"); /* Needs to be global, referenced somewhere inside libfrr. */ struct thread_master *master; @@ -1336,7 +1336,8 @@ FRR_DAEMON_INFO(watchfrr, WATCHFRR, .signals = watchfrr_signals, .n_signals = array_size(watchfrr_signals), - .privs = &watchfrr_privs, ) + .privs = &watchfrr_privs, +); #define DEPRECATED_OPTIONS "aAezR:" diff --git a/watchfrr/watchfrr.h b/watchfrr/watchfrr.h index ba6e94960f..4df1bf74af 100644 --- a/watchfrr/watchfrr.h +++ b/watchfrr/watchfrr.h @@ -23,7 +23,7 @@ #include "lib/memory.h" -DECLARE_MGROUP(WATCHFRR) +DECLARE_MGROUP(WATCHFRR); extern void watchfrr_vty_init(void); diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang index f959ff8be5..2070649ec2 100644 --- a/yang/frr-pim.yang +++ b/yang/frr-pim.yang @@ -294,6 +294,9 @@ module frr-pim { type uint8 { range "1..180"; } + must ". > ./../hello-interval" { + error-message "HoldTime must be greater than Hello"; + } description "Hello holdtime"; } diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 782e0a4b74..be2f7b5a68 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -597,6 +597,7 @@ module frr-zebra { grouping ribs { container ribs { + config false; description "RIBs supported by FRR."; list rib { @@ -617,7 +618,6 @@ module frr-zebra { list route { key "prefix"; - config false; leaf prefix { type inet:ip-prefix; description diff --git a/zebra/connected.c b/zebra/connected.c index dd8fab5e4e..6f405ca1bb 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -29,7 +29,6 @@ #include "table.h" #include "log.h" #include "memory.h" -#include "zebra_memory.h" #include "vty.h" #include "zebra/debug.h" diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 79a5d148a6..9abed77fa6 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -1517,4 +1517,4 @@ FRR_MODULE_SETUP( .version = "0.0.1", .description = "Data plane plugin for FPM using netlink.", .init = fpm_nl_init, - ) +); diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index 8bec256355..14d8ac442e 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -29,7 +29,6 @@ #include "ioctl.h" #include "connected.h" #include "memory.h" -#include "zebra_memory.h" #include "log.h" #include "vrf.h" #include "vty.h" diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 98bde4b3c0..af2c251607 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -44,7 +44,6 @@ #include "connected.h" #include "table.h" #include "memory.h" -#include "zebra_memory.h" #include "rib.h" #include "thread.h" #include "privs.h" diff --git a/zebra/if_sysctl.c b/zebra/if_sysctl.c index 695cef1995..38729c8d38 100644 --- a/zebra/if_sysctl.c +++ b/zebra/if_sysctl.c @@ -28,7 +28,6 @@ #include "prefix.h" #include "connected.h" #include "memory.h" -#include "zebra_memory.h" #include "ioctl.h" #include "log.h" #include "interface.h" diff --git a/zebra/interface.c b/zebra/interface.c index 6373b4b200..3eeed9ac90 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -28,7 +28,6 @@ #include "prefix.h" #include "command.h" #include "memory.h" -#include "zebra_memory.h" #include "ioctl.h" #include "connected.h" #include "log.h" @@ -53,14 +52,14 @@ #include "zebra/zebra_errors.h" #include "zebra/zebra_evpn_mh.h" -DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information") +DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information"); #define ZEBRA_PTM_SUPPORT DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp), - (vty, ifp)) + (vty, ifp)); DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp), - (vty, ifp)) + (vty, ifp)); static void if_down_del_nbr_connected(struct interface *ifp); diff --git a/zebra/interface.h b/zebra/interface.h index 64569742b4..67eb1176b9 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -417,9 +417,9 @@ struct zebra_if { }; DECLARE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp), - (vty, ifp)) + (vty, ifp)); DECLARE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp), - (vty, ifp)) + (vty, ifp)); #define IS_ZEBRA_IF_VRF(ifp) \ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VRF) diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 5352c6214d..28db2ad87d 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -34,7 +34,6 @@ #include "prefix.h" #include "command.h" #include "memory.h" -#include "zebra_memory.h" #include "stream.h" #include "ioctl.h" #include "connected.h" @@ -57,7 +56,7 @@ extern int irdp_sock; -DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data") +DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data"); #define IRDP_CONFIGED \ do { \ diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index 936206641f..600fc3f2fc 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -42,7 +42,6 @@ #include "prefix.h" #include "command.h" #include "memory.h" -#include "zebra_memory.h" #include "stream.h" #include "ioctl.h" #include "connected.h" @@ -349,4 +348,5 @@ static int irdp_module_init(void) } FRR_MODULE_SETUP(.name = "zebra_irdp", .version = FRR_VERSION, - .description = "zebra IRDP module", .init = irdp_module_init, ) + .description = "zebra IRDP module", .init = irdp_module_init, +); diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 6134df9c41..7d67c42a79 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -54,7 +54,6 @@ #include "zclient.h" #include "lib_errors.h" -#include "zebra_memory.h" #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index aa19b18089..e71e662458 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -29,7 +29,6 @@ #include "connected.h" #include "table.h" #include "memory.h" -#include "zebra_memory.h" #include "rib.h" #include "thread.h" #include "privs.h" @@ -159,7 +158,7 @@ extern uint32_t nl_rcvbufsize; extern struct zebra_privs_t zserv_privs; -DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers") +DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers"); size_t nl_batch_tx_bufsize; char *nl_batch_tx_buf; diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index adbdf54c1f..03884a9168 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -32,7 +32,6 @@ #include "sockunion.h" #include "connected.h" #include "memory.h" -#include "zebra_memory.h" #include "ioctl.h" #include "log.h" #include "table.h" diff --git a/zebra/main.c b/zebra/main.c index 55fd3244cb..09350f72c1 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -26,7 +26,6 @@ #include "thread.h" #include "filter.h" #include "memory.h" -#include "zebra_memory.h" #include "prefix.h" #include "log.h" #include "plist.h" @@ -274,7 +273,8 @@ FRR_DAEMON_INFO( .privs = &zserv_privs, .yang_modules = zebra_yang_modules, - .n_yang_modules = array_size(zebra_yang_modules), ) + .n_yang_modules = array_size(zebra_yang_modules), +); /* Main startup routine. */ int main(int argc, char **argv) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index ac60d09ecc..9e675011ee 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -41,7 +41,6 @@ #include "zebra/debug.h" #include "zebra/router-id.h" #include "zebra/zapi_msg.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_errors.h" diff --git a/zebra/rib.h b/zebra/rib.h index 86766b8175..e7676a1324 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -23,6 +23,7 @@ #define _ZEBRA_RIB_H #include "zebra.h" +#include "memory.h" #include "hook.h" #include "typesafe.h" #include "linklist.h" @@ -41,9 +42,13 @@ extern "C" { #endif +DECLARE_MGROUP(ZEBRA); + +DECLARE_MTYPE(RE); + enum rnh_type { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE }; -PREDECL_LIST(rnh_list) +PREDECL_LIST(rnh_list); /* Nexthop structure. */ struct rnh { @@ -82,7 +87,7 @@ struct rnh { #define DISTANCE_INFINITY 255 #define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */ -PREDECL_LIST(re_list) +PREDECL_LIST(re_list); struct opaque { uint16_t length; @@ -541,7 +546,7 @@ static inline void rib_tables_iter_cleanup(rib_tables_iter_t *iter) } DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason), - (rn, reason)) + (rn, reason)); /* * Access installed/fib nexthops, which may be a subset of the diff --git a/zebra/router-id.c b/zebra/router-id.c index ac21978ee8..3b556c92b5 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -29,7 +29,6 @@ #include "stream.h" #include "command.h" #include "memory.h" -#include "zebra_memory.h" #include "ioctl.h" #include "connected.h" #include "network.h" diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index fdeef2c88c..55e0775a8c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -41,7 +41,6 @@ #include "connected.h" #include "table.h" #include "memory.h" -#include "zebra_memory.h" #include "rib.h" #include "thread.h" #include "privs.h" diff --git a/zebra/rtadv.c b/zebra/rtadv.c index c3add16c56..8ffb3870fa 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -23,7 +23,6 @@ #include <zebra.h> #include "memory.h" -#include "zebra_memory.h" #include "sockopt.h" #include "thread.h" #include "if.h" @@ -54,7 +53,7 @@ extern struct zebra_privs_t zserv_privs; #include "zebra/rtadv_clippy.c" #endif -DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") +DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix"); #ifdef OPEN_BSD #include <netinet/icmp6.h> @@ -71,8 +70,8 @@ DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") #define ALLNODE "ff02::1" #define ALLROUTER "ff02::2" -DEFINE_MTYPE_STATIC(ZEBRA, RTADV_RDNSS, "Router Advertisement RDNSS") -DEFINE_MTYPE_STATIC(ZEBRA, RTADV_DNSSL, "Router Advertisement DNSSL") +DEFINE_MTYPE_STATIC(ZEBRA, RTADV_RDNSS, "Router Advertisement RDNSS"); +DEFINE_MTYPE_STATIC(ZEBRA, RTADV_DNSSL, "Router Advertisement DNSSL"); /* Order is intentional. Matches RFC4191. This array is also used for command matching, so only modify with care. */ diff --git a/zebra/rtread_sysctl.c b/zebra/rtread_sysctl.c index 01a97db8b3..74c6825ba1 100644 --- a/zebra/rtread_sysctl.c +++ b/zebra/rtread_sysctl.c @@ -24,7 +24,6 @@ #if !defined(GNU_LINUX) #include "memory.h" -#include "zebra_memory.h" #include "log.h" #include "vrf.h" diff --git a/zebra/sample_plugin.c b/zebra/sample_plugin.c index 464205f2f3..e54186bc18 100644 --- a/zebra/sample_plugin.c +++ b/zebra/sample_plugin.c @@ -130,4 +130,4 @@ FRR_MODULE_SETUP( .version = "0.0.1", .description = "Dataplane Sample Plugin", .init = module_init, - ) +); diff --git a/zebra/subdir.am b/zebra/subdir.am index f842a8c0f3..b5c26d720f 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -88,7 +88,6 @@ zebra_zebra_SOURCES = \ zebra/zebra_evpn_neigh.c \ zebra/zebra_mlag.c \ zebra/zebra_mlag_vty.c \ - zebra/zebra_memory.c \ zebra/zebra_mpls.c \ zebra/zebra_mpls_netlink.c \ zebra/zebra_mpls_openbsd.c \ @@ -158,7 +157,6 @@ noinst_HEADERS += \ zebra/zebra_evpn_vxlan.h \ zebra/zebra_fpm_private.h \ zebra/zebra_l2.h \ - zebra/zebra_memory.h \ zebra/zebra_mlag.h \ zebra/zebra_mlag_vty.h \ zebra/zebra_mpls.h \ @@ -193,7 +191,7 @@ zebra_zebra_irdp_la_SOURCES = \ zebra_zebra_irdp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_SOURCES = zebra/zebra_snmp.c -zebra_zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +zebra_zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 9f5adfa409..63ba6cd8d9 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -38,7 +38,6 @@ #include "zebra/zebra_router.h" #include "zebra/rib.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/router-id.h" @@ -62,6 +61,8 @@ #include "zebra/zebra_opaque.h" #include "zebra/zebra_srte.h" +DEFINE_MTYPE_STATIC(ZEBRA, OPAQUE, "Opaque Data"); + static int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg); /* Encoding helpers -------------------------------------------------------- */ @@ -2076,6 +2077,11 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) } } +void zapi_opaque_free(struct opaque *opaque) +{ + XFREE(MTYPE_OPAQUE, opaque); +} + static void zread_route_del(ZAPI_HANDLER_ARGS) { struct stream *s; diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 023b9f74a8..ca471f8d98 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -111,6 +111,8 @@ extern int zsend_client_close_notify(struct zserv *client, int zsend_nhg_notify(uint16_t type, uint16_t instance, uint32_t session_id, uint32_t id, enum zapi_nhg_notify_owner note); +extern void zapi_opaque_free(struct opaque *opaque); + #ifdef __cplusplus } #endif diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 4e63d08aca..18fe0a7e85 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -28,7 +28,6 @@ #include "lib/memory.h" #include "lib/queue.h" #include "lib/zebra.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_router.h" #include "zebra/zebra_dplane.h" #include "zebra/zebra_vxlan_private.h" @@ -39,10 +38,10 @@ #include "printfrr.h" /* Memory type for context blocks */ -DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx") -DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf") -DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider") -DEFINE_MTYPE_STATIC(ZEBRA, DP_NETFILTER, "Zebra Netfilter Internal Object") +DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx"); +DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf"); +DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider"); +DEFINE_MTYPE_STATIC(ZEBRA, DP_NETFILTER, "Zebra Netfilter Internal Object"); #ifndef AOK # define AOK 0 diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 27a5a07e48..80e06d913d 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -44,7 +44,6 @@ #include "zebra/rt_netlink.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_l2.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index b36e8034b7..7bbe092d8c 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -34,7 +34,6 @@ #include "zebra/zserv.h" #include "zebra/debug.h" #include "zebra/zebra_router.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_evpn.h" diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 5a28ee10c6..1c258a04f7 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -41,7 +41,6 @@ #include "zebra/if_netlink.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_l2.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 0e31617c4f..d1b93dbe8a 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -34,7 +34,6 @@ #include "zebra/debug.h" #include "zebra/zebra_router.h" #include "zebra/rt.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_evpn.h" diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 099ac1434b..5fe8934a82 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -37,7 +37,6 @@ #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_errors.h" -#include "zebra/zebra_memory.h" #include "fpm/fpm.h" #include "zebra_fpm_private.h" @@ -2046,4 +2045,5 @@ static int zebra_fpm_module_init(void) FRR_MODULE_SETUP(.name = "zebra_fpm", .version = FRR_VERSION, .description = "zebra FPM (Forwarding Plane Manager) module", - .init = zebra_fpm_module_init, ) + .init = zebra_fpm_module_init, +); diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 3583c5fbf4..c3fbff2723 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -38,7 +38,6 @@ #include "zebra/zserv.h" #include "zebra/debug.h" #include "zebra/interface.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/rt_netlink.h" #include "zebra/interface.h" diff --git a/zebra/zebra_memory.c b/zebra/zebra_memory.c deleted file mode 100644 index 17b52a2bcb..0000000000 --- a/zebra/zebra_memory.c +++ /dev/null @@ -1,33 +0,0 @@ -/* zebra memory type definitions - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "zebra_memory.h" - -DEFINE_MGROUP(ZEBRA, "zebra") -DEFINE_MTYPE(ZEBRA, RE, "Route Entry") -DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination") -DEFINE_MTYPE(ZEBRA, ZVLAN, "VLAN") -DEFINE_MTYPE(ZEBRA, ZVLAN_BITMAP, "VLAN bitmap") -DEFINE_MTYPE(ZEBRA, OPAQUE, "Opaque Data") diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h deleted file mode 100644 index 71901b765f..0000000000 --- a/zebra/zebra_memory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* zebra memory type declarations - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * Quagga is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QUAGGA_ZEBRA_MEMORY_H -#define _QUAGGA_ZEBRA_MEMORY_H - -#include "memory.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DECLARE_MGROUP(ZEBRA) -DECLARE_MTYPE(ZEBRA_NS) -DECLARE_MTYPE(RE) -DECLARE_MTYPE(RIB_DEST) -DECLARE_MTYPE(OPAQUE) - -#ifdef __cplusplus -} -#endif - -#endif /* _QUAGGA_ZEBRA_MEMORY_H */ diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c index d8ed9b2a3a..3b0c75151b 100644 --- a/zebra/zebra_mlag.c +++ b/zebra/zebra_mlag.c @@ -29,7 +29,6 @@ #include "zebra/zebra_mlag.h" #include "zebra/zebra_mlag_vty.h" #include "zebra/zebra_router.h" -#include "zebra/zebra_memory.h" #include "zebra/zapi_msg.h" #include "zebra/debug.h" @@ -38,11 +37,11 @@ #endif DEFINE_HOOK(zebra_mlag_private_write_data, - (uint8_t *data, uint32_t len), (data, len)) -DEFINE_HOOK(zebra_mlag_private_monitor_state, (), ()) -DEFINE_HOOK(zebra_mlag_private_open_channel, (), ()) -DEFINE_HOOK(zebra_mlag_private_close_channel, (), ()) -DEFINE_HOOK(zebra_mlag_private_cleanup_data, (), ()) + (uint8_t *data, uint32_t len), (data, len)); +DEFINE_HOOK(zebra_mlag_private_monitor_state, (), ()); +DEFINE_HOOK(zebra_mlag_private_open_channel, (), ()); +DEFINE_HOOK(zebra_mlag_private_close_channel, (), ()); +DEFINE_HOOK(zebra_mlag_private_cleanup_data, (), ()); #define ZEBRA_MLAG_METADATA_LEN 4 #define ZEBRA_MLAG_MSG_BCAST 0xFFFFFFFF @@ -659,7 +658,7 @@ void zebra_mlag_terminate(void) #ifdef HAVE_PROTOBUF_VERSION_3 -DEFINE_MTYPE_STATIC(ZEBRA, MLAG_PBUF, "ZEBRA MLAG PROTOBUF") +DEFINE_MTYPE_STATIC(ZEBRA, MLAG_PBUF, "ZEBRA MLAG PROTOBUF"); int zebra_mlag_protobuf_encode_client_data(struct stream *s, uint32_t *msg_type) { diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h index b195c75ea3..eb96a57d30 100644 --- a/zebra/zebra_mlag.h +++ b/zebra/zebra_mlag.h @@ -34,11 +34,11 @@ extern "C" { #define ZEBRA_MLAG_LEN_SIZE 4 DECLARE_HOOK(zebra_mlag_private_write_data, - (uint8_t *data, uint32_t len), (data, len)) -DECLARE_HOOK(zebra_mlag_private_monitor_state, (), ()) -DECLARE_HOOK(zebra_mlag_private_open_channel, (), ()) -DECLARE_HOOK(zebra_mlag_private_close_channel, (), ()) -DECLARE_HOOK(zebra_mlag_private_cleanup_data, (), ()) + (uint8_t *data, uint32_t len), (data, len)); +DECLARE_HOOK(zebra_mlag_private_monitor_state, (), ()); +DECLARE_HOOK(zebra_mlag_private_open_channel, (), ()); +DECLARE_HOOK(zebra_mlag_private_close_channel, (), ()); +DECLARE_HOOK(zebra_mlag_private_cleanup_data, (), ()); extern uint8_t mlag_wr_buffer[ZEBRA_MLAG_BUF_LIMIT]; extern uint8_t mlag_rd_buffer[ZEBRA_MLAG_BUF_LIMIT]; diff --git a/zebra/zebra_mlag_private.c b/zebra/zebra_mlag_private.c index 8a66d6de72..aaf93b4dc1 100644 --- a/zebra/zebra_mlag_private.c +++ b/zebra/zebra_mlag_private.c @@ -297,4 +297,4 @@ FRR_MODULE_SETUP( .version = FRR_VERSION, .description = "zebra Cumulus MLAG interface", .init = zebra_mlag_module_init, -) +); diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index dc49695019..c0c064cbc7 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -44,15 +44,14 @@ #include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/debug.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_srte.h" #include "zebra/zebra_errors.h" -DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") -DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object") -DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object") +DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object"); +DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object"); +DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object"); int mpls_enabled; diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index 1fc1faff67..bdeb84486d 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -401,14 +401,24 @@ const struct frr_yang_module_info frr_zebra_info = { { .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib", .cbs = { - .create = lib_vrf_zebra_ribs_rib_create, - .destroy = lib_vrf_zebra_ribs_rib_destroy, .get_next = lib_vrf_zebra_ribs_rib_get_next, .get_keys = lib_vrf_zebra_ribs_rib_get_keys, .lookup_entry = lib_vrf_zebra_ribs_rib_lookup_entry, } }, { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/afi-safi-name", + .cbs = { + .get_elem = lib_vrf_zebra_ribs_rib_afi_safi_name_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/table-id", + .cbs = { + .get_elem = lib_vrf_zebra_ribs_rib_table_id_get_elem, + } + }, + { .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route", .cbs = { .get_next = lib_vrf_zebra_ribs_rib_route_get_next, diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index e68b819767..79632dc83e 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -149,12 +149,14 @@ struct yang_data *lib_interface_zebra_state_remote_vtep_get_elem( struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_zebra_state_mcast_group_get_elem( struct nb_cb_get_elem_args *args); -int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args); -int lib_vrf_zebra_ribs_rib_destroy(struct nb_cb_destroy_args *args); const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args); int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args); const void * lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_zebra_ribs_rib_afi_safi_name_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_zebra_ribs_rib_table_id_get_elem(struct nb_cb_get_elem_args *args); const void * lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args); int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args); @@ -201,19 +203,6 @@ lib_vrf_zebra_ribs_rib_route_nexthop_group_frr_nexthops_nexthop_get_next( struct nb_cb_get_next_args *args); int lib_vrf_zebra_ribs_rib_route_nexthop_group_frr_nexthops_nexthop_get_keys( struct nb_cb_get_keys_args *args); -int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args); -int lib_vrf_zebra_ribs_rib_destroy(struct nb_cb_destroy_args *args); -const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args); -int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args); -const void * -lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args); -const void * -lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args); -int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args); -const void * -lib_vrf_zebra_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args); -struct yang_data * -lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args); const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next( struct nb_cb_get_next_args *args); int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys( diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index ea2e20ed3b..ba9f96b7de 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -841,7 +841,6 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) struct interface *ifp; struct prefix prefix; - ifp = nb_running_get_entry(args->dnode, NULL, true); // addr_family = yang_dnode_get_enum(dnode, "./address-family"); yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix"); apply_mask(&prefix); @@ -864,6 +863,7 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) case NB_EV_ABORT: break; case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); if (prefix.family == AF_INET) if_ip_address_install(ifp, &prefix, NULL, NULL); else if (prefix.family == AF_INET6) @@ -881,12 +881,15 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) struct prefix prefix; struct connected *ifc; - ifp = nb_running_get_entry(args->dnode, NULL, true); yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix"); apply_mask(&prefix); switch (args->event) { case NB_EV_VALIDATE: + ifp = nb_running_get_entry(args->dnode, NULL, false); + if (!ifp) + return NB_OK; + if (prefix.family == AF_INET) { /* Check current interface address. */ ifc = connected_check_ptp(ifp, &prefix, NULL); @@ -927,6 +930,7 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) case NB_EV_ABORT: break; case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); if_ip_address_uinstall(ifp, &prefix); break; } @@ -1068,6 +1072,9 @@ int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args) */ int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args) { + if (args->event != NB_EV_APPLY) + return NB_OK; + struct interface *ifp; ifp = nb_running_get_entry(args->dnode, NULL, true); @@ -1079,6 +1086,9 @@ int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args) int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args) { + if (args->event != NB_EV_APPLY) + return NB_OK; + struct interface *ifp; ifp = nb_running_get_entry(args->dnode, NULL, true); @@ -1130,61 +1140,6 @@ int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib - */ -int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args) -{ - struct vrf *vrf; - afi_t afi; - safi_t safi; - struct zebra_vrf *zvrf; - struct zebra_router_table *zrt; - uint32_t table_id; - const char *afi_safi_name; - - vrf = nb_running_get_entry(args->dnode, NULL, false); - zvrf = vrf_info_lookup(vrf->vrf_id); - table_id = yang_dnode_get_uint32(args->dnode, "./table-id"); - if (!table_id) - table_id = zvrf->table_id; - - afi_safi_name = yang_dnode_get_string(args->dnode, "./afi-safi-name"); - yang_afi_safi_identity2value(afi_safi_name, &afi, &safi); - - zrt = zebra_router_find_zrt(zvrf, table_id, afi, safi); - - switch (args->event) { - case NB_EV_VALIDATE: - if (!zrt) { - snprintf(args->errmsg, args->errmsg_len, - "vrf %s table is not found.", vrf->name); - return NB_ERR_VALIDATION; - } - break; - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - - nb_running_set_entry(args->dnode, zrt); - - break; - } - - return NB_OK; -} - -int lib_vrf_zebra_ribs_rib_destroy(struct nb_cb_destroy_args *args) -{ - if (args->event != NB_EV_APPLY) - return NB_OK; - - nb_running_unset_entry(args->dnode); - - return NB_OK; -} - -/* * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id */ int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 21c89f64ed..a9cb096aee 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -214,6 +214,29 @@ lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args) } /* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/afi-safi-name + */ +struct yang_data * +lib_vrf_zebra_ribs_rib_afi_safi_name_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct zebra_router_table *zrt = args->list_entry; + + return yang_data_new_string(args->xpath, + yang_afi_safi_value2identity(zrt->afi, zrt->safi)); +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/table-id + */ +struct yang_data * +lib_vrf_zebra_ribs_rib_table_id_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct zebra_router_table *zrt = args->list_entry; + + return yang_data_new_uint32(args->xpath, zrt->tableid); +} + +/* * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route */ const void * diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index ee2dc7a0ed..3e89df68fd 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -37,7 +37,6 @@ #include "lib_errors.h" #include "zebra_router.h" -#include "zebra_memory.h" #endif /* defined(HAVE_NETLINK) */ #include "zebra_netns_notify.h" @@ -53,7 +52,7 @@ #define ZEBRA_NS_POLLING_INTERVAL_MSEC 1000 #define ZEBRA_NS_POLLING_MAX_RETRIES 200 -DEFINE_MTYPE_STATIC(ZEBRA, NETNS_MISC, "ZebraNetNSInfo") +DEFINE_MTYPE_STATIC(ZEBRA, NETNS_MISC, "ZebraNetNSInfo"); static struct thread *zebra_netns_notify_current; struct zebra_netns_info { diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 9246283fdf..12ed024a66 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -36,7 +36,6 @@ #include "zebra/zebra_nhg_private.h" #include "zebra/zebra_rnh.h" #include "zebra/zebra_routemap.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_srte.h" #include "zebra/zserv.h" #include "zebra/rt.h" diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index e9ff3fcc08..27b8a3ea47 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -28,7 +28,6 @@ #include "zebra_ns.h" #include "zebra_vrf.h" -#include "zebra_memory.h" #include "rt.h" #include "zebra_vxlan.h" #include "debug.h" @@ -41,7 +40,7 @@ extern struct zebra_privs_t zserv_privs; -DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") +DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_NS, "Zebra Name Space"); static struct zebra_ns *dzns; diff --git a/zebra/zebra_opaque.c b/zebra/zebra_opaque.c index 1d59e0ab34..244f16302b 100644 --- a/zebra/zebra_opaque.c +++ b/zebra/zebra_opaque.c @@ -24,7 +24,6 @@ #include "lib/stream.h" #include "zebra/debug.h" #include "zebra/zserv.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_opaque.h" /* Mem type */ diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 92a7a0ba3a..c4004842e6 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -30,12 +30,11 @@ #include "zebra/zebra_pbr.h" #include "zebra/rt.h" #include "zebra/zapi_msg.h" -#include "zebra/zebra_memory.h" #include "zebra/zserv.h" #include "zebra/debug.h" /* definitions */ -DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list") +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list"); /* definitions */ static const struct message ipset_type_msg[] = { @@ -128,12 +127,12 @@ static const struct message fragment_value_str[] = { DEFINE_HOOK(zebra_pbr_ipset_entry_get_stat, (struct zebra_pbr_ipset_entry *ipset, uint64_t *pkts, uint64_t *bytes), - (ipset, pkts, bytes)) + (ipset, pkts, bytes)); DEFINE_HOOK(zebra_pbr_iptable_get_stat, (struct zebra_pbr_iptable *iptable, uint64_t *pkts, uint64_t *bytes), - (iptable, pkts, bytes)) + (iptable, pkts, bytes)); DEFINE_HOOK(zebra_pbr_iptable_update, (int cmd, struct zebra_pbr_iptable *iptable), (cmd, iptable)); diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index ef93033661..2e9658e7e5 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -249,11 +249,11 @@ size_t zebra_pbr_tcpflags_snprintf(char *buffer, size_t len, DECLARE_HOOK(zebra_pbr_ipset_entry_get_stat, (struct zebra_pbr_ipset_entry *ipset, uint64_t *pkts, uint64_t *bytes), - (ipset, pkts, bytes)) + (ipset, pkts, bytes)); DECLARE_HOOK(zebra_pbr_iptable_get_stat, (struct zebra_pbr_iptable *iptable, uint64_t *pkts, uint64_t *bytes), - (iptable, pkts, bytes)) + (iptable, pkts, bytes)); DECLARE_HOOK(zebra_pbr_iptable_update, (int cmd, struct zebra_pbr_iptable *iptable), (cmd, iptable)); diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 1e7b38086b..bea855d1af 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -1167,8 +1167,6 @@ void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp) #else /* HAVE_BFDD */ -#include "zebra/zebra_memory.h" - /* * Data structures. */ diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c index eabc2e005e..537d69fbca 100644 --- a/zebra/zebra_ptm_redistribute.c +++ b/zebra/zebra_ptm_redistribute.c @@ -26,7 +26,6 @@ #include "zebra/zapi_msg.h" #include "zebra/zebra_ptm.h" #include "zebra/zebra_ptm_redistribute.h" -#include "zebra/zebra_memory.h" static int zsend_interface_bfd_update(int cmd, struct zserv *client, struct interface *ifp, struct prefix *dp, diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index ecae021dba..5afb3e5926 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -35,12 +35,12 @@ #include "zebra/zebra_vrf.h" #include "zebra/zebra_pw.h" -DEFINE_MTYPE_STATIC(LIB, PW, "Pseudowire") +DEFINE_MTYPE_STATIC(LIB, PW, "Pseudowire"); -DEFINE_QOBJ_TYPE(zebra_pw) +DEFINE_QOBJ_TYPE(zebra_pw); -DEFINE_HOOK(pw_install, (struct zebra_pw * pw), (pw)) -DEFINE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)) +DEFINE_HOOK(pw_install, (struct zebra_pw * pw), (pw)); +DEFINE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)); #define MPLS_NO_LABEL MPLS_INVALID_LABEL diff --git a/zebra/zebra_pw.h b/zebra/zebra_pw.h index 7b13c7e16b..0da8203802 100644 --- a/zebra/zebra_pw.h +++ b/zebra/zebra_pw.h @@ -53,9 +53,9 @@ struct zebra_pw { struct zserv *client; struct rnh *rnh; struct thread *install_retry_timer; - QOBJ_FIELDS + QOBJ_FIELDS; }; -DECLARE_QOBJ_TYPE(zebra_pw) +DECLARE_QOBJ_TYPE(zebra_pw); RB_HEAD(zebra_pw_head, zebra_pw); RB_PROTOTYPE(zebra_pw_head, zebra_pw, pw_entry, zebra_pw_compare); @@ -63,8 +63,8 @@ RB_PROTOTYPE(zebra_pw_head, zebra_pw, pw_entry, zebra_pw_compare); RB_HEAD(zebra_static_pw_head, zebra_pw); RB_PROTOTYPE(zebra_static_pw_head, zebra_pw, static_pw_entry, zebra_pw_compare); -DECLARE_HOOK(pw_install, (struct zebra_pw * pw), (pw)) -DECLARE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)) +DECLARE_HOOK(pw_install, (struct zebra_pw * pw), (pw)); +DECLARE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)); struct zebra_pw *zebra_pw_add(struct zebra_vrf *zvrf, const char *ifname, uint8_t protocol, struct zserv *client); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index bc3c68638d..ffe4be8557 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -49,7 +49,6 @@ #include "zebra/rt.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_errors.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_rnh.h" #include "zebra/zebra_routemap.h" @@ -58,6 +57,10 @@ #include "zebra/zapi_msg.h" #include "zebra/zebra_dplane.h" +DEFINE_MGROUP(ZEBRA, "zebra"); + +DEFINE_MTYPE(ZEBRA, RE, "Route Entry"); +DEFINE_MTYPE_STATIC(ZEBRA, RIB_DEST, "RIB destination"); DEFINE_MTYPE_STATIC(ZEBRA, RIB_UPDATE_CTX, "Rib update context object"); /* @@ -68,7 +71,7 @@ static struct thread *t_dplane; static struct dplane_ctx_q rib_dplane_q; DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), - (rn, reason)) + (rn, reason)); /* Should we allow non Quagga processes to delete our routes */ extern int allow_delete; @@ -800,6 +803,23 @@ int rib_gc_dest(struct route_node *rn) return 1; } +void zebra_rtable_node_cleanup(struct route_table *table, + struct route_node *node) +{ + struct route_entry *re, *next; + + RNODE_FOREACH_RE_SAFE (node, re, next) { + rib_unlink(node, re); + } + + if (node->info) { + rib_dest_t *dest = node->info; + + rnh_list_fini(&dest->nht); + XFREE(MTYPE_RIB_DEST, node->info); + } +} + static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *new) { @@ -2698,7 +2718,7 @@ void rib_unlink(struct route_node *rn, struct route_entry *re) nexthops_free(re->fib_ng.nexthop); - XFREE(MTYPE_OPAQUE, re->opaque); + zapi_opaque_free(re->opaque); XFREE(MTYPE_RE, re); } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 48e2bafe44..3b0ef71987 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -48,10 +48,9 @@ #include "zebra/zebra_routemap.h" #include "zebra/zebra_srte.h" #include "zebra/interface.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_errors.h" -DEFINE_MTYPE_STATIC(ZEBRA, RNH, "Nexthop tracking object") +DEFINE_MTYPE_STATIC(ZEBRA, RNH, "Nexthop tracking object"); static void free_state(vrf_id_t vrf_id, struct route_entry *re, struct route_node *rn); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 17a9bf97f9..c9660c7309 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -21,7 +21,6 @@ #include <zebra.h> #include "memory.h" -#include "zebra_memory.h" #include "prefix.h" #include "rib.h" #include "vty.h" diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 249ec38a69..5a00f3155d 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -25,14 +25,14 @@ #include "lib/frratomic.h" #include "zebra_router.h" -#include "zebra_memory.h" #include "zebra_pbr.h" #include "zebra_vxlan.h" #include "zebra_mlag.h" #include "zebra_nhg.h" #include "debug.h" -DEFINE_MTYPE_STATIC(ZEBRA, RIB_TABLE_INFO, "RIB table info") +DEFINE_MTYPE_STATIC(ZEBRA, RIB_TABLE_INFO, "RIB table info"); +DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_RT_TABLE, "Zebra VRF table"); struct zebra_router zrouter = { .multipath_num = MULTIPATH_NUM, @@ -121,7 +121,7 @@ struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, if (zrt) return zrt->table; - zrt = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*zrt)); + zrt = XCALLOC(MTYPE_ZEBRA_RT_TABLE, sizeof(*zrt)); zrt->tableid = tableid; zrt->afi = afi; zrt->safi = safi; @@ -185,7 +185,7 @@ static void zebra_router_free_table(struct zebra_router_table *zrt) RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt); XFREE(MTYPE_RIB_TABLE_INFO, table_info); - XFREE(MTYPE_ZEBRA_NS, zrt); + XFREE(MTYPE_ZEBRA_RT_TABLE, zrt); } void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid, diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 89b8238c29..3e08d83724 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -566,4 +566,5 @@ static int zebra_snmp_module_init(void) FRR_MODULE_SETUP(.name = "zebra_snmp", .version = FRR_VERSION, .description = "zebra AgentX SNMP module", - .init = zebra_snmp_module_init, ) + .init = zebra_snmp_module_init, +); diff --git a/zebra/zebra_srte.c b/zebra/zebra_srte.c index d6043534e3..98158ecc12 100644 --- a/zebra/zebra_srte.c +++ b/zebra/zebra_srte.c @@ -24,12 +24,11 @@ #include "lib/lib_errors.h" #include "zebra/zebra_srte.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_rnh.h" #include "zebra/zapi_msg.h" -DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_SR_POLICY, "SR Policy") +DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_SR_POLICY, "SR Policy"); static void zebra_sr_policy_deactivate(struct zebra_sr_policy *policy); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index be4fb29aae..b42923640f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -36,7 +36,6 @@ #include "zebra/zebra_vrf.h" #include "zebra/zebra_rnh.h" #include "zebra/router-id.h" -#include "zebra/zebra_memory.h" #include "zebra/interface.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_vxlan.h" @@ -48,8 +47,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, static void zebra_rnhtable_node_cleanup(struct route_table *table, struct route_node *node); -DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_VRF, "ZEBRA VRF") -DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table") +DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_VRF, "ZEBRA VRF"); +DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table"); /* VRF information update. */ static void zebra_vrf_add_update(struct zebra_vrf *zvrf) @@ -413,23 +412,6 @@ done: return table; } -void zebra_rtable_node_cleanup(struct route_table *table, - struct route_node *node) -{ - struct route_entry *re, *next; - - RNODE_FOREACH_RE_SAFE (node, re, next) { - rib_unlink(node, re); - } - - if (node->info) { - rib_dest_t *dest = node->info; - - rnh_list_fini(&dest->nht); - XFREE(MTYPE_RIB_DEST, node->info); - } -} - static void zebra_rnhtable_node_cleanup(struct route_table *table, struct route_node *node) { diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 910d192317..ed6376b01f 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -238,7 +238,7 @@ zvrf_other_table_compare_func(const struct other_route_table *a, } DECLARE_RBTREE_UNIQ(otable, struct other_route_table, next, - zvrf_other_table_compare_func) + zvrf_other_table_compare_func); extern struct route_table * zebra_vrf_lookup_table_with_table_id(afi_t afi, safi_t safi, vrf_id_t vrf_id, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 3349c18204..283a3e52d6 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -21,7 +21,6 @@ #include <zebra.h> #include "memory.h" -#include "zebra_memory.h" #include "if.h" #include "prefix.h" #include "command.h" @@ -2565,10 +2564,8 @@ DEFUN (default_vrf_vni_mapping, "VNI-ID\n" "Prefix routes only \n") { - int ret = 0; - char err[ERR_STR_SZ]; + char xpath[XPATH_MAXLEN]; struct zebra_vrf *zvrf = NULL; - vni_t vni = strtoul(argv[1]->arg, NULL, 10); int filter = 0; zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -2578,25 +2575,35 @@ DEFUN (default_vrf_vni_mapping, if (argc == 3) filter = 1; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, - filter, 1); - if (ret != 0) { - vty_out(vty, "%s\n", err); - return CMD_WARNING; + snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + + snprintf(xpath, sizeof(xpath), + FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[1]->arg); + + if (filter) { + snprintf(xpath, sizeof(xpath), + FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true"); } - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } DEFUN (no_default_vrf_vni_mapping, no_default_vrf_vni_mapping_cmd, - "no vni " CMD_VNI_RANGE, + "no vni " CMD_VNI_RANGE "[prefix-routes-only]", NO_STR "VNI corresponding to DEFAULT VRF\n" - "VNI-ID") + "VNI-ID\n" + "Prefix routes only \n") { - int ret = 0; - char err[ERR_STR_SZ]; + char xpath[XPATH_MAXLEN]; + int filter = 0; vni_t vni = strtoul(argv[2]->arg, NULL, 10); struct zebra_vrf *zvrf = NULL; @@ -2604,13 +2611,32 @@ DEFUN (no_default_vrf_vni_mapping, if (!zvrf) return CMD_WARNING; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0); - if (ret != 0) { - vty_out(vty, "%s\n", err); + if (argc == 4) + filter = 1; + + if (zvrf->l3vni != vni) { + vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, + zvrf->vrf->name); return CMD_WARNING; } - return CMD_SUCCESS; + snprintf(xpath, sizeof(xpath), + FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, argv[2]->arg); + + if (filter) { + snprintf(xpath, sizeof(xpath), + FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, "true"); + } + + snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", + VRF_DEFAULT_NAME); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } DEFUN (vrf_vni_mapping, @@ -2638,9 +2664,7 @@ DEFUN (vrf_vni_mapping, nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", NB_OP_MODIFY, "true"); - nb_cli_apply_changes(vty, NULL); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } DEFUN (no_vrf_vni_mapping, @@ -2677,9 +2701,7 @@ DEFUN (no_vrf_vni_mapping, nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_DESTROY, NULL); - nb_cli_apply_changes(vty, NULL); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* show vrf */ diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index e5efbe0d4a..bc2eac7a0b 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -46,7 +46,6 @@ #include "zebra/rt_netlink.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_l2.h" -#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" @@ -65,7 +64,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, L3NEIGH, "EVPN Neighbor"); DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group"); DEFINE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni, - bool delete, const char *reason), (rmac, zl3vni, delete, reason)) + bool delete, const char *reason), (rmac, zl3vni, delete, reason)); /* static function declarations */ static void zevpn_print_neigh_hash_all_evpn(struct hash_bucket *bucket, diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index 4ec55542a7..0556c4adce 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -226,7 +226,7 @@ extern struct interface *zl3vni_map_to_mac_vlan_if(zebra_l3vni_t *zl3vni); extern zebra_l3vni_t *zl3vni_lookup(vni_t vni); DECLARE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni, - bool delete, const char *reason), (rmac, zl3vni, delete, reason)) + bool delete, const char *reason), (rmac, zl3vni, delete, reason)); #ifdef __cplusplus |
