]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: OSPFv2 VRF Support
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 25 Aug 2017 20:51:12 +0000 (13:51 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Tue, 3 Oct 2017 16:15:19 +0000 (09:15 -0700)
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
27 files changed:
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_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
vtysh/vtysh.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..20d1b5944b16ca435fd5aa011009fe467d6e7114 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,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
 
        struct ospf *ospf;
 
-       ospf = ospf_lookup();
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
        /* Create a stream for internal opaque LSA */
@@ -1429,6 +1431,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
 
        new->area = area;
        new->oi = oi;
+       new->vrf_id = oi->ospf->vrf_id;
 
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, newlsa, length);
@@ -1497,7 +1500,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 +1643,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 +1659,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 +1729,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 +1813,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 +1865,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 +1926,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..b623b173c17895f59a1b1ae1f198af32e0c3ea56 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.
index fa13843764ce06e0b5230c82fe5f4aec31496548..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",
@@ -3046,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:
@@ -3120,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)
@@ -3536,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 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 0ab83c407f09b3161eb6aa7fb2bc47bc684ea17d..f883c034ca9af4fe2fc634ee687787894bd882be 100644 (file)
@@ -907,9 +907,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 +1557,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 +1698,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) {
@@ -2173,6 +2176,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 +2201,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 +2270,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 +2838,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 +2849,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 +2867,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 +3493,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
         */
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..c3ba1d93bc9e619f3184f7325df9499bde205561 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..4d6fc37e7c2378a5d57b5104379514b66a651cb8 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,61 @@ 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,
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               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 cf5fa80f9404e1133556c16c2f8792d22bf35fa3..062cf74c22c7c4d7edbf37a15a1b9bd671b28e93 100644 (file)
@@ -128,34 +128,47 @@ int ospf_oi_count(struct interface *ifp)
 
 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;
+       struct ospf *ospf = NULL;
        u_short instance = 0;
        int ret = CMD_SUCCESS;
+       int idx_vrf = 0;
+       const char *vrf_name = NULL;
+
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               if (argc > 4)
+                       instance = strtoul(argv[2]->arg, NULL, 10);
+               vrf_name = argv[idx_vrf + 1]->arg;
+               /* Allocate VRF aware instance */
+               ospf = ospf_get(instance, vrf_name);
+       } else {
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (!ospf) {
+                       vty_out(vty, "There isn't active ospf instance\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
 
-       ospf = ospf_lookup();
-       if (!ospf) {
-               vty_out(vty, "There isn't active ospf instance \n");
-               return CMD_WARNING_CONFIG_FAILED;
+               if (argc > 2)
+                       instance = strtoul(argv[2]->arg, NULL, 10);
        }
 
-       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. */
        if (ospf->instance != instance) {
                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,21 +178,33 @@ 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;
+       int idx_vrf = 0;
+       const char *vrf_name = NULL;
+
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               if (argc > 5)
+                       instance = strtoul(argv[3]->arg, NULL, 10);
+               vrf_name = argv[idx_vrf + 1]->arg;
+               ospf = ospf_lookup_by_inst_name(instance, vrf_name);
+               if (ospf == NULL)
+                       return CMD_SUCCESS;
+       } else {
+               if (argc > 3)
+                       instance = strtoul(argv[3]->arg, NULL, 10);
 
-       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_lookup_instance(instance);
+               if (ospf == NULL)
+                       return CMD_NOT_MY_INSTANCE;
+       }
 
        ospf_finish(ospf);
 
@@ -292,7 +317,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 +391,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 +463,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 +2451,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 +2477,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 +3137,55 @@ 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));
+       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, 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 +3554,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 +3574,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 +3606,60 @@ 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] interface [INTERFACE] [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
        "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;
-
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
        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 +3830,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 +3854,57 @@ 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;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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 +3931,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 +3948,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 +3958,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 +4032,59 @@ 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;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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 +4125,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 +4134,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 +4176,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 +4213,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 +4224,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 +4585,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 +4674,56 @@ 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;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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 +4811,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 +4824,44 @@ 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;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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 +4915,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 +4964,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 +5652,65 @@ 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;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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 +5720,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,19 +5850,25 @@ 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;
+       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)) {
@@ -5507,14 +5876,44 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                ospf = ospf_lookup_instance(instance);
                if (ospf == NULL)
                        return CMD_NOT_MY_INSTANCE;
-       } else
-               ospf = ospf_lookup();
-
-       if (!ospf || !ospf->oi_running)
-               return CMD_SUCCESS;
-
-       return (show_ip_ospf_database_type_adv_router_common(
-               vty, ospf, idx ? 1 : 0, argc, argv));
+               if (!ospf->oi_running)
+                       return CMD_SUCCESS;
+               return (show_ip_ospf_database_type_adv_router_common(vty, ospf,
+                                                                    idx ? 1 : 0,
+                                                                    argc,
+                                                                    argv));
+       }
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf_name = argv[++idx]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
+       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,
@@ -6159,8 +6558,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);
@@ -6271,9 +6672,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);
@@ -6857,7 +7259,7 @@ DEFUN (ip_ospf_area,
        struct in_addr addr;
        struct ospf_if_params *params;
        struct route_node *rn;
-       struct ospf *ospf;
+       struct ospf *ospf = NULL;
        u_short instance = 0;
        char *areaid;
 
@@ -6867,13 +7269,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;
@@ -6925,7 +7331,7 @@ DEFUN (ip_ospf_area,
        SET_IF_PARAM(params, if_area);
        params->if_area = area_id;
        params->if_area_id_fmt = format;
-       ospf_interface_area_set(ifp);
+       ospf_interface_area_set(ospf, ifp);
        ospf->if_ospf_cli_count++;
 
        return CMD_SUCCESS;
@@ -6953,7 +7359,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;
 
@@ -6983,7 +7393,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;
 }
@@ -7657,7 +8067,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;
        }
@@ -7713,7 +8123,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;
        }
@@ -7762,7 +8172,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 ;
@@ -7802,14 +8213,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",
@@ -7818,14 +8229,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 ;
@@ -7833,7 +8245,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
        struct listnode *node;
        struct ospf_path *path;
 
-       vty_out(vty, "============ OSPF router routing table =============\n");
+       /*vty_out(vty, "============ OSPF router routing table =============\n");*/
        for (rn = route_top(rtrs); rn; rn = route_next(rn))
                if (rn->info) {
                        int flag = 0;
@@ -7864,14 +8276,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",
@@ -7880,7 +8292,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));
                                        }
                                }
                        }
@@ -7888,7 +8300,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;
@@ -7921,14 +8334,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",
@@ -7937,7 +8350,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));
                                }
                        }
                }
@@ -7959,7 +8372,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");
 
@@ -7968,18 +8381,59 @@ 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;
+       int count = 0;
 
-       if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
-               return CMD_SUCCESS;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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;
+                               count++;
+                               if (count == 1)
+                                       vty_out(vty,
+                                                "============ OSPF router routing table =============\n");
+
+                               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;
+
+                       vty_out(vty, "============ OSPF router routing table =============\n");
+                       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;
+               vty_out(vty, "============ OSPF router routing table =============\n");
+               ret = show_ip_ospf_border_routers_common(vty, ospf);
+       }
+
+       return ret;
 }
 
 DEFUN (show_ip_ospf_instance_border_routers,
@@ -8017,13 +8471,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");
 
@@ -8032,18 +8486,51 @@ 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;
+       if (argv_find (argv, argc, "vrf", &idx_vrf)) {
+               vrf_name = argv[idx_vrf + 1]->arg;
+               all_vrf = strmatch(vrf_name, "all");
+       }
 
-       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,
@@ -8070,6 +8557,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"};
 
@@ -8090,234 +8648,240 @@ static int config_write_interface(struct vty *vty)
        int write = 0;
        struct route_node *rn = NULL;
        struct ospf_if_params *params;
-       struct ospf *ospf = ospf_lookup();
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
 
-       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) {
-               if (memcmp(ifp->name, "VLINK", 5) == 0)
-                       continue;
+       /* Traverse all ospf [vrf] instances */
+       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
 
-               if (ifp->ifindex == IFINDEX_DELETED)
-                       continue;
+               for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) {
+                       if (memcmp(ifp->name, "VLINK", 5) == 0)
+                               continue;
 
-               vty_frame(vty, "!\n");
-               vty_frame(vty, "interface %s\n", ifp->name);
-               if (ifp->desc)
-                       vty_out(vty, " description %s\n", ifp->desc);
+                       if (ifp->ifindex == IFINDEX_DELETED)
+                               continue;
 
-               write++;
+                       vty_frame(vty, "!\n");
+                       vty_frame(vty, "interface %s\n", ifp->name);
+                       if (ifp->desc)
+                               vty_out(vty, " description %s\n", ifp->desc);
 
-               params = IF_DEF_PARAMS(ifp);
+                       write++;
+
+                       params = IF_DEF_PARAMS(ifp);
 
-               do {
-                       /* Interface Network print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, type)
-                           && params->type != OSPF_IFTYPE_LOOPBACK) {
-                               if (params->type != ospf_default_iftype(ifp)) {
-                                       vty_out(vty, " ip ospf network %s",
-                                               ospf_int_type_str
+                       do {
+                               /* Interface Network print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, type)
+                                   && params->type != OSPF_IFTYPE_LOOPBACK) {
+                                       if (params->type != ospf_default_iftype(ifp)) {
+                                               vty_out(vty, " ip ospf network %s",
+                                                       ospf_int_type_str
                                                        [params->type]);
-                                       if (params != IF_DEF_PARAMS(ifp))
-                                               vty_out(vty, " %s",
+                                               if (params != IF_DEF_PARAMS(ifp))
+                                                       vty_out(vty, " %s",
                                                        inet_ntoa(
                                                                rn->p.u.prefix4));
-                                       vty_out(vty, "\n");
+                                               vty_out(vty, "\n");
+                                       }
                                }
-                       }
 
-                       /* OSPF interface authentication print */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, auth_type)
-                           && params->auth_type != OSPF_AUTH_NOTSET) {
-                               const char *auth_str;
+                               /* OSPF interface authentication print */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, auth_type)
+                                   && params->auth_type != OSPF_AUTH_NOTSET) {
+                                       const char *auth_str;
 
-                               /* Translation tables are not that much help
-                                  here due to syntax
-                                  of the simple option */
-                               switch (params->auth_type) {
+                                       /* Translation tables are not that much help
+                                        * here due to syntax
+                                        * of the simple option */
+                                       switch (params->auth_type) {
 
-                               case OSPF_AUTH_NULL:
-                                       auth_str = " null";
-                                       break;
+                                       case OSPF_AUTH_NULL:
+                                               auth_str = " null";
+                                               break;
 
-                               case OSPF_AUTH_SIMPLE:
-                                       auth_str = "";
-                                       break;
+                                       case OSPF_AUTH_SIMPLE:
+                                               auth_str = "";
+                                               break;
 
-                               case OSPF_AUTH_CRYPTOGRAPHIC:
-                                       auth_str = " message-digest";
-                                       break;
+                                       case OSPF_AUTH_CRYPTOGRAPHIC:
+                                               auth_str = " message-digest";
+                                               break;
 
-                               default:
-                                       auth_str = "";
-                                       break;
+                                       default:
+                                               auth_str = "";
+                                               break;
+                                       }
+
+                                       vty_out(vty, " ip ospf authentication%s",
+                                               auth_str);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
                                }
 
-                               vty_out(vty, " ip ospf authentication%s",
-                                       auth_str);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Simple Authentication Password print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, auth_simple)
+                                   && params->auth_simple[0] != '\0') {
+                                       vty_out(vty, " ip ospf authentication-key %s",
+                                               params->auth_simple);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* Simple Authentication Password print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, auth_simple)
-                           && params->auth_simple[0] != '\0') {
-                               vty_out(vty, " ip ospf authentication-key %s",
-                                       params->auth_simple);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* 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");
+                               }
 
-                       /* 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");
-                       }
+                               /* Interface Output Cost print. */
+                               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))
+                                               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)) {
-                               vty_out(vty, " ip ospf cost %u",
-                                       params->output_cost_cmd);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Hello Interval print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, v_hello)
+                                   && params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) {
+                                       vty_out(vty, " ip ospf hello-interval %u",
+                                               params->v_hello);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* Hello Interval print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, v_hello)
-                           && params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) {
-                               vty_out(vty, " ip ospf hello-interval %u",
-                                       params->v_hello);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
 
+                               /* Router Dead Interval print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
+                                   && params->v_wait
+                                   != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
+                                       vty_out(vty, " ip ospf dead-interval ");
 
-                       /* Router Dead Interval print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
-                           && params->v_wait
-                                      != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
-                               vty_out(vty, " ip ospf dead-interval ");
+                                       /* fast hello ? */
+                                       if (OSPF_IF_PARAM_CONFIGURED(params,
+                                                                    fast_hello))
+                                               vty_out(vty,
+                                                       "minimal hello-multiplier %d",
+                                                       params->fast_hello);
+                                       else
+                                               vty_out(vty, "%u", params->v_wait);
 
-                               /* fast hello ? */
-                               if (OSPF_IF_PARAM_CONFIGURED(params,
-                                                            fast_hello))
-                                       vty_out(vty,
-                                               "minimal hello-multiplier %d",
-                                               params->fast_hello);
-                               else
-                                       vty_out(vty, "%u", params->v_wait);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Router Priority print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, priority)
+                                   && params->priority
+                                   != OSPF_ROUTER_PRIORITY_DEFAULT) {
+                                       vty_out(vty, " ip ospf priority %u",
+                                               params->priority);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* Router Priority print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, priority)
-                           && params->priority
-                                      != OSPF_ROUTER_PRIORITY_DEFAULT) {
-                               vty_out(vty, " ip ospf priority %u",
-                                       params->priority);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Retransmit Interval print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params,
+                                                            retransmit_interval)
+                                   && params->retransmit_interval
+                                   != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
+                                       vty_out(vty, " ip ospf retransmit-interval %u",
+                                               params->retransmit_interval);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* Retransmit Interval print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params,
-                                                    retransmit_interval)
-                           && params->retransmit_interval
-                                      != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
-                               vty_out(vty, " ip ospf retransmit-interval %u",
-                                       params->retransmit_interval);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Transmit Delay print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
+                                   && params->transmit_delay
+                                   != OSPF_TRANSMIT_DELAY_DEFAULT) {
+                                       vty_out(vty, " ip ospf transmit-delay %u",
+                                               params->transmit_delay);
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* Transmit Delay print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
-                           && params->transmit_delay
-                                      != OSPF_TRANSMIT_DELAY_DEFAULT) {
-                               vty_out(vty, " ip ospf transmit-delay %u",
-                                       params->transmit_delay);
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* Area  print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
+                                       if (ospf->instance)
+                                               vty_out(vty, " ip ospf %d",
+                                                       ospf->instance);
+                                       else
+                                               vty_out(vty, " ip ospf");
 
-                       /* Area  print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
-                               if (ospf->instance)
-                                       vty_out(vty, " ip ospf %d",
-                                               ospf->instance);
-                               else
-                                       vty_out(vty, " ip ospf");
-
-
-                               size_t buflen = MAX(strlen("4294967295"),
-                                                   strlen("255.255.255.255"));
-                               char buf[buflen];
-                               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))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
 
-                       /* bfd  print. */
-                       ospf_bfd_write_config(vty, params);
+                                       size_t buflen = MAX(strlen("4294967295"),
+                                                           strlen("255.255.255.255"));
+                                       char buf[buflen];
+                                       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))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       /* MTU ignore print. */
-                       if (OSPF_IF_PARAM_CONFIGURED(params, mtu_ignore)
-                           && params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) {
-                               if (params->mtu_ignore == 0)
-                                       vty_out(vty, " no ip ospf mtu-ignore");
-                               else
-                                       vty_out(vty, " ip ospf mtu-ignore");
-                               if (params != IF_DEF_PARAMS(ifp))
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
-                               vty_out(vty, "\n");
-                       }
+                               /* bfd  print. */
+                               ospf_bfd_write_config(vty, params);
 
+                               /* MTU ignore print. */
+                               if (OSPF_IF_PARAM_CONFIGURED(params, mtu_ignore)
+                                   && params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) {
+                                       if (params->mtu_ignore == 0)
+                                               vty_out(vty, " no ip ospf mtu-ignore");
+                                       else
+                                               vty_out(vty, " ip ospf mtu-ignore");
+                                       if (params != IF_DEF_PARAMS(ifp))
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, "\n");
+                               }
 
-                       while (1) {
-                               if (rn == NULL)
-                                       rn = route_top(IF_OIFS_PARAMS(ifp));
-                               else
-                                       rn = route_next(rn);
 
-                               if (rn == NULL)
-                                       break;
-                               params = rn->info;
-                               if (params != NULL)
-                                       break;
-                       }
-               } while (rn);
+                               while (1) {
+                                       if (rn == NULL)
+                                               rn = route_top(IF_OIFS_PARAMS(ifp));
+                                       else
+                                               rn = route_next(rn);
 
-               ospf_opaque_config_write_if(vty, ifp);
+                                       if (rn == NULL)
+                                               break;
+                                       params = rn->info;
+                                       if (params != NULL)
+                                               break;
+                               }
+                       } while (rn);
 
-               vty_endframe(vty, NULL);
-       }
+                       ospf_opaque_config_write_if(vty, ifp);
 
+                       vty_endframe(vty, NULL);
+               }
+       }
        return write;
 }
 
@@ -8663,148 +9227,159 @@ static int ospf_config_write(struct vty *vty)
        struct ospf *ospf;
        struct interface *ifp;
        struct ospf_interface *oi;
-       struct listnode *node;
+       struct listnode *node, *ospf_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");
-
-               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");
-               }
+       if (listcount(om->ospf) == 0)
+               return write;
+       for (ALL_LIST_ELEMENTS_RO (om->ospf, ospf_node, ospf)) {
+               if (ospf->oi_running) {
+                       /* `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");
 
-               /* RFC1583 compatibility flag print -- Compatible with CISCO
-                * 12.1. */
-               if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
-                       vty_out(vty, " compatible rfc1583\n");
+                       if (!ospf->networks) {
+                               write++;
+                               continue;
+                       }
 
-               /* 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);
-               }
+                       /* 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");
+                       }
+
+                       /* RFC1583 compatibility flag print -- Compatible with CISCO
+                        * 12.1. */
+                       if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
+                               vty_out(vty, " compatible rfc1583\n");
+
+                       /* 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);
+                       }
 
-               /* 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
+                       /* 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)
+                                               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;
-                       } else if (oi->params->passive_interface
-                                  == ospf->passive_interface_default)
-                               continue;
 
-                       vty_out(vty, " %spassive-interface %s %s\n",
-                               oi->params->passive_interface ? "" : "no ",
-                               oi->ifp->name,
-                               inet_ntoa(oi->address->u.prefix4));
-               }
+                               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);
+                       /* Network area print. */
+                       config_write_network_area(vty, ospf);
 
-               /* Area config print. */
-               config_write_ospf_area(vty, ospf);
+                       /* Area config print. */
+                       config_write_ospf_area(vty, ospf);
 
-               /* static neighbor print. */
-               config_write_ospf_nbr_nbma(vty, ospf);
+                       /* static neighbor print. */
+                       config_write_ospf_nbr_nbma(vty, ospf);
 
-               /* Virtual-Link print. */
-               config_write_virtual_link(vty, ospf);
+                       /* Virtual-Link print. */
+                       config_write_virtual_link(vty, ospf);
 
-               /* Default metric configuration.  */
-               config_write_ospf_default_metric(vty, ospf);
+                       /* Default metric configuration.  */
+                       config_write_ospf_default_metric(vty, ospf);
 
-               /* Distribute-list and default-information print. */
-               config_write_ospf_distribute(vty, ospf);
+                       /* Distribute-list and default-information print. */
+                       config_write_ospf_distribute(vty, ospf);
 
-               /* Distance configuration. */
-               config_write_ospf_distance(vty, ospf);
+                       /* Distance configuration. */
+                       config_write_ospf_distance(vty, ospf);
 
-               ospf_opaque_config_write_router(vty, ospf);
-       }
+                       ospf_opaque_config_write_router(vty, ospf);
 
+                       write++;
+               }
+       }
        return write;
 }
 
@@ -8853,6 +9428,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);
 }
 
 
@@ -8993,17 +9571,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..cb6c1338e0b4c769e92bdaa13294661f607feb85 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,16 @@ 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 (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 +122,9 @@ 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);
+
+       ospf_if_update(ospf, ifp);
 
        hook_call(ospf_if_update, ifp);
 
@@ -136,8 +151,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 +176,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 +265,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 +276,14 @@ 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);
+
+       ospf_if_update(ospf, c->ifp);
 
        hook_call(ospf_if_update, c->ifp);
 
@@ -330,19 +351,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;
 
-void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
+       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 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 +411,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 +456,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 +478,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 +497,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 +636,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 +648,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 +658,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 +686,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 +704,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 +739,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 +755,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 +775,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 +927,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 +1060,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 +1074,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,16 +1112,22 @@ 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);
        if (!ext || !(rt = EXTERNAL_INFO(ext)))
@@ -1084,7 +1140,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 +1151,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 +1396,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 +1422,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 +1475,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..85fbe6151097a247965d3809b11a0c983254cf7b 100644 (file)
@@ -118,6 +118,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 +208,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 +224,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 +235,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();
@@ -313,14 +335,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 +371,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 +415,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 +436,29 @@ 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;
+
+}
+
+struct ospf *ospf_lookup_by_name(const char *name)
+{
+       struct ospf *ospf = NULL;
+       struct listnode *node, *nnode;
+
+       for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
+               if ((ospf->name == NULL && name == NULL)
+                   || (ospf->name && name && strcmp(ospf->name, 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 +585,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 +617,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 +629,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 +709,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 +717,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 +764,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 +964,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 +1085,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 +1096,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;
@@ -1204,7 +1284,13 @@ 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();
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
+       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 +1949,117 @@ 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) {
+                       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..afc7786c03c14c4d65d88629f4f6b7898a1f8431 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "filter.h"
 #include "log.h"
+#include "vrf.h"
 
 #include "ospf_memory.h"
 #include "ospf_dump_api.h"
@@ -136,6 +137,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 +507,17 @@ 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_name(const char *name);
+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 struct ospf *ospf_lookup_by_name(const char *name);
+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 +570,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 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;