LSA flooding done.
This commit is contained in:
parent
10000b96a8
commit
2c971094eb
2 changed files with 140 additions and 24 deletions
|
@ -14,6 +14,116 @@ ospf_lsupd_tx(struct ospf_neighbor *n)
|
|||
/* FIXME Go on! */
|
||||
}
|
||||
|
||||
void
|
||||
flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
|
||||
struct ospf_lsa_header *hh, struct proto_ospf *po, struct ospf_iface *iff)
|
||||
{
|
||||
struct ospf_iface *ifa;
|
||||
struct ospf_neighbor *nn;
|
||||
struct top_hash_entry *en;
|
||||
int ret;
|
||||
|
||||
/* pg 148 */
|
||||
WALK_LIST(NODE ifa,po->iface_list)
|
||||
{
|
||||
if(hh->type==LSA_T_EXT)
|
||||
{
|
||||
if(ifa->type==OSPF_IT_VLINK) continue;
|
||||
if(ifa->oa->stub) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(iff->oa->areaid==BACKBONE)
|
||||
{
|
||||
if((ifa->type!=OSPF_IT_VLINK)&&(ifa->oa!=iff->oa)) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ifa->oa!=iff->oa) continue;
|
||||
}
|
||||
}
|
||||
ret=0;
|
||||
WALK_LIST(NODE nn, ifa->neigh_list)
|
||||
{
|
||||
if(nn->state<NEIGHBOR_EXCHANGE) continue;
|
||||
if(nn->state<NEIGHBOR_FULL)
|
||||
{
|
||||
|
||||
if((en=ospf_hash_find_header(nn->lsrqh,hh))!=NULL)
|
||||
{
|
||||
switch(lsa_comp(hh,&en->lsa))
|
||||
{
|
||||
case CMP_OLDER:
|
||||
continue;
|
||||
break;
|
||||
case CMP_SAME:
|
||||
s_rem_node(SNODE en);
|
||||
DBG("Removing from lsreq list for neigh %u\n", nn->rid);
|
||||
ospf_hash_delete(nn->lsrqh,en);
|
||||
if(EMPTY_SLIST(nn->lsrql)) ospf_neigh_sm(nn, INM_LOADDONE);
|
||||
continue;
|
||||
break;
|
||||
case CMP_NEWER:
|
||||
s_rem_node(SNODE en);
|
||||
DBG("Removing from lsreq list for neigh %u\n", nn->rid);
|
||||
ospf_hash_delete(nn->lsrqh,en);
|
||||
if(EMPTY_SLIST(nn->lsrql)) ospf_neigh_sm(nn, INM_LOADDONE);
|
||||
break;
|
||||
default: bug("Bug in lsa_comp?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nn==n) continue;
|
||||
en=ospf_hash_get_header(nn->lsrth, hh);
|
||||
s_add_tail(&nn->lsrtl, SNODE en);
|
||||
ret=1;
|
||||
}
|
||||
if(ret==0) continue;
|
||||
if(ifa==iff)
|
||||
{
|
||||
if((n->rid==iff->drid)||n->rid==iff->bdrid) continue;
|
||||
if(iff->state=OSPF_IS_BACKUP) continue;
|
||||
}
|
||||
/* FIXME directly flood */
|
||||
{
|
||||
sock *sk;
|
||||
ip_addr to;
|
||||
u16 len;
|
||||
struct ospf_lsupd_packet *pk;
|
||||
struct ospf_packet *op;
|
||||
|
||||
if(ifa->type==OSPF_IT_NBMA) sk=iff->ip_sk;
|
||||
else sk=iff->hello_sk; /* FIXME is this tru for PTP? */
|
||||
|
||||
pk=(struct ospf_lsupd_packet *)sk->tbuf;
|
||||
op=(struct ospf_packet *)sk->tbuf;
|
||||
|
||||
fill_ospf_pkt_hdr(ifa, pk, LSUPD);
|
||||
pk->lsano=htonl(1);
|
||||
memcpy(pk+1,hn,ntohs(hn->length));
|
||||
len=sizeof(struct ospf_lsupd_packet)+ntohs(hn->length);
|
||||
op->length=htons(len);
|
||||
ospf_pkt_finalize(ifa, op);
|
||||
|
||||
if(ifa->type==OSPF_IT_NBMA)
|
||||
{
|
||||
struct ospf_neighbor *nnn;
|
||||
WALK_LIST(NODE nnn,ifa->neigh_list)
|
||||
{
|
||||
if(nnn->state>NEIGHBOR_EXSTART)
|
||||
sk_send_to(sk,len, nnn->ip, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((ifa->state==OSPF_IS_BACKUP)||(ifa->state==OSPF_IS_DR))
|
||||
sk_send_to(sk,len, AllSPFRouters, OSPF_PROTO);
|
||||
else sk_send_to(sk,len, AllDRouters, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void /* I send all I received in LSREQ */
|
||||
ospf_lsupd_tx_list(struct ospf_neighbor *n, list *l)
|
||||
{
|
||||
|
@ -116,16 +226,19 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
{
|
||||
struct ospf_lsa_header lsatmp;
|
||||
struct top_hash_entry *lsadb;
|
||||
/* pg 143 (1) */
|
||||
if(lsa->checksum!=lsasum_check(lsa,NULL,po))
|
||||
{
|
||||
log("Received bad lsa checksum from %u\n",n->rid);
|
||||
continue;
|
||||
}
|
||||
/* pg 143 (2) */
|
||||
if((lsa->type<LSA_T_RT)||(lsa->type>LSA_T_EXT))
|
||||
{
|
||||
log("Unknown LSA type from %u\n",n->rid);
|
||||
continue;
|
||||
}
|
||||
/* pg 143 (3) */
|
||||
if((lsa->type==LSA_T_EXT)&&oa->stub)
|
||||
{
|
||||
log("Received External LSA in stub area from %u\n",n->rid);
|
||||
|
@ -136,21 +249,7 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
lsatmp.id, lsatmp.rt);
|
||||
lsadb=ospf_hash_find_header(oa->gr, &lsatmp);
|
||||
|
||||
/* Remove it from link state request list */
|
||||
WALK_LIST(NODE ifa,po->iface_list)
|
||||
WALK_LIST(NODE ntmp,ifa->neigh_list)
|
||||
{
|
||||
struct top_hash_entry *en;
|
||||
if(ntmp->state>NEIGHBOR_EXSTART)
|
||||
if((en=ospf_hash_find_header(ntmp->lsrqh,&lsatmp))!=NULL)
|
||||
{
|
||||
s_rem_node(SNODE en);
|
||||
DBG("Removing from lsreq list for neigh %u\n", ntmp->rid);
|
||||
ospf_hash_delete(ntmp->lsrqh,en);
|
||||
if(EMPTY_SLIST(ntmp->lsrql)) ospf_neigh_sm(ntmp, INM_LOADDONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* pg 143 (4) */
|
||||
if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
|
||||
{
|
||||
struct ospf_neighbor *n=NULL;
|
||||
|
@ -169,20 +268,23 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
/* pg 144 (5) */
|
||||
if((lsadb==NULL)||(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_NEWER))
|
||||
{
|
||||
struct ospf_neighbor *n=NULL;
|
||||
struct ospf_iface *ifa=NULL;
|
||||
struct ospf_iface *ift=NULL;
|
||||
void *body;
|
||||
|
||||
/* FIXME self originated? */
|
||||
|
||||
/* pg 144 (5a) */
|
||||
if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
|
||||
|
||||
flood_lsa(n,lsa,&lsatmp,po,ifa);
|
||||
|
||||
/* Remove old from all ret lists */
|
||||
/* pg 144 (5c) */
|
||||
if(lsadb)
|
||||
WALK_LIST(NODE ifa,po->iface_list)
|
||||
WALK_LIST(NODE ntmp,ifa->neigh_list)
|
||||
WALK_LIST(NODE ift,po->iface_list)
|
||||
WALK_LIST(NODE ntmp,ift->neigh_list)
|
||||
{
|
||||
struct top_hash_entry *en;
|
||||
if(ntmp->state>NEIGHBOR_EXSTART)
|
||||
|
@ -193,17 +295,22 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
}
|
||||
}
|
||||
|
||||
/* Install new */
|
||||
/* pg 144 (5d) */
|
||||
body=mb_alloc(p->pool,lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||
ntohlsab(lsa+1,body,lsatmp.type,lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||
ntohlsab(lsa+1,body,lsatmp.type,
|
||||
lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||
lsadb=lsa_install_new(&lsatmp,body, oa);
|
||||
DBG("New LSA installed in DB\n");
|
||||
|
||||
/* FIXME 144 (5e) ack */
|
||||
/* FIXME 145 (5f) self originated? */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* FIXME pg144 (6)?? */
|
||||
/* FIXME pg145 (6)?? */
|
||||
|
||||
/* pg145 (7) */
|
||||
if(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_SAME)
|
||||
{
|
||||
struct top_hash_entry *en;
|
||||
|
@ -213,9 +320,17 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* pg145 (8) */
|
||||
if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO)) continue;
|
||||
|
||||
/* FIXME lsa_send(n,lsa) */
|
||||
{
|
||||
list l;
|
||||
struct l_lsr_head llsh;
|
||||
init_list(&l);
|
||||
memcpy(&llsh.lsh,&lsadb->lsa,sizeof(struct ospf_lsa_header));
|
||||
add_tail(&l, NODE &llsh);
|
||||
ospf_lsupd_tx_list(n, &l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ struct ospf_packet {
|
|||
u16 length;
|
||||
u32 routerid;
|
||||
u32 areaid;
|
||||
#define BACKBONE 0
|
||||
u16 checksum;
|
||||
u16 autype;
|
||||
u8 authetication[8];
|
||||
|
|
Loading…
Reference in a new issue