]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4295 from donaldsharp/topotest_if
authorRenato Westphal <renato@opensourcerouting.org>
Fri, 10 May 2019 11:42:07 +0000 (08:42 -0300)
committerGitHub <noreply@github.com>
Fri, 10 May 2019 11:42:07 +0000 (08:42 -0300)
topotests: ifindex values are not guaranteed to be the same

21 files changed:
.gitignore
bgpd/bgpd.c
doc/developer/lists.rst
doc/user/basic.rst
doc/user/bgp.rst
doc/user/static.rst
lib/command.c
lib/prefix.c
lib/prefix.h
lib/routemap.c
lib/table.c
lib/table.h
lib/typesafe.h
pimd/pim_upstream.c
tools/checkpatch.pl
vtysh/vtysh.c
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zebra_vrf.c

index 7a1378d588259f364446f64ab3a290ed6946803d..df2b0a6bf39cad3077246b423ae980d55e6089c7 100644 (file)
@@ -88,5 +88,6 @@ GSYMS
 GRTAGS
 GPATH
 compile_commands.json
+.ccls-cache
 .dirstamp
 refix
index b2925cd5122849f17318af7fbca8ef1ae4f40254..6183bbd4714eebc6691263b7e4da1b3ec5dfdd58 100644 (file)
@@ -6186,8 +6186,15 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
 
        /* Set configuration on peer. */
        filter = &peer->filter[afi][safi];
-       if (filter->map[direct].name)
+       if (filter->map[direct].name) {
+               /* If the neighbor is configured with the same route-map
+                * again then, ignore the duplicate configuration.
+                */
+               if (strcmp(filter->map[direct].name, name) == 0)
+                       return 0;
+
                XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
+       }
        route_map_counter_decrement(filter->map[direct].map);
        filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
        filter->map[direct].map = route_map;
index 6d60420b2fb2b675596e513bf3f2678e7286b1f6..987b3b7f4fb3a849a8971a4a8fa46d5dbb05c791 100644 (file)
@@ -119,6 +119,8 @@ The common setup pattern will look like this:
 
 .. code-block:: c
 
+   #include <typesafe.h>
+
    PREDECL_XXX(Z)
    struct item {
        int otherdata;
@@ -159,26 +161,26 @@ Common iteration macros
 
 The following iteration macros work across all data structures:
 
-.. c:function:: for_each(Z, head, item)
+.. c:function:: for_each(Z, &head, item)
 
    Equivalent to:
 
    .. code-block:: c
 
-      for (item = Z_first(head); item; item = Z_next(head, item))
+      for (item = Z_first(&head); item; item = Z_next(&head, item))
 
    Note that this will fail if the list is modified while being iterated
    over.
 
-.. c:function:: for_each_safe(Z, head, item)
+.. c:function:: for_each_safe(Z, &head, item)
 
    Same as the previous, but the next element is pre-loaded into a "hidden"
    variable (named ``Z_safe``.)  Equivalent to:
 
    .. code-block:: c
 
-      for (item = Z_first(head); item; item = next) {
-          next = Z_next_safe(head, item);
+      for (item = Z_first(&head); item; item = next) {
+          next = Z_next_safe(&head, item);
           ...
       }
 
@@ -189,7 +191,7 @@ The following iteration macros work across all data structures:
       tables is resized while iterating.  This will cause items to be
       skipped or iterated over twice.
 
-.. c:function:: for_each_from(Z, head, item, from)
+.. c:function:: for_each_from(Z, &head, item, from)
 
    Iterates over the list, starting at item ``from``.  This variant is "safe"
    as in the previous macro.  Equivalent to:
@@ -197,7 +199,7 @@ The following iteration macros work across all data structures:
    .. code-block:: c
 
       for (item = from; item; item = from) {
-          from = Z_next_safe(head, item);
+          from = Z_next_safe(&head, item);
           ...
       }
 
index 8fbea29ee7ec42aef3cc83d2101d35baa2877422..f55b1b9d73a77a88fd350f2a282802203f709363 100644 (file)
@@ -287,8 +287,8 @@ Terminal Mode Commands
 
    Write current configuration to configuration file.
 
-.. index:: configure terminal
-.. clicmd:: configure terminal
+.. index:: configure [terminal]
+.. clicmd:: configure [terminal]
 
    Change to configuration mode. This command is the first step to
    configuration.
index 35e42d95cb5176038a9e69dafb2c324df04bf315..d663b4fc10f920c979ff2b2fa5d9664bf8503568 100644 (file)
@@ -942,14 +942,18 @@ Configuring Peers
 .. index:: [no] neighbor PEER maximum-prefix NUMBER
 .. clicmd:: [no] neighbor PEER maximum-prefix NUMBER
 
-.. index:: [no] neighbor PEER local-as AS-NUMBER no-prepend
-.. clicmd:: [no] neighbor PEER local-as AS-NUMBER no-prepend
-
-.. index:: [no] neighbor PEER local-as AS-NUMBER no-prepend replace-as
-.. clicmd:: [no] neighbor PEER local-as AS-NUMBER no-prepend replace-as
-
-.. index:: [no] neighbor PEER local-as AS-NUMBER
-.. clicmd:: [no] neighbor PEER local-as AS-NUMBER
+   Sets a maximum number of prefixes we can receive from a given peer. If this
+   number is exceeded, the BGP session will be destroyed.
+
+   In practice, it is generally preferable to use a prefix-list to limit what
+   prefixes are received from the peer instead of using this knob. Tearing down
+   the BGP session when a limit is exceeded is far more destructive than merely
+   rejecting undesired prefixes. The prefix-list method is also much more
+   granular and offers much smarter matching criterion than number of received
+   prefixes, making it more suited to implementing policy.
+
+.. index:: [no] neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as]
+.. clicmd:: [no] neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as]
 
    Specify an alternate AS for this BGP process when interacting with the
    specified peer. With no modifiers, the specified local-as is prepended to
index 1705b6379e8aa9f0e1f129d09c22b737c68d8161..09bdc9cbea0ea238c0d71cd517514abb74b4fd2c 100644 (file)
@@ -123,7 +123,7 @@ but this time, the route command will apply to the VRF.
 .. code-block:: frr
 
    # case with VRF
-   configure terminal
+   configure
    vrf r1-cust1
     ip route 10.0.0.0/24 10.0.0.2
    exit-vrf
index b3ef028004f687dcf686c7669bc205f10a50548c..d6fd1fa561d4edfc20b876cb0d19dfa88085879f 100644 (file)
@@ -1386,7 +1386,7 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num)
 /* Configuration from terminal */
 DEFUN (config_terminal,
        config_terminal_cmd,
-       "configure terminal",
+       "configure [terminal]",
        "Configuration from vty interface\n"
        "Configuration terminal\n")
 {
index 6b91969218fdb0c704e179dfc0a880342b2c69e5..d2a4c3a432351193e2c24fcb4ecb40784924ad78 100644 (file)
@@ -1543,7 +1543,7 @@ char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size)
        return ptr;
 }
 
-unsigned prefix_hash_key(void *pp)
+unsigned prefix_hash_key(const void *pp)
 {
        struct prefix copy;
 
index d3c387e102945e9df619485f6e0db9749e0d250a..d57b43dac689e10d377a7afbef3510daf230b0ee 100644 (file)
@@ -466,7 +466,7 @@ extern int is_zero_mac(struct ethaddr *mac);
 extern int prefix_str2mac(const char *str, struct ethaddr *mac);
 extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size);
 
-extern unsigned prefix_hash_key(void *pp);
+extern unsigned prefix_hash_key(const void *pp);
 
 extern int str_to_esi(const char *str, esi_t *esi);
 extern char *esi_to_str(const esi_t *esi, char *buf, int size);
index 4898a8d0fa776e0650a6b440f4a3e8aa4b201e97..e9c8d9c4cfa7eee814b5f0c501eedc20c98da230 100644 (file)
@@ -1308,6 +1308,16 @@ int route_map_add_match(struct route_map_index *index, const char *match_name,
        for (rule = index->match_list.head; rule; rule = next) {
                next = rule->next;
                if (rule->cmd == cmd) {
+                       /* If the configured route-map match rule is exactly
+                        * the same as the existing configuration then,
+                        * ignore the duplicate configuration.
+                        */
+                       if (strcmp(match_arg, rule->rule_str) == 0) {
+                               if (cmd->func_free)
+                                       (*cmd->func_free)(compile);
+                               return RMAP_COMPILE_SUCCESS;
+                       }
+
                        route_map_rule_delete(&index->match_list, rule);
                        replaced = 1;
                }
@@ -2803,6 +2813,13 @@ DEFUN (rmap_call,
 
        assert(index);
 
+       /* If "call" is invoked with the same route-map name as
+        * the one previously configured then, ignore the duplicate
+        * configuration.
+        */
+       if (index->nextrm && (strcmp(index->nextrm, rmap) == 0))
+               return CMD_SUCCESS;
+
        if (index->nextrm) {
                route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
                                          index->nextrm, index->map->name);
index edba7f1932455181bf85657c238a40bab5c21a2d..2d42e2d55c904fe8942f497df267cd979c610df9 100644 (file)
@@ -33,12 +33,14 @@ DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node")
 
 static void route_table_free(struct route_table *);
 
-static bool route_table_hash_cmp(const void *a, const void *b)
+static int route_table_hash_cmp(const void *a, const void *b)
 {
        const struct prefix *pa = a, *pb = b;
-       return prefix_cmp(pa, pb) == 0;
+       return prefix_cmp(pa, pb);
 }
 
+DECLARE_HASH(rn_hash_node, struct route_node, nodehash, route_table_hash_cmp,
+            prefix_hash_key)
 /*
  * route_table_init_with_delegate
  */
@@ -49,8 +51,7 @@ route_table_init_with_delegate(route_table_delegate_t *delegate)
 
        rt = XCALLOC(MTYPE_ROUTE_TABLE, sizeof(struct route_table));
        rt->delegate = delegate;
-       rt->hash = hash_create(prefix_hash_key, route_table_hash_cmp,
-                              "route table hash");
+       rn_hash_node_init(&rt->hash);
        return rt;
 }
 
@@ -69,15 +70,14 @@ static struct route_node *route_node_new(struct route_table *table)
 static struct route_node *route_node_set(struct route_table *table,
                                         const struct prefix *prefix)
 {
-       struct route_node *node, *inserted;
+       struct route_node *node;
 
        node = route_node_new(table);
 
        prefix_copy(&node->p, prefix);
        node->table = table;
 
-       inserted = hash_get(node->table->hash, node, hash_alloc_intern);
-       assert(inserted == node);
+       rn_hash_node_add(&node->table->hash, node);
 
        return node;
 }
@@ -99,9 +99,6 @@ static void route_table_free(struct route_table *rt)
        if (rt == NULL)
                return;
 
-       hash_clean(rt->hash, NULL);
-       hash_free(rt->hash);
-
        node = rt->top;
 
        /* Bulk deletion of nodes remaining in this table.  This function is not
@@ -123,6 +120,7 @@ static void route_table_free(struct route_table *rt)
 
                tmp_node->table->count--;
                tmp_node->lock = 0; /* to cause assert if unlocked after this */
+               rn_hash_node_del(&rt->hash, tmp_node);
                route_node_free(rt, tmp_node);
 
                if (node != NULL) {
@@ -137,6 +135,7 @@ static void route_table_free(struct route_table *rt)
 
        assert(rt->count == 0);
 
+       rn_hash_node_fini(&rt->hash);
        XFREE(MTYPE_ROUTE_TABLE, rt);
        return;
 }
@@ -257,7 +256,7 @@ struct route_node *route_node_lookup(const struct route_table *table,
        prefix_copy(&p, pu.p);
        apply_mask(&p);
 
-       node = hash_get(table->hash, (void *)&p, NULL);
+       node = rn_hash_node_find(&table->hash, (void *)&p);
        return (node && node->info) ? route_lock_node(node) : NULL;
 }
 
@@ -270,7 +269,7 @@ struct route_node *route_node_lookup_maynull(const struct route_table *table,
        prefix_copy(&p, pu.p);
        apply_mask(&p);
 
-       node = hash_get(table->hash, (void *)&p, NULL);
+       node = rn_hash_node_find(&table->hash, (void *)&p);
        return node ? route_lock_node(node) : NULL;
 }
 
@@ -282,12 +281,11 @@ struct route_node *route_node_get(struct route_table *const table,
        struct route_node *new;
        struct route_node *node;
        struct route_node *match;
-       struct route_node *inserted;
        uint16_t prefixlen = p->prefixlen;
        const uint8_t *prefix = &p->u.prefix;
 
        apply_mask((struct prefix *)p);
-       node = hash_get(table->hash, (void *)p, NULL);
+       node = rn_hash_node_find(&table->hash, (void *)p);
        if (node && node->info)
                return route_lock_node(node);
 
@@ -314,8 +312,7 @@ struct route_node *route_node_get(struct route_table *const table,
                new->p.family = p->family;
                new->table = table;
                set_link(new, node);
-               inserted = hash_get(node->table->hash, new, hash_alloc_intern);
-               assert(inserted == new);
+               rn_hash_node_add(&table->hash, new);
 
                if (match)
                        set_link(match, new);
@@ -367,7 +364,7 @@ void route_node_delete(struct route_node *node)
 
        node->table->count--;
 
-       hash_release(node->table->hash, node);
+       rn_hash_node_del(&node->table->hash, node);
 
        /* WARNING: FRAGILE CODE!
         * route_node_free may have the side effect of free'ing the entire
index ce578e795c648f782fbffc8c64aead792fb8d5bf..3e3fb658aebe011df1ded9fde4bab856489b1b7c 100644 (file)
@@ -25,6 +25,7 @@
 #include "memory.h"
 #include "hash.h"
 #include "prefix.h"
+#include "typesafe.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -59,10 +60,12 @@ struct route_table_delegate_t_ {
        route_table_destroy_node_func_t destroy_node;
 };
 
+PREDECL_HASH(rn_hash_node)
+
 /* Routing table top structure. */
 struct route_table {
        struct route_node *top;
-       struct hash *hash;
+       struct rn_hash_node_head hash;
 
        /*
         * Delegate that performs certain functions for this table.
@@ -129,6 +132,7 @@ struct route_table {
        /* Lock of this radix */                                               \
        unsigned int table_rdonly(lock);                                       \
                                                                                \
+       struct rn_hash_node_item nodehash;                                     \
        /* Each node of route. */                                              \
        void *info;                                                            \
 
index bbf3ce8f1cb508c8aaa447064f02d67d954509ba..94002da599c23ea4d66a3184bbc63486f2825cc3 100644 (file)
@@ -275,7 +275,7 @@ macro_pure size_t prefix ## _count(struct prefix##_head *h)                    \
 #define DECLARE_SORTLIST_UNIQ(prefix, type, field, cmpfn)                      \
        _DECLARE_SORTLIST(prefix, type, field, cmpfn, cmpfn)                   \
                                                                                \
-macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item)  \
+macro_inline type *prefix ## _find(const struct prefix##_head *h, const type *item)  \
 {                                                                              \
        struct ssort_item *sitem = h->sh.first;                                \
        int cmpval = 0;                                                        \
@@ -383,7 +383,7 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item)         \
        *np = &item->field.hi;                                                 \
        return NULL;                                                           \
 }                                                                              \
-macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item)  \
+macro_inline type *prefix ## _find(const struct prefix##_head *h, const type *item)  \
 {                                                                              \
        if (!h->hh.tabshift)                                                   \
                return NULL;                                                   \
@@ -576,7 +576,7 @@ macro_inline int prefix ## __cmp(const struct sskip_item *a,                   \
        return cmpfn(container_of(a, type, field.si),                          \
                        container_of(b, type, field.si));                      \
 }                                                                              \
-macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item)  \
+macro_inline type *prefix ## _find(const struct prefix##_head *h, const type *item)  \
 {                                                                              \
        struct sskip_item *sitem = typesafe_skiplist_find(&h->sh,              \
                        &item->field.si, &prefix ## __cmp);                    \
index b708e86a2050891625ab06f6a1c44e4beed6d5a7..d829d01347e4e613b78ac3a30d99851d62bc28f8 100644 (file)
@@ -1181,8 +1181,16 @@ struct pim_upstream *pim_upstream_keep_alive_timer_proc(
                                "kat expired on %s[%s]; remove stream reference",
                                up->sg_str, pim->vrf->name);
                PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
-               up = pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
-       } else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) {
+
+               /* Return if upstream entry got deleted.*/
+               if (!pim_upstream_del(pim, up, __PRETTY_FUNCTION__))
+                       return NULL;
+       }
+       /* upstream reference would have been added to track the local
+        * membership if it is LHR. We have to clear it when KAT expires.
+        * Otherwise would result in stale entry with uncleared ref count.
+        */
+       if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) {
                struct pim_upstream *parent = up->parent;
 
                PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
index 77e6e9a3301fc79e0d53d62f0b6862f100b94539..1b48d10a09a0cab9b810a5c2017f9ef26730d28f 100755 (executable)
@@ -6347,6 +6347,35 @@ sub process {
                             "Please, only use 32 bit atomics.\n" . $herecurr);
                }
 
+# check for use of strcpy()
+               if ($line =~ /\bstrcpy\s*\(.*\)/) {
+                       ERROR("STRCPY",
+                             "strcpy() is error-prone; please use strlcpy()"  . $herecurr);
+               }
+
+# check for use of strncpy()
+               if ($line =~ /\bstrncpy\s*\(.*\)/) {
+                       WARN("STRNCPY",
+                            "strncpy() is error-prone; please use strlcpy() if possible, or memcpy()"  . $herecurr);
+               }
+
+# check for use of strcat()
+               if ($line =~ /\bstrcat\s*\(.*\)/) {
+                       ERROR("STRCAT",
+                             "strcat() is error-prone; please use strlcat() if possible"  . $herecurr);
+               }
+
+# check for use of strncat()
+               if ($line =~ /\bstrncat\s*\(.*\)/) {
+                       WARN("STRNCAT",
+                            "strncat() is error-prone; please use strlcat() if possible"  . $herecurr);
+               }
+
+# check for use of bzero()
+               if ($line =~ /\bbzero\s*\(.*\)/) {
+                       ERROR("BZERO",
+                             "bzero() is deprecated; use memset()"  . $herecurr);
+               }
        }
 
        # If we have no input at all, then there is nothing to report on
index eff1e996ed144a95f69151e1dff2e82e71b6bdc1..24effa70472460f9ac90225471d7bfebf503c743 100644 (file)
@@ -502,7 +502,7 @@ static int vtysh_execute_func(const char *line, int pager)
                        vtysh_execute("exit");
                } else if (tried) {
                        vtysh_execute("end");
-                       vtysh_execute("configure terminal");
+                       vtysh_execute("configure");
                }
        }
        /*
@@ -540,7 +540,7 @@ static int vtysh_execute_func(const char *line, int pager)
                if (pager && strncmp(line, "exit", 4))
                        vty_open_pager(vty);
 
-               if (!strcmp(cmd->string, "configure terminal")) {
+               if (!strcmp(cmd->string, "configure")) {
                        for (i = 0; i < array_size(vtysh_client); i++) {
                                cmd_stat = vtysh_client_execute(
                                        &vtysh_client[i], line);
@@ -674,7 +674,7 @@ int vtysh_mark_file(const char *filename)
        vty->node = CONFIG_NODE;
 
        vtysh_execute_no_pager("enable");
-       vtysh_execute_no_pager("configure terminal");
+       vtysh_execute_no_pager("configure");
        vty_buf_copy = XCALLOC(MTYPE_VTYSH_CMD, VTY_BUFSIZ);
 
        while (fgets(vty->buf, VTY_BUFSIZ, confp)) {
@@ -1744,7 +1744,7 @@ DEFUNSH(VTYSH_REALLYALL, vtysh_disable, vtysh_disable_cmd, "disable",
 }
 
 DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd,
-       "configure terminal",
+       "configure [terminal]",
        "Configuration from vty interface\n"
        "Configuration terminal\n")
 {
@@ -1786,7 +1786,7 @@ static int vtysh_exit(struct vty *vty)
        case BFD_NODE:
        case RPKI_NODE:
                vtysh_execute("end");
-               vtysh_execute("configure terminal");
+               vtysh_execute("configure");
                vty->node = CONFIG_NODE;
                break;
        case BGP_VPNV4_NODE:
index e26831e1a6427b7d4e2dda7f625aff06aa735d37..8a59cea6d0d5a7000c3999958c4d4faf0de0a93f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "zebra.h"
 #include "hook.h"
+#include "typesafe.h"
 #include "linklist.h"
 #include "prefix.h"
 #include "table.h"
 extern "C" {
 #endif
 
+typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
+
+PREDECL_LIST(rnh_list)
+
+/* Nexthop structure. */
+struct rnh {
+       uint8_t flags;
+
+#define ZEBRA_NHT_CONNECTED     0x1
+#define ZEBRA_NHT_DELETED       0x2
+#define ZEBRA_NHT_EXACT_MATCH   0x4
+
+       /* VRF identifier. */
+       vrf_id_t vrf_id;
+
+       afi_t afi;
+
+       rnh_type_t type;
+
+       uint32_t seqno;
+
+       struct route_entry *state;
+       struct prefix resolved_route;
+       struct list *client_list;
+
+       /* pseudowires dependent on this nh */
+       struct list *zebra_pseudowire_list;
+
+       struct route_node *node;
+
+       /*
+        * if this has been filtered for the client
+        */
+       int filtered[ZEBRA_ROUTE_MAX];
+
+       struct rnh_list_item rnh_list_item;
+};
+
 #define DISTANCE_INFINITY  255
 #define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
 
+PREDECL_LIST(re_list)
+
 struct route_entry {
        /* Link list. */
-       struct route_entry *next;
-       struct route_entry *prev;
+       struct re_list_item next;
 
        /* Nexthop structure */
        struct nexthop_group ng;
@@ -135,7 +175,7 @@ typedef struct rib_dest_t_ {
        /*
         * Doubly-linked list of routes for this prefix.
         */
-       struct route_entry *routes;
+       struct re_list_head routes;
 
        struct route_entry *selected_fib;
 
@@ -151,7 +191,7 @@ typedef struct rib_dest_t_ {
         * the data plane we will run evaluate_rnh
         * on these prefixes.
         */
-       struct list *nht;
+       struct rnh_list_head nht;
 
        /*
         * Linkage to put dest on the FPM processing queue.
@@ -160,6 +200,9 @@ typedef struct rib_dest_t_ {
 
 } rib_dest_t;
 
+DECLARE_LIST(rnh_list, struct rnh, rnh_list_item);
+DECLARE_LIST(re_list, struct route_entry, next);
+
 #define RIB_ROUTE_QUEUED(x)    (1 << (x))
 // If MQ_SIZE is modified this value needs to be updated.
 #define RIB_ROUTE_ANY_QUEUED    0x1F
@@ -187,14 +230,16 @@ typedef struct rib_dest_t_ {
  * Macro to iterate over each route for a destination (prefix).
  */
 #define RE_DEST_FOREACH_ROUTE(dest, re)                                        \
-       for ((re) = (dest) ? (dest)->routes : NULL; (re); (re) = (re)->next)
+       for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL; (re);    \
+            (re) = re_list_next(&((dest)->routes), (re)))
 
 /*
  * Same as above, but allows the current node to be unlinked.
  */
 #define RE_DEST_FOREACH_ROUTE_SAFE(dest, re, next)                             \
-       for ((re) = (dest) ? (dest)->routes : NULL;                            \
-            (re) && ((next) = (re)->next, 1); (re) = (next))
+       for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL;          \
+            (re) && ((next) = re_list_next(&((dest)->routes), (re)), 1);      \
+            (re) = (next))
 
 #define RNODE_FOREACH_RE(rn, re)                                               \
        RE_DEST_FOREACH_ROUTE (rib_dest_from_rnode(rn), re)
@@ -406,7 +451,7 @@ static inline struct route_entry *rnode_to_ribs(struct route_node *rn)
        if (!dest)
                return NULL;
 
-       return dest->routes;
+       return re_list_first(&dest->routes);
 }
 
 /*
index 2945a5ef9d186c09a9356371671b86e1b401aefd..3623852afd0bab61071c9a930661420f33ea9ab9 100644 (file)
@@ -1174,7 +1174,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
  */
 static int rib_can_delete_dest(rib_dest_t *dest)
 {
-       if (dest->routes) {
+       if (re_list_first(&dest->routes)) {
                return 0;
        }
 
@@ -1202,7 +1202,6 @@ static int rib_can_delete_dest(rib_dest_t *dest)
 void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
 {
        rib_dest_t *dest = rib_dest_from_rnode(rn);
-       struct listnode *node, *nnode;
        struct rnh *rnh;
 
        /*
@@ -1234,7 +1233,7 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
                 * nht resolution and as such we need to call the
                 * nexthop tracking evaluation code
                 */
-               for (ALL_LIST_ELEMENTS(dest->nht, node, nnode, rnh)) {
+               for_each (rnh_list, &dest->nht, rnh) {
                        struct zebra_vrf *zvrf =
                                zebra_vrf_lookup_by_id(rnh->vrf_id);
                        struct prefix *p = &rnh->node->p;
@@ -1310,7 +1309,7 @@ int rib_gc_dest(struct route_node *rn)
        zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence());
 
        dest->rnode = NULL;
-       list_delete(&dest->nht);
+       rnh_list_fini(&dest->nht);
        XFREE(MTYPE_RIB_DEST, dest);
        rn->info = NULL;
 
@@ -2355,7 +2354,7 @@ rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
        rib_dest_t *dest;
 
        dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
-       dest->nht = list_new();
+       rnh_list_init(&dest->nht);
        route_lock_node(rn); /* rn route table reference */
        rn->info = dest;
        dest->rnode = rn;
@@ -2403,7 +2402,6 @@ rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
 /* Add RE to head of the route node. */
 static void rib_link(struct route_node *rn, struct route_entry *re, int process)
 {
-       struct route_entry *head;
        rib_dest_t *dest;
        afi_t afi;
        const char *rmap_name;
@@ -2418,12 +2416,7 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process)
                dest = zebra_rib_create_dest(rn);
        }
 
-       head = dest->routes;
-       if (head) {
-               head->prev = re;
-       }
-       re->next = head;
-       dest->routes = re;
+       re_list_add_head(&dest->routes, re);
 
        afi = (rn->p.family == AF_INET)
                      ? AFI_IP
@@ -2473,14 +2466,7 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
 
        dest = rib_dest_from_rnode(rn);
 
-       if (re->next)
-               re->next->prev = re->prev;
-
-       if (re->prev)
-               re->prev->next = re->next;
-       else {
-               dest->routes = re->next;
-       }
+       re_list_del(&dest->routes, re);
 
        if (dest->selected_fib == re)
                dest->selected_fib = NULL;
index 220a8006d011c8cd08d1c5dafbe778a4e9adf37b..2917d0e7a8ff19c8604df1a70609d137db79ecc0 100644 (file)
@@ -119,7 +119,7 @@ static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
        }
 
        dest = rib_dest_from_rnode(rn);
-       listnode_delete(dest->nht, rnh);
+       rnh_list_del(&dest->nht, rnh);
        route_unlock_node(rn);
 }
 
@@ -145,7 +145,7 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
        }
 
        dest = rib_dest_from_rnode(rn);
-       listnode_add(dest->nht, rnh);
+       rnh_list_add_tail(&dest->nht, rnh);
        route_unlock_node(rn);
 }
 
@@ -251,7 +251,7 @@ void zebra_free_rnh(struct rnh *rnh)
                        route_unlock_node(rern);
 
                        dest = rib_dest_from_rnode(rern);
-                       listnode_delete(dest->nht, rnh);
+                       rnh_list_del(&dest->nht, rnh);
                }
        }
        free_state(rnh->vrf_id, rnh->state, rnh->node);
index 9cd9116eed01c9673ad1ecb4593c9dde5d26bf02..95a39411816ff4be7920f95c5934cd548deb2205 100644 (file)
 extern "C" {
 #endif
 
-typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
-
-/* Nexthop structure. */
-struct rnh {
-       uint8_t flags;
-
-#define ZEBRA_NHT_CONNECTED    0x1
-#define ZEBRA_NHT_DELETED       0x2
-#define ZEBRA_NHT_EXACT_MATCH   0x4
-
-       /* VRF identifier. */
-       vrf_id_t vrf_id;
-
-       afi_t afi;
-
-       rnh_type_t type;
-
-       uint32_t seqno;
-
-       struct route_entry *state;
-       struct prefix resolved_route;
-       struct list *client_list;
-
-       /* pseudowires dependent on this nh */
-       struct list *zebra_pseudowire_list;
-
-       struct route_node *node;
-
-       /*
-        * if this has been filtered for the client
-        */
-       int filtered[ZEBRA_ROUTE_MAX];
-};
-
 extern int zebra_rnh_ip_default_route;
 extern int zebra_rnh_ipv6_default_route;
 
index 315d5b49053935e629e09f42be0bb4c2735d1af0..5a18534ac4c54bedf0ba0fd39e74000a2dbade44 100644 (file)
@@ -355,7 +355,7 @@ void zebra_rtable_node_cleanup(struct route_table *table,
        if (node->info) {
                rib_dest_t *dest = node->info;
 
-               list_delete(&dest->nht);
+               rnh_list_fini(&dest->nht);
                XFREE(MTYPE_RIB_DEST, node->info);
        }
 }