]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #1280 from donaldsharp/eigrp_interface
authorRenato Westphal <renato@openbsd.org>
Thu, 5 Oct 2017 14:03:54 +0000 (11:03 -0300)
committerGitHub <noreply@github.com>
Thu, 5 Oct 2017 14:03:54 +0000 (11:03 -0300)
Eigrp interface cleanup

60 files changed:
babeld/babel_main.c
babeld/neighbour.c
bgpd/bgp_evpn_vty.c
bgpd/bgp_route.c
debian/control
doc/Building_FRR_on_Ubuntu1604.md
isisd/isis_adjacency.c
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isis_constants.h
isisd/isis_lsp.c
isisd/isis_lsp_hash.c [new file with mode: 0644]
isisd/isis_lsp_hash.h [new file with mode: 0644]
isisd/isis_pdu.c
isisd/subdir.am
ldpd/adjacency.c
ldpd/interface.c
ldpd/l2vpn.c
ldpd/ldp_vty.h
ldpd/ldp_vty_cmds.c
ldpd/ldp_vty_conf.c
ldpd/ldp_vty_exec.c
ldpd/ldpd.c
lib/sha256.c
lib/zclient.c
ospf6d/ospf6_route.c
ospfd/.gitignore
ospfd/ospf_abr.c
ospfd/ospf_apiserver.c
ospfd/ospf_asbr.c
ospfd/ospf_ase.c
ospfd/ospf_bfd.c
ospfd/ospf_dump.c
ospfd/ospf_flood.c
ospfd/ospf_flood.h
ospfd/ospf_interface.c
ospfd/ospf_lsa.c
ospfd/ospf_lsa.h
ospfd/ospf_main.c
ospfd/ospf_network.c
ospfd/ospf_network.h
ospfd/ospf_opaque.c
ospfd/ospf_packet.c
ospfd/ospf_ri.c
ospfd/ospf_route.c
ospfd/ospf_route.h
ospfd/ospf_routemap.c
ospfd/ospf_snmp.c
ospfd/ospf_spf.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospf_zebra.h
ospfd/ospfd.c
ospfd/ospfd.h
ospfd/subdir.am
pimd/pim_nht.c
tools/frr-reload.py
vtysh/vtysh.c
zebra/zebra_rnh.c

index 6a8f9bb75f59f110e1362dde592d18614fa2ad9a..239ab71f066f0a987407fc80a5935fa34bafe574 100644 (file)
@@ -279,8 +279,7 @@ babel_load_state_file(void)
     if(fd >= 0 && rc < 0) {
         zlog_err("unlink(babel-state): %s", safe_strerror(errno));
         /* If we couldn't unlink it, it's probably stale. */
-        close(fd);
-        fd = -1;
+        goto fini;
     }
     if(fd >= 0) {
         char buf[100];
@@ -315,9 +314,12 @@ babel_load_state_file(void)
                 zlog_err("Couldn't parse babel-state.");
             }
         }
-        close(fd);
-        fd = -1;
+        goto fini;
     }
+fini:
+    if (fd >= 0)
+        close(fd);
+    return ;
 }
 
 static void
index 5bf7e06fae8e2bf0d9750f30b37b80eb7c270dbd..48a32c4a9c39c658d86ee6564958475685ed20cf 100644 (file)
@@ -165,7 +165,6 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
     if(missed_hellos > 0) {
         neigh->reach >>= missed_hellos;
         neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos);
-        missed_hellos = 0;
         rc = 1;
     }
 
index 7454aec892b96d5f2d891bb7cc60aac6877b8055..145890846b75b5701e051855df2547e9f5edbf96 100644 (file)
@@ -2144,7 +2144,7 @@ static void write_vni_config_for_entry(struct hash_backet *backet,
 DEFUN (bgp_evpn_advertise_default_gw_vni,
        bgp_evpn_advertise_default_gw_vni_cmd,
        "advertise-default-gw",
-       "Advertise defualt g/w mac-ip routes in EVPN for a VNI\n")
+       "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
        VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
@@ -2184,7 +2184,7 @@ DEFUN (no_bgp_evpn_advertise_default_vni_gw,
 DEFUN (bgp_evpn_advertise_default_gw,
        bgp_evpn_advertise_default_gw_cmd,
        "advertise-default-gw",
-       "Advertise All defualt g/w mac-ip routes in EVPN\n")
+       "Advertise All default g/w mac-ip routes in EVPN\n")
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
 
index b9f23a387e5c14e0d18c06f01d69d7df27794a40..3307f8608814548ed35d2cf4fe16334bbeeeb1f3 100644 (file)
@@ -391,7 +391,7 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
        int exist_cluster;
        int internal_as_route;
        int confed_as_route;
-       int ret;
+       int ret = 0;
        char new_buf[PATH_ADDPATH_STR_BUFFER];
        char exist_buf[PATH_ADDPATH_STR_BUFFER];
        u_int32_t new_mm_seq;
@@ -488,8 +488,6 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
        }
 
        /* 1. Weight check. */
-       new_weight = exist_weight = 0;
-
        new_weight = newattr->weight;
        exist_weight = existattr->weight;
 
index d2b2e7cea698fa51ed4410b3ff51bd97d8481aaa..84b04c347d2e7e024198e1258801392cf1025aef 100644 (file)
@@ -10,7 +10,7 @@ XS-Testsuite: autopkgtest
 
 Package: frr
 Architecture: any
-Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute, ${misc:Depends}, libc-ares2
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2
 Pre-Depends: adduser
 Conflicts: zebra, zebra-pj, quagga
 Replaces: zebra, zebra-pj
index b33fb602539cd7041e3e9e01b19db5867fc81269..bdd0a962496f827e4e052b01d5bfe38fcdcee09c 100644 (file)
@@ -14,7 +14,7 @@ Add packages:
 
     apt-get install git autoconf automake libtool make gawk libreadline-dev \
        texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
-       python-pytest libc-ares-dev python3-dev libsystemd-dev
+       python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr
 
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
@@ -113,7 +113,7 @@ Add the following lines to `/etc/modules-load.d/modules.conf`:
 **Reboot** or use `sysctl -p` to apply the same config to the running system
 
 
-### Install the systemd service
+### Install the systemd service (if rebooted from last step, change directory back to frr directory)
 
     sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
     sudo install -m 644 tools/etc/default/frr /etc/default/frr
index 0afa65d726914aba336a0074f0d02729860d6191..c8b9a66e294a7ea39a88e183f78b01fc491a0151 100644 (file)
@@ -214,13 +214,11 @@ void isis_adj_state_change(struct isis_adjacency *adj,
                        } else if (new_state == ISIS_ADJ_DOWN) {
                                listnode_delete(circuit->u.bc.adjdb[level - 1],
                                                adj);
+
                                circuit->upadjcount[level - 1]--;
-                               if (circuit->upadjcount[level - 1] == 0) {
-                                       /* Clean lsp_queue when no adj is up. */
-                                       if (circuit->lsp_queue)
-                                               list_delete_all_node(
-                                                       circuit->lsp_queue);
-                               }
+                               if (circuit->upadjcount[level - 1] == 0)
+                                       isis_circuit_lsp_queue_clean(circuit);
+
                                isis_event_adjacency_state_change(adj,
                                                                  new_state);
                                del = true;
@@ -270,12 +268,9 @@ void isis_adj_state_change(struct isis_adjacency *adj,
                                if (adj->circuit->u.p2p.neighbor == adj)
                                        adj->circuit->u.p2p.neighbor = NULL;
                                circuit->upadjcount[level - 1]--;
-                               if (circuit->upadjcount[level - 1] == 0) {
-                                       /* Clean lsp_queue when no adj is up. */
-                                       if (circuit->lsp_queue)
-                                               list_delete_all_node(
-                                                       circuit->lsp_queue);
-                               }
+                               if (circuit->upadjcount[level - 1] == 0)
+                                       isis_circuit_lsp_queue_clean(circuit);
+
                                isis_event_adjacency_state_change(adj,
                                                                  new_state);
                                del = true;
index 1a978ee0423a5553c68c87c2727827b321037075..1c1385ab77a4c72640b617a8a59870ed8a9a4a0e 100644 (file)
@@ -45,6 +45,7 @@
 #include "isisd/isis_flags.h"
 #include "isisd/isis_circuit.h"
 #include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
 #include "isisd/isis_pdu.h"
 #include "isisd/isis_network.h"
 #include "isisd/isis_misc.h"
@@ -674,7 +675,8 @@ int isis_circuit_up(struct isis_circuit *circuit)
        isis_circuit_prepare(circuit);
 
        circuit->lsp_queue = list_new();
-       circuit->lsp_queue_last_cleared = time(NULL);
+       circuit->lsp_hash = isis_lsp_hash_new();
+       monotime(&circuit->lsp_queue_last_cleared);
 
        return ISIS_OK;
 }
@@ -739,14 +741,19 @@ void isis_circuit_down(struct isis_circuit *circuit)
        THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
        THREAD_TIMER_OFF(circuit->t_send_psnp[0]);
        THREAD_TIMER_OFF(circuit->t_send_psnp[1]);
+       THREAD_OFF(circuit->t_send_lsp);
        THREAD_OFF(circuit->t_read);
 
        if (circuit->lsp_queue) {
-               circuit->lsp_queue->del = NULL;
                list_delete(circuit->lsp_queue);
                circuit->lsp_queue = NULL;
        }
 
+       if (circuit->lsp_hash) {
+               isis_lsp_hash_free(circuit->lsp_hash);
+               circuit->lsp_hash = NULL;
+       }
+
        /* send one gratuitous hello to spead up convergence */
        if (circuit->is_type & IS_LEVEL_1)
                send_hello(circuit, IS_LEVEL_1);
@@ -1339,3 +1346,56 @@ void isis_circuit_init()
 
        isis_vty_init();
 }
+
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit)
+{
+       if (circuit->t_send_lsp)
+               return;
+       circuit->t_send_lsp = thread_add_event(master, send_lsp, circuit, 0, NULL);
+}
+
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp)
+{
+       if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp))
+               return;
+
+       listnode_add(circuit->lsp_queue, lsp);
+       isis_lsp_hash_add(circuit->lsp_hash, lsp);
+       isis_circuit_schedule_lsp_send(circuit);
+}
+
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit)
+{
+       if (!circuit->lsp_queue)
+               return;
+
+       list_delete_all_node(circuit->lsp_queue);
+       isis_lsp_hash_clean(circuit->lsp_hash);
+}
+
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+                                   struct isis_lsp *lsp)
+{
+       if (!circuit->lsp_queue)
+               return;
+
+       listnode_delete(circuit->lsp_queue, lsp);
+       isis_lsp_hash_release(circuit->lsp_hash, lsp);
+}
+
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit)
+{
+       if (!circuit->lsp_queue)
+               return NULL;
+
+       struct listnode *node = listhead(circuit->lsp_queue);
+       if (!node)
+               return NULL;
+
+       struct isis_lsp *rv = listgetdata(node);
+
+       list_delete_node(circuit->lsp_queue, node);
+       isis_lsp_hash_release(circuit->lsp_hash, rv);
+
+       return rv;
+}
index 5906efd2b8af205925f2667588555d3f547933f8..29694deb349584ccf6de0ab182566c5520f1472c 100644 (file)
@@ -34,6 +34,8 @@
 
 #define CIRCUIT_MAX 255
 
+struct isis_lsp;
+
 struct password {
        struct password *next;
        int len;
@@ -79,8 +81,10 @@ struct isis_circuit {
        struct thread *t_read;
        struct thread *t_send_csnp[2];
        struct thread *t_send_psnp[2];
+       struct thread *t_send_lsp;
        struct list *lsp_queue; /* LSPs to be txed (both levels) */
-       time_t lsp_queue_last_cleared; /* timestamp used to enforce transmit
+       struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
+       struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit
                                        * interval;
                                        * for scalability, use one timestamp per
                                        * circuit, instead of one per lsp per
@@ -195,4 +199,10 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit,
 int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
                                bool enabled);
 
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit);
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp);
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit);
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+                                   struct isis_lsp *lsp);
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit);
 #endif /* _ZEBRA_ISIS_CIRCUIT_H */
index f3a5a24dde577b0ca62913837b686c71ce99b431..b7b5d35c2e6df30671caab0c452ed0a406a30f4c 100644 (file)
@@ -73,7 +73,7 @@
 #define MAX_MIN_LSP_GEN_INTERVAL      120  /* RFC 4444 says 65535 */
 #define DEFAULT_MIN_LSP_GEN_INTERVAL  30
 
-#define MIN_LSP_TRANS_INTERVAL        5
+#define MIN_LSP_TRANS_INTERVAL        20000 /* Microseconds */
 
 #define MIN_CSNP_INTERVAL             1
 #define MAX_CSNP_INTERVAL             600
index 33c52804e4a60e0668ec5794c322697c920cf278..bee6abfdab9c182b837ec7eedfb6216c2805a8ea 100644 (file)
@@ -111,25 +111,15 @@ static void lsp_clear_data(struct isis_lsp *lsp)
 
 static void lsp_destroy(struct isis_lsp *lsp)
 {
-       struct listnode *cnode, *lnode, *lnnode;
-       struct isis_lsp *lsp_in_list;
+       struct listnode *cnode;
        struct isis_circuit *circuit;
 
        if (!lsp)
                return;
 
-       if (lsp->area->circuit_list) {
-               for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode,
-                                         circuit)) {
-                       if (circuit->lsp_queue == NULL)
-                               continue;
-                       for (ALL_LIST_ELEMENTS(circuit->lsp_queue, lnode,
-                                              lnnode, lsp_in_list))
-                               if (lsp_in_list == lsp)
-                                       list_delete_node(circuit->lsp_queue,
-                                                        lnode);
-               }
-       }
+       for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit))
+               isis_circuit_cancel_queued_lsp(circuit, lsp);
+
        ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags);
        ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
 
@@ -1890,12 +1880,15 @@ int lsp_tick(struct thread *thread)
                        if (listcount(lsp_list) > 0) {
                                for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
                                                          cnode, circuit)) {
-                                       int diff =
-                                               time(NULL)
-                                               - circuit->lsp_queue_last_cleared;
-                                       if (circuit->lsp_queue == NULL
-                                           || diff < MIN_LSP_TRANS_INTERVAL)
+                                       if (!circuit->lsp_queue)
                                                continue;
+
+                                       if (monotime_since(
+                                                 &circuit->lsp_queue_last_cleared,
+                                                 NULL) < MIN_LSP_TRANS_INTERVAL) {
+                                               continue;
+                                       }
+
                                        for (ALL_LIST_ELEMENTS_RO(
                                                     lsp_list, lspnode, lsp)) {
                                                if (circuit->upadjcount
@@ -1903,23 +1896,7 @@ int lsp_tick(struct thread *thread)
                                                    && ISIS_CHECK_FLAG(
                                                               lsp->SRMflags,
                                                               circuit)) {
-                                                       /* Add the lsp only if
-                                                        * it is not already in
-                                                        * lsp
-                                                        * queue */
-                                                       if (!listnode_lookup(
-                                                                   circuit->lsp_queue,
-                                                                   lsp)) {
-                                                               listnode_add(
-                                                                       circuit->lsp_queue,
-                                                                       lsp);
-                                                               thread_add_event(
-                                                                       master,
-                                                                       send_lsp,
-                                                                       circuit,
-                                                                       0,
-                                                                       NULL);
-                                                       }
+                                                       isis_circuit_queue_lsp(circuit, lsp);
                                                }
                                        }
                                }
diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c
new file mode 100644 (file)
index 0000000..9196128
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include "hash.h"
+#include "jhash.h"
+
+#include "isisd/isis_memory.h"
+#include "isisd/isis_flags.h"
+#include "dict.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
+
+DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash")
+
+struct isis_lsp_hash {
+       struct hash *h;
+};
+
+static unsigned lsp_hash_key(void *lp)
+{
+       struct isis_lsp *lsp = lp;
+
+       return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
+}
+
+static int lsp_hash_cmp(const void *a, const void *b)
+{
+       const struct isis_lsp *la = a, *lb = b;
+
+       return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2);
+}
+
+struct isis_lsp_hash *isis_lsp_hash_new(void)
+{
+       struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv));
+
+       rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL);
+       return rv;
+}
+
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih)
+{
+       hash_clean(ih->h, NULL);
+}
+
+void isis_lsp_hash_free(struct isis_lsp_hash *ih)
+{
+       isis_lsp_hash_clean(ih);
+       hash_free(ih->h);
+}
+
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+                           struct isis_lsp *lsp)
+{
+       return hash_lookup(ih->h, lsp);
+}
+
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+       struct isis_lsp *inserted;
+       inserted = hash_get(ih->h, lsp, hash_alloc_intern);
+       assert(inserted == lsp);
+}
+
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+       hash_release(ih->h, lsp);
+}
diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_lsp_hash.h
new file mode 100644 (file)
index 0000000..b50aa09
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef ISIS_LSP_HASH_H
+#define ISIS_LSP_HASH_H
+
+struct isis_lsp_hash;
+
+struct isis_lsp_hash *isis_lsp_hash_new(void);
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih);
+void isis_lsp_hash_free(struct isis_lsp_hash *ih);
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+                                     struct isis_lsp *lsp);
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+#endif
index a20051f8c366f7b4152f689bb554e0086cb1b6be..2f9e3caf1ccb8f3194d01172dbca57d00c38d18c 100644 (file)
@@ -2046,39 +2046,24 @@ int send_lsp(struct thread *thread)
 {
        struct isis_circuit *circuit;
        struct isis_lsp *lsp;
-       struct listnode *node;
        int clear_srm = 1;
        int retval = ISIS_OK;
 
        circuit = THREAD_ARG(thread);
        assert(circuit);
+       circuit->t_send_lsp = NULL;
 
-       if (!circuit->lsp_queue)
+       lsp = isis_circuit_lsp_queue_pop(circuit);
+       if (!lsp)
                return ISIS_OK;
-
-       node = listhead(circuit->lsp_queue);
-
-       /*
-        * Handle case where there are no LSPs on the queue. This can
-        * happen, for instance, if an adjacency goes down before this
-        * thread gets a chance to run.
-        */
-       if (!node)
-               return ISIS_OK;
-
-       /*
-        * Delete LSP from lsp_queue. If it's still in queue, it is assumed
-        * as 'transmit pending', but send_lsp may never be called again.
-        * Retry will happen because SRM flag will not be cleared.
-        */
-       lsp = listgetdata(node);
-       list_delete_node(circuit->lsp_queue, node);
-
        /* Set the last-cleared time if the queue is empty. */
        /* TODO: Is is possible that new lsps keep being added to the queue
         * that the queue is never empty? */
-       if (list_isempty(circuit->lsp_queue))
-               circuit->lsp_queue_last_cleared = time(NULL);
+       if (list_isempty(circuit->lsp_queue)) {
+               monotime(&circuit->lsp_queue_last_cleared);
+       } else {
+               isis_circuit_schedule_lsp_send(circuit);
+       }
 
        if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
                goto out;
index 6e49d4ec80ac0424c571d861df1f37ad3c16e333..7b56715fa917fa504782ecc0385106d0e181ab3c 100644 (file)
@@ -18,6 +18,7 @@ isisd_libisis_a_SOURCES = \
        isisd/isis_events.c \
        isisd/isis_flags.c \
        isisd/isis_lsp.c \
+       isisd/isis_lsp_hash.c \
        isisd/isis_memory.c \
        isisd/isis_misc.c \
        isisd/isis_mt.c \
@@ -46,6 +47,7 @@ noinst_HEADERS += \
        isisd/isis_events.h \
        isisd/isis_flags.h \
        isisd/isis_lsp.h \
+       isisd/isis_lsp_hash.h \
        isisd/isis_memory.h \
        isisd/isis_misc.h \
        isisd/isis_mt.h \
index 5b0723a0084c855eed00cc133df1ed0a6e19faae..7e4f0fd78b14b5232f821f07975c977fca1fec5c 100644 (file)
@@ -60,11 +60,11 @@ adj_compare(const struct adj *a, const struct adj *b)
 
        switch (a->source.type) {
        case HELLO_LINK:
-               if (strcmp(a->source.link.ia->iface->name,
-                   b->source.link.ia->iface->name) < 0)
+               if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+                   (char *)b->source.link.ia->iface->name) < 0)
                        return (-1);
-               if (strcmp(a->source.link.ia->iface->name,
-                   b->source.link.ia->iface->name) > 0)
+               if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+                   (char *)b->source.link.ia->iface->name) > 0)
                        return (1);
                return (ldp_addrcmp(a->source.link.ia->af,
                    &a->source.link.src_addr, &b->source.link.src_addr));
index ac48520f7bd4710dc2591326d6ccacf33739fbea..a18019c0c152d87ce6faf6d2f21145c7c48fbe70 100644 (file)
@@ -45,7 +45,7 @@ RB_GENERATE(iface_head, iface, entry, iface_compare)
 static __inline int
 iface_compare(const struct iface *a, const struct iface *b)
 {
-       return (strcmp(a->name, b->name));
+       return (if_cmp_name_func((char *)a->name, (char *)b->name));
 }
 
 struct iface *
index 9bad503b9c815f47a4294cdcff48d97394ae69ac..f9f577d564a1ffc84bf1c47bd7718a475b61b2f2 100644 (file)
@@ -114,7 +114,7 @@ l2vpn_exit(struct l2vpn *l2vpn)
 static __inline int
 l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b)
 {
-       return (strcmp(a->ifname, b->ifname));
+       return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
 }
 
 struct l2vpn_if *
@@ -177,7 +177,7 @@ l2vpn_if_update(struct l2vpn_if *lif)
 static __inline int
 l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b)
 {
-       return (strcmp(a->ifname, b->ifname));
+       return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
 }
 
 struct l2vpn_pw *
index 3d2072f1e51c8098c712ac98a6c347c91dfaa5ee..5e9df4aafe1c408ed5fa35eeefa17220136409dc 100644 (file)
@@ -38,8 +38,8 @@ int    ldp_l2vpn_config_write(struct vty *);
 int     ldp_debug_config_write(struct vty *);
 int     ldp_vty_mpls_ldp (struct vty *, const char *);
 int     ldp_vty_address_family (struct vty *, const char *, const char *);
-int     ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long);
-int     ldp_vty_disc_interval(struct vty *, const char *, const char *, long);
+int     ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long);
+int     ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long);
 int     ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *);
 int     ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long);
 int     ldp_vty_af_session_holdtime(struct vty *, const char *, long);
@@ -69,13 +69,16 @@ int  ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long);
 int     ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
 int     ldp_vty_clear_nbr(struct vty *, const char *);
 int     ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *);
-int     ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
+int     ldp_vty_show_binding(struct vty *, const char *, const char *, int,
+           const char *, unsigned long, unsigned long, const char *, const char *);
 int     ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
 int     ldp_vty_show_interface(struct vty *, const char *, const char *);
 int     ldp_vty_show_capabilities(struct vty *, const char *);
-int     ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
-int     ldp_vty_show_atom_binding(struct vty *, const char *);
-int     ldp_vty_show_atom_vc(struct vty *, const char *);
+int     ldp_vty_show_neighbor(struct vty *, const char *, int, const char *, const char *);
+int     ldp_vty_show_atom_binding(struct vty *, const char *, unsigned long,
+           unsigned long, const char *);
+int     ldp_vty_show_atom_vc(struct vty *, const char *, const char *,
+           const char *, const char *);
 int     ldp_vty_show_debugging(struct vty *);
 
 void    ldp_vty_init(void);
index cd92958d4c8fa2bd38ebbee71b56b60d4db5caa8..aa2e06dfb98dbdb513235fd3e0f07f333bbd932d 100644 (file)
@@ -112,30 +112,52 @@ DEFUN_NOSH(ldp_exit_address_family,
        return CMD_SUCCESS;
 }
 
-DEFPY  (ldp_discovery_holdtime,
-       ldp_discovery_holdtime_cmd,
-       "[no] discovery <hello|targeted-hello>$hello_type holdtime (1-65535)$holdtime",
+DEFPY  (ldp_discovery_link_holdtime,
+       ldp_discovery_link_holdtime_cmd,
+       "[no] discovery hello holdtime (1-65535)$holdtime",
        NO_STR
        "Configure discovery parameters\n"
        "LDP Link Hellos\n"
+       "Hello holdtime\n"
+       "Time (seconds) - 65535 implies infinite\n")
+{
+       return (ldp_vty_disc_holdtime(vty, no, HELLO_LINK, holdtime));
+}
+
+DEFPY  (ldp_discovery_targeted_holdtime,
+       ldp_discovery_targeted_holdtime_cmd,
+       "[no] discovery targeted-hello holdtime (1-65535)$holdtime",
+       NO_STR
+       "Configure discovery parameters\n"
        "LDP Targeted Hellos\n"
        "Hello holdtime\n"
        "Time (seconds) - 65535 implies infinite\n")
 {
-       return (ldp_vty_disc_holdtime(vty, no, hello_type, holdtime));
+       return (ldp_vty_disc_holdtime(vty, no, HELLO_TARGETED, holdtime));
 }
 
-DEFPY  (ldp_discovery_interval,
-       ldp_discovery_interval_cmd,
-       "[no] discovery <hello|targeted-hello>$hello_type interval (1-65535)$interval",
+DEFPY  (ldp_discovery_link_interval,
+       ldp_discovery_link_interval_cmd,
+       "[no] discovery hello interval (1-65535)$interval",
        NO_STR
        "Configure discovery parameters\n"
        "LDP Link Hellos\n"
+       "Hello interval\n"
+       "Time (seconds)\n")
+{
+       return (ldp_vty_disc_interval(vty, no, HELLO_LINK, interval));
+}
+
+DEFPY  (ldp_discovery_targeted_interval,
+       ldp_discovery_targeted_interval_cmd,
+       "[no] discovery targeted-hello interval (1-65535)$interval",
+       NO_STR
+       "Configure discovery parameters\n"
        "LDP Targeted Hellos\n"
        "Hello interval\n"
        "Time (seconds)\n")
 {
-       return (ldp_vty_disc_interval(vty, no, hello_type, interval));
+       return (ldp_vty_disc_interval(vty, no, HELLO_TARGETED, interval));
 }
 
 DEFPY  (ldp_dual_stack_transport_connection_prefer_ipv4,
@@ -581,17 +603,38 @@ DEFPY  (ldp_debug_mpls_ldp_messages_sent,
 
 DEFPY  (ldp_show_mpls_ldp_binding,
        ldp_show_mpls_ldp_binding_cmd,
-       "show mpls ldp [<ipv4|ipv6>]$af binding [detail]$detail [json]$json",
+       "show mpls ldp [<ipv4|ipv6>]$af binding\
+         [<A.B.C.D/M|X:X::X:X/M>$prefix [longer-prefixes$longer_prefixes]]\
+         [{\
+           neighbor A.B.C.D$nbr\
+           |local-label (0-1048575)$local_label\
+           |remote-label (0-1048575)$remote_label\
+         }]\
+        [detail]$detail [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "IPv4 Address Family\n"
        "IPv6 Address Family\n"
        "Label Information Base (LIB) information\n"
+       "Destination prefix (IPv4)\n"
+       "Destination prefix (IPv6)\n"
+       "Include longer matches\n"
+       "Display labels from LDP neighbor\n"
+       "Neighbor LSR-ID\n"
+       "Match locally assigned label values\n"
+       "Locally assigned label value\n"
+       "Match remotely assigned label values\n"
+       "Remotely assigned label value\n"
        "Show detailed information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_binding(vty, af, detail, json));
+       if (!local_label_str)
+               local_label = NO_LABEL;
+       if (!remote_label_str)
+               remote_label = NO_LABEL;
+       return (ldp_vty_show_binding(vty, af, prefix_str, !!longer_prefixes,
+           nbr_str, local_label, remote_label, detail, json));
 }
 
 DEFPY  (ldp_show_mpls_ldp_discovery,
@@ -637,52 +680,81 @@ DEFPY  (ldp_show_mpls_ldp_capabilities,
 
 DEFPY  (ldp_show_mpls_ldp_neighbor,
        ldp_show_mpls_ldp_neighbor_cmd,
-       "show mpls ldp neighbor [detail]$detail [json]$json",
+       "show mpls ldp neighbor [A.B.C.D]$lsr_id [detail]$detail [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "Neighbor information\n"
+       "Neighbor LSR-ID\n"
        "Show detailed information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_neighbor(vty, 0, detail, json));
+       return (ldp_vty_show_neighbor(vty, lsr_id_str, 0, detail, json));
 }
 
 DEFPY  (ldp_show_mpls_ldp_neighbor_capabilities,
        ldp_show_mpls_ldp_neighbor_capabilities_cmd,
-       "show mpls ldp neighbor capabilities [json]$json",
+       "show mpls ldp neighbor [A.B.C.D]$lsr_id capabilities [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "Neighbor information\n"
+       "Neighbor LSR-ID\n"
        "Display neighbor capability information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_neighbor(vty, 1, NULL, json));
+       return (ldp_vty_show_neighbor(vty, lsr_id_str, 1, NULL, json));
 }
 
 DEFPY  (ldp_show_l2vpn_atom_binding,
        ldp_show_l2vpn_atom_binding_cmd,
-       "show l2vpn atom binding [json]$json",
+       "show l2vpn atom binding\
+         [{\
+           A.B.C.D$peer\
+           |local-label (16-1048575)$local_label\
+           |remote-label (16-1048575)$remote_label\
+         }]\
+        [json]$json",
        "Show running system information\n"
        "Show information about Layer2 VPN\n"
        "Show Any Transport over MPLS information\n"
        "Show AToM label binding information\n"
+       "Destination address of the VC\n"
+       "Match locally assigned label values\n"
+       "Locally assigned label value\n"
+       "Match remotely assigned label values\n"
+       "Remotely assigned label value\n"
        JSON_STR)
 {
-       return (ldp_vty_show_atom_binding(vty, json));
+       if (!local_label_str)
+               local_label = NO_LABEL;
+       if (!remote_label_str)
+               remote_label = NO_LABEL;
+       return (ldp_vty_show_atom_binding(vty, peer_str, local_label,
+           remote_label, json));
 }
 
 DEFPY  (ldp_show_l2vpn_atom_vc,
        ldp_show_l2vpn_atom_vc_cmd,
-       "show l2vpn atom vc [json]$json",
+       "show l2vpn atom vc\
+         [{\
+           A.B.C.D$peer\
+           |interface IFNAME$ifname\
+           |vc-id (1-4294967295)$vcid\
+         }]\
+        [json]$json",
        "Show running system information\n"
        "Show information about Layer2 VPN\n"
        "Show Any Transport over MPLS information\n"
        "Show AToM virtual circuit information\n"
+       "Destination address of the VC\n"
+       "Local interface of the pseudowire\n"
+       "Interface's name\n"
+       "VC ID\n"
+       "VC ID\n"
        JSON_STR)
 {
-       return (ldp_vty_show_atom_vc(vty, json));
+       return (ldp_vty_show_atom_vc(vty, peer_str, ifname, vcid_str, json));
 }
 
 DEFUN_NOSH (ldp_show_debugging_mpls_ldp,
@@ -747,8 +819,10 @@ ldp_vty_init (void)
 
        install_element(LDP_NODE, &ldp_address_family_cmd);
        install_element(LDP_NODE, &no_ldp_address_family_cmd);
-       install_element(LDP_NODE, &ldp_discovery_holdtime_cmd);
-       install_element(LDP_NODE, &ldp_discovery_interval_cmd);
+       install_element(LDP_NODE, &ldp_discovery_link_holdtime_cmd);
+       install_element(LDP_NODE, &ldp_discovery_targeted_holdtime_cmd);
+       install_element(LDP_NODE, &ldp_discovery_link_interval_cmd);
+       install_element(LDP_NODE, &ldp_discovery_targeted_interval_cmd);
        install_element(LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd);
        install_element(LDP_NODE, &ldp_dual_stack_cisco_interop_cmd);
        install_element(LDP_NODE, &ldp_neighbor_password_cmd);
@@ -756,8 +830,10 @@ ldp_vty_init (void)
        install_element(LDP_NODE, &ldp_neighbor_ttl_security_cmd);
        install_element(LDP_NODE, &ldp_router_id_cmd);
 
-       install_element(LDP_IPV4_NODE, &ldp_discovery_holdtime_cmd);
-       install_element(LDP_IPV4_NODE, &ldp_discovery_interval_cmd);
+       install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd);
+       install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd);
+       install_element(LDP_IPV4_NODE, &ldp_discovery_link_interval_cmd);
+       install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_interval_cmd);
        install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd);
        install_element(LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd);
        install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_cmd);
@@ -771,8 +847,10 @@ ldp_vty_init (void)
        install_element(LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd);
        install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
 
-       install_element(LDP_IPV6_NODE, &ldp_discovery_holdtime_cmd);
-       install_element(LDP_IPV6_NODE, &ldp_discovery_interval_cmd);
+       install_element(LDP_IPV6_NODE, &ldp_discovery_link_holdtime_cmd);
+       install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_holdtime_cmd);
+       install_element(LDP_IPV6_NODE, &ldp_discovery_link_interval_cmd);
+       install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_interval_cmd);
        install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd);
        install_element(LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd);
        install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_cmd);
@@ -785,11 +863,11 @@ ldp_vty_init (void)
        install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
        install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
 
-       install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_holdtime_cmd);
-       install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_interval_cmd);
+       install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+       install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_interval_cmd);
 
-       install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_holdtime_cmd);
-       install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_interval_cmd);
+       install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+       install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_interval_cmd);
 
        install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd);
        install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd);
index e938582d0d53096055054614387eb7dc2f162f06..76c602afbb126b6ed05662d45d1cc3658f6880af 100644 (file)
@@ -233,6 +233,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
 
        ldp_af_iface_config_write(vty, af);
 
+       vty_out(vty, "  !\n");
        vty_out(vty, " exit-address-family\n");
 }
 
@@ -459,20 +460,13 @@ ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str)
        return (CMD_SUCCESS);
 }
 
-int
-ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
-    const char *hello_type_str, long secs)
+int ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
+    enum hello_type hello_type, long secs)
 {
        struct ldpd_af_conf     *af_conf;
        struct iface            *iface;
        struct iface_af         *ia;
        int                      af;
-       enum hello_type          hello_type;
-
-       if (hello_type_str[0] == 'h')
-               hello_type = HELLO_LINK;
-       else
-               hello_type = HELLO_TARGETED;
 
        switch (vty->node) {
        case LDP_NODE:
@@ -547,18 +541,12 @@ ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
 
 int
 ldp_vty_disc_interval(struct vty *vty, const char *negate,
-    const char *hello_type_str, long secs)
+    enum hello_type hello_type, long secs)
 {
        struct ldpd_af_conf     *af_conf;
        struct iface            *iface;
        struct iface_af         *ia;
        int                      af;
-       enum hello_type          hello_type;
-
-       if (hello_type_str[0] == 'h')
-               hello_type = HELLO_LINK;
-       else
-               hello_type = HELLO_TARGETED;
 
        switch (vty->node) {
        case LDP_NODE:
index ad5e79c721be0e39bdd16502bfd9e037669f320c..66c127abdc982b1f67a0710c49f26f35136c1adf 100644 (file)
@@ -44,9 +44,28 @@ struct show_params {
        int             family;
        union ldpd_addr addr;
        uint8_t         prefixlen;
-       int             capabilities;
        int             detail;
        int             json;
+       union {
+               struct {
+                       struct in_addr lsr_id;
+                       int capabilities;
+               } neighbor;
+               struct {
+                       struct prefix prefix;
+                       int longer_prefixes;
+                       struct in_addr neighbor;
+                       uint32_t local_label;
+                       uint32_t remote_label;
+               } lib;
+               struct {
+                       struct in_addr peer;
+                       uint32_t local_label;
+                       uint32_t remote_label;
+                       char ifname[IFNAMSIZ];
+                       uint32_t vcid;
+               } l2vpn;
+       };
 };
 
 #define LDPBUFSIZ      65535
@@ -1005,6 +1024,12 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
+               rt = imsg->data;
+
+               if (params->lib.remote_label != NO_LABEL &&
+                   params->lib.remote_label != rt->remote_label)
+                       return (0);
+               /* FALLTHROUGH */
        case IMSG_CTL_SHOW_LIB_RCVD:
                rt = imsg->data;
 
@@ -1012,9 +1037,6 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
                    !rt->no_downstream)
                        break;
 
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       break;
-
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
 
@@ -1039,7 +1061,7 @@ static int
 show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
 {
        struct ctl_rt   *rt = NULL;
-       char             dstnet[BUFSIZ];
+       static char      dstnet[BUFSIZ];
        static int       upstream, downstream;
        size_t           buflen;
        static char      sent_buffer[LDPBUFSIZ];
@@ -1047,38 +1069,25 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
-       case IMSG_CTL_SHOW_LIB_SENT:
-       case IMSG_CTL_SHOW_LIB_RCVD:
-       case IMSG_CTL_SHOW_LIB_END:
                rt = imsg->data;
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       return (0);
-               break;
-       default:
-               break;
-       }
 
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_LIB_BEGIN:
                upstream = 0;
                downstream = 0;
                sent_buffer[0] = '\0';
                rcvd_buffer[0] = '\0';
-
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
-
-               vty_out (vty, "%s\n", dstnet);
-               vty_out (vty, "%-8sLocal binding: label: %s\n", "",
-                   log_label(rt->local_label));
                break;
        case IMSG_CTL_SHOW_LIB_SENT:
+               rt = imsg->data;
+
                upstream = 1;
                buflen = strlen(sent_buffer);
                snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
                    "%12s%s:0\n", "", inet_ntoa(rt->nexthop));
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
+               rt = imsg->data;
                downstream = 1;
                buflen = strlen(rcvd_buffer);
                snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
@@ -1087,6 +1096,14 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
                    rt->in_use ? " (in use)" : "");
                break;
        case IMSG_CTL_SHOW_LIB_END:
+               rt = imsg->data;
+
+               if (params->lib.remote_label != NO_LABEL &&
+                   !downstream)
+                       break;
+               vty_out(vty, "%s\n", dstnet);
+               vty_out(vty, "%-8sLocal binding: label: %s\n", "",
+                   log_label(rt->local_label));
                if (upstream) {
                        vty_out (vty, "%-8sAdvertised to:\n", "");
                        vty_out(vty, "%s", sent_buffer);
@@ -1170,19 +1187,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
-       case IMSG_CTL_SHOW_LIB_SENT:
-       case IMSG_CTL_SHOW_LIB_RCVD:
-       case IMSG_CTL_SHOW_LIB_END:
                rt = imsg->data;
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       return (0);
-               break;
-       default:
-               break;
-       }
 
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_LIB_BEGIN:
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
 
@@ -1201,12 +1207,16 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
                json_object_object_add(json, dstnet, json_lib_entry);
                break;
        case IMSG_CTL_SHOW_LIB_SENT:
+               rt = imsg->data;
+
                json_adv_label = json_object_new_object();
                json_object_string_add(json_adv_label, "neighborId",
                    inet_ntoa(rt->nexthop));
                json_object_array_add(json_adv_labels, json_adv_label);
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
+               rt = imsg->data;
+
                json_remote_label = json_object_new_object();
                json_object_string_add(json_remote_label, "neighborId",
                    inet_ntoa(rt->nexthop));
@@ -1410,88 +1420,272 @@ ldp_vty_connect(struct imsgbuf *ibuf)
 }
 
 static int
-ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg,
     struct show_params *params, json_object *json)
 {
        int      ret;
 
-       switch (cmd) {
-       case SHOW_IFACE:
+       if (params->json)
+               ret = show_interface_msg_json(imsg, params, json);
+       else
+               ret = show_interface_msg(vty, imsg, params);
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       int      ret;
+
+       if (params->detail) {
                if (params->json)
-                       ret = show_interface_msg_json(imsg, params, json);
+                       ret = show_discovery_detail_msg_json(imsg, params,
+                           json);
                else
-                       ret = show_interface_msg(vty, imsg, params);
-               break;
-       case SHOW_DISC:
-               if (params->detail) {
-                       if (params->json)
-                               ret = show_discovery_detail_msg_json(imsg,
-                                   params, json);
-                       else
-                               ret = show_discovery_detail_msg(vty, imsg,
-                                   params);
-               } else {
-                       if (params->json)
-                               ret = show_discovery_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_discovery_msg(vty, imsg, params);
+                       ret = show_discovery_detail_msg(vty, imsg, params);
+       } else {
+               if (params->json)
+                       ret = show_discovery_msg_json(imsg, params, json);
+               else
+                       ret = show_discovery_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       static bool      filtered = false;
+       struct ctl_nbr  *nbr;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_NBR:
+               filtered = false;
+               nbr = imsg->data;
+
+               if (params->neighbor.lsr_id.s_addr != INADDR_ANY &&
+                   params->neighbor.lsr_id.s_addr != nbr->id.s_addr) {
+                       filtered = true;
+                       return (0);
                }
                break;
-       case SHOW_NBR:
-               if (params->capabilities) {
-                       if (params->json)
-                               ret = show_nbr_capabilities_msg_json(imsg,
-                                   params, json);
-                       else
-                               ret = show_nbr_capabilities_msg(vty, imsg,
-                                   params);
-               } else if (params->detail) {
-                       if (params->json)
-                               ret = show_nbr_detail_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_nbr_detail_msg(vty, imsg, params);
-               } else {
-                       if (params->json)
-                               ret = show_nbr_msg_json(imsg, params, json);
-                       else
-                               ret = show_nbr_msg(vty, imsg, params);
-               }
+       case IMSG_CTL_SHOW_NBR_DISC:
+       case IMSG_CTL_SHOW_NBR_END:
+               if (filtered)
+                       return (0);
                break;
-       case SHOW_LIB:
-               if (params->detail) {
-                       if (params->json)
-                               ret = show_lib_detail_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_lib_detail_msg(vty, imsg, params);
-               } else {
-                       if (params->json)
-                               ret = show_lib_msg_json(imsg, params, json);
-                       else
-                               ret = show_lib_msg(vty, imsg, params);
-               }
+       default:
                break;
-       case SHOW_L2VPN_PW:
+       }
+
+       if (params->neighbor.capabilities) {
+               if (params->json)
+                       ret = show_nbr_capabilities_msg_json(imsg, params,
+                           json);
+               else
+                       ret = show_nbr_capabilities_msg(vty, imsg, params);
+       } else if (params->detail) {
+               if (params->json)
+                       ret = show_nbr_detail_msg_json(imsg, params, json);
+               else
+                       ret = show_nbr_detail_msg(vty, imsg, params);
+       } else {
                if (params->json)
-                       ret = show_l2vpn_pw_msg_json(imsg, params, json);
+                       ret = show_nbr_msg_json(imsg, params, json);
                else
-                       ret = show_l2vpn_pw_msg(vty, imsg, params);
+                       ret = show_nbr_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       static bool      filtered = false;
+       struct ctl_rt   *rt = NULL;
+       struct prefix    prefix;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_BEGIN:
+               filtered = false;
                break;
-       case SHOW_L2VPN_BINDING:
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+       case IMSG_CTL_SHOW_LIB_END:
+               if (filtered)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_BEGIN:
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+       case IMSG_CTL_SHOW_LIB_END:
+               rt = imsg->data;
+
+               if (params->family != AF_UNSPEC && params->family != rt->af) {
+                       filtered = true;
+                       return (0);
+               }
+
+               prefix.family = rt->af;
+               prefix.prefixlen = rt->prefixlen;
+               memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val));
+               if (params->lib.prefix.family != AF_UNSPEC) {
+                       if (!params->lib.longer_prefixes &&
+                           !prefix_same(&params->lib.prefix, &prefix)) {
+                               filtered = true;
+                               return (0);
+                       } else if (params->lib.longer_prefixes &&
+                           !prefix_match(&params->lib.prefix, &prefix)) {
+                               filtered = true;
+                               return (0);
+                       }
+               }
+
+               if (params->lib.local_label != NO_LABEL &&
+                   params->lib.local_label != rt->local_label) {
+                       filtered = true;
+                       return (0);
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+               if (params->lib.neighbor.s_addr != INADDR_ANY &&
+                   params->lib.neighbor.s_addr != rt->nexthop.s_addr)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_RCVD:
+               if (params->lib.remote_label != NO_LABEL &&
+                   params->lib.remote_label != rt->remote_label)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       if (params->detail) {
                if (params->json)
-                       ret = show_l2vpn_binding_msg_json(imsg, params, json);
+                       ret = show_lib_detail_msg_json(imsg, params, json);
                else
-                       ret = show_l2vpn_binding_msg(vty, imsg, params);
+                       ret = show_lib_detail_msg(vty, imsg, params);
+       } else {
+               if (params->json)
+                       ret = show_lib_msg_json(imsg, params, json);
+               else
+                       ret = show_lib_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       struct ctl_pw   *pw;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_L2VPN_PW:
+               pw = imsg->data;
+               if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+                   params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+                       return (0);
+               if (params->l2vpn.ifname[0] != '\0' &&
+                   strcmp(params->l2vpn.ifname, pw->ifname))
+                       return (0);
+               if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid)
+                       return (0);
                break;
        default:
-               return (0);
+               break;
        }
 
+       if (params->json)
+               ret = show_l2vpn_pw_msg_json(imsg, params, json);
+       else
+               ret = show_l2vpn_pw_msg(vty, imsg, params);
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       struct ctl_pw   *pw;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_L2VPN_BINDING:
+               pw = imsg->data;
+               if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+                   params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+                       return (0);
+               if (params->l2vpn.local_label != NO_LABEL &&
+                   params->l2vpn.local_label != pw->local_label)
+                       return (0);
+               if (params->l2vpn.remote_label != NO_LABEL &&
+                   params->l2vpn.remote_label != pw->remote_label)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       if (params->json)
+               ret = show_l2vpn_binding_msg_json(imsg, params, json);
+       else
+               ret = show_l2vpn_binding_msg(vty, imsg, params);
+
        return (ret);
 }
 
+static int
+ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+    struct show_params *params, json_object *json)
+{
+       switch (cmd) {
+       case SHOW_IFACE:
+               return (ldp_vty_dispatch_iface(vty, imsg, params, json));
+       case SHOW_DISC:
+               return (ldp_vty_dispatch_disc(vty, imsg, params, json));
+       case SHOW_NBR:
+               return (ldp_vty_dispatch_nbr(vty, imsg, params, json));
+       case SHOW_LIB:
+               return (ldp_vty_dispatch_lib(vty, imsg, params, json));
+       case SHOW_L2VPN_PW:
+               return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json));
+       case SHOW_L2VPN_BINDING:
+               return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params,
+                   json));
+       default:
+               return (0);
+       }
+}
+
 static int
 ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
     struct show_params *params)
@@ -1565,7 +1759,9 @@ ldp_vty_get_af(const char *str, int *af)
 }
 
 int
-ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json)
+ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix,
+    int longer_prefixes, const char *neighbor, unsigned long local_label,
+    unsigned long remote_label, const char *detail, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1581,6 +1777,18 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, co
        params.family = af;
        params.detail = (detail) ? 1 : 0;
        params.json = (json) ? 1 : 0;
+       if (prefix) {
+               (void)str2prefix(prefix, &params.lib.prefix);
+               params.lib.longer_prefixes = longer_prefixes;
+       }
+       if (neighbor &&
+           (inet_pton(AF_INET, neighbor, &params.lib.neighbor) != 1 ||
+            bad_addr_v4(params.lib.neighbor))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       params.lib.local_label = local_label;
+       params.lib.remote_label = remote_label;
 
        if (!params.detail && !params.json)
                vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
@@ -1703,7 +1911,8 @@ ldp_vty_show_capabilities(struct vty *vty, const char *json)
 }
 
 int
-ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json)
+ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities,
+    const char *detail, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1712,11 +1921,17 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
                return (CMD_WARNING);
 
        memset(&params, 0, sizeof(params));
-       params.capabilities = capabilities;
        params.detail = (detail) ? 1 : 0;
        params.json = (json) ? 1 : 0;
+       params.neighbor.capabilities = capabilities;
+       if (lsr_id &&
+           (inet_pton(AF_INET, lsr_id, &params.neighbor.lsr_id) != 1 ||
+            bad_addr_v4(params.neighbor.lsr_id))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
 
-       if (params.capabilities)
+       if (params.neighbor.capabilities)
                params.detail = 1;
 
        if (!params.detail && !params.json)
@@ -1728,7 +1943,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
 }
 
 int
-ldp_vty_show_atom_binding(struct vty *vty, const char *json)
+ldp_vty_show_atom_binding(struct vty *vty, const char *peer,
+    unsigned long local_label, unsigned long remote_label, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1738,13 +1954,22 @@ ldp_vty_show_atom_binding(struct vty *vty, const char *json)
 
        memset(&params, 0, sizeof(params));
        params.json = (json) ? 1 : 0;
+       if (peer &&
+           (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+            bad_addr_v4(params.l2vpn.peer))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       params.l2vpn.local_label = local_label;
+       params.l2vpn.remote_label = remote_label;
 
        imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
        return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
 }
 
 int
-ldp_vty_show_atom_vc(struct vty *vty, const char *json)
+ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname,
+    const char *vcid, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1754,6 +1979,17 @@ ldp_vty_show_atom_vc(struct vty *vty, const char *json)
 
        memset(&params, 0, sizeof(params));
        params.json = (json) ? 1 : 0;
+       if (peer &&
+           (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+            bad_addr_v4(params.l2vpn.peer))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       if (ifname)
+               strlcpy(params.l2vpn.ifname, ifname,
+                   sizeof(params.l2vpn.ifname));
+       if (vcid)
+               params.l2vpn.vcid = atoi(vcid);
 
        if (!params.json) {
                /* header */
index d31c575920031badfafe232a0439b06ae1174067..a79e63229fa700879484dd2fcbb8137cf7f0b805 100644 (file)
@@ -206,7 +206,7 @@ main(int argc, char *argv[])
        frr_preinit(&ldpd_di, argc, argv);
        frr_opt_add("LEn:", longopts,
                "      --ctl_socket   Override ctl socket path\n"
-               "-n,   --instance     Instance id\n");
+               "  -n, --instance     Instance id\n");
 
        while (1) {
                int opt;
@@ -435,7 +435,7 @@ static pid_t
 start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
 {
        char    *argv[3];
-       int      argc = 0;
+       int      argc = 0, nullfd;
        pid_t    pid;
 
        switch (pid = fork()) {
@@ -449,6 +449,12 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
                return (pid);
        }
 
+       nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
+       dup2(nullfd, 0);
+       dup2(nullfd, 1);
+       dup2(nullfd, 2);
+       close(nullfd);
+
        if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
                fatal("cannot setup imsg async fd");
        if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
index a1b77901eed919987957972faadd8026b7afacdd..37ced5b402de5ccb8e15dd11c25bfb267eab5f6c 100644 (file)
@@ -192,7 +192,8 @@ static void SHA256_Transform(uint32_t *state, const unsigned char block[64])
        /* Clean the stack. */
        memset(W, 0, 256);
        memset(S, 0, 32);
-       t0 = t1 = 0;
+       memset(&t0, 0, sizeof(t0));
+       memset(&t1, 0, sizeof(t0));
 }
 
 static unsigned char PAD[64] = {
index e30f166ddeab256fc61458c20d28bcba539ab9df..0b06dbacbaf4c683067d9d6b97c3158c17075da0 100644 (file)
@@ -1619,7 +1619,7 @@ static int zclient_read_sync_response(struct zclient *zclient,
                                      u_int16_t expected_cmd)
 {
        struct stream *s;
-       u_int16_t size;
+       u_int16_t size = -1;
        u_char marker;
        u_char version;
        vrf_id_t vrf_id;
index e58eab2b156d52d9ced1476fb532d37d6d9464a4..117d2eef89f6771a4f2338a092cbbb8c9636fee7 100644 (file)
@@ -1516,6 +1516,9 @@ int config_write_ospf6_debug_route(struct vty *vty)
                vty_out(vty, "debug ospf6 route intra-area\n");
        if (IS_OSPF6_DEBUG_ROUTE(INTER))
                vty_out(vty, "debug ospf6 route inter-area\n");
+       if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
+               vty_out(vty, "debug ospf6 route memory\n");
+
        return 0;
 }
 
index 752c875a622136a8e523968d0e02b27e4c44b0bf..018a363a93b3d93d5df39a042ca8a7096f3192de 100644 (file)
@@ -15,3 +15,4 @@ TAGS
 *~
 *.loT
 *.a
+*.clippy.c
index 968461b4d00592cf7a1ca7f7ee997b25bad5db5c..f7aa94ad188c2f5042a98dec7f3f6a593dc982dd 100644 (file)
@@ -91,7 +91,7 @@ static void ospf_area_range_delete(struct ospf_area *area,
        struct ospf_area_range *range = rn->info;
 
        if (range->specifics != 0)
-               ospf_delete_discard_route(area->ospf->new_table,
+               ospf_delete_discard_route(area->ospf, area->ospf->new_table,
                                          (struct prefix_ipv4 *)&rn->p);
 
        ospf_area_range_free(range);
@@ -1684,12 +1684,12 @@ static void ospf_abr_manage_discard_routes(struct ospf *ospf)
                                if (CHECK_FLAG(range->flags,
                                               OSPF_AREA_RANGE_ADVERTISE)) {
                                        if (range->specifics)
-                                               ospf_add_discard_route(
+                                               ospf_add_discard_route(ospf,
                                                        ospf->new_table, area,
                                                        (struct prefix_ipv4
                                                                 *)&rn->p);
                                        else
-                                               ospf_delete_discard_route(
+                                               ospf_delete_discard_route(ospf,
                                                        ospf->new_table,
                                                        (struct prefix_ipv4
                                                                 *)&rn->p);
index a5f5971ac01ea0e2aa1e045a808ad495f197f1f5..252a5df0fdef44da505c2fc896355a6e9f8c1d20 100644 (file)
@@ -80,9 +80,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address)
 {
        struct listnode *node, *nnode;
        struct ospf_interface *oi;
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
 
-       if (!(ospf = ospf_lookup()))
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       if (!ospf)
                return NULL;
 
        for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@@ -97,9 +98,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp)
 {
        struct listnode *node, *nnode;
        struct ospf_interface *oi;
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
 
-       if (!(ospf = ospf_lookup()))
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       if (!ospf)
                return NULL;
 
        for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@@ -999,7 +1001,7 @@ void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv)
        struct ospf_interface *oi;
        struct registered_opaque_type *r;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
                /* Check if this interface is indeed ready for type 9 */
@@ -1047,7 +1049,7 @@ void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv)
        struct ospf *ospf;
        struct ospf_area *area;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
                struct registered_opaque_type *r;
@@ -1094,7 +1096,7 @@ void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv)
        struct ospf *ospf;
        struct registered_opaque_type *r;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Can type 11 be originated? */
        if (!ospf_apiserver_is_ready_type11(ospf))
@@ -1271,7 +1273,7 @@ int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv,
        struct ospf *ospf;
        struct ospf_area *area;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Get request sequence number */
        seqnum = msg_get_seq(msg);
@@ -1374,7 +1376,11 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
 
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       if (oi && oi->ospf)
+               ospf = oi->ospf;
+       else
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
        assert(ospf);
 
        /* Create a stream for internal opaque LSA */
@@ -1429,6 +1435,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
 
        new->area = area;
        new->oi = oi;
+       new->vrf_id = ospf->vrf_id;
 
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, newlsa, length);
@@ -1497,7 +1504,7 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv,
        int ready = 0;
        int rc = 0;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Extract opaque LSA data from message */
        omsg = (struct msg_originate_request *)STREAM_DATA(msg->s);
@@ -1640,7 +1647,7 @@ void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa)
        case OSPF_OPAQUE_AS_LSA: {
                struct ospf *ospf;
 
-               ospf = ospf_lookup();
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                assert(ospf);
 
                /* Increment counters? XXX */
@@ -1656,7 +1663,7 @@ int ospf_apiserver_originate1(struct ospf_lsa *lsa)
 {
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
        /* Install this LSA into LSDB. */
@@ -1726,7 +1733,7 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
        struct ospf_lsa *new = NULL;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
        apiserv = lookup_apiserver_by_lsa(lsa);
@@ -1810,7 +1817,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
        int rc = 0;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
        /* Extract opaque LSA from message */
@@ -1862,7 +1869,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
         * the LSDB until it is finally handled by the maxage remover thread.
         * Therefore, the lookup function below may return non-NULL result.
         */
-       old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id);
+       old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id);
        if (!old) {
                zlog_warn(
                        "ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
@@ -1923,7 +1930,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
        struct ospf *ospf;
        struct ospf_area *area;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
        /* Set parameter struct. */
index e3b66d597b97bdbe53a95e2b9cb0180faf591fcb..89c462693b6c7babaf74067e4c4835915743147c 100644 (file)
@@ -58,7 +58,8 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
 
                        /* Remove route from zebra. */
                        if (or->type == OSPF_DESTINATION_NETWORK)
-                               ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+                               ospf_zebra_delete(ospf,
+                                                 (struct prefix_ipv4 *)&rn->p,
                                                  or);
 
                        ospf_route_free(or);
index bf2b809ddcf2f212a9203fd11e92eaa5eb6b673d..877e4b7fb0e8d2bd09ca48d2b797695aba81e728 100644 (file)
@@ -598,7 +598,8 @@ static int ospf_ase_route_match_same(struct route_table *rt,
        return 1;
 }
 
-static int ospf_ase_compare_tables(struct route_table *new_external_route,
+static int ospf_ase_compare_tables(struct ospf *ospf,
+                                  struct route_table *new_external_route,
                                   struct route_table *old_external_route)
 {
        struct route_node *rn, *new_rn;
@@ -609,7 +610,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
                if ((or = rn->info)) {
                        if (!(new_rn = route_node_lookup(new_external_route,
                                                         &rn->p)))
-                               ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+                               ospf_zebra_delete(ospf,
+                                                 (struct prefix_ipv4 *)&rn->p,
                                                  or);
                        else
                                route_unlock_node(new_rn);
@@ -621,7 +623,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
                if ((or = rn->info) != NULL)
                        if (!ospf_ase_route_match_same(old_external_route,
                                                       &rn->p, or))
-                               ospf_zebra_add((struct prefix_ipv4 *)&rn->p,
+                               ospf_zebra_add(ospf,
+                                              (struct prefix_ipv4 *)&rn->p,
                                               or);
 
        return 0;
@@ -666,7 +669,7 @@ static int ospf_ase_calculate_timer(struct thread *t)
 
                /* Compare old and new external routing table and install the
                   difference info zebra/kernel */
-               ospf_ase_compare_tables(ospf->new_external_route,
+               ospf_ase_compare_tables(ospf, ospf->new_external_route,
                                        ospf->old_external_route);
 
                /* Delete old external routing table */
@@ -814,7 +817,7 @@ void ospf_ase_incremental_update(struct ospf *ospf, struct ospf_lsa *lsa)
        }
 
        /* install changes to zebra */
-       ospf_ase_compare_tables(ospf->new_external_route, tmp_old);
+       ospf_ase_compare_tables(ospf, ospf->new_external_route, tmp_old);
 
        /* update ospf->old_external_route table */
        if (rn && rn->info)
index 6d07b44364dae7ce52b36e62714ce28e421b6f81..9254e7d240e5a07014907b686f0488d9253df346 100644 (file)
@@ -75,12 +75,13 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
        bfd_info = (struct bfd_info *)params->bfd_info;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
-               zlog_debug("%s nbr (%s) with BFD",
+               zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s",
                           bfd_get_command_dbg_str(command),
-                          inet_ntoa(nbr->src));
+                          inet_ntoa(nbr->src),
+                          ospf_vrf_id_to_name(oi->ospf->vrf_id));
 
        bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
-                        0, 0, command, 0, VRF_DEFAULT);
+                        0, 0, command, 0, oi->ospf->vrf_id);
 }
 
 /*
@@ -158,7 +159,7 @@ static int ospf_bfd_nbr_replay(int command, struct zclient *zclient,
        /* Send the client registration */
        bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
 
-       /* Replay the neighbor, if BFD is enabled in BGP */
+       /* Replay the neighbor, if BFD is enabled in OSPF */
        for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) {
                for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) {
                        if ((nbrs = oi->nbrs) == NULL)
index 619bd4e5f529d9b7546a49b09a1072103a0d5dea..eca0f85f57ba7df2a5bfe731ef5f63f16a0af6b2 100644 (file)
@@ -1604,9 +1604,10 @@ DEFUN_NOSH (show_debugging_ospf,
            DEBUG_STR
            OSPF_STR)
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
 
-       if ((ospf = ospf_lookup()) == NULL)
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       if (ospf == NULL)
                return CMD_SUCCESS;
 
        return show_debugging_ospf_common(vty, ospf);
@@ -1651,7 +1652,8 @@ static int config_write_debug(struct vty *vty)
        char str[16];
        memset(str, 0, 16);
 
-       if ((ospf = ospf_lookup()) == NULL)
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       if (ospf == NULL)
                return CMD_SUCCESS;
 
        if (ospf->instance)
index c775f2ea2e0daf82723f95afe7469e5b22e1ecae..aac2f3ee92834b23c54630206394bdb3734faafa 100644 (file)
@@ -77,7 +77,8 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr,
 }
 
 /* Check LSA is related to external info. */
-struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
+struct external_info *ospf_external_info_check(struct ospf *ospf,
+                                              struct ospf_lsa *lsa)
 {
        struct as_external_lsa *al;
        struct prefix_ipv4 p;
@@ -96,11 +97,11 @@ struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
                redist_on =
                        is_prefix_default(&p)
                                ? vrf_bitmap_check(zclient->default_information,
-                                                  VRF_DEFAULT)
+                                                  ospf->vrf_id)
                                : (zclient->mi_redist[AFI_IP][type].enabled
                                   || vrf_bitmap_check(
                                              zclient->redist[AFI_IP][type],
-                                             VRF_DEFAULT));
+                                             ospf->vrf_id));
                // Pending: check for MI above.
                if (redist_on) {
                        struct list *ext_list;
@@ -205,7 +206,7 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
                        ospf_translated_nssa_refresh(ospf, NULL, new);
                        return;
                }
-               ei = ospf_external_info_check(new);
+               ei = ospf_external_info_check(ospf, new);
                if (ei)
                        ospf_external_lsa_refresh(ospf, new, ei,
                                                  LSA_REFRESH_FORCE);
index b74894567d0d39f7ad92d2d79912246b6d7ac898..6f7ecfccf0532eea82fde38fcb7335d9bdc2d9cd 100644 (file)
@@ -61,7 +61,8 @@ extern void ospf_flood_lsa_as(struct ospf_lsa *);
 extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *);
 extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *);
 extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *);
-extern struct external_info *ospf_external_info_check(struct ospf_lsa *);
+extern struct external_info *ospf_external_info_check(struct ospf *,
+                                                     struct ospf_lsa *);
 
 extern void ospf_lsdb_init(struct ospf_lsdb *);
 
index 422e1a2a6b6e7b95ea1a852ae59aedff6fc04e74..d8d7caa6888b5e04e0e9393164ad78ee95e131d1 100644 (file)
@@ -243,6 +243,11 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
        oi->ospf = ospf;
        QOBJ_REG(oi, ospf_interface);
 
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: ospf interface %s vrf %s id %u created",
+                          __PRETTY_FUNCTION__, ifp->name,
+                          ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+
        return oi;
 }
 
@@ -313,6 +318,12 @@ void ospf_if_free(struct ospf_interface *oi)
        list_free(oi->ls_ack);
        list_free(oi->ls_ack_direct.ls_ack);
 
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
+                          __PRETTY_FUNCTION__, oi->ifp->name,
+                          ospf_vrf_id_to_name(oi->ifp->vrf_id),
+                          oi->ifp->vrf_id);
+
        ospf_delete_from_if(oi->ifp, oi);
 
        listnode_delete(oi->ospf->oiflist, oi);
@@ -335,7 +346,11 @@ struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
        struct ospf *ospf;
        struct ospf_interface *oi;
 
-       if ((ospf = ospf_lookup()) == NULL)
+       if (!oic)
+               return NULL;
+
+       ospf = oic->ospf;
+       if (ospf == NULL)
                return NULL;
 
        for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
@@ -800,10 +815,11 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_vl_new(): creating pseudo zebra interface");
+               zlog_debug("ospf_vl_new(): creating pseudo zebra interface vrf id %u",
+                          ospf->vrf_id);
 
        snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
-       vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT);
+       vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id);
        /*
         * if_create sets ZEBRA_INTERFACE_LINKDETECTION
         * virtual links don't need this.
@@ -1164,7 +1180,6 @@ u_char ospf_default_iftype(struct interface *ifp)
 void ospf_if_init()
 {
        /* Initialize Zebra interface data structure. */
-       om->iflist = vrf_iflist(VRF_DEFAULT);
        hook_register_prio(if_add, 0, ospf_if_new_hook);
        hook_register_prio(if_del, 0, ospf_if_delete_hook);
 }
index 68adf2e10be7198e49c047927d2abe6d298798dc..e5d4d3423108afbdfb290b9dd7016026395fa1bf 100644 (file)
@@ -161,6 +161,7 @@ struct ospf_lsa *ospf_lsa_new()
        monotime(&new->tv_recv);
        new->tv_orig = new->tv_recv;
        new->refresh_list = -1;
+       new->vrf_id = VRF_DEFAULT;
 
        return new;
 }
@@ -786,6 +787,7 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
 
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+       new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA data to store, discard stream. */
        new->data = ospf_lsa_data_new(length);
@@ -1001,6 +1003,7 @@ static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi)
 
        new->area = oi->area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+       new->vrf_id = oi->ospf->vrf_id;
 
        /* Copy LSA to store. */
        new->data = ospf_lsa_data_new(length);
@@ -1180,6 +1183,7 @@ static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area,
        new = ospf_lsa_new();
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+       new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA to store. */
        new->data = ospf_lsa_data_new(length);
@@ -1321,6 +1325,7 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area,
        new = ospf_lsa_new();
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+       new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA to store. */
        new->data = ospf_lsa_data_new(length);
@@ -1627,6 +1632,7 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
        new->area = NULL;
        SET_FLAG(new->flags,
                 OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
+       new->vrf_id = ospf->vrf_id;
 
        /* Copy LSA data to store, discard stream. */
        new->data = ospf_lsa_data_new(length);
@@ -2121,14 +2127,15 @@ int ospf_default_originate_timer(struct thread *thread)
 void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
 {
        struct listnode *node, *nnode;
-       struct ospf_lsa *lsa;
+       struct ospf_lsa *lsa = NULL;
        struct ospf_area *area;
 
        for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
                if (area->external_routing == OSPF_AREA_NSSA) {
-                       if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA,
-                                                   p->prefix,
-                                                   ospf->router_id))) {
+                       lsa  = ospf_lsa_lookup(ospf, area,
+                                              OSPF_AS_NSSA_LSA, p->prefix,
+                                              ospf->router_id);
+                       if (!lsa) {
                                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                                        zlog_debug(
                                                "LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
@@ -2844,11 +2851,12 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
 void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
 {
        struct route_node *rn;
-       struct prefix_ptr lsa_prefix;
+       struct prefix lsa_prefix;
 
+       memset(&lsa_prefix, 0, sizeof(struct prefix));
        lsa_prefix.family = 0;
-       lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
-       lsa_prefix.prefix = (uintptr_t)lsa;
+       lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+       lsa_prefix.u.ptr = (uintptr_t)lsa;
 
        if ((rn = route_node_lookup(ospf->maxage_lsa,
                                    (struct prefix *)&lsa_prefix))) {
@@ -2860,6 +2868,10 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
                                rn); /* unlock node because lsa is deleted */
                }
                route_unlock_node(rn); /* route_node_lookup */
+       } else {
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: lsa %s is not found in maxage db.",
+                                  __PRETTY_FUNCTION__, dump_lsa_key(lsa));
        }
 }
 
@@ -2870,7 +2882,7 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
  */
 void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
 {
-       struct prefix_ptr lsa_prefix;
+       struct prefix lsa_prefix;
        struct route_node *rn;
 
        /* When we saw a MaxAge LSA flooded to us, we put it on the list
@@ -2884,9 +2896,10 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
                return;
        }
 
+       memset(&lsa_prefix, 0, sizeof(struct prefix));
        lsa_prefix.family = 0;
-       lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
-       lsa_prefix.prefix = (uintptr_t)lsa;
+       lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+       lsa_prefix.u.ptr = (uintptr_t)lsa;
 
        if ((rn = route_node_get(ospf->maxage_lsa,
                                 (struct prefix *)&lsa_prefix))
@@ -2903,7 +2916,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
                        SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
                }
        } else {
-               zlog_err("Unable to allocate memory for maxage lsa\n");
+               zlog_err("Unable to allocate memory for maxage lsa %s\n",
+                        dump_lsa_key(lsa));
                assert(0);
        }
 
@@ -3039,11 +3053,12 @@ struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, u_char type,
        return lsa;
 }
 
-struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type,
-                                struct in_addr id, struct in_addr adv_router)
+struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area,
+                                u_int32_t type, struct in_addr id,
+                                struct in_addr adv_router)
 {
-       struct ospf *ospf = ospf_lookup();
-       assert(ospf);
+       if (!ospf)
+               return NULL;
 
        switch (type) {
        case OSPF_ROUTER_LSA:
@@ -3113,7 +3128,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area,
         * they two were forming a unique LSA-ID.
         */
 
-       match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router);
+       match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id,
+                               lsah->adv_router);
 
        if (match == NULL)
                if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
@@ -3529,7 +3545,7 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
                 */
                if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
                        break;
-               ei = ospf_external_info_check(lsa);
+               ei = ospf_external_info_check(ospf, lsa);
                if (ei)
                        new = ospf_external_lsa_refresh(ospf, lsa, ei,
                                                        LSA_REFRESH_FORCE);
index ab8e62b6e4d7c733f92df60f42eee7646a7838d9..94a34d4a90cd6820611667f49f3957783849100c 100644 (file)
@@ -111,6 +111,9 @@ struct ospf_lsa {
 
        /* For Type-9 Opaque-LSAs */
        struct ospf_interface *oi;
+
+       /* VRF Id */
+       vrf_id_t vrf_id;
 };
 
 /* OSPF LSA Link Type. */
@@ -267,8 +270,9 @@ extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *,
                                                    struct external_info *);
 extern int ospf_external_lsa_originate_timer(struct thread *);
 extern int ospf_default_originate_timer(struct thread *);
-extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t,
-                                       struct in_addr, struct in_addr);
+extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
+                                       u_int32_t, struct in_addr,
+                                       struct in_addr);
 extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t,
                                              struct in_addr);
 extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *,
index f284a04cbe5498a6ebf204066217252435bfb2ae..7bd644f43d676d73c95049e61ad89571348f9ada 100644 (file)
@@ -187,7 +187,7 @@ int main(int argc, char **argv)
 
        /* Library inits. */
        debug_init();
-       vrf_init(NULL, NULL, NULL, NULL);
+       ospf_vrf_init();
 
        access_list_init();
        prefix_list_init();
index c72c69856c4f4a0ab0a7ac1dc62690a16c5d18a0..d1c1429054d05f692b1928369d85f6c32eb60187 100644 (file)
@@ -153,7 +153,10 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
        if (ret < 0)
                zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
                          top->fd, safe_strerror(errno));
-
+#ifndef GNU_LINUX
+       /* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
+        * packet out of ifindex. Below would be used Non Linux system.
+        */
        ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
        if (ret < 0)
                zlog_warn(
@@ -161,23 +164,53 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
                        "ifindex %u): %s",
                        top->fd, inet_ntoa(p->u.prefix4), ifindex,
                        safe_strerror(errno));
+#endif
 
        return ret;
 }
 
-int ospf_sock_init(void)
+int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock)
+{
+       int ret = 0;
+
+#ifdef SO_BINDTODEVICE
+
+       if (ospf && ospf->vrf_id != VRF_DEFAULT &&
+           ospf->vrf_id != VRF_UNKNOWN) {
+               ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE,
+                                ospf->name,
+                                strlen(ospf->name));
+               if (ret < 0) {
+                       int save_errno = errno;
+
+                       zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s",
+                                       __PRETTY_FUNCTION__,
+                                       safe_strerror(save_errno));
+               } else {
+                       zlog_debug("%s: Bind socket %d to vrf %s id %u device",
+                                  __PRETTY_FUNCTION__, ospf_sock,
+                                  ospf->name, ospf->vrf_id);
+               }
+       }
+#endif
+       return ret;
+}
+
+int ospf_sock_init(struct ospf *ospf)
 {
        int ospf_sock;
        int ret, hincl = 1;
        int bufsize = (8 * 1024 * 1024);
 
-       if (ospfd_privs.change(ZPRIVS_RAISE))
+       if (ospfd_privs.change(ZPRIVS_RAISE)) {
                zlog_err("ospf_sock_init: could not raise privs, %s",
                         safe_strerror(errno));
+       }
 
        ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
        if (ospf_sock < 0) {
                int save_errno = errno;
+
                if (ospfd_privs.change(ZPRIVS_LOWER))
                        zlog_err("ospf_sock_init: could not lower privs, %s",
                                 safe_strerror(errno));
@@ -186,17 +219,20 @@ int ospf_sock_init(void)
                exit(1);
        }
 
+       ret = ospf_bind_vrfdevice(ospf, ospf_sock);
+       if (ret < 0)
+               goto out;
+
 #ifdef IP_HDRINCL
        /* we will include IP header with packet */
        ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
                         sizeof(hincl));
        if (ret < 0) {
                int save_errno = errno;
-               if (ospfd_privs.change(ZPRIVS_LOWER))
-                       zlog_err("ospf_sock_init: could not lower privs, %s",
-                                safe_strerror(errno));
+
                zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
                          ospf_sock, safe_strerror(save_errno));
+               goto out;
        }
 #elif defined(IPTOS_PREC_INTERNETCONTROL)
 #warning "IP_HDRINCL not available on this system"
@@ -204,13 +240,11 @@ int ospf_sock_init(void)
        ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
        if (ret < 0) {
                int save_errno = errno;
-               if (ospfd_privs.change(ZPRIVS_LOWER))
-                       zlog_err("ospf_sock_init: could not lower privs, %s",
-                                safe_strerror(errno));
+
                zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos,
                          ospf_sock, safe_strerror(save_errno));
                close(ospf_sock); /* Prevent sd leak. */
-               return ret;
+               goto out;
        }
 #else /* !IPTOS_PREC_INTERNETCONTROL */
 #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
@@ -222,13 +256,14 @@ int ospf_sock_init(void)
        if (ret < 0)
                zlog_warn("Can't set pktinfo option for fd %d", ospf_sock);
 
+       setsockopt_so_sendbuf(ospf_sock, bufsize);
+       setsockopt_so_recvbuf(ospf_sock, bufsize);
+
+       ospf->fd = ospf_sock;
+out:
        if (ospfd_privs.change(ZPRIVS_LOWER)) {
                zlog_err("ospf_sock_init: could not lower privs, %s",
                         safe_strerror(errno));
        }
-
-       setsockopt_so_sendbuf(ospf_sock, bufsize);
-       setsockopt_so_recvbuf(ospf_sock, bufsize);
-
-       return ospf_sock;
+       return ret;
 }
index ed5e00315c9a67546423cd7dc56d34ca4193bae8..41a7abda7013ed1af4b6e1d25d7d859c0576b440 100644 (file)
@@ -29,6 +29,7 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *,
 extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
 extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
 extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
-extern int ospf_sock_init(void);
+extern int ospf_sock_init(struct ospf *ospf);
+extern int ospf_bind_vrfdevice(struct ospf *, int);
 
 #endif /* _ZEBRA_OSPF_NETWORK_H */
index db523bd2a430b064b18f02f09a818c4732a3d48a..bc71e371b1c8b6166abc8c3854d4a30b7335ad7e 100644 (file)
@@ -544,7 +544,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
                listnode_add(new->area->opaque_lsa_self, oipt);
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup();
+               top = ospf_lookup_by_vrf_id(new->vrf_id);
                if (new->area != NULL && (top = new->area->ospf) == NULL) {
                        free_opaque_info_per_type((void *)oipt);
                        oipt = NULL;
@@ -648,7 +648,7 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa)
                                "Type-10 Opaque-LSA: Reference to AREA is missing?");
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup();
+               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
                if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
                        zlog_warn(
                                "Type-11 Opaque-LSA: Reference to OSPF is missing?");
@@ -1571,7 +1571,7 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc)
                }
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup();
+               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
                if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
                        /* Above conditions must have passed. */
                        zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
@@ -1597,7 +1597,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
        struct ospf_opaque_functab *functab;
        struct ospf_lsa *new = NULL;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(lsa->vrf_id);
 
        if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL
            || functab->lsa_refresher == NULL) {
@@ -1638,7 +1638,7 @@ static int ospf_opaque_lsa_refresh_timer(struct thread *t);
 void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
                                          u_char lsa_type, u_char opaque_type)
 {
-       struct ospf *top;
+       struct ospf *top = NULL;
        struct ospf_area dummy, *area = NULL;
        struct ospf_interface *oi = NULL;
 
@@ -1739,6 +1739,7 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
 
        /* Generate a dummy lsa to be passed for a lookup function. */
        lsa = pseudo_lsa(oi, area, lsa_type, opaque_type);
+       lsa->vrf_id = top->vrf_id;
 
        if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
                struct ospf_opaque_functab *functab;
@@ -1804,6 +1805,7 @@ static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi,
        lsa.oi = oi;
        lsa.area = area;
        lsa.data = &lsah;
+       lsa.vrf_id = VRF_DEFAULT;
 
        lsah.type = lsa_type;
        tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */
@@ -2000,7 +2002,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
                ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup();
+               top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
                if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
                        top = lsa0->area->ospf;
                ospf_ls_retransmit_delete_nbr_as(top, lsa);
@@ -2054,7 +2056,7 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0)
        struct ospf_lsa *lsa;
        struct ospf *top;
 
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
 
        if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
            || (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
index 36f9a6757a1d4bb34bca4ff3deb5685157a87e9a..015eac096ca4fb1dc24c46046343fe29e2ce6db6 100644 (file)
@@ -649,6 +649,12 @@ static int ospf_write(struct thread *thread)
 #define OSPF_WRITE_IPHL_SHIFT 2
        int pkt_count = 0;
 
+#ifdef GNU_LINUX
+       unsigned char cmsgbuf[64] = {};
+       struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
+       struct in_pktinfo *pi;
+#endif
+
        ospf->t_write = NULL;
 
        node = listhead(ospf->oi_write_q);
@@ -753,14 +759,28 @@ static int ospf_write(struct thread *thread)
                msg.msg_namelen = sizeof(sa_dst);
                msg.msg_iov = iov;
                msg.msg_iovlen = 2;
+
                iov[0].iov_base = (char *)&iph;
                iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
                iov[1].iov_base = STREAM_PNT(op->s);
                iov[1].iov_len = op->length;
 
-/* Sadly we can not rely on kernels to fragment packets because of either
- * IP_HDRINCL and/or multicast destination being set.
- */
+#ifdef GNU_LINUX
+               msg.msg_control = (caddr_t)cm;
+               cm->cmsg_level = SOL_IP;
+               cm->cmsg_type = IP_PKTINFO;
+               cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+               pi = (struct in_pktinfo *)CMSG_DATA(cm);
+               pi->ipi_ifindex = oi->ifp->ifindex;
+
+               msg.msg_controllen = cm->cmsg_len;
+#endif
+
+       /* Sadly we can not rely on kernels to fragment packets
+        * because of either IP_HDRINCL and/or multicast
+        * destination being set.
+        */
+
 #ifdef WANT_OSPF_WRITE_FRAGMENT
                if (op->length > maxdatasize)
                        ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
@@ -907,9 +927,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("Packet %s [Hello:RECV]: Options %s",
+               zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
                           inet_ntoa(ospfh->router_id),
-                          ospf_options_dump(hello->options));
+                          ospf_options_dump(hello->options),
+                          ospf_vrf_id_to_name(oi->ospf->vrf_id));
 
 /* Compare options. */
 #define REJECT_IF_TBIT_ON      1 /* XXX */
@@ -1556,7 +1577,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
                }
 
                /* Search proper LSA in LSDB. */
-               find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router);
+               find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id,
+                                      adv_router);
                if (find == NULL) {
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
                        list_delete(ls_upd);
@@ -1696,6 +1718,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
                /* Create OSPF LSA instance. */
                lsa = ospf_lsa_new();
 
+               lsa->vrf_id = oi->ospf->vrf_id;
                /* We may wish to put some error checking if type NSSA comes in
                   and area not in NSSA mode */
                switch (lsah->type) {
@@ -1784,6 +1807,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
         */
        lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size);
 
+       if (lsas == NULL)
+               return;
 #define DISCARD_LSA(L, N)                                                              \
        {                                                                              \
                if (IS_DEBUG_OSPF_EVENT)                                               \
@@ -2173,6 +2198,7 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
 
                lsa = ospf_lsa_new();
                lsa->data = (struct lsa_header *)STREAM_PNT(s);
+               lsa->vrf_id = oi->ospf->vrf_id;
 
                /* lsah = (struct lsa_header *) STREAM_PNT (s); */
                size -= OSPF_LSA_HEADER_SIZE;
@@ -2197,7 +2223,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
        return;
 }
 
-static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
+static struct stream *ospf_recv_packet(struct ospf *ospf, int fd,
+                                      struct interface **ifp,
                                       struct stream *ibuf)
 {
        int ret;
@@ -2265,7 +2292,7 @@ static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
 
        ifindex = getsockopt_ifindex(AF_INET, &msgh);
 
-       *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+       *ifp = if_lookup_by_index(ifindex, ospf->vrf_id);
 
        if (ret != ip_len) {
                zlog_warn(
@@ -2833,7 +2860,7 @@ int ospf_read(struct thread *thread)
        struct ip *iph;
        struct ospf_header *ospfh;
        u_int16_t length;
-       struct interface *ifp;
+       struct interface *ifp = NULL;
        struct connected *c;
 
        /* first of all get interface pointer. */
@@ -2844,7 +2871,8 @@ int ospf_read(struct thread *thread)
        thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
 
        stream_reset(ospf->ibuf);
-       if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf)))
+       ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf);
+       if (ibuf == NULL)
                return -1;
        /* This raw packet is known to be at least as big as its IP header. */
 
@@ -2861,7 +2889,7 @@ int ospf_read(struct thread *thread)
                   ifindex
                   retrieval but do not. */
                c = if_lookup_address((void *)&iph->ip_src, AF_INET,
-                                     VRF_DEFAULT);
+                                     ospf->vrf_id);
                if (c)
                        ifp = c->ifp;
                if (ifp == NULL)
@@ -3487,6 +3515,13 @@ static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr)
 
        op->dst.s_addr = addr;
 
+       if (IS_DEBUG_OSPF_EVENT) {
+               if (oi->ospf->vrf_id)
+                       zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u",
+                                   __PRETTY_FUNCTION__, oi->ifp->name,
+                                   ospf_vrf_id_to_name(oi->ospf->vrf_id),
+                                   oi->ospf->vrf_id);
+       }
        /* Add packet to the top of the interface output queue, so that they
         * can't get delayed by things like long queues of LS Update packets
         */
@@ -4065,21 +4100,19 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi)
  * punt-to-CPU set on them. This may overload the CPU control path that
  * can be avoided if the MAC was known apriori.
  */
-#define OSPF_PING_NBR_STR_MAX  (8 + 40 + 20)
+#define OSPF_PING_NBR_STR_MAX  (BUFSIZ)
 void ospf_proactively_arp(struct ospf_neighbor *nbr)
 {
        char ping_nbr[OSPF_PING_NBR_STR_MAX];
-       char *str_ptr;
        int ret;
 
        if (!nbr || !nbr->oi || !nbr->oi->ifp)
                return;
 
-       str_ptr = strcpy(ping_nbr, "ping -c 1 -I ");
-       str_ptr = strcat(str_ptr, nbr->oi->ifp->name);
-       str_ptr = strcat(str_ptr, " ");
-       str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4));
-       str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &");
+       snprintf(ping_nbr, sizeof(ping_nbr),
+               "ping -c 1 -I %s %s > /dev/null 2>&1 &",
+               nbr->oi->ifp->name, inet_ntoa(nbr->address.u.prefix4));
+
        ret = system(ping_nbr);
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug("Executed %s %s", ping_nbr,
index 13013bf8cac055187f6ec238e717bf303c3d3e44..f9e346b1d1f83e0a5dd99a262c9633ba3f26f3bc 100644 (file)
@@ -427,7 +427,7 @@ static void initialize_params(struct ospf_router_info *ori)
 
        /* If Area address is not null and exist, retrieve corresponding
         * structure */
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        zlog_info("RI-> Initialize Router Info for %s scope within area %s",
                  OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS",
                  inet_ntoa(OspfRI.area_id));
@@ -586,7 +586,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
                        "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
                        lsa_type, inet_ntoa(lsa_id));
 
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Set opaque-LSA header fields. */
        lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
@@ -615,6 +615,11 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
        new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
                                    scope, fulfill otherwise */
 
+       if (new->area && new->area->ospf)
+               new->vrf_id = new->area->ospf->vrf_id;
+       else
+               new->vrf_id = VRF_DEFAULT;
+
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, lsah, length);
        stream_free(s);
@@ -628,6 +633,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
        struct ospf *top;
        struct ospf_area *area;
        int rc = -1;
+       vrf_id_t vrf_id = VRF_DEFAULT;
 
        /* First check if the area is known if flooding scope is Area */
        if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
@@ -638,6 +644,8 @@ static int ospf_router_info_lsa_originate1(void *arg)
                        return rc;
                }
                OspfRI.area = area;
+               if (area->ospf)
+                       vrf_id = area->ospf->vrf_id;
        }
 
        /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
@@ -646,9 +654,15 @@ static int ospf_router_info_lsa_originate1(void *arg)
                        "ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
                return rc;
        }
+       new->vrf_id = vrf_id;
 
        /* Get ospf info */
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(vrf_id);
+       if (top == NULL) {
+               zlog_debug("%s: ospf instance not found for vrf id %u",
+                          __PRETTY_FUNCTION__, vrf_id);
+               return rc;
+       }
 
        /* Install this LSA into LSDB. */
        if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@@ -751,10 +765,11 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
                return NULL;
        }
        new->data->ls_seqnum = lsa_seqnum_increment(lsa);
+       new->vrf_id = lsa->vrf_id;
 
        /* Install this LSA into LSDB. */
        /* Given "lsa" will be freed in the next function. */
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(lsa->vrf_id);
        if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
                zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
                ospf_lsa_unlock(&new);
@@ -800,7 +815,7 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
        if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA))
                opcode = REFRESH_THIS_LSA;
 
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
                zlog_warn(
                        "ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
index 89ea331b52b5b149418dc96e99934ddc3182a7be..ca851ec75d25476c87d3181d2624126078f41f18 100644 (file)
@@ -83,7 +83,7 @@ void ospf_path_free(struct ospf_path *op)
        XFREE(MTYPE_OSPF_PATH, op);
 }
 
-void ospf_route_delete(struct route_table *rt)
+void ospf_route_delete(struct ospf *ospf, struct route_table *rt)
 {
        struct route_node *rn;
        struct ospf_route * or ;
@@ -91,10 +91,11 @@ void ospf_route_delete(struct route_table *rt)
        for (rn = route_top(rt); rn; rn = route_next(rn))
                if ((or = rn->info) != NULL) {
                        if (or->type == OSPF_DESTINATION_NETWORK)
-                               ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+                               ospf_zebra_delete(ospf,
+                                                 (struct prefix_ipv4 *)&rn->p,
                                                  or);
                        else if (or->type == OSPF_DESTINATION_DISCARD)
-                               ospf_zebra_delete_discard(
+                               ospf_zebra_delete_discard(ospf,
                                        (struct prefix_ipv4 *)&rn->p);
                }
 }
@@ -191,7 +192,8 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix,
 /* delete routes generated from AS-External routes if there is a inter/intra
  * area route
  */
-static void ospf_route_delete_same_ext(struct route_table *external_routes,
+static void ospf_route_delete_same_ext(struct ospf *ospf,
+                                      struct route_table *external_routes,
                                       struct route_table *routes)
 {
        struct route_node *rn, *ext_rn;
@@ -206,7 +208,8 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
                        if ((ext_rn = route_node_lookup(external_routes,
                                                        (struct prefix *)p))) {
                                if (ext_rn->info) {
-                                       ospf_zebra_delete(p, ext_rn->info);
+                                       ospf_zebra_delete(ospf, p,
+                                                         ext_rn->info);
                                        ospf_route_free(ext_rn->info);
                                        ext_rn->info = NULL;
                                }
@@ -217,7 +220,7 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
 }
 
 /* rt: Old, cmprt: New */
-static void ospf_route_delete_uniq(struct route_table *rt,
+static void ospf_route_delete_uniq(struct ospf *ospf, struct route_table *rt,
                                   struct route_table *cmprt)
 {
        struct route_node *rn;
@@ -232,7 +235,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
                                                    cmprt,
                                                    (struct prefix_ipv4 *)&rn
                                                            ->p))
-                                               ospf_zebra_delete(
+                                               ospf_zebra_delete(ospf,
                                                        (struct prefix_ipv4
                                                                 *)&rn->p,
                                                        or);
@@ -241,7 +244,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
                                                    cmprt,
                                                    (struct prefix_ipv4 *)&rn
                                                            ->p))
-                                               ospf_zebra_delete_discard(
+                                               ospf_zebra_delete_discard(ospf,
                                                        (struct prefix_ipv4
                                                                 *)&rn->p);
                        }
@@ -263,9 +266,9 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
 
        /* Delete old routes. */
        if (ospf->old_table)
-               ospf_route_delete_uniq(ospf->old_table, rt);
+               ospf_route_delete_uniq(ospf, ospf->old_table, rt);
        if (ospf->old_external_route)
-               ospf_route_delete_same_ext(ospf->old_external_route, rt);
+               ospf_route_delete_same_ext(ospf, ospf->old_external_route, rt);
 
        /* Install new routes. */
        for (rn = route_top(rt); rn; rn = route_next(rn))
@@ -274,14 +277,14 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
                                if (!ospf_route_match_same(
                                            ospf->old_table,
                                            (struct prefix_ipv4 *)&rn->p, or))
-                                       ospf_zebra_add(
+                                       ospf_zebra_add(ospf,
                                                (struct prefix_ipv4 *)&rn->p,
                                                or);
                        } else if (or->type == OSPF_DESTINATION_DISCARD)
                                if (!ospf_route_match_same(
                                            ospf->old_table,
                                            (struct prefix_ipv4 *)&rn->p, or))
-                                       ospf_zebra_add_discard(
+                                       ospf_zebra_add_discard(ospf,
                                                (struct prefix_ipv4 *)&rn->p);
                }
 }
@@ -906,7 +909,8 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
        }
 }
 
-int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
+int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
+                          struct ospf_area *area,
                           struct prefix_ipv4 *p)
 {
        struct route_node *rn;
@@ -961,12 +965,13 @@ int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
        new_or->path_type = OSPF_PATH_INTER_AREA;
        rn->info = new_or;
 
-       ospf_zebra_add_discard(p);
+       ospf_zebra_add_discard(ospf, p);
 
        return 1;
 }
 
-void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
+void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
+                              struct prefix_ipv4 *p)
 {
        struct route_node *rn;
        struct ospf_route * or ;
@@ -1012,7 +1017,7 @@ void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
        route_unlock_node(rn);
 
        /* remove the discard entry from the rib */
-       ospf_zebra_delete_discard(p);
+       ospf_zebra_delete_discard(ospf, p);
 
        return;
 }
index 199937984430d417507807d3951940faeab07dfe..76df54fb3f9e3f2e39237405f3cc4b45eca55fac 100644 (file)
@@ -115,7 +115,7 @@ extern void ospf_path_free(struct ospf_path *);
 extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *);
 extern struct ospf_route *ospf_route_new(void);
 extern void ospf_route_free(struct ospf_route *);
-extern void ospf_route_delete(struct route_table *);
+extern void ospf_route_delete(struct ospf *, struct route_table *);
 extern void ospf_route_table_free(struct route_table *);
 
 extern void ospf_route_install(struct ospf *, struct route_table *);
@@ -145,9 +145,9 @@ extern void ospf_route_add(struct route_table *, struct prefix_ipv4 *,
 extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *);
 extern void ospf_prune_unreachable_networks(struct route_table *);
 extern void ospf_prune_unreachable_routers(struct route_table *);
-extern int ospf_add_discard_route(struct route_table *, struct ospf_area *,
-                                 struct prefix_ipv4 *);
-extern void ospf_delete_discard_route(struct route_table *,
+extern int ospf_add_discard_route(struct ospf *, struct route_table *,
+                                 struct ospf_area *, struct prefix_ipv4 *);
+extern void ospf_delete_discard_route(struct ospf *, struct route_table *,
                                      struct prefix_ipv4 *);
 extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,
                                 struct ospf_route *);
index f47e2b6f1ee303d51fbfcb54bd98a657a897d29d..b7a47602d0b16037a5090ab49a8054235cf75f87 100644 (file)
@@ -45,38 +45,40 @@ static void ospf_route_map_update(const char *name)
 {
        struct ospf *ospf;
        int type;
+       struct listnode *n1 = NULL;
 
        /* If OSPF instatnce does not exist, return right now. */
-       ospf = ospf_lookup();
-       if (ospf == NULL)
+       if (listcount(om->ospf) == 0)
                return;
 
-       /* Update route-map */
-       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
-               struct list *red_list;
-               struct listnode *node;
-               struct ospf_redist *red;
-
-               red_list = ospf->redist[type];
-               if (!red_list)
-                       continue;
-
-               for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                       if (ROUTEMAP_NAME(red)
-                           && strcmp(ROUTEMAP_NAME(red), name) == 0) {
-                               /* Keep old route-map. */
-                               struct route_map *old = ROUTEMAP(red);
-
-                               /* Update route-map. */
-                               ROUTEMAP(red) = route_map_lookup_by_name(
-                                       ROUTEMAP_NAME(red));
-
-                               /* No update for this distribute type. */
-                               if (old == NULL && ROUTEMAP(red) == NULL)
-                                       continue;
-
-                               ospf_distribute_list_update(ospf, type,
-                                                           red->instance);
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+               /* Update route-map */
+               for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+                       struct list *red_list;
+                       struct listnode *node;
+                       struct ospf_redist *red;
+
+                       red_list = ospf->redist[type];
+                       if (!red_list)
+                               continue;
+
+                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+                               if (ROUTEMAP_NAME(red)
+                                   && strcmp(ROUTEMAP_NAME(red), name) == 0) {
+                                       /* Keep old route-map. */
+                                       struct route_map *old = ROUTEMAP(red);
+
+                                       /* Update route-map. */
+                                       ROUTEMAP(red) = route_map_lookup_by_name(
+                                                                                ROUTEMAP_NAME(red));
+
+                                       /* No update for this distribute type. */
+                                       if (old == NULL && ROUTEMAP(red) == NULL)
+                                               continue;
+
+                                       ospf_distribute_list_update(ospf, type,
+                                                                   red->instance);
+                               }
                        }
                }
        }
@@ -86,26 +88,24 @@ static void ospf_route_map_event(route_map_event_t event, const char *name)
 {
        struct ospf *ospf;
        int type;
-
-       /* If OSPF instatnce does not exist, return right now. */
-       ospf = ospf_lookup();
-       if (ospf == NULL)
-               return;
-
-       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
-               struct list *red_list;
-               struct listnode *node;
-               struct ospf_redist *red;
-
-               red_list = ospf->redist[type];
-               if (!red_list)
-                       continue;
-
-               for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                       if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
-                           && !strcmp(ROUTEMAP_NAME(red), name)) {
-                               ospf_distribute_list_update(ospf, type,
-                                                           red->instance);
+       struct listnode *n1 = NULL;
+
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+               for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+                       struct list *red_list;
+                       struct listnode *node;
+                       struct ospf_redist *red;
+
+                       red_list = ospf->redist[type];
+                       if (!red_list)
+                               continue;
+
+                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+                               if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
+                                   && !strcmp(ROUTEMAP_NAME(red), name)) {
+                                       ospf_distribute_list_update(ospf, type,
+                                                               red->instance);
+                               }
                        }
                }
        }
@@ -285,7 +285,7 @@ static route_map_result_t route_match_interface(void *rule,
 
        if (type == RMAP_OSPF) {
                ei = object;
-               ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
+               ifp = if_lookup_by_name_all_vrf((char *)rule);
 
                if (ifp == NULL || ifp->ifindex != ei->ifindex)
                        return RMAP_NOMATCH;
index 6a352380b8c8c6b1e430dbc4724d24d2a6b67ffa..36ae091f99ecdd527a8e4c8cc687f66e21bd205c 100644 (file)
@@ -532,7 +532,7 @@ static u_char *ospfGeneralGroup(struct variable *v, oid *name, size_t *length,
 {
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Check whether the instance identifier is valid */
        if (smux_header_generic(v, name, length, exact, var_len, write_method)
@@ -661,7 +661,7 @@ static struct ospf_area *ospfAreaLookup(struct variable *v, oid name[],
        struct ospf_area *area;
        int len;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -765,7 +765,7 @@ static struct ospf_area *ospf_stub_area_lookup_next(struct in_addr *area_id,
        struct listnode *node;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -792,7 +792,7 @@ static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[],
        struct ospf_area *area;
        int len;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -934,7 +934,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name,
        oid *offset;
        int offsetlen;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
 #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
 
@@ -1084,7 +1084,7 @@ static u_char *ospfLsdbEntry(struct variable *v, oid *name, size_t *length,
        memset(&router_id, 0, sizeof(struct in_addr));
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -1145,7 +1145,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v,
        p.family = AF_INET;
        p.prefixlen = IPV4_MAX_BITLEN;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (exact) {
                /* Area ID + Range Network. */
@@ -1239,7 +1239,7 @@ static u_char *ospfAreaRangeEntry(struct variable *v, oid *name, size_t *length,
                return NULL;
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -1290,7 +1290,7 @@ static struct ospf_nbr_nbma *ospfHostLookup(struct variable *v, oid *name,
        struct ospf_nbr_nbma *nbr_nbma;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -1347,7 +1347,7 @@ static u_char *ospfHostEntry(struct variable *v, oid *name, size_t *length,
                return NULL;
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -1504,7 +1504,7 @@ static struct ospf_interface *ospf_snmp_if_lookup(struct in_addr *ifaddr,
        struct listnode *node;
        struct ospf_snmp_if *osif;
        struct ospf_interface *oi = NULL;
-       struct ospf *ospf = ospf_lookup();
+       struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) {
                if (ifaddr->s_addr) {
@@ -1527,7 +1527,7 @@ static struct ospf_interface *ospf_snmp_if_lookup_next(struct in_addr *ifaddr,
 {
        struct ospf_snmp_if *osif;
        struct listnode *nn;
-       struct ospf *ospf = ospf_lookup();
+       struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        struct ospf_interface *oi = NULL;
 
        if (ospf == NULL)
@@ -1675,7 +1675,7 @@ static u_char *ospfIfEntry(struct variable *v, oid *name, size_t *length,
        memset(&ifaddr, 0, sizeof(struct in_addr));
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -1845,7 +1845,7 @@ static u_char *ospfIfMetricEntry(struct variable *v, oid *name, size_t *length,
        memset(&ifaddr, 0, sizeof(struct in_addr));
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -2125,7 +2125,7 @@ static struct ospf_neighbor *ospf_snmp_nbr_lookup_next(struct in_addr *nbr_addr,
        struct ospf_neighbor *min = NULL;
        struct ospf *ospf = ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) {
                for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
@@ -2165,7 +2165,7 @@ static struct ospf_neighbor *ospfNbrLookup(struct variable *v, oid *name,
        struct ospf_neighbor *nbr;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (!ospf)
                return NULL;
@@ -2325,7 +2325,7 @@ static u_char *ospfVirtNbrEntry(struct variable *v, oid *name, size_t *length,
        memset(&neighbor, 0, sizeof(struct in_addr));
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
@@ -2379,7 +2379,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name,
        struct ospf_lsa *lsa;
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (exact) {
                if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
                        return NULL;
@@ -2476,7 +2476,7 @@ static u_char *ospfExtLsdbEntry(struct variable *v, oid *name, size_t *length,
        memset(&router_id, 0, sizeof(struct in_addr));
 
        /* Check OSPF instance. */
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL)
                return NULL;
 
index 891088ecc2da46dd7ad5030fa772bc212f6379e8..5e5742608921f91c46761e9fe25af5d87c46b88b 100644 (file)
@@ -781,7 +781,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
  * of candidates with any vertices not already on the list.  If a lower-cost
  * path is found to a vertex already on the candidate list, store the new cost.
  */
-static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
+static void ospf_spf_next(struct vertex *v, struct ospf *ospf,
+                         struct ospf_area *area,
                          struct pqueue *candidate)
 {
        struct ospf_lsa *w_lsa = NULL;
@@ -841,7 +842,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
                                                        inet_ntoa(l->link_id));
                                }
 
-                               w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA,
+                               w_lsa = ospf_lsa_lookup(ospf, area,
+                                                       OSPF_ROUTER_LSA,
                                                        l->link_id, l->link_id);
                                if (w_lsa) {
                                        if (IS_DEBUG_OSPF_EVENT)
@@ -1159,7 +1161,7 @@ ospf_rtrs_print (struct route_table *rtrs)
 #endif
 
 /* Calculating the shortest-path tree for an area. */
-static void ospf_spf_calculate(struct ospf_area *area,
+static void ospf_spf_calculate(struct ospf *ospf, struct ospf_area *area,
                               struct route_table *new_table,
                               struct route_table *new_rtrs)
 {
@@ -1209,7 +1211,7 @@ static void ospf_spf_calculate(struct ospf_area *area,
 
        for (;;) {
                /* RFC2328 16.1. (2). */
-               ospf_spf_next(v, area, candidate);
+               ospf_spf_next(v, ospf, area, candidate);
 
                /* RFC2328 16.1. (3). */
                /* If at this step the candidate list is empty, the shortest-
@@ -1307,13 +1309,13 @@ static int ospf_spf_calculate_timer(struct thread *thread)
                if (ospf->backbone && ospf->backbone == area)
                        continue;
 
-               ospf_spf_calculate(area, new_table, new_rtrs);
+               ospf_spf_calculate(ospf, area, new_table, new_rtrs);
                areas_processed++;
        }
 
        /* SPF for backbone, if required */
        if (ospf->backbone) {
-               ospf_spf_calculate(ospf->backbone, new_table, new_rtrs);
+               ospf_spf_calculate(ospf, ospf->backbone, new_table, new_rtrs);
                areas_processed++;
        }
 
@@ -1339,6 +1341,12 @@ static int ospf_spf_calculate_timer(struct thread *thread)
 
        ospf_ase_calculate_timer_add(ospf);
 
+
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu",
+                          __PRETTY_FUNCTION__,
+                          ospf_vrf_id_to_name(ospf->vrf_id),
+                          ospf->vrf_id, new_table->count);
        /* Update routing table. */
        monotime(&start_time);
        ospf_route_install(ospf, new_table);
index 55170089098553adb1e0d32dbdb0a54377646665..294ffe48b3c6b89ae0950ed1360eac60e8358741 100644 (file)
@@ -728,7 +728,7 @@ static void update_linkparams(struct mpls_te_link *lp)
                        else {
                                lp->flags = INTER_AS | FLOOD_AREA;
                                lp->area = ospf_area_lookup_by_area_id(
-                                       ospf_lookup(),
+                                       ospf_lookup_by_vrf_id(VRF_DEFAULT),
                                        OspfMplsTE.interas_areaid);
                        }
                }
@@ -1127,7 +1127,8 @@ static void ospf_mpls_te_lsa_body_set(struct stream *s, struct mpls_te_link *lp)
 }
 
 /* Create new opaque-LSA. */
-static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
+static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
+                                            struct ospf_area *area,
                                             struct mpls_te_link *lp)
 {
        struct stream *s;
@@ -1167,9 +1168,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
                tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance);
                lsa_id.s_addr = htonl(tmp);
 
-               struct ospf *top = ospf_lookup();
+               if (!ospf)
+                       return NULL;
 
-               lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
+               lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id);
        } else {
                options |= LSA_OPTIONS_GET(area); /* Get area default option */
                options |= LSA_OPTIONS_NSSA_GET(area);
@@ -1207,6 +1209,9 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
                return new;
        }
 
+       new->vrf_id = ospf->vrf_id;
+       if (area && area->ospf)
+               new->vrf_id = area->ospf->vrf_id;
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, lsah, length);
@@ -1218,11 +1223,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
 static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
                                       struct mpls_te_link *lp)
 {
-       struct ospf_lsa *new;
+       struct ospf_lsa *new = NULL;
        int rc = -1;
 
        /* Create new Opaque-LSA/MPLS-TE instance. */
-       if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+       new = ospf_mpls_te_lsa_new(area->ospf, area, lp);
+       if (new == NULL) {
                zlog_warn(
                        "ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
                return rc;
@@ -1321,11 +1327,13 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
        int rc = -1;
 
        /* Create new Opaque-LSA/Inter-AS instance. */
-       if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
+       new = ospf_mpls_te_lsa_new(top, NULL, lp);
+       if (new == NULL) {
                zlog_warn(
                        "ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
                return rc;
        }
+       new->vrf_id = top->vrf_id;
 
        /* Install this LSA into LSDB. */
        if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@@ -1451,9 +1459,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
                ospf_opaque_lsa_flush_schedule(lsa);
                return NULL;
        }
-
+       top = ospf_lookup_by_vrf_id(lsa->vrf_id);
        /* Create new Opaque-LSA/MPLS-TE instance. */
-       if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+       new = ospf_mpls_te_lsa_new(top, area, lp);
+       if (new == NULL) {
                zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
                return NULL;
        }
@@ -1465,8 +1474,6 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
         * ospf_lookup() to get ospf instance */
        if (area)
                top = area->ospf;
-       else
-               top = ospf_lookup();
 
        if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
                zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
@@ -1500,7 +1507,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode)
 
        memset(&lsa, 0, sizeof(lsa));
        memset(&lsah, 0, sizeof(lsah));
-       top = ospf_lookup();
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        /* Check if the pseudo link is ready to flood */
        if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE))
@@ -2517,29 +2524,64 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
 
 DEFUN (show_ip_ospf_mpls_te_link,
        show_ip_ospf_mpls_te_link_cmd,
-       "show ip ospf mpls-te interface [INTERFACE]",
+       "show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]",
        SHOW_STR
        IP_STR
        OSPF_STR
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "MPLS-TE information\n"
        "Interface information\n"
        "Interface name\n")
 {
        int idx_interface = 5;
        struct interface *ifp;
-       struct listnode *node, *nnode;
-
+       struct listnode *node, *nnode, *n1;
+       char *vrf_name = NULL;
+       bool all_vrf;
+       int inst = 0;
+       int idx_vrf = 0;
+       struct ospf *ospf = NULL;
+
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
+
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id),
+                                                      node, nnode, ifp))
+                                       show_mpls_te_link_sub(vty, ifp);
+                       }
+                       return CMD_SUCCESS;
+               }
+               ospf = ospf_lookup_by_inst_name (inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
+                                      nnode, ifp))
+                       show_mpls_te_link_sub(vty, ifp);
+               return CMD_SUCCESS;
+       }
        /* Show All Interfaces. */
        if (argc == 5) {
-               for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode,
-                                      ifp))
-                       show_mpls_te_link_sub(vty, ifp);
+               for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+                       if (!ospf->oi_running)
+                               continue;
+                       for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
+                                              nnode, ifp))
+                               show_mpls_te_link_sub(vty, ifp);
+               }
        }
        /* Interface name is specified. */
        else {
-               if ((ifp = if_lookup_by_name(argv[idx_interface]->arg,
-                                            VRF_DEFAULT))
-                   == NULL)
+               ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);
+               if (ifp == NULL)
                        vty_out(vty, "No such interface name\n");
                else
                        show_mpls_te_link_sub(vty, ifp);
index f6a101de80d4385bd6f76a8cc1b0d5509fc70882..3840bc41708ae3b2bbbe7b4d23152a71db8967a3 100644 (file)
@@ -126,25 +126,70 @@ int ospf_oi_count(struct interface *ifp)
        return i;
 }
 
+#define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
+               vrf_name = argv[idx_vrf + 1]->arg; \
+               all_vrf = strmatch(vrf_name, "all"); \
+       }
+
+static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
+                                        struct cmd_token *argv[],
+                                        const int argc,
+                                        uint32_t enable,
+                                        u_short *instance)
+{
+       struct ospf *ospf = NULL;
+       int idx_vrf = 0;
+       const char *vrf_name = NULL;
+
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               if (enable) {
+                       if (argc > 4)
+                               *instance = strtoul(argv[2]->arg, NULL, 10);
+                       /* Allocate VRF aware instance */
+                       ospf = ospf_get(*instance, vrf_name);
+               } else {
+                       if (argc > 5)
+                               *instance = strtoul(argv[3]->arg, NULL, 10);
+                       ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
+               }
+       } else {
+               if (enable) {
+                       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+                       if (!ospf)
+                               vty_out(vty,
+                                       "There isn't active ospf instance\n");
+                       if (argc > 2)
+                               *instance = strtoul(argv[2]->arg, NULL, 10);
+               } else {
+                       if (argc > 3)
+                               *instance = strtoul(argv[3]->arg, NULL, 10);
+                       ospf = ospf_lookup_instance(*instance);
+               }
+       }
+       return ospf;
+}
+
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf_vty_clippy.c"
+#endif
+
 DEFUN_NOSH (router_ospf,
        router_ospf_cmd,
-       "router ospf [(1-65535)]",
+       "router ospf [{(1-65535)|vrf NAME}]",
        "Enable a routing process\n"
        "Start OSPF configuration\n"
-       "Instance ID\n")
+       "Instance ID\n"
+       VRF_CMD_HELP_STR)
 {
-       struct ospf *ospf;
-       u_short instance = 0;
+       struct ospf *ospf = NULL;
        int ret = CMD_SUCCESS;
+       u_short instance = 0;
 
-       ospf = ospf_lookup();
-       if (!ospf) {
-               vty_out(vty, "There isn't active ospf instance \n");
+       ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
+       if (!ospf)
                return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (argc > 2)
-               instance = strtoul(argv[2]->arg, NULL, 10);
 
        /* The following logic to set the vty qobj index is in place to be able
           to ignore the commands which dont belong to this instance. */
@@ -152,10 +197,12 @@ DEFUN_NOSH (router_ospf,
                VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
                ret = CMD_NOT_MY_INSTANCE;
        } else {
+               if (ospf->vrf_id != VRF_UNKNOWN)
+                       ospf->oi_running = 1;
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("Config command 'router ospf %d' received",
-                                  instance);
-               ospf->oi_running = 1;
+                       zlog_debug("Config command 'router ospf %d' received, vrf %s id %d oi_running %u",
+                                  instance,  ospf->name ? ospf->name : "NIL",
+                                  ospf->vrf_id, ospf->oi_running);
                VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
                ospf_router_id_update(ospf);
        }
@@ -165,29 +212,30 @@ DEFUN_NOSH (router_ospf,
 
 DEFUN (no_router_ospf,
        no_router_ospf_cmd,
-       "no router ospf [(1-65535)]",
+       "no router ospf [{(1-65535)|vrf NAME}]",
        NO_STR
        "Enable a routing process\n"
        "Start OSPF configuration\n"
-       "Instance ID\n")
+       "Instance ID\n"
+       VRF_CMD_HELP_STR)
 {
        struct ospf *ospf;
        u_short instance = 0;
 
-       if (argc > 3)
-               instance = strtoul(argv[3]->arg, NULL, 10);
-
-       ospf = ospf_lookup_instance(instance);
-       if (ospf == NULL)
-               return CMD_NOT_MY_INSTANCE;
-
+       ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
+       if (ospf == NULL) {
+               if (instance)
+                       return CMD_NOT_MY_INSTANCE;
+               else
+                       return CMD_WARNING;
+       }
        ospf_finish(ospf);
 
        return CMD_SUCCESS;
 }
 
 
-DEFUN (ospf_router_id,
+DEFPY (ospf_router_id,
        ospf_router_id_cmd,
        "ospf router-id A.B.C.D",
        "OSPF specific commands\n"
@@ -195,17 +243,9 @@ DEFUN (ospf_router_id,
        "OSPF router-id in IP address format\n")
 {
        VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-       int idx_ipv4 = 2;
+
        struct listnode *node;
        struct ospf_area *area;
-       struct in_addr router_id;
-       int ret;
-
-       ret = inet_aton(argv[idx_ipv4]->arg, &router_id);
-       if (!ret) {
-               vty_out(vty, "Please specify Router ID by A.B.C.D\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
 
        ospf->router_id_static = router_id;
 
@@ -256,7 +296,7 @@ DEFUN_HIDDEN (ospf_router_id_old,
        return CMD_SUCCESS;
 }
 
-DEFUN (no_ospf_router_id,
+DEFPY (no_ospf_router_id,
        no_ospf_router_id_cmd,
        "no ospf router-id [A.B.C.D]",
        NO_STR
@@ -268,6 +308,13 @@ DEFUN (no_ospf_router_id,
        struct listnode *node;
        struct ospf_area *area;
 
+       if (router_id_str) {
+               if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) {
+                       vty_out(vty, "%% OSPF router-id doesn't match\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
        ospf->router_id_static.s_addr = 0;
 
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
@@ -292,7 +339,7 @@ static void ospf_passive_interface_default(struct ospf *ospf, u_char newval)
 
        ospf->passive_interface_default = newval;
 
-       for (ALL_LIST_ELEMENTS_RO(om->iflist, ln, ifp)) {
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), ln, ifp)) {
                if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
                                                    passive_interface))
                        UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface);
@@ -366,7 +413,12 @@ DEFUN (ospf_passive_interface,
                return CMD_SUCCESS;
        }
 
-       ifp = if_get_by_name(argv[1]->arg, VRF_DEFAULT);
+       ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id);
+       if (ifp == NULL) {
+               vty_out(vty, "interface %s not found.\n",
+                       (char *)argv[1]->arg);
+               return CMD_WARNING;
+       }
 
        params = IF_DEF_PARAMS(ifp);
 
@@ -433,7 +485,12 @@ DEFUN (no_ospf_passive_interface,
                return CMD_SUCCESS;
        }
 
-       ifp = if_get_by_name(argv[2]->arg, VRF_DEFAULT);
+       ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
+       if (ifp == NULL) {
+               vty_out(vty, "interface %s not found.\n",
+                       (char *)argv[1]->arg);
+               return CMD_WARNING;
+       }
 
        params = IF_DEF_PARAMS(ifp);
 
@@ -2416,7 +2473,7 @@ DEFUN (ospf_auto_cost_reference_bandwidth,
                return CMD_SUCCESS;
 
        ospf->ref_bandwidth = refbw;
-       for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
                ospf_if_recalculate_output_cost(ifp);
 
        return CMD_SUCCESS;
@@ -2442,7 +2499,7 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth,
        vty_out(vty,
                "        Please ensure reference bandwidth is consistent across all routers\n");
 
-       for (ALL_LIST_ELEMENTS(om->iflist, node, nnode, ifp))
+       for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode, ifp))
                ospf_if_recalculate_output_cost(ifp);
 
        return CMD_SUCCESS;
@@ -3102,19 +3159,52 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf,
        show_ip_ospf_cmd,
-       "show ip ospf [json]",
+       "show ip ospf [vrf <NAME|all>] [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        JSON_STR)
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
+       if (listcount(om->ospf) == 0)
                return CMD_SUCCESS;
 
-       return (show_ip_ospf_common(vty, ospf, uj));
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+         /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_common(vty, ospf, uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if ((ospf == NULL) || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               /* Display default ospf (instance 0) info */
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               show_ip_ospf_common(vty, ospf, uj);
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance,
@@ -3483,7 +3573,8 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
 
        if (argc == iface_argv) {
                /* Show All Interfaces.*/
-               for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+               for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+                                         node, ifp)) {
                        if (ospf_oi_count(ifp)) {
                                if (use_json)
                                        json_interface_sub =
@@ -3502,7 +3593,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
        } else {
                /* Interface name is specified. */
                if ((ifp = if_lookup_by_name(argv[iface_argv]->arg,
-                                            VRF_DEFAULT))
+                                            ospf->vrf_id))
                    == NULL) {
                        if (use_json)
                                json_object_boolean_true_add(json,
@@ -3534,24 +3625,59 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_interface,
        show_ip_ospf_interface_cmd,
-       "show ip ospf interface [INTERFACE] [json]",
+       "show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Interface information\n"
        "Interface name\n"
        JSON_STR)
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
        if (uj)
                argc--;
 
-       return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj);
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_interface_common(vty,
+                                                                   ospf, argc,
+                                                                   argv, 6,
+                                                                   uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_interface_common(vty, ospf,
+                                                   argc, argv, 6, uj);
+
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_interface_common(vty, ospf,
+                                                   argc, argv, 4, uj);
+       }
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_interface,
@@ -3722,8 +3848,6 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
 
        if (use_json)
                json = json_object_new_object();
-       else
-               show_ip_ospf_neighbour_header(vty);
 
        if (ospf->instance) {
                if (use_json)
@@ -3748,20 +3872,54 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_neighbor,
        show_ip_ospf_neighbor_cmd,
-       "show ip ospf neighbor [json]",
+       "show ip ospf [vrf <NAME|all>] neighbor [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Neighbor list\n"
        JSON_STR)
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_neighbor_common(vty, ospf, uj);
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
+
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_neighbor_common(vty, ospf,
+                                                                  uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               ret = show_ip_ospf_neighbor_common(vty, ospf, uj);
+
+       return ret;
 }
 
 
@@ -3788,6 +3946,9 @@ DEFUN (show_ip_ospf_instance_neighbor,
        if (!ospf->oi_running)
                return CMD_SUCCESS;
 
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
+
        return show_ip_ospf_neighbor_common(vty, ospf, uj);
 }
 
@@ -3802,8 +3963,7 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
        if (use_json) {
                json = json_object_new_object();
                json_neighbor_sub = json_object_new_object();
-       } else
-               show_ip_ospf_neighbour_header(vty);
+       }
 
        if (ospf->instance) {
                if (use_json)
@@ -3813,6 +3973,22 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
+       if (ospf->name) {
+               if (use_json) {
+                       json_object_int_add(json, "vrfId",
+                                           (ospf->vrf_id == VRF_UNKNOWN)
+                                           ? -1 : ospf->vrf_id);
+                       json_object_string_add(json, "vrfName",
+                                              (ospf->vrf_id == VRF_DEFAULT)
+                                              ? "Default" : ospf->name);
+               } else {
+                       vty_out(vty, "\nOSPF vrf: %s\n\n",
+                               ospf->vrf_id == VRF_DEFAULT
+                               ? "Default" : ospf->name);
+               }
+       }
+
+
        for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
                struct listnode *nbr_node;
                struct ospf_nbr_nbma *nbr_nbma;
@@ -3871,21 +4047,56 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_neighbor_all,
        show_ip_ospf_neighbor_all_cmd,
-       "show ip ospf neighbor all [json]",
+       "show ip ospf [vrf <NAME|all>] neighbor all [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Neighbor list\n"
        "include down status neighbor\n"
        JSON_STR)
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
+
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_neighbor_all_common(vty,
+                                                                      ospf,
+                                                                      uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               ret = show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_all,
@@ -3926,8 +4137,6 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
 
        if (use_json)
                json = json_object_new_object();
-       else
-               show_ip_ospf_neighbour_header(vty);
 
        if (ospf->instance) {
                if (use_json)
@@ -3937,7 +4146,8 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
-       ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+       /*ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);*/
+       ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
        if (!ifp) {
                if (use_json)
                        json_object_boolean_true_add(json, "noSuchIface");
@@ -3978,11 +4188,24 @@ DEFUN (show_ip_ospf_neighbor_int,
        struct ospf *ospf;
        int idx_ifname = 4;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       int ret = CMD_SUCCESS;
+       struct interface *ifp = NULL;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
 
-       return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
+       ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+               if (!ospf->oi_running)
+                       continue;
+               if (!ifp || ifp->vrf_id != ospf->vrf_id)
+                       continue;
+               ret = show_ip_ospf_neighbor_int_common(vty, ospf,
+                                                      idx_ifname, argv, uj);
+       }
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_int,
@@ -4002,6 +4225,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
        u_short instance = 0;
        u_char uj = use_json(argc, argv);
 
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
+
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
        ospf = ospf_lookup_instance(instance);
        if (ospf == NULL)
@@ -4010,6 +4236,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
        if (!ospf->oi_running)
                return CMD_SUCCESS;
 
+       if (!uj)
+               show_ip_ospf_neighbour_header(vty);
+
        return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
 }
 
@@ -4368,13 +4597,17 @@ DEFUN (show_ip_ospf_neighbor_id,
        JSON_STR)
 {
        struct ospf *ospf;
-       int idx_router_id = 4;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       int ret = CMD_SUCCESS;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return 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);
+       }
 
-       return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv, uj);
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_id,
@@ -4453,21 +4686,53 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
 
 DEFUN (show_ip_ospf_neighbor_detail,
        show_ip_ospf_neighbor_detail_cmd,
-       "show ip ospf neighbor detail [json]",
+       "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Neighbor list\n"
        "detail of all neighbors\n"
        JSON_STR)
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_neighbor_detail_common(vty,
+                                                                         ospf,
+                                                                         uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               ret = show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_detail,
@@ -4555,10 +4820,12 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
 
 DEFUN (show_ip_ospf_neighbor_detail_all,
        show_ip_ospf_neighbor_detail_all_cmd,
-       "show ip ospf neighbor detail all [json]",
+       "show ip ospf [vrf <NAME|all>] neighbor detail all [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Neighbor list\n"
        "detail of all neighbors\n"
        "include down status neighbor\n"
@@ -4566,11 +4833,41 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
 {
        struct ospf *ospf;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_neighbor_detail_all_common(vty,
+                                                                             ospf,
+                                                                             uj);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_detail_all,
@@ -4624,7 +4921,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
-       ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+       ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
        if (!ifp) {
                if (!use_json)
                        vty_out(vty, "No such interface.\n");
@@ -4673,13 +4970,18 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
        JSON_STR)
 {
        struct ospf *ospf;
-       int idx_ifname = 4;
        u_char uj = use_json(argc, argv);
+       struct listnode *node = NULL;
+       int ret = CMD_SUCCESS;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+               if (!ospf->oi_running)
+                       continue;
+               ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0,
+                                                             argv, uj);
+       }
 
-       return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname, argv, uj);
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_neighbor_int_detail,
@@ -5356,29 +5658,62 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_database_max,
        show_ip_ospf_database_max_cmd,
-       "show ip ospf database <max-age|self-originate>",
+       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Database summary\n"
        "LSAs in MaxAge list\n"
        "Self-originated link states\n")
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_database_common(vty, ospf,
+                                                                   idx_vrf ? 2
+                                                                   : 0, argc,
+                                                                   argv);
+                       }
+               } else {
+                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+                       if (ospf == NULL || !ospf->oi_running)
+                               return CMD_SUCCESS;
+                       ret = (show_ip_ospf_database_common(vty, ospf, idx_vrf ?
+                                                           2 : 0, argc, argv));
+               }
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv);
+       }
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_database,
        show_ip_ospf_instance_database_cmd,
-       "show ip ospf [(1-65535)] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
+       "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Instance ID\n"
+       VRF_CMD_HELP_STR
        "Database summary\n"
         OSPF_LSA_TYPES_DESC
        "Link State ID (as an IP address)\n"
@@ -5388,22 +5723,53 @@ DEFUN (show_ip_ospf_instance_database,
 {
        struct ospf *ospf;
        u_short instance = 0;
-
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
        int idx = 0;
+
        if (argv_find(argv, argc, "(1-65535)", &idx)) {
                instance = strtoul(argv[idx]->arg, NULL, 10);
                ospf = ospf_lookup_instance(instance);
                if (ospf == NULL)
                        return CMD_NOT_MY_INSTANCE;
-       } else {
-               ospf = ospf_lookup();
+               if (!ospf->oi_running)
+                       return CMD_SUCCESS;
+
+               return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
+                                                    argc, argv));
+       } else if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf_name = argv[++idx]->arg;
+               all_vrf = strmatch(vrf_name, "all");
        }
 
-       if (!ospf || !ospf->oi_running)
-               return CMD_SUCCESS;
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = (show_ip_ospf_database_common(vty, ospf,
+                                                                   idx ? 2 : 0,
+                                                                   argc, argv));
+                       }
+               } else {
+                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+                       if ((ospf == NULL) || !ospf->oi_running)
+                               return CMD_SUCCESS;
+                       ret = (show_ip_ospf_database_common(vty, ospf, idx ? 2 :
+                                                           0, argc, argv));
+               }
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+       }
 
-       return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc,
-                                            argv));
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_database_max,
@@ -5487,34 +5853,69 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
 
 DEFUN (show_ip_ospf_instance_database_type_adv_router,
        show_ip_ospf_instance_database_type_adv_router_cmd,
-       "show ip ospf [(1-65535)] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
+       "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Instance ID\n"
+       VRF_CMD_HELP_STR
        "Database summary\n"
        OSPF_LSA_TYPES_DESC
        "Advertising Router link states\n"
        "Advertising Router (as an IP address)\n"
        "Self-originated link states\n")
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
        u_short instance = 0;
-       int idx = 0;
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx = 0, idx_vrf = 0;
 
        if (argv_find(argv, argc, "(1-65535)", &idx)) {
                instance = strtoul(argv[idx]->arg, NULL, 10);
                ospf = ospf_lookup_instance(instance);
                if (ospf == NULL)
                        return CMD_NOT_MY_INSTANCE;
-       } else
-               ospf = ospf_lookup();
+               if (!ospf->oi_running)
+                       return CMD_SUCCESS;
+               return (show_ip_ospf_database_type_adv_router_common(vty, ospf,
+                                                                    idx ? 1 : 0,
+                                                                    argc,
+                                                                    argv));
+       }
 
-       if (!ospf || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return (show_ip_ospf_database_type_adv_router_common(
-               vty, ospf, idx ? 1 : 0, argc, argv));
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_database_type_adv_router_common(vty,
+                                               ospf, idx ? 1 : 0, argc, argv);
+                       }
+               } else {
+                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+                       if ((ospf == NULL) || !ospf->oi_running)
+                               return CMD_SUCCESS;
+                       ret = show_ip_ospf_database_type_adv_router_common(vty,
+                                               ospf, idx ? 1 : 0, argc, argv);
+               }
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_database_type_adv_router_common(vty, ospf,
+                                                                  idx ? 1 : 0,
+                                                                  argc, argv);
+       }
+       return ret;
+       /*return (show_ip_ospf_database_type_adv_router_common(
+               vty, ospf, idx ? 1 : 0, argc, argv));*/
 }
 
 DEFUN (ip_ospf_authentication_args,
@@ -5994,19 +6395,19 @@ DEFUN (ip_ospf_cost,
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
-       u_int32_t cost;
+       u_int32_t cost = OSPF_OUTPUT_COST_DEFAULT;
        struct in_addr addr;
        struct ospf_if_params *params;
        params = IF_DEF_PARAMS(ifp);
 
        // get arguments
        char *coststr = NULL, *ifaddr = NULL;
-       coststr = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg
-                                                          : NULL;
-       ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
 
+       argv_find(argv, argc, "(1-65535)", &idx);
+       coststr = argv[idx]->arg;
        cost = strtol(coststr, NULL, 10);
 
+       ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
        if (ifaddr) {
                if (!inet_aton(ifaddr, &addr)) {
                        vty_out(vty,
@@ -6160,8 +6561,10 @@ static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str,
 
        /* Update timer values in neighbor structure. */
        if (nbr_str) {
-               struct ospf *ospf;
-               if ((ospf = ospf_lookup())) {
+               struct ospf *ospf = NULL;
+
+               ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+               if (ospf) {
                        oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
                        if (oi)
                                ospf_nbr_timer_update(oi);
@@ -6272,9 +6675,10 @@ DEFUN (no_ip_ospf_dead_interval,
 
        /* Update timer values in neighbor structure. */
        if (argc == 1) {
-               struct ospf *ospf;
+               struct ospf *ospf = NULL;
 
-               if ((ospf = ospf_lookup())) {
+               ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+               if (ospf) {
                        oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
                        if (oi)
                                ospf_nbr_timer_update(oi);
@@ -6856,9 +7260,9 @@ DEFUN (ip_ospf_area,
        int format, ret;
        struct in_addr area_id;
        struct in_addr addr;
-       struct ospf_if_params *params;
+       struct ospf_if_params *params = NULL;
        struct route_node *rn;
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
        u_short instance = 0;
        char *areaid;
 
@@ -6868,13 +7272,17 @@ DEFUN (ip_ospf_area,
        argv_find(argv, argc, "area", &idx);
        areaid = argv[idx + 1]->arg;
 
-       ospf = ospf_lookup_instance(instance);
+       if (ifp->vrf_id && !instance)
+               ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+       else
+               ospf = ospf_lookup_instance(instance);
+
        if (ospf == NULL) {
                params = IF_DEF_PARAMS(ifp);
                if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
                        UNSET_IF_PARAM(params, if_area);
-                       ospf_interface_area_unset(ifp);
-                       ospf = ospf_lookup();
+                       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+                       ospf_interface_area_unset(ospf, ifp);
                        ospf->if_ospf_cli_count--;
                }
                return CMD_NOT_MY_INSTANCE;
@@ -6923,10 +7331,12 @@ DEFUN (ip_ospf_area,
        }
 
        /* enable ospf on this interface with area_id */
-       SET_IF_PARAM(params, if_area);
-       params->if_area = area_id;
-       params->if_area_id_fmt = format;
-       ospf_interface_area_set(ifp);
+       if (params) {
+               SET_IF_PARAM(params, if_area);
+               params->if_area = area_id;
+               params->if_area_id_fmt = format;
+       }
+       ospf_interface_area_set(ospf, ifp);
        ospf->if_ospf_cli_count++;
 
        return CMD_SUCCESS;
@@ -6954,7 +7364,11 @@ DEFUN (no_ip_ospf_area,
        if (argv_find(argv, argc, "(1-65535)", &idx))
                instance = strtol(argv[idx]->arg, NULL, 10);
 
-       ospf = ospf_lookup_instance(instance);
+       if (ifp->vrf_id && !instance)
+               ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+       else
+               ospf = ospf_lookup_instance(instance);
+
        if (ospf == NULL)
                return CMD_NOT_MY_INSTANCE;
 
@@ -6984,7 +7398,7 @@ DEFUN (no_ip_ospf_area,
                ospf_if_update_params((ifp), (addr));
        }
 
-       ospf_interface_area_unset(ifp);
+       ospf_interface_area_unset(ospf, ifp);
        ospf->if_ospf_cli_count--;
        return CMD_SUCCESS;
 }
@@ -7658,7 +8072,7 @@ DEFUN (ospf_max_metric_router_lsa_startup,
        int idx_number = 3;
        unsigned int seconds;
 
-       if (argc != 1) {
+       if (argc < 4) {
                vty_out(vty, "%% Must supply stub-router period");
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -7714,7 +8128,7 @@ DEFUN (ospf_max_metric_router_lsa_shutdown,
        int idx_number = 3;
        unsigned int seconds;
 
-       if (argc != 1) {
+       if (argc < 4) {
                vty_out(vty, "%% Must supply stub-router shutdown period");
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -7763,7 +8177,8 @@ static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
        return;
 }
 
-static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
+                                      struct route_table *rt)
 {
        struct route_node *rn;
        struct ospf_route * or ;
@@ -7803,14 +8218,14 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
                                for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode,
                                                       path)) {
                                        if (if_lookup_by_index(path->ifindex,
-                                                              VRF_DEFAULT)) {
+                                                              ospf->vrf_id)) {
                                                if (path->nexthop.s_addr == 0)
                                                        vty_out(vty,
                                                                "%24s   directly attached to %s\n",
                                                                "",
                                                                ifindex2ifname(
                                                                        path->ifindex,
-                                                                       VRF_DEFAULT));
+                                                                       ospf->vrf_id));
                                                else
                                                        vty_out(vty,
                                                                "%24s   via %s, %s\n",
@@ -7819,14 +8234,15 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
                                                                        path->nexthop),
                                                                ifindex2ifname(
                                                                        path->ifindex,
-                                                                       VRF_DEFAULT));
+                                                                       ospf->vrf_id));
                                        }
                                }
                }
        vty_out(vty, "\n");
 }
 
-static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
+static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
+                                     struct route_table *rtrs)
 {
        struct route_node *rn;
        struct ospf_route * or ;
@@ -7865,14 +8281,14 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
                                for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
                                                          path)) {
                                        if (if_lookup_by_index(path->ifindex,
-                                                              VRF_DEFAULT)) {
+                                                              ospf->vrf_id)) {
                                                if (path->nexthop.s_addr == 0)
                                                        vty_out(vty,
                                                                "%24s   directly attached to %s\n",
                                                                "",
                                                                ifindex2ifname(
                                                                        path->ifindex,
-                                                                       VRF_DEFAULT));
+                                                                       ospf->vrf_id));
                                                else
                                                        vty_out(vty,
                                                                "%24s   via %s, %s\n",
@@ -7881,7 +8297,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
                                                                        path->nexthop),
                                                                ifindex2ifname(
                                                                        path->ifindex,
-                                                                       VRF_DEFAULT));
+                                                                       ospf->vrf_id));
                                        }
                                }
                        }
@@ -7889,7 +8305,8 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
        vty_out(vty, "\n");
 }
 
-static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
+                                       struct route_table *rt)
 {
        struct route_node *rn;
        struct ospf_route *er;
@@ -7922,14 +8339,14 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
                        for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode,
                                               path)) {
                                if (if_lookup_by_index(path->ifindex,
-                                                      VRF_DEFAULT)) {
+                                                      ospf->vrf_id)) {
                                        if (path->nexthop.s_addr == 0)
                                                vty_out(vty,
                                                        "%24s   directly attached to %s\n",
                                                        "",
                                                        ifindex2ifname(
                                                                path->ifindex,
-                                                               VRF_DEFAULT));
+                                                               ospf->vrf_id));
                                        else
                                                vty_out(vty,
                                                        "%24s   via %s, %s\n",
@@ -7938,7 +8355,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
                                                                path->nexthop),
                                                        ifindex2ifname(
                                                                path->ifindex,
-                                                               VRF_DEFAULT));
+                                                               ospf->vrf_id));
                                }
                        }
                }
@@ -7960,7 +8377,7 @@ static int show_ip_ospf_border_routers_common(struct vty *vty,
        show_ip_ospf_route_network (vty, ospf->new_table);   */
 
        /* Show Router routes. */
-       show_ip_ospf_route_router(vty, ospf->new_rtrs);
+       show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
 
        vty_out(vty, "\n");
 
@@ -7969,18 +8386,49 @@ static int show_ip_ospf_border_routers_common(struct vty *vty,
 
 DEFUN (show_ip_ospf_border_routers,
        show_ip_ospf_border_routers_cmd,
-       "show ip ospf border-routers",
+       "show ip ospf [vrf <NAME|all>] border-routers",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
        "Show all the ABR's and ASBR's\n")
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_border_routers_common(vty, ospf);
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+
+                               ret = show_ip_ospf_border_routers_common(vty,
+                                                                        ospf);
+                       }
+               } else {
+                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+                       if (ospf == NULL || !ospf->oi_running)
+                               return CMD_SUCCESS;
+
+                       ret = show_ip_ospf_border_routers_common(vty, ospf);
+               }
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_border_routers_common(vty, ospf);
+       }
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_border_routers,
@@ -8018,13 +8466,13 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf)
        }
 
        /* Show Network routes. */
-       show_ip_ospf_route_network(vty, ospf->new_table);
+       show_ip_ospf_route_network(vty, ospf, ospf->new_table);
 
        /* Show Router routes. */
-       show_ip_ospf_route_router(vty, ospf->new_rtrs);
+       show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
 
        /* Show AS External routes. */
-       show_ip_ospf_route_external(vty, ospf->old_external_route);
+       show_ip_ospf_route_external(vty, ospf, ospf->old_external_route);
 
        vty_out(vty, "\n");
 
@@ -8033,18 +8481,48 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf)
 
 DEFUN (show_ip_ospf_route,
        show_ip_ospf_route_cmd,
-       "show ip ospf route",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "OSPF routing table\n")
-{
-       struct ospf *ospf;
+       "show ip ospf [vrf <NAME|all>] route",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
+       "OSPF routing table\n")
+{
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+       char *vrf_name = NULL;
+       bool all_vrf = FALSE;
+       int ret = CMD_SUCCESS;
+       int inst = 0;
+       int idx_vrf = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
-       return show_ip_ospf_route_common(vty, ospf);
+       /* vrf input is provided could be all or specific vrf*/
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = show_ip_ospf_route_common(vty, ospf);
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       } else {
+               /* Display default ospf (instance 0) info */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+       }
+
+       if (ospf)
+               ret = show_ip_ospf_route_common(vty, ospf);
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_route,
@@ -8071,6 +8549,77 @@ DEFUN (show_ip_ospf_instance_route,
        return show_ip_ospf_route_common(vty, ospf);
 }
 
+
+DEFUN (show_ip_ospf_vrfs,
+       show_ip_ospf_vrfs_cmd,
+       "show ip ospf vrfs [json]",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Show OSPF VRFs \n"
+       JSON_STR)
+{
+       u_char uj = use_json(argc, argv);
+       json_object *json = NULL;
+       json_object *json_vrfs = NULL;
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+       int count = 0;
+       static char header[] = "Name                       Id     RouterId  ";
+
+       if (uj) {
+               json = json_object_new_object();
+               json_vrfs = json_object_new_object();
+       }
+
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+               json_object *json_vrf = NULL;
+               const char *name = NULL;
+               int vrf_id_ui = 0;
+
+               count++;
+
+               if (!uj && count == 1)
+                       vty_out(vty, "%s\n", header);
+               if (uj)
+                       json_vrf = json_object_new_object();
+
+               if (ospf->vrf_id == 0)
+                       name = VRF_DEFAULT_NAME;
+               else
+                       name = ospf->name;
+
+               vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN) ? -1 : ospf->vrf_id;
+
+               if (uj) {
+                       json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
+                       json_object_string_add(json_vrf, "routerId",
+                                              inet_ntoa(ospf->router_id));
+
+                       json_object_object_add(json_vrfs, name, json_vrf);
+
+               } else {
+                       vty_out(vty, "%-25s  %-5d  %-16s  \n",
+                               name, ospf->vrf_id, inet_ntoa(ospf->router_id));
+               }
+       }
+
+       if (uj) {
+               json_object_object_add(json, "vrfs", json_vrfs);
+               json_object_int_add(json, "totalVrfs", count);
+
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+                                               JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       } else {
+               if (count)
+                       vty_out(vty, "\nTotal number of OSPF VRFs (including default): %d\n",
+                               count);
+       }
+
+       return CMD_SUCCESS;
+}
+
 const char *ospf_abr_type_str[] = {"unknown", "standard", "ibm", "cisco",
                                   "shortcut"};
 
@@ -8082,26 +8631,32 @@ const char *ospf_int_type_str[] = {"unknown", /* should never be used. */
                                   "virtual-link", /* should never be used. */
                                   "loopback"};
 
-/* Configuration write function for ospfd. */
-static int config_write_interface(struct vty *vty)
+static int config_write_interface_one(struct vty *vty, struct ospf *ospf)
 {
        struct listnode *n1, *n2;
        struct interface *ifp;
        struct crypt_key *ck;
-       int write = 0;
        struct route_node *rn = NULL;
        struct ospf_if_params *params;
-       struct ospf *ospf = ospf_lookup();
+       int write = 0;
+
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) {
+               struct vrf *vrf = NULL;
 
-       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) {
                if (memcmp(ifp->name, "VLINK", 5) == 0)
                        continue;
 
                if (ifp->ifindex == IFINDEX_DELETED)
                        continue;
 
+               vrf = vrf_lookup_by_id(ifp->vrf_id);
+
                vty_frame(vty, "!\n");
-               vty_frame(vty, "interface %s\n", ifp->name);
+               if (ifp->vrf_id == VRF_DEFAULT || vrf == NULL)
+                       vty_frame(vty, "interface %s\n", ifp->name);
+               else
+                       vty_frame(vty, "interface %s vrf %s\n",
+                                 ifp->name, vrf->name);
                if (ifp->desc)
                        vty_out(vty, " description %s\n", ifp->desc);
 
@@ -8116,11 +8671,11 @@ static int config_write_interface(struct vty *vty)
                                if (params->type != ospf_default_iftype(ifp)) {
                                        vty_out(vty, " ip ospf network %s",
                                                ospf_int_type_str
-                                                       [params->type]);
+                                               [params->type]);
                                        if (params != IF_DEF_PARAMS(ifp))
                                                vty_out(vty, " %s",
                                                        inet_ntoa(
-                                                               rn->p.u.prefix4));
+                                                                 rn->p.u.prefix4));
                                        vty_out(vty, "\n");
                                }
                        }
@@ -8131,8 +8686,8 @@ static int config_write_interface(struct vty *vty)
                                const char *auth_str;
 
                                /* Translation tables are not that much help
-                                  here due to syntax
-                                  of the simple option */
+                                * here due to syntax
+                                * of the simple option */
                                switch (params->auth_type) {
 
                                case OSPF_AUTH_NULL:
@@ -8172,18 +8727,22 @@ static int config_write_interface(struct vty *vty)
                        }
 
                        /* Cryptographic Authentication Key print. */
-                       for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, n2, ck)) {
-                               vty_out(vty,
-                                       " ip ospf message-digest-key %d md5 %s",
-                                       ck->key_id, ck->auth_key);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
+                       if (params && params->auth_crypt) {
+                               for (ALL_LIST_ELEMENTS_RO(params->auth_crypt,
+                                                         n2, ck)) {
+                                       vty_out(vty,
+                                               " ip ospf message-digest-key %d md5 %s",
+                                               ck->key_id, ck->auth_key);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
                        }
 
                        /* Interface Output Cost print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) {
+                       if (OSPF_IF_PARAM_CONFIGURED(params,
+                                                    output_cost_cmd)) {
                                vty_out(vty, " ip ospf cost %u",
                                        params->output_cost_cmd);
                                if (params != IF_DEF_PARAMS(ifp))
@@ -8207,7 +8766,7 @@ static int config_write_interface(struct vty *vty)
                        /* Router Dead Interval print. */
                        if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
                            && params->v_wait
-                                      != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
+                           != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
                                vty_out(vty, " ip ospf dead-interval ");
 
                                /* fast hello ? */
@@ -8228,7 +8787,7 @@ static int config_write_interface(struct vty *vty)
                        /* Router Priority print. */
                        if (OSPF_IF_PARAM_CONFIGURED(params, priority)
                            && params->priority
-                                      != OSPF_ROUTER_PRIORITY_DEFAULT) {
+                           != OSPF_ROUTER_PRIORITY_DEFAULT) {
                                vty_out(vty, " ip ospf priority %u",
                                        params->priority);
                                if (params != IF_DEF_PARAMS(ifp))
@@ -8241,7 +8800,7 @@ static int config_write_interface(struct vty *vty)
                        if (OSPF_IF_PARAM_CONFIGURED(params,
                                                     retransmit_interval)
                            && params->retransmit_interval
-                                      != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
+                           != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
                                vty_out(vty, " ip ospf retransmit-interval %u",
                                        params->retransmit_interval);
                                if (params != IF_DEF_PARAMS(ifp))
@@ -8253,7 +8812,7 @@ static int config_write_interface(struct vty *vty)
                        /* Transmit Delay print. */
                        if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
                            && params->transmit_delay
-                                      != OSPF_TRANSMIT_DELAY_DEFAULT) {
+                           != OSPF_TRANSMIT_DELAY_DEFAULT) {
                                vty_out(vty, " ip ospf transmit-delay %u",
                                        params->transmit_delay);
                                if (params != IF_DEF_PARAMS(ifp))
@@ -8274,7 +8833,9 @@ static int config_write_interface(struct vty *vty)
                                size_t buflen = MAX(strlen("4294967295"),
                                                    strlen("255.255.255.255"));
                                char buf[buflen];
-                               area_id2str(buf, sizeof(buf), &params->if_area,
+
+                               area_id2str(buf, sizeof(buf),
+                                           &params->if_area,
                                            params->if_area_id_fmt);
                                vty_out(vty, " area %s", buf);
                                if (params != IF_DEF_PARAMS(ifp))
@@ -8318,6 +8879,19 @@ static int config_write_interface(struct vty *vty)
 
                vty_endframe(vty, NULL);
        }
+       return write;
+}
+
+/* Configuration write function for ospfd. */
+static int config_write_interface(struct vty *vty)
+{
+       int write = 0;
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+
+       /* Traverse all ospf [vrf] instances */
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf))
+               write += config_write_interface_one(vty, ospf);
 
        return write;
 }
@@ -8658,154 +9232,174 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf)
        return 0;
 }
 
-/* OSPF configuration write function. */
-static int ospf_config_write(struct vty *vty)
+static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
 {
-       struct ospf *ospf;
        struct interface *ifp;
        struct ospf_interface *oi;
-       struct listnode *node;
+       struct listnode *node = NULL;
        int write = 0;
 
-       ospf = ospf_lookup();
-       if (ospf != NULL && ospf->oi_running) {
-               /* `router ospf' print. */
-               if (ospf->instance)
-                       vty_out(vty, "router ospf %d\n", ospf->instance);
-               else
-                       vty_out(vty, "router ospf\n");
+       /* `router ospf' print. */
+       if (ospf->instance && ospf->name) {
+               vty_out(vty, "router ospf %d vrf %s\n",
+                       ospf->instance, ospf->name);
+       } else if (ospf->instance) {
+               vty_out(vty, "router ospf %d\n",
+                       ospf->instance);
+       } else if (ospf->name) {
+               vty_out(vty, "router ospf vrf %s\n",
+                       ospf->name);
+       } else
+               vty_out(vty, "router ospf\n");
 
+       if (!ospf->networks) {
                write++;
+               return write;
+       }
 
-               if (!ospf->networks)
-                       return write;
-
-               /* Router ID print. */
-               if (ospf->router_id_static.s_addr != 0)
-                       vty_out(vty, " ospf router-id %s\n",
-                               inet_ntoa(ospf->router_id_static));
-
-               /* ABR type print. */
-               if (ospf->abr_type != OSPF_ABR_DEFAULT)
-                       vty_out(vty, " ospf abr-type %s\n",
-                               ospf_abr_type_str[ospf->abr_type]);
-
-               /* log-adjacency-changes flag print. */
-               if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
-                       if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
-                               vty_out(vty, " log-adjacency-changes detail\n");
-                       else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
-                               vty_out(vty, " log-adjacency-changes\n");
-               } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
-                       vty_out(vty, " no log-adjacency-changes\n");
-               }
+       /* Router ID print. */
+       if (ospf->router_id_static.s_addr != 0)
+               vty_out(vty, " ospf router-id %s\n",
+                       inet_ntoa(ospf->router_id_static));
 
-               /* RFC1583 compatibility flag print -- Compatible with CISCO
-                * 12.1. */
-               if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
-                       vty_out(vty, " compatible rfc1583\n");
+       /* ABR type print. */
+       if (ospf->abr_type != OSPF_ABR_DEFAULT)
+               vty_out(vty, " ospf abr-type %s\n",
+                       ospf_abr_type_str[ospf->abr_type]);
 
-               /* auto-cost reference-bandwidth configuration.  */
-               if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
-                       vty_out(vty,
-                               "! Important: ensure reference bandwidth "
-                               "is consistent across all routers\n");
-                       vty_out(vty, " auto-cost reference-bandwidth %d\n",
-                               ospf->ref_bandwidth);
-               }
+       /* log-adjacency-changes flag print. */
+       if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
+               if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
+                       vty_out(vty, " log-adjacency-changes detail\n");
+               else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
+                       vty_out(vty, " log-adjacency-changes\n");
+       } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
+               vty_out(vty, " no log-adjacency-changes\n");
+       }
 
-               /* SPF timers print. */
-               if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
-                   || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
-                   || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
-                       vty_out(vty, " timers throttle spf %d %d %d\n",
-                               ospf->spf_delay, ospf->spf_holdtime,
-                               ospf->spf_max_holdtime);
-
-               /* LSA timers print. */
-               if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
-                       vty_out(vty, " timers throttle lsa all %d\n",
-                               ospf->min_ls_interval);
-               if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
-                       vty_out(vty, " timers lsa min-arrival %d\n",
-                               ospf->min_ls_arrival);
-
-               /* Write multiplier print. */
-               if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
-                       vty_out(vty, " ospf write-multiplier %d\n",
-                               ospf->write_oi_count);
-
-               /* Max-metric router-lsa print */
-               config_write_stub_router(vty, ospf);
-
-               /* SPF refresh parameters print. */
-               if (ospf->lsa_refresh_interval
-                   != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
-                       vty_out(vty, " refresh timer %d\n",
-                               ospf->lsa_refresh_interval);
-
-               /* Redistribute information print. */
-               config_write_ospf_redistribute(vty, ospf);
-
-               /* passive-interface print. */
-               if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
-                       vty_out(vty, " passive-interface default\n");
-
-               for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
-                       if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
-                                                    passive_interface)
-                           && IF_DEF_PARAMS(ifp)->passive_interface
-                                      != ospf->passive_interface_default) {
-                               vty_out(vty, " %spassive-interface %s\n",
-                                       IF_DEF_PARAMS(ifp)->passive_interface
-                                               ? ""
-                                               : "no ",
-                                       ifp->name);
-                       }
-               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
-                       if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
-                                                     passive_interface))
-                               continue;
-                       if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
-                                                    passive_interface)) {
-                               if (oi->params->passive_interface
-                                   == IF_DEF_PARAMS(oi->ifp)
-                                              ->passive_interface)
-                                       continue;
-                       } else if (oi->params->passive_interface
-                                  == ospf->passive_interface_default)
-                               continue;
+       /* RFC1583 compatibility flag print -- Compatible with CISCO
+        * 12.1. */
+       if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
+               vty_out(vty, " compatible rfc1583\n");
 
-                       vty_out(vty, " %spassive-interface %s %s\n",
-                               oi->params->passive_interface ? "" : "no ",
-                               oi->ifp->name,
-                               inet_ntoa(oi->address->u.prefix4));
-               }
+       /* auto-cost reference-bandwidth configuration.  */
+       if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
+               vty_out(vty,
+                       "! Important: ensure reference bandwidth "
+                       "is consistent across all routers\n");
+               vty_out(vty, " auto-cost reference-bandwidth %d\n",
+                       ospf->ref_bandwidth);
+       }
 
-               /* Network area print. */
-               config_write_network_area(vty, ospf);
+       /* SPF timers print. */
+       if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
+           || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
+           || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
+               vty_out(vty, " timers throttle spf %d %d %d\n",
+                       ospf->spf_delay, ospf->spf_holdtime,
+                       ospf->spf_max_holdtime);
+
+       /* LSA timers print. */
+       if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
+               vty_out(vty, " timers throttle lsa all %d\n",
+                       ospf->min_ls_interval);
+       if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
+               vty_out(vty, " timers lsa min-arrival %d\n",
+                       ospf->min_ls_arrival);
 
-               /* Area config print. */
-               config_write_ospf_area(vty, ospf);
+       /* Write multiplier print. */
+       if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
+               vty_out(vty, " ospf write-multiplier %d\n",
+                       ospf->write_oi_count);
 
-               /* static neighbor print. */
-               config_write_ospf_nbr_nbma(vty, ospf);
+       /* Max-metric router-lsa print */
+       config_write_stub_router(vty, ospf);
 
-               /* Virtual-Link print. */
-               config_write_virtual_link(vty, ospf);
+       /* SPF refresh parameters print. */
+       if (ospf->lsa_refresh_interval
+           != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
+               vty_out(vty, " refresh timer %d\n",
+                       ospf->lsa_refresh_interval);
 
-               /* Default metric configuration.  */
-               config_write_ospf_default_metric(vty, ospf);
+       /* Redistribute information print. */
+       config_write_ospf_redistribute(vty, ospf);
 
-               /* Distribute-list and default-information print. */
-               config_write_ospf_distribute(vty, ospf);
+       /* passive-interface print. */
+       if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
+               vty_out(vty, " passive-interface default\n");
 
-               /* Distance configuration. */
-               config_write_ospf_distance(vty, ospf);
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
+               if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
+                                            passive_interface)
+                   && IF_DEF_PARAMS(ifp)->passive_interface
+                   != ospf->passive_interface_default) {
+                       vty_out(vty, " %spassive-interface %s\n",
+                               IF_DEF_PARAMS(ifp)->passive_interface
+                               ? ""
+                               : "no ",
+                               ifp->name);
+               }
+       for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+               if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
+                                             passive_interface))
+                       continue;
+               if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
+                                            passive_interface)) {
+                       if (oi->params->passive_interface
+                           == IF_DEF_PARAMS(oi->ifp)
+                           ->passive_interface)
+                               continue;
+               } else if (oi->params->passive_interface
+                          == ospf->passive_interface_default)
+                       continue;
 
-               ospf_opaque_config_write_router(vty, ospf);
+               vty_out(vty, " %spassive-interface %s %s\n",
+                       oi->params->passive_interface ? "" : "no ",
+                       oi->ifp->name,
+                       inet_ntoa(oi->address->u.prefix4));
        }
 
+       /* Network area print. */
+       config_write_network_area(vty, ospf);
+
+       /* Area config print. */
+       config_write_ospf_area(vty, ospf);
+
+       /* static neighbor print. */
+       config_write_ospf_nbr_nbma(vty, ospf);
+
+       /* Virtual-Link print. */
+       config_write_virtual_link(vty, ospf);
+
+       /* Default metric configuration.  */
+       config_write_ospf_default_metric(vty, ospf);
+
+       /* Distribute-list and default-information print. */
+       config_write_ospf_distribute(vty, ospf);
+
+       /* Distance configuration. */
+       config_write_ospf_distance(vty, ospf);
+
+       ospf_opaque_config_write_router(vty, ospf);
+
+       write++;
+       return write;
+}
+
+/* OSPF configuration write function. */
+static int ospf_config_write(struct vty *vty)
+{
+       struct ospf *ospf;
+       struct listnode *ospf_node = NULL;
+       int write = 0;
+
+       if (listcount(om->ospf) == 0)
+               return write;
+
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) {
+               if (ospf->oi_running)
+                       write += ospf_config_write_one(vty, ospf);
+       }
        return write;
 }
 
@@ -8854,6 +9448,9 @@ void ospf_vty_show_init(void)
 
        install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd);
        install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
+
+       /* "show ip ospf vrfs" commands. */
+       install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
 }
 
 
@@ -8994,17 +9591,20 @@ DEFUN (clear_ip_ospf_interface,
 {
        int idx_ifname = 4;
        struct interface *ifp;
-       struct listnode *node;
+       struct listnode *node, *n1;
+       struct ospf *ospf = NULL;
 
        if (argc == 4) /* Clear all the ospfv2 interfaces. */
        {
-               for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
-                       ospf_interface_clear(ifp);
-       } else /* Interface name is specified. */
-       {
-               if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
-                                            VRF_DEFAULT))
-                   == NULL)
+               for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+                       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+                                                 node, ifp))
+                               ospf_interface_clear(ifp);
+               }
+       } else {
+               /* Interface name is specified. */
+               ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+               if (ifp == NULL)
                        vty_out(vty, "No such interface name\n");
                else
                        ospf_interface_clear(ifp);
index 9bba2c980658b1ef0b37bd52778779dd87fbf7f6..d8fd9afbd7b936e2aaa7d5c39c55a1a4a61287a8 100644 (file)
@@ -53,6 +53,7 @@
 
 DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
 DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
+DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
 
 DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
 DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
@@ -68,23 +69,33 @@ struct in_addr router_id_zebra;
 static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
                                       zebra_size_t length, vrf_id_t vrf_id)
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
        struct prefix router_id;
        zebra_router_id_update_read(zclient->ibuf, &router_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
                char buf[PREFIX2STR_BUFFER];
                prefix2str(&router_id, buf, sizeof(buf));
-               zlog_debug("Zebra rcvd: router id update %s", buf);
+               zlog_debug("Zebra rcvd: router id update %s vrf %s id %u",
+                          buf, ospf_vrf_id_to_name(vrf_id), vrf_id);
        }
 
        router_id_zebra = router_id.u.prefix4;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
 
        if (ospf != NULL)
                ospf_router_id_update(ospf);
-
+       else {
+               if (IS_DEBUG_OSPF_EVENT) {
+                       char buf[PREFIX2STR_BUFFER];
+
+                       prefix2str(&router_id, buf, sizeof(buf));
+                       zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s",
+                                  __PRETTY_FUNCTION__,
+                                  ospf_vrf_id_to_name(vrf_id), vrf_id, buf);
+               }
+       }
        return 0;
 }
 
@@ -92,14 +103,18 @@ static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
 static int ospf_interface_add(int command, struct zclient *zclient,
                              zebra_size_t length, vrf_id_t vrf_id)
 {
-       struct interface *ifp;
+       struct interface *ifp = NULL;
+       struct ospf *ospf = NULL;
 
        ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
+       if (ifp == NULL)
+               return 0;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
-                       "Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d",
-                       ifp->name, ifp->vrf_id, ifp->ifindex,
+                       "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+                       ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+                       ifp->vrf_id, ifp->ifindex,
                        (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
 
        assert(ifp->info);
@@ -109,7 +124,11 @@ static int ospf_interface_add(int command, struct zclient *zclient,
                IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
        }
 
-       ospf_if_update(NULL, ifp);
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
+       if (!ospf)
+               return 0;
+
+       ospf_if_update(ospf, ifp);
 
        hook_call(ospf_if_update, ifp);
 
@@ -136,8 +155,9 @@ static int ospf_interface_delete(int command, struct zclient *zclient,
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
-                       "Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d",
-                       ifp->name, ifp->vrf_id, ifp->ifindex,
+                       "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+                       ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+                       ifp->vrf_id, ifp->ifindex,
                        (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
 
        hook_call(ospf_if_delete, ifp);
@@ -160,7 +180,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s,
 
        /* And look it up. */
        return if_lookup_by_name_len(
-               ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT);
+               ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
 }
 
 static int ospf_interface_state_up(int command, struct zclient *zclient,
@@ -249,6 +269,8 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
                                      zebra_size_t length, vrf_id_t vrf_id)
 {
        struct connected *c;
+       struct ospf *ospf = NULL;
+
 
        c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
 
@@ -258,11 +280,16 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
                char buf[PREFIX2STR_BUFFER];
                prefix2str(c->address, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s address add %s", c->ifp->name,
-                          buf);
+               zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
+                          c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
+                          vrf_id);
        }
 
-       ospf_if_update(NULL, c->ifp);
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
+       if (!ospf)
+               return 0;
+
+       ospf_if_update(ospf, c->ifp);
 
        hook_call(ospf_if_update, c->ifp);
 
@@ -330,19 +357,41 @@ static int ospf_interface_link_params(int command, struct zclient *zclient,
        return 0;
 }
 
+/* VRF update for an interface. */
+static int ospf_interface_vrf_update(int command, struct zclient *zclient,
+                                     zebra_size_t length, vrf_id_t vrf_id)
+{
+       struct interface *ifp = NULL;
+       vrf_id_t new_vrf_id;
+
+       ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
+                                              &new_vrf_id);
+       if (!ifp)
+               return 0;
+
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
+                          __PRETTY_FUNCTION__, ifp->name, vrf_id,
+                          ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
+
+       /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
+       if_update_to_new_vrf(ifp, new_vrf_id);
+
+        return 0;
+}
 
-void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
+                   struct ospf_route *or)
 {
        struct zapi_route api;
        struct zapi_nexthop *api_nh;
        u_char distance;
        struct ospf_path *path;
        struct listnode *node;
-       struct ospf *ospf = ospf_lookup();
        int count = 0;
 
        memset(&api, 0, sizeof(api));
-       api.vrf_id = VRF_DEFAULT;
+       api.vrf_id = ospf->vrf_id;
        api.type = ZEBRA_ROUTE_OSPF;
        api.instance = ospf->instance;
        api.safi = SAFI_UNICAST;
@@ -368,7 +417,7 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
        }
 
        /* Distance value. */
-       distance = ospf_distance_apply(p, or);
+       distance = ospf_distance_apply(ospf, p, or);
        if (distance) {
                SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
                api.distance = distance;
@@ -413,13 +462,13 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
 }
 
-void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
+                      struct ospf_route *or)
 {
        struct zapi_route api;
-       struct ospf *ospf = ospf_lookup();
 
        memset(&api, 0, sizeof(api));
-       api.vrf_id = VRF_DEFAULT;
+       api.vrf_id = ospf->vrf_id;
        api.type = ZEBRA_ROUTE_OSPF;
        api.instance = ospf->instance;
        api.safi = SAFI_UNICAST;
@@ -435,13 +484,12 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
        zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 }
 
-void ospf_zebra_add_discard(struct prefix_ipv4 *p)
+void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
 {
        struct zapi_route api;
-       struct ospf *ospf = ospf_lookup();
 
        memset(&api, 0, sizeof(api));
-       api.vrf_id = VRF_DEFAULT;
+       api.vrf_id = ospf->vrf_id;
        api.type = ZEBRA_ROUTE_OSPF;
        api.instance = ospf->instance;
        api.safi = SAFI_UNICAST;
@@ -455,13 +503,12 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p)
                           inet_ntoa(p->prefix), p->prefixlen);
 }
 
-void ospf_zebra_delete_discard(struct prefix_ipv4 *p)
+void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
 {
        struct zapi_route api;
-       struct ospf *ospf = ospf_lookup();
 
        memset(&api, 0, sizeof(api));
-       api.vrf_id = VRF_DEFAULT;
+       api.vrf_id = ospf->vrf_id;
        api.type = ZEBRA_ROUTE_OSPF;
        api.instance = ospf->instance;
        api.safi = SAFI_UNICAST;
@@ -595,11 +642,11 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
 }
 
 
-int ospf_is_type_redistributed(int type, u_short instance)
+int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
 {
        return (DEFAULT_ROUTE_TYPE(type)
                        ? vrf_bitmap_check(zclient->default_information,
-                                          VRF_DEFAULT)
+                                          ospf->vrf_id)
                        : ((instance
                            && redist_check_instance(
                                       &zclient->mi_redist[AFI_IP][type],
@@ -607,7 +654,7 @@ int ospf_is_type_redistributed(int type, u_short instance)
                           || (!instance
                               && vrf_bitmap_check(
                                          zclient->redist[AFI_IP][type],
-                                         VRF_DEFAULT))));
+                                         ospf->vrf_id))));
 }
 
 int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
@@ -617,7 +664,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
        struct ospf_redist *red;
 
        red = ospf_redist_lookup(ospf, type, instance);
-       if (ospf_is_type_redistributed(type, instance)) {
+       if (ospf_is_type_redistributed(ospf, type, instance)) {
                if (mtype != red->dmetric.type) {
                        red->dmetric.type = mtype;
                        force = LSA_REFRESH_FORCE;
@@ -645,11 +692,11 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
        ospf_external_add(type, instance);
 
        zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
-                            instance, VRF_DEFAULT);
+                            instance, ospf->vrf_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
-               zlog_debug("Redistribute[%s][%d]: Start  Type[%d], Metric[%d]",
-                          ospf_redist_string(type), instance,
+               zlog_debug("Redistribute[%s][%d] vrf id %u: Start  Type[%d], Metric[%d]",
+                          ospf_redist_string(type), instance, ospf->vrf_id,
                           metric_type(ospf, type, instance),
                           metric_value(ospf, type, instance));
 
@@ -663,15 +710,15 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
        if (type == zclient->redist_default && instance == zclient->instance)
                return CMD_SUCCESS;
 
-       if (!ospf_is_type_redistributed(type, instance))
+       if (!ospf_is_type_redistributed(ospf, type, instance))
                return CMD_SUCCESS;
 
        zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
-                            instance, VRF_DEFAULT);
+                            instance, ospf->vrf_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
-               zlog_debug("Redistribute[%s][%d]: Stop",
-                          ospf_redist_string(type), instance);
+               zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
+                          ospf_redist_string(type), instance, ospf->vrf_id);
 
        ospf_redist_del(ospf, type, instance);
 
@@ -698,7 +745,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
 
        ospf_external_add(DEFAULT_ROUTE, 0);
 
-       if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) {
+       if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
                /* if ospf->default_originate changes value, is calling
                   ospf_external_lsa_refresh_default sufficient to implement
                   the change? */
@@ -714,7 +761,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
        }
 
        zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
-                                    VRF_DEFAULT);
+                                    ospf->vrf_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                zlog_debug("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
@@ -734,14 +781,14 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
 
 int ospf_redistribute_default_unset(struct ospf *ospf)
 {
-       if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0))
+       if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
                return CMD_SUCCESS;
 
        ospf->default_originate = DEFAULT_ORIGINATE_NONE;
        ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
 
        zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
-                                    VRF_DEFAULT);
+                                    ospf->vrf_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                zlog_debug("Redistribute[DEFAULT]: Stop");
@@ -886,7 +933,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
        struct ospf *ospf;
        int i;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
        if (ospf == NULL)
                return 0;
 
@@ -1019,10 +1066,13 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
        struct external_info *ei;
        struct route_table *rt;
        struct ospf_lsa *lsa;
-       int type, default_refresh = 0;
-       struct ospf *ospf;
+       int type, default_refresh = 0, arg_type;
+       struct ospf *ospf = NULL;
+       void **arg = THREAD_ARG (thread);
+
+       ospf = (struct ospf *)arg[0];
+       arg_type = (int)(intptr_t)arg[1];
 
-       ospf = ospf_lookup();
        if (ospf == NULL)
                return 0;
 
@@ -1030,6 +1080,12 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
 
        zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
 
+       if (IS_DEBUG_OSPF_EVENT) {
+               zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
+                          __PRETTY_FUNCTION__, arg_type,
+                          ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+       }
+
        /* foreach all external info. */
        for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
                struct list *ext_list;
@@ -1062,15 +1118,21 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
        }
        if (default_refresh)
                ospf_external_lsa_refresh_default(ospf);
+
+       XFREE(MTYPE_OSPF_DIST_ARGS, arg);
        return 0;
 }
 
 /* Update distribute-list and set timer to apply access-list. */
-void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
+void ospf_distribute_list_update(struct ospf *ospf, int type,
                                 u_short instance)
 {
        struct route_table *rt;
        struct ospf_external *ext;
+       void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
+
+       args[0] = ospf;
+       args[1] = (void *)((ptrdiff_t) type);
 
        /* External info does not exist. */
        ext = ospf_external_lookup(type, instance);
@@ -1084,7 +1146,7 @@ void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
        /* Set timer. */
        ospf->t_distribute_update = NULL;
        thread_add_timer_msec(master, ospf_distribute_list_update_timer,
-                             (void *)type, ospf->min_ls_interval,
+                             (void **)args, ospf->min_ls_interval,
                              &ospf->t_distribute_update);
 }
 
@@ -1095,134 +1157,148 @@ static void ospf_filter_update(struct access_list *access)
        int type;
        int abr_inv = 0;
        struct ospf_area *area;
-       struct listnode *node;
+       struct listnode *node, *n1;
 
        /* If OSPF instance does not exist, return right now. */
-       ospf = ospf_lookup();
-       if (ospf == NULL)
+       if (listcount(om->ospf) == 0)
                return;
 
-       /* Update distribute-list, and apply filter. */
-       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
-               struct list *red_list;
-               struct listnode *node;
-               struct ospf_redist *red;
-
-               red_list = ospf->redist[type];
-               if (red_list)
-                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                               if (ROUTEMAP(red)) {
-                                       /* if route-map is not NULL it may be
-                                        * using this access list */
-                                       ospf_distribute_list_update(
-                                               ospf, type, red->instance);
+       /* Iterate all ospf [VRF] instances */
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+               /* Update distribute-list, and apply filter. */
+               for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+                       struct list *red_list;
+                       struct listnode *node;
+                       struct ospf_redist *red;
+
+                       red_list = ospf->redist[type];
+                       if (red_list)
+                               for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+                                       if (ROUTEMAP(red)) {
+                                               /* if route-map is not NULL it may be
+                                                * using this access list */
+                                               ospf_distribute_list_update(
+                                                                           ospf,
+                                                                           type, red->instance);
+                                       }
                                }
-                       }
-
-               /* There is place for route-map for default-information
-                * (ZEBRA_ROUTE_MAX),
-                * but no distribute list. */
-               if (type == ZEBRA_ROUTE_MAX)
-                       break;
-
-               if (DISTRIBUTE_NAME(ospf, type)) {
-                       /* Keep old access-list for distribute-list. */
-                       struct access_list *old = DISTRIBUTE_LIST(ospf, type);
 
-                       /* Update access-list for distribute-list. */
-                       DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
-                               AFI_IP, DISTRIBUTE_NAME(ospf, type));
-
-                       /* No update for this distribute type. */
-                       if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
-                               continue;
-
-                       /* Schedule distribute-list update timer. */
-                       if (DISTRIBUTE_LIST(ospf, type) == NULL
-                           || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
-                                      == 0)
-                               ospf_distribute_list_update(ospf, type, 0);
+                       /* There is place for route-map for default-information
+                        * (ZEBRA_ROUTE_MAX),
+                        * but no distribute list. */
+                       if (type == ZEBRA_ROUTE_MAX)
+                               break;
+
+                       if (DISTRIBUTE_NAME(ospf, type)) {
+                               /* Keep old access-list for distribute-list. */
+                               struct access_list *old = DISTRIBUTE_LIST(ospf,
+                                                                         type);
+
+                               /* Update access-list for distribute-list. */
+                               DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
+                                                                                AFI_IP, DISTRIBUTE_NAME(ospf, type));
+
+                               /* No update for this distribute type. */
+                               if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
+                                       continue;
+
+                               /* Schedule distribute-list update timer. */
+                               if (DISTRIBUTE_LIST(ospf, type) == NULL
+                                   || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
+                                   == 0)
+                                       ospf_distribute_list_update(ospf, type, 0);
+                       }
                }
-       }
 
-       /* Update Area access-list. */
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
-               if (EXPORT_NAME(area)) {
-                       EXPORT_LIST(area) = NULL;
-                       abr_inv++;
-               }
+               /* Update Area access-list. */
+               for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+                       if (EXPORT_NAME(area)) {
+                               EXPORT_LIST(area) = NULL;
+                               abr_inv++;
+                       }
 
-               if (IMPORT_NAME(area)) {
-                       IMPORT_LIST(area) = NULL;
-                       abr_inv++;
+                       if (IMPORT_NAME(area)) {
+                               IMPORT_LIST(area) = NULL;
+                               abr_inv++;
+                       }
                }
-       }
 
-       /* Schedule ABR tasks -- this will be changed -- takada. */
-       if (IS_OSPF_ABR(ospf) && abr_inv)
-               ospf_schedule_abr_task(ospf);
+               /* Schedule ABR tasks -- this will be changed -- takada. */
+               if (IS_OSPF_ABR(ospf) && abr_inv)
+                       ospf_schedule_abr_task(ospf);
+       }
 }
 
 /* If prefix-list is updated, do some updates. */
 void ospf_prefix_list_update(struct prefix_list *plist)
 {
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
        int type;
        int abr_inv = 0;
        struct ospf_area *area;
-       struct listnode *node;
+       struct listnode *node, *n1;
 
        /* If OSPF instatnce does not exist, return right now. */
-       ospf = ospf_lookup();
-       if (ospf == NULL)
+       if (listcount(om->ospf) == 0)
                return;
 
-       /* Update all route-maps which are used as redistribution filters.
-        * They might use prefix-list.
-        */
-       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
-               struct list *red_list;
-               struct listnode *node;
-               struct ospf_redist *red;
-
-               red_list = ospf->redist[type];
-               if (red_list)
-                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                               if (ROUTEMAP(red)) {
-                                       /* if route-map is not NULL it may be
-                                        * using this prefix list */
-                                       ospf_distribute_list_update(
-                                               ospf, type, red->instance);
+       /* Iterate all ospf [VRF] instances */
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+
+               /* Update all route-maps which are used
+                * as redistribution filters.
+                * They might use prefix-list.
+                */
+               for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+                       struct list *red_list;
+                       struct listnode *node;
+                       struct ospf_redist *red;
+
+                       red_list = ospf->redist[type];
+                       if (red_list) {
+                               for (ALL_LIST_ELEMENTS_RO(red_list,
+                                                         node, red)) {
+                                       if (ROUTEMAP(red)) {
+                                               /* if route-map is not NULL
+                                                * it may be using
+                                                * this prefix list */
+                                               ospf_distribute_list_update(
+                                                       ospf, type,
+                                                       red->instance);
+                                       }
                                }
                        }
-       }
+               }
 
-       /* Update area filter-lists. */
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
-               /* Update filter-list in. */
-               if (PREFIX_NAME_IN(area))
-                       if (strcmp(PREFIX_NAME_IN(area),
-                                  prefix_list_name(plist))
-                           == 0) {
-                               PREFIX_LIST_IN(area) = prefix_list_lookup(
-                                       AFI_IP, PREFIX_NAME_IN(area));
-                               abr_inv++;
-                       }
+               /* Update area filter-lists. */
+               for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+                       /* Update filter-list in. */
+                       if (PREFIX_NAME_IN(area))
+                               if (strcmp(PREFIX_NAME_IN(area),
+                                          prefix_list_name(plist)) == 0) {
+                                       PREFIX_LIST_IN(area) =
+                                               prefix_list_lookup(
+                                                                  AFI_IP,
+                                                                  PREFIX_NAME_IN(area));
+                                       abr_inv++;
+                               }
 
-               /* Update filter-list out. */
-               if (PREFIX_NAME_OUT(area))
-                       if (strcmp(PREFIX_NAME_OUT(area),
-                                  prefix_list_name(plist))
-                           == 0) {
-                               PREFIX_LIST_IN(area) = prefix_list_lookup(
-                                       AFI_IP, PREFIX_NAME_OUT(area));
-                               abr_inv++;
-                       }
-       }
+                       /* Update filter-list out. */
+                       if (PREFIX_NAME_OUT(area))
+                               if (strcmp(PREFIX_NAME_OUT(area),
+                                          prefix_list_name(plist)) == 0) {
+                                       PREFIX_LIST_IN(area) =
+                                               prefix_list_lookup(
+                                                                  AFI_IP,
+                                                                  PREFIX_NAME_OUT(area));
+                                       abr_inv++;
+                               }
+               }
 
-       /* Schedule ABR task. */
-       if (IS_OSPF_ABR(ospf) && abr_inv)
-               ospf_schedule_abr_task(ospf);
+               /* Schedule ABR task. */
+               if (IS_OSPF_ABR(ospf) && abr_inv)
+                       ospf_schedule_abr_task(ospf);
+       }
 }
 
 static struct ospf_distance *ospf_distance_new(void)
@@ -1326,11 +1402,10 @@ void ospf_distance_reset(struct ospf *ospf)
                }
 }
 
-u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
+u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
+                          struct ospf_route *or)
 {
-       struct ospf *ospf;
 
-       ospf = ospf_lookup();
        if (ospf == NULL)
                return 0;
 
@@ -1353,6 +1428,37 @@ u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
        return 0;
 }
 
+void ospf_zebra_vrf_register(struct ospf *ospf)
+{
+       if (!zclient || zclient->sock < 0 || !ospf)
+               return;
+
+       if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: Register VRF %s id %u",
+                                  __PRETTY_FUNCTION__,
+                                  ospf_vrf_id_to_name(ospf->vrf_id),
+                                  ospf->vrf_id);
+               zclient_send_reg_requests(zclient, ospf->vrf_id);
+       }
+}
+
+void ospf_zebra_vrf_deregister(struct ospf *ospf)
+{
+       if (!zclient || zclient->sock < 0 || !ospf)
+               return;
+
+       if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: De-Register VRF %s id %u",
+                                  __PRETTY_FUNCTION__,
+                                  ospf_vrf_id_to_name(ospf->vrf_id),
+                                  ospf->vrf_id);
+               /* Deregister for router-id, interfaces,
+                * redistributed routes. */
+               zclient_send_dereg_requests(zclient, ospf->vrf_id);
+       }
+}
 static void ospf_zebra_connected(struct zclient *zclient)
 {
        /* Send the client registration */
@@ -1375,6 +1481,7 @@ void ospf_zebra_init(struct thread_master *master, u_short instance)
        zclient->interface_address_add = ospf_interface_address_add;
        zclient->interface_address_delete = ospf_interface_address_delete;
        zclient->interface_link_params = ospf_interface_link_params;
+       zclient->interface_vrf_update = ospf_interface_vrf_update;
 
        zclient->redistribute_route_add = ospf_zebra_read_route;
        zclient->redistribute_route_del = ospf_zebra_read_route;
index 6fa9e33dddb7bb900d0638842d1f83d3f5a98313..8340f49ede9d82b1ed13b10dc1b6c2867ee74aaf 100644 (file)
@@ -41,21 +41,24 @@ struct ospf_distance {
 };
 
 /* Prototypes */
-extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *);
-extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *);
+extern void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *,
+                          struct ospf_route *);
+extern void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *,
+                             struct ospf_route *);
 
-extern void ospf_zebra_add_discard(struct prefix_ipv4 *);
-extern void ospf_zebra_delete_discard(struct prefix_ipv4 *);
+extern void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *);
+extern void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *);
 
 extern int ospf_redistribute_check(struct ospf *, struct external_info *,
                                   int *);
 extern int ospf_distribute_check_connected(struct ospf *,
                                           struct external_info *);
-extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short);
+extern void ospf_distribute_list_update(struct ospf *, int, u_short);
 
-extern int ospf_is_type_redistributed(int, u_short);
+extern int ospf_is_type_redistributed(struct ospf *, int, u_short);
 extern void ospf_distance_reset(struct ospf *);
-extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *);
+extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
+                                 struct ospf_route *);
 extern struct ospf_external *ospf_external_lookup(u_char, u_short);
 extern struct ospf_external *ospf_external_add(u_char, u_short);
 extern void ospf_external_del(u_char, u_short);
@@ -77,6 +80,8 @@ extern int ospf_distance_set(struct vty *, struct ospf *, const char *,
 extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
                               const char *, const char *);
 extern void ospf_zebra_init(struct thread_master *, u_short);
+extern void ospf_zebra_vrf_register(struct ospf *ospf);
+extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
 
 DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
 DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
index ed1d8901fb4e77f7425328b6d2a336443b5f75b1..507c97d9793d7ac3461479e01c795285708afec8 100644 (file)
@@ -67,6 +67,7 @@ struct ospf_master *om;
 
 extern struct zclient *zclient;
 extern struct in_addr router_id_zebra;
+extern struct zebra_privs_t ospfd_privs;
 
 
 static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
@@ -118,6 +119,10 @@ void ospf_router_id_update(struct ospf *ospf)
        else
                router_id = router_id_zebra;
 
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("Router-ID[OLD:%s]: Update to %s",
+                          inet_ntoa(ospf->router_id),
+                          inet_ntoa(router_id_old));
 
        if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
 
@@ -204,7 +209,7 @@ void ospf_router_id_update(struct ospf *ospf)
                ospf_router_lsa_update(ospf);
 
                /* update ospf_interface's */
-               for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+               for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
                        ospf_if_update(ospf, ifp);
        }
 }
@@ -220,9 +225,10 @@ static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2)
 }
 
 /* Allocate new ospf structure. */
-static struct ospf *ospf_new(u_short instance)
+static struct ospf *ospf_new(u_short instance, const char *name)
 {
        int i;
+       struct vrf *vrf = NULL;
 
        struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
 
@@ -230,6 +236,23 @@ static struct ospf *ospf_new(u_short instance)
        new->router_id.s_addr = htonl(0);
        new->router_id_static.s_addr = htonl(0);
 
+       if (name) {
+               new->vrf_id = VRF_UNKNOWN;
+               /* Freed in ospf_finish_final */
+               new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
+               vrf = vrf_lookup_by_name(new->name);
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d",
+                                  __PRETTY_FUNCTION__, name, new->vrf_id);
+               if (vrf)
+                       ospf_vrf_link(new, vrf);
+       } else {
+               new->vrf_id = VRF_DEFAULT;
+               vrf = vrf_lookup_by_id(VRF_DEFAULT);
+               ospf_vrf_link(new, vrf);
+       }
+       ospf_zebra_vrf_register(new);
+
        new->abr_type = OSPF_ABR_DEFAULT;
        new->oiflist = list_new();
        new->vlinks = list_new();
@@ -286,7 +309,7 @@ static struct ospf *ospf_new(u_short instance)
                         new->lsa_refresh_interval, &new->t_lsa_refresher);
        new->lsa_refresher_started = monotime(NULL);
 
-       if ((new->fd = ospf_sock_init()) < 0) {
+       if ((ospf_sock_init(new)) < 0) {
                zlog_err(
                        "ospf_new: fatal error: ospf_sock_init was unable to open "
                        "a socket");
@@ -313,14 +336,6 @@ static struct ospf *ospf_new(u_short instance)
        return new;
 }
 
-struct ospf *ospf_lookup()
-{
-       if (listcount(om->ospf) == 0)
-               return NULL;
-
-       return listgetdata((struct listnode *)listhead(om->ospf));
-}
-
 struct ospf *ospf_lookup_instance(u_short instance)
 {
        struct ospf *ospf;
@@ -357,13 +372,33 @@ static void ospf_delete(struct ospf *ospf)
        listnode_delete(om->ospf, ospf);
 }
 
-struct ospf *ospf_get()
+struct ospf *ospf_lookup_by_inst_name(u_short instance, const char *name)
+{
+       struct ospf *ospf = NULL;
+       struct listnode *node, *nnode;
+
+       for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
+               if ((ospf->instance == instance) &&
+                   ((ospf->name == NULL && name == NULL) ||
+                    (ospf->name && name && strcmp(ospf->name, name) == 0)))
+                       return ospf;
+       }
+       return NULL;
+}
+
+struct ospf *ospf_get(u_short instance, const char *name)
 {
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       /* vrf name provided call inst and name based api
+        * in case of no name pass default ospf instance */
+       if (name)
+               ospf = ospf_lookup_by_inst_name(instance, name);
+       else
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
        if (ospf == NULL) {
-               ospf = ospf_new(0);
+               ospf = ospf_new(instance, name);
                ospf_add(ospf);
 
                if (ospf->router_id_static.s_addr == 0)
@@ -381,11 +416,20 @@ struct ospf *ospf_get_instance(u_short instance)
 
        ospf = ospf_lookup_instance(instance);
        if (ospf == NULL) {
-               ospf = ospf_new(instance);
+               ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
                ospf_add(ospf);
 
-               if (ospf->router_id_static.s_addr == 0)
+               if (ospf->router_id_static.s_addr == 0) {
+                       if (vrf_lookup_by_id(ospf->vrf_id))
+                               ospf_router_id_update(ospf);
+                       else {
+                               if (IS_DEBUG_OSPF_EVENT)
+                                       zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update"
+                                                   , __PRETTY_FUNCTION__,
+                                                   ospf->vrf_id);
+                       }
                        ospf_router_id_update(ospf);
+               }
 
                ospf_opaque_type11_lsa_init(ospf);
        }
@@ -393,6 +437,34 @@ struct ospf *ospf_get_instance(u_short instance)
        return ospf;
 }
 
+struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
+{
+       struct vrf *vrf = NULL;
+
+       vrf = vrf_lookup_by_id(vrf_id);
+       if (!vrf)
+               return NULL;
+       return (vrf->info) ? (struct ospf *)vrf->info : NULL;
+
+}
+
+/* It should only be used when processing incoming info update from zebra.
+ * Other situations, it is not sufficient to lookup the ospf instance by
+ * vrf_name only without using the instance number.
+ */
+static struct ospf *ospf_lookup_by_name(const char *vrf_name)
+{
+       struct ospf *ospf = NULL;
+       struct listnode *node, *nnode;
+
+       for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
+               if ((ospf->name == NULL && vrf_name == NULL)
+                   || (ospf->name && vrf_name &&
+                       strcmp(ospf->name, vrf_name) == 0))
+                       return ospf;
+       return NULL;
+}
+
 /* Handle the second half of deferred shutdown. This is called either
  * from the deferred-shutdown timer thread, or directly through
  * ospf_deferred_shutdown_check.
@@ -519,6 +591,7 @@ static void ospf_finish_final(struct ospf *ospf)
        struct listnode *node, *nnode;
        int i;
        u_short instance = 0;
+       struct vrf *vrf = NULL;
 
        QOBJ_UNREG(ospf);
 
@@ -550,7 +623,7 @@ static void ospf_finish_final(struct ospf *ospf)
        list_delete(ospf->vlinks);
 
        /* Remove any ospf interface config params */
-       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) {
                struct ospf_if_params *params;
 
                params = IF_DEF_PARAMS(ifp);
@@ -562,6 +635,9 @@ static void ospf_finish_final(struct ospf *ospf)
        for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
                ospf_if_free(oi);
 
+       /* De-Register VRF */
+       ospf_zebra_vrf_deregister(ospf);
+
        /* Clear static neighbors */
        for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
                if ((nbr_nbma = rn->info)) {
@@ -639,7 +715,7 @@ static void ospf_finish_final(struct ospf *ospf)
        if (ospf->old_table)
                ospf_route_table_free(ospf->old_table);
        if (ospf->new_table) {
-               ospf_route_delete(ospf->new_table);
+               ospf_route_delete(ospf, ospf->new_table);
                ospf_route_table_free(ospf->new_table);
        }
        if (ospf->old_rtrs)
@@ -647,11 +723,11 @@ static void ospf_finish_final(struct ospf *ospf)
        if (ospf->new_rtrs)
                ospf_rtrs_free(ospf->new_rtrs);
        if (ospf->new_external_route) {
-               ospf_route_delete(ospf->new_external_route);
+               ospf_route_delete(ospf, ospf->new_external_route);
                ospf_route_table_free(ospf->new_external_route);
        }
        if (ospf->old_external_route) {
-               ospf_route_delete(ospf->old_external_route);
+               ospf_route_delete(ospf, ospf->old_external_route);
                ospf_route_table_free(ospf->old_external_route);
        }
        if (ospf->external_lsas) {
@@ -694,6 +770,17 @@ static void ospf_finish_final(struct ospf *ospf)
 
        ospf_delete(ospf);
 
+       if (ospf->name) {
+               vrf = vrf_lookup_by_name(ospf->name);
+               if (vrf)
+                       ospf_vrf_unlink(ospf, vrf);
+               XFREE(MTYPE_OSPF_TOP, ospf->name);
+       } else {
+               vrf = vrf_lookup_by_id(VRF_DEFAULT);
+               if (vrf)
+                       ospf_vrf_unlink(ospf, vrf);
+       }
+
        XFREE(MTYPE_OSPF_TOP, ospf);
 
        if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
@@ -883,7 +970,7 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
        struct external_info *ei;
        struct ospf_external *ext;
 
-       if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0))
+       if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
                if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
                    && EXTERNAL_INFO(ext)) {
                        for (rn = route_top(EXTERNAL_INFO(ext)); rn;
@@ -1004,9 +1091,10 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
  *
  * Otherwise, doesn't do anything different to ospf_if_update for now
  */
-void ospf_interface_area_set(struct interface *ifp)
+void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
 {
-       struct ospf *ospf = ospf_get();
+       if (!ospf)
+               return;
 
        ospf_if_update(ospf, ifp);
        /* if_update does a update_redistributed */
@@ -1014,19 +1102,17 @@ void ospf_interface_area_set(struct interface *ifp)
        return;
 }
 
-void ospf_interface_area_unset(struct interface *ifp)
+void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
 {
        struct route_node *rn_oi;
-       struct ospf *ospf;
 
-       ospf = ospf_lookup();
        if (!ospf)
                return; /* Ospf not ready yet */
 
        /* Find interfaces that may need to be removed. */
        for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
             rn_oi = route_next(rn_oi)) {
-               struct ospf_interface *oi;
+               struct ospf_interface *oi = NULL;
 
                if ((oi = rn_oi->info) == NULL)
                        continue;
@@ -1174,7 +1260,7 @@ static void ospf_network_run(struct prefix *p, struct ospf_area *area)
                ospf_router_id_update(area->ospf);
 
        /* Get target interface. */
-       for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp))
                ospf_network_run_interface(area->ospf, ifp, p, area);
 }
 
@@ -1203,8 +1289,15 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
 
 void ospf_if_update(struct ospf *ospf, struct interface *ifp)
 {
+
        if (!ospf)
-               ospf = ospf_lookup();
+               return;
+
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
+                          __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
+                          ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
+                          inet_ntoa(ospf->router_id));
 
        /* OSPF must be ready. */
        if (!ospf_is_ready(ospf))
@@ -1863,3 +1956,128 @@ void ospf_master_init(struct thread_master *master)
        om->ospf = list_new();
        om->master = master;
 }
+
+/* Link OSPF instance to VRF. */
+void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
+{
+       ospf->vrf_id = vrf->vrf_id;
+       if (vrf->info != (void *)ospf)
+               vrf->info = (void *)ospf;
+}
+
+/* Unlink OSPF instance from VRF. */
+void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
+{
+       if (vrf->info == (void *)ospf)
+               vrf->info = NULL;
+       ospf->vrf_id = VRF_UNKNOWN;
+}
+
+/* This is hook function for vrf create called as part of vrf_init */
+static int ospf_vrf_new(struct vrf *vrf)
+{
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__,
+                          vrf->name, vrf->vrf_id);
+
+       return 0;
+}
+
+/* This is hook function for vrf delete call as part of vrf_init */
+static int ospf_vrf_delete(struct vrf *vrf)
+{
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__,
+                          vrf->name, vrf->vrf_id);
+
+       return 0;
+}
+
+/* Enable OSPF VRF instance */
+static int ospf_vrf_enable(struct vrf *vrf)
+{
+       struct ospf *ospf = NULL;
+       vrf_id_t old_vrf_id = VRF_DEFAULT;
+
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: VRF %s id %d enabled",
+                          __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+       ospf = ospf_lookup_by_name(vrf->name);
+       if (ospf) {
+               old_vrf_id = ospf->vrf_id;
+               /* We have instance configured, link to VRF and make it "up". */
+               ospf_vrf_link(ospf, vrf);
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)",
+                                  __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
+                                  old_vrf_id);
+
+               if (old_vrf_id != ospf->vrf_id) {
+                       if (ospfd_privs.change(ZPRIVS_RAISE)) {
+                               zlog_err("ospf_sock_init: could not raise privs, %s",
+                                        safe_strerror(errno));
+                       }
+                       if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
+                               return 0;
+                       if (ospfd_privs.change(ZPRIVS_LOWER)) {
+                               zlog_err("ospf_sock_init: could not lower privs, %s",
+                                        safe_strerror(errno));
+                       }
+
+                       ospf->oi_running = 1;
+                       ospf_router_id_update(ospf);
+               }
+       }
+
+       return 0;
+}
+
+/* Disable OSPF VRF instance */
+static int ospf_vrf_disable(struct vrf *vrf)
+{
+       struct ospf *ospf = NULL;
+       vrf_id_t old_vrf_id = VRF_UNKNOWN;
+
+       if (vrf->vrf_id == VRF_DEFAULT)
+               return 0;
+
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: VRF %s id %d disabled.",
+                          __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+       ospf = ospf_lookup_by_name(vrf->name);
+       if (ospf) {
+               old_vrf_id = ospf->vrf_id;
+
+               /* We have instance configured, unlink
+                * from VRF and make it "down".
+                */
+               ospf_vrf_unlink(ospf, vrf);
+               ospf->oi_running = 0;
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug("%s: ospf old_vrf_id %d unlinked",
+                                   __PRETTY_FUNCTION__, old_vrf_id);
+       }
+
+       /* Note: This is a callback, the VRF will be deleted by the caller. */
+       return 0;
+}
+
+void ospf_vrf_init(void)
+{
+       vrf_init(ospf_vrf_new, ospf_vrf_enable,
+                ospf_vrf_disable, ospf_vrf_delete);
+}
+
+void ospf_vrf_terminate(void)
+{
+       vrf_terminate();
+}
+
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
+{
+       struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+       return vrf ? vrf->name : "NIL";
+}
index b49bbdc17dfd33ae1a09acafa19c4953c0eb7ce6..01147c20040aa6b9c931958551b547cc696714ec 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "filter.h"
 #include "log.h"
+#include "vrf.h"
 
 #include "ospf_memory.h"
 #include "ospf_dump_api.h"
@@ -92,8 +93,6 @@ struct ospf_master {
        /* OSPF thread master. */
        struct thread_master *master;
 
-       /* Zebra interface list. */
-       struct list *iflist;
 
        /* Redistributed external information. */
        struct list *external[ZEBRA_ROUTE_MAX + 1];
@@ -136,6 +135,9 @@ struct ospf {
        struct in_addr router_id;       /* Configured automatically. */
        struct in_addr router_id_static; /* Configured manually. */
 
+       vrf_id_t vrf_id;  /* VRF Id */
+       char *name;       /* VRF name */
+
        /* ABR/ASBR internal flags. */
        u_char flags;
 #define OSPF_FLAG_ABR           0x0001
@@ -503,10 +505,12 @@ extern int ospf_zlog;
 
 /* Prototypes. */
 extern const char *ospf_redist_string(u_int route_type);
-extern struct ospf *ospf_lookup(void);
 extern struct ospf *ospf_lookup_instance(u_short);
-extern struct ospf *ospf_get(void);
+extern struct ospf *ospf_get(u_short instance, const char *name);
 extern struct ospf *ospf_get_instance(u_short);
+extern struct ospf *ospf_lookup_by_inst_name(u_short instance,
+                                            const char *name);
+extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
 extern void ospf_finish(struct ospf *);
 extern void ospf_router_id_update(struct ospf *ospf);
 extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
@@ -559,11 +563,15 @@ extern struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *,
 extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *);
 extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *);
 
-extern void ospf_interface_area_set(struct interface *);
-extern void ospf_interface_area_unset(struct interface *);
+extern void ospf_interface_area_set(struct ospf *, struct interface *);
+extern void ospf_interface_area_unset(struct ospf *, struct interface *);
 
 extern void ospf_route_map_init(void);
 
 extern void ospf_master_init(struct thread_master *master);
-
+extern void ospf_vrf_init(void);
+extern void ospf_vrf_terminate(void);
+extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf);
+extern void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf);
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id);
 #endif /* _ZEBRA_OSPFD_H */
index 12c2313e65a41dc1f06aada5e3b3637c7e272394..e063415fbdfa6f03ebf4f55ff9b1f7ba2ef3978f 100644 (file)
@@ -58,6 +58,9 @@ ospfdheader_HEADERS = \
        # end
 endif
 
+ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS)
+ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c
+
 noinst_HEADERS += \
        ospfd/ospf_abr.h \
        ospfd/ospf_apiserver.h \
index 1e88ff13ff86b7299fc7b19bcd98fc4cc63fbee5..7a380796a1c88b625c2942b8d69761aa6ee0849d 100644 (file)
@@ -194,7 +194,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
        }
 
        if (up != NULL)
-               up = hash_get(pnc->upstream_hash, up, hash_alloc_intern);
+               hash_get(pnc->upstream_hash, up, hash_alloc_intern);
 
        if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
                memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
index afe66b6eafea5e818d937abc172eb767f1fda4ad..e19eeb04eea305d96b0ea11ff603afd050844bcc 100755 (executable)
@@ -940,6 +940,32 @@ def compare_context_objects(newconf, running):
     return (lines_to_add, lines_to_del)
 
 
+
+def vtysh_config_available():
+    """
+    Return False if no frr daemon is running or some other vtysh session is
+    in 'configuration terminal' mode which will prevent us from making any
+    configuration changes.
+    """
+
+    try:
+        cmd = ['/usr/bin/vtysh', '-c', 'conf t']
+        output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
+
+        if 'VTY configuration is locked by other VTY' in output:
+            print output
+            log.error("'%s' returned\n%s\n" % (' '.join(cmd), output))
+            return False
+
+    except subprocess.CalledProcessError as e:
+        msg = "vtysh could not connect with any frr daemons"
+        print msg
+        log.error(msg)
+        return False
+
+    return True
+
+
 if __name__ == '__main__':
     # Command line options
     parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs')
@@ -1060,6 +1086,10 @@ if __name__ == '__main__':
 
     elif args.reload:
 
+        # We will not be able to do anything, go ahead and exit(1)
+        if not vtysh_config_available():
+            sys.exit(1)
+
         log.debug('New Frr Config\n%s', newconf.get_lines())
 
         # This looks a little odd but we have to do this twice...here is why
index 73440461ecd33b2bf32ce0686517855d0caa8941..061c25cea5f5a74cb1c7b7a40bac80590d4a864c 100644 (file)
@@ -1273,10 +1273,12 @@ DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng",
        return CMD_SUCCESS;
 }
 
-DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]",
+DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
+       "router ospf [(1-65535)] [vrf NAME]",
        "Enable a routing process\n"
        "Start OSPF configuration\n"
-       "Instance ID\n")
+       "Instance ID\n"
+       VRF_CMD_HELP_STR)
 {
        vty->node = OSPF_NODE;
        return CMD_SUCCESS;
index 4bc9caca5d0768060101e57becd03a4e565a332c..fabb4f9e14d2243d6934fb6fe0c0da2492cc9da5 100644 (file)
@@ -304,6 +304,7 @@ static void addr2hostprefix(int af, const union g_addr *addr,
                prefix->u.prefix6 = addr->ipv6;
                break;
        default:
+               memset(prefix, 0, sizeof(*prefix));
                zlog_warn("%s: unknown address family %d", __func__, af);
                break;
        }