summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proto/ospf/config.Y20
-rw-r--r--proto/ospf/hello.c80
-rw-r--r--proto/ospf/iface.c31
-rw-r--r--proto/ospf/ospf.h7
4 files changed, 101 insertions, 37 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 9416612..e678a26 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -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);
}
;
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index 3e4bfff..21cd1ea 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -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);
}
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index c0d8770..6435d39 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -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;
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index d44db95..6736fa0 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -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);