Some lsack work. There is something very worng. :-( It locked my network.
This commit is contained in:
parent
2a0925948d
commit
67315ef64e
8 changed files with 175 additions and 26 deletions
|
@ -118,6 +118,13 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
|||
n->lsrr_timer->hook=lsrr_timer_hook;
|
||||
n->lsrr_timer->recurrent=ifa->rxmtint;
|
||||
DBG("%s: Installing lsrr timer.\n", p->name);
|
||||
init_list(&n->ackl);
|
||||
n->ackd_timer=tm_new(p->pool);
|
||||
n->ackd_timer->data=n;
|
||||
n->ackd_timer->randomize=0;
|
||||
n->ackd_timer->hook=ackd_timer_hook;
|
||||
n->ackd_timer->recurrent=ifa->rxmtint/2; /* FIXME use some config? */
|
||||
DBG("%s: Installing ackd timer.\n", p->name);
|
||||
}
|
||||
ospf_neigh_sm(n, INM_HELLOREC);
|
||||
|
||||
|
|
|
@ -8,12 +8,131 @@
|
|||
|
||||
#include "ospf.h"
|
||||
|
||||
/* Note, that h is in network endianity! */
|
||||
void
|
||||
ospf_lsack_tx(struct ospf_neighbor *n)
|
||||
ospf_lsack_direct_tx(struct ospf_neighbor *n,struct ospf_lsa_header *h)
|
||||
{
|
||||
/* FIXME Go on! */
|
||||
struct ospf_packet *op;
|
||||
struct ospf_lsack_packet *pk;
|
||||
sock *sk=n->ifa->ip_sk;
|
||||
u16 len;
|
||||
|
||||
pk=(struct ospf_lsack_packet *)sk->tbuf;
|
||||
op=(struct ospf_packet *)sk->tbuf;
|
||||
|
||||
fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
|
||||
|
||||
memcpy(pk+1,h,sizeof(struct ospf_lsa_header));
|
||||
len=sizeof(struct ospf_lsack_packet)+sizeof(struct ospf_lsa_header);
|
||||
op->length=htons(len);
|
||||
ospf_pkt_finalize(n->ifa, op);
|
||||
sk_send_to(sk,len, n->ip, OSPF_PROTO);
|
||||
}
|
||||
|
||||
void
|
||||
ospf_lsa_delay(struct ospf_neighbor *n,struct ospf_lsa_header *h,
|
||||
struct proto *p)
|
||||
{
|
||||
struct lsah_n *no;
|
||||
|
||||
no=mb_alloc(p->pool,sizeof(struct lsah_n));
|
||||
memcpy(&no->lsa,h,sizeof(struct ospf_lsa_header));
|
||||
add_tail(&n->ackl, NODE no);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ackd_timer_hook(timer *t)
|
||||
{
|
||||
struct ospf_neighbor *n=t->data;
|
||||
if(!EMPTY_LIST(n->ackl)) ospf_lsack_delay_tx(n);
|
||||
}
|
||||
|
||||
void
|
||||
ospf_lsack_delay_tx(struct ospf_neighbor *n)
|
||||
{
|
||||
struct ospf_packet *op;
|
||||
struct ospf_lsack_packet *pk;
|
||||
sock *sk;
|
||||
u16 len,i=0;
|
||||
struct ospf_lsa_header *h;
|
||||
struct lsah_n *no;
|
||||
struct ospf_iface *ifa=n->ifa;
|
||||
|
||||
if(ifa->type==OSPF_IT_BCAST)
|
||||
{
|
||||
sk=ifa->hello_sk;
|
||||
}
|
||||
else
|
||||
{
|
||||
sk=ifa->ip_sk;
|
||||
}
|
||||
|
||||
pk=(struct ospf_lsack_packet *)sk->tbuf;
|
||||
op=(struct ospf_packet *)sk->tbuf;
|
||||
|
||||
fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
|
||||
h=(struct ospf_lsa_header *)(pk+1);
|
||||
|
||||
while(!EMPTY_LIST(n->ackl))
|
||||
{
|
||||
no=(struct lsah_n *)HEAD(n->ackl);
|
||||
memcpy(h+i,&no->lsa, sizeof(struct ospf_lsa_header));
|
||||
i++;
|
||||
rem_node(NODE n);
|
||||
if((i*sizeof(struct ospf_lsa_header)+sizeof(struct ospf_lsack_packet)-SIPH)>
|
||||
n->ifa->iface->mtu)
|
||||
{
|
||||
if(!EMPTY_LIST(n->ackl))
|
||||
{
|
||||
len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
|
||||
op->length=htons(len);
|
||||
ospf_pkt_finalize(n->ifa, op);
|
||||
if(ifa->type==OSPF_IT_BCAST)
|
||||
{
|
||||
if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
|
||||
{
|
||||
sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
|
||||
}
|
||||
else
|
||||
{
|
||||
sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
|
||||
}
|
||||
|
||||
fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
|
||||
h=(struct ospf_lsa_header *)(pk+1);
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
|
||||
op->length=htons(len);
|
||||
ospf_pkt_finalize(n->ifa, op);
|
||||
if(ifa->type==OSPF_IT_BCAST)
|
||||
{
|
||||
if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
|
||||
{
|
||||
sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
|
||||
}
|
||||
else
|
||||
{
|
||||
sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
|
||||
struct ospf_iface *ifa, u16 size)
|
||||
|
@ -60,10 +179,3 @@ ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
|
|||
ospf_hash_delete(n->lsrth,en);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa)
|
||||
{
|
||||
/* FIXME Go on */
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,16 @@
|
|||
|
||||
#ifndef _BIRD_OSPF_LSACK_H_
|
||||
#define _BIRD_OSPF_LSACK_H_
|
||||
struct lsah_n {
|
||||
node n;
|
||||
struct ospf_lsa_header lsa;
|
||||
};
|
||||
|
||||
void ospf_lsack_tx(struct ospf_neighbor *n);
|
||||
void ospf_lsack_direct_tx(struct ospf_neighbor *n,struct ospf_lsa_header *h);
|
||||
void ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
|
||||
struct ospf_iface *ifa, u16 size);
|
||||
void add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa);
|
||||
|
||||
void ackd_timer_hook(timer *t);
|
||||
void ospf_lsack_delay_tx(struct ospf_neighbor *n);
|
||||
void ospf_lsa_delay(struct ospf_neighbor *n,struct ospf_lsa_header *h,
|
||||
struct proto *p);
|
||||
#endif /* _BIRD_OSPF_LSACK_H_ */
|
||||
|
|
|
@ -122,12 +122,7 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
|
|||
|
||||
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);
|
||||
}
|
||||
sk_send_to_agt(sk ,len, ifa, NEIGHBOR_EXCHANGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -267,19 +262,19 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
/* pg 143 (4) */
|
||||
if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
|
||||
{
|
||||
struct ospf_neighbor *n=NULL;
|
||||
struct ospf_iface *ifa=NULL;
|
||||
int flag=0;
|
||||
struct ospf_iface *ifatmp;
|
||||
|
||||
WALK_LIST(NODE ifa,po->iface_list)
|
||||
WALK_LIST(NODE ntmp,ifa->neigh_list)
|
||||
WALK_LIST(NODE ifatmp,po->iface_list)
|
||||
WALK_LIST(NODE ntmp,ifatmp->neigh_list)
|
||||
if((ntmp->state==NEIGHBOR_EXCHANGE)&&
|
||||
(ntmp->state==NEIGHBOR_LOADING))
|
||||
flag=1;
|
||||
|
||||
if(flag==0)
|
||||
{
|
||||
add_ack_list(n,lsa);
|
||||
ospf_lsack_direct_tx(n,lsa);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +312,11 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
lsadb=lsa_install_new(&lsatmp,body, oa);
|
||||
DBG("New LSA installed in DB\n");
|
||||
|
||||
/* FIXME 144 (5e) ack */
|
||||
if(ifa->state==OSPF_IS_BACKUP)
|
||||
{
|
||||
if(ifa->drid==n->rid) ospf_lsa_delay(n, lsa, p);
|
||||
}
|
||||
else if(ifa->drid==n->rid) ospf_lsa_delay(n, lsa, p);
|
||||
/* FIXME 145 (5f) self originated? */
|
||||
|
||||
continue;
|
||||
|
@ -330,13 +329,25 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
|||
{
|
||||
struct top_hash_entry *en;
|
||||
if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL)
|
||||
{
|
||||
s_rem_node(SNODE en);
|
||||
/* FIXME ack_lsa() */
|
||||
if(ifa->state==OSPF_IS_BACKUP)
|
||||
{
|
||||
if(n->rid==ifa->drid) ospf_lsa_delay(n, lsa, p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ospf_lsack_direct_tx(n,lsa);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* pg145 (8) */
|
||||
if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO)) continue;
|
||||
if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
list l;
|
||||
|
|
|
@ -215,6 +215,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
|
|||
s_init(&(n->lsrqi), &(n->lsrql));
|
||||
s_init(&(n->lsrti), &(n->lsrtl));
|
||||
tm_start(n->lsrr_timer,n->ifa->rxmtint);
|
||||
tm_start(n->ackd_timer,n->ifa->rxmtint/2);
|
||||
}
|
||||
else die("NEGDONE and I'm not in EXSTART?\n");
|
||||
break;
|
||||
|
|
|
@ -286,6 +286,8 @@ struct ospf_neighbor
|
|||
void *ldbdes; /* Last database description packet */
|
||||
timer *rxmt_timer; /* RXMT timer */
|
||||
timer *lsrr_timer; /* Link state requiest retransmition timer */
|
||||
list ackl;
|
||||
timer *ackd_timer; /* Delayed ack timer */
|
||||
};
|
||||
|
||||
/* Definitions for interface state machine */
|
||||
|
|
|
@ -187,3 +187,12 @@ ospf_err_hook(sock *sk, int err)
|
|||
DBG("%s: Err_Hook called on interface %s\n", p->name,sk->iface->name);
|
||||
}
|
||||
|
||||
void
|
||||
sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state)
|
||||
{
|
||||
struct ospf_neighbor *n;
|
||||
|
||||
WALK_LIST(NODE n,ifa->neigh_list)
|
||||
if(n->state>=state)
|
||||
sk_send_to(sk, len, n->ip, OSPF_PROTO);
|
||||
}
|
||||
|
|
|
@ -16,5 +16,6 @@ void ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt);
|
|||
int ospf_rx_hook(sock *sk, int size);
|
||||
void ospf_tx_hook(sock *sk);
|
||||
void ospf_err_hook(sock *sk, int err);
|
||||
void sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state);
|
||||
|
||||
#endif /* _BIRD_OSPF_PACKET_H_ */
|
||||
|
|
Loading…
Reference in a new issue