diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bfd.c | 451 | ||||
| -rw-r--r-- | lib/bfd.h | 17 | ||||
| -rw-r--r-- | lib/command.h | 8 | ||||
| -rw-r--r-- | lib/elf_py.c | 2 | ||||
| -rw-r--r-- | lib/if.c | 3 | ||||
| -rw-r--r-- | lib/orr_msg.h | 94 | ||||
| -rw-r--r-- | lib/prefix.c | 2 | ||||
| -rw-r--r-- | lib/subdir.am | 1 | ||||
| -rw-r--r-- | lib/vrf.c | 3 | ||||
| -rw-r--r-- | lib/xref.h | 13 | ||||
| -rw-r--r-- | lib/zclient.h | 6 | ||||
| -rw-r--r-- | lib/zlog_5424.c | 7 |
12 files changed, 495 insertions, 112 deletions
@@ -29,11 +29,13 @@ #include "stream.h" #include "vrf.h" #include "zclient.h" +#include "libfrr.h" #include "table.h" #include "vty.h" #include "bfd.h" DEFINE_MTYPE_STATIC(LIB, BFD_INFO, "BFD info"); +DEFINE_MTYPE_STATIC(LIB, BFD_SOURCE, "BFD source cache"); /** * BFD protocol integration configuration. @@ -48,6 +50,29 @@ enum bfd_session_event { }; /** + * BFD source selection result cache. + * + * This structure will keep track of the result based on the destination + * prefix. When the result changes all related BFD sessions with automatic + * source will be updated. + */ +struct bfd_source_cache { + /** Address VRF belongs. */ + vrf_id_t vrf_id; + /** Destination network address. */ + struct prefix address; + /** Source selected. */ + struct prefix source; + /** Is the source address valid? */ + bool valid; + /** BFD sessions using this. */ + size_t refcount; + + SLIST_ENTRY(bfd_source_cache) entry; +}; +SLIST_HEAD(bfd_source_list, bfd_source_cache); + +/** * Data structure to do the necessary tricks to hide the BFD protocol * integration internals. */ @@ -82,6 +107,11 @@ struct bfd_session_params { /** BFD session installation state. */ bool installed; + /** Automatic source selection. */ + bool auto_source; + /** Currently selected source. */ + struct bfd_source_cache *source_cache; + /** Global BFD paramaters list. */ TAILQ_ENTRY(bfd_session_params) entry; }; @@ -92,11 +122,15 @@ struct bfd_sessions_global { * without code duplication among daemons. */ TAILQ_HEAD(bsplist, bfd_session_params) bsplist; + /** BFD automatic source selection cache. */ + struct bfd_source_list source_list; /** Pointer to FRR's event manager. */ struct thread_master *tm; /** Pointer to zebra client data structure. */ struct zclient *zc; + /** Zebra next hop tracking (NHT) client. */ + struct zclient *nht_zclient; /** Debugging state. */ bool debugging; @@ -111,6 +145,34 @@ static struct bfd_sessions_global bsglobal; static const struct in6_addr i6a_zero; /* + * Prototypes + */ +static void bfd_nht_zclient_connect(struct thread *thread); + +static void bfd_nht_zclient_connected(struct zclient *zclient); +static int bfd_nht_update(ZAPI_CALLBACK_ARGS); + +static void bfd_source_cache_get(struct bfd_session_params *session); +static void bfd_source_cache_put(struct bfd_session_params *session); + +static inline void +bfd_source_cache_register(const struct bfd_source_cache *source) +{ + zclient_send_rnh(bsglobal.nht_zclient, ZEBRA_NEXTHOP_REGISTER, + &source->address, SAFI_UNICAST, false, false, + source->vrf_id); +} + +static inline void +bfd_source_cache_unregister(const struct bfd_source_cache *source) +{ + zclient_send_rnh(bsglobal.nht_zclient, ZEBRA_NEXTHOP_UNREGISTER, + &source->address, SAFI_UNICAST, false, false, + source->vrf_id); +} + + +/* * bfd_get_peer_info - Extract the Peer information for which the BFD session * went down from the message sent from Zebra to clients. */ @@ -531,6 +593,8 @@ void bfd_sess_free(struct bfd_session_params **bsp) /* Remove from global list. */ TAILQ_REMOVE(&bsglobal.bsplist, (*bsp), entry); + bfd_source_cache_put(*bsp); + /* Free the memory and point to NULL. */ XFREE(MTYPE_BFD_INFO, (*bsp)); } @@ -565,6 +629,8 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); + /* Address changed so we must reapply auto source. */ + bfd_source_cache_put(bsp); bsp->args.family = AF_INET; @@ -578,6 +644,9 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, assert(dst); memcpy(&bsp->args.dst, dst, sizeof(struct in_addr)); + + if (bsp->auto_source) + bfd_source_cache_get(bsp); } void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, @@ -589,6 +658,8 @@ void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); + /* Address changed so we must reapply auto source. */ + bfd_source_cache_put(bsp); bsp->args.family = AF_INET6; @@ -600,6 +671,9 @@ void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, assert(dst); bsp->args.dst = *dst; + + if (bsp->auto_source) + bfd_source_cache_get(bsp); } void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname) @@ -646,8 +720,13 @@ 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); + /* Address changed so we must reapply auto source. */ + bfd_source_cache_put(bsp); bsp->args.vrf_id = vrf_id; + + if (bsp->auto_source) + bfd_source_cache_get(bsp); } void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t hops) @@ -677,6 +756,18 @@ void bfd_sess_set_timers(struct bfd_session_params *bsp, bsp->args.min_tx = min_tx; } +void bfd_sess_set_auto_source(struct bfd_session_params *bsp, bool enable) +{ + if (bsp->auto_source == enable) + return; + + bsp->auto_source = enable; + if (enable) + bfd_source_cache_get(bsp); + else + bfd_source_cache_put(bsp); +} + void bfd_sess_install(struct bfd_session_params *bsp) { bsp->lastev = BSE_INSTALL; @@ -746,6 +837,11 @@ void bfd_sess_timers(const struct bfd_session_params *bsp, *min_tx = bsp->args.min_tx; } +bool bfd_sess_auto_source(const struct bfd_session_params *bsp) +{ + return bsp->auto_source; +} + void bfd_sess_show(struct vty *vty, struct json_object *json, struct bfd_session_params *bsp) { @@ -950,10 +1046,51 @@ int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS) return 0; } +/** + * Frees all allocated resources and stops any activity. + * + * Must be called after every BFD session has been successfully + * unconfigured otherwise this function will `free()` any available + * session causing existing pointers to dangle. + * + * This is just a comment, in practice it will be called by the FRR + * library late finish hook. \see `bfd_protocol_integration_init`. + */ +static int bfd_protocol_integration_finish(void) +{ + if (bsglobal.zc == NULL) + return 0; + + while (!TAILQ_EMPTY(&bsglobal.bsplist)) { + struct bfd_session_params *session = + TAILQ_FIRST(&bsglobal.bsplist); + bfd_sess_free(&session); + } + + /* + * BFD source cache is linked to sessions, if all sessions are gone + * then the source cache must be empty. + */ + if (!SLIST_EMPTY(&bsglobal.source_list)) + zlog_warn("BFD integration source cache not empty"); + + zclient_stop(bsglobal.nht_zclient); + zclient_free(bsglobal.nht_zclient); + + return 0; +} + +static zclient_handler *const bfd_nht_handlers[] = { + [ZEBRA_NEXTHOP_UPDATE] = bfd_nht_update, +}; + void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm) { + struct zclient_options bfd_nht_options = zclient_options_default; + /* Initialize data structure. */ TAILQ_INIT(&bsglobal.bsplist); + SLIST_INIT(&bsglobal.source_list); /* Copy pointers. */ bsglobal.zc = zc; @@ -964,6 +1101,18 @@ void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm) /* Send the client registration */ bfd_client_sendmsg(zc, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT); + + /* Start NHT client (for automatic source decisions). */ + bsglobal.nht_zclient = + zclient_new(tm, &bfd_nht_options, bfd_nht_handlers, + array_size(bfd_nht_handlers)); + bsglobal.nht_zclient->sock = -1; + bsglobal.nht_zclient->privs = zc->privs; + bsglobal.nht_zclient->zebra_connected = bfd_nht_zclient_connected; + thread_add_timer(tm, bfd_nht_zclient_connect, bsglobal.nht_zclient, 1, + &bsglobal.nht_zclient->t_connect); + + hook_register(frr_fini, bfd_protocol_integration_finish); } void bfd_protocol_integration_set_debug(bool enable) @@ -985,3 +1134,305 @@ bool bfd_protocol_integration_shutting_down(void) { return bsglobal.shutting_down; } + +/* + * BFD automatic source selection + * + * This feature will use the next hop tracking (NHT) provided by zebra + * to find out the source address by looking at the output interface. + * + * When the interface address / routing table change we'll be notified + * and be able to update the source address accordingly. + * + * <daemon> zebra + * | + * +-----------------+ + * | BFD session set | + * | to auto source | + * +-----------------+ + * | + * \ +-----------------+ + * --------------> | Resolves | + * | destination | + * | address | + * +-----------------+ + * | + * +-----------------+ / + * | Sets resolved | <---------- + * | source address | + * +-----------------+ + */ +static bool +bfd_source_cache_session_match(const struct bfd_source_cache *source, + const struct bfd_session_params *session) +{ + const struct in_addr *address; + const struct in6_addr *address_v6; + + if (session->args.vrf_id != source->vrf_id) + return false; + if (session->args.family != source->address.family) + return false; + + switch (session->args.family) { + case AF_INET: + address = (const struct in_addr *)&session->args.dst; + if (address->s_addr != source->address.u.prefix4.s_addr) + return false; + break; + case AF_INET6: + address_v6 = &session->args.dst; + if (memcmp(address_v6, &source->address.u.prefix6, + sizeof(struct in6_addr))) + return false; + break; + default: + return false; + } + + return true; +} + +static struct bfd_source_cache * +bfd_source_cache_find(vrf_id_t vrf_id, const struct prefix *prefix) +{ + struct bfd_source_cache *source; + + SLIST_FOREACH (source, &bsglobal.source_list, entry) { + if (source->vrf_id != vrf_id) + continue; + if (!prefix_same(&source->address, prefix)) + continue; + + return source; + } + + return NULL; +} + +static void bfd_source_cache_get(struct bfd_session_params *session) +{ + struct bfd_source_cache *source; + struct prefix target = {}; + + switch (session->args.family) { + case AF_INET: + target.family = AF_INET; + target.prefixlen = IPV4_MAX_BITLEN; + memcpy(&target.u.prefix4, &session->args.dst, + sizeof(struct in_addr)); + break; + case AF_INET6: + target.family = AF_INET6; + target.prefixlen = IPV6_MAX_BITLEN; + memcpy(&target.u.prefix6, &session->args.dst, + sizeof(struct in6_addr)); + break; + default: + return; + } + + source = bfd_source_cache_find(session->args.vrf_id, &target); + if (source) { + if (session->source_cache == source) + return; + + bfd_source_cache_put(session); + session->source_cache = source; + source->refcount++; + return; + } + + source = XCALLOC(MTYPE_BFD_SOURCE, sizeof(*source)); + prefix_copy(&source->address, &target); + source->vrf_id = session->args.vrf_id; + SLIST_INSERT_HEAD(&bsglobal.source_list, source, entry); + + bfd_source_cache_put(session); + session->source_cache = source; + source->refcount = 1; + + bfd_source_cache_register(source); + + return; +} + +static void bfd_source_cache_put(struct bfd_session_params *session) +{ + if (session->source_cache == NULL) + return; + + session->source_cache->refcount--; + if (session->source_cache->refcount > 0) { + session->source_cache = NULL; + return; + } + + bfd_source_cache_unregister(session->source_cache); + SLIST_REMOVE(&bsglobal.source_list, session->source_cache, + bfd_source_cache, entry); + XFREE(MTYPE_BFD_SOURCE, session->source_cache); +} + +/** Updates BFD running session if source address has changed. */ +static void +bfd_source_cache_update_session(const struct bfd_source_cache *source, + struct bfd_session_params *session) +{ + const struct in_addr *address; + const struct in6_addr *address_v6; + + switch (session->args.family) { + case AF_INET: + address = (const struct in_addr *)&session->args.src; + if (memcmp(address, &source->source.u.prefix4, + sizeof(struct in_addr)) == 0) + return; + + _bfd_sess_remove(session); + memcpy(&session->args.src, &source->source.u.prefix4, + sizeof(struct in_addr)); + break; + case AF_INET6: + address_v6 = &session->args.src; + if (memcmp(address_v6, &source->source.u.prefix6, + sizeof(struct in6_addr)) == 0) + return; + + _bfd_sess_remove(session); + memcpy(&session->args.src, &source->source.u.prefix6, + sizeof(struct in6_addr)); + break; + default: + return; + } + + bfd_sess_install(session); +} + +static void +bfd_source_cache_update_sessions(const struct bfd_source_cache *source) +{ + struct bfd_session_params *session; + + if (!source->valid) + return; + + TAILQ_FOREACH (session, &bsglobal.bsplist, entry) { + if (!session->auto_source) + continue; + if (!bfd_source_cache_session_match(source, session)) + continue; + + bfd_source_cache_update_session(source, session); + } +} + +/** + * Try to translate next hop information into source address. + * + * \returns `true` if source changed otherwise `false`. + */ +static bool bfd_source_cache_update(struct bfd_source_cache *source, + const struct zapi_route *route) +{ + size_t nh_index; + + for (nh_index = 0; nh_index < route->nexthop_num; nh_index++) { + const struct zapi_nexthop *nh = &route->nexthops[nh_index]; + const struct interface *interface; + const struct connected *connected; + const struct listnode *node; + + interface = if_lookup_by_index(nh->ifindex, nh->vrf_id); + if (interface == NULL) { + zlog_err("next hop interface not found (index %d)", + nh->ifindex); + continue; + } + + for (ALL_LIST_ELEMENTS_RO(interface->connected, node, + connected)) { + if (source->address.family != + connected->address->family) + continue; + if (prefix_same(connected->address, &source->source)) + return false; + /* + * Skip link-local as it is only useful for single hop + * and in that case no source is specified usually. + */ + if (source->address.family == AF_INET6 && + IN6_IS_ADDR_LINKLOCAL( + &connected->address->u.prefix6)) + continue; + + prefix_copy(&source->source, connected->address); + source->valid = true; + return true; + } + } + + memset(&source->source, 0, sizeof(source->source)); + source->valid = false; + return false; +} + +static void bfd_nht_zclient_connect(struct thread *thread) +{ + struct zclient *zclient = THREAD_ARG(thread); + + if (bsglobal.debugging) + zlog_debug("BFD NHT zclient connection attempt"); + + if (zclient_start(zclient) == -1) { + if (bsglobal.debugging) + zlog_debug("BFD NHT zclient connection failed"); + + thread_add_timer(bsglobal.tm, bfd_nht_zclient_connect, zclient, + 3, &zclient->t_connect); + return; + } + + if (bsglobal.debugging) + zlog_debug("BFD NHT zclient connection succeeded"); +} + +static void bfd_nht_zclient_connected(struct zclient *zclient) +{ + struct bfd_source_cache *source; + + if (bsglobal.debugging) + zlog_debug("BFD NHT zclient connected"); + + SLIST_FOREACH (source, &bsglobal.source_list, entry) + bfd_source_cache_register(source); +} + +static int bfd_nht_update(ZAPI_CALLBACK_ARGS) +{ + struct bfd_source_cache *source; + struct zapi_route route; + struct prefix match; + + if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &route)) { + zlog_warn("BFD NHT update decode failure"); + return 0; + } + if (cmd != ZEBRA_NEXTHOP_UPDATE) + return 0; + + if (bsglobal.debugging) + zlog_debug("BFD NHT update for %pFX", &route.prefix); + + SLIST_FOREACH (source, &bsglobal.source_list, entry) { + if (source->vrf_id != route.vrf_id) + continue; + if (!prefix_same(&match, &source->address)) + continue; + if (bfd_source_cache_update(source, &route)) + bfd_source_cache_update_sessions(source); + } + + return 0; +} @@ -222,6 +222,18 @@ void bfd_sess_set_timers(struct bfd_session_params *bsp, uint32_t min_tx); /** + * Configures the automatic source selection for the BFD session. + * + * NOTE: + * Setting this configuration will override the IP source value set by + * `bfd_sess_set_ipv4_addrs` or `bfd_sess_set_ipv6_addrs`. + * + * \param bsp BFD session parameters + * \param enable BFD automatic source selection state. + */ +void bfd_sess_set_auto_source(struct bfd_session_params *bsp, bool enable); + +/** * Installs or updates the BFD session based on the saved session arguments. * * NOTE: @@ -331,6 +343,11 @@ void bfd_sess_timers(const struct bfd_session_params *bsp, uint32_t *min_tx); /** + * Gets the automatic source selection state. + */ +bool bfd_sess_auto_source(const struct bfd_session_params *bsp); + +/** * 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`. diff --git a/lib/command.h b/lib/command.h index 0f9715e81c..bce4fb9e1c 100644 --- a/lib/command.h +++ b/lib/command.h @@ -398,7 +398,6 @@ struct cmd_node { #define BGP_SOFT_IN_STR "Send route-refresh unless using 'soft-reconfiguration inbound'\n" #define BGP_SOFT_OUT_STR "Resend all outbound updates\n" #define BGP_SOFT_RSCLIENT_RIB_STR "Soft reconfig for rsclient RIB\n" -#define BGP_ORR_DEBUG "Enable Optimal Route Reflection Debugging logs\n" #define OSPF_STR "OSPF information\n" #define NEIGHBOR_STR "Specify neighbor router\n" #define DEBUG_STR "Debugging functions\n" @@ -497,6 +496,13 @@ struct cmd_node { #define ROLE_STR \ "Providing transit\nRoute server\nRS client\nUsing transit\nPublic/private peering\n" +/* BFD protocol integration strings. */ +#define BFD_INTEGRATION_STR "BFD monitoring\n" +#define BFD_INTEGRATION_MULTI_HOP_STR "Use BFD multi hop session\n" +#define BFD_INTEGRATION_SOURCE_STR "Use source for BFD session\n" +#define BFD_INTEGRATION_SOURCEV4_STR "Use IPv4 source for BFD session\n" +#define BFD_INTEGRATION_SOURCEV6_STR "Use IPv4 source for BFD session\n" + /* Prototypes. */ extern void install_node(struct cmd_node *node); extern void install_default(enum node_type); diff --git a/lib/elf_py.c b/lib/elf_py.c index 75d2d6007f..7c503cfb9d 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -293,7 +293,7 @@ static PyObject *elfreloc_getsection(PyObject *self, PyObject *args) if (!w->es) Py_RETURN_NONE; - if (w->symidx == 0) { + if (!w->symvalid || w->symidx == 0) { size_t idx = 0; Elf_Scn *scn; @@ -580,8 +580,7 @@ struct interface *if_get_vrf_loopback(vrf_id_t vrf_id) } /* Get interface by name if given name interface doesn't exist create - * one. - */ + one. */ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, const char *vrf_name) { diff --git a/lib/orr_msg.h b/lib/orr_msg.h deleted file mode 100644 index b0c4c48df8..0000000000 --- a/lib/orr_msg.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Structures common to BGP, OSPF and ISIS for BGP Optimal Route Reflection - * Copyright (C) 2021 Samsung R&D Institute India - Bangalore. - * Madhurilatha Kuruganti - * - * 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_ORR_MSG_H -#define _FRR_ORR_MSG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* REVISIT: Need to check if we can use zero length array */ -#define ORR_MAX_PREFIX 100 -#define ORR_GROUP_NAME_SIZE 32 - -struct orr_prefix_metric { - struct prefix prefix; - uint32_t metric; -}; - -/* BGP-IGP Register for IGP metric */ -struct orr_igp_metric_reg { - bool reg; - uint8_t proto; - safi_t safi; - struct prefix prefix; - char group_name[ORR_GROUP_NAME_SIZE]; -}; - -/* IGP-BGP message structures */ -struct orr_igp_metric_info { - /* IGP instance data. */ - uint8_t proto; - uint32_t instId; - - safi_t safi; - - /* Add or delete routes */ - bool add; - - /* IGP metric from Active Root. */ - struct prefix root; - uint32_t num_entries; - struct orr_prefix_metric nexthop[ORR_MAX_PREFIX]; -}; - -/* BGP ORR Root node */ -struct orr_root { - afi_t afi; - safi_t safi; - - char group_name[ORR_GROUP_NAME_SIZE]; - - /* MPLS_TE prefix and router ID */ - struct prefix prefix; - struct in_addr router_id; - - /* Advertising OSPF Router ID. */ - struct in_addr adv_router; - - /* BGP-ORR Received LSAs */ - struct ospf_lsa *router_lsa_rcvd; - - /* Routing tables from root node */ - struct route_table *old_table; /* Old routing table. */ - struct route_table *new_table; /* Current routing table. */ - - struct route_table *old_rtrs; /* Old ABR/ASBR RT. */ - struct route_table *new_rtrs; /* New ABR/ASBR RT. */ -}; - -/* Prototypes. */ - -#ifdef __cplusplus -} -#endif - -#endif /* _FRR_ORR_MSG_H */ diff --git a/lib/prefix.c b/lib/prefix.c index 4642f14d35..1d098f78c5 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1489,7 +1489,7 @@ static ssize_t printfrr_ia(struct fbuf *buf, struct printfrr_eargs *ea, ea->fmt++; } - if (!ipa) + if (!ipa || !ipa->ipa_type) return bputs(buf, "(null)"); if (use_star) { diff --git a/lib/subdir.am b/lib/subdir.am index 1a8c184823..754a7da638 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -225,7 +225,6 @@ pkginclude_HEADERS += \ lib/ns.h \ lib/openbsd-queue.h \ lib/openbsd-tree.h \ - lib/orr_msg.h \ lib/plist.h \ lib/prefix.h \ lib/printfrr.h \ @@ -1000,8 +1000,7 @@ lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args *args) struct vrf *vrfp = (struct vrf *)args->list_entry; if (vrfp->status == VRF_ACTIVE) - return yang_data_new_bool( - args->xpath, vrfp->status == VRF_ACTIVE ? true : false); + return yang_data_new_bool(args->xpath, true); return NULL; } diff --git a/lib/xref.h b/lib/xref.h index 0e3f00f690..37242bd79e 100644 --- a/lib/xref.h +++ b/lib/xref.h @@ -208,8 +208,19 @@ extern const struct xref * const __stop_xref_array[1] DSO_LOCAL; * some build issue with it just add -DFRR_XREF_NO_NOTE to your build flags * to disable it. */ -#ifdef FRR_XREF_NO_NOTE +#if defined(FRR_XREF_NO_NOTE) || defined(__mips64) #define XREF_NOTE "" + +/* mips64 note: MIPS64 (regardless of endianness, both mips64 & mips64el) + * does not have a 64-bit PC-relative relocation type. Unfortunately, a + * 64-bit PC-relative relocation is exactly what the below asm magic emits. + * Therefore, the xref ELF note is permanently disabled on MIPS64. + * + * For some context, refer to https://reviews.llvm.org/D80390 + * + * As noted above, xref extraction still works through the section header + * path, so no functionality is lost. + */ #else #if __SIZEOF_POINTER__ == 4 diff --git a/lib/zclient.h b/lib/zclient.h index 584a42194d..8c4ce1b777 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -102,8 +102,6 @@ enum zserv_client_capabilities { extern struct sockaddr_storage zclient_addr; extern socklen_t zclient_addr_len; -#define ZAPI_ORR_FLAG_UNICAST 0x01 - /* Zebra message types. */ typedef enum { ZEBRA_INTERFACE_ADD, @@ -1248,10 +1246,6 @@ enum zapi_opaque_registry { LDP_RLFA_UNREGISTER_ALL = 8, /* Announce LDP labels associated to a previously registered RLFA */ LDP_RLFA_LABELS = 9, - /* Register for IGP METRIC with OSPF/ISIS */ - ORR_IGP_METRIC_REGISTER = 10, - /* Send SPF data to BGP */ - ORR_IGP_METRIC_UPDATE = 11 }; /* Send the hello message. diff --git a/lib/zlog_5424.c b/lib/zlog_5424.c index 9da7c55fc5..60feca7fcb 100644 --- a/lib/zlog_5424.c +++ b/lib/zlog_5424.c @@ -605,12 +605,13 @@ static void gmtime_assafe(time_t ts, struct tm *res) if (ts >= 306) /* Jan 1 of next year */ res->tm_year++; - static unsigned int months[13] = { + static time_t months[13] = { 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337, 365, }; + const size_t month_max = array_size(months) - 1; - for (size_t i = 0; i < array_size(months); i++) { - if ((unsigned int)ts < months[i + 1]) { + for (size_t i = 0; i < month_max; i++) { + if (ts < months[i + 1]) { res->tm_mon = ((i + 2) % 12); res->tm_mday = 1 + ts - months[i]; break; |
