summaryrefslogtreecommitdiff
path: root/ospf6d
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_area.c6
-rw-r--r--ospf6d/ospf6_asbr.c5
-rw-r--r--ospf6d/ospf6_asbr.h1
-rw-r--r--ospf6d/ospf6_interface.c58
-rw-r--r--ospf6d/ospf6_interface.h3
-rw-r--r--ospf6d/ospf6_intra.c2
-rw-r--r--ospf6d/ospf6_lsa.c5
-rw-r--r--ospf6d/ospf6_lsa.h1
-rw-r--r--ospf6d/ospf6_main.c35
-rw-r--r--ospf6d/ospf6_message.c20
-rw-r--r--ospf6d/ospf6_message.h1
-rw-r--r--ospf6d/ospf6_route.c15
-rw-r--r--ospf6d/ospf6_spf.c35
-rw-r--r--ospf6d/ospf6_top.c9
-rw-r--r--ospf6d/ospf6_top.h1
-rw-r--r--ospf6d/ospf6_zebra.c3
16 files changed, 161 insertions, 39 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 3c999bbc..f4b327e4 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -199,14 +199,10 @@ ospf6_area_delete (struct ospf6_area *oa)
ospf6_lsdb_delete (oa->lsdb);
ospf6_lsdb_delete (oa->lsdb_self);
+ ospf6_spf_table_finish (oa->spf_table);
ospf6_route_table_delete (oa->spf_table);
ospf6_route_table_delete (oa->route_table);
-#if 0
- ospf6_spftree_delete (oa->spf_tree);
- ospf6_route_table_delete (oa->topology_table);
-#endif /*0*/
-
THREAD_OFF (oa->thread_spf_calculation);
THREAD_OFF (oa->thread_route_calculation);
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 685b147c..3efaab44 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1219,6 +1219,11 @@ ospf6_asbr_init (void)
install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
}
+void
+ospf6_asbr_terminate (void)
+{
+ route_map_finish ();
+}
DEFUN (debug_ospf6_asbr,
debug_ospf6_asbr_cmd,
diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h
index 7166aa3e..6deb93ef 100644
--- a/ospf6d/ospf6_asbr.h
+++ b/ospf6d/ospf6_asbr.h
@@ -79,6 +79,7 @@ extern void ospf6_asbr_redistribute_remove (int type, int ifindex,
extern int ospf6_redistribute_config_write (struct vty *vty);
extern void ospf6_asbr_init (void);
+extern void ospf6_asbr_terminate (void);
extern int config_write_ospf6_debug_asbr (struct vty *vty);
extern void install_element_ospf6_debug_asbr (void);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index cb347451..236baf17 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -118,6 +118,7 @@ ospf6_interface_create (struct interface *ifp)
oi->cost = 1;
oi->state = OSPF6_INTERFACE_DOWN;
oi->flag = 0;
+ oi->mtu_ignore = 0;
/* Try to adjust I/O buffer size with IfMtu */
oi->ifmtu = ifp->mtu6;
@@ -784,6 +785,8 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
{
vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
+ vty_out (vty, " MTU mismatch detection: %s%s", oi->mtu_ignore ?
+ "disabled" : "enabled", VNL);
inet_ntop (AF_INET, &oi->area->area_id,
strbuf, sizeof (strbuf));
vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost,
@@ -1368,6 +1371,55 @@ DEFUN (no_ipv6_ospf6_passive,
return CMD_SUCCESS;
}
+DEFUN (ipv6_ospf6_mtu_ignore,
+ ipv6_ospf6_mtu_ignore_cmd,
+ "ipv6 ospf6 mtu-ignore",
+ IP6_STR
+ OSPF6_STR
+ "Ignore MTU mismatch on this interface\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL)
+ oi = ospf6_interface_create (ifp);
+ assert (oi);
+
+ oi->mtu_ignore = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_mtu_ignore,
+ no_ipv6_ospf6_mtu_ignore_cmd,
+ "no ipv6 ospf6 mtu-ignore",
+ NO_STR
+ IP6_STR
+ OSPF6_STR
+ "Ignore MTU mismatch on this interface\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL)
+ oi = ospf6_interface_create (ifp);
+ assert (oi);
+
+ oi->mtu_ignore = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ipv6_ospf6_advertise_prefix_list,
ipv6_ospf6_advertise_prefix_list_cmd,
"ipv6 ospf6 advertise prefix-list WORD",
@@ -1495,6 +1547,9 @@ config_write_ospf6_interface (struct vty *vty)
if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
vty_out (vty, " ipv6 ospf6 passive%s", VNL);
+ if (oi->mtu_ignore)
+ vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
+
vty_out (vty, "!%s", VNL);
}
return 0;
@@ -1547,6 +1602,9 @@ ospf6_interface_init (void)
install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
+ install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
+ install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
+
install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
}
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 878c29e2..cf758c07 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -76,6 +76,9 @@ struct ospf6_interface
/* OSPF6 Interface flag */
char flag;
+ /* MTU mismatch check */
+ u_char mtu_ignore;
+
/* Decision of DR Election */
u_int32_t drouter;
u_int32_t bdrouter;
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 05b11ba3..9bc603b3 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1177,6 +1177,8 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
}
ospf6_route_remove (route, oa->route_table);
}
+ if (route)
+ ospf6_route_unlock (route);
}
if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index c1db3741..588b9462 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -712,6 +712,11 @@ ospf6_lsa_init (void)
ospf6_install_lsa_handler (&unknown_handler);
}
+void
+ospf6_lsa_terminate (void)
+{
+ vector_free (ospf6_lsa_handler_vector);
+}
static char *
ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index fb0f27cd..c1093cab 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -243,6 +243,7 @@ extern void ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler);
extern struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type);
extern void ospf6_lsa_init (void);
+extern void ospf6_lsa_terminate (void);
extern void ospf6_lsa_cmd_init (void);
extern int config_write_ospf6_debug_lsa (struct vty *vty);
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index a7a96a1f..800fae4b 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -124,6 +124,35 @@ Report bugs to zebra@zebra.org\n", progname);
exit (status);
}
+static void
+ospf6_exit (int status)
+{
+ extern struct ospf6 *ospf6;
+ extern struct zclient *zclient;
+
+ if (ospf6)
+ ospf6_delete (ospf6);
+
+ ospf6_message_terminate ();
+ ospf6_asbr_terminate ();
+ ospf6_lsa_terminate ();
+
+ if_terminate ();
+ vty_terminate ();
+ cmd_terminate ();
+
+ if (zclient)
+ zclient_free (zclient);
+
+ if (master)
+ thread_master_free (master);
+
+ if (zlog_default)
+ closezlog (zlog_default);
+
+ exit (status);
+}
+
/* SIGHUP handler. */
static void
sighup (void)
@@ -136,7 +165,7 @@ static void
sigint (void)
{
zlog_notice ("Terminating on signal SIGINT");
- exit (0);
+ ospf6_exit (0);
}
/* SIGTERM handler. */
@@ -144,7 +173,7 @@ static void
sigterm (void)
{
zlog_notice ("Terminating on signal SIGTERM");
- exit (0);
+ ospf6_exit (0);
}
/* SIGUSR1 handler. */
@@ -308,7 +337,7 @@ main (int argc, char *argv[], char *envp[])
zlog_warn ("Thread failed");
/* Not reached. */
- exit (0);
+ ospf6_exit (0);
}
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 790fc0ae..51933b76 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -832,7 +832,7 @@ ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
((caddr_t) oh + sizeof (struct ospf6_header));
/* Interface MTU check */
- if (ntohs (dbdesc->ifmtu) != oi->ifmtu)
+ if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("I/F MTU mismatch");
@@ -1168,6 +1168,24 @@ ospf6_iobuf_size (unsigned int size)
return iobuflen;
}
+void
+ospf6_message_terminate (void)
+{
+ if (recvbuf)
+ {
+ XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
+ recvbuf = NULL;
+ }
+
+ if (sendbuf)
+ {
+ XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
+ sendbuf = NULL;
+ }
+
+ iobuflen = 0;
+}
+
int
ospf6_receive (struct thread *thread)
{
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index ebb6308e..c72f0af4 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -123,6 +123,7 @@ extern void ospf6_lsupdate_print (struct ospf6_header *);
extern void ospf6_lsack_print (struct ospf6_header *);
extern int ospf6_iobuf_size (unsigned int size);
+extern void ospf6_message_terminate (void);
extern int ospf6_receive (struct thread *thread);
extern int ospf6_hello_send (struct thread *thread);
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 1e1f4fb5..398acfa8 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -690,6 +690,8 @@ ospf6_route_best_next (struct ospf6_route *route)
struct route_node *rnode;
struct ospf6_route *next;
+ ospf6_route_unlock (route);
+
rnode = route->rnode;
route_lock_node (rnode);
rnode = route_next (rnode);
@@ -701,7 +703,6 @@ ospf6_route_best_next (struct ospf6_route *route)
assert (rnode->info);
next = (struct ospf6_route *) rnode->info;
- ospf6_route_unlock (route);
ospf6_route_lock (next);
return next;
}
@@ -1335,13 +1336,14 @@ ospf6_brouter_show (struct vty *vty, struct ospf6_route *route)
DEFUN (debug_ospf6_route,
debug_ospf6_route_cmd,
- "debug ospf6 route (table|intra-area|inter-area)",
+ "debug ospf6 route (table|intra-area|inter-area|memory)",
DEBUG_STR
OSPF6_STR
"Debug route table calculation\n"
"Debug detail\n"
"Debug intra-area route calculation\n"
"Debug inter-area route calculation\n"
+ "Debug route memory use\n"
)
{
unsigned char level = 0;
@@ -1352,18 +1354,21 @@ DEFUN (debug_ospf6_route,
level = OSPF6_DEBUG_ROUTE_INTRA;
else if (! strncmp (argv[0], "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
+ else if (! strncmp (argv[0], "memor", 5))
+ level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_ON (level);
return CMD_SUCCESS;
}
DEFUN (no_debug_ospf6_route,
no_debug_ospf6_route_cmd,
- "no debug ospf6 route (table|intra-area|inter-area)",
+ "no debug ospf6 route (table|intra-area|inter-area|memory)",
NO_STR
DEBUG_STR
OSPF6_STR
"Debug route table calculation\n"
- "Debug intra-area route calculation\n")
+ "Debug intra-area route calculation\n"
+ "Debug route memory use\n")
{
unsigned char level = 0;
@@ -1373,6 +1378,8 @@ DEFUN (no_debug_ospf6_route,
level = OSPF6_DEBUG_ROUTE_INTRA;
else if (! strncmp (argv[0], "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
+ else if (! strncmp (argv[0], "memor", 5))
+ level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_OFF (level);
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index bfb6df2e..cb549618 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -50,7 +50,9 @@ ospf6_vertex_cmp (void *a, void *b)
struct ospf6_vertex *vb = (struct ospf6_vertex *) b;
/* ascending order */
- return (va->cost - vb->cost);
+ if (va->cost != vb->cost)
+ return (va->cost - vb->cost);
+ return (va->hops - vb->hops);
}
static int
@@ -320,22 +322,8 @@ ospf6_spf_install (struct ospf6_vertex *v,
}
prev = (struct ospf6_vertex *) route->route_option;
- if (prev->hops > v->hops)
- {
- for (ALL_LIST_ELEMENTS (prev->child_list, node, nnode, w))
- {
- assert (w->parent == prev);
- w->parent = v;
- listnode_add_sort (v->child_list, w);
- }
- listnode_delete (prev->parent->child_list, prev);
- listnode_add_sort (v->parent->child_list, v);
-
- ospf6_vertex_delete (prev);
- route->route_option = v;
- }
- else
- ospf6_vertex_delete (v);
+ assert (prev->hops <= v->hops);
+ ospf6_vertex_delete (v);
return -1;
}
@@ -404,18 +392,19 @@ ospf6_spf_calculation (u_int32_t router_id,
caddr_t lsdesc;
struct ospf6_lsa *lsa;
- /* initialize */
- candidate_list = pqueue_create ();
- candidate_list->cmp = ospf6_vertex_cmp;
-
- ospf6_spf_table_finish (result_table);
-
/* Install the calculating router itself as the root of the SPF tree */
/* construct root vertex */
lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0),
router_id, oa->lsdb);
if (lsa == NULL)
return;
+
+ /* initialize */
+ candidate_list = pqueue_create ();
+ candidate_list->cmp = ospf6_vertex_cmp;
+
+ ospf6_spf_table_finish (result_table);
+
root = ospf6_vertex_create (lsa);
root->area = oa;
root->cost = 0;
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 82370268..2b65be82 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -51,6 +51,8 @@
/* global ospf6d variable */
struct ospf6 *ospf6;
+static void ospf6_disable (struct ospf6 *o);
+
static void
ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
{
@@ -143,15 +145,17 @@ ospf6_create (void)
return o;
}
-#if 0
-static void
+void
ospf6_delete (struct ospf6 *o)
{
struct listnode *node, *nnode;
struct ospf6_area *oa;
+ ospf6_disable (ospf6);
+
for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
ospf6_area_delete (oa);
+ list_delete (o->area_list);
ospf6_lsdb_delete (o->lsdb);
ospf6_lsdb_delete (o->lsdb_self);
@@ -164,7 +168,6 @@ ospf6_delete (struct ospf6 *o)
XFREE (MTYPE_OSPF6_TOP, o);
}
-#endif
static void
ospf6_enable (struct ospf6 *o)
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index ba485f9e..4b2d2c3e 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -69,6 +69,7 @@ extern struct ospf6 *ospf6;
/* prototypes */
extern void ospf6_top_init (void);
+extern void ospf6_delete (struct ospf6 *o);
extern void ospf6_maxage_remove (struct ospf6 *o);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 0a8ac3e4..881771a7 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -132,6 +132,9 @@ ospf6_zebra_if_state_update (int command, struct zclient *zclient,
struct interface *ifp;
ifp = zebra_interface_state_read (zclient->ibuf);
+ if (ifp == NULL)
+ return 0;
+
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
zlog_debug ("Zebra Interface state change: "
"%s index %d flags %llx metric %d mtu %d",