]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'f623ab9875cad2d129f708e95021d3a252930000' into integrated
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 30 Jul 2013 19:59:36 +0000 (21:59 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 30 Jul 2013 19:59:36 +0000 (21:59 +0200)
Conflicts:

proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/rt.c
proto/ospf/topology.c

1  2 
proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/ospf/rt.c
proto/ospf/topology.c

index 2f1ee624e88042a2b390dadbedf70fde09a6a3c6,ba050d852a18e9c06373dc3521baa3ba61e562b3..b43ef8a88c0a1048c242ed29a76d46fbd16a0db0
@@@ -148,7 -158,8 +148,8 @@@ ospf_proto
  ospf_proto_item:
     proto_item
   | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
 - | ECMP bool { OSPF_CFG->ecmp = $2 ? DEFAULT_ECMP_LIMIT : 0; }
+  | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
 + | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; }
   | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); }
   | TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); }
   | ospf_area
index bfd7777d7ffcc658ac45058c97af7e68c0b37321,2fa872017924d4e672819336e28c4e6b1ba0054c..43e24805144ccbc6d26007add644bdb5864dc6bb
@@@ -164,7 -164,11 +164,10 @@@ ospf_area_add(struct proto_ospf *po, st
    if (oa->areaid == 0)
      po->backbone = oa;
  
-   oa->options = ospf_is_v2(po) ? ac->type : (OPT_R | ac->type | OPT_V6);
 -#ifdef OSPFv2
 -  oa->options = ac->type;
 -#else /* OSPFv3 */
 -  oa->options = ac->type | OPT_V6 | (po->stub_router ? 0 : OPT_R);
 -#endif
++  if (ospf_is_v2(po))
++    oa->options = ac->type;
++  else
++    oa->options = ac->type | OPT_V6 | (po->stub_router ? 0 : OPT_R);
  
    /*
     * Set E-bit for NSSA ABR routers. No need to explicitly call
@@@ -678,8 -688,11 +682,11 @@@ ospf_area_reconfigure(struct ospf_area 
    oa->ac = nac;
  
    // FIXME better area type reconfiguration
-   oa->options = ospf_is_v2(oa->po) ? nac->type : (OPT_R | nac->type | OPT_V6);
 -#ifdef OSPFv2
 -  oa->options = nac->type;
 -#else /* OSPFv3 */
 -  oa->options = nac->type | OPT_V6 | (oa->po->stub_router ? 0 : OPT_R);
 -#endif
++  if (ospf_is_v2(po))
++    oa->options = nac->type;
++  else
++    oa->options = nac->type | OPT_V6 | (oa->po->stub_router ? 0 : OPT_R);
 +
    if (oa_is_nssa(oa) && (oa->po->areano > 1))
      oa->po->ebit = 1;
  
index 90acc5c6598e47e086fc79fce28c904af2983dc5,7608225ff224782a4cd1c0c78e98ee653e4ee746..b5ecc4359c949e6f7471510ba5576a20815a8086
@@@ -70,10 -82,10 +70,11 @@@ struct ospf_confi
  {
    struct proto_config c;
    unsigned tick;
 +  byte ospf2;
    byte rfc1583;
+   byte stub_router;
    byte abr;
 -  int ecmp;
 +  byte ecmp;
    list area_list;             /* list of struct ospf_area_config */
    list vlink_list;            /* list of struct ospf_iface_patt */
  };
@@@ -708,8 -771,8 +709,9 @@@ struct proto_osp
    list area_list;
    int areano;                 /* Number of area I belong to */
    struct fib rtf;             /* Routing table */
 +  byte ospf2;                 /* OSPF v2 or v3 */
    byte rfc1583;                       /* RFC1583 compatibility */
+   byte stub_router;           /* Do not forward transit traffic */
    byte ebit;                  /* Did I originate any ext lsa? */
    byte ecmp;                  /* Maximal number of nexthops in ECMP route, or 0 */
    struct ospf_area *backbone; /* If exists */
diff --cc proto/ospf/rt.c
index bf9b2adf81f1a109f7b02a3bd9a3db0d8f1689ee,f509b8965465711133010c5aaa0b4319a6138d1a..51fbf66c1f855b639331f802f902ab646cc2c711
@@@ -288,114 -294,21 +288,118 @@@ add_network(struct ospf_area *oa, ip_ad
       */
  
      struct ospf_iface *ifa;
 -#ifdef OSPFv2
 -    ifa = rt_pos_to_ifa(oa, pos);
 -#else /* OSPFv3 */
 -    ifa = px_pos_to_ifa(oa, pos);
 -#endif
 +    ifa = ospf_is_v2(po) ? rt_pos_to_ifa(oa, pos) : px_pos_to_ifa(oa, pos);
 +    nf.nhs = ifa ? new_nexthop(po, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL;
 +  }
  
 -    nf.nhs = ifa ? new_nexthop(oa->po, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL;
 +  ri_install_net(po, px, pxlen, &nf);
 +}
 +
 +
 +
 +static inline void
 +spfa_process_rt(struct ospf_area *oa, struct top_hash_entry *act)
 +{
 +  struct proto_ospf *po = oa->po;
 +  struct ospf_lsa_rt *rt = act->lsa_body;
 +  struct ospf_lsa_rt_walk rtl;
 +  struct top_hash_entry *tmp;
 +  ip_addr prefix;
 +  int pxlen, i;
 +
 +  if (rt->options & OPT_RT_V)
 +    oa->trcap = 1;
 +
 +  /*
 +   * In OSPFv3, all routers are added to per-area routing
 +   * tables. But we use it just for ASBRs and ABRs. For the
 +   * purpose of the last step in SPF - prefix-LSA processing in
 +   * spfa_process_prefixes(), we use information stored in LSA db.
 +   */
 +  if (((rt->options & OPT_RT_E) || (rt->options & OPT_RT_B))
 +      && (act->lsa.rt != po->router_id))
 +  {
 +    orta nf = {
 +      .type = RTS_OSPF,
 +      .options = rt->options,
 +      .metric1 = act->dist,
 +      .metric2 = LSINFINITY,
 +      .tag = 0,
 +      .rid = act->lsa.rt,
 +      .oa = oa,
 +      .nhs = act->nhs
 +    };
 +    ri_install_rt(oa, act->lsa.rt, &nf);
    }
  
 -  ri_install_net(oa->po, px, pxlen, &nf);
++  /* Errata 2078 to RFC 5340 4.8.1 - skip links from non-routing nodes */
++  if (ospf_is_v3(po) && (act != oa->rt) && !(rt->options & OPT_R))
++    break;
++
 +  /* Now process Rt links */
 +  for (lsa_walk_rt_init(po, act, &rtl), i = 0; lsa_walk_rt(&rtl); i++)
 +  {
 +    tmp = NULL;
 +
 +    switch (rtl.type)
 +    {
 +    case LSART_STUB:
 +
 +      /* Should not happen, LSART_STUB is not defined in OSPFv3 */
 +      if (ospf_is_v3(po))
 +      break;
 +
 +      /*
 +       * RFC 2328 in 16.1. (2a) says to handle stub networks in an
 +       * second phase after the SPF for an area is calculated. We get
 +       * the same result by handing them here because add_network()
 +       * will keep the best (not the first) found route.
 +       */
 +      prefix = ipa_from_u32(rtl.id & rtl.data);
 +      pxlen = u32_masklen(rtl.data);
 +      add_network(oa, prefix, pxlen, act->dist + rtl.metric, act, i);
 +      break;
 +
 +    case LSART_NET:
 +      tmp = ospf_hash_find_net(po->gr, oa->areaid, rtl.id, rtl.nif);
 +      break;
 +
 +    case LSART_VLNK:
 +    case LSART_PTP:
 +      tmp = ospf_hash_find_rt(po->gr, oa->areaid, rtl.id);
 +      break;
 +    }
 +
 +    add_cand(&oa->cand, tmp, act, act->dist + rtl.metric, oa, i);
 +  }
  }
  
 -#ifdef OSPFv3
 -static void
 -process_prefixes(struct ospf_area *oa)
 +static inline void
 +spfa_process_net(struct ospf_area *oa, struct top_hash_entry *act)
 +{
 +  struct proto_ospf *po = oa->po;
 +  struct ospf_lsa_net *ln = act->lsa_body;
 +  struct top_hash_entry *tmp;
 +  ip_addr prefix;
 +  int pxlen, i, cnt;
 +
 +  if (ospf_is_v2(po))
 +  {
 +    prefix = ipa_from_u32(act->lsa.id & ln->optx);
 +    pxlen = u32_masklen(ln->optx);
 +    add_network(oa, prefix, pxlen, act->dist, act, -1);
 +  }
 +
 +  cnt = lsa_net_count(&act->lsa);
 +  for (i = 0; i < cnt; i++)
 +  {
 +    tmp = ospf_hash_find_rt(po->gr, oa->areaid, ln->routers[i]);
 +    add_cand(&oa->cand, tmp, act, act->dist, oa, -1);
 +  }
 +}
 +
 +static inline void
 +spfa_process_prefixes(struct ospf_area *oa)
  {
    struct proto_ospf *po = oa->po;
    // struct proto *p = &po->proto;
@@@ -1711,13 -1839,14 +1715,13 @@@ add_cand(list * l, struct top_hash_entr
    if (en->lsa.age == LSA_MAXAGE)
      return;
  
 -#ifdef OSPFv3
 -  if (en->lsa.type == LSA_T_RT)
 -    {
 -      struct ospf_lsa_rt *rt = en->lsa_body;
 -      if (!(rt->options & OPT_V6))
 -      return;
 -    }
 -#endif
 +  if (ospf_is_v3(po) && (en->lsa_type == LSA_T_RT))
-     {
-       /* In OSPFv3, check V6 and R flags */
-       struct ospf_lsa_rt *rt = en->lsa_body;
-       if (!(rt->options & OPT_V6) || !(rt->options & OPT_R))
-       return;
-     }
++  {
++    /* In OSPFv3, check V6 flag */
++    struct ospf_lsa_rt *rt = en->lsa_body;
++    if (!(rt->options & OPT_V6))
++      return;
++  }
  
    /* 16.1. (2c) */
    if (en->color == INSPF)
index f8637fdc5964631f1440c7c02a937344ca6bb139,5d93c0e987aae344d79cc6623d8e273be8ef0ccb..df7b63c6e97b0f8ed6a2e2a480ab49d69d79a02c
@@@ -249,7 -268,9 +250,7 @@@ prepare_rt2_lsa_body(struct proto_ospf 
             * compatibility with some broken implementations that use
             * this address as a next-hop.
             */
-           add_rt2_lsa_link(po, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), ifa->cost);
 -          ln->data = ipa_to_u32(ifa->addr->ip);
 -          ln->metric = link_cost;
 -          ln->padding = 0;
++          add_rt2_lsa_link(po, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost);
            i++;
          }
        break;
        case OSPF_IT_NBMA:
        if (bcast_net_active(ifa))
          {
-           add_rt2_lsa_link(po, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), ifa->cost);
 -          ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
 -          ln->type = LSART_NET;
 -          ln->id = ipa_to_u32(ifa->drip);
 -          ln->data = ipa_to_u32(ifa->addr->ip);
 -          ln->metric = link_cost;
 -          ln->padding = 0;
++          add_rt2_lsa_link(po, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), link_cost);
            i++;
            net_lsa = 1;
          }
        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))
-         add_rt2_lsa_link(po, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), ifa->cost), i++;
 -      {
 -        ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
 -        ln->type = LSART_VLNK;
 -        ln->id = neigh->rid;
 -        ln->data = ipa_to_u32(ifa->addr->ip);
 -        ln->metric = link_cost;
 -        ln->padding = 0;
 -        i++;
 -        }
++        add_rt2_lsa_link(po, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost), i++;
          break;
  
        default: