Commit e5b5d18c authored by Ondřej Filip's avatar Ondřej Filip

NBMA networks should work now.

parent 5c18880e
......@@ -16,12 +16,14 @@ CF_DEFINES
static struct ospf_area_config *this_area;
static struct iface_patt *this_ipatt;
#define OSPF_PATT ((struct ospf_iface_patt *) this_ipatt)
static struct nbma_node *this_nbma;
CF_DECLS
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG)
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
CF_KEYWORDS(HELLO, TRANSIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
CF_KEYWORDS(NEIGHBORS)
%type <t> opttext
......@@ -83,8 +85,23 @@ 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 ; }
|
| NEIGHBORS '{' ipa_list '}'
|
;
ipa_list:
/* empty */
| ipa_list ipa_item
;
ipa_item: IPA ';'
{
this_nbma = cfg_allocz(sizeof(struct nbma_node));
add_tail(&OSPF_PATT->nbma_list, NODE this_nbma);
this_nbma->ip=$1;
}
;
ospf_iface_start:
{
......@@ -98,6 +115,7 @@ ospf_iface_start:
OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
OSPF_PATT->deadc = DEADC_D;
OSPF_PATT->type = OSPF_IT_UNDEF;
init_list(&OSPF_PATT->nbma_list);
}
;
......
......@@ -194,39 +194,69 @@ hello_timer_hook(timer *timer)
/* First a common packet header */
if(ifa->type!=OSPF_IT_NBMA)
{
/* Now fill ospf_hello header */
pkt=(struct ospf_hello_packet *)(ifa->hello_sk->tbuf);
op=(struct ospf_packet *)pkt;
fill_ospf_pkt_hdr(ifa, pkt, HELLO_P);
pkt->netmask=ipa_mkmask(ifa->iface->addr->pxlen);
ipa_hton(pkt->netmask);
pkt->helloint=ntohs(ifa->helloint);
pkt->options=ifa->options;
pkt->priority=ifa->priority;
pkt->deadint=htonl(ifa->deadc*ifa->helloint);
pkt->dr=htonl(ifa->drid);
pkt->bdr=htonl(ifa->bdrid);
/* Fill all neighbors */
i=0;
pp=(u32 *)(((u8 *)pkt)+sizeof(struct ospf_hello_packet));
WALK_LIST (neigh, ifa->neigh_list)
{
*(pp+i)=htonl(neigh->rid);
i++;
}
}
else
{
pkt=(struct ospf_hello_packet *)(ifa->ip_sk->tbuf);
}
length=sizeof(struct ospf_hello_packet)+i*sizeof(u32);
op->length=htons(length);
/* Now fill ospf_hello header */
op=(struct ospf_packet *)pkt;
ospf_pkt_finalize(ifa, op);
fill_ospf_pkt_hdr(ifa, pkt, HELLO_P);
pkt->netmask=ipa_mkmask(ifa->iface->addr->pxlen);
ipa_hton(pkt->netmask);
pkt->helloint=ntohs(ifa->helloint);
pkt->options=ifa->options;
pkt->priority=ifa->priority;
pkt->deadint=htonl(ifa->deadc*ifa->helloint);
pkt->dr=htonl(ifa->drid);
pkt->bdr=htonl(ifa->bdrid);
/* Fill all neighbors */
i=0;
pp=(u32 *)(((u8 *)pkt)+sizeof(struct ospf_hello_packet));
WALK_LIST (neigh, ifa->neigh_list)
{
*(pp+i)=htonl(neigh->rid);
i++;
}
length=sizeof(struct ospf_hello_packet)+i*sizeof(u32);
op->length=htons(length);
ospf_pkt_finalize(ifa, op);
/* And finally send it :-) */
if(ifa->type!=OSPF_IT_NBMA)
{
sk_send(ifa->hello_sk,length);
}
else /* NBMA */
{
list n_list;
struct ospf_neighbor *n1;
struct nbma_node *nb;
int send;
init_list(&n_list);
WALK_LIST(nb,ifa->nbma_list)
{
send=1;
WALK_LIST(n1, ifa->neigh_list)
{
if(ipa_compare(nb->ip,n1->ip)==0)
{
send=0;
break;
}
}
if(send) sk_send_to(ifa->ip_sk, length, nb->ip, OSPF_PROTO);
}
sk_send_to_agt(ifa->ip_sk, length, ifa, NEIGHBOR_DOWN);
}
debug("%s: Hello sent via %s\n",p->name,ifa->iface->name);
}
......
......@@ -33,7 +33,7 @@ iface_chstate(struct ospf_iface *ifa, u8 state)
{
if((state==OSPF_IS_BACKUP)||(state==OSPF_IS_DR))
{
if(ifa->dr_sk==NULL)
if((ifa->dr_sk==NULL)&&(ifa->type!=OSPF_IT_NBMA))
{
DBG("%s: Adding new multicast socket for (B)DR\n", p->name);
ifa->dr_sk=sk_new(p->pool);
......@@ -290,6 +290,7 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
struct ospf_config *c=(struct ospf_config *)(p->cf);
struct ospf_area_config *ac;
struct ospf_iface_patt *ip=NULL;
struct nbma_node *nbma,*nb;
u8 i;
DBG("%s: If notify called\n", p->name);
......@@ -323,7 +324,7 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
for(i=0;i<8;i++) ifa->aukey[i]=0;
ifa->options=2; /* FIXME what options? */
if(ip->type=OSPF_IT_UNDEF)
if(ip->type==OSPF_IT_UNDEF)
ifa->type=ospf_iface_clasify(ifa->iface, (struct proto *)ifa->proto);
else ifa->type=ip->type;
......@@ -338,18 +339,26 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
return;
}
ifa->dr_sk=NULL;
}
if((ifa->ip_sk=ospf_open_ip_socket(ifa))==NULL)
{
log("%s: Huh? could not open ip socket on interface %s?", p->name,
iface->name);
mb_free(ifa);
log("%s: Ignoring this interface", p->name);
return;
}
if((ifa->ip_sk=ospf_open_ip_socket(ifa))==NULL)
{
log("%s: Huh? could not open ip socket on interface %s?", p->name,
iface->name);
mb_free(ifa);
log("%s: Ignoring this interface", p->name);
return;
}
init_list(&(ifa->neigh_list));
init_list(&ifa->neigh_list);
init_list(&ifa->nbma_list);
WALK_LIST(nb,ip->nbma_list)
{
nbma=mb_alloc(p->pool,sizeof(struct nbma_node));
nbma->ip=nb->ip;
add_tail(&ifa->nbma_list, NODE nbma);
}
/* Add hello timer */
ifa->hello_timer=tm_new(p->pool);
ifa->hello_timer->data=ifa;
......
......@@ -52,6 +52,11 @@ struct ospf_config {
list area_list;
};
struct nbma_node {
node n;
ip_addr ip;
};
struct ospf_area_config {
node n;
u32 areaid;
......@@ -114,6 +119,7 @@ struct ospf_iface {
*/
struct top_hash_entry *nlsa; /* Originated net lsa */
int fadj; /* Number of full adjacent neigh */
list nbma_list;
};
struct ospf_packet {
......@@ -369,6 +375,7 @@ struct ospf_iface_patt {
int waitint;
int deadc;
int type;
list nbma_list;
};
static int ospf_start(struct proto *p);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment