]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Added hellos on NBMA networks. (I don't violate RFC now.)
authorOndrej Filip <feela@network.cz>
Sat, 2 Sep 2000 00:03:36 +0000 (00:03 +0000)
committerOndrej Filip <feela@network.cz>
Sat, 2 Sep 2000 00:03:36 +0000 (00:03 +0000)
doc/bird.sgml
proto/ospf/config.Y
proto/ospf/hello.c
proto/ospf/hello.h
proto/ospf/iface.c
proto/ospf/ospf.h

index 3722e489bdcaf15b2c84351060d81ef40d0660b3..5441e31e13dbf90c9435992b110d2890aa31181a 100644 (file)
@@ -1015,15 +1015,18 @@ protocol ospf &lt;name&gt; {
                {
                        cost &lt;num&gt;;
                        hello &lt;num&gt;;
+                       poll &lt;num&gt;;
                        retransmit &lt;num&gt;;
                        priority &lt;num&gt;;
                        wait &lt;num&gt;;
                        dead count &lt;num&gt;;
                        type [broadcast|nonbroadcast|pointopoint];
+                       strict nonbroadcast &lt;switch&gt;;
                        authetication [none|simple];
                        password "&lt;text&gt;";
                        neighbors {
                                &lt;ip&gt;;
+                               &lt;ip&gt; eligible;
                        };
                };
        };
@@ -1062,6 +1065,10 @@ protocol ospf &lt;name&gt; {
         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 &lt;name&gt; {
 
        <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;
                        };
index c78023809c681283415f72288d239c9c425a1163..50ba371a179f705efd5a20597a713928a97f3783 100644 (file)
@@ -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;
  }
index d902bbdd1ce0472038bc6eac569cb8266ad3b780..94326c5da14967eed99adabe90c11cbe06722a84 100644 (file)
@@ -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 */
+    {
+      sk_send_to(ifa->ip_sk, length, dirn->ip, OSPF_PROTO);
+    }
+    else
     {
-      send=1;
-      WALK_LIST(n1, ifa->neigh_list)
+      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);
 }
index fe53c104235fc000e6f7f4b0e841645cb47a79af..4a5d5042dd65fad4d0f68e316552e1f73c042d9b 100644 (file)
 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_ */
index 172a60ab9ddedd7c12cad96dc497b1c1c9c025f5..4c0e2866d5852a7ebd1d1aa46783a953d341c3fe 100644 (file)
@@ -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;
index 8854d8daa3c0bb530bbf3d7955182e1fcc7e38e0..6a7c753b9dc5c08b5a5c9cf56123c03e25b815b7 100644 (file)
@@ -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