summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_top.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_top.c')
-rw-r--r--ospf6d/ospf6_top.c268
1 files changed, 188 insertions, 80 deletions
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 49b7e4f142..08beb98f20 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -59,17 +59,76 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
)
/* global ospf6d variable */
-struct ospf6 *ospf6;
static struct ospf6_master ospf6_master;
struct ospf6_master *om6;
static void ospf6_disable(struct ospf6 *o);
+static void ospf6_add(struct ospf6 *ospf6)
+{
+ listnode_add(om6->ospf6, ospf6);
+}
+
+static void ospf6_del(struct ospf6 *ospf6)
+{
+ listnode_delete(om6->ospf6, ospf6);
+}
+
+const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+ return vrf ? vrf->name : "NIL";
+}
+
+/* Link OSPF instance to VRF. */
+void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
+{
+ ospf6->vrf_id = vrf->vrf_id;
+ if (vrf->info != (void *)ospf6)
+ vrf->info = (void *)ospf6;
+}
+
+/* Unlink OSPF instance from VRF. */
+void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
+{
+ if (vrf->info == (void *)ospf6)
+ vrf->info = NULL;
+ ospf6->vrf_id = VRF_UNKNOWN;
+}
+
+struct ospf6 *ospf6_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 ospf6 *)vrf->info : NULL;
+}
+
+struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
+{
+ struct ospf6 *o = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) {
+ if (((o->name == NULL && name == NULL)
+ || (o->name && name && strcmp(o->name, name) == 0)))
+ return o;
+ }
+ return NULL;
+}
+
+
static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
{
+ struct ospf6 *ospf6 = NULL;
+
switch (ntohs(lsa->header->type)) {
case OSPF6_LSTYPE_AS_EXTERNAL:
- ospf6_asbr_lsa_add(lsa);
+ ospf6 = ospf6_get_by_lsdb(lsa);
+ ospf6_asbr_lsa_add(lsa, ospf6);
break;
default:
@@ -89,20 +148,23 @@ static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
}
}
-static void ospf6_top_route_hook_add(struct ospf6_route *route)
+static void ospf6_top_route_hook_add(struct ospf6_route *route,
+ struct ospf6 *ospf6)
{
- ospf6_abr_originate_summary(route);
- ospf6_zebra_route_update_add(route);
+ ospf6_abr_originate_summary(route, ospf6);
+ ospf6_zebra_route_update_add(route, ospf6);
}
-static void ospf6_top_route_hook_remove(struct ospf6_route *route)
+static void ospf6_top_route_hook_remove(struct ospf6_route *route,
+ struct ospf6 *ospf6)
{
route->flag |= OSPF6_ROUTE_REMOVE;
- ospf6_abr_originate_summary(route);
- ospf6_zebra_route_update_remove(route);
+ ospf6_abr_originate_summary(route, ospf6);
+ ospf6_zebra_route_update_remove(route, ospf6);
}
-static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
+static void ospf6_top_brouter_hook_add(struct ospf6_route *route,
+ struct ospf6 *ospf6)
{
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
IS_OSPF6_DEBUG_BROUTER) {
@@ -117,12 +179,14 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
route->path.origin.adv_router,
listcount(route->nh_list));
}
- ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
- ospf6_asbr_lsentry_add(route);
- ospf6_abr_originate_summary(route);
+ ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
+ ospf6);
+ ospf6_asbr_lsentry_add(route, ospf6);
+ ospf6_abr_originate_summary(route, ospf6);
}
-static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
+static void ospf6_top_brouter_hook_remove(struct ospf6_route *route,
+ struct ospf6 *ospf6)
{
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
IS_OSPF6_DEBUG_BROUTER) {
@@ -138,9 +202,10 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
listcount(route->nh_list));
}
route->flag |= OSPF6_ROUTE_REMOVE;
- ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
- ospf6_asbr_lsentry_remove(route);
- ospf6_abr_originate_summary(route);
+ ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
+ ospf6);
+ ospf6_asbr_lsentry_remove(route, ospf6);
+ ospf6_abr_originate_summary(route, ospf6);
}
static struct ospf6 *ospf6_create(const char *name)
@@ -153,9 +218,16 @@ static struct ospf6 *ospf6_create(const char *name)
vrf = vrf_lookup_by_name(name);
if (vrf) {
o->vrf_id = vrf->vrf_id;
- /* Freed in ospf6_delete */
- o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
- }
+ } else
+ o->vrf_id = VRF_UNKNOWN;
+
+ /* Freed in ospf6_delete */
+ o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
+ if (vrf)
+ ospf6_vrf_link(o, vrf);
+
+ ospf6_zebra_vrf_register(o);
+
/* initialize */
monotime(&o->starttime);
o->area_list = list_new();
@@ -201,16 +273,20 @@ static struct ospf6 *ospf6_create(const char *name)
return o;
}
-void ospf6_instance_create(const char *name)
+struct ospf6 *ospf6_instance_create(const char *name)
{
+ struct ospf6 *ospf6;
+
ospf6 = ospf6_create(name);
if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
if (ospf6->router_id == 0)
- ospf6_router_id_update();
-
+ ospf6_router_id_update(ospf6);
+ ospf6_add(ospf6);
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
&ospf6->t_ospf6_receive);
+
+ return ospf6;
}
void ospf6_delete(struct ospf6 *o)
@@ -220,8 +296,9 @@ void ospf6_delete(struct ospf6 *o)
QOBJ_UNREG(o);
- ospf6_flush_self_originated_lsas_now();
- ospf6_disable(ospf6);
+ ospf6_flush_self_originated_lsas_now(o);
+ ospf6_disable(o);
+ ospf6_del(o);
for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
ospf6_area_delete(oa);
@@ -232,10 +309,10 @@ void ospf6_delete(struct ospf6 *o)
ospf6_lsdb_delete(o->lsdb);
ospf6_lsdb_delete(o->lsdb_self);
- ospf6_route_table_delete(o->route_table);
- ospf6_route_table_delete(o->brouter_table);
+ ospf6_route_table_delete(o->route_table, o);
+ ospf6_route_table_delete(o->brouter_table, o);
- ospf6_route_table_delete(o->external_table);
+ ospf6_route_table_delete(o->external_table, o);
route_table_finish(o->external_id_table);
ospf6_distance_reset(o);
@@ -260,8 +337,8 @@ static void ospf6_disable(struct ospf6 *o)
ospf6_asbr_redistribute_reset(o->vrf_id);
ospf6_lsdb_remove_all(o->lsdb);
- ospf6_route_remove_all(o->route_table);
- ospf6_route_remove_all(o->brouter_table);
+ ospf6_route_remove_all(o->route_table, o);
+ ospf6_route_remove_all(o->brouter_table, o);
THREAD_OFF(o->maxage_remover);
THREAD_OFF(o->t_spf_calc);
@@ -271,11 +348,13 @@ static void ospf6_disable(struct ospf6 *o)
}
}
-void ospf6_master_init(void)
+void ospf6_master_init(struct thread_master *master)
{
memset(&ospf6_master, 0, sizeof(struct ospf6_master));
om6 = &ospf6_master;
+ om6->ospf6 = list_new();
+ om6->master = master;
}
static int ospf6_maxage_remover(struct thread *thread)
@@ -333,7 +412,7 @@ void ospf6_maxage_remove(struct ospf6 *o)
&o->maxage_remover);
}
-void ospf6_router_id_update(void)
+void ospf6_router_id_update(struct ospf6 *ospf6)
{
if (!ospf6)
return;
@@ -351,8 +430,11 @@ DEFUN_NOSH (router_ospf6,
ROUTER_STR
OSPF6_STR)
{
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
if (ospf6 == NULL)
- ospf6_instance_create(VRF_DEFAULT_NAME);
+ ospf6 = ospf6_instance_create(VRF_DEFAULT_NAME);
/* set current ospf point. */
VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
@@ -368,6 +450,9 @@ DEFUN (no_router_ospf6,
ROUTER_STR
OSPF6_STR)
{
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
if (ospf6 == NULL)
vty_out(vty, "OSPFv3 is not configured\n");
else {
@@ -672,13 +757,14 @@ DEFUN (ospf6_interface_area,
"OSPF6 area ID in decimal notation\n"
)
{
- VTY_DECLVAR_CONTEXT(ospf6, o);
int idx_ifname = 1;
int idx_ipv4 = 3;
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
/* find/create ospf6 interface */
ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
oi = (struct ospf6_interface *)ifp->info;
@@ -691,7 +777,7 @@ DEFUN (ospf6_interface_area,
}
/* parse Area-ID */
- OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
/* attach interface to area */
listnode_add(oa->if_list, oi); /* sort ?? */
@@ -700,14 +786,14 @@ DEFUN (ospf6_interface_area,
SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
/* ospf6 process is currently disabled, not much more to do */
- if (CHECK_FLAG(o->flag, OSPF6_DISABLED))
+ if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
return CMD_SUCCESS;
/* start up */
ospf6_interface_enable(oi);
/* If the router is ABR, originate summary routes */
- if (ospf6_is_router_abr(o))
+ if (ospf6_is_router_abr(ospf6))
ospf6_abr_enable_area(oa);
return CMD_SUCCESS;
@@ -783,6 +869,8 @@ DEFUN (ospf6_stub_router_admin,
struct listnode *node;
struct ospf6_area *oa;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
@@ -805,6 +893,7 @@ DEFUN (no_ospf6_stub_router_admin,
struct listnode *node;
struct ospf6_area *oa;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
@@ -944,8 +1033,10 @@ DEFUN (show_ipv6_ospf6,
IP6_STR
OSPF6_STR)
{
- OSPF6_CMD_CHECK_RUNNING();
+ struct ospf6 *ospf6;
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING(ospf6);
ospf6_show(vty, ospf6);
return CMD_SUCCESS;
}
@@ -966,7 +1057,10 @@ DEFUN (show_ipv6_ospf6_route,
"Detailed information\n"
"Summary of route table\n")
{
- OSPF6_CMD_CHECK_RUNNING();
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING(ospf6);
ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
@@ -983,9 +1077,13 @@ DEFUN (show_ipv6_ospf6_route_match,
"Display routes which match the specified route\n"
"Display routes longer than the specified route\n")
{
- OSPF6_CMD_CHECK_RUNNING();
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING(ospf6);
ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
+
return CMD_SUCCESS;
}
@@ -1001,7 +1099,10 @@ DEFUN (show_ipv6_ospf6_route_match_detail,
"Detailed information\n"
)
{
- OSPF6_CMD_CHECK_RUNNING();
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING(ospf6);
ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
@@ -1022,13 +1123,16 @@ DEFUN (show_ipv6_ospf6_route_type_detail,
"Detailed information\n"
)
{
- OSPF6_CMD_CHECK_RUNNING();
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING(ospf6);
ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
}
-static void ospf6_stub_router_config_write(struct vty *vty)
+static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
{
if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
vty_out(vty, " stub-router administrative\n");
@@ -1036,7 +1140,7 @@ static void ospf6_stub_router_config_write(struct vty *vty)
return;
}
-static int ospf6_distance_config_write(struct vty *vty)
+static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
{
struct route_node *rn;
struct ospf6_distance *odistance;
@@ -1074,52 +1178,56 @@ static int ospf6_distance_config_write(struct vty *vty)
/* OSPF configuration write function. */
static int config_write_ospf6(struct vty *vty)
{
- char router_id[16];
struct listnode *j, *k;
struct ospf6_area *oa;
struct ospf6_interface *oi;
+ struct ospf6 *ospf6;
+ struct listnode *node, *nnode;
/* OSPFv3 configuration. */
- if (ospf6 == NULL)
+ if (om6 == NULL)
return CMD_SUCCESS;
- inet_ntop(AF_INET, &ospf6->router_id_static, router_id,
- sizeof(router_id));
- vty_out(vty, "router ospf6\n");
- if (ospf6->router_id_static != 0)
- vty_out(vty, " ospf6 router-id %s\n", router_id);
-
- /* log-adjacency-changes flag print. */
- if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
- if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
- vty_out(vty, " log-adjacency-changes detail\n");
- else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
- vty_out(vty, " log-adjacency-changes\n");
- } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
- vty_out(vty, " no log-adjacency-changes\n");
- }
+ for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+ vty_out(vty, "router ospf6\n");
+ if (ospf6->router_id_static != 0)
+ vty_out(vty, " ospf6 router-id %pI4\n",
+ &ospf6->router_id_static);
+
+ /* log-adjacency-changes flag print. */
+ if (CHECK_FLAG(ospf6->config_flags,
+ OSPF6_LOG_ADJACENCY_CHANGES)) {
+ if (CHECK_FLAG(ospf6->config_flags,
+ OSPF6_LOG_ADJACENCY_DETAIL))
+ vty_out(vty, " log-adjacency-changes detail\n");
+ else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
+ vty_out(vty, " log-adjacency-changes\n");
+ } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
+ vty_out(vty, " no log-adjacency-changes\n");
+ }
- if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
- vty_out(vty, " auto-cost reference-bandwidth %d\n",
- ospf6->ref_bandwidth);
-
- /* LSA timers print. */
- if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
- vty_out(vty, " timers lsa min-arrival %d\n",
- ospf6->lsa_minarrival);
-
- ospf6_stub_router_config_write(vty);
- ospf6_redistribute_config_write(vty);
- ospf6_area_config_write(vty);
- ospf6_spf_config_write(vty);
- ospf6_distance_config_write(vty);
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
- vty_out(vty, " interface %s area %s\n",
- oi->interface->name, oa->name);
+ if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
+ vty_out(vty, " auto-cost reference-bandwidth %d\n",
+ ospf6->ref_bandwidth);
+
+ /* LSA timers print. */
+ if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
+ vty_out(vty, " timers lsa min-arrival %d\n",
+ ospf6->lsa_minarrival);
+
+ ospf6_stub_router_config_write(vty, ospf6);
+ ospf6_redistribute_config_write(vty, ospf6);
+ ospf6_area_config_write(vty, ospf6);
+ ospf6_spf_config_write(vty, ospf6);
+ ospf6_distance_config_write(vty, ospf6);
+
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
+ vty_out(vty, " interface %s area %s\n",
+ oi->interface->name, oa->name);
+ }
+ vty_out(vty, "!\n");
}
- vty_out(vty, "!\n");
return 0;
}