summaryrefslogtreecommitdiffstats
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-08-25 16:42:14 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2009-08-25 16:42:14 +0200
commitb49e6f5a65d437cb7e7bdefe8397e0f550496012 (patch)
tree21e0f77023119de17ea8ab6ab7871b1026db92e6 /proto/ospf/topology.c
parentc3226991a061415fa83b757cbff678111c586e58 (diff)
downloadbird-b49e6f5a65d437cb7e7bdefe8397e0f550496012.tar
bird-b49e6f5a65d437cb7e7bdefe8397e0f550496012.zip
Temporary OSPFv3 development commit
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r--proto/ospf/topology.c222
1 files changed, 144 insertions, 78 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 21627f0..360e362 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -20,6 +20,23 @@
#define HASH_LO_STEP 2
#define HASH_LO_MIN 8
+void originate_prefix_rt_lsa(struct ospf_area *oa);
+void originate_prefix_net_lsa(struct ospf_iface *ifa);
+
+#ifdef OSPFv2
+#define ipa_to_rid(x) _I(x)
+#else /* OSPFv3 */
+#define ipa_to_rid(x) _I3(x)
+#endif
+
+/* FIXME very ugly hack */
+#ifdef OSPFv2
+#define ipa_to_lsaid(x) _I(x)
+#else /* OSPFv3 */
+#define ipa_to_lsaid(x) _I0(x) ^ _I1(x) ^ _I2(x) ^ _I3(x)
+#endif
+
+
static void *
lsab_alloc(struct proto_ospf *po, unsigned size)
{
@@ -300,7 +317,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
{
struct proto_ospf *po = oa->po;
struct ospf_iface *ifa;
- int i = 0, j = 0, k = 0, bitv = 0;
+ int bitv = 0;
struct ospf_lsa_rt *rt;
struct ospf_neighbor *neigh;
@@ -390,18 +407,9 @@ originate_rt_lsa(struct ospf_area *oa)
struct ospf_lsa_header lsa;
struct proto_ospf *po = oa->po;
struct proto *p = &po->proto;
- u32 rtid = po->proto.cf->global->router_id;
- struct top_hash_entry *en;
+ u32 rid = po->proto.cf->global->router_id;
void *body;
- if ((oa->rt) && ((oa->rt->inst_t + MINLSINTERVAL)) > now)
- return;
- /*
- * Tick is probably set to very low value. We cannot
- * originate new LSA before MINLSINTERVAL. We will
- * try to do it next tick.
- */
-
OSPF_TRACE(D_EVENTS, "Originating RT_lsa for area %R.", oa->areaid);
lsa.age = 0;
@@ -411,16 +419,33 @@ originate_rt_lsa(struct ospf_area *oa)
lsa.options = oa->options;
#endif
- lsa.id = rtid;
- lsa.rt = rtid;
+ lsa.id = rid;
+ lsa.rt = rid;
lsa.sn = oa->rt ? (oa->rt->lsa.sn + 1) : LSA_INITSEQNO;
u32 dom = oa->areaid;
body = originate_rt_lsa_body(oa, &lsa.length);
lsasum_calculate(&lsa, body);
- en = lsa_install_new(po, &lsa, dom, body);
- oa->rt = en;
- ospf_lsupd_flood(po, NULL, NULL, &oa->rt->lsa, dom, 1);
+ oa->rt = lsa_install_new(po, &lsa, dom, body);
+ ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
+}
+
+void
+update_rt_lsa(struct ospf_area *oa)
+{
+ struct proto_ospf *po = oa->po;
+
+ if ((oa->rt) && ((oa->rt->inst_t + MINLSINTERVAL)) > now)
+ return;
+ /*
+ * Tick is probably set to very low value. We cannot
+ * originate new LSA before MINLSINTERVAL. We will
+ * try to do it next tick.
+ */
+
+ originate_rt_lsa(oa);
+ originate_prefix_rt_lsa(oa);
+
schedule_rtcalc(po);
oa->origrt = 0;
}
@@ -454,7 +479,7 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length,
if (n->state == NEIGHBOR_FULL)
{
#ifdef OSPFv3
- en = ospfxx_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK);
+ en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK);
if (en)
options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
#endif
@@ -474,6 +499,7 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length,
return net;
}
+
/**
* originate_net_lsa - originates of deletes network LSA
* @ifa: interface which is LSA originated for
@@ -488,39 +514,11 @@ originate_net_lsa(struct ospf_iface *ifa)
{
struct proto_ospf *po = ifa->oa->po;
struct ospf_lsa_header lsa;
- u32 rtid = po->proto.cf->global->router_id;
+ u32 rid = po->proto.cf->global->router_id;
u32 dom = ifa->oa->areaid;
struct proto *p = &po->proto;
void *body;
- if (ifa->net_lsa && ((ifa->net_lsa->inst_t + MINLSINTERVAL) > now))
- return;
- /*
- * It's too early to originate new network LSA. We will
- * try to do it next tick
- */
-
- if ((ifa->state != OSPF_IS_DR) || (ifa->fadj == 0))
- {
- if (ifa->net_lsa == NULL)
- return;
-
- OSPF_TRACE(D_EVENTS, "Deleting Net lsa for iface \"%s\".",
- ifa->iface->name);
- ifa->net_lsa->lsa.sn += 1;
- ifa->net_lsa->lsa.age = LSA_MAXAGE;
- lsasum_calculate(&ifa->net_lsa->lsa, ifa->net_lsa->lsa_body);
- ospf_lsupd_flood(po, NULL, NULL, &ifa->net_lsa->lsa, dom, 0);
- s_rem_node(SNODE ifa->net_lsa);
- if (ifa->net_lsa->lsa_body != NULL)
- mb_free(ifa->net_lsa->lsa_body);
- ifa->net_lsa->lsa_body = NULL;
- ospf_hash_delete(po->gr, ifa->net_lsa);
- schedule_rtcalc(po);
- ifa->net_lsa = NULL;
- return;
- }
-
OSPF_TRACE(D_EVENTS, "Originating Net lsa for iface \"%s\".",
ifa->iface->name);
@@ -534,16 +532,63 @@ originate_net_lsa(struct ospf_iface *ifa)
lsa.id = ifa->iface->index;
#endif
- lsa.rt = rtid;
+ lsa.rt = rid;
lsa.sn = ifa->net_lsa ? (ifa->net_lsa->lsa.sn + 1) : LSA_INITSEQNO;
body = originate_net_lsa_body(ifa, &lsa.length, po);
lsasum_calculate(&lsa, body);
ifa->net_lsa = lsa_install_new(po, &lsa, dom, body);
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
- ifa->orignet = 0;
}
+void
+flush_net_lsa(struct ospf_iface *ifa)
+{
+ struct proto_ospf *po = ifa->oa->po;
+ struct proto *p = &po->proto;
+ u32 dom = ifa->oa->areaid;
+
+ if (ifa->net_lsa == NULL)
+ return;
+
+ OSPF_TRACE(D_EVENTS, "Deleting Net lsa for iface \"%s\".",
+ ifa->iface->name);
+ ifa->net_lsa->lsa.sn += 1;
+ ifa->net_lsa->lsa.age = LSA_MAXAGE;
+ lsasum_calculate(&ifa->net_lsa->lsa, ifa->net_lsa->lsa_body);
+ ospf_lsupd_flood(po, NULL, NULL, &ifa->net_lsa->lsa, dom, 0);
+
+
+ flush_lsa(ifa->net_lsa, po);
+ ifa->net_lsa = NULL;
+}
+
+void
+update_net_lsa(struct ospf_iface *ifa)
+{
+ struct proto_ospf *po = ifa->oa->po;
+
+ if (ifa->net_lsa && ((ifa->net_lsa->inst_t + MINLSINTERVAL) > now))
+ return;
+ /*
+ * It's too early to originate new network LSA. We will
+ * try to do it next tick
+ */
+
+ if ((ifa->state != OSPF_IS_DR) || (ifa->fadj == 0))
+ {
+ flush_net_lsa(ifa);
+ flush_prefix_net_lsa(ifa);
+ }
+ else
+ {
+ originate_net_lsa(ifa);
+ originate_prefix_net_lsa(ifa);
+ }
+
+ schedule_rtcalc(po);
+ ifa->orignet = 0;
+}
#ifdef OSPFv2
@@ -630,7 +675,7 @@ originate_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type, int metri
u32 dom = oa->areaid;
/* FIXME check for the same LSA */
- if ((en = ospfxx_hash_find_header(po->gr, oa->areaid, &lsa)) != NULL)
+ if ((en = ospf_hash_find_header(po->gr, oa->areaid, &lsa)) != NULL)
lsa.sn = en->lsa.sn + 1;
if (type == ORT_NET)
@@ -677,7 +722,7 @@ flush_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type)
lsa.type = LSA_T_SUM_RT;
}
- if ((en = ospfxx_hash_find_header(po->gr, oa->areaid, &lsa)) != NULL)
+ if ((en = ospf_hash_find_header(po->gr, oa->areaid, &lsa)) != NULL)
{
struct ospf_lsa_sum *sum = en->lsa_body;
en->lsa.age = LSA_MAXAGE;
@@ -733,10 +778,12 @@ check_sum_lsa(struct proto_ospf *po, ort *nf, int dest)
mlen = nf->fn.pxlen;
ip = ipa_and(nf->fn.prefix, ipa_mkmask(mlen));
- if ((oa == po->backbone) && (nf->n.type == RTS_OSPF_IA)) flush = 1; /* Only intra-area can go to the backbone */
+ if ((oa == po->backbone) && (nf->n.type == RTS_OSPF_IA))
+ flush = 1; /* Only intra-area can go to the backbone */
- if ((!flush) && (dest == ORT_NET) && fib_route(&nf->n.oa->net_fib, ip, mlen)) /* The route fits into area networks */
+ if ((!flush) && (dest == ORT_NET) && fib_route(&nf->n.oa->net_fib, ip, mlen))
{
+ /* The route fits into area networks */
flush = 1;
if ((nf->n.oa == po->backbone) && (oa->trcap)) flush = 0;
}
@@ -833,8 +880,6 @@ originate_ext_lsa(net * n, rte * e, struct proto_ospf *po,
void *body;
struct proto *p = &po->proto;
struct ospf_area *oa;
- struct ospf_lsa_ext *ext1, *ext2;
- int i, max;
OSPF_TRACE(D_EVENTS, "Originating Ext lsa for %I/%d.", n->n.prefix,
n->n.pxlen);
@@ -850,7 +895,7 @@ originate_ext_lsa(net * n, rte * e, struct proto_ospf *po,
/* FIXME proper handling of LSA IDs and check for the same network */
lsa.id = ipa_to_lsaid(n->n.prefix);
- if ((en = ospfxx_hash_find_header(po->gr, 0, &lsa)) != NULL)
+ if ((en = ospf_hash_find_header(po->gr, 0, &lsa)) != NULL)
{
lsa.sn = en->lsa.sn + 1;
}
@@ -877,13 +922,11 @@ flush_ext_lsa(net *n, struct proto_ospf *po)
u32 rid = po->proto.cf->global->router_id;
struct ospf_area *oa;
struct top_hash_entry *en;
- struct ospf_lsa_ext *ext;
- int i;
/* FIXME proper handling of LSA IDs and check for the same network */
u32 lsaid = ipa_to_lsaid(n->n.prefix);
- if (en = ospfxx_hash_find(po->gr, 0, lsaid, rid, LSA_T_EXT))
+ if (en = ospf_hash_find(po->gr, 0, lsaid, rid, LSA_T_EXT))
{
/* FIXME this is nonsense */
WALK_LIST(oa, po->area_list)
@@ -907,7 +950,7 @@ originate_link_lsa_body(struct ospf_iface *ifa, u16 *length)
ASSERT(po->lsab_used == 0);
ll = lsab_allocz(po, sizeof(struct ospf_lsa_link));
ll->options = ifa->oa->options | (ifa->priority << 24);
- ll->lladdr = FIX;
+ ll->lladdr = ifa->lladdr;
ll = NULL; /* buffer might be reallocated later */
struct ifa *a;
@@ -935,23 +978,16 @@ originate_link_lsa(struct ospf_iface *ifa)
struct ospf_lsa_header lsa;
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
- u32 rtid = po->proto.cf->global->router_id;
+ u32 rid = po->proto.cf->global->router_id;
void *body;
- if (ifa->link_lsa && ((ifa->link_lsa->inst_t + MINLSINTERVAL) > now))
- return;
- /*
- * It's too early to originate new link LSA. We will
- * try to do it next tick
- */
-
/* FIXME check for vlink and skip that? */
OSPF_TRACE(D_EVENTS, "Originating Link_lsa for iface %s.", ifa->iface->name);
lsa.age = 0;
lsa.type = LSA_T_LINK;
lsa.id = ifa->iface->index;
- lsa.rt = rtid;
+ lsa.rt = rid;
lsa.sn = ifa->link_lsa ? (ifa->link_lsa->lsa.sn + 1) : LSA_INITSEQNO;
u32 dom = ifa->iface->index;
@@ -959,9 +995,20 @@ originate_link_lsa(struct ospf_iface *ifa)
lsasum_calculate(&lsa, body);
ifa->link_lsa = lsa_install_new(po, &lsa, dom, body);
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
- ifa->origlink = 0;
}
+void
+update_link_lsa(struct ospf_iface *ifa)
+{
+ if (ifa->link_lsa && ((ifa->link_lsa->inst_t + MINLSINTERVAL) > now))
+ return;
+ /*
+ * It's too early to originate new link LSA. We will
+ * try to do it next tick
+ */
+ originate_link_lsa(ifa);
+ ifa->origlink = 0;
+}
static void *
originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
@@ -1129,7 +1176,7 @@ originate_prefix_net_lsa_body(struct ospf_iface *ifa, u16 *length)
/* Find all Link LSA associated with the link and merge their prefixes */
WALK_LIST(n, ifa->neigh_list)
if ((n->state == NEIGHBOR_FULL) &&
- (en = ospfxx_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK)))
+ (en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK)))
{
ll = en->lsa_body;
pxb = ll->rest;
@@ -1170,6 +1217,7 @@ originate_prefix_net_lsa(struct ospf_iface *ifa)
#endif
+
static void
ospf_top_ht_alloc(struct top_graph *f)
{
@@ -1263,7 +1311,7 @@ ospf_top_rehash(struct top_graph *f, int step)
oldn = f->hash_size;
oldt = f->hash_table;
- dbg("re-hashing topology hash from order %d to %d\n", f->hash_order,
+ DBG("re-hashing topology hash from order %d to %d\n", f->hash_order,
f->hash_order + step);
f->hash_order += step;
ospf_top_ht_alloc(f);
@@ -1284,20 +1332,37 @@ ospf_top_rehash(struct top_graph *f, int step)
ospf_top_ht_free(oldt);
}
+u32
+ospf_lsa_domain(u32 type, struct ospf_iface *ifa)
+{
+ switch (type & LSA_SCOPE_MASK)
+ {
+ case LSA_SCOPE_LINK:
+ return ifa->iface->index;
+
+ case LSA_SCOPE_AREA:
+ return ifa->oa->areaid;
+
+ case LSA_SCOPE_AS:
+ default:
+ return 0;
+ }
+}
+
struct top_hash_entry *
-ospfxx_hash_find_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
+ospf_hash_find_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
{
- return ospfxx_hash_find(f, domain, h->id, h->rt, h->type);
+ return ospf_hash_find(f, domain, h->id, h->rt, h->type);
}
struct top_hash_entry *
-ospfxx_hash_get_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
+ospf_hash_get_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
{
- return ospfxx_hash_get(f, domain, h->id, h->rt, h->type);
+ return ospf_hash_get(f, domain, h->id, h->rt, h->type);
}
struct top_hash_entry *
-ospfxx_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
+ospf_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
{
struct top_hash_entry *e;
@@ -1322,7 +1387,7 @@ ospfxx_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
}
struct top_hash_entry *
-ospfxx_hash_get(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
+ospf_hash_get(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
{
struct top_hash_entry **ee;
struct top_hash_entry *e;
@@ -1379,6 +1444,7 @@ ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e)
static void
ospf_dump_lsa(struct top_hash_entry *he, struct proto *p)
{
+ /*
struct ospf_lsa_rt *rt = NULL;
struct ospf_lsa_rt_link *rr = NULL;
struct ospf_lsa_net *ln = NULL;
@@ -1389,7 +1455,7 @@ ospf_dump_lsa(struct top_hash_entry *he, struct proto *p)
he->lsa.type, he->lsa.id, he->lsa.rt, he->lsa.age, he->lsa.sn,
he->lsa.checksum, he->domain);
- /*
+
switch (he->lsa.type)
{
case LSA_T_RT: