summaryrefslogtreecommitdiffstats
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
authorOndrej Filip <feela@network.cz>2000-03-09 23:38:05 +0100
committerOndrej Filip <feela@network.cz>2000-03-09 23:38:05 +0100
commitce17d4c165cadb09d391e34cda1b796a125ef012 (patch)
tree866eb12926c4b1bceed1688dc80318765a74dc74 /proto/ospf/topology.c
parentaf834f8630eb0078c723fb9b0af053dba6725d5e (diff)
downloadbird-ce17d4c165cadb09d391e34cda1b796a125ef012.tar
bird-ce17d4c165cadb09d391e34cda1b796a125ef012.zip
LSA DB is completely redesigned. Now it should be faster and it needs
less memory.
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r--proto/ospf/topology.c182
1 files changed, 145 insertions, 37 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index ad88f01..ae49228 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -24,12 +24,140 @@
#define HASH_LO_MIN 8
void
+make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
+{
+ struct ospf_iface *ifa;
+ int i=0,j=0,k=0,v=0,e=0,b=0;
+ struct ospf_lsa_rt *rt;
+ struct ospf_lsa_rt_link *ln;
+ struct ospf_neighbor *neigh;
+ struct top_hash_entry *old;
+
+ old=oa->rt;
+
+ WALK_LIST (ifa, p->iface_list) i++;
+ {
+ if((ifa->an==oa->areaid) && (ifa->state!=OSPF_IS_DOWN))
+ {
+ i++;
+ if(ifa->type==OSPF_IT_VLINK) v=1;
+ }
+ }
+ rt=mb_allocz(p->proto.pool, sizeof(struct ospf_lsa_rt)+
+ i*sizeof(struct ospf_lsa_rt_link));
+ if((p->areano>1) && (!oa->stub)) e=1;
+ rt->VEB=(v>>LSA_RT_V)+(e>>LSA_RT_E)+(b>>LSA_RT_B);
+ ln=(struct ospf_lsa_rt_link *)(rt+1);
+
+ WALK_LIST (ifa, p->iface_list)
+ {
+ if((ifa->an==oa->areaid) && (ifa->state!=OSPF_IS_DOWN))
+ {
+ if(ifa->state==OSPF_IS_LOOP)
+ {
+ ln->type=3;
+ ln->id=ipa_to_u32(ifa->iface->addr->ip);
+ ln->data=0xffffffff;
+ ln->metric=0;
+ ln->notos=0;
+ }
+ else
+ {
+ switch(ifa->type)
+ {
+ case OSPF_IT_PTP: /* rfc2328 - pg126 */
+ neigh=(struct ospf_neighbor *)HEAD(ifa->neigh_list);
+ if((neigh!=NULL) || (neigh->state==NEIGHBOR_FULL))
+ {
+ ln->type=LSART_PTP;
+ ln->id=neigh->rid;
+ ln->metric=ifa->cost;
+ ln->notos=0;
+ if(ifa->iface->flags && IA_UNNUMBERED)
+ {
+ ln->data=ifa->iface->index;
+ }
+ else
+ {
+ ln->id=ipa_to_u32(ifa->iface->addr->ip);
+ }
+ }
+ else
+ {
+ if(ifa->state==OSPF_IS_PTP)
+ {
+ ln->type=LSART_STUB;
+ ln->id=ln->id=ipa_to_u32(ifa->iface->addr->opposite);
+ ln->metric=ifa->cost;
+ ln->notos=0;
+ ln->data=0xffffffff;
+ }
+ else
+ {
+ i--; /* No link added */
+ }
+ }
+ break;
+ case OSPF_IT_BCAST: /*FIXME Go on */
+ case OSPF_IT_NBMA:
+ if(ifa->state==OSPF_IS_WAITING)
+ {
+ ln->type=LSART_STUB;
+ ln->id=ipa_to_u32(ifa->iface->addr->prefix);
+ ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
+ ln->metric=ifa->cost;
+ ln->notos=0;
+ }
+ else
+ {
+ j=0,k=0;
+ WALK_LIST(neigh, ifa->neigh_list)
+ {
+ if((neigh->rid==ifa->drid) &&
+ (neigh->state==NEIGHBOR_FULL)) k=1;
+ if(neigh->state==NEIGHBOR_FULL) j=1;
+ }
+ if(((ifa->state=OSPF_IS_DR) && (j==1)) || (k==1))
+ {
+ ln->type=LSART_NET;
+ ln->id=ipa_to_u32(ifa->drip);
+ ln->data=ipa_to_u32(ifa->iface->addr->ip);
+ ln->metric=ifa->cost;
+ ln->notos=0;
+ }
+ else
+ {
+ ln->type=LSART_STUB;
+ ln->id=ipa_to_u32(ifa->iface->addr->prefix);
+ ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
+ ln->metric=ifa->cost;
+ ln->notos=0;
+ }
+ }
+ break;
+ case OSPF_IT_VLINK: /* FIXME Add virtual links! */
+ i--;
+ break;
+ }
+ }
+ if(ifa->type==OSPF_IT_VLINK) v=1;
+ }
+ ln=(ln+1);
+ }
+ rt->links=i;
+ if(old->lsa_body!=NULL) mb_free(old->lsa_body);
+ old->lsa_body=rt;
+}
+
+
+
+void
addifa_rtlsa(struct ospf_iface *ifa)
{
struct ospf_area *oa;
struct proto_ospf *po;
u32 rtid;
- struct top_graph_rtlsa *rt;
+ struct top_hash_entry *rt;
struct top_graph_rtlsa_link *li, *lih;
po=ifa->proto;
@@ -53,37 +181,17 @@ addifa_rtlsa(struct ospf_iface *ifa)
oa->areaid=ifa->an;
oa->gr=ospf_top_new(po);
s_init_list(&(oa->lsal));
- oa->rtlinks=sl_new(po->proto.pool,
- sizeof(struct top_graph_rtlsa_link));
oa->rt=ospf_hash_get(oa->gr, rtid, rtid, LSA_T_RT);
s_add_head(&(oa->lsal), (snode *)oa->rt);
- rt=mb_alloc(po->proto.pool, sizeof(struct top_graph_rtlsa));
- oa->rt->vertex=(void *)rt;
- oa->rt->lsage=0;
- oa->rt->lsseqno=LSA_INITSEQNO; /* FIXME Check it latter */
- rt->Vbit=0;
- rt->Ebit= (po->areano++ ? 0 : 1); /* If it's 1st area set 0 */
- rt->Bbit=0; /* FIXME Could read config */
+ oa->rt->lsa_body=NULL;
+ oa->rt->lsa.age=0;
+ oa->rt->lsa.sn=LSA_INITSEQNO-1; /* FIXME Check it latter */
DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an);
- if(po->areano==2) /* We are attached to more than 2 areas! */
- {
- oa=po->firstarea;
-
- while(oa!=NULL)
- {
- rt=(struct top_graph_rtlsa *)oa->rt->vertex;
- rt->Ebit=1;
- /*FIXME lsa_flood(oa->rt) */
-
- oa=oa->next;
- }
- }
- else
- {
- /*FIXME lsa_flood(oa->rt) */;
- }
}
+ make_rt_lsa(oa, po);
+ /*FIXME seq no++ */
+ /*FIXME lsa_flood(oa->rt) */
}
@@ -170,7 +278,7 @@ ospf_top_rehash(struct top_graph *f, int step)
while (e)
{
x = e->next;
- n = newt + ospf_top_hash(f, e->lsa_id, e->rtr_id, e->lsa_type);
+ n = newt + ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type);
e->next = *n;
*n = e;
e = x;
@@ -184,7 +292,7 @@ ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
{
struct top_hash_entry *e = f->hash_table[ospf_top_hash(f, lsa, rtr, type)];
- while (e && (e->lsa_id != lsa || e->rtr_id != rtr || e->lsa_type != type))
+ while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type))
e = e->next;
return e;
}
@@ -195,15 +303,15 @@ ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
struct top_hash_entry **ee = f->hash_table + ospf_top_hash(f, lsa, rtr, type);
struct top_hash_entry *e = *ee;
- while (e && (e->lsa_id != lsa || e->rtr_id != rtr || e->lsa_type != type))
+ while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type))
e = e->next;
if (e)
return e;
e = sl_alloc(f->hash_slab);
- e->lsa_id = lsa;
- e->rtr_id = rtr;
- e->lsa_type = type;
- e->vertex = NULL;
+ e->lsa.id = lsa;
+ e->lsa.rt = rtr;
+ e->lsa.type = type;
+ e->lsa_body = NULL;
e->next=*ee; /* MJ you forgot this :-) */
*ee=e;
if (f->hash_entries++ > f->hash_entries_max)
@@ -214,7 +322,7 @@ ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
void
ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e)
{
- unsigned int h = ospf_top_hash(f, e->lsa_id, e->rtr_id, e->lsa_type);
+ unsigned int h = ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type);
struct top_hash_entry **ee = f->hash_table + h;
while (*ee)
@@ -243,8 +351,8 @@ ospf_top_dump(struct top_graph *f)
struct top_hash_entry *e = f->hash_table[i];
while (e)
{
- debug("\t%04x %08x %08x %p\n", e->lsa_type, e->lsa_id,
- e->rtr_id, e->vertex);
+ debug("\t%04x %08x %08x %p\n", e->lsa.type, e->lsa.id,
+ e->lsa.rt, e->lsa_body);
e = e->next;
}
}