]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements Point-to-MultiPoint interface type for OSPF.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 24 Dec 2010 17:08:07 +0000 (18:08 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 24 Dec 2010 17:08:07 +0000 (18:08 +0100)
13 files changed:
doc/bird.sgml
proto/ospf/config.Y
proto/ospf/hello.c
proto/ospf/iface.c
proto/ospf/iface.h
proto/ospf/lsupd.c
proto/ospf/neighbor.c
proto/ospf/neighbor.h
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/ospf/packet.c
proto/ospf/rt.c
proto/ospf/topology.c

index c7816f086257d5fa21d5d1fbe3647b475e0b47a6..5d9c7bd69b02c5e1d816383efb3077296ddf9065 100644 (file)
@@ -407,8 +407,8 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
        <cf>interface "*" { type broadcast; };</cf> - start the protocol on all interfaces with
        <cf>type broadcast</cf> option.
 
-       <cf>interface "eth1", "eth4", "eth5" { type pointopoint; };</cf> - start the protocol
-       on enumerated interfaces with <cf>type pointopoint</cf> option.
+       <cf>interface "eth1", "eth4", "eth5" { type ptp; };</cf> - start the protocol
+       on enumerated interfaces with <cf>type ptp</cf> option.
        
        <cf>interface -192.168.1.0/24, 192.168.0.0/16;</cf> - start the protocol on all
        interfaces that have address from 192.168.0.0/16, but not
@@ -1549,7 +1549,8 @@ protocol ospf &lt;name&gt; {
                        dead count &lt;num&gt;;
                        dead &lt;num&gt;;
                        rx buffer [normal|large|&lt;num&gt;];
-                       type [broadcast|nonbroadcast|pointopoint];
+                       type [broadcast|bcast|pointopoint|ptp|
+                               nonbroadcast|nbma|pointomultipoint|ptmp];
                        strict nonbroadcast &lt;switch&gt;;
                        check link &lt;switch&gt;;
                        ecmp weight &lt;num&gt;;
@@ -1688,23 +1689,43 @@ protocol ospf &lt;name&gt; {
         be bigger than maximal size of any packets. Value NORMAL (default)
         means 2*MTU, value LARGE means maximal allowed packet - 65535.
 
-       <tag>type broadcast</tag>
-        BIRD detects a type of a connected network automatically, but sometimes it's
-        convenient to force use of a different type manually.
-        On broadcast networks, flooding and Hello messages are sent using multicasts
-        (a single packet for all the neighbors).
-
-       <tag>type pointopoint</tag>
-        Point-to-point networks connect just 2 routers together. No election
-        is performed there which reduces the number of messages sent.
-
-       <tag>type nonbroadcast</tag>
-        On nonbroadcast networks, the packets are sent to each neighbor
+       <tag>type broadcast|bcast</tag>
+        BIRD detects a type of a connected network automatically, but
+        sometimes it's convenient to force use of a different type
+        manually. On broadcast networks (like ethernet), flooding
+        and Hello messages are sent using multicasts (a single packet
+        for all the neighbors). A designated router is elected and it
+        is responsible for synchronizing the link-state databases and
+        originating network LSAs. This network type cannot be used on
+        physically NBMA networks and on unnumbered networks (networks
+        without proper IP prefix).
+
+       <tag>type pointopoint|ptp</tag>
+        Point-to-point networks connect just 2 routers together. No
+        election is performed and no network LSA is originated, which
+        makes it simpler and faster to establish. This network type
+        is useful not only for physically PtP ifaces (like PPP or
+        tunnels), but also for broadcast networks used as PtP links.
+        This network type cannot be used on physically NBMA networks.
+
+       <tag>type nonbroadcast|nbma</tag>
+        On NBMA networks, the packets are sent to each neighbor
         separately because of lack of multicast capabilities.
+        Like on broadcast networks, a designated router is elected,
+        which plays a central role in propagation of LSAs.
+        This network type cannot be used on unnumbered networks.
+
+       <tag>type pointomultipoint|ptmp</tag>
+        This is another network type designed to handle NBMA
+        networks. In this case the NBMA network is treated as a
+        collection of PtP links. This is useful if not every pair of
+        routers on the NBMA network has direct communication, or if
+        the NBMA network is used as an (possibly unnumbered) PtP
+        link.
 
        <tag>strict nonbroadcast <M>switch</M></tag>
         If set, don't send hello to any undefined neighbor. This switch
-        is ignored on any non-NBMA network. Default value is no.
+        is ignored on other than NBMA or PtMP networks. Default value is no.
 
        <tag>check link <M>switch</M></tag>
         If set, a hardware link state (reported by OS) is taken into
@@ -1738,8 +1759,9 @@ protocol ospf &lt;name&gt; {
         See <ref id="dsc-pass" name="password"> common option for detailed description.
 
        <tag>neighbors { <m/set/ } </tag>
-        A set of neighbors to which Hello messages on nonbroadcast networks
-        are to be sent. Some of them could be marked as eligible.
+        A set of neighbors to which Hello messages on NBMA or PtMP
+        networks are to be sent. For NBMA networks, some of them
+        could be marked as eligible.
 
 </descrip>
 
index 59e1fbe02498fc85d79f64a0f8a7768d106ead34..321bd8d46fd7a89e95ebe5251cfebdf0148b57b2 100644 (file)
@@ -46,8 +46,9 @@ finish_iface_config(struct ospf_iface_patt *ip)
 CF_DECLS
 
 CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
-CF_KEYWORDS(BROADCAST, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
-CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
+CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
+CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST)
+CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
 CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
 CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
 CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
@@ -190,8 +191,13 @@ ospf_iface_item:
  | DEAD expr { OSPF_PATT->dead = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
  | DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
  | TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
+ | TYPE BCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
  | TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
+ | TYPE NBMA { OSPF_PATT->type = OSPF_IT_NBMA ; }
  | TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
+ | TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
+ | TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
+ | TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
  | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
  | STUB bool { OSPF_PATT->stub = $2 ; }
  | CHECK LINK bool { OSPF_PATT->check_link = $3; }
index 216dc72f7027a373790d64ed6c2ccb570c462c5a..47b84a4dbe520384404a99edf8c700310a6fd799 100644 (file)
@@ -48,7 +48,7 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
   struct proto_ospf *po = ifa->oa->po;
   struct proto *p = &po->proto;
   char *beg = "OSPF: Bad HELLO packet from ";
-  unsigned int size, i, twoway, eligible, peers;
+  unsigned int size, i, twoway, peers;
   u32 tmp;
   u32 *pnrid;
 
@@ -103,37 +103,30 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
 
   if (!n)
   {
-    if ((ifa->type == OSPF_IT_NBMA))
+    if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
     {
-      struct nbma_node *nn;
-      int found = 0;
+      struct nbma_node *nn = find_nbma_node(ifa, faddr);
 
-      WALK_LIST(nn, ifa->nbma_list)
-      {
-       if (ipa_equal(faddr, nn->ip))
-       {
-         found = 1;
-         break;
-       }
-      }
-      if ((found == 0) && (ifa->strictnbma))
+      if (!nn && ifa->strictnbma)
       {
        log(L_WARN "Ignoring new neighbor: %I on %s", faddr,
            ifa->iface->name);
        return;
       }
-      if (found)
+
+      if (nn && (ifa->type == OSPF_IT_NBMA) &&
+         (((ps->priority == 0) && nn->eligible) ||
+          ((ps->priority > 0) && !nn->eligible)))
       {
-       eligible = nn->eligible;
-       if (((ps->priority == 0) && eligible)
-           || ((ps->priority > 0) && (eligible == 0)))
-       {
-         log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
-             faddr, ifa->iface->name);
-         return;
-       }
+       log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
+           faddr, ifa->iface->name);
+       return;
       }
+
+      if (nn)
+       nn->found = 1;
     }
+
     OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr,
               ifa->iface->name);
 
@@ -239,7 +232,7 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
   struct ospf_neighbor *neigh, *n1;
   u16 length;
   u32 *pp;
-  int i, send;
+  int i;
   struct nbma_node *nb;
 
   if (timer == NULL)
@@ -311,53 +304,56 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
 
   switch(ifa->type)
   {
-    case OSPF_IT_NBMA:
-      if (timer == NULL)               /* Response to received hello */
-      {
-        ospf_send_to(ifa, dirn->ip);
-      }
-      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)
-        {
-          send = 1;
-          WALK_LIST(n1, ifa->neigh_list)
-          {
-            if (ipa_equal(nb->ip, n1->ip))
-            {
-              send = 0;
-              break;
-            }
-          }
-          if ((poll == 1) && (send))
-          {
-            if (toall || (meeli && nb->eligible))
-              ospf_send_to(ifa, nb->ip);
-          }
-        }
-        if (poll == 0)
-        {
-          WALK_LIST(n1, ifa->neigh_list)
-          {
-            if (toall || (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid) ||
-                (meeli && (n1->priority > 0)))
-              ospf_send_to(ifa, n1->ip);
-          }
-        }
-      }
-      break;
-    case OSPF_IT_VLINK:
-      ospf_send_to(ifa, ifa->vip);
+  case OSPF_IT_BCAST:
+  case OSPF_IT_PTP:
+    ospf_send_to(ifa, AllSPFRouters);
+    break;
+
+  case OSPF_IT_NBMA:
+    if (timer == NULL)         /* Response to received hello */
+    {
+      ospf_send_to(ifa, dirn->ip);
       break;
-    default:
-      ospf_send_to(ifa, AllSPFRouters);
+    }
+
+    int to_all = ifa->state > OSPF_IS_DROTHER;
+    int me_elig = ifa->priority > 0;
+    if (poll)                  /* Poll timer */
+    {
+      WALK_LIST(nb, ifa->nbma_list)
+       if (!nb->found && (to_all || (me_elig && nb->eligible)))
+         ospf_send_to(ifa, nb->ip);
+    }
+    else                       /* Hello timer */
+    {
+      WALK_LIST(n1, ifa->neigh_list)
+       if (to_all || (me_elig && (n1->priority > 0)) ||
+           (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid))
+         ospf_send_to(ifa, n1->ip);
+    }
+    break;
+
+  case OSPF_IT_PTMP:
+    WALK_LIST(n1, ifa->neigh_list)
+      ospf_send_to(ifa, n1->ip);
+
+    WALK_LIST(nb, ifa->nbma_list)
+      if (!nb->found)
+       ospf_send_to(ifa, nb->ip);
+
+    /* If there is no other target, we also send HELLO packet to the other end */
+    if (ipa_nonzero(ifa->addr->opposite) && !ifa->strictnbma &&
+       EMPTY_LIST(ifa->neigh_list) && EMPTY_LIST(ifa->nbma_list))
+      ospf_send_to(ifa, ifa->addr->opposite);
+    break;
+
+  case OSPF_IT_VLINK:
+    ospf_send_to(ifa, ifa->vip);
+    break;
+
+  default:
+    bug("Bug in ospf_hello_send()");
   }
 
   OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s",
index 8b21f94bbed31adfd801b10fb04d2c36f44e47cf..05442dfee6d47ce64cac92e6a61683166bb67d99 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "ospf.h"
 
-char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother",
+char *ospf_is[] = { "down", "loop", "waiting", "ptp", "drother",
   "backup", "dr"
 };
 
@@ -16,7 +16,7 @@ char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen",
   "neighbor change", "loop indicated", "unloop indicated", "interface down"
 };
 
-char *ospf_it[] = { "broadcast", "nbma", "point-to-point", "virtual link" };
+char *ospf_it[] = { "broadcast", "nbma", "ptp", "ptmp", "virtual link" };
 
 static void
 poll_timer_hook(timer * timer)
@@ -57,8 +57,18 @@ rxbufsize(struct ospf_iface *ifa)
   }
 }
 
+struct nbma_node *
+find_nbma_node_in(list *nnl, ip_addr ip)
+{
+  struct nbma_node *nn;
+  WALK_LIST(nn, *nnl)
+    if (ipa_equal(nn->ip, ip))
+      return nn;
+  return NULL;
+}
+
 static int
-ospf_sk_open(struct ospf_iface *ifa)
+ospf_sk_open(struct ospf_iface *ifa, int multicast)
 {
   sock *sk = sk_new(ifa->pool);
   sk->type = SK_IP;
@@ -106,11 +116,16 @@ ospf_sk_open(struct ospf_iface *ifa)
    */
 
   sk->saddr = ifa->addr->ip;
-  if (sk_setup_multicast(sk) < 0)
-    goto err;
+  if (multicast)
+  {
+    if (sk_setup_multicast(sk) < 0)
+      goto err;
+
+    if (sk_join_group(sk, AllSPFRouters) < 0)
+      goto err;
+  }
 
   ifa->sk = sk;
-  ifa->sk_spf = 0;
   ifa->sk_dr = 0;
   return 1;
 
@@ -119,16 +134,6 @@ ospf_sk_open(struct ospf_iface *ifa)
   return 0;
 }
 
-static inline void
-ospf_sk_join_spf(struct ospf_iface *ifa)
-{
-  if (ifa->sk_spf)
-    return;
-
-  sk_join_group(ifa->sk, AllSPFRouters);
-  ifa->sk_spf = 1;
-}
-
 static inline void
 ospf_sk_join_dr(struct ospf_iface *ifa)
 {
@@ -138,17 +143,6 @@ ospf_sk_join_dr(struct ospf_iface *ifa)
   sk_join_group(ifa->sk, AllDRouters);
   ifa->sk_dr = 1;
 }
-
-static inline void
-ospf_sk_leave_spf(struct ospf_iface *ifa)
-{
-  if (!ifa->sk_spf)
-    return;
-
-  sk_leave_group(ifa->sk, AllSPFRouters);
-  ifa->sk_spf = 0;
-}
-
 static inline void
 ospf_sk_leave_dr(struct ospf_iface *ifa)
 {
@@ -291,7 +285,7 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
     if (ifa->state <= OSPF_IS_LOOP)
     {
       /* Now, nothing should be adjacent */
-      if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK))
+      if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP) || (ifa->type == OSPF_IT_VLINK))
       {
        ospf_iface_chstate(ifa, OSPF_IS_PTP);
       }
@@ -355,11 +349,11 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
 
 }
 
-u8
-ospf_iface_clasify(struct iface *ifa, struct ifa *addr)
+static u8
+ospf_iface_classify(struct iface *ifa, struct ifa *addr)
 {
   if (ipa_nonzero(addr->opposite))
-    return OSPF_IT_PTP;
+    return (ifa->flags & IF_MULTICAST) ? OSPF_IT_PTP :  OSPF_IT_PTMP;
 
   if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
       (IF_MULTIACCESS | IF_MULTICAST))
@@ -388,12 +382,8 @@ ospf_iface_add(struct object_lock *lock)
   struct proto_ospf *po = ifa->oa->po;
   struct proto *p = &po->proto;
 
-  if (ospf_sk_open(ifa))
-  {
-    if (ifa->type != OSPF_IT_NBMA)
-      ospf_sk_join_spf(ifa);
-  }
-  else
+  int mc = (ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP);
+  if (! ospf_sk_open(ifa, mc))
   {
     log(L_ERR "%s: Socket open failed on interface %s, declaring as stub", p->name, ifa->iface->name);
     ifa->ioprob = OSPF_I_SK;
@@ -448,7 +438,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
 #endif
 
   if (ip->type == OSPF_IT_UNDEF)
-    ifa->type = ospf_iface_clasify(iface, addr);
+    ifa->type = ospf_iface_classify(iface, addr);
   else
     ifa->type = ip->type;
 
@@ -456,16 +446,28 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
   if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite))
     ifa->stub = 1;
 
+  /* Check validity of interface type */
+  int old_type = ifa->type;
+
 #ifdef OSPFv2
-  if ((ifa->type != OSPF_IT_PTP) && (ifa->type != OSPF_IT_VLINK) &&
-      (addr->flags & IA_UNNUMBERED))
-  {
-    log(L_WARN "%s: Missing proper IP prefix on interface %s, forcing point-to-point mode",
-       p->name,  iface->name);
+  if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_UNNUMBERED))
     ifa->type = OSPF_IT_PTP;
-  }
+
+  if ((ifa->type == OSPF_IT_NBMA) && (addr->flags & IA_UNNUMBERED))
+    ifa->type = OSPF_IT_PTMP;
 #endif
 
+  if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & IF_MULTICAST))
+    ifa->type = OSPF_IT_NBMA;
+
+  if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & IF_MULTICAST))
+    ifa->type = OSPF_IT_PTMP;
+
+  if (ifa->type != old_type)
+    log(L_WARN "%s: Cannot use interface %s as %s, forcing %s",
+       p->name, iface->name, ospf_it[old_type], ospf_it[ifa->type]);
+
+
   init_list(&ifa->neigh_list);
   init_list(&ifa->nbma_list);
 
@@ -477,6 +479,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
     nbma = mb_alloc(pool, sizeof(struct nbma_node));
     nbma->ip = nb->ip;
     nbma->eligible = nb->eligible;
+    nbma->found = 0;
     add_tail(&ifa->nbma_list, NODE nbma);
   }
 
@@ -766,10 +769,12 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
 void
 ospf_iface_info(struct ospf_iface *ifa)
 {
-  char *strict = "(strict)";
+  char *strict = "";
+
+  if (ifa->strictnbma &&
+      ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP)))
+    strict = "(strict)";
 
-  if ((ifa->type != OSPF_IT_NBMA) || (ifa->strictnbma == 0))
-    strict = "";
   if (ifa->type == OSPF_IT_VLINK)
   {
     cli_msg(-1015, "Virtual link to %R:", ifa->vid);
index 38a814864ebf23997d228cca8a0e8c2628ca6fa5..f9631eb3c38d45497efe01ea67fbc3bf5389e91e 100644 (file)
@@ -21,6 +21,11 @@ void ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr
 void ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa);
 void ospf_set_rxbuf_size(struct ospf_iface *ifa, u32 rxbuf);
 
+struct nbma_node *find_nbma_node_in(list *nnl, ip_addr ip);
+
+static inline struct nbma_node *
+find_nbma_node(struct ospf_iface *ifa, ip_addr ip)
+{ return find_nbma_node_in(&ifa->nbma_list, ip); }
 
 
 #endif /* _BIRD_OSPF_IFACE_H_ */
index fb757d0865d587efc7f241aa7ff83f89dc3da639..06b62ae21f1cad40d15848f8755d033128da93c3 100644 (file)
@@ -304,6 +304,13 @@ ospf_lsupd_flood(struct proto_ospf *po,
 
       switch (ifa->type)
       {
+      case OSPF_IT_BCAST:
+       if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
+         ospf_send_to(ifa, AllSPFRouters);
+       else
+         ospf_send_to(ifa, AllDRouters);
+       break;
+
       case OSPF_IT_NBMA:
        if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
          ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
@@ -311,16 +318,20 @@ ospf_lsupd_flood(struct proto_ospf *po,
          ospf_send_to_bdr(ifa);
        break;
 
+      case OSPF_IT_PTP:
+       ospf_send_to(ifa, AllSPFRouters);
+       break;
+
+      case OSPF_IT_PTMP:
+       ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
+       break;
+
       case OSPF_IT_VLINK:
        ospf_send_to(ifa, ifa->vip);
        break;
 
       default:
-       if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR) ||
-           (ifa->type == OSPF_IT_PTP))
-         ospf_send_to(ifa, AllSPFRouters);
-       else
-         ospf_send_to(ifa, AllDRouters);
+       bug("Bug in ospf_lsupd_flood()");
       }
     }
   }
index 05f024a703b9fa5ca33861fd17ac515089937e66..98c9de5076cb569e7e5107fd20b17783db233655 100644 (file)
@@ -276,6 +276,7 @@ can_do_adj(struct ospf_neighbor *n)
   switch (ifa->type)
   {
   case OSPF_IT_PTP:
+  case OSPF_IT_PTMP:
   case OSPF_IT_VLINK:
     i = 1;
     break;
@@ -531,9 +532,19 @@ struct ospf_neighbor *
 find_neigh(struct ospf_iface *ifa, u32 rid)
 {
   struct ospf_neighbor *n;
+  WALK_LIST(n, ifa->neigh_list)
+    if (n->rid == rid)
+      return n;
+  return NULL;
+}
 
-  WALK_LIST(n, ifa->neigh_list) if (n->rid == rid)
-    return n;
+struct ospf_neighbor *
+find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip)
+{
+  struct ospf_neighbor *n;
+  WALK_LIST(n, ifa->neigh_list)
+    if (ipa_equal(n->ip, ip))
+      return n;
   return NULL;
 }
 
@@ -543,7 +554,7 @@ ospf_find_area(struct proto_ospf *po, u32 aid)
   struct ospf_area *oa;
   WALK_LIST(oa, po->area_list)
     if (((struct ospf_area *) oa)->areaid == aid)
-    return oa;
+      return oa;
   return NULL;
 }
 
@@ -567,6 +578,13 @@ ospf_neigh_remove(struct ospf_neighbor *n)
   struct ospf_iface *ifa = n->ifa;
   struct proto *p = &ifa->oa->po->proto;
 
+  if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
+  {
+    struct nbma_node *nn = find_nbma_node(ifa, n->ip);
+    if (nn)
+      nn->found = 0;
+  }
+
   s_get(&(n->dbsi));
   neigh_chstate(n, NEIGHBOR_DOWN);
   rem_node(NODE n);
@@ -596,9 +614,10 @@ ospf_sh_neigh_info(struct ospf_neighbor *n)
 
   if (n->rid == ifa->drid)
     pos = "dr   ";
-  if (n->rid == ifa->bdrid)
+  else if (n->rid == ifa->bdrid)
     pos = "bdr  ";
-  if ((n->ifa->type == OSPF_IT_PTP) || (n->ifa->type == OSPF_IT_VLINK))
+  else if ((n->ifa->type == OSPF_IT_PTP) || (n->ifa->type == OSPF_IT_PTMP) ||
+          (n->ifa->type == OSPF_IT_VLINK))
     pos = "ptp  ";
 
   cli_msg(-1013, "%-1R\t%3u\t%s/%s\t%-5s\t%-10s %-1I", n->rid, n->priority,
index 5612eca1c8e27f7d77c7cbdb1201ee10bfefc053..dcaa12df2b96807ca4277a3314efb4940e3053da 100644 (file)
@@ -14,9 +14,9 @@ struct ospf_neighbor *ospf_neighbor_new(struct ospf_iface *ifa);
 void ospf_neigh_sm(struct ospf_neighbor *n, int event);
 void bdr_election(struct ospf_iface *ifa);
 struct ospf_neighbor *find_neigh(struct ospf_iface *ifa, u32 rid);
+struct ospf_neighbor *find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip);
 struct ospf_area *ospf_find_area(struct proto_ospf *po, u32 aid);
 void ospf_neigh_remove(struct ospf_neighbor *n);
 void ospf_sh_neigh_info(struct ospf_neighbor *n);
 
-
 #endif /* _BIRD_OSPF_NEIGHBOR_H_ */
index 19e68e248ed34d5b82c26b14c6aeaf3ba34f7d60..e10a405c24f392008b7744f7ef800bc46d98fba2 100644 (file)
@@ -649,7 +649,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
   struct ospf_iface *ifa;
   struct nbma_node *nb1, *nb2, *nbnx;
   struct ospf_area *oa = NULL;
-  int found, olddead, newdead;
+  int olddead, newdead;
   
   if (po->rfc1583 != new->rfc1583)
     return 0;
@@ -881,19 +881,17 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
        /* First remove old */
        WALK_LIST_DELSAFE(nb1, nbnx, ifa->nbma_list)
        {
-         found = 0;
-         WALK_LIST(nb2, newip->nbma_list)
-           if (ipa_equal(nb1->ip, nb2->ip))
+         nb2 = find_nbma_node_in(&newip->nbma_list, nb1->ip);
+         if (nb2)
          {
-           found = 1;
            if (nb1->eligible != nb2->eligible)
-             OSPF_TRACE(D_EVENTS,
-                        "Changing neighbor eligibility %I on interface %s",
+           {
+             nb1->eligible = nb2->eligible;
+             OSPF_TRACE(D_EVENTS, "Changing neighbor eligibility %I on interface %s",
                         nb1->ip, ifa->iface->name);
-           break;
+           }
          }
-
-         if (!found)
+         else
          {
            OSPF_TRACE(D_EVENTS,
                       "Removing NBMA neighbor %I on interface %s",
@@ -908,18 +906,12 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
          if (!ipa_in_net(nb2->ip, ifa->addr->prefix, ifa->addr->pxlen))
            continue;
 
-         found = 0;
-         WALK_LIST(nb1, ifa->nbma_list)
-           if (ipa_equal(nb1->ip, nb2->ip))
-         {
-           found = 1;
-           break;
-         }
-         if (!found)
+         if (find_nbma_node(ifa, nb2->ip) == NULL)
          {
            nb1 = mb_alloc(ifa->pool, sizeof(struct nbma_node));
            nb1->ip = nb2->ip;
            nb1->eligible = nb2->eligible;
+           nb1->found = !!find_neigh_by_ip(ifa, nb1->ip);
            add_tail(&ifa->nbma_list, NODE nb1);
            OSPF_TRACE(D_EVENTS,
                       "Adding NBMA neighbor %I on interface %s",
index 2ef0180c099629f26a355031f78de3bf9f11c177..e260dc0872adde051584bb5807366d889d6f5905 100644 (file)
@@ -90,7 +90,8 @@ struct nbma_node
 {
   node n;
   ip_addr ip;
-  int eligible;
+  byte eligible;
+  byte found; 
 };
 
 struct area_net_config
@@ -205,8 +206,9 @@ struct ospf_iface
 #define OSPF_IT_BCAST 0
 #define OSPF_IT_NBMA 1
 #define OSPF_IT_PTP 2
-#define OSPF_IT_VLINK 3
-#define OSPF_IT_UNDEF 4
+#define OSPF_IT_PTMP 3
+#define OSPF_IT_VLINK 4
+#define OSPF_IT_UNDEF 5
   u8 strictnbma;               /* Can I talk with unknown neighbors? */
   u8 stub;                     /* Inactive interface */
   u8 state;                    /* Interface state machine */
@@ -245,7 +247,7 @@ struct ospf_iface
 #define OSPF_I_OK 0            /* Everything OK */
 #define OSPF_I_SK 1            /* Socket open failed */
 #define OSPF_I_LL 2            /* Missing link-local address (OSPFv3) */
-  u8 sk_spf;                   /* Socket is a member of SPFRouters group */
+  // u8 sk_spf;                        /* Socket is a member of SPFRouters group */
   u8 sk_dr;                    /* Socket is a member of DRouters group */
   u16 rxbuf;                   /* Buffer size */
   u8 check_link;               /* Whether iface link change is used */
index bfc17d767b7ae2922281de2327001a867c8000d7..e8ebafd8495fe2a4f2e1d80dcf5d118db151b319 100644 (file)
@@ -240,19 +240,6 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_
  
 #endif
 
-#ifdef OSPFv2
-static inline struct ospf_neighbor *
-find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip)
-{
-  struct ospf_neighbor *n;
-  WALK_LIST(n, ifa->neigh_list)
-    if (ipa_equal(n->ip, ip))
-      return n;
-  return NULL;
-}
-#endif
-
-
 
 /**
  * ospf_rx_hook
@@ -433,7 +420,7 @@ ospf_rx_hook(sock *sk, int size)
 #ifdef OSPFv2
   /* In OSPFv2, neighbors are identified by either IP or Router ID, base on network type */
   struct ospf_neighbor *n;
-  if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA))
+  if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
     n = find_neigh_by_ip(ifa, sk->faddr);
   else
     n = find_neigh(ifa, rid);
index 5469bdcfaa3455bcad418e7118b6759e4aac8b4c..953a679a227c8ba0014596d4da9368d129ff8b96 100644 (file)
@@ -1341,12 +1341,13 @@ static inline int
 match_rtlink(struct ospf_iface *ifa, struct ospf_lsa_rt_link *rtl)
 {
 #ifdef OSPFv2
-  return (ifa->type == OSPF_IT_PTP) && (ifa->cost == rtl->metric) &&
+  return ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP)) &&
+    (ifa->cost == rtl->metric) &&
     (((ifa->addr->flags & IA_UNNUMBERED) ? ifa->iface->index :
       ipa_to_u32(ifa->addr->ip)) == rtl->data);
 #else /* OSPFv3 */
-  return (ifa->type == OSPF_IT_PTP) && (ifa->cost == rtl->metric) &&
-    (ifa->iface->index == rtl->lif);
+  return ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP)) &&
+    (ifa->cost == rtl->metric) && (ifa->iface->index == rtl->lif);
 #endif
 }
 
index bb608498239be54bfe045115ecc71855f3031c9d..dc6cd1dcd939882817fc23f452d8e729148f64ed 100644 (file)
@@ -241,24 +241,26 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
     if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
       continue;
 
+    /* RFC2328 - 12.4.1.1-4 */
     switch (ifa->type)
       {
-      case OSPF_IT_PTP:        /* RFC2328 - 12.4.1.1 */
-       neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
-       if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
-       {
-         ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
-         ln->type = LSART_PTP;
-         ln->id = neigh->rid;
-         ln->data = (ifa->addr->flags & IA_UNNUMBERED) ?
-           ifa->iface->index : ipa_to_u32(ifa->addr->ip);
-         ln->metric = ifa->cost;
-         ln->padding = 0;
-         i++;
-       }
+      case OSPF_IT_PTP:
+      case OSPF_IT_PTMP:
+       WALK_LIST(neigh, ifa->neigh_list)
+         if (neigh->state == NEIGHBOR_FULL)
+         {
+           ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
+           ln->type = LSART_PTP;
+           ln->id = neigh->rid;
+           ln->data = (ifa->addr->flags & IA_UNNUMBERED) ?
+             ifa->iface->index : ipa_to_u32(ifa->addr->ip);
+           ln->metric = ifa->cost;
+           ln->padding = 0;
+           i++;
+         }
        break;
 
-      case OSPF_IT_BCAST: /* RFC2328 - 12.4.1.2 */
+      case OSPF_IT_BCAST:
       case OSPF_IT_NBMA:
        if (bcast_net_active(ifa))
          {
@@ -273,7 +275,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
          }
        break;
 
-      case OSPF_IT_VLINK: /* RFC2328 - 12.4.1.3 */
+      case OSPF_IT_VLINK:
        neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
        if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
        {
@@ -300,7 +302,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
       continue;
 
     ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
-    if (ifa->state == OSPF_IS_LOOP)
+    if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP))
     {
       /* Host stub entry */
       ln->type = LSART_STUB;
@@ -398,9 +400,10 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
     switch (ifa->type)
       {
       case OSPF_IT_PTP:
-       neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
-       if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
-         add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
+      case OSPF_IT_PTMP:
+       WALK_LIST(neigh, ifa->neigh_list)
+         if (neigh->state == NEIGHBOR_FULL)
+           add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
        break;
 
       case OSPF_IT_BCAST:
@@ -1202,7 +1205,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
            configured_stubnet(oa, a))
          continue;
 
-       if (ifa->state == OSPF_IS_LOOP)
+       if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP))
          lsa_put_prefix(po, a->ip, MAX_PREFIX_LENGTH, 0);
        else
          lsa_put_prefix(po, a->prefix, a->pxlen, ifa->cost);