Added hellos on NBMA networks. (I don't violate RFC now.)
This commit is contained in:
parent
94e2bbcc72
commit
a190e7200b
6 changed files with 167 additions and 17 deletions
|
@ -1015,15 +1015,18 @@ protocol ospf <name> {
|
|||
{
|
||||
cost <num>;
|
||||
hello <num>;
|
||||
poll <num>;
|
||||
retransmit <num>;
|
||||
priority <num>;
|
||||
wait <num>;
|
||||
dead count <num>;
|
||||
type [broadcast|nonbroadcast|pointopoint];
|
||||
strict nonbroadcast <switch>;
|
||||
authetication [none|simple];
|
||||
password "<text>";
|
||||
neighbors {
|
||||
<ip>;
|
||||
<ip> eligible;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1062,6 +1065,10 @@ protocol ospf <name> {
|
|||
routers on the same network need to have the same hello interval.
|
||||
Default value is 10.
|
||||
|
||||
<tag>poll <M>num</M></tag>
|
||||
Specifies interval in seconds between sending of Hello messages for
|
||||
some neighbors on NBMA netwok. Default value is 20.
|
||||
|
||||
<tag>retransmit <M>num</M></tag>
|
||||
Specifies interval in seconds between retransmissions of unacknowledged updates.
|
||||
Default value is 5.
|
||||
|
@ -1107,7 +1114,12 @@ protocol ospf <name> {
|
|||
|
||||
<tag>neighbors { <m/set/ } </tag>
|
||||
A set of neighbors to which Hello messages on nonbroadcast networks
|
||||
are to be sent.
|
||||
are to be sent. Some of them could be marked as eligible.
|
||||
|
||||
<tag>strict nonbroadcast <M>switch</M></tag>
|
||||
If set, don't send hello to any undefined neighbor. This switch
|
||||
is ignored on on any non-NBMA network. Default is No.
|
||||
|
||||
</descrip>
|
||||
|
||||
<sect1>Attributes
|
||||
|
@ -1156,10 +1168,12 @@ protocol ospf MyOSPF {
|
|||
interface "-arc0" , "arc*" {
|
||||
type nonbroadcast;
|
||||
authentication none;
|
||||
wait 50;
|
||||
dead count 6;
|
||||
strict nonbroadcast no;
|
||||
wait 120;
|
||||
poll 40;
|
||||
dead count 8;
|
||||
neighbors {
|
||||
192.168.120.1;
|
||||
192.168.120.1 eligible;
|
||||
192.168.120.2;
|
||||
192.168.120.10;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,8 @@ CF_DECLS
|
|||
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG)
|
||||
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
||||
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
|
||||
CF_KEYWORDS(NEIGHBORS, NONE, SIMPLE, AUTHENTICATION, PASSWORD)
|
||||
CF_KEYWORDS(NEIGHBORS, NONE, SIMPLE, AUTHENTICATION, PASSWORD, STRICT)
|
||||
CF_KEYWORDS(ELIGIBLE, POLL)
|
||||
|
||||
%type <t> opttext
|
||||
|
||||
|
@ -77,6 +78,7 @@ ospf_area_item:
|
|||
ospf_iface_item:
|
||||
COST expr { OSPF_PATT->cost = $2 ; if($2<=0) cf_error("Cost must be greater than zero"); }
|
||||
| HELLO expr { OSPF_PATT->helloint = $2 ; if($2<=0) cf_error("Hello int must be greater than zero"); }
|
||||
| POLL expr { OSPF_PATT->pollint = $2 ; if($2<=0) cf_error("Poll int must be greater than zero"); }
|
||||
| RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if($2<=0) cf_error("Retransmit int must be greater than zero"); }
|
||||
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if($3<=0) cf_error("Transmit delay must be greater than zero"); }
|
||||
| PRIORITY expr { OSPF_PATT->priority = $2 ; }
|
||||
|
@ -85,6 +87,7 @@ ospf_iface_item:
|
|||
| TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
|
||||
| TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
|
||||
| TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
|
||||
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
|
||||
| NEIGHBORS '{' ipa_list '}'
|
||||
| AUTHENTICATION NONE { OSPF_PATT->autype=AU_NONE ; }
|
||||
| AUTHENTICATION SIMPLE { OSPF_PATT->autype=AU_SIMPLE ; }
|
||||
|
@ -96,12 +99,26 @@ ipa_list:
|
|||
/* empty */
|
||||
| ipa_list ipa_item
|
||||
;
|
||||
|
||||
ipa_item:
|
||||
ipa_el;
|
||||
| ipa_ne;
|
||||
|
||||
ipa_item: IPA ';'
|
||||
ipa_el: IPA ';'
|
||||
{
|
||||
this_nbma = cfg_allocz(sizeof(struct nbma_node));
|
||||
add_tail(&OSPF_PATT->nbma_list, NODE this_nbma);
|
||||
this_nbma->ip=$1;
|
||||
this_nbma->eligible=0;
|
||||
}
|
||||
;
|
||||
|
||||
ipa_ne: IPA ELIGIBLE ';'
|
||||
{
|
||||
this_nbma = cfg_allocz(sizeof(struct nbma_node));
|
||||
add_tail(&OSPF_PATT->nbma_list, NODE this_nbma);
|
||||
this_nbma->ip=$1;
|
||||
this_nbma->eligible=1;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -112,12 +129,14 @@ ospf_iface_start:
|
|||
add_tail(&this_area->patt_list, NODE this_ipatt);
|
||||
OSPF_PATT->cost = COST_D;
|
||||
OSPF_PATT->helloint = HELLOINT_D;
|
||||
OSPF_PATT->pollint = POLLINT_D;
|
||||
OSPF_PATT->rxmtint = RXMTINT_D;
|
||||
OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
|
||||
OSPF_PATT->priority = PRIORITY_D;
|
||||
OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
|
||||
OSPF_PATT->deadc = DEADC_D;
|
||||
OSPF_PATT->type = OSPF_IT_UNDEF;
|
||||
OSPF_PATT->strictnbma = 0;
|
||||
init_list(&OSPF_PATT->nbma_list);
|
||||
OSPF_PATT->autype=AU_NONE;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,13 @@ restart_hellotim(struct ospf_iface *ifa)
|
|||
tm_start(ifa->hello_timer,ifa->helloint);
|
||||
}
|
||||
|
||||
void
|
||||
restart_polltim(struct ospf_iface *ifa)
|
||||
{
|
||||
if(ifa->poll_timer)
|
||||
tm_start(ifa->poll_timer,ifa->pollint);
|
||||
}
|
||||
|
||||
void
|
||||
restart_waittim(struct ospf_iface *ifa)
|
||||
{
|
||||
|
@ -56,6 +63,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
|||
ip_addr olddr,oldbdr;
|
||||
ip_addr mask;
|
||||
char *beg=": Bad OSPF hello packet from ", *rec=" received: ";
|
||||
int eligible=0;
|
||||
|
||||
nrid=ntohl(((struct ospf_packet *)ps)->routerid);
|
||||
|
||||
|
@ -90,6 +98,36 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
|||
|
||||
if((n=find_neigh(ifa, nrid))==NULL)
|
||||
{
|
||||
if((ifa->type==OSPF_IT_NBMA))
|
||||
{
|
||||
struct nbma_node *nn;
|
||||
int found=0;
|
||||
|
||||
WALK_LIST(nn,ifa->nbma_list)
|
||||
{
|
||||
if(ipa_compare(faddr,nn->ip)==0)
|
||||
{
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((found==0)&&(ifa->strictnbma))
|
||||
{
|
||||
OSPF_TRACE(D_EVENTS, "Ignoring new neighbor: %I on %s.", faddr,
|
||||
ifa->iface->name);
|
||||
return;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
eligible=nn->eligible;
|
||||
if(((ps->priority==0)&&eligible)||((ps->priority>0)&&(eligible==0)))
|
||||
{
|
||||
OSPF_TRACE(D_EVENTS, "Eligibility mismatch for neighbor: %I on %s",
|
||||
faddr, ifa->iface->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s.", faddr,
|
||||
ifa->iface->name);
|
||||
n=mb_allocz(p->pool, sizeof(struct ospf_neighbor));
|
||||
|
@ -177,11 +215,27 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
|||
ospf_int_sm(ifa, ISM_NEICH);
|
||||
}
|
||||
|
||||
if(ifa->type!=OSPF_IT_NBMA)
|
||||
{
|
||||
if((ifa->priority==0)&&(n->priority>0)) hello_send(NULL,0, n);
|
||||
}
|
||||
ospf_neigh_sm(n, INM_HELLOREC);
|
||||
}
|
||||
|
||||
void
|
||||
poll_timer_hook(timer *timer)
|
||||
{
|
||||
hello_send(timer,1, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
hello_timer_hook(timer *timer)
|
||||
{
|
||||
hello_send(timer,0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
hello_send(timer *timer,int poll, struct ospf_neighbor *dirn)
|
||||
{
|
||||
struct ospf_iface *ifa;
|
||||
struct ospf_hello_packet *pkt;
|
||||
|
@ -192,9 +246,11 @@ hello_timer_hook(timer *timer)
|
|||
u32 *pp;
|
||||
u8 i;
|
||||
|
||||
ifa=(struct ospf_iface *)timer->data;
|
||||
if(timer==NULL) ifa=dirn->ifa;
|
||||
else ifa=(struct ospf_iface *)timer->data;
|
||||
|
||||
p=(struct proto *)(ifa->proto);
|
||||
DBG("%s: Hello timer fired on interface %s.\n",
|
||||
DBG("%s: Hello/Poll timer fired on interface %s.\n",
|
||||
p->name, ifa->iface->name);
|
||||
/* Now we should send a hello packet */
|
||||
/* First a common packet header */
|
||||
|
@ -248,20 +304,44 @@ hello_timer_hook(timer *timer)
|
|||
struct nbma_node *nb;
|
||||
int send;
|
||||
|
||||
WALK_LIST(nb,ifa->nbma_list)
|
||||
if(timer==NULL) /* Response to received hello */
|
||||
{
|
||||
send=1;
|
||||
WALK_LIST(n1, ifa->neigh_list)
|
||||
sk_send_to(ifa->ip_sk, length, dirn->ip, OSPF_PROTO);
|
||||
}
|
||||
else
|
||||
{
|
||||
int toall=0;
|
||||
int meeli=0;
|
||||
if(ifa->state>OSPF_IS_DROTHER) toall=1;
|
||||
if(ifa->priority>0) meeli=1;
|
||||
|
||||
WALK_LIST(nb,ifa->nbma_list)
|
||||
{
|
||||
if(ipa_compare(nb->ip,n1->ip)==0)
|
||||
send=1;
|
||||
WALK_LIST(n1, ifa->neigh_list)
|
||||
{
|
||||
if(ipa_compare(nb->ip,n1->ip)==0)
|
||||
{
|
||||
send=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((poll==1)&&(send))
|
||||
{
|
||||
send=0;
|
||||
break;
|
||||
if(toall||(meeli&&nb->eligible))
|
||||
sk_send_to(ifa->ip_sk, length, nb->ip, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
if(send) sk_send_to(ifa->ip_sk, length, nb->ip, OSPF_PROTO);
|
||||
if(poll==0)
|
||||
{
|
||||
WALK_LIST(n1,ifa->neigh_list)
|
||||
{
|
||||
if(toall||(n1->rid==ifa->drid)||(n1->rid==ifa->bdrid)||
|
||||
(meeli&&(n1->priority>0)))
|
||||
sk_send_to(ifa->ip_sk, length, n1->ip, OSPF_PROTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
sk_send_to_agt(ifa->ip_sk, length, ifa, NEIGHBOR_DOWN);
|
||||
}
|
||||
OSPF_TRACE(D_PACKETS, "Hello sent via %s",ifa->iface->name);
|
||||
}
|
||||
|
|
|
@ -13,10 +13,13 @@
|
|||
void install_inactim(struct ospf_neighbor *n);
|
||||
void restart_inactim(struct ospf_neighbor *n);
|
||||
void restart_hellotim(struct ospf_iface *ifa);
|
||||
void restart_polltim(struct ospf_iface *ifa);
|
||||
void restart_waittim(struct ospf_iface *ifa);
|
||||
void ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
||||
struct ospf_iface *ifa, int size, ip_addr faddr);
|
||||
void hello_timer_hook(timer *timer);
|
||||
void poll_timer_hook(timer *timer);
|
||||
void wait_timer_hook(timer *timer);
|
||||
void hello_send(timer *timer,int poll, struct ospf_neighbor *dirn);
|
||||
|
||||
#endif /* _BIRD_OSPF_HELLO_H_ */
|
||||
|
|
|
@ -122,6 +122,11 @@ downint(struct ospf_iface *ifa)
|
|||
tm_stop(ifa->hello_timer);
|
||||
rfree(ifa->hello_timer);
|
||||
}
|
||||
if(ifa->poll_timer!=NULL)
|
||||
{
|
||||
tm_stop(ifa->poll_timer);
|
||||
rfree(ifa->poll_timer);
|
||||
}
|
||||
rfree(ifa->lock);
|
||||
mb_free(ifa);
|
||||
}
|
||||
|
@ -151,6 +156,7 @@ ospf_int_sm(struct ospf_iface *ifa, int event)
|
|||
{
|
||||
/* Now, nothing should be adjacent */
|
||||
restart_hellotim(ifa);
|
||||
restart_polltim(ifa);
|
||||
if((ifa->type==OSPF_IT_PTP) || (ifa->type==OSPF_IT_VLINK))
|
||||
{
|
||||
iface_chstate(ifa, OSPF_IS_PTP);
|
||||
|
@ -358,13 +364,20 @@ void
|
|||
ospf_iface_info(struct ospf_iface *ifa)
|
||||
{
|
||||
int x;
|
||||
char *strict="(strict)";
|
||||
|
||||
if((ifa->type!=OSPF_IT_NBMA)||(ifa->strictnbma==0)) strict="";
|
||||
cli_msg(-1015,"Interface \"%s\":", ifa->iface->name);
|
||||
cli_msg(-1015,"\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid);
|
||||
cli_msg(-1015,"\tType: %s", ospf_it[ifa->type]);
|
||||
cli_msg(-1015,"\tType: %s %s", ospf_it[ifa->type], strict);
|
||||
cli_msg(-1015,"\tState: %s", ospf_is[ifa->state]);
|
||||
cli_msg(-1015,"\tPriority: %u", ifa->priority);
|
||||
cli_msg(-1015,"\tCost: %u", ifa->cost);
|
||||
cli_msg(-1015,"\tHello timer: %u", ifa->helloint);
|
||||
if(ifa->type==OSPF_IT_NBMA)
|
||||
{
|
||||
cli_msg(-1015,"\tPoll timer: %u", ifa->pollint);
|
||||
}
|
||||
cli_msg(-1015,"\tWait timer: %u", ifa->waitint);
|
||||
cli_msg(-1015,"\tDead timer: %u", ifa->deadc*ifa->helloint);
|
||||
cli_msg(-1015,"\tRetransmit timer: %u", ifa->rxmtint);
|
||||
|
@ -412,6 +425,8 @@ ospf_ifa_add(struct object_lock *lock)
|
|||
ifa->inftransdelay=ip->inftransdelay;
|
||||
ifa->priority=ip->priority;
|
||||
ifa->helloint=ip->helloint;
|
||||
ifa->pollint=ip->pollint;
|
||||
ifa->strictnbma=ip->strictnbma;
|
||||
ifa->waitint=ip->waitint;
|
||||
ifa->deadc=ip->deadc;
|
||||
ifa->autype=ip->autype;
|
||||
|
@ -453,6 +468,7 @@ ospf_ifa_add(struct object_lock *lock)
|
|||
{
|
||||
nbma=mb_alloc(p->pool,sizeof(struct nbma_node));
|
||||
nbma->ip=nb->ip;
|
||||
nbma->eligible=nb->eligible;
|
||||
add_tail(&ifa->nbma_list, NODE nbma);
|
||||
}
|
||||
|
||||
|
@ -464,6 +480,17 @@ ospf_ifa_add(struct object_lock *lock)
|
|||
ifa->hello_timer->recurrent=ifa->helloint;
|
||||
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
|
||||
|
||||
if(ifa->type==OSPF_IT_NBMA)
|
||||
{
|
||||
ifa->poll_timer=tm_new(p->pool);
|
||||
ifa->poll_timer->data=ifa;
|
||||
ifa->poll_timer->randomize=0;
|
||||
ifa->poll_timer->hook=poll_timer_hook;
|
||||
ifa->poll_timer->recurrent=ifa->pollint;
|
||||
DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint);
|
||||
}
|
||||
else ifa->poll_timer=NULL;
|
||||
|
||||
ifa->wait_timer=tm_new(p->pool);
|
||||
ifa->wait_timer->data=ifa;
|
||||
ifa->wait_timer->randomize=0;
|
||||
|
|
|
@ -62,6 +62,7 @@ struct ospf_config {
|
|||
struct nbma_node {
|
||||
node n;
|
||||
ip_addr ip;
|
||||
int eligible;
|
||||
};
|
||||
|
||||
struct ospf_area_config {
|
||||
|
@ -91,6 +92,7 @@ struct ospf_iface {
|
|||
u8 priority; /* A router priority for DR election */
|
||||
u16 helloint; /* number of seconds between hello sending */
|
||||
u16 waitint; /* number of sec before changing state from wait */
|
||||
u16 pollint; /* Poll interval */
|
||||
u32 deadc; /* after "deadint" missing hellos is router dead */
|
||||
u16 autype;
|
||||
u8 aukey[8];
|
||||
|
@ -100,6 +102,7 @@ struct ospf_iface {
|
|||
ip_addr bdrip; /* Backup DR */
|
||||
u32 bdrid;
|
||||
u8 type; /* OSPF view of type */
|
||||
u8 strictnbma; /* Can I talk with unknown neighbors? */
|
||||
#define OSPF_IT_BCAST 0
|
||||
#define OSPF_IT_NBMA 1
|
||||
#define OSPF_IT_PTP 2
|
||||
|
@ -115,12 +118,14 @@ struct ospf_iface {
|
|||
#define OSPF_IS_DR 6 /* I'm DR */
|
||||
timer *wait_timer; /* WAIT timer */
|
||||
timer *hello_timer; /* HELLOINT timer */
|
||||
timer *poll_timer; /* Poll Interval - for NBMA */
|
||||
/* Default values for interface parameters */
|
||||
#define COST_D 10
|
||||
#define RXMTINT_D 5
|
||||
#define INFTRANSDELAY_D 1
|
||||
#define PRIORITY_D 1
|
||||
#define HELLOINT_D 10
|
||||
#define POLLINT_D 20
|
||||
#define DEADC_D 4
|
||||
#define WAIT_DMH 4 /* Value of Wait timer - not found it in RFC
|
||||
* - using 4*HELLO
|
||||
|
@ -377,12 +382,14 @@ struct ospf_iface_patt {
|
|||
int cost;
|
||||
int helloint;
|
||||
int rxmtint;
|
||||
int pollint;
|
||||
int inftransdelay;
|
||||
int priority;
|
||||
int waitint;
|
||||
int deadc;
|
||||
int type;
|
||||
int autype;
|
||||
int strictnbma;
|
||||
#define AU_NONE 0
|
||||
#define AU_SIMPLE 1
|
||||
#define AU_CRYPT 2
|
||||
|
|
Loading…
Reference in a new issue