From b5a8894de6454e1dc0b75e1d676c5ed0fcf3438b Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 25 Aug 2017 13:51:12 -0700 Subject: [PATCH] ospfd: OSPFv2 VRF Support Signed-off-by: Chirag Shah --- ospfd/ospf_abr.c | 6 +- ospfd/ospf_apiserver.c | 35 +- ospfd/ospf_asbr.c | 3 +- ospfd/ospf_ase.c | 13 +- ospfd/ospf_bfd.c | 9 +- ospfd/ospf_dump.c | 8 +- ospfd/ospf_flood.c | 9 +- ospfd/ospf_flood.h | 3 +- ospfd/ospf_interface.c | 22 +- ospfd/ospf_lsa.c | 29 +- ospfd/ospf_lsa.h | 8 +- ospfd/ospf_main.c | 2 +- ospfd/ospf_opaque.c | 16 +- ospfd/ospf_packet.c | 29 +- ospfd/ospf_ri.c | 25 +- ospfd/ospf_route.c | 37 +- ospfd/ospf_route.h | 8 +- ospfd/ospf_routemap.c | 98 +-- ospfd/ospf_snmp.c | 38 +- ospfd/ospf_spf.c | 20 +- ospfd/ospf_te.c | 77 +- ospfd/ospf_vty.c | 1503 ++++++++++++++++++++++++++++------------ ospfd/ospf_zebra.c | 403 +++++++---- ospfd/ospf_zebra.h | 19 +- ospfd/ospfd.c | 254 ++++++- ospfd/ospfd.h | 25 +- vtysh/vtysh.c | 6 +- 27 files changed, 1866 insertions(+), 839 deletions(-) diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 968461b4d0..f7aa94ad18 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -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); diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index a5f5971ac0..20d1b5944b 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -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. */ diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index e3b66d597b..89c462693b 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -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); diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index bf2b809ddc..877e4b7fb0 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -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) diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index 6d07b44364..9254e7d240 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -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) diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 619bd4e5f5..eca0f85f57 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -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) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index c775f2ea2e..aac2f3ee92 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -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); diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index b74894567d..6f7ecfccf0 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -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 *); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 422e1a2a6b..b623b173c1 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -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. diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index fa13843764..e5d4d34231 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -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); diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index ab8e62b6e4..94a34d4a90 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -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 *, diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index f284a04cbe..7bd644f43d 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -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(); diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index db523bd2a4..bc71e371b1 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -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) { diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 0ab83c407f..f883c034ca 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -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 */ diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 13013bf8ca..f9e346b1d1 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -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"); diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 89ea331b52..ca851ec75d 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -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; } diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 1999379844..76df54fb3f 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -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 *); diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index f47e2b6f1e..c3ba1d93bc 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -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; diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 6a352380b8..36ae091f99 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -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; diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 891088ecc2..5e57426089 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -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); diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 5517008909..4d6fc37e7c 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -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 ] 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); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index cf5fa80f94..062cf74c22 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -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 ] [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 ] 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 ] 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 ] 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 ] 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 ", + "show ip ospf [vrf ] database ", 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 [ [A.B.C.D []]]", + "show ip ospf [(1-65535)] [vrf NAME] database [ [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 ", + "show ip ospf [(1-65535)] [vrf NAME] database ", 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 ] 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 ] 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), ¶ms->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), + ¶ms->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); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 9bba2c9806..cb6c1338e0 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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; diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 6fa9e33ddd..8340f49ede 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -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)) diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index ed1d8901fb..85fbe61510 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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"; +} diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b49bbdc17d..afc7786c03 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -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 */ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 73440461ec..061c25cea5 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -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; -- 2.39.5