]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #12969 from opensourcerouting/ospfd-nssa
authorRuss White <russ@riw.us>
Tue, 4 Apr 2023 13:38:55 +0000 (09:38 -0400)
committerGitHub <noreply@github.com>
Tue, 4 Apr 2023 13:38:55 +0000 (09:38 -0400)
ospfd: implement NSSA default routes & ranges

22 files changed:
babeld/babeld.c
babeld/babeld.h
babeld/util.h
bgpd/bgp_bfd.c
bgpd/bgp_bmp.c
bgpd/bgp_ecommunity.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
doc/user/overview.rst
isisd/isis_snmp.c
lib/compiler.h
lib/routemap.c
mgmtd/mgmt_vty.c
nhrpd/debug.h
ospfd/ospf_routemap.c
tests/topotests/bgp_route_origin_parser/pe1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py [new file with mode: 0644]
zebra/dpdk/zebra_dplane_dpdk.c
zebra/main.c
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_routemap.c

index 4ce92c520472603d1013ea470f852b9ba57985a7..f4c932971eb0e010cd0fcd1131e133c0a9bc61b6 100644 (file)
@@ -444,37 +444,39 @@ babel_fill_with_next_timeout(struct timeval *tv)
 #if (defined NO_DEBUG)
 #define printIfMin(a,b,c,d)
 #else
-#define printIfMin(a,b,c,d) \
-  if (UNLIKELY(debug & BABEL_DEBUG_TIMEOUT)) {printIfMin(a,b,c,d);}
-
-    struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
-    struct interface *ifp = NULL;
+#define printIfMin(a, b, c, d)                                                 \
+       if (unlikely(debug & BABEL_DEBUG_TIMEOUT)) {                           \
+               printIfMin(a, b, c, d);                                        \
+       }
 
-    *tv = check_neighbours_timeout;
-    printIfMin(tv, 0, "check_neighbours_timeout", NULL);
-    timeval_min_sec(tv, expiry_time);
-    printIfMin(tv, 1, "expiry_time", NULL);
-    timeval_min_sec(tv, source_expiry_time);
-    printIfMin(tv, 1, "source_expiry_time", NULL);
-    timeval_min(tv, &resend_time);
-    printIfMin(tv, 1, "resend_time", NULL);
-    FOR_ALL_INTERFACES(vrf, ifp) {
-        babel_interface_nfo *babel_ifp = NULL;
-        if(!if_up(ifp))
-            continue;
-        babel_ifp = babel_get_if_nfo(ifp);
-        timeval_min(tv, &babel_ifp->flush_timeout);
-        printIfMin(tv, 1, "flush_timeout", ifp->name);
-        timeval_min(tv, &babel_ifp->hello_timeout);
-        printIfMin(tv, 1, "hello_timeout", ifp->name);
-        timeval_min(tv, &babel_ifp->update_timeout);
-        printIfMin(tv, 1, "update_timeout", ifp->name);
-        timeval_min(tv, &babel_ifp->update_flush_timeout);
-        printIfMin(tv, 1, "update_flush_timeout",ifp->name);
-    }
-    timeval_min(tv, &unicast_flush_timeout);
-    printIfMin(tv, 1, "unicast_flush_timeout", NULL);
-    printIfMin(tv, 2, NULL, NULL);
+       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       struct interface *ifp = NULL;
+
+       *tv = check_neighbours_timeout;
+       printIfMin(tv, 0, "check_neighbours_timeout", NULL);
+       timeval_min_sec(tv, expiry_time);
+       printIfMin(tv, 1, "expiry_time", NULL);
+       timeval_min_sec(tv, source_expiry_time);
+       printIfMin(tv, 1, "source_expiry_time", NULL);
+       timeval_min(tv, &resend_time);
+       printIfMin(tv, 1, "resend_time", NULL);
+       FOR_ALL_INTERFACES (vrf, ifp) {
+               babel_interface_nfo *babel_ifp = NULL;
+               if (!if_up(ifp))
+                       continue;
+               babel_ifp = babel_get_if_nfo(ifp);
+               timeval_min(tv, &babel_ifp->flush_timeout);
+               printIfMin(tv, 1, "flush_timeout", ifp->name);
+               timeval_min(tv, &babel_ifp->hello_timeout);
+               printIfMin(tv, 1, "hello_timeout", ifp->name);
+               timeval_min(tv, &babel_ifp->update_timeout);
+               printIfMin(tv, 1, "update_timeout", ifp->name);
+               timeval_min(tv, &babel_ifp->update_flush_timeout);
+               printIfMin(tv, 1, "update_flush_timeout", ifp->name);
+       }
+       timeval_min(tv, &unicast_flush_timeout);
+       printIfMin(tv, 1, "unicast_flush_timeout", NULL);
+       printIfMin(tv, 2, NULL, NULL);
 #undef printIfMin
 #endif
 }
index 6c51af48a89572c97f56a29c90c62ad87555afe0..619550f651f7579669240e85f8fb324ccb206866 100644 (file)
@@ -26,12 +26,8 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
 
 #if defined(__GNUC__) && (__GNUC__ >= 3)
 #define ATTRIBUTE(x) __attribute__ (x)
-#define LIKELY(_x) __builtin_expect(!!(_x), 1)
-#define UNLIKELY(_x) __builtin_expect(!!(_x), 0)
 #else
 #define ATTRIBUTE(x) /**/
-#define LIKELY(_x) !!(_x)
-#define UNLIKELY(_x) !!(_x)
 #endif
 
 #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
index 5e5843543a22cba1e47e7438caf370c3dc155b7e..8535d4dd6a173aa605bb5b2c853cd1b46e99179f 100644 (file)
@@ -122,10 +122,11 @@ extern const unsigned char v4prefix[16];
 #define BABEL_DEBUG_ROUTE       (1 << 5)
 #define BABEL_DEBUG_ALL         (0xFFFF)
 
-#define debugf(level, ...) \
-do { \
-if(UNLIKELY(debug & level)) zlog_debug(__VA_ARGS__);     \
-} while(0)
+#define debugf(level, ...)                                                     \
+       do {                                                                   \
+               if (unlikely(debug & level))                                   \
+                       zlog_debug(__VA_ARGS__);                               \
+       } while (0)
 
 #endif /* NO_DEBUG */
 
index a51bcb1a1a6fae5012ceccf2cb88c50d0fefacaf..d1ddfd046025e1be25da3b3d25d4078725d86fda 100644 (file)
@@ -55,7 +55,7 @@ static void bfd_session_status_update(struct bfd_session_params *bsp,
                }
                peer->last_reset = PEER_DOWN_BFD_DOWN;
 
-               /* draft-ietf-idr-bfd-subcode */
+               /* rfc9384 */
                if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
                                        BGP_NOTIFY_CEASE_BFD_DOWN);
index 73dbf4ab2b4ec8f0446b37c5bc78007154cd39a0..baf164679c725586c871eaaa0c7df7e46d2e4037 100644 (file)
@@ -389,13 +389,13 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down)
 
                /* Local Port, Remote Port */
                if (peer->su_local->sa.sa_family == AF_INET6)
-                       stream_putw(s, peer->su_local->sin6.sin6_port);
+                       stream_putw(s, htons(peer->su_local->sin6.sin6_port));
                else if (peer->su_local->sa.sa_family == AF_INET)
-                       stream_putw(s, peer->su_local->sin.sin_port);
+                       stream_putw(s, htons(peer->su_local->sin.sin_port));
                if (peer->su_remote->sa.sa_family == AF_INET6)
-                       stream_putw(s, peer->su_remote->sin6.sin6_port);
+                       stream_putw(s, htons(peer->su_remote->sin6.sin6_port));
                else if (peer->su_remote->sa.sa_family == AF_INET)
-                       stream_putw(s, peer->su_remote->sin.sin_port);
+                       stream_putw(s, htons(peer->su_remote->sin.sin_port));
 
                static const uint8_t dummy_open[] = {
                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
index 541da9ecd6886edd97270962401fe5c525f2069b..dc1905868bd20d8221787dd925a8e1dcb9b52257 100644 (file)
@@ -503,6 +503,8 @@ static const char *ecommunity_gettoken(const char *str,
        uint8_t ecomm_type;
        char buf[INET_ADDRSTRLEN + 1];
        struct ecommunity_val *eval = (struct ecommunity_val *)eval_ptr;
+       uint64_t tmp_as = 0;
+
        /* Skip white space. */
        while (isspace((unsigned char)*p)) {
                p++;
@@ -581,9 +583,18 @@ static const char *ecommunity_gettoken(const char *str,
                        goto error;
 
                endptr++;
-               as = strtoul(endptr, &endptr, 10);
-               if (*endptr != '\0' || as == BGP_AS4_MAX)
+               errno = 0;
+               tmp_as = strtoul(endptr, &endptr, 10);
+               /* 'unsigned long' is a uint64 on 64-bit
+                * systems, and uint32 on 32-bit systems. So for
+                * 64-bit we can just directly check the value
+                * against BGP_AS4_MAX/UINT32_MAX, and for
+                * 32-bit we can check for errno (set to ERANGE
+                * upon overflow).
+                */
+               if (*endptr != '\0' || tmp_as == BGP_AS4_MAX || errno)
                        goto error;
+               as = (as_t)tmp_as;
 
                memcpy(buf, p, (limit - p));
                buf[limit - p] = '\0';
@@ -625,9 +636,19 @@ static const char *ecommunity_gettoken(const char *str,
                                        goto error;
                        } else {
                                /* ASN */
-                               as = strtoul(buf, &endptr, 10);
-                               if (*endptr != '\0' || as == BGP_AS4_MAX)
+                               errno = 0;
+                               tmp_as = strtoul(buf, &endptr, 10);
+                               /* 'unsigned long' is a uint64 on 64-bit
+                                * systems, and uint32 on 32-bit systems. So for
+                                * 64-bit we can just directly check the value
+                                * against BGP_AS4_MAX/UINT32_MAX, and for
+                                * 32-bit we can check for errno (set to ERANGE
+                                * upon overflow).
+                                */
+                               if (*endptr != '\0' || tmp_as > BGP_AS4_MAX ||
+                                   errno)
                                        goto error;
+                               as = (as_t)tmp_as;
                        }
                } else if (*p == '.') {
                        if (separator)
index 4813874748fa478d1569e9d6c74711737a152919..a23bffd4ae960c944686ef4e2f8b6e96b0047e7d 100644 (file)
@@ -11603,9 +11603,28 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                        vty_out(vty, ",\"%pFX\": ", dest_p);
                        }
 
+                       /* This is used for 'json detail' vty keywords.
+                        *
+                        * In plain 'json' the per-prefix header is encoded
+                        * as a standalone dictionary in the first json_paths
+                        * array element:
+                        * "<prefix>": [{header}, {path-1}, {path-N}]
+                        * (which is confusing and borderline broken)
+                        *
+                        * For 'json detail' this changes the value
+                        * of each prefix-key to be a dictionary where each
+                        * header item has its own key, and json_paths is
+                        * tucked under the "paths" key:
+                        * "<prefix>": {
+                        *   "<header-key-1>": <header-val-1>,
+                        *   "<header-key-N>": <header-val-N>,
+                        *   "paths": [{path-1}, {path-N}]
+                        * }
+                        */
                        if (json_detail_header && json_paths != NULL) {
                                const struct prefix_rd *prd;
 
+                               /* Start per-prefix dictionary */
                                vty_out(vty, "{\n");
 
                                prd = bgp_rd_from_dest(dest, safi);
@@ -11630,6 +11649,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                         */
                        vty_json_no_pretty(vty, json_paths);
 
+                       /* End per-prefix dictionary */
                        if (json_detail_header_used)
                                vty_out(vty, "} ");
 
index 4faf4a9f15ce290dc18e0921a6f3dbb8d68f64d3..32ecb083beca51ccd503d4bdf407b5770ac583c5 100644 (file)
@@ -461,7 +461,8 @@ route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
        if (prefix->family == AF_INET) {
                alist = access_list_lookup(AFI_IP, (char *)rule);
                if (alist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -521,7 +522,8 @@ route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
 
                alist = access_list_lookup(AFI_IP, (char *)rule);
                if (alist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -581,7 +583,8 @@ route_match_ip_route_source(void *rule, const struct prefix *pfx, void *object)
 
                alist = access_list_lookup(AFI_IP, (char *)rule);
                if (alist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -676,7 +679,7 @@ route_match_address_prefix_list(void *rule, afi_t afi,
 
        plist = prefix_list_lookup(afi, (char *)rule);
        if (plist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -737,7 +740,8 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
 
                plist = prefix_list_lookup(AFI_IP, (char *)rule);
                if (plist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -786,7 +790,8 @@ route_match_ipv6_next_hop_prefix_list(void *rule, const struct prefix *prefix,
 
                plist = prefix_list_lookup(AFI_IP6, (char *)rule);
                if (!plist) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -891,7 +896,8 @@ route_match_ip_route_source_prefix_list(void *rule, const struct prefix *prefix,
 
                plist = prefix_list_lookup(AFI_IP, (char *)rule);
                if (plist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -956,7 +962,7 @@ route_match_mac_address(void *rule, const struct prefix *prefix, void *object)
 
        alist = access_list_lookup(AFI_L2VPN, (char *)rule);
        if (alist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -964,7 +970,7 @@ route_match_mac_address(void *rule, const struct prefix *prefix, void *object)
                return RMAP_NOMATCH;
        }
        if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix %pFX is not a EVPN MAC IP ROUTE defaulting to NO_MATCH",
                                __func__, prefix);
@@ -3242,7 +3248,8 @@ route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
        if (prefix->family == AF_INET6) {
                alist = access_list_lookup(AFI_IP6, (char *)rule);
                if (alist == NULL) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
@@ -3299,7 +3306,8 @@ route_match_ipv6_next_hop(void *rule, const struct prefix *prefix, void *object)
 
                alist = access_list_lookup(AFI_IP6, (char *)rule);
                if (!alist) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                        __func__, (char *)rule);
index 4a24fa52be565e59a15252c344582ac5108fab94..5ea33d62c956da95e60d92e3b57f7068976c03de 100644 (file)
@@ -424,6 +424,8 @@ BGP
   :t:`Extended Optional Parameters Length for BGP OPEN Message. E. Chen, J. Scudder. July 2021.`
 - :rfc:`9234`
   :t:`Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages. A. Azimov, E. Bogomazov, R. Bush, K. Patel, K. Sriram. May 2022.`
+- :rfc:`9384`
+  :t:`A BGP Cease NOTIFICATION Subcode for Bidirectional Forwarding Detection (BFD). J. Haas. March 2023.`
 
 OSPF
 ----
index fa566c5470dafc1cdb3bb46b34bd92f8efc5ab61..6d9974fe9fe0ade1c8b7fe9ea421c3e454e3b525 100644 (file)
 /* Declare static local variables for convenience. */
 SNMP_LOCAL_VARIABLES
 
-/* If ARRAY_SIZE is not available use a primitive substitution */
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
 /*
  * Define time function, it serves two purposes
  * 1. Uses unint32_t for unix time and encapsulates
@@ -425,7 +420,7 @@ static struct isis_func_to_prefix isis_func_to_prefix_arr[] = {
        {isis_snmp_find_isadj_ipaddr, {ISIS_ISADJIPADDR_ENTRY}, 4},
        {isis_snmp_find_isadj_prot_supp, {ISIS_ISADJPROTSUPP_ENTRY}, 4},
 };
-static size_t isis_func_to_prefix_count = ARRAY_SIZE(isis_func_to_prefix_arr);
+static size_t isis_func_to_prefix_count = array_size(isis_func_to_prefix_arr);
 
 static struct variable isis_var_arr[] = {
        {ISIS_SYS_VERSION, INTEGER, RONLY, isis_snmp_find_sys_object},
@@ -554,7 +549,7 @@ static struct variable isis_var_arr[] = {
         isis_snmp_find_isadj_prot_supp},
 };
 
-static const size_t isis_var_count = ARRAY_SIZE(isis_var_arr);
+static const size_t isis_var_count = array_size(isis_var_arr);
 
 /* Minimal set of hard-coded data */
 #define ISIS_VERSION (1)
@@ -2859,7 +2854,7 @@ static int isis_snmp_db_overload_update(const struct isis_area *area)
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)&isis_snmp_trap_val_db_overload,
                                  sizeof(isis_snmp_trap_val_db_overload));
 
@@ -2868,11 +2863,11 @@ static int isis_snmp_db_overload_update(const struct isis_area *area)
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
        /* Patch sys_level_state with proper index */
-       off = ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state) - 1;
+       off = array_size(isis_snmp_trap_data_var_sys_level_state) - 1;
        isis_snmp_trap_data_var_sys_level_state[off] = val;
 
        /* Prepare data */
@@ -2883,7 +2878,7 @@ static int isis_snmp_db_overload_update(const struct isis_area *area)
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_state,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_state), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
        send_v2trap(notification_vars);
@@ -2905,7 +2900,7 @@ static int isis_snmp_lsp_exceed_max_update(const struct isis_area *area,
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max,
                                  sizeof(isis_snmp_trap_val_lsp_exceed_max));
 
@@ -2914,12 +2909,12 @@ static int isis_snmp_lsp_exceed_max_update(const struct isis_area *area,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2);
 
        send_v2trap(notification_vars);
@@ -2962,18 +2957,18 @@ static void isis_snmp_update_worker_a(const struct isis_circuit *circuit,
        /* Put in trap value */
        memcpy(var_name, isis_snmp_notifications,
               sizeof(isis_snmp_notifications));
-       var_count = ARRAY_SIZE(isis_snmp_notifications);
+       var_count = array_size(isis_snmp_notifications);
        var_name[var_count++] = trap_id;
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)var_name, var_count * sizeof(oid));
 
        val = circuit->is_type;
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
        if (oid_a_len != 0) {
@@ -2992,7 +2987,7 @@ static void isis_snmp_update_worker_a(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_circ_if_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
 
@@ -3042,18 +3037,18 @@ static void isis_snmp_update_worker_b(const struct isis_circuit *circuit,
        /* Put in trap value */
        memcpy(var_name, isis_snmp_notifications,
               sizeof(isis_snmp_notifications));
-       var_count = ARRAY_SIZE(isis_snmp_notifications);
+       var_count = array_size(isis_snmp_notifications);
        var_name[var_count++] = trap_id;
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)var_name, var_count * sizeof(oid));
 
        val = circuit->is_type;
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
        if (circuit->interface == NULL)
@@ -3063,7 +3058,7 @@ static void isis_snmp_update_worker_b(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_circ_if_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
 
@@ -3108,9 +3103,9 @@ static int isis_snmp_id_len_mismatch_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_ID_LEN_MISMATCH,
                isis_snmp_trap_data_var_pdu_field_len,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_field_len), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_pdu_field_len), UNSIGNED32,
                &val, sizeof(val), isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3133,10 +3128,10 @@ isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH,
                isis_snmp_trap_data_var_pdu_max_area_addr,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_max_area_addr),
+               array_size(isis_snmp_trap_data_var_pdu_max_area_addr),
                UNSIGNED32, &val, sizeof(val),
                isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3150,7 +3145,7 @@ static int isis_snmp_own_lsp_purge_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_OWN_LSP_PURGE, NULL, 0, STRING, NULL, 0,
                isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2);
        return 0;
 }
@@ -3164,7 +3159,7 @@ static int isis_snmp_seqno_skipped_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_SEQNO_SKIPPED, NULL, 0, STRING, NULL, 0,
                isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2);
        return 0;
 }
@@ -3183,7 +3178,7 @@ isis_snmp_authentication_type_failure_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_AUTHEN_TYPE_FAILURE, NULL, 0, STRING, NULL,
                0, isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3201,7 +3196,7 @@ isis_snmp_authentication_failure_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_AUTHEN_FAILURE, NULL, 0, STRING, NULL, 0,
                isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3223,9 +3218,9 @@ static int isis_snmp_version_skew_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_b(
                circuit, ISIS_TRAP_VERSION_SKEW,
                isis_snmp_trap_data_var_pdu_proto_ver,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_proto_ver), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_pdu_proto_ver), UNSIGNED32,
                &val, sizeof(val), isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3248,7 +3243,7 @@ static int isis_snmp_area_mismatch_update(const struct isis_circuit *circuit,
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)&isis_snmp_trap_val_area_mismatch,
                                  sizeof(isis_snmp_trap_val_area_mismatch));
 
@@ -3260,7 +3255,7 @@ static int isis_snmp_area_mismatch_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_circ_if_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
 
@@ -3269,7 +3264,7 @@ static int isis_snmp_area_mismatch_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
 
        send_v2trap(notification_vars);
@@ -3292,7 +3287,7 @@ static int isis_snmp_reject_adjacency_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_a(
                circuit, ISIS_TRAP_REJ_ADJACENCY, NULL, 0, STRING, NULL, 0,
                isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
        return 0;
 }
@@ -3307,9 +3302,9 @@ static int isis_snmp_lsp_too_large_update(const struct isis_circuit *circuit,
        isis_snmp_update_worker_b(
                circuit, ISIS_TRAP_LSP_TOO_LARGE,
                isis_snmp_trap_data_var_pdu_lsp_size,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_size), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_size), UNSIGNED32,
                &pdu_size, sizeof(pdu_size), isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2);
        return 0;
 }
@@ -3334,9 +3329,9 @@ static int isis_snmp_adj_state_change_update(const struct isis_adjacency *adj)
        isis_snmp_update_worker_b(
                adj->circuit, ISIS_TRAP_ADJ_STATE_CHANGE,
                isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2, isis_snmp_trap_data_var_adj_state,
-               ARRAY_SIZE(isis_snmp_trap_data_var_adj_state), INTEGER, &val,
+               array_size(isis_snmp_trap_data_var_adj_state), INTEGER, &val,
                sizeof(val));
        return 0;
 }
@@ -3359,7 +3354,7 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        /* Put in trap value */
        snmp_varlist_add_variable(&notification_vars, isis_snmp_trap_var,
-                                 ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+                                 array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
                                  (uint8_t *)&isis_snmp_trap_val_lsp_error,
                                  sizeof(isis_snmp_trap_val_lsp_error));
 
@@ -3368,13 +3363,13 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_sys_level_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+               array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
                (uint8_t *)&val, sizeof(val));
 
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_pdu_lsp_id,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+               array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
                ISIS_SYS_ID_LEN + 2);
 
        /* Prepare data */
@@ -3385,7 +3380,7 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_circ_if_index,
-               ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
        /* Prepare data */
@@ -3394,7 +3389,7 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_pdu_fragment,
-               ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+               array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
                raw_pdu, raw_pdu_len);
 
        /* Prepare data */
@@ -3402,7 +3397,7 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_error_offset,
-               ARRAY_SIZE(isis_snmp_trap_data_var_error_offset), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_error_offset), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
        /* Prepare data */
@@ -3410,7 +3405,7 @@ static int isis_snmp_lsp_error_update(const struct isis_circuit *circuit,
 
        snmp_varlist_add_variable(
                &notification_vars, isis_snmp_trap_data_var_error_tlv_type,
-               ARRAY_SIZE(isis_snmp_trap_data_var_error_tlv_type), UNSIGNED32,
+               array_size(isis_snmp_trap_data_var_error_tlv_type), UNSIGNED32,
                (uint8_t *)&val, sizeof(val));
 
        send_v2trap(notification_vars);
index d12e2828326f1d914ad93b61697919591d047097..29fcfbefbf2d6c0593d38abe8bf587bd5e5e1281 100644 (file)
@@ -439,6 +439,14 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
 #pragma diag_suppress 167
 #endif /* __INTELISENSE__ */
 
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define likely(_x) __builtin_expect(!!(_x), 1)
+#define unlikely(_x) __builtin_expect(!!(_x), 0)
+#else
+#define likely(_x) !!(_x)
+#define unlikely(_x) !!(_x)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index 16da81fa746255f5834b38712ae4ab28a3083d0e..20dcd2a53d4dc73589f666ee4e8509e7c7a69ad2 100644 (file)
@@ -669,7 +669,7 @@ static struct route_map *route_map_add(const char *name)
        if (!map->ipv6_prefix_table)
                map->ipv6_prefix_table = route_table_init();
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Add route-map %s", name);
        return map;
 }
@@ -689,7 +689,7 @@ static void route_map_free_map(struct route_map *map)
        while ((index = map->head) != NULL)
                route_map_index_delete(index, 0);
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Deleting route-map %s", map->name);
 
        list = &route_map_master;
@@ -706,6 +706,9 @@ static void route_map_free_map(struct route_map *map)
        else
                list->head = map->next;
 
+       route_table_finish(map->ipv4_prefix_table);
+       route_table_finish(map->ipv6_prefix_table);
+
        hash_release(route_map_master_hash, map);
        XFREE(MTYPE_ROUTE_MAP_NAME, map->name);
        XFREE(MTYPE_ROUTE_MAP, map);
@@ -1120,7 +1123,7 @@ void route_map_index_delete(struct route_map_index *index, int notify)
 
        QOBJ_UNREG(index);
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Deleting route-map %s sequence %d",
                           index->map->name, index->pref);
 
@@ -1231,7 +1234,7 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref)
                route_map_notify_dependencies(map->name, RMAP_EVENT_CALL_ADDED);
        }
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Route-map %s add sequence %d, type: %s",
                           map->name, pref, route_map_type_str(type));
 
@@ -1811,10 +1814,8 @@ route_map_get_index(struct route_map *map, const struct prefix *prefix,
         * must be AF_INET or AF_INET6 in order for the lookup to succeed. So if
         * the AF doesn't line up with the LPM trees, skip the optimization.
         */
-       if (map->optimization_disabled ||
-           (prefix->family == AF_INET && !map->ipv4_prefix_table) ||
-           (prefix->family == AF_INET6 && !map->ipv6_prefix_table)) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+       if (map->optimization_disabled) {
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "Skipping route-map optimization for route-map: %s, pfx: %pFX, family: %d",
                                map->name, prefix, prefix->family);
@@ -1826,9 +1827,6 @@ route_map_get_index(struct route_map *map, const struct prefix *prefix,
        else
                table = map->ipv6_prefix_table;
 
-       if (!table)
-               return NULL;
-
        do {
                candidate_rmap_list =
                        route_map_get_index_list(&rn, prefix, table);
@@ -1914,19 +1912,10 @@ static void route_map_pfx_table_add_default(afi_t afi,
        p.family = afi2family(afi);
        p.prefixlen = 0;
 
-       if (p.family == AF_INET) {
-               table = index->map->ipv4_prefix_table;
-               if (!table)
-                       index->map->ipv4_prefix_table = route_table_init();
-
+       if (p.family == AF_INET)
                table = index->map->ipv4_prefix_table;
-       } else {
-               table = index->map->ipv6_prefix_table;
-               if (!table)
-                       index->map->ipv6_prefix_table = route_table_init();
-
+       else
                table = index->map->ipv6_prefix_table;
-       }
 
        /* Add default route to table */
        rn = route_node_get(table, &p);
@@ -2317,8 +2306,6 @@ static void route_map_pfx_tbl_update(route_map_event_t event,
                                     struct route_map_index *index, afi_t afi,
                                     const char *plist_name)
 {
-       struct route_map *rmap = NULL;
-
        if (!index)
                return;
 
@@ -2332,19 +2319,6 @@ static void route_map_pfx_tbl_update(route_map_event_t event,
                route_map_pfx_table_del_default(AFI_IP, index);
                route_map_pfx_table_del_default(AFI_IP6, index);
 
-               if ((index->map->head == NULL) && (index->map->tail == NULL)) {
-                       rmap = index->map;
-
-                       if (rmap->ipv4_prefix_table) {
-                               route_table_finish(rmap->ipv4_prefix_table);
-                               rmap->ipv4_prefix_table = NULL;
-                       }
-
-                       if (rmap->ipv6_prefix_table) {
-                               route_table_finish(rmap->ipv6_prefix_table);
-                               rmap->ipv6_prefix_table = NULL;
-                       }
-               }
                return;
        }
 
@@ -2569,12 +2543,14 @@ route_map_result_t route_map_apply_ext(struct route_map *map,
         */
        if (prefix->family == AF_EVPN) {
                if (evpn_prefix2prefix(prefix, &conv) != 0) {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "Unable to convert EVPN prefix %pFX into IPv4/IPv6 prefix. Falling back to non-optimized route-map lookup",
                                        prefix);
                } else {
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+                       if (unlikely(CHECK_FLAG(rmap_debug,
+                                               DEBUG_ROUTEMAP_DETAIL)))
                                zlog_debug(
                                        "Converted EVPN prefix %pFX into %pFX for optimized route-map lookup",
                                        prefix, &conv);
@@ -2586,13 +2562,13 @@ route_map_result_t route_map_apply_ext(struct route_map *map,
        index = route_map_get_index(map, prefix, match_object, &match_ret);
        if (index) {
                index->applied++;
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug(
                                "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s",
                                map->name, index->pref, prefix,
                                route_map_cmd_result_str(match_ret));
        } else {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug(
                                "No best match sequence for pfx: %pFX in route-map: %s, result: %s",
                                prefix, map->name,
@@ -2615,7 +2591,7 @@ route_map_result_t route_map_apply_ext(struct route_map *map,
                        /* Apply this index. */
                        match_ret = route_map_apply_match(&index->match_list,
                                                          prefix, match_object);
-                       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)) {
+                       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))) {
                                zlog_debug(
                                        "Route-map: %s, sequence: %d, prefix: %pFX, result: %s",
                                        map->name, index->pref, prefix,
@@ -2728,7 +2704,7 @@ route_map_result_t route_map_apply_ext(struct route_map *map,
        }
 
 route_map_apply_end:
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Route-map: %s, prefix: %pFX, result: %s",
                           (map ? map->name : "null"), prefix,
                           route_map_result_str(ret));
@@ -2783,7 +2759,7 @@ static void route_map_clear_reference(struct hash_bucket *bucket, void *arg)
        tmp_dep_data.rname = arg;
        dep_data = hash_release(dep->dep_rmap_hash, &tmp_dep_data);
        if (dep_data) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug("Clearing reference for %s to %s count: %d",
                                   dep->dep_name, tmp_dep_data.rname,
                                   dep_data->refcnt);
@@ -2803,7 +2779,7 @@ static void route_map_clear_all_references(char *rmap_name)
 {
        int i;
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Clearing references for %s", rmap_name);
 
        for (i = 1; i < ROUTE_MAP_DEP_MAX; i++) {
@@ -2879,7 +2855,7 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name,
        case RMAP_EVENT_LLIST_ADDED:
        case RMAP_EVENT_CALL_ADDED:
        case RMAP_EVENT_FILTER_ADDED:
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug("Adding dependency for filter %s in route-map %s",
                                   dep_name, rmap_name);
                dep = (struct route_map_dep *)hash_get(
@@ -2908,7 +2884,7 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name,
        case RMAP_EVENT_LLIST_DELETED:
        case RMAP_EVENT_CALL_DELETED:
        case RMAP_EVENT_FILTER_DELETED:
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug("Deleting dependency for filter %s in route-map %s",
                                   dep_name, rmap_name);
                dep = (struct route_map_dep *)hash_get(dephash, dname, NULL);
@@ -3034,7 +3010,7 @@ static void route_map_process_dependency(struct hash_bucket *bucket, void *data)
        dep_data = bucket->data;
        rmap_name = dep_data->rname;
 
-       if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+       if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                zlog_debug("Notifying %s of dependency", rmap_name);
        if (route_map_master.event_hook)
                (*route_map_master.event_hook)(rmap_name);
@@ -3082,7 +3058,7 @@ void route_map_notify_dependencies(const char *affected_name,
                if (!dep->this_hash)
                        dep->this_hash = upd8_hash;
 
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP)))
                        zlog_debug("Filter %s updated", dep->dep_name);
                hash_iterate(dep->dep_rmap_hash, route_map_process_dependency,
                             (void *)event);
index 79fa54a791d2e6f07d4c68b5eb258843f5161914..898eb43915f67e1102f9b1eb457c0b5b732dc262 100644 (file)
@@ -386,12 +386,14 @@ static struct cmd_node debug_node = {
        .config_write = config_write_mgmt_debug,
 };
 
-static int config_write_mgmt_debug(struct vty *vty)
+static int config_write_mgmt_debug_helper(struct vty *vty, bool config)
 {
        int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
        if (!n)
                return 0;
-       if (n == 4) {
+
+       if (config && mgmt_debug_be && mgmt_debug_fe && mgmt_debug_ds &&
+           mgmt_debug_txn) {
                vty_out(vty, "debug mgmt all\n");
                return 0;
        }
@@ -411,12 +413,26 @@ static int config_write_mgmt_debug(struct vty *vty)
        return 0;
 }
 
-DEFPY(debug_mgmt,
-      debug_mgmt_cmd,
+static int config_write_mgmt_debug(struct vty *vty)
+{
+       return config_write_mgmt_debug_helper(vty, true);
+}
+
+DEFUN_NOSH(show_debugging_mgmt, show_debugging_mgmt_cmd,
+          "show debugging [mgmt]", SHOW_STR DEBUG_STR "MGMT Information\n")
+{
+       vty_out(vty, "MGMT debugging status:\n");
+
+       config_write_mgmt_debug_helper(vty, false);
+
+       cmd_show_lib_debugs(vty);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(debug_mgmt, debug_mgmt_cmd,
       "[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
-      NO_STR
-      DEBUG_STR
-      MGMTD_STR
+      NO_STR DEBUG_STR MGMTD_STR
       "All debug\n"
       "Back-end debug\n"
       "Datastore debug\n"
@@ -479,6 +495,8 @@ void mgmt_vty_init(void)
        install_element(ENABLE_NODE, &mgmt_performance_measurement_cmd);
        install_element(ENABLE_NODE, &mgmt_reset_performance_stats_cmd);
 
+       install_element(ENABLE_NODE, &show_debugging_mgmt_cmd);
+
        /*
         * TODO: Register and handlers for auto-completion here.
         */
index e9428fa90a0e9fbb1aab5ce8236fa45b0cccdce9..f2c7022ad409298087020d3c2f8a30d503313116 100644 (file)
@@ -1,13 +1,5 @@
 #include "log.h"
 
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#define likely(_x) __builtin_expect(!!(_x), 1)
-#define unlikely(_x) __builtin_expect(!!(_x), 0)
-#else
-#define likely(_x) !!(_x)
-#define unlikely(_x) !!(_x)
-#endif
-
 #define NHRP_DEBUG_COMMON      (1 << 0)
 #define NHRP_DEBUG_KERNEL      (1 << 1)
 #define NHRP_DEBUG_IF          (1 << 2)
index 3087008819275c7a97fa0040d083fc9c56a7dc4f..3d5c5aa2d572c99d0e4f598701e45fa2cf18d242 100644 (file)
@@ -120,7 +120,7 @@ route_match_ip_nexthop(void *rule, const struct prefix *prefix, void *object)
 
        alist = access_list_lookup(AFI_IP, (char *)rule);
        if (alist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -168,7 +168,7 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
 
        plist = prefix_list_lookup(AFI_IP, (char *)rule);
        if (plist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -245,7 +245,7 @@ route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
 
        alist = access_list_lookup(AFI_IP, (char *)rule);
        if (alist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -286,7 +286,7 @@ route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
 
        plist = prefix_list_lookup(AFI_IP, (char *)rule);
        if (plist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
diff --git a/tests/topotests/bgp_route_origin_parser/pe1/bgpd.conf b/tests/topotests/bgp_route_origin_parser/pe1/bgpd.conf
new file mode 100644 (file)
index 0000000..1929dfa
--- /dev/null
@@ -0,0 +1,2 @@
+router bgp 65001
+ neighbor 192.168.2.1 remote-as external
diff --git a/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py b/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py
new file mode 100644 (file)
index 0000000..673efc2
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# April 03 2023, Trey Aspelund <taspelund@nvidia.com>
+#
+# Copyright (C) 2023 NVIDIA Corporation
+#
+# Test if the CLI parser for RT/SoO ecoms correctly
+# constrain user input to valid 4-byte ASN values.
+#
+
+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.common_config import step
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+    tgen.add_router("pe1")
+
+
+def setup_module(mod):
+    tgen = Topogen(build_topo, mod.__name__)
+    tgen.start_topology()
+    pe1 = tgen.gears["pe1"]
+    pe1.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "pe1/bgpd.conf"))
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_route_origin_parser():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    pe1 = tgen.gears["pe1"]
+
+    def _invalid_soo_accepted():
+        pe1.vtysh_cmd(
+            """
+        configure terminal
+        router bgp 65001
+         address-family ipv4 unicast
+          neighbor 192.168.2.1 soo 4294967296:65
+        """
+        )
+        run_cfg = pe1.vtysh_cmd("show run")
+        return "soo" in run_cfg
+
+    def _max_soo_accepted():
+        pe1.vtysh_cmd(
+            """
+        configure terminal
+        router bgp 65001
+         address-family ipv4 unicast
+          neighbor 192.168.2.1 soo 4294967295:65
+            """
+        )
+        run_cfg = pe1.vtysh_cmd("show run")
+        return "soo 4294967295:65" in run_cfg
+
+    def _invalid_rt_accepted():
+        pe1.vtysh_cmd(
+            """
+        configure terminal
+        router bgp 65001
+         address-family ipv4 unicast
+          rt vpn both 4294967296:65
+        """
+        )
+        run_cfg = pe1.vtysh_cmd("show run")
+        return "rt vpn" in run_cfg
+
+    def _max_rt_accepted():
+        pe1.vtysh_cmd(
+            """
+        configure terminal
+        router bgp 65001
+         address-family ipv4 unicast
+          rt vpn both 4294967295:65
+            """
+        )
+        run_cfg = pe1.vtysh_cmd("show run")
+        return "rt vpn both 4294967295:65" in run_cfg
+
+    step(
+        "Configure invalid 4-byte value SoO (4294967296:65), this should not be accepted"
+    )
+    test_func = functools.partial(_invalid_soo_accepted)
+    _, result = topotest.run_and_expect(test_func, False, count=30, wait=0.5)
+    assert result is False, "invalid 4-byte value of SoO accepted"
+
+    step("Configure max 4-byte value SoO (4294967295:65), this should be accepted")
+    test_func = functools.partial(_max_soo_accepted)
+    _, result = topotest.run_and_expect(test_func, True, count=30, wait=0.5)
+    assert result is True, "max 4-byte value of SoO not accepted"
+
+    step(
+        "Configure invalid 4-byte value RT (4294967296:65), this should not be accepted"
+    )
+    test_func = functools.partial(_invalid_rt_accepted)
+    _, result = topotest.run_and_expect(test_func, False, count=30, wait=0.5)
+    assert result is False, "invalid 4-byte value of RT accepted"
+
+    step("Configure max 4-byte value RT (4294967295:65), this should be accepted")
+    test_func = functools.partial(_max_rt_accepted)
+    _, result = topotest.run_and_expect(test_func, True, count=30, wait=0.5)
+    assert result is True, "max 4-byte value of RT not accepted"
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index b13daa3a97bc6d1309cab3ac866c0282b237a98b..fc140b07a34dbe1ba398f383c5eeb6423f338632 100644 (file)
@@ -645,7 +645,7 @@ static int zd_dpdk_init(void)
        zd_dpdk_vty_init();
 
        frr_with_privs (&zserv_privs) {
-               rc = rte_eal_init(ARRAY_SIZE(argv), argv);
+               rc = rte_eal_init(array_size(argv), argv);
        }
        if (rc < 0) {
                zlog_warn("EAL init failed %s", rte_strerror(rte_errno));
index 78932bfced44948ed170d1f020e5caa726474093..81a30664453a5e43ebd247a7ae8a919bb7817afc 100644 (file)
@@ -185,6 +185,8 @@ static void sigint(void)
         */
        zebra_routemap_finish();
 
+       rib_update_finish();
+
        list_delete(&zrouter.client_list);
 
        /* Indicate that all new dplane work has been enqueued. When that
index 0e897881e440d4cb0c7774b967a0c187f4271ef7..26425a331fedbace1f78052cfb74a771526170a9 100644 (file)
@@ -323,6 +323,7 @@ enum rib_update_event {
        RIB_UPDATE_OTHER,
        RIB_UPDATE_MAX
 };
+void rib_update_finish(void);
 
 int route_entry_update_nhe(struct route_entry *re,
                           struct nhg_hash_entry *new_nhghe);
index 7a9d0c0ed6219749f242ff3966d023fb8fc4937f..ceb0640553a06c3c821725513f831675240bf53b 100644 (file)
@@ -4410,6 +4410,22 @@ static void rib_update_handler(struct event *thread)
  */
 static struct event *t_rib_update_threads[RIB_UPDATE_MAX];
 
+void rib_update_finish(void)
+{
+       int i;
+
+       for (i = RIB_UPDATE_KERNEL; i < RIB_UPDATE_MAX; i++) {
+               if (event_is_scheduled(t_rib_update_threads[i])) {
+                       struct rib_update_ctx *ctx;
+
+                       ctx = EVENT_ARG(t_rib_update_threads[i]);
+
+                       rib_update_ctx_fini(&ctx);
+                       EVENT_OFF(t_rib_update_threads[i]);
+               }
+       }
+}
+
 /* Schedule a RIB update event for all vrfs */
 void rib_update(enum rib_update_event event)
 {
@@ -4418,6 +4434,9 @@ void rib_update(enum rib_update_event event)
        if (event_is_scheduled(t_rib_update_threads[event]))
                return;
 
+       if (zebra_router_in_shutdown())
+               return;
+
        ctx = rib_update_ctx_init(0, event);
 
        event_add_event(zrouter.master, rib_update_handler, ctx, 0,
index d9a7ee465a9fcb2d8f86cf612f13deb863681ef2..142501b14994168e08158bb9439f53bc7b301552 100644 (file)
@@ -1041,7 +1041,7 @@ route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
        }
        alist = access_list_lookup(AFI_IP, (char *)rule);
        if (alist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -1104,7 +1104,7 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
        }
        plist = prefix_list_lookup(AFI_IP, (char *)rule);
        if (plist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -1145,7 +1145,7 @@ route_match_address(afi_t afi, void *rule, const struct prefix *prefix,
 
        alist = access_list_lookup(afi, (char *)rule);
        if (alist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);
@@ -1207,7 +1207,7 @@ route_match_address_prefix_list(void *rule, const struct prefix *prefix,
 
        plist = prefix_list_lookup(afi, (char *)rule);
        if (plist == NULL) {
-               if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+               if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
                        zlog_debug(
                                "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
                                __func__, (char *)rule);