]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #3543 from donaldsharp/eigrp_router_id_is_the_bee
authorRenato Westphal <renato@openbsd.org>
Wed, 2 Jan 2019 00:39:03 +0000 (22:39 -0200)
committerGitHub <noreply@github.com>
Wed, 2 Jan 2019 00:39:03 +0000 (22:39 -0200)
Eigrp router id cleanup

19 files changed:
babeld/babel_filter.c
babeld/babel_interface.c
babeld/babeld.c
babeld/babeld.h
eigrpd/eigrp_filter.c
eigrpd/eigrp_filter.h
eigrpd/eigrp_main.c
eigrpd/eigrp_structs.h
eigrpd/eigrp_vty.c
eigrpd/eigrpd.c
lib/distribute.c
lib/distribute.h
lib/vrf.c
ospfd/ospf_vty.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripngd.c
ripngd/ripngd.h
staticd/static_zebra.c

index 31778901a62efb8567c6ee8edbaa60c15ebb1246..28ba8e16a23793d77527c68c99b5741df2ef75b4 100644 (file)
@@ -39,10 +39,11 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
     struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
     babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL;
     struct prefix p;
-    struct distribute *dist;
+    struct distribute *dist = NULL;
     struct access_list *alist;
     struct prefix_list *plist;
     int distribute;
+    struct babel *babel;
 
     p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
     p.prefixlen = v4mapped(prefix) ? plen - 96 : plen;
@@ -81,7 +82,9 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
     }
 
     /* All interface filter check. */
-    dist = distribute_lookup (NULL);
+    babel = babel_lookup();
+    if (babel)
+        dist = distribute_lookup (babel->distribute_ctx, NULL);
     if (dist) {
         if (dist->list[distribute]) {
             alist = access_list_lookup (p.family, dist->list[distribute]);
index 7121ca28d4097f04a686e2e5e23b6c12f6428e7a..a8698bfce34dea829d7e4ba9d22f73785d811f5f 100644 (file)
@@ -1248,11 +1248,16 @@ DEFUN (show_babel_parameters,
        "Babel information\n"
        "Configuration information\n")
 {
+    struct babel *babel_ctx;
+
     vty_out (vty, "    -- Babel running configuration --\n");
     show_babel_main_configuration(vty);
-    vty_out (vty, "    -- distribution lists --\n");
-    config_show_distribute(vty);
 
+    babel_ctx = babel_lookup();
+    if (babel_ctx) {
+        vty_out (vty, "    -- distribution lists --\n");
+        config_show_distribute(vty, babel_ctx->distribute_ctx);
+    }
     return CMD_SUCCESS;
 }
 
index 0517cbea6d5a9e9f2a1c864a3d071823981f96e9..702c1fbabb7c8c6f7c9ef5e27900c41eb97fb5ea 100644 (file)
@@ -53,7 +53,8 @@ static int babel_read_protocol (struct thread *thread);
 static int babel_main_loop(struct thread *thread);
 static void babel_set_timer(struct timeval *timeout);
 static void babel_fill_with_next_timeout(struct timeval *tv);
-
+static void
+babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist);
 
 /* Informations relative to the babel running daemon. */
 static struct babel *babel_routing_process = NULL;
@@ -123,7 +124,7 @@ babel_config_write (struct vty *vty)
         }
     }
 
-    lines += config_write_distribute (vty);
+    lines += config_write_distribute (vty, babel_routing_process->distribute_ctx);
 
     return lines;
 }
@@ -154,8 +155,12 @@ babel_create_routing_process (void)
     thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
     /* wait a little: zebra will announce interfaces, addresses, routes... */
     thread_add_timer_msec(master, babel_init_routing_process, NULL, 200L, &babel_routing_process->t_update);
-    return 0;
 
+    /* Distribute list install. */
+    babel_routing_process->distribute_ctx = distribute_list_ctx_create (vrf_lookup_by_id(VRF_DEFAULT));
+    distribute_list_add_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
+    distribute_list_delete_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
+    return 0;
 fail:
     XFREE(MTYPE_BABEL, babel_routing_process);
     babel_routing_process = NULL;
@@ -315,6 +320,7 @@ babel_clean_routing_process()
         thread_cancel(babel_routing_process->t_update);
     }
 
+    distribute_list_delete(&babel_routing_process->distribute_ctx);
     XFREE(MTYPE_BABEL, babel_routing_process);
     babel_routing_process = NULL;
 }
@@ -539,7 +545,7 @@ resize_receive_buffer(int size)
 }
 
 static void
-babel_distribute_update (struct distribute *dist)
+babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist)
 {
     struct interface *ifp;
     babel_interface_nfo *babel_ifp;
@@ -574,11 +580,12 @@ babel_distribute_update (struct distribute *dist)
 static void
 babel_distribute_update_interface (struct interface *ifp)
 {
-    struct distribute *dist;
+    struct distribute *dist = NULL;
 
-    dist = distribute_lookup (ifp->name);
+    if (babel_routing_process)
+        dist = distribute_lookup(babel_routing_process->distribute_ctx, ifp->name);
     if (dist)
-        babel_distribute_update (dist);
+        babel_distribute_update (babel_routing_process->distribute_ctx, dist);
 }
 
 /* Update all interface's distribute list. */
@@ -736,9 +743,7 @@ babeld_quagga_init(void)
     prefix_list_delete_hook (babel_distribute_update_all);
 
     /* Distribute list install. */
-    distribute_list_init (BABEL_NODE);
-    distribute_list_add_hook (babel_distribute_update);
-    distribute_list_delete_hook (babel_distribute_update);
+    distribute_list_init(BABEL_NODE);
 }
 
 /* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
@@ -767,3 +772,7 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen,
     return 0;
 }
 
+struct babel *babel_lookup(void)
+{
+    return babel_routing_process;
+}
index bc284c1e96d5fa255ca6dbc1d0c8cbc5221423d1..752cc8620a84708dc5189d5c53d9fca6907dacf6 100644 (file)
@@ -111,6 +111,8 @@ struct babel
     /* Babel threads. */
     struct thread *t_read;    /* on Babel protocol's socket */
     struct thread *t_update;  /* timers */
+    /* distribute_ctx */
+    struct distribute_ctx *distribute_ctx;
 };
 
 extern struct zebra_privs_t babeld_privs;
@@ -125,6 +127,6 @@ extern int redistribute_filter(const unsigned char *prefix, unsigned short plen,
                                unsigned int ifindex, int proto);
 extern int resize_receive_buffer(int size);
 extern void schedule_neighbours_check(int msecs, int override);
-
+extern struct babel *babel_lookup(void);
 
 #endif /* BABEL_BABELD_H */
index c1bf1647d81fc08125f69a7e771d809b7a5262a4..93eed9452ccbb6ab4ad9174b45f4f4f2b90a0908 100644 (file)
@@ -62,7 +62,8 @@
 /*
  * Distribute-list update functions.
  */
-void eigrp_distribute_update(struct distribute *dist)
+void eigrp_distribute_update(struct distribute_ctx *ctx,
+                            struct distribute *dist)
 {
        struct interface *ifp;
        struct eigrp_interface *ei = NULL;
@@ -285,10 +286,15 @@ void eigrp_distribute_update(struct distribute *dist)
 void eigrp_distribute_update_interface(struct interface *ifp)
 {
        struct distribute *dist;
+       struct eigrp *eigrp;
 
-       dist = distribute_lookup(ifp->name);
+       eigrp = eigrp_lookup();
+       if (!eigrp)
+               return;
+       dist = distribute_lookup(eigrp->distribute_ctx, ifp->name);
        if (dist)
-               eigrp_distribute_update(dist);
+               eigrp_distribute_update(eigrp->distribute_ctx,
+                                       dist);
 }
 
 /* Update all interface's distribute list.
index caec19b0fbee46e39746b271796a8f24e6f8ec4a..34d00ecc133d0dd40f8f63f857269e145b0fa84e 100644 (file)
@@ -33,7 +33,8 @@
 #ifndef EIGRPD_EIGRP_FILTER_H_
 #define EIGRPD_EIGRP_FILTER_H_
 
-extern void eigrp_distribute_update(struct distribute *);
+extern void eigrp_distribute_update(struct distribute_ctx *ctx,
+                                   struct distribute *dist);
 extern void eigrp_distribute_update_interface(struct interface *);
 extern void eigrp_distribute_update_all(struct prefix_list *);
 extern void eigrp_distribute_update_all_wrapper(struct access_list *);
index 063fc5fec10dc61366e4ece1692921b32dc95005..b19b383e65c601dc509ace4b26ae872680f82c07 100644 (file)
@@ -217,8 +217,6 @@ int main(int argc, char **argv, char **envp)
 
        /* Distribute list install. */
        distribute_list_init(EIGRP_NODE);
-       distribute_list_add_hook(eigrp_distribute_update);
-       distribute_list_delete_hook(eigrp_distribute_update);
 
        frr_config_fork();
        frr_run(master);
index f661d9ec581bec5d57c34174dd7c7ec6bbda6833..644ab0829f8b32bc85f66bc590f720d841c2f383 100644 (file)
@@ -131,6 +131,9 @@ struct eigrp {
                uint32_t metric;
        } route_map[ZEBRA_ROUTE_MAX];
 
+       /* distribute_ctx */
+       struct distribute_ctx *distribute_ctx;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(eigrp)
index f29305e7a3117015726358fe6ef39c946e60b2dd..474f683989c07fbd5e75792136295f44f7c2f0e5 100644 (file)
@@ -174,7 +174,7 @@ static int config_write_eigrp_distribute(struct vty *vty, struct eigrp *eigrp)
        int write = 0;
 
        /* Distribute configuration. */
-       write += config_write_distribute(vty);
+       write += config_write_distribute(vty, eigrp->distribute_ctx);
 
        return write;
 }
index 2b2293f24f4c8c84f7dbf0c38445cf1fd86c0827..5541ec15f343f695971ee2f63624d5244533b555 100644 (file)
@@ -44,6 +44,7 @@
 #include "keychain.h"
 #include "libfrr.h"
 #include "lib_errors.h"
+#include "distribute.h"
 
 #include "eigrpd/eigrp_structs.h"
 #include "eigrpd/eigrpd.h"
@@ -55,6 +56,7 @@
 #include "eigrpd/eigrp_network.h"
 #include "eigrpd/eigrp_topology.h"
 #include "eigrpd/eigrp_memory.h"
+#include "eigrpd/eigrp_filter.h"
 
 DEFINE_QOBJ_TYPE(eigrp)
 
@@ -197,6 +199,13 @@ static struct eigrp *eigrp_new(const char *AS)
        eigrp->routemap[EIGRP_FILTER_IN] = NULL;
        eigrp->routemap[EIGRP_FILTER_OUT] = NULL;
 
+       /* Distribute list install. */
+       eigrp->distribute_ctx = distribute_list_ctx_create(
+                                          vrf_lookup_by_id(VRF_DEFAULT));
+       distribute_list_add_hook(eigrp->distribute_ctx,
+                                eigrp_distribute_update);
+       distribute_list_delete_hook(eigrp->distribute_ctx,
+                                   eigrp_distribute_update);
        QOBJ_REG(eigrp, eigrp);
        return eigrp;
 }
@@ -279,6 +288,7 @@ void eigrp_finish_final(struct eigrp *eigrp)
        listnode_delete(eigrp_om->eigrp, eigrp);
 
        stream_free(eigrp->ibuf);
+       distribute_list_delete(&eigrp->distribute_ctx);
        XFREE(MTYPE_EIGRP_TOP, eigrp);
 }
 
index 96979163323480b3a78a64a04bfb1fe40c357b4b..3a6b775bc88f300c6d97fa9c6d918c5469e1145c 100644 (file)
 #include "distribute.h"
 #include "memory.h"
 
+DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx")
 DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list")
 DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname")
 DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name")
 
-/* Hash of distribute list. */
-struct hash *disthash;
-
-/* Hook functions. */
-void (*distribute_add_hook)(struct distribute *);
-void (*distribute_delete_hook)(struct distribute *);
+struct list *dist_ctx_list;
 
 static struct distribute *distribute_new(void)
 {
@@ -62,7 +58,8 @@ static void distribute_free(struct distribute *dist)
        XFREE(MTYPE_DISTRIBUTE, dist);
 }
 
-static void distribute_free_if_empty(struct distribute *dist)
+static void distribute_free_if_empty(struct distribute_ctx *ctx,
+                                    struct distribute *dist)
 {
        int i;
 
@@ -70,12 +67,13 @@ static void distribute_free_if_empty(struct distribute *dist)
                if (dist->list[i] != NULL || dist->prefix[i] != NULL)
                        return;
 
-       hash_release(disthash, dist);
+       hash_release(ctx->disthash, dist);
        distribute_free(dist);
 }
 
 /* Lookup interface's distribute list. */
-struct distribute *distribute_lookup(const char *ifname)
+struct distribute *distribute_lookup(struct distribute_ctx *ctx,
+                                    const char *ifname)
 {
        struct distribute key;
        struct distribute *dist;
@@ -83,7 +81,7 @@ struct distribute *distribute_lookup(const char *ifname)
        /* temporary reference */
        key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
 
-       dist = hash_lookup(disthash, &key);
+       dist = hash_lookup(ctx->disthash, &key);
 
        if (key.ifname)
                XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
@@ -91,14 +89,18 @@ struct distribute *distribute_lookup(const char *ifname)
        return dist;
 }
 
-void distribute_list_add_hook(void (*func)(struct distribute *))
+void distribute_list_add_hook(struct distribute_ctx *ctx,
+                             void (*func)(struct distribute_ctx *ctx,
+                                          struct distribute *))
 {
-       distribute_add_hook = func;
+       ctx->distribute_add_hook = func;
 }
 
-void distribute_list_delete_hook(void (*func)(struct distribute *))
+void distribute_list_delete_hook(struct distribute_ctx *ctx,
+                                void (*func)(struct distribute_ctx *ctx,
+                                             struct distribute *))
 {
-       distribute_delete_hook = func;
+       ctx->distribute_delete_hook = func;
 }
 
 static void *distribute_hash_alloc(struct distribute *arg)
@@ -114,7 +116,8 @@ static void *distribute_hash_alloc(struct distribute *arg)
 }
 
 /* Make new distribute list and push into hash. */
-static struct distribute *distribute_get(const char *ifname)
+static struct distribute *distribute_get(struct distribute_ctx *ctx,
+                                        const char *ifname)
 {
        struct distribute key;
        struct distribute *ret;
@@ -122,7 +125,7 @@ static struct distribute *distribute_get(const char *ifname)
        /* temporary reference */
        key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
 
-       ret = hash_get(disthash, &key,
+       ret = hash_get(ctx->disthash, &key,
                       (void *(*)(void *))distribute_hash_alloc);
 
        if (key.ifname)
@@ -152,29 +155,32 @@ static bool distribute_cmp(const struct distribute *dist1,
 }
 
 /* Set access-list name to the distribute list. */
-static void distribute_list_set(const char *ifname, enum distribute_type type,
+static void distribute_list_set(struct distribute_ctx *ctx,
+                               const char *ifname, enum distribute_type type,
                                const char *alist_name)
 {
        struct distribute *dist;
 
-       dist = distribute_get(ifname);
+       dist = distribute_get(ctx, ifname);
 
        if (dist->list[type])
                XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
        dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
 
        /* Apply this distribute-list to the interface. */
-       (*distribute_add_hook)(dist);
+       (ctx->distribute_add_hook)(ctx, dist);
 }
 
 /* Unset distribute-list.  If matched distribute-list exist then
    return 1. */
-static int distribute_list_unset(const char *ifname, enum distribute_type type,
+static int distribute_list_unset(struct distribute_ctx *ctx,
+                                const char *ifname,
+                                enum distribute_type type,
                                 const char *alist_name)
 {
        struct distribute *dist;
 
-       dist = distribute_lookup(ifname);
+       dist = distribute_lookup(ctx, ifname);
        if (!dist)
                return 0;
 
@@ -187,39 +193,41 @@ static int distribute_list_unset(const char *ifname, enum distribute_type type,
        dist->list[type] = NULL;
 
        /* Apply this distribute-list to the interface. */
-       (*distribute_delete_hook)(dist);
+       (ctx->distribute_delete_hook)(ctx, dist);
 
        /* If all dist are NULL, then free distribute list. */
-       distribute_free_if_empty(dist);
+       distribute_free_if_empty(ctx, dist);
        return 1;
 }
 
 /* Set access-list name to the distribute list. */
-static void distribute_list_prefix_set(const char *ifname,
+static void distribute_list_prefix_set(struct distribute_ctx *ctx,
+                                      const char *ifname,
                                       enum distribute_type type,
                                       const char *plist_name)
 {
        struct distribute *dist;
 
-       dist = distribute_get(ifname);
+       dist = distribute_get(ctx, ifname);
 
        if (dist->prefix[type])
                XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
        dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
 
        /* Apply this distribute-list to the interface. */
-       (*distribute_add_hook)(dist);
+       (ctx->distribute_add_hook)(ctx, dist);
 }
 
 /* Unset distribute-list.  If matched distribute-list exist then
    return 1. */
-static int distribute_list_prefix_unset(const char *ifname,
+static int distribute_list_prefix_unset(struct distribute_ctx *ctx,
+                                       const char *ifname,
                                        enum distribute_type type,
                                        const char *plist_name)
 {
        struct distribute *dist;
 
-       dist = distribute_lookup(ifname);
+       dist = distribute_lookup(ctx, ifname);
        if (!dist)
                return 0;
 
@@ -232,10 +240,10 @@ static int distribute_list_prefix_unset(const char *ifname,
        dist->prefix[type] = NULL;
 
        /* Apply this distribute-list to the interface. */
-       (*distribute_delete_hook)(dist);
+       (ctx->distribute_delete_hook)(ctx, dist);
 
        /* If all dist are NULL, then free distribute list. */
-       distribute_free_if_empty(dist);
+       distribute_free_if_empty(ctx, dist);
        return 1;
 }
 
@@ -250,15 +258,17 @@ DEFUN (distribute_list,
        "Interface name\n")
 {
        int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
-
        /* Check of distribute list type. */
        enum distribute_type type = argv[2 + prefix]->arg[0] == 'i'
                                            ? DISTRIBUTE_V4_IN
                                            : DISTRIBUTE_V4_OUT;
 
        /* Set appropriate function call */
-       void (*distfn)(const char *, enum distribute_type, const char *) =
+       void (*distfn)(struct distribute_ctx *, const char *,
+                      enum distribute_type, const char *) =
                prefix ? &distribute_list_prefix_set : &distribute_list_set;
+       struct distribute_ctx *ctx =
+               (struct distribute_ctx *)listnode_head(dist_ctx_list);
 
        /* if interface is present, get name */
        const char *ifname = NULL;
@@ -266,7 +276,7 @@ DEFUN (distribute_list,
                ifname = argv[argc - 1]->arg;
 
        /* Get interface name corresponding distribute list. */
-       distfn(ifname, type, argv[1 + prefix]->arg);
+       distfn(ctx, ifname, type, argv[1 + prefix]->arg);
 
        return CMD_SUCCESS;
 }
@@ -283,15 +293,16 @@ DEFUN (ipv6_distribute_list,
        "Interface name\n")
 {
        int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
-
        /* Check of distribute list type. */
        enum distribute_type type = argv[3 + prefix]->arg[0] == 'i'
                                            ? DISTRIBUTE_V6_IN
                                            : DISTRIBUTE_V6_OUT;
 
        /* Set appropriate function call */
-       void (*distfn)(const char *, enum distribute_type, const char *) =
+       void (*distfn)(struct distribute_ctx *, const char *,
+                      enum distribute_type, const char *) =
                prefix ? &distribute_list_prefix_set : &distribute_list_set;
+       struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
 
        /* if interface is present, get name */
        const char *ifname = NULL;
@@ -299,7 +310,7 @@ DEFUN (ipv6_distribute_list,
                ifname = argv[argc - 1]->arg;
 
        /* Get interface name corresponding distribute list. */
-       distfn(ifname, type, argv[2 + prefix]->arg);
+       distfn(ctx, ifname, type, argv[2 + prefix]->arg);
 
        return CMD_SUCCESS;
 }
@@ -316,7 +327,6 @@ DEFUN (no_distribute_list,
        "Interface name\n")
 {
        int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
-
        int idx_alname = 2 + prefix;
        int idx_disttype = idx_alname + 1;
        enum distribute_type type =
@@ -324,16 +334,17 @@ DEFUN (no_distribute_list,
                DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
 
        /* Set appropriate function call */
-       int (*distfn)(const char *, enum distribute_type,
-                     const char *) =
+       int (*distfn)(struct distribute_ctx *, const char *,
+                      enum distribute_type, const char *) =
                prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
+       struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
 
        /* if interface is present, get name */
        const char *ifname = NULL;
        if (argv[argc - 1]->type == VARIABLE_TKN)
                ifname = argv[argc - 1]->arg;
        /* Get interface name corresponding distribute list. */
-       int ret = distfn(ifname, type, argv[2 + prefix]->arg);
+       int ret = distfn(ctx, ifname, type, argv[2 + prefix]->arg);
 
        if (!ret) {
                vty_out(vty, "distribute list doesn't exist\n");
@@ -355,16 +366,17 @@ DEFUN (no_ipv6_distribute_list,
        "Interface name\n")
 {
        int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
-
        int idx_alname = 3 + prefix;
        int idx_disttype = idx_alname + 1;
 
        enum distribute_type type =
                argv[idx_disttype]->arg[0] == 'i' ?
                DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
+       struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
 
        /* Set appropriate function call */
-       int (*distfn)(const char *, enum distribute_type, const char *) =
+       int (*distfn)(struct distribute_ctx *, const char *,
+                      enum distribute_type, const char *) =
                prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
 
        /* if interface is present, get name */
@@ -373,7 +385,7 @@ DEFUN (no_ipv6_distribute_list,
        if (argv[argc - 1]->type == VARIABLE_TKN)
                ifname = argv[argc - 1]->arg;
        /* Get interface name corresponding distribute list. */
-       int ret = distfn(ifname, type, argv[3 + prefix]->arg);
+       int ret = distfn(ctx, ifname, type, argv[3 + prefix]->arg);
 
        if (!ret) {
                vty_out(vty, "distribute list doesn't exist\n");
@@ -393,7 +405,7 @@ static int distribute_print(struct vty *vty, char *tab[], int is_prefix,
        return has_print;
 }
 
-int config_show_distribute(struct vty *vty)
+int config_show_distribute(struct vty *vty, struct distribute_ctx *dist_ctxt)
 {
        unsigned int i;
        int has_print = 0;
@@ -401,7 +413,7 @@ int config_show_distribute(struct vty *vty)
        struct distribute *dist;
 
        /* Output filter configuration. */
-       dist = distribute_lookup(NULL);
+       dist = distribute_lookup(dist_ctxt, NULL);
        vty_out(vty, "  Outgoing update filter list for all interface is");
        has_print = 0;
        if (dist) {
@@ -419,8 +431,8 @@ int config_show_distribute(struct vty *vty)
        else
                vty_out(vty, " not set\n");
 
-       for (i = 0; i < disthash->size; i++)
-               for (mp = disthash->index[i]; mp; mp = mp->next) {
+       for (i = 0; i < dist_ctxt->disthash->size; i++)
+               for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
                        dist = mp->data;
                        if (dist->ifname) {
                                vty_out(vty, "    %s filtered by",
@@ -447,7 +459,7 @@ int config_show_distribute(struct vty *vty)
 
 
        /* Input filter configuration. */
-       dist = distribute_lookup(NULL);
+       dist = distribute_lookup(dist_ctxt, NULL);
        vty_out(vty, "  Incoming update filter list for all interface is");
        has_print = 0;
        if (dist) {
@@ -465,8 +477,8 @@ int config_show_distribute(struct vty *vty)
        else
                vty_out(vty, " not set\n");
 
-       for (i = 0; i < disthash->size; i++)
-               for (mp = disthash->index[i]; mp; mp = mp->next) {
+       for (i = 0; i < dist_ctxt->disthash->size; i++)
+               for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
                        dist = mp->data;
                        if (dist->ifname) {
                                vty_out(vty, "    %s filtered by",
@@ -494,7 +506,8 @@ int config_show_distribute(struct vty *vty)
 }
 
 /* Configuration write function. */
-int config_write_distribute(struct vty *vty)
+int config_write_distribute(struct vty *vty,
+                           struct distribute_ctx *dist_ctxt)
 {
        unsigned int i;
        int j;
@@ -502,8 +515,8 @@ int config_write_distribute(struct vty *vty)
        struct hash_backet *mp;
        int write = 0;
 
-       for (i = 0; i < disthash->size; i++)
-               for (mp = disthash->index[i]; mp; mp = mp->next) {
+       for (i = 0; i < dist_ctxt->disthash->size; i++)
+               for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
                        struct distribute *dist;
 
                        dist = mp->data;
@@ -543,19 +556,38 @@ int config_write_distribute(struct vty *vty)
        return write;
 }
 
-/* Clear all distribute list. */
-void distribute_list_reset()
+void distribute_list_delete(struct distribute_ctx **ctx)
 {
-       hash_clean(disthash, (void (*)(void *))distribute_free);
+       if ((*ctx)->disthash) {
+               hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free);
+       }
+       if (!dist_ctx_list)
+               dist_ctx_list = list_new();
+       listnode_delete(dist_ctx_list, *ctx);
+       if (list_isempty(dist_ctx_list))
+               list_delete(&dist_ctx_list);
+       XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx));
 }
 
-/* Initialize distribute list related hash. */
-void distribute_list_init(int node)
+/* Initialize distribute list container */
+struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf)
 {
-       disthash = hash_create(
+       struct distribute_ctx *ctx;
+
+       ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx));
+       ctx->vrf = vrf;
+       ctx->disthash = hash_create(
                distribute_hash_make,
                (bool (*)(const void *, const void *))distribute_cmp, NULL);
+       if (!dist_ctx_list)
+               dist_ctx_list = list_new();
+       listnode_add(dist_ctx_list, ctx);
+       return ctx;
+}
 
+/* Initialize distribute list vty commands */
+void distribute_list_init(int node)
+{
        /* vtysh command-extraction doesn't grok install_element(node, ) */
        if (node == RIP_NODE) {
                install_element(RIP_NODE, &distribute_list_cmd);
@@ -563,10 +595,7 @@ void distribute_list_init(int node)
        } else if (node == RIPNG_NODE) {
                install_element(RIPNG_NODE, &distribute_list_cmd);
                install_element(RIPNG_NODE, &no_distribute_list_cmd);
-       }
-
-       /* install v6 */
-       if (node == RIPNG_NODE) {
+               /* install v6 */
                install_element(RIPNG_NODE, &ipv6_distribute_list_cmd);
                install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd);
        }
index 35c5e0d6b6e20594dd7d6bd4686d6767ed700f6c..44c699b38a15b217e5691427b684b93d2ebcabe9 100644 (file)
@@ -45,14 +45,36 @@ struct distribute {
        char *prefix[DISTRIBUTE_MAX];
 };
 
+struct distribute_ctx {
+       /* Hash of distribute list. */
+       struct hash *disthash;
+
+       /* Hook functions. */
+       void (*distribute_add_hook)(struct distribute_ctx *ctx,
+                                   struct distribute *dist);
+       void (*distribute_delete_hook)(struct distribute_ctx *ctx,
+                                      struct distribute *dist);
+
+       /* vrf information */
+       struct vrf *vrf;
+};
+
 /* Prototypes for distribute-list. */
-extern void distribute_list_init(int);
-extern void distribute_list_reset(void);
-extern void distribute_list_add_hook(void (*)(struct distribute *));
-extern void distribute_list_delete_hook(void (*)(struct distribute *));
-extern struct distribute *distribute_lookup(const char *);
-extern int config_write_distribute(struct vty *);
-extern int config_show_distribute(struct vty *);
+extern void distribute_list_init(int node);
+extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf);
+extern void distribute_list_delete(struct distribute_ctx **ctx);
+extern void distribute_list_add_hook(struct distribute_ctx *ctx,
+                                    void (*)(struct distribute_ctx *ctx,
+                                             struct distribute *));
+extern void distribute_list_delete_hook(struct distribute_ctx *ctx,
+                                       void (*)(struct distribute_ctx *ctx,
+                                                struct distribute *));
+extern struct distribute *distribute_lookup(struct distribute_ctx *ctx,
+                                           const char *ifname);
+extern int config_write_distribute(struct vty *vty,
+                                  struct distribute_ctx *ctx);
+extern int config_show_distribute(struct vty *vty,
+                                 struct distribute_ctx *ctx);
 
 extern enum filter_type distribute_apply_in(struct interface *,
                                            struct prefix *);
index 8409a1c9a13ed5e9bb4febd561d3c0e637ef8cd2..0c82f6a3cd451a4dda81f4605f62ef544ef47d7a 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -330,6 +330,8 @@ vrf_id_t vrf_name_to_id(const char *name)
        vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
                                       // id/ routine not used.
 
+       if (!name)
+               return vrf_id;
        vrf = vrf_lookup_by_name(name);
        if (vrf)
                vrf_id = vrf->vrf_id;
index fb08833b61148626abee8ecb020dd9eca6b8d023..3ab9c018ea2bbb78c18c9807175c6b8033aaea78 100644 (file)
@@ -5096,15 +5096,12 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
 }
 
 static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
-                                          int arg_base,
-                                          struct cmd_token **argv,
+                                          struct in_addr *router_id,
                                           bool use_json, uint8_t use_vrf)
 {
        struct listnode *node;
        struct ospf_neighbor *nbr;
        struct ospf_interface *oi;
-       struct in_addr router_id;
-       int ret;
        json_object *json = NULL;
 
        if (use_json)
@@ -5120,19 +5117,8 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
 
        ospf_show_vrf_name(ospf, vty, json, use_vrf);
 
-       ret = inet_aton(argv[arg_base]->arg, &router_id);
-       if (!ret) {
-               if (!use_json)
-                       vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
-               else {
-                       vty_out(vty, "{}\n");
-                       json_object_free(json);
-               }
-               return CMD_WARNING;
-       }
-
        for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
-               if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &router_id))) {
+               if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id))) {
                        show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, json,
                                                         use_json);
                }
@@ -5148,9 +5134,9 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
        return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_id,
+DEFPY (show_ip_ospf_neighbor_id,
        show_ip_ospf_neighbor_id_cmd,
-       "show ip ospf neighbor A.B.C.D [json]",
+       "show ip ospf neighbor A.B.C.D$router_id [json$json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
@@ -5159,23 +5145,22 @@ DEFUN (show_ip_ospf_neighbor_id,
        JSON_STR)
 {
        struct ospf *ospf;
-       bool uj = use_json(argc, argv);
-       struct listnode *node = NULL;
+       struct listnode *node;
        int ret = CMD_SUCCESS;
 
        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                if (!ospf->oi_running)
                        continue;
-               ret = show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj,
-                                                     0);
+               ret = show_ip_ospf_neighbor_id_common(vty, ospf, &router_id,
+                                                     !!json, 0);
        }
 
        return ret;
 }
 
-DEFUN (show_ip_ospf_instance_neighbor_id,
+DEFPY (show_ip_ospf_instance_neighbor_id,
        show_ip_ospf_instance_neighbor_id_cmd,
-       "show ip ospf (1-65535) neighbor A.B.C.D [json]",
+       "show ip ospf (1-65535)$instance neighbor A.B.C.D$router_id [json$json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
@@ -5184,13 +5169,8 @@ DEFUN (show_ip_ospf_instance_neighbor_id,
        "Neighbor ID\n"
        JSON_STR)
 {
-       int idx_number = 3;
-       int idx_router_id = 5;
        struct ospf *ospf;
-       unsigned short instance = 0;
-       bool uj = use_json(argc, argv);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
        ospf = ospf_lookup_instance(instance);
        if (ospf == NULL)
                return CMD_NOT_MY_INSTANCE;
@@ -5198,8 +5178,8 @@ DEFUN (show_ip_ospf_instance_neighbor_id,
        if (!ospf->oi_running)
                return CMD_SUCCESS;
 
-       return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv,
-                                              uj, 0);
+       return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json,
+                                              0);
 }
 
 static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
index 59a883225768ed5d10861c3cd36894b4d55ff5ee..0ce5324057cf849c30483021df4013e40dc54d60 100644 (file)
@@ -68,6 +68,9 @@ static void rip_output_process(struct connected *, struct sockaddr_in *, int,
 static int rip_triggered_update(struct thread *);
 static int rip_update_jitter(unsigned long);
 
+static void rip_distribute_update(struct distribute_ctx *ctx,
+                                 struct distribute *dist);
+
 /* RIP output routes type. */
 enum { rip_all_route, rip_changed_route };
 
@@ -328,7 +331,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
        }
 
        /* All interface filter check. */
-       dist = distribute_lookup(NULL);
+       dist = distribute_lookup(rip->distribute_ctx, NULL);
        if (dist) {
                if (dist->list[distribute]) {
                        alist = access_list_lookup(AFI_IP,
@@ -2702,7 +2705,13 @@ int rip_create(int socket)
        /* Create read and timer thread. */
        rip_event(RIP_READ, rip->sock);
        rip_event(RIP_UPDATE_EVENT, 1);
-
+       /* Distribute list install. */
+       rip->distribute_ctx = distribute_list_ctx_create(
+                                        vrf_lookup_by_id(VRF_DEFAULT));
+       distribute_list_add_hook(rip->distribute_ctx,
+                                rip_distribute_update);
+       distribute_list_delete_hook(rip->distribute_ctx,
+                                   rip_distribute_update);
        return 0;
 }
 
@@ -3121,7 +3130,7 @@ DEFUN (show_ip_rip_status,
        vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
 
        /* Filtering status show. */
-       config_show_distribute(vty);
+       config_show_distribute(vty, rip->distribute_ctx);
 
        /* Default metric information. */
        vty_out(vty, "  Default redistribution metric is %u\n",
@@ -3215,7 +3224,8 @@ static int config_write_rip(struct vty *vty)
                nb_cli_show_dnode_cmds(vty, dnode, false);
 
                /* Distribute configuration. */
-               write += config_write_distribute(vty);
+               write += config_write_distribute(vty,
+                                                rip->distribute_ctx);
 
                /* Interface routemap configuration */
                write += config_write_if_rmap(vty);
@@ -3227,7 +3237,8 @@ static int config_write_rip(struct vty *vty)
 static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1};
 
 /* Distribute-list update functions. */
-static void rip_distribute_update(struct distribute *dist)
+static void rip_distribute_update(struct distribute_ctx *ctx,
+                                 struct distribute *dist)
 {
        struct interface *ifp;
        struct rip_interface *ri;
@@ -3288,9 +3299,11 @@ void rip_distribute_update_interface(struct interface *ifp)
 {
        struct distribute *dist;
 
-       dist = distribute_lookup(ifp->name);
+       if (!rip)
+               return;
+       dist = distribute_lookup(rip->distribute_ctx, ifp->name);
        if (dist)
-               rip_distribute_update(dist);
+               rip_distribute_update(rip->distribute_ctx, dist);
 }
 
 /* Update all interface's distribute list. */
@@ -3367,6 +3380,7 @@ void rip_clean(void)
                route_table_finish(rip->table);
                route_table_finish(rip->neighbor);
 
+               distribute_list_delete(&rip->distribute_ctx);
                XFREE(MTYPE_RIP, rip);
                rip = NULL;
        }
@@ -3390,7 +3404,6 @@ static void rip_if_rmap_update(struct if_rmap *if_rmap)
                return;
 
        ri = ifp->info;
-
        if (if_rmap->routemap[IF_RMAP_IN]) {
                rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
                if (rmap)
@@ -3472,8 +3485,6 @@ void rip_init(void)
 
        /* Distribute list install. */
        distribute_list_init(RIP_NODE);
-       distribute_list_add_hook(rip_distribute_update);
-       distribute_list_delete_hook(rip_distribute_update);
 
        /* Route-map */
        rip_route_map_init();
index 91fab2a7a2e3d63b190b8be002db5c88f25e1393..7b8fe3a906b5f35e7766c4c96266105640a95ae2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "hook.h"
 #include "nexthop.h"
+#include "distribute.h"
 #include "rip_memory.h"
 
 /* RIP version number. */
@@ -150,6 +151,9 @@ struct rip {
                bool metric_config;
                uint8_t metric;
        } route_map[ZEBRA_ROUTE_MAX];
+
+       /* For distribute-list container */
+       struct distribute_ctx *distribute_ctx;
 };
 
 /* RIP routing table entry which belong to rip_packet. */
index 4ec9209da7670ed3f19efce2b50076da901f0673..ae8e8ab7d9d9ef099c2b57462fd6014a897d91a9 100644 (file)
@@ -52,6 +52,9 @@ enum { ripng_all_route,
        ripng_changed_route,
 };
 
+static void ripng_distribute_update(struct distribute_ctx *ctx,
+                                   struct distribute *dist);
+
 /* Prototypes. */
 void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
 
@@ -619,7 +622,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
        }
 
        /* All interface filter check. */
-       dist = distribute_lookup(NULL);
+       dist = distribute_lookup(ripng->distribute_ctx, NULL);
        if (dist) {
                if (dist->list[distribute]) {
                        alist = access_list_lookup(AFI_IP6,
@@ -1806,6 +1809,13 @@ int ripng_create(int socket)
        /* Initialize RIPng routig table. */
        ripng->table = agg_table_init();
 
+       /* Distribute list install. */
+       ripng->distribute_ctx = distribute_list_ctx_create(
+                                          vrf_lookup_by_id(VRF_DEFAULT));
+       distribute_list_add_hook(ripng->distribute_ctx,
+                                ripng_distribute_update);
+       distribute_list_delete_hook(ripng->distribute_ctx,
+                                   ripng_distribute_update);
        /* Make socket. */
        ripng->sock = socket;
 
@@ -2071,7 +2081,7 @@ DEFUN (show_ipv6_ripng_status,
                ripng->garbage_time);
 
        /* Filtering status show. */
-       config_show_distribute(vty);
+       config_show_distribute(vty, ripng->distribute_ctx);
 
        /* Default metric information. */
        vty_out(vty, "  Default redistribution metric is %d\n",
@@ -2290,7 +2300,8 @@ static int ripng_config_write(struct vty *vty)
        if (dnode) {
                nb_cli_show_dnode_cmds(vty, dnode, false);
 
-               config_write_distribute(vty);
+               config_write_distribute(vty,
+                                       ripng->distribute_ctx);
 
                config_write_if_rmap(vty);
 
@@ -2305,7 +2316,8 @@ static struct cmd_node cmd_ripng_node = {
        RIPNG_NODE, "%s(config-router)# ", 1,
 };
 
-static void ripng_distribute_update(struct distribute *dist)
+static void ripng_distribute_update(struct distribute_ctx *ctx,
+                                   struct distribute *dist)
 {
        struct interface *ifp;
        struct ripng_interface *ri;
@@ -2366,9 +2378,11 @@ void ripng_distribute_update_interface(struct interface *ifp)
 {
        struct distribute *dist;
 
-       dist = distribute_lookup(ifp->name);
+       if (!ripng)
+               return;
+       dist = distribute_lookup(ripng->distribute_ctx, ifp->name);
        if (dist)
-               ripng_distribute_update(dist);
+               ripng_distribute_update(ripng->distribute_ctx, dist);
 }
 
 /* Update all interface's distribute list. */
@@ -2450,6 +2464,7 @@ void ripng_clean()
                stream_free(ripng->ibuf);
                stream_free(ripng->obuf);
 
+               distribute_list_delete(&ripng->distribute_ctx);
                XFREE(MTYPE_RIPNG, ripng);
                ripng = NULL;
        } /* if (ripng) */
@@ -2563,8 +2578,6 @@ void ripng_init()
 
        /* Distribute list install. */
        distribute_list_init(RIPNG_NODE);
-       distribute_list_add_hook(ripng_distribute_update);
-       distribute_list_delete_hook(ripng_distribute_update);
 
        /* Route-map for interface. */
        ripng_route_map_init();
index 5b32374ace87238f08127ea0a80c941ba628ce02..1db7a83b114ad052b585c345b45b66c7d452c3e6 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <zclient.h>
 #include <vty.h>
+#include <distribute.h>
 
 #include "ripng_memory.h"
 
@@ -128,6 +129,9 @@ struct ripng {
                bool metric_config;
                uint8_t metric;
        } route_map[ZEBRA_ROUTE_MAX];
+
+       /* For distribute-list container */
+       struct distribute_ctx *distribute_ctx;
 };
 
 /* Routing table entry. */
index 1e23f597b0384eb4f30ff2e98b4c1617e011c59f..d6db60d3ed604676986901abd0db5005721c9a7a 100644 (file)
@@ -154,11 +154,11 @@ static int route_notify_owner(int command, struct zclient *zclient,
        uint32_t table_id;
        char buf[PREFIX_STRLEN];
 
-       prefix2str(&p, buf, sizeof(buf));
-
        if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note))
                return -1;
 
+       prefix2str(&p, buf, sizeof(buf));
+
        switch (note) {
        case ZAPI_ROUTE_FAIL_INSTALL:
                zlog_warn("%s: Route %s failed to install for table: %u",