1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Temporary OSPFv3 development commit

This commit is contained in:
Ondrej Zajicek
2009-08-25 16:42:14 +02:00
parent c3226991a0
commit b49e6f5a65
23 changed files with 449 additions and 214 deletions

View File

@@ -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);
}
struct top_hash_entry *
ospfxx_hash_find_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
u32
ospf_lsa_domain(u32 type, struct ospf_iface *ifa)
{
return ospfxx_hash_find(f, domain, h->id, h->rt, h->type);
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_get_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_get(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_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
ospf_hash_get_header(struct top_graph *f, u32 domain, struct ospf_lsa_header *h)
{
return ospf_hash_get(f, domain, h->id, h->rt, h->type);
}
struct top_hash_entry *
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: