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.c101
1 files changed, 91 insertions, 10 deletions
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 4a33d476..865a1167 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -42,8 +42,10 @@
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
+#include "ospf6_flood.h"
#include "ospf6_asbr.h"
#include "ospf6_abr.h"
+#include "ospf6_intra.h"
#include "ospf6d.h"
/* global ospf6d variable */
@@ -84,17 +86,31 @@ ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
void
ospf6_top_route_hook_add (struct ospf6_route *route)
{
- ospf6_abr_originate_prefix (route, ospf6);
+ ospf6_abr_originate_summary (route);
ospf6_zebra_route_update_add (route);
}
void
ospf6_top_route_hook_remove (struct ospf6_route *route)
{
- ospf6_abr_originate_prefix (route, ospf6);
+ ospf6_abr_originate_summary (route);
ospf6_zebra_route_update_remove (route);
}
+void
+ospf6_top_brouter_hook_add (struct ospf6_route *route)
+{
+ ospf6_abr_originate_summary (route);
+ ospf6_asbr_lsentry_add (route);
+}
+
+void
+ospf6_top_brouter_hook_remove (struct ospf6_route *route)
+{
+ ospf6_abr_originate_summary (route);
+ ospf6_asbr_lsentry_remove (route);
+}
+
struct ospf6 *
ospf6_create ()
{
@@ -107,7 +123,8 @@ ospf6_create ()
gettimeofday (&o->starttime, (struct timezone *) NULL);
o->area_list = list_new ();
o->area_list->cmp = ospf6_area_cmp;
- o->lsdb = ospf6_lsdb_create ();
+ o->lsdb = ospf6_lsdb_create (o);
+ o->lsdb_self = ospf6_lsdb_create (o);
o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
@@ -115,11 +132,9 @@ ospf6_create ()
o->route_table->hook_add = ospf6_top_route_hook_add;
o->route_table->hook_remove = ospf6_top_route_hook_remove;
- o->asbr_table = ospf6_route_table_create ();
- o->asbr_table->hook_add = ospf6_asbr_lsentry_add;
- o->asbr_table->hook_remove = ospf6_asbr_lsentry_remove;
-
o->brouter_table = ospf6_route_table_create ();
+ o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
+ o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
o->external_table = ospf6_route_table_create ();
o->external_id_table = route_table_init ();
@@ -140,9 +155,9 @@ 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->asbr_table);
ospf6_route_table_delete (o->brouter_table);
ospf6_route_table_delete (o->external_table);
@@ -185,7 +200,7 @@ ospf6_disable (struct ospf6 *o)
ospf6_lsdb_remove_all (o->lsdb);
ospf6_route_remove_all (o->route_table);
- ospf6_route_remove_all (o->asbr_table);
+ ospf6_route_remove_all (o->brouter_table);
}
}
@@ -320,10 +335,12 @@ DEFUN (ospf6_interface_area,
)
{
struct ospf6 *o;
- struct ospf6_area *oa;
+ struct ospf6_area *oa, *area;
struct ospf6_interface *oi;
struct interface *ifp;
u_int32_t area_id;
+ listnode node;
+ struct ospf6_route *ro;
o = (struct ospf6 *) vty->index;
@@ -355,8 +372,31 @@ DEFUN (ospf6_interface_area,
listnode_add (oa->if_list, oi); /* sort ?? */
oi->area = oa;
+ SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
+
/* start up */
thread_add_event (master, interface_up, oi, 0);
+
+ /* ABR stuff, redistribute inter-area LSAs and
+ re-originate Router-LSA (B-bit may have been changed) */
+ for (node = listhead (o->area_list); node; nextnode (node))
+ {
+ area = OSPF6_AREA (getdata (node));
+ OSPF6_ROUTER_LSA_SCHEDULE (area);
+
+ for (ro = ospf6_route_head (area->range_table); ro;
+ ro = ospf6_route_next (ro))
+ ospf6_abr_originate_summary_to_area (ro, oa);
+ }
+
+ for (ro = ospf6_route_head (o->brouter_table); ro;
+ ro = ospf6_route_next (ro))
+ ospf6_abr_originate_summary_to_area (ro, oa);
+
+ for (ro = ospf6_route_head (o->route_table); ro;
+ ro = ospf6_route_next (ro))
+ ospf6_abr_originate_summary_to_area (ro, oa);
+
return CMD_SUCCESS;
}
@@ -372,8 +412,12 @@ DEFUN (no_ospf6_interface_area,
{
struct ospf6 *o;
struct ospf6_interface *oi;
+ struct ospf6_area *oa, *area;
struct interface *ifp;
u_int32_t area_id;
+ listnode node;
+ struct ospf6_route *ro;
+ struct ospf6_lsa *old;
o = (struct ospf6 *) vty->index;
@@ -407,9 +451,45 @@ DEFUN (no_ospf6_interface_area,
thread_execute (master, interface_down, oi, 0);
+ oa = oi->area;
listnode_delete (oi->area->if_list, oi);
oi->area = (struct ospf6_area *) NULL;
+ /* Withdraw inter-area routes from this area, if necessary */
+ if (oa->if_list->count == 0)
+ {
+ UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
+
+ for (ro = ospf6_route_head (oa->summary_prefix); ro;
+ ro = ospf6_route_next (ro))
+ {
+ old = ospf6_lsdb_lookup (ro->path.origin.type,
+ ro->path.origin.id,
+ oa->ospf6->router_id, oa->lsdb);
+ if (old)
+ ospf6_lsa_purge (old);
+ ospf6_route_remove (ro, oa->summary_prefix);
+ }
+ for (ro = ospf6_route_head (oa->summary_router); ro;
+ ro = ospf6_route_next (ro))
+ {
+ old = ospf6_lsdb_lookup (ro->path.origin.type,
+ ro->path.origin.id,
+ oa->ospf6->router_id, oa->lsdb);
+ if (old)
+ ospf6_lsa_purge (old);
+ ospf6_route_remove (ro, oa->summary_router);
+ }
+ }
+
+ /* Schedule Refreshment of Router-LSA for each area
+ (ABR status may change) */
+ for (node = listhead (o->area_list); node; nextnode (node))
+ {
+ area = OSPF6_AREA (getdata (node));
+ OSPF6_ROUTER_LSA_SCHEDULE (area);
+ }
+
return CMD_SUCCESS;
}
@@ -562,6 +642,7 @@ config_write_ospf6 (struct vty *vty)
vty_out (vty, " router-id %s%s", router_id, VNL);
ospf6_redistribute_config_write (vty);
+ ospf6_area_config_write (vty);
for (j = listhead (ospf6->area_list); j; nextnode (j))
{