summaryrefslogtreecommitdiff
path: root/proto/ospf/ospf.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf/ospf.c')
-rw-r--r--proto/ospf/ospf.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 0cab1d7b..c9b5f430 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -76,6 +76,9 @@
#include <stdlib.h>
#include "ospf.h"
+
+static void ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED, ea_list * attrs);
+static void ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a);
static int ospf_rte_better(struct rte *new, struct rte *old);
static int ospf_rte_same(struct rte *new, struct rte *old);
static void ospf_disp(timer *timer);
@@ -124,6 +127,9 @@ ospf_start(struct proto *p)
po->disp_timer->hook = ospf_disp;
po->disp_timer->recurrent = po->tick;
tm_start(po->disp_timer, 1);
+ po->lsab_size = 256;
+ po->lsab_used = 0;
+ po->lsab = mb_alloc(p->pool, po->lsab_size);
init_list(&(po->iface_list));
init_list(&(po->area_list));
fib_init(&po->rtf, p->pool, sizeof(ort), 16, ospf_rt_initort);
@@ -142,6 +148,7 @@ ospf_start(struct proto *p)
oa = mb_allocz(p->pool, sizeof(struct ospf_area));
add_tail(&po->area_list, NODE oa);
po->areano++;
+ oa->ac = ac;
oa->stub = ac->stub;
oa->areaid = ac->areaid;
oa->rt = NULL;
@@ -224,8 +231,10 @@ ospf_init(struct proto_config *c)
p->import_control = ospf_import_control;
p->make_tmp_attrs = ospf_make_tmp_attrs;
p->store_tmp_attrs = ospf_store_tmp_attrs;
+ p->accept_ra_types = RA_OPTIMAL;
p->rt_notify = ospf_rt_notify;
p->if_notify = ospf_iface_notify;
+ p->ifa_notify = ospf_ifa_notify;
p->rte_better = ospf_rte_better;
p->rte_same = ospf_rte_same;
@@ -428,7 +437,7 @@ ospf_shutdown(struct proto *p)
return PS_DOWN;
}
-void
+static void
ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
ea_list * attrs)
{
@@ -473,6 +482,25 @@ ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
}
static void
+ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a)
+{
+ struct proto_ospf *po = (struct proto_ospf *) p;
+ struct ospf_iface *ifa;
+
+ if ((a->flags & IA_SECONDARY) || (a->flags & IA_UNNUMBERED))
+ return;
+
+ WALK_LIST(ifa, po->iface_list)
+ {
+ if (ifa->iface == a->iface)
+ {
+ schedule_rt_lsa(ifa->oa);
+ return;
+ }
+ }
+}
+
+static void
ospf_get_status(struct proto *p, byte * buf)
{
struct proto_ospf *po = (struct proto_ospf *) p;
@@ -602,9 +630,31 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
if (!oa)
return 0;
+ oa->ac = newac;
oa->stub = newac->stub;
if (newac->stub && (oa->areaid == 0)) oa->stub = 0;
+ /* Check stubnet_list */
+ struct ospf_stubnet_config *oldsn = HEAD(oldac->stubnet_list);
+ struct ospf_stubnet_config *newsn = HEAD(newac->stubnet_list);
+
+ while (((NODE(oldsn))->next != NULL) && ((NODE(newsn))->next != NULL))
+ {
+ if (!ipa_equal(oldsn->px.addr, newsn->px.addr) ||
+ (oldsn->px.len != newsn->px.len) ||
+ (oldsn->hidden != newsn->hidden) ||
+ (oldsn->summary != newsn->summary) ||
+ (oldsn->cost != newsn->cost))
+ break;
+
+ oldsn = (struct ospf_stubnet_config *)(NODE(oldsn))->next;
+ newsn = (struct ospf_stubnet_config *)(NODE(newsn))->next;
+ }
+
+ /* If there is no change, both pointers should be NULL */
+ if (((NODE(oldsn))->next) != ((NODE(newsn))->next))
+ schedule_rt_lsa(oa);
+
/* Change net_list */
FIB_WALK(&oa->net_fib, nf) /* First check if some networks are deleted */
{