]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
NBMA networks should work now.
authorOndrej Filip <feela@network.cz>
Mon, 5 Jun 2000 23:44:26 +0000 (23:44 +0000)
committerOndrej Filip <feela@network.cz>
Mon, 5 Jun 2000 23:44:26 +0000 (23:44 +0000)
proto/ospf/config.Y
proto/ospf/hello.c
proto/ospf/iface.c
proto/ospf/ospf.h

index 9416612cc8a65634db605eec3dfade14025c4702..e678a262cf9bd5f6560c9cb7f344ed4274e36faf 100644 (file)
@@ -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);
  }
 ;
 
index 3e4bfff59506594191d297271a71dfb42f1bb77c..21cd1ea4906038f398b49673c79412702b5aa93c 100644 (file)
@@ -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);
 }
 
index c0d8770f7d8343a4d1e186f7fb184a5d5fab06c1..6435d3901f8f34922d2e8d4e61d57203652376bc 100644 (file)
@@ -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;
index d44db95fd41903a5d157a5a27b51365e9e26a7e0..6736fa0f0fc03398c0358c1593c60abc0f7ebcdc 100644 (file)
@@ -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);