]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'dd4da6f640fb581cbd7d1ca537bf382558492b8e' into integrated
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 12 Jan 2013 23:17:49 +0000 (00:17 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Sat, 12 Jan 2013 23:17:49 +0000 (00:17 +0100)
1  2 
proto/ospf/config.Y
proto/ospf/hello.c
proto/ospf/iface.c
proto/ospf/lsalib.c
proto/ospf/lsupd.c
proto/ospf/neighbor.c
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/ospf/topology.c

Simple merge
index 08ad6f919a7daee0e8cd433414d9e55c49ed116b,6ec5c511bec88576247b00242584ef936af4d2b1..c25187087effebc7edde7c4e25251ec74edccfc4
@@@ -258,55 -242,51 +258,55 @@@ ospf_hello_send(struct ospf_iface *ifa
    DBG("%s: Hello/Poll timer fired on interface %s with IP %I\n",
        p->name, ifa->iface->name, ifa->addr->ip);
  
 -  /* Now we should send a hello packet */
    pkt = ospf_tx_buffer(ifa);
 -  op = &pkt->ospf_packet;
 -
 -  /* Now fill ospf_hello header */
    ospf_pkt_fill_hdr(ifa, pkt, HELLO_P);
  
 -#ifdef OSPFv2
 -  pkt->netmask = ipa_mkmask(ifa->addr->pxlen);
 -  ipa_hton(pkt->netmask);
 -  if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP))
 -    pkt->netmask = IPA_NONE;
 -#endif
 -
 -  pkt->helloint = ntohs(ifa->helloint);
 -  pkt->priority = ifa->priority;
 -
 -#ifdef OSPFv3
 -  pkt->iface_id = htonl(ifa->iface_id);
 -
 -  pkt->options3 = ifa->oa->options >> 16;
 -  pkt->options2 = ifa->oa->options >> 8;
 -#endif
 -  pkt->options = ifa->oa->options;
 -
 -#ifdef OSPFv2
 -  pkt->deadint = htonl(ifa->deadint);
 -  pkt->dr = htonl(ipa_to_u32(ifa->drip));
 -  pkt->bdr = htonl(ipa_to_u32(ifa->bdrip));
 -#else /* OSPFv3 */
 -  pkt->deadint = htons(ifa->deadint);
 -  pkt->dr = htonl(ifa->drid);
 -  pkt->bdr = htonl(ifa->bdrid);
 -#endif
 +  if (ospf_is_v2(po))
 +  {
 +    struct ospf_hello2_packet *ps = (void *) pkt;
 +
 +    ps->netmask = htonl(u32_mkmask(ifa->addr->pxlen));
 +
 +    if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP))
 +      ps->netmask = 0;
 +
 +    ps->helloint = ntohs(ifa->helloint);
 +    ps->options = ifa->oa->options;
 +    ps->priority = ifa->priority;
 +    ps->deadint = htonl(ifa->deadint);
 +    ps->dr = htonl(ipa_to_u32(ifa->drip));
 +    ps->bdr = htonl(ipa_to_u32(ifa->bdrip));
 +
 +    length = sizeof(struct ospf_hello2_packet);
 +    neighbors = ps->neighbors;
 +  }
 +  else
 +  {
 +    struct ospf_hello3_packet *ps = (void *) pkt;
 +
-     ps->iface_id = htonl(ifa->iface->index);
++    ps->iface_id = htonl(ifa->iface_id);
 +    ps->priority = ifa->priority;
 +    ps->options3 = ifa->oa->options >> 16;
 +    ps->options2 = ifa->oa->options >> 8;
 +    ps->options = ifa->oa->options;
 +    ps->helloint = ntohs(ifa->helloint);
 +    ps->deadint = htons(ifa->deadint);
 +    ps->dr = htonl(ifa->drid);
 +    ps->bdr = htonl(ifa->bdrid);
 +
 +    length = sizeof(struct ospf_hello3_packet);
 +    neighbors = ps->neighbors;
 +  }
  
 -  /* Fill all neighbors */
    i = 0;
 +  max = (ospf_pkt_bufsize(ifa) - length) / sizeof(u32);
  
 +  /* Fill all neighbors */
    if (kind != OHS_SHUTDOWN)
    {
 -    u32 *pp = (u32 *) (((u8 *) pkt) + sizeof(struct ospf_hello_packet));
      WALK_LIST(neigh, ifa->neigh_list)
      {
 -      if ((i+1) * sizeof(u32) + sizeof(struct ospf_hello_packet) > ospf_pkt_bufsize(ifa))
 +      if (i == max)
        {
        log(L_WARN "%s: Too many neighbors on interface %s", p->name, ifa->iface->name);
        break;
index 10f87e51fb3f47815d1c8dce2d4c28f747116bdd,aa7f7892726daa4b18bb6cf08de9cadbe96d70d8..cfd2219a7f95bb19d75f7740b61d7bcacf6b0bf9
@@@ -558,8 -565,10 +558,10 @@@ ospf_iface_new(struct ospf_area *oa, st
  
    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]);
 +      po->proto.name, iface->name, ospf_it[old_type], ospf_it[ifa->type]);
  
+   /* Assign iface ID, for vlinks, this is ugly hack */
+   ifa->iface_id = (ifa->type != OSPF_IT_VLINK) ? iface->index : oa->po->last_vlink_id++;
  
    init_list(&ifa->neigh_list);
    init_list(&ifa->nbma_list);
index 51a407459af1ab603a098b6853ee861bbd2c8ad7,bcf7bcdddf3e3a7242d61b8b9d221514c1eb27c5..f2857c6014593356dd34a84a78cc60eb98c24f8c
@@@ -135,95 -144,6 +135,98 @@@ lsa_ntoh_body(void *n, void *h, u16 len
  }
  #endif /* little endian */
  
- {    
 +
 +
 +int
 +lsa_flooding_allowed(u32 type, u32 domain, struct ospf_iface *ifa)
++{   
++  /* Handle inactive vlinks */
++  if (ifa->state == OSPF_IS_DOWN)
++    return 0;
++ 
 +  /* 4.5.2 (Case 2) */
-     return ifa->iface->index == domain;
 +  switch (LSA_SCOPE(type))
 +  {
 +  case LSA_SCOPE_LINK:
-     *domain = ifa->iface->index;
++    return ifa->iface_id == domain;
 +
 +  case LSA_SCOPE_AREA:
 +    return ifa->oa->areaid == domain;
 +
 +  case LSA_SCOPE_AS:
 +    if (ifa->type == OSPF_IT_VLINK)
 +      return 0;
 +    if (!oa_is_ext(ifa->oa))
 +      return 0;
 +    return 1;
 +
 +  default:
 +    log(L_ERR "OSPF: LSA with invalid scope");
 +    return 0;
 +  }
 +}
 +
 +
 +static int
 +unknown_lsa_type(u32 type)
 +{
 +  switch (type)
 +  {
 +  case LSA_T_RT:
 +  case LSA_T_NET:
 +  case LSA_T_SUM_NET:
 +  case LSA_T_SUM_RT:
 +  case LSA_T_EXT:
 +  case LSA_T_NSSA:
 +  case LSA_T_LINK:
 +  case LSA_T_PREFIX:
 +    return 0;
 +
 +  default:
 +    return 1;
 +  }
 +}
 +
 +#define LSA_V2_TMAX 8
 +static const u16 lsa_v2_types[LSA_V2_TMAX] =
 +  {0, LSA_T_RT, LSA_T_NET, LSA_T_SUM_NET, LSA_T_SUM_RT, LSA_T_EXT, 0, LSA_T_NSSA};
 +
 +void
 +lsa_xxxxtype(u32 itype, struct ospf_iface *ifa, u32 *otype, u32 *domain)
 +{
 +  if (ospf_is_v2(ifa->oa->po))
 +  {
 +    itype = itype & LSA_T_V2_MASK;
 +    itype = (itype < LSA_V2_TMAX) ? lsa_v2_types[itype] : 0;
 +  }
 +  else
 +  {
 +    /* For unkown LSAs without U-bit change scope to LSA_SCOPE_LINK */
 +    if (unknown_lsa_type(itype) && !(itype & LSA_UBIT))
 +      itype = itype & ~LSA_SCOPE_MASK;
 +  }
 +
 +  *otype = itype;
 +
 +  switch (LSA_SCOPE(itype))
 +  {
 +  case LSA_SCOPE_LINK:
++    *domain = ifa->iface_id;
 +    return;
 +
 +  case LSA_SCOPE_AREA:
 +    *domain = ifa->oa->areaid;
 +    return;
 +
 +  case LSA_SCOPE_AS:
 +  default:
 +    *domain = 0;
 +    return;
 +  }
 +}
 +
 +
 +
  /*
  void
  buf_dump(const char *hdr, const byte *buf, int blen)
index 80c9b0b2ed22d741925eb8dcf93db0fb1424a01a,a5da4251dae7ab7988ec60e3364f062c6db7c654..94e1b743b113dc8d70aa48982e1de45706e559b7
@@@ -93,7 -67,82 +93,6 @@@ static void ospf_lsupd_dump(struct prot
      }
  }
  
 -
 -#ifdef OSPFv2
 -
 -int
 -ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa)
 -{
 -  if (lsa->type == LSA_T_EXT)
 -    {
 -      if (ifa->type == OSPF_IT_VLINK)
 -      return 0;
 -      if (!oa_is_ext(ifa->oa))
 -      return 0;
 -      return 1;
 -    }
 -  else
 -    return ifa->oa->areaid == domain;
 -}
 -
 -#else /* OSPFv3 */
 -
 -static int
 -unknown_lsa_type(struct ospf_lsa_header *lsa)
 -{
 -  switch (lsa->type)
 -    {
 -    case LSA_T_RT:
 -    case LSA_T_NET:
 -    case LSA_T_SUM_NET:
 -    case LSA_T_SUM_RT:
 -    case LSA_T_EXT:
 -    case LSA_T_NSSA:
 -    case LSA_T_LINK:
 -    case LSA_T_PREFIX:
 -      return 0;
 -
 -    default:
 -      return 1;
 -    }
 -}
 -
 -int
 -ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa)
 -{    
 -  u32 scope = LSA_SCOPE(lsa);
 -
 -  /* Handle inactive vlinks */
 -  if (ifa->state == OSPF_IS_DOWN)
 -    return 0;
 -
 -  /* 4.5.2 (Case 2) */
 -  if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT))
 -    scope = LSA_SCOPE_LINK;
 -
 -  switch (scope)
 -    {
 -    case LSA_SCOPE_LINK:
 -      return ifa->iface_id == domain;
 -
 -    case LSA_SCOPE_AREA:
 -      return ifa->oa->areaid == domain;
 -
 -    case LSA_SCOPE_AS:
 -      if (ifa->type == OSPF_IT_VLINK)
 -      return 0;
 -      if (!oa_is_ext(ifa->oa))
 -      return 0;
 -      return 1;
 -
 -    default:
 -      log(L_ERR "LSA with invalid scope");
 -      return 0;
 -    }
 -}
 -
 -#endif
--
  /**
   * ospf_lsupd_flood - send received or generated lsa to the neighbors
   * @po: OSPF protocol
index 118919d49cdfb1627e3b67ea32c83ed4a41033f5,26d81dcebf86b8fce22c3a7af63035fd1c9ab5db..228e02d282aab5edd7d194eb8565f90dd16e3f5c
@@@ -442,9 -453,14 +442,9 @@@ bdr_election(struct ospf_iface *ifa
    me.priority = ifa->priority;
    me.ip = ifa->addr->ip;
  
 -#ifdef OSPFv2
 -  me.dr = ipa_to_u32(ifa->drip);
 -  me.bdr = ipa_to_u32(ifa->bdrip);
 -#else /* OSPFv3 */
 -  me.dr = ifa->drid;
 -  me.bdr = ifa->bdrid;
 +  me.dr  = ospf_is_v2(po) ? ipa_to_u32(ifa->drip) : ifa->drid;
 +  me.bdr = ospf_is_v2(po) ? ipa_to_u32(ifa->bdrip) : ifa->bdrid;
-   me.iface_id = ifa->iface->index;
+   me.iface_id = ifa->iface_id;
 -#endif
  
    add_tail(&ifa->neigh_list, NODE & me);
  
index 9a7eaa63bb5635a3f922d899eac6fee3f18a5f87,6654e107cbd09226362031c27322cd7e9c0223a5..0b5de651ba8094e278589cbfd328c5c35e72e9c2
@@@ -935,70 -949,80 +936,85 @@@ static int lsa_compare_ospf3
  static int
  lsa_compare_for_state(const void *p1, const void *p2)
  {
 -  struct top_hash_entry * he1 = * (struct top_hash_entry **) p1;
 -  struct top_hash_entry * he2 = * (struct top_hash_entry **) p2;
 +  struct top_hash_entry *he1 = * (struct top_hash_entry **) p1;
 +  struct top_hash_entry *he2 = * (struct top_hash_entry **) p2;
    struct ospf_lsa_header *lsa1 = &(he1->lsa);
    struct ospf_lsa_header *lsa2 = &(he2->lsa);
 +  struct ospf_lsa_header lsatmp1, lsatmp2;
 +  u16 lsa1_type = he1->lsa_type;
 +  u16 lsa2_type = he2->lsa_type;
  
-   if (he1->domain != he2->domain)
-     return he1->domain - he2->domain;
+   if (he1->domain < he2->domain)
+     return -1;
+   if (he1->domain > he2->domain)
+     return 1;
  
 -#ifdef OSPFv3
 -  struct ospf_lsa_header lsatmp1, lsatmp2;
  
 -  int px1 = (lsa1->type == LSA_T_PREFIX);
 -  int px2 = (lsa2->type == LSA_T_PREFIX);
 +  /* px1 or px2 assumes OSPFv3 */
 +  int px1 = (lsa1_type == LSA_T_PREFIX);
 +  int px2 = (lsa2_type == LSA_T_PREFIX);
  
    if (px1)
 +  {
      lsa1 = fake_lsa_from_prefix_lsa(&lsatmp1, lsa1, he1->lsa_body);
 +    lsa1_type = lsa1->type_raw;       /* FIXME: handle unknown ref_type */
 +  }
  
    if (px2)
 +  {
      lsa2 = fake_lsa_from_prefix_lsa(&lsatmp2, lsa2, he2->lsa_body);
 -#endif
 +    lsa2_type = lsa2->type_raw;
 +  }
  
 -  int nt1 = (lsa1->type == LSA_T_NET);
 -  int nt2 = (lsa2->type == LSA_T_NET);
 +
 +  int nt1 = (lsa1_type == LSA_T_NET);
 +  int nt2 = (lsa2_type == LSA_T_NET);
  
    if (nt1 != nt2)
      return nt1 - nt2;
  
    if (nt1)
    {
 -#ifdef OSPFv3
 -    /* In OSPFv3, neworks are named base on ID of DR */
 -    if (lsa1->rt < lsa2->rt)
 -      return -1;
 -    if (lsa1->rt > lsa2->rt)
 -      return 1;
 -#endif
 +    /* In OSPFv3, networks are named based on ID of DR */
-     if (lsa_compare_ospf3 && (lsa1->rt != lsa2->rt))
-       return lsa1->rt - lsa2->rt;
++    if (lsa_compare_ospf3)
++    {
++      if (lsa1->rt < lsa2->rt)
++      return -1;
++      if (lsa1->rt > lsa2->rt)
++      return 1;
++    }
  
      /* For OSPFv2, this is IP of the network,
         for OSPFv3, this is interface ID */
-     if (lsa1->id != lsa2->id)
-       return lsa1->id - lsa2->id;
+     if (lsa1->id < lsa2->id)
+       return -1;
+     if (lsa1->id > lsa2->id)
+       return 1;
  
 -#ifdef OSPFv3
      if (px1 != px2)
        return px1 - px2;
 -#endif
  
      return lsa1->sn - lsa2->sn;
    }
    else 
    {
-     if (lsa1->rt != lsa2->rt)
-       return lsa1->rt - lsa2->rt;
+     if (lsa1->rt < lsa2->rt)
+       return -1;
+     if (lsa1->rt > lsa2->rt)
+       return 1;
  
-     if (lsa1_type != lsa2_type)
-       return lsa1_type - lsa2_type;
-   
-     if (lsa1->id != lsa2->id)
-       return lsa1->id - lsa2->id;
 -    if (lsa1->type < lsa2->type)
++    if (lsa1_type < lsa2_type)
+       return -1;
 -    if (lsa1->type > lsa2->type)
++    if (lsa1_type > lsa2_type)
+       return 1;
+     if (lsa1->id < lsa2->id)
+       return -1;
+     if (lsa1->id > lsa2->id)
+       return 1;
  
 -#ifdef OSPFv3
      if (px1 != px2)
        return px1 - px2;
 -#endif
    
      return lsa1->sn - lsa2->sn;
    }
Simple merge
index 91b7810ab3bb7b3e41b14f9942402acaa262620b,177cd53ac0499e5446e428f6dc31c6fa6bde17d5..ea1e8f1b711697135224e6bb5b4fb5d0ce5350f5
@@@ -262,8 -255,13 +262,8 @@@ originate_rt2_lsa_body(struct ospf_are
        WALK_LIST(neigh, ifa->neigh_list)
          if (neigh->state == NEIGHBOR_FULL)
          {
-           u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface->index : ipa_to_u32(ifa->addr->ip);
 -          ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
 -          ln->type = LSART_PTP;
 -          ln->id = neigh->rid;
 -          ln->data = (ifa->addr->flags & IA_PEER) ?
 -            ifa->iface_id : ipa_to_u32(ifa->addr->ip);
 -          ln->metric = ifa->cost;
 -          ln->padding = 0;
++          u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface_id : ipa_to_u32(ifa->addr->ip);
 +          add_rt2_lsa_link(po, LSART_PTP, neigh->rid, data, ifa->cost);
            i++;
          }
        break;
@@@ -514,10 -545,11 +514,10 @@@ originate_net3_lsa_body(struct proto_os
    {
      if (n->state == NEIGHBOR_FULL)
      {
 -#ifdef OSPFv3
 +      /* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */
-       en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK);
+       en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK);
        if (en)
        options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
 -#endif
  
        net->routers[i] = n->rid;
        i++;
@@@ -560,13 -590,19 +560,13 @@@ originate_net_lsa(struct ospf_iface *if
             ifa->iface->name);
  
    lsa.age = 0;
 -  lsa.type = LSA_T_NET;
 -
 -#ifdef OSPFv2
 -  lsa.options = ifa->oa->options;
 -  lsa.id = ipa_to_u32(ifa->addr->ip);
 -#else /* OSPFv3 */
 -  lsa.id = ifa->iface_id;
 -#endif
 -
 +  lsa.type_raw = LSA_T_NET;
-   lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface->index;
++  lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id;
    lsa.rt = po->router_id;
    lsa.sn = get_seqnum(ifa->net_lsa);
 +  lsa_fix_options(po, &lsa, ifa->oa->options);
  
 -  body = originate_net_lsa_body(ifa, &lsa.length, po);
 +  body = originate_net_lsa_body(po, ifa, &lsa.length);
    lsasum_calculate(&lsa, body);
    ifa->net_lsa = lsa_install_new(po, &lsa, dom, body);
    ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
@@@ -1183,19 -1197,20 +1183,19 @@@ originate_link_lsa_body(struct ospf_ifa
  void
  originate_link_lsa(struct ospf_iface *ifa)
  {
 -  struct ospf_lsa_header lsa;
    struct proto_ospf *po = ifa->oa->po;
 -  struct proto *p = &po->proto;
 +  struct ospf_lsa_header lsa;
-   u32 dom = ifa->iface->index;
++  u32 dom = ifa->iface_id;
    void *body;
  
    /* FIXME check for vlink and skip that? */
    OSPF_TRACE(D_EVENTS, "Originating link-LSA for iface %s", ifa->iface->name);
  
    lsa.age = 0;
 -  lsa.type = LSA_T_LINK;
 +  lsa.type_raw = LSA_T_LINK;
-   lsa.id = ifa->iface->index;
+   lsa.id = ifa->iface_id;
    lsa.rt = po->router_id;
    lsa.sn = get_seqnum(ifa->link_lsa);
 -  u32 dom = ifa->iface_id;
  
    body = originate_link_lsa_body(ifa, &lsa.length);
    lsasum_calculate(&lsa, body);
@@@ -1464,10 -1492,11 +1486,10 @@@ originate_prefix_net_lsa(struct ospf_if
             ifa->iface->name);
  
    lsa.age = 0;
 -  lsa.type = LSA_T_PREFIX;
 +  lsa.type_raw = LSA_T_PREFIX;
-   lsa.id = ifa->iface->index;
+   lsa.id = ifa->iface_id;
    lsa.rt = po->router_id;
    lsa.sn = get_seqnum(ifa->pxn_lsa);
 -  u32 dom = ifa->oa->areaid;
  
    body = originate_prefix_net_lsa_body(ifa, &lsa.length);
    lsasum_calculate(&lsa, body);