Annotation of embedaddon/bird/proto/ospf/rt.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     BIRD -- OSPF
                      3:  *
                      4:  *     (c) 2000--2004 Ondrej Filip <feela@network.cz>
                      5:  *     (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
                      6:  *     (c) 2009--2014 CZ.NIC z.s.p.o.
                      7:  *
                      8:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      9:  */
                     10: 
                     11: #include "ospf.h"
                     12: 
                     13: static void add_cand(list * l, struct top_hash_entry *en,
                     14:                     struct top_hash_entry *par, u32 dist,
                     15:                     struct ospf_area *oa, int i);
                     16: static void rt_sync(struct ospf_proto *p);
                     17: 
                     18: 
                     19: static inline void reset_ri(ort *ort)
                     20: {
                     21:   bzero(&ort->n, sizeof(orta));
                     22: }
                     23: 
                     24: void
                     25: ospf_rt_initort(struct fib_node *fn)
                     26: {
                     27:   ort *ri = (ort *) fn;
                     28:   reset_ri(ri);
                     29:   ri->old_rta = NULL;
                     30:   ri->fn.flags = 0;
                     31: }
                     32: 
                     33: static inline int
                     34: nh_is_vlink(struct mpnh *nhs)
                     35: {
                     36:   return !nhs->iface;
                     37: }
                     38: 
                     39: static inline int
                     40: unresolved_vlink(ort *ort)
                     41: {
                     42:   return ort->n.nhs && nh_is_vlink(ort->n.nhs);
                     43: }
                     44: 
                     45: static inline struct mpnh *
                     46: new_nexthop(struct ospf_proto *p, ip_addr gw, struct iface *iface, byte weight)
                     47: {
                     48:   struct mpnh *nh = lp_alloc(p->nhpool, sizeof(struct mpnh));
                     49:   nh->gw = gw;
                     50:   nh->iface = iface;
                     51:   nh->next = NULL;
                     52:   nh->weight = weight;
                     53:   return nh;
                     54: }
                     55: 
                     56: /* Returns true if there are device nexthops in n */
                     57: static inline int
                     58: has_device_nexthops(const struct mpnh *n)
                     59: {
                     60:   for (; n; n = n->next)
                     61:     if (ipa_zero(n->gw))
                     62:       return 1;
                     63: 
                     64:   return 0;
                     65: }
                     66: 
                     67: /* Replace device nexthops with nexthops to gw */
                     68: static struct mpnh *
                     69: fix_device_nexthops(struct ospf_proto *p, const struct mpnh *n, ip_addr gw)
                     70: {
                     71:   struct mpnh *root1 = NULL;
                     72:   struct mpnh *root2 = NULL;
                     73:   struct mpnh **nn1 = &root1;
                     74:   struct mpnh **nn2 = &root2;
                     75: 
                     76:   if (!p->ecmp)
                     77:     return new_nexthop(p, gw, n->iface, n->weight);
                     78: 
                     79:   /* This is a bit tricky. We cannot just copy the list and update n->gw,
                     80:      because the list should stay sorted, so we create two lists, one with new
                     81:      gateways and one with old ones, and then merge them. */
                     82: 
                     83:   for (; n; n = n->next)
                     84:   {
                     85:     struct mpnh *nn = new_nexthop(p, ipa_zero(n->gw) ? gw : n->gw, n->iface, n->weight);
                     86: 
                     87:     if (ipa_zero(n->gw))
                     88:     {
                     89:       *nn1 = nn;
                     90:       nn1 = &(nn->next);
                     91:     }
                     92:     else
                     93:     {
                     94:       *nn2 = nn;
                     95:       nn2 = &(nn->next);
                     96:     }
                     97:   }
                     98: 
                     99:   return mpnh_merge(root1, root2, 1, 1, p->ecmp, p->nhpool);
                    100: }
                    101: 
                    102: 
                    103: /* Whether the ASBR or the forward address destination is preferred
                    104:    in AS external route selection according to 16.4.1. */
                    105: static inline int
                    106: epath_preferred(const orta *ep)
                    107: {
                    108:   return (ep->type == RTS_OSPF) && (ep->oa->areaid != 0);
                    109: }
                    110: 
                    111: /* Whether the ext route has ASBR/next_hop marked as preferred. */
                    112: static inline int
                    113: orta_pref(const orta *nf)
                    114: {
                    115:   return !!(nf->options & ORTA_PREF);
                    116: }
                    117: 
                    118: /* Classify orta entries according to RFC 3101 2.5 (6e) priorities:
                    119:    Type-7 LSA with P-bit, Type-5 LSA, Type-7 LSA without P-bit */
                    120: static int
                    121: orta_prio(const orta *nf)
                    122: {
                    123:   /* RFC 3103 2.5 (6e) priorities */
                    124:   u32 opts = nf->options & (ORTA_NSSA | ORTA_PROP);
                    125: 
                    126:   /* A Type-7 LSA with the P-bit set */
                    127:   if (opts == (ORTA_NSSA | ORTA_PROP))
                    128:     return 2;
                    129: 
                    130:   /* A Type-5 LSA */
                    131:   if (opts == 0)
                    132:     return 1;
                    133: 
                    134:   return 0;
                    135: }
                    136: 
                    137: /* Whether the route is better according to RFC 3101 2.5 (6e):
                    138:    Prioritize Type-7 LSA with P-bit, then Type-5 LSA, then higher router ID */
                    139: static int
                    140: orta_prefer_lsa(const orta *new, const orta *old)
                    141: {
                    142:   int pn = orta_prio(new);
                    143:   int po = orta_prio(old);
                    144: 
                    145:   return (pn > po) || ((pn == po) && (new->en->lsa.rt > old->en->lsa.rt));
                    146: }
                    147: 
                    148: /*
                    149:  * Compare an existing routing table entry with a new one. Applicable for
                    150:  * intra-area routes, inter-area routes and router entries. Returns integer
                    151:  * <, = or > than 0 if the new orta is less, equal or more preferred than
                    152:  * the old orta.
                    153:  */
                    154: static int
                    155: orta_compare(const struct ospf_proto *p, const orta *new, const orta *old)
                    156: {
                    157:   int r;
                    158: 
                    159:   if (old->type == RTS_DUMMY)
                    160:     return 1;
                    161: 
                    162:   /* Prefer intra-area to inter-area to externals */
                    163:   r = ((int) old->type) - ((int) new->type);
                    164:   if (r) return r;
                    165: 
                    166:   /* Prefer lowest type 1 metric */
                    167:   r = ((int) old->metric1) - ((int) new->metric1);
                    168:   if (r) return r;
                    169: 
                    170: 
                    171:   /* Rest is BIRD-specific */
                    172: 
                    173:   /* Area-wide routes should not mix next-hops from different areas.
                    174:      This generally should not happen unless there is some misconfiguration. */
                    175:   if (new->oa->areaid != old->oa->areaid)
                    176:     return (new->oa->areaid > old->oa->areaid) ? 1 : -1;
                    177: 
                    178:   /* Prefer routes for configured stubnets (!nhs) to regular routes to dummy
                    179:      vlink nexthops. We intentionally return -1 if both are stubnets or vlinks. */
                    180:   if (!old->nhs)
                    181:     return -1;
                    182:   if (!new->nhs)
                    183:     return 1;
                    184:   if (nh_is_vlink(new->nhs))
                    185:     return -1;
                    186:   if (nh_is_vlink(old->nhs))
                    187:     return 1;
                    188: 
                    189: 
                    190:   if (p->ecmp)
                    191:     return 0;
                    192: 
                    193:   /* Prefer routes with higher Router ID, just to be more deterministic */
                    194:   if (new->rid > old->rid)
                    195:     return 1;
                    196: 
                    197:   return -1;
                    198: }
                    199: 
                    200: /*
                    201:  * Compare ASBR routing table entry with a new one, used for precompute ASBRs
                    202:  * for AS external route selection (RFC 2328 16.4 (3)), Returns integer < or >
                    203:  * than 0 if the new ASBR is less or more preferred than the old ASBR.
                    204:  */
                    205: static int
                    206: orta_compare_asbr(const struct ospf_proto *p, const orta *new, const orta *old)
                    207: {
                    208:   int r;
                    209: 
                    210:   if (old->type == RTS_DUMMY)
                    211:     return 1;
                    212: 
                    213:   if (!p->rfc1583)
                    214:   {
                    215:     r = epath_preferred(new) - epath_preferred(old);
                    216:     if (r) return r;
                    217:   }
                    218: 
                    219:   r = ((int) old->metric1) - ((int) new->metric1);
                    220:   if (r) return r;
                    221: 
                    222:   /* Larger area ID is preferred */
                    223:   if (new->oa->areaid > old->oa->areaid)
                    224:     return 1;
                    225: 
                    226:   /* There is just one ASBR of that RID per area, so tie is not possible */
                    227:   return -1;
                    228: }
                    229: 
                    230: /*
                    231:  * Compare a routing table entry with a new one, for AS external routes
                    232:  * (RFC 2328 16.4) and NSSA routes (RFC 3103 2.5), Returns integer <, = or >
                    233:  * than 0 if the new orta is less, equal or more preferred than the old orta.
                    234:  */
                    235: static int
                    236: orta_compare_ext(const struct ospf_proto *p, const orta *new, const orta *old)
                    237: {
                    238:   int r;
                    239: 
                    240:   if (old->type == RTS_DUMMY)
                    241:     return 1;
                    242: 
                    243:   /* 16.4 (6a) - prefer routes with lower type */
                    244:   r = ((int) old->type) - ((int) new->type);
                    245:   if (r) return r;
                    246: 
                    247:   /* 16.4 (6b) - prefer routes with lower type 2 metric */
                    248:   if (new->type == RTS_OSPF_EXT2)
                    249:   {
                    250:     r = ((int) old->metric2) - ((int) new->metric2);
                    251:     if (r) return r;
                    252:   }
                    253: 
                    254:   /* 16.4 (6c) - if not RFC1583, prefer routes with preferred ASBR/next_hop */
                    255:   if (!p->rfc1583)
                    256:   {
                    257:     r = orta_pref(new) - orta_pref(old);
                    258:     if (r) return r;
                    259:   }
                    260: 
                    261:   /* 16.4 (6d) - prefer routes with lower type 1 metric */
                    262:   r = ((int) old->metric1) - ((int) new->metric1);
                    263:   if (r) return r;
                    264: 
                    265: 
                    266:   if (p->ecmp && p->merge_external)
                    267:     return 0;
                    268: 
                    269:   /*
                    270:    * RFC 3101 2.5 (6e) - prioritize Type-7 LSA with P-bit, then Type-5 LSA, then
                    271:    * LSA with higher router ID. Although this should apply just to functionally
                    272:    * equivalent LSAs (i.e. ones with the same non-zero forwarding address), we
                    273:    * use it also to disambiguate otherwise equally preferred nexthops.
                    274:    */
                    275:   if (orta_prefer_lsa(new, old))
                    276:     return 1;
                    277: 
                    278:   return -1;
                    279: }
                    280: 
                    281: 
                    282: static inline void
                    283: ort_replace(ort *o, const orta *new)
                    284: {
                    285:   memcpy(&o->n, new, sizeof(orta));
                    286: }
                    287: 
                    288: static void
                    289: ort_merge(struct ospf_proto *p, ort *o, const orta *new)
                    290: {
                    291:   orta *old = &o->n;
                    292: 
                    293:   if (old->nhs != new->nhs)
                    294:   {
                    295:     old->nhs = mpnh_merge(old->nhs, new->nhs, old->nhs_reuse, new->nhs_reuse,
                    296:                          p->ecmp, p->nhpool);
                    297:     old->nhs_reuse = 1;
                    298:   }
                    299: 
                    300:   if (old->rid < new->rid)
                    301:     old->rid = new->rid;
                    302: }
                    303: 
                    304: static void
                    305: ort_merge_ext(struct ospf_proto *p, ort *o, const orta *new)
                    306: {
                    307:   orta *old = &o->n;
                    308: 
                    309:   if (old->nhs != new->nhs)
                    310:   {
                    311:     old->nhs = mpnh_merge(old->nhs, new->nhs, old->nhs_reuse, new->nhs_reuse,
                    312:                          p->ecmp, p->nhpool);
                    313:     old->nhs_reuse = 1;
                    314:   }
                    315: 
                    316:   if (old->tag != new->tag)
                    317:     old->tag = 0;
                    318: 
                    319:   /*
                    320:    * Even with multipath, we store only one LSA in orta.en for the purpose of
                    321:    * NSSA/ext translation. Therefore, we apply procedures from RFC 3101 2.5 (6e)
                    322:    * to all chosen LSAs for given network, not just to functionally equivalent
                    323:    * ones (i.e. ones with the same non-zero forwarding address).
                    324:    */
                    325:   if (orta_prefer_lsa(new, old))
                    326:   {
                    327:     old->options = new->options;
                    328:     old->rid = new->rid;
                    329:     old->oa = new->oa;
                    330:     old->en = new->en;
                    331:   }
                    332: }
                    333: 
                    334: 
                    335: 
                    336: static inline void
                    337: ri_install_net(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
                    338: {
                    339:   ort *old = (ort *) fib_get(&p->rtf, &prefix, pxlen);
                    340:   int cmp = orta_compare(p, new, &old->n);
                    341: 
                    342:   if (cmp > 0)
                    343:     ort_replace(old, new);
                    344:   else if (cmp == 0)
                    345:     ort_merge(p, old, new);
                    346: }
                    347: 
                    348: static inline void
                    349: ri_install_rt(struct ospf_area *oa, u32 rid, const orta *new)
                    350: {
                    351:   ip_addr addr = ipa_from_rid(rid);
                    352:   ort *old = (ort *) fib_get(&oa->rtr, &addr, MAX_PREFIX_LENGTH);
                    353:   int cmp = orta_compare(oa->po, new, &old->n);
                    354: 
                    355:   if (cmp > 0)
                    356:     ort_replace(old, new);
                    357:   else if (cmp == 0)
                    358:     ort_merge(oa->po, old, new);
                    359: }
                    360: 
                    361: static inline void
                    362: ri_install_asbr(struct ospf_proto *p, ip_addr *addr, const orta *new)
                    363: {
                    364:   ort *old = (ort *) fib_get(&p->backbone->rtr, addr, MAX_PREFIX_LENGTH);
                    365:   if (orta_compare_asbr(p, new, &old->n) > 0)
                    366:     ort_replace(old, new);
                    367: }
                    368: 
                    369: static inline void
                    370: ri_install_ext(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
                    371: {
                    372:   ort *old = (ort *) fib_get(&p->rtf, &prefix, pxlen);
                    373:   int cmp = orta_compare_ext(p, new, &old->n);
                    374: 
                    375:   if (cmp > 0)
                    376:     ort_replace(old, new);
                    377:   else if (cmp == 0)
                    378:     ort_merge_ext(p, old, new);
                    379: }
                    380: 
                    381: static inline struct ospf_iface *
                    382: rt_pos_to_ifa(struct ospf_area *oa, int pos)
                    383: {
                    384:   struct ospf_iface *ifa;
                    385: 
                    386:   WALK_LIST(ifa, oa->po->iface_list)
                    387:     if (ifa->oa == oa && pos >= ifa->rt_pos_beg && pos < ifa->rt_pos_end)
                    388:       return ifa;
                    389: 
                    390:   return NULL;
                    391: }
                    392: 
                    393: static inline struct ospf_iface *
                    394: px_pos_to_ifa(struct ospf_area *oa, int pos)
                    395: {
                    396:   struct ospf_iface *ifa;
                    397: 
                    398:   WALK_LIST(ifa, oa->po->iface_list)
                    399:     if (ifa->oa == oa && pos >= ifa->px_pos_beg && pos < ifa->px_pos_end)
                    400:       return ifa;
                    401: 
                    402:   return NULL;
                    403: }
                    404: 
                    405: 
                    406: static void
                    407: add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_hash_entry *en, int pos)
                    408: {
                    409:   struct ospf_proto *p = oa->po;
                    410: 
                    411:   orta nf = {
                    412:     .type = RTS_OSPF,
                    413:     .options = 0,
                    414:     .metric1 = metric,
                    415:     .metric2 = LSINFINITY,
                    416:     .tag = 0,
                    417:     .rid = en->lsa.rt,
                    418:     .oa = oa,
                    419:     .nhs = en->nhs
                    420:   };
                    421: 
                    422:   if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
                    423:   {
                    424:     log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
                    425:        p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
                    426:     return;
                    427:   }
                    428: 
                    429:   if (en == oa->rt)
                    430:   {
                    431:     /*
                    432:      * Local stub networks do not have proper iface in en->nhi (because they all
                    433:      * have common top_hash_entry en). We have to find iface responsible for
                    434:      * that stub network. Configured stubnets do not have any iface. They will
                    435:      * be removed in rt_sync().
                    436:      */
                    437: 
                    438:     struct ospf_iface *ifa;
                    439:     ifa = ospf_is_v2(p) ? rt_pos_to_ifa(oa, pos) : px_pos_to_ifa(oa, pos);
                    440:     nf.nhs = ifa ? new_nexthop(p, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL;
                    441:   }
                    442: 
                    443:   ri_install_net(p, px, pxlen, &nf);
                    444: }
                    445: 
                    446: 
                    447: 
                    448: static inline void
                    449: spfa_process_rt(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_entry *act)
                    450: {
                    451:   struct ospf_lsa_rt *rt = act->lsa_body;
                    452:   struct ospf_lsa_rt_walk rtl;
                    453:   struct top_hash_entry *tmp;
                    454:   ip_addr prefix;
                    455:   int pxlen, i;
                    456: 
                    457:   if (rt->options & OPT_RT_V)
                    458:     oa->trcap = 1;
                    459: 
                    460:   /*
                    461:    * In OSPFv3, all routers are added to per-area routing
                    462:    * tables. But we use it just for ASBRs and ABRs. For the
                    463:    * purpose of the last step in SPF - prefix-LSA processing in
                    464:    * spfa_process_prefixes(), we use information stored in LSA db.
                    465:    */
                    466:   if (((rt->options & OPT_RT_E) || (rt->options & OPT_RT_B))
                    467:       && (act->lsa.rt != p->router_id))
                    468:   {
                    469:     orta nf = {
                    470:       .type = RTS_OSPF,
                    471:       .options = rt->options,
                    472:       .metric1 = act->dist,
                    473:       .metric2 = LSINFINITY,
                    474:       .tag = 0,
                    475:       .rid = act->lsa.rt,
                    476:       .oa = oa,
                    477:       .nhs = act->nhs
                    478:     };
                    479:     ri_install_rt(oa, act->lsa.rt, &nf);
                    480:   }
                    481: 
                    482:   /* Errata 2078 to RFC 5340 4.8.1 - skip links from non-routing nodes */
                    483:   if (ospf_is_v3(p) && (act != oa->rt) && !(rt->options & OPT_R))
                    484:     return;
                    485: 
                    486:   /* Now process Rt links */
                    487:   for (lsa_walk_rt_init(p, act, &rtl), i = 0; lsa_walk_rt(&rtl); i++)
                    488:   {
                    489:     tmp = NULL;
                    490: 
                    491:     switch (rtl.type)
                    492:     {
                    493:     case LSART_STUB:
                    494: 
                    495:       /* Should not happen, LSART_STUB is not defined in OSPFv3 */
                    496:       if (ospf_is_v3(p))
                    497:        break;
                    498: 
                    499:       /*
                    500:        * RFC 2328 in 16.1. (2a) says to handle stub networks in an
                    501:        * second phase after the SPF for an area is calculated. We get
                    502:        * the same result by handing them here because add_network()
                    503:        * will keep the best (not the first) found route.
                    504:        */
                    505:       prefix = ipa_from_u32(rtl.id & rtl.data);
                    506:       pxlen = u32_masklen(rtl.data);
                    507:       add_network(oa, prefix, pxlen, act->dist + rtl.metric, act, i);
                    508:       break;
                    509: 
                    510:     case LSART_NET:
                    511:       tmp = ospf_hash_find_net(p->gr, oa->areaid, rtl.id, rtl.nif);
                    512:       break;
                    513: 
                    514:     case LSART_VLNK:
                    515:     case LSART_PTP:
                    516:       tmp = ospf_hash_find_rt(p->gr, oa->areaid, rtl.id);
                    517:       break;
                    518:     }
                    519: 
                    520:     add_cand(&oa->cand, tmp, act, act->dist + rtl.metric, oa, i);
                    521:   }
                    522: }
                    523: 
                    524: static inline void
                    525: spfa_process_net(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_entry *act)
                    526: {
                    527:   struct ospf_lsa_net *ln = act->lsa_body;
                    528:   struct top_hash_entry *tmp;
                    529:   ip_addr prefix;
                    530:   int pxlen, i, cnt;
                    531: 
                    532:   if (ospf_is_v2(p))
                    533:   {
                    534:     prefix = ipa_from_u32(act->lsa.id & ln->optx);
                    535:     pxlen = u32_masklen(ln->optx);
                    536:     add_network(oa, prefix, pxlen, act->dist, act, -1);
                    537:   }
                    538: 
                    539:   cnt = lsa_net_count(&act->lsa);
                    540:   for (i = 0; i < cnt; i++)
                    541:   {
                    542:     tmp = ospf_hash_find_rt(p->gr, oa->areaid, ln->routers[i]);
                    543:     add_cand(&oa->cand, tmp, act, act->dist, oa, -1);
                    544:   }
                    545: }
                    546: 
                    547: static inline void
                    548: spfa_process_prefixes(struct ospf_proto *p, struct ospf_area *oa)
                    549: {
                    550:   struct top_hash_entry *en, *src;
                    551:   struct ospf_lsa_prefix *px;
                    552:   ip_addr pxa;
                    553:   int pxlen;
                    554:   u8 pxopts;
                    555:   u16 metric;
                    556:   u32 *buf;
                    557:   int i;
                    558: 
                    559:   WALK_SLIST(en, p->lsal)
                    560:   {
                    561:     if (en->lsa_type != LSA_T_PREFIX)
                    562:       continue;
                    563: 
                    564:     if (en->domain != oa->areaid)
                    565:       continue;
                    566: 
                    567:     if (en->lsa.age == LSA_MAXAGE)
                    568:       continue;
                    569: 
                    570:     px = en->lsa_body;
                    571: 
                    572:     /* For router prefix-LSA, we would like to find the first router-LSA */
                    573:     if (px->ref_type == LSA_T_RT)
                    574:       src = ospf_hash_find_rt(p->gr, oa->areaid, px->ref_rt);
                    575:     else
                    576:       src = ospf_hash_find(p->gr, oa->areaid, px->ref_id, px->ref_rt, px->ref_type);
                    577: 
                    578:     if (!src)
                    579:       continue;
                    580: 
                    581:     /* Reachable in SPF */
                    582:     if (src->color != INSPF)
                    583:       continue;
                    584: 
                    585:     if ((src->lsa_type != LSA_T_RT) && (src->lsa_type != LSA_T_NET))
                    586:       continue;
                    587: 
                    588:     buf = px->rest;
                    589:     for (i = 0; i < px->pxcount; i++)
                    590:       {
                    591:        buf = lsa_get_ipv6_prefix(buf, &pxa, &pxlen, &pxopts, &metric);
                    592: 
                    593:        if (pxopts & OPT_PX_NU)
                    594:          continue;
                    595: 
                    596:        /* Store the first global address to use it later as a vlink endpoint */
                    597:        if ((pxopts & OPT_PX_LA) && ipa_zero(src->lb))
                    598:          src->lb = pxa;
                    599: 
                    600:        add_network(oa, pxa, pxlen, src->dist + metric, src, i);
                    601:       }
                    602:   }
                    603: }
                    604: 
                    605: /* RFC 2328 16.1. calculating shortest paths for an area */
                    606: static void
                    607: ospf_rt_spfa(struct ospf_area *oa)
                    608: {
                    609:   struct ospf_proto *p = oa->po;
                    610:   struct top_hash_entry *act;
                    611:   node *n;
                    612: 
                    613:   if (oa->rt == NULL)
                    614:     return;
                    615:   if (oa->rt->lsa.age == LSA_MAXAGE)
                    616:     return;
                    617: 
                    618:   OSPF_TRACE(D_EVENTS, "Starting routing table calculation for area %R", oa->areaid);
                    619: 
                    620:   /* 16.1. (1) */
                    621:   init_list(&oa->cand);                /* Empty list of candidates */
                    622:   oa->trcap = 0;
                    623: 
                    624:   DBG("LSA db prepared, adding me into candidate list.\n");
                    625: 
                    626:   oa->rt->dist = 0;
                    627:   oa->rt->color = CANDIDATE;
                    628:   add_head(&oa->cand, &oa->rt->cn);
                    629:   DBG("RT LSA: rt: %R, id: %R, type: %u\n",
                    630:       oa->rt->lsa.rt, oa->rt->lsa.id, oa->rt->lsa_type);
                    631: 
                    632:   while (!EMPTY_LIST(oa->cand))
                    633:   {
                    634:     n = HEAD(oa->cand);
                    635:     act = SKIP_BACK(struct top_hash_entry, cn, n);
                    636:     rem_node(n);
                    637: 
                    638:     DBG("Working on LSA: rt: %R, id: %R, type: %u\n",
                    639:        act->lsa.rt, act->lsa.id, act->lsa_type);
                    640: 
                    641:     act->color = INSPF;
                    642:     switch (act->lsa_type)
                    643:     {
                    644:     case LSA_T_RT:
                    645:       spfa_process_rt(p, oa, act);
                    646:       break;
                    647: 
                    648:     case LSA_T_NET:
                    649:       spfa_process_net(p, oa, act);
                    650:       break;
                    651: 
                    652:     default:
                    653:       log(L_WARN "%s: Unknown LSA type in SPF: %d", p->p.name, act->lsa_type);
                    654:     }
                    655:   }
                    656: 
                    657:   if (ospf_is_v3(p))
                    658:     spfa_process_prefixes(p, oa);
                    659: }
                    660: 
                    661: static int
                    662: link_back(struct ospf_area *oa, struct top_hash_entry *en, struct top_hash_entry *par)
                    663: {
                    664:   struct ospf_proto *p = oa->po;
                    665:   struct ospf_lsa_rt_walk rtl;
                    666:   struct top_hash_entry *tmp;
                    667:   struct ospf_lsa_net *ln;
                    668:   u32 i, cnt;
                    669: 
                    670:   if (!en || !par) return 0;
                    671: 
                    672:   /* We should check whether there is a link back from en to par,
                    673:      this is used in SPF calc (RFC 2328 16.1. (2b)). According to RFC 2328
                    674:      note 23, we don't have to find the same link that is used for par
                    675:      to en, any link is enough. This we do for ptp links. For net-rt
                    676:      links, we have to find the same link to compute proper lb/lb_id,
                    677:      which may be later used as the next hop. */
                    678: 
                    679:   /* In OSPFv2, en->lb is set here. In OSPFv3, en->lb is just cleared here,
                    680:      it is set in process_prefixes() to any global address in the area */
                    681: 
                    682:   en->lb = IPA_NONE;
                    683:   en->lb_id = 0;
                    684: 
                    685:   switch (en->lsa_type)
                    686:   {
                    687:   case LSA_T_RT:
                    688:     lsa_walk_rt_init(p, en, &rtl);
                    689:     while (lsa_walk_rt(&rtl))
                    690:     {
                    691:       switch (rtl.type)
                    692:       {
                    693:       case LSART_STUB:
                    694:        break;
                    695: 
                    696:       case LSART_NET:
                    697:        tmp = ospf_hash_find_net(p->gr, oa->areaid, rtl.id, rtl.nif);
                    698:        if (tmp == par)
                    699:        {
                    700:          if (ospf_is_v2(p))
                    701:            en->lb = ipa_from_u32(rtl.data);
                    702:          else
                    703:            en->lb_id = rtl.lif;
                    704: 
                    705:          return 1;
                    706:        }
                    707:        break;
                    708: 
                    709:       case LSART_VLNK:
                    710:       case LSART_PTP:
                    711:        /* Not necessary the same link, see RFC 2328 [23] */
                    712:        tmp = ospf_hash_find_rt(p->gr, oa->areaid, rtl.id);
                    713:        if (tmp == par)
                    714:          return 1;
                    715:        break;
                    716:       }
                    717:     }
                    718:     break;
                    719: 
                    720:   case LSA_T_NET:
                    721:     ln = en->lsa_body;
                    722:     cnt = lsa_net_count(&en->lsa);
                    723:     for (i = 0; i < cnt; i++)
                    724:     {
                    725:       tmp = ospf_hash_find_rt(p->gr, oa->areaid, ln->routers[i]);
                    726:       if (tmp == par)
                    727:        return 1;
                    728:     }
                    729:     break;
                    730: 
                    731:   default:
                    732:     log(L_WARN "%s: Unknown LSA type in SPF: %d", p->p.name, en->lsa_type);
                    733:   }
                    734:   return 0;
                    735: }
                    736: 
                    737: 
                    738: /* RFC 2328 16.2. calculating inter-area routes */
                    739: static void
                    740: ospf_rt_sum(struct ospf_area *oa)
                    741: {
                    742:   struct ospf_proto *p = oa->po;
                    743:   struct top_hash_entry *en;
                    744:   ip_addr ip, abrip;
                    745:   u32 dst_rid, metric, options;
                    746:   ort *abr;
                    747:   int pxlen = -1, type = -1;
                    748:   u8 pxopts;
                    749: 
                    750: 
                    751:   OSPF_TRACE(D_EVENTS, "Starting routing table calculation for inter-area (area %R)", oa->areaid);
                    752: 
                    753:   WALK_SLIST(en, p->lsal)
                    754:   {
                    755:     if ((en->lsa_type != LSA_T_SUM_RT) && (en->lsa_type != LSA_T_SUM_NET))
                    756:       continue;
                    757: 
                    758:     if (en->domain != oa->areaid)
                    759:       continue;
                    760: 
                    761:     /* 16.2. (1a) */
                    762:     if (en->lsa.age == LSA_MAXAGE)
                    763:       continue;
                    764: 
                    765:     /* 16.2. (2) */
                    766:     if (en->lsa.rt == p->router_id)
                    767:       continue;
                    768: 
                    769:     /* 16.2. (3) is handled later in ospf_rt_abr() by resetting such rt entry */
                    770: 
                    771:     if (en->lsa_type == LSA_T_SUM_NET)
                    772:     {
                    773:       lsa_parse_sum_net(en, ospf_is_v2(p), &ip, &pxlen, &pxopts, &metric);
                    774: 
                    775:       if (pxopts & OPT_PX_NU)
                    776:        continue;
                    777: 
                    778:       if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
                    779:       {
                    780:        log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
                    781:            p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
                    782:        continue;
                    783:       }
                    784: 
                    785:       options = 0;
                    786:       type = ORT_NET;
                    787:     }
                    788:     else /* LSA_T_SUM_RT */
                    789:     {
                    790:       lsa_parse_sum_rt(en, ospf_is_v2(p), &dst_rid, &metric, &options);
                    791: 
                    792:       /* We don't want local router in ASBR routing table */
                    793:       if (dst_rid == p->router_id)
                    794:        continue;
                    795: 
                    796:       options |= ORTA_ASBR;
                    797:       type = ORT_ROUTER;
                    798:     }
                    799: 
                    800:     /* 16.2. (1b) */
                    801:     if (metric == LSINFINITY)
                    802:       continue;
                    803: 
                    804:     /* 16.2. (4) */
                    805:     abrip = ipa_from_rid(en->lsa.rt);
                    806:     abr = (ort *) fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
                    807:     if (!abr || !abr->n.type)
                    808:       continue;
                    809: 
                    810:     if (!(abr->n.options & ORTA_ABR))
                    811:       continue;
                    812: 
                    813:     /* This check is not mentioned in RFC 2328 */
                    814:     if (abr->n.type != RTS_OSPF)
                    815:       continue;
                    816: 
                    817:     /* 16.2. (5) */
                    818:     orta nf = {
                    819:       .type = RTS_OSPF_IA,
                    820:       .options = options,
                    821:       .metric1 = abr->n.metric1 + metric,
                    822:       .metric2 = LSINFINITY,
                    823:       .tag = 0,
                    824:       .rid = en->lsa.rt, /* ABR ID */
                    825:       .oa = oa,
                    826:       .nhs = abr->n.nhs
                    827:     };
                    828: 
                    829:     if (type == ORT_NET)
                    830:       ri_install_net(p, ip, pxlen, &nf);
                    831:     else
                    832:       ri_install_rt(oa, dst_rid, &nf);
                    833:   }
                    834: }
                    835: 
                    836: /* RFC 2328 16.3. examining summary-LSAs in transit areas */
                    837: static void
                    838: ospf_rt_sum_tr(struct ospf_area *oa)
                    839: {
                    840:   struct ospf_proto *p = oa->po;
                    841:   struct ospf_area *bb = p->backbone;
                    842:   struct top_hash_entry *en;
                    843:   ort *re, *abr;
                    844:   ip_addr ip, abrip;
                    845:   u32 dst_rid, metric, options;
                    846:   int pxlen;
                    847:   u8 pxopts;
                    848: 
                    849: 
                    850:   if (!bb)
                    851:     return;
                    852: 
                    853:   WALK_SLIST(en, p->lsal)
                    854:   {
                    855:     if ((en->lsa_type != LSA_T_SUM_RT) && (en->lsa_type != LSA_T_SUM_NET))
                    856:       continue;
                    857: 
                    858:     if (en->domain != oa->areaid)
                    859:       continue;
                    860: 
                    861:     /* 16.3 (1a) */
                    862:     if (en->lsa.age == LSA_MAXAGE)
                    863:       continue;
                    864: 
                    865:     /* 16.3 (2) */
                    866:     if (en->lsa.rt == p->router_id)
                    867:       continue;
                    868: 
                    869:     if (en->lsa_type == LSA_T_SUM_NET)
                    870:     {
                    871:       lsa_parse_sum_net(en, ospf_is_v2(p), &ip, &pxlen, &pxopts, &metric);
                    872: 
                    873:       if (pxopts & OPT_PX_NU)
                    874:        continue;
                    875: 
                    876:       if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
                    877:       {
                    878:        log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
                    879:            p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
                    880:        continue;
                    881:       }
                    882: 
                    883:       re = fib_find(&p->rtf, &ip, pxlen);
                    884:     }
                    885:     else // en->lsa_type == LSA_T_SUM_RT
                    886:     {
                    887:       lsa_parse_sum_rt(en, ospf_is_v2(p), &dst_rid, &metric, &options);
                    888: 
                    889:       ip = ipa_from_rid(dst_rid);
                    890:       re = fib_find(&bb->rtr, &ip, MAX_PREFIX_LENGTH);
                    891:     }
                    892: 
                    893:     /* 16.3 (1b) */
                    894:     if (metric == LSINFINITY)
                    895:       continue;
                    896: 
                    897:     /* 16.3 (3) */
                    898:     if (!re || !re->n.type)
                    899:       continue;
                    900: 
                    901:     if (re->n.oa->areaid != 0)
                    902:       continue;
                    903: 
                    904:     if ((re->n.type != RTS_OSPF) && (re->n.type != RTS_OSPF_IA))
                    905:       continue;
                    906: 
                    907:     /* 16.3. (4) */
                    908:     abrip = ipa_from_rid(en->lsa.rt);
                    909:     abr = fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
                    910:     if (!abr || !abr->n.type)
                    911:       continue;
                    912: 
                    913:     metric = abr->n.metric1 + metric; /* IAC */
                    914: 
                    915:     /* 16.3. (5) */
                    916:     if ((metric < re->n.metric1) ||
                    917:        ((metric == re->n.metric1) && unresolved_vlink(re)))
                    918:     {
                    919:       /* We want to replace the next-hop even if the metric is equal
                    920:         to replace a virtual next-hop through vlink with a real one.
                    921:         Proper ECMP would merge nexthops here, but we do not do that.
                    922:         We restrict nexthops to fit one area to simplify check
                    923:         12.4.3 p4 in decide_sum_lsa() */
                    924: 
                    925:       re->n.metric1 = metric;
                    926:       re->n.voa = oa;
                    927:       re->n.nhs = abr->n.nhs;
                    928:     }
                    929:   }
                    930: }
                    931: 
                    932: /* Decide about originating or flushing summary LSAs for condensed area networks */
                    933: static int
                    934: decide_anet_lsa(struct ospf_area *oa, struct area_net *anet, struct ospf_area *anet_oa)
                    935: {
                    936:   /* 12.4.3.1. - for stub/NSSA areas, originating summary routes is configurable */
                    937:   if (!oa_is_ext(oa) && !oa->ac->summary)
                    938:     return 0;
                    939: 
                    940:   if (oa == anet_oa)
                    941:     return 0;
                    942: 
                    943:   /* Do not condense routing info when exporting from backbone to the transit area */
                    944:   if ((anet_oa == oa->po->backbone) && oa->trcap)
                    945:     return 0;
                    946: 
                    947:   return (anet->active && !anet->hidden);
                    948: }
                    949: 
                    950: /* Decide about originating or flushing summary LSAs (12.4.3) */
                    951: static int
                    952: decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
                    953: {
                    954:   /* 12.4.3.1. - for stub/NSSA areas, originating summary routes is configurable */
                    955:   if (!oa_is_ext(oa) && !oa->ac->summary)
                    956:     return 0;
                    957: 
                    958:   /* Invalid field - no route */
                    959:   if (!nf->n.type)
                    960:     return 0;
                    961: 
                    962:   /* 12.4.3 p2 */
                    963:   if (nf->n.type > RTS_OSPF_IA)
                    964:     return 0;
                    965: 
                    966:   /* 12.4.3 p3 */
                    967:   if ((nf->n.oa->areaid == oa->areaid))
                    968:     return 0;
                    969: 
                    970:   /* 12.4.3 p4 */
                    971:   if (nf->n.voa && (nf->n.voa->areaid == oa->areaid))
                    972:     return 0;
                    973: 
                    974:   /* 12.4.3 p5 */
                    975:   if (nf->n.metric1 >= LSINFINITY)
                    976:     return 0;
                    977: 
                    978:   /* 12.4.3 p6 - AS boundary router */
                    979:   if (dest == ORT_ROUTER)
                    980:   {
                    981:     /* We call decide_sum_lsa() on preferred ASBR entries, no need for 16.4. (3) */
                    982:     /* 12.4.3 p1 */
                    983:     return oa_is_ext(oa) && (nf->n.options & ORTA_ASBR);
                    984:   }
                    985: 
                    986:   /* 12.4.3 p7 - inter-area route */
                    987:   if (nf->n.type == RTS_OSPF_IA)
                    988:   {
                    989:     /* Inter-area routes are not repropagated into the backbone */
                    990:     return (oa != oa->po->backbone);
                    991:   }
                    992: 
                    993:   /* 12.4.3 p8 - intra-area route */
                    994: 
                    995:   /* Do not condense routing info when exporting from backbone to the transit area */
                    996:   if ((nf->n.oa == oa->po->backbone) && oa->trcap)
                    997:     return 1;
                    998: 
                    999:   struct area_net *anet = (struct area_net *)
                   1000:     fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
                   1001: 
                   1002:   /* Condensed area network found */
                   1003:   if (anet)
                   1004:     return 0;
                   1005: 
                   1006:   return 1;
                   1007: }
                   1008: 
                   1009: /* RFC 2328 16.7. p1 - originate or flush summary LSAs */
                   1010: static inline void
                   1011: check_sum_net_lsa(struct ospf_proto *p, ort *nf)
                   1012: {
                   1013:   struct area_net *anet = NULL;
                   1014:   struct ospf_area *anet_oa = NULL;
                   1015: 
                   1016:   if (nf->area_net)
                   1017:   {
                   1018:     /* It is a default route for stub areas, handled entirely in ospf_rt_abr() */
                   1019:     if (nf->fn.pxlen == 0)
                   1020:       return;
                   1021: 
                   1022:     /* Find that area network */
                   1023:     WALK_LIST(anet_oa, p->area_list)
                   1024:     {
                   1025:       anet = (struct area_net *) fib_find(&anet_oa->net_fib, &nf->fn.prefix, nf->fn.pxlen);
                   1026:       if (anet)
                   1027:        break;
                   1028:     }
                   1029:   }
                   1030: 
                   1031:   struct ospf_area *oa;
                   1032:   WALK_LIST(oa, p->area_list)
                   1033:   {
                   1034:     if (anet && decide_anet_lsa(oa, anet, anet_oa))
                   1035:       ospf_originate_sum_net_lsa(p, oa, nf, anet->metric);
                   1036:     else if (decide_sum_lsa(oa, nf, ORT_NET))
                   1037:       ospf_originate_sum_net_lsa(p, oa, nf, nf->n.metric1);
                   1038:   }
                   1039: }
                   1040: 
                   1041: static inline void
                   1042: check_sum_rt_lsa(struct ospf_proto *p, ort *nf)
                   1043: {
                   1044:   struct ospf_area *oa;
                   1045:   WALK_LIST(oa, p->area_list)
                   1046:     if (decide_sum_lsa(oa, nf, ORT_ROUTER))
                   1047:       ospf_originate_sum_rt_lsa(p, oa, nf, nf->n.metric1, nf->n.options);
                   1048: }
                   1049: 
                   1050: static inline int
                   1051: decide_nssa_lsa(struct ospf_proto *p UNUSED4 UNUSED6, ort *nf, struct ospf_lsa_ext_local *rt)
                   1052: {
                   1053:   struct ospf_area *oa = nf->n.oa;
                   1054:   struct top_hash_entry *en = nf->n.en;
                   1055: 
                   1056:   if (!rt_is_nssa(nf) || !oa->translate)
                   1057:     return 0;
                   1058: 
                   1059:   /* Condensed area network found */
                   1060:   if (fib_route(&oa->enet_fib, nf->fn.prefix, nf->fn.pxlen))
                   1061:     return 0;
                   1062: 
                   1063:   if (!en || (en->lsa_type != LSA_T_NSSA))
                   1064:     return 0;
                   1065: 
                   1066:   /* We do not store needed data in struct orta, we have to parse the LSA */
                   1067:   lsa_parse_ext(en, ospf_is_v2(p), rt);
                   1068: 
                   1069:   if (rt->pxopts & OPT_PX_NU)
                   1070:     return 0;
                   1071: 
                   1072:   if (!rt->propagate || ipa_zero(rt->fwaddr))
                   1073:     return 0;
                   1074: 
                   1075:   return 1;
                   1076: }
                   1077: 
                   1078: /* RFC 3103 3.2 - translating Type-7 LSAs into Type-5 LSAs */
                   1079: static inline void
                   1080: check_nssa_lsa(struct ospf_proto *p, ort *nf)
                   1081: {
                   1082:   struct area_net *anet = NULL;
                   1083:   struct ospf_area *oa = NULL;
                   1084:   struct ospf_lsa_ext_local rt;
                   1085: 
                   1086:   /* Do not translate LSA if there is already the external LSA from route export */
                   1087:   if (nf->external_rte)
                   1088:     return;
                   1089: 
                   1090:   if (nf->area_net)
                   1091:   {
                   1092:     /* Find that area network */
                   1093:     WALK_LIST(oa, p->area_list)
                   1094:     {
                   1095:       anet = (struct area_net *) fib_find(&oa->enet_fib, &nf->fn.prefix, nf->fn.pxlen);
                   1096:       if (anet)
                   1097:        break;
                   1098:     }
                   1099:   }
                   1100: 
                   1101:   /* RFC 3103 3.2 (3) - originate the aggregated address range */
                   1102:   if (anet && anet->active && !anet->hidden && oa->translate)
                   1103:     ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, anet->metric,
                   1104:                           (anet->metric & LSA_EXT3_EBIT), IPA_NONE, anet->tag, 0);
                   1105: 
                   1106:   /* RFC 3103 3.2 (2) - originate the same network */
                   1107:   else if (decide_nssa_lsa(p, nf, &rt))
                   1108:     ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, rt.metric, rt.ebit, rt.fwaddr, rt.tag, 0);
                   1109: }
                   1110: 
                   1111: /* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
                   1112: static void
                   1113: ospf_check_vlinks(struct ospf_proto *p)
                   1114: {
                   1115:   struct ospf_iface *ifa;
                   1116:   WALK_LIST(ifa, p->iface_list)
                   1117:   {
                   1118:     if (ifa->type == OSPF_IT_VLINK)
                   1119:     {
                   1120:       struct top_hash_entry *tmp;
                   1121:       tmp = ospf_hash_find_rt(p->gr, ifa->voa->areaid, ifa->vid);
                   1122: 
                   1123:       if (tmp && (tmp->color == INSPF) && ipa_nonzero(tmp->lb) && tmp->nhs)
                   1124:       {
                   1125:        struct ospf_iface *nhi = ospf_iface_find(p, tmp->nhs->iface);
                   1126: 
                   1127:        if ((ifa->state != OSPF_IS_PTP)
                   1128:            || (ifa->vifa != nhi)
                   1129:            || !ipa_equal(ifa->vip, tmp->lb))
                   1130:        {
                   1131:          OSPF_TRACE(D_EVENTS, "Vlink peer %R found", ifa->vid);
                   1132:          ospf_iface_sm(ifa, ISM_DOWN);
                   1133:          ifa->vifa = nhi;
                   1134:          ifa->addr = nhi->addr;
                   1135:          ifa->cost = tmp->dist;
                   1136:          ifa->vip = tmp->lb;
                   1137:          ospf_iface_sm(ifa, ISM_UP);
                   1138:        }
                   1139:        else if ((ifa->state == OSPF_IS_PTP) && (ifa->cost != tmp->dist))
                   1140:        {
                   1141:          ifa->cost = tmp->dist;
                   1142: 
                   1143:          /* RFC 2328 12.4 Event 8 - vlink state change */
                   1144:          ospf_notify_rt_lsa(ifa->oa);
                   1145:        }
                   1146:       }
                   1147:       else
                   1148:       {
                   1149:        if (ifa->state > OSPF_IS_DOWN)
                   1150:        {
                   1151:          OSPF_TRACE(D_EVENTS, "Vlink peer %R lost", ifa->vid);
                   1152:          ospf_iface_sm(ifa, ISM_DOWN);
                   1153:        }
                   1154:       }
                   1155:     }
                   1156:   }
                   1157: }
                   1158: 
                   1159: 
                   1160: /* Miscellaneous route processing that needs to be done by ABRs */
                   1161: static void
                   1162: ospf_rt_abr1(struct ospf_proto *p)
                   1163: {
                   1164:   struct area_net *anet;
                   1165:   ort *nf, *default_nf;
                   1166: 
                   1167:   /* RFC 2328 G.3 - incomplete resolution of virtual next hops - routers */
                   1168:   FIB_WALK(&p->backbone->rtr, nftmp)
                   1169:   {
                   1170:     nf = (ort *) nftmp;
                   1171: 
                   1172:     if (nf->n.type && unresolved_vlink(nf))
                   1173:       reset_ri(nf);
                   1174:   }
                   1175:   FIB_WALK_END;
                   1176: 
                   1177: 
                   1178:   FIB_WALK(&p->rtf, nftmp)
                   1179:   {
                   1180:     nf = (ort *) nftmp;
                   1181: 
                   1182: 
                   1183:     /* RFC 2328 G.3 - incomplete resolution of virtual next hops - networks */
                   1184:     if (nf->n.type && unresolved_vlink(nf))
                   1185:       reset_ri(nf);
                   1186: 
                   1187: 
                   1188:     /* Compute condensed area networks */
                   1189:     if (nf->n.type == RTS_OSPF)
                   1190:     {
                   1191:       anet = (struct area_net *) fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
                   1192:       if (anet)
                   1193:       {
                   1194:        if (!anet->active)
                   1195:        {
                   1196:          anet->active = 1;
                   1197: 
                   1198:          /* Get a RT entry and mark it to know that it is an area network */
                   1199:          ort *nfi = (ort *) fib_get(&p->rtf, &anet->fn.prefix, anet->fn.pxlen);
                   1200:          nfi->area_net = 1;
                   1201: 
                   1202:          /* 16.2. (3) */
                   1203:          if (nfi->n.type == RTS_OSPF_IA)
                   1204:            reset_ri(nfi);
                   1205:        }
                   1206: 
                   1207:        if (anet->metric < nf->n.metric1)
                   1208:          anet->metric = nf->n.metric1;
                   1209:       }
                   1210:     }
                   1211:   }
                   1212:   FIB_WALK_END;
                   1213: 
                   1214:   ip_addr addr = IPA_NONE;
                   1215:   default_nf = (ort *) fib_get(&p->rtf, &addr, 0);
                   1216:   default_nf->area_net = 1;
                   1217: 
                   1218:   struct ospf_area *oa;
                   1219:   WALK_LIST(oa, p->area_list)
                   1220:   {
                   1221: 
                   1222:     /* 12.4.3.1. - originate or flush default route for stub/NSSA areas */
                   1223:     if (oa_is_stub(oa) || (oa_is_nssa(oa) && !oa->ac->summary))
                   1224:       ospf_originate_sum_net_lsa(p, oa, default_nf, oa->ac->default_cost);
                   1225: 
                   1226:     /*
                   1227:      * Originate type-7 default route for NSSA areas
                   1228:      *
                   1229:      * Because type-7 default LSAs are originated by ABRs, they do not
                   1230:      * collide with other type-7 LSAs (as ABRs generate type-5 LSAs
                   1231:      * for both external route export or external-NSSA translation),
                   1232:      * so we use 0 for the src arg.
                   1233:      */
                   1234: 
                   1235:     if (oa_is_nssa(oa) && oa->ac->default_nssa)
                   1236:       ospf_originate_ext_lsa(p, oa, default_nf, LSA_M_RTCALC, oa->ac->default_cost,
                   1237:                             (oa->ac->default_cost & LSA_EXT3_EBIT), IPA_NONE, 0, 0);
                   1238: 
                   1239:     /* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
                   1240:     if (oa_is_ext(oa))
                   1241:     {
                   1242:       FIB_WALK(&oa->rtr, nftmp)
                   1243:       {
                   1244:        nf = (ort *) nftmp;
                   1245:        if (nf->n.options & ORTA_ASBR)
                   1246:          ri_install_asbr(p, &nf->fn.prefix, &nf->n);
                   1247:       }
                   1248:       FIB_WALK_END;
                   1249:     }
                   1250:   }
                   1251: 
                   1252: 
                   1253:   /* Originate or flush ASBR summary LSAs */
                   1254:   FIB_WALK(&p->backbone->rtr, nftmp)
                   1255:   {
                   1256:     check_sum_rt_lsa(p, (ort *) nftmp);
                   1257:   }
                   1258:   FIB_WALK_END;
                   1259: 
                   1260: 
                   1261:   /* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
                   1262:   ospf_check_vlinks(p);
                   1263: }
                   1264: 
                   1265: 
                   1266: static void
                   1267: translator_timer_hook(timer *timer)
                   1268: {
                   1269:   struct ospf_area *oa = timer->data;
                   1270: 
                   1271:   if (oa->translate != TRANS_WAIT)
                   1272:     return;
                   1273: 
                   1274:   oa->translate = TRANS_OFF;
                   1275:   ospf_schedule_rtcalc(oa->po);
                   1276: }
                   1277: 
                   1278: static void
                   1279: ospf_rt_abr2(struct ospf_proto *p)
                   1280: {
                   1281:   struct ospf_area *oa;
                   1282:   struct top_hash_entry *en;
                   1283:   ort *nf, *nf2;
                   1284: 
                   1285: 
                   1286:   /* RFC 3103 3.1 - type-7 translator election */
                   1287:   struct ospf_area *bb = p->backbone;
                   1288:   WALK_LIST(oa, p->area_list)
                   1289:     if (oa_is_nssa(oa))
                   1290:     {
                   1291:       int translate = 1;
                   1292: 
                   1293:       if (oa->ac->translator)
                   1294:        goto decided;
                   1295: 
                   1296:       FIB_WALK(&oa->rtr, nftmp)
                   1297:       {
                   1298:        nf = (ort *) nftmp;
                   1299:        if (!nf->n.type || !(nf->n.options & ORTA_ABR))
                   1300:          continue;
                   1301: 
                   1302:        nf2 = fib_find(&bb->rtr, &nf->fn.prefix, MAX_PREFIX_LENGTH);
                   1303:        if (!nf2 || !nf2->n.type || !(nf2->n.options & ORTA_ABR))
                   1304:          continue;
                   1305: 
                   1306:        en = ospf_hash_find_rt(p->gr, oa->areaid, nf->n.rid);
                   1307:        if (!en || (en->color != INSPF))
                   1308:          continue;
                   1309: 
                   1310:        struct ospf_lsa_rt *rt = en->lsa_body;
                   1311:        /* There is better candidate - Nt-bit or higher Router ID */
                   1312:        if ((rt->options & OPT_RT_NT) || (p->router_id < nf->n.rid))
                   1313:        {
                   1314:          translate = 0;
                   1315:          goto decided;
                   1316:        }
                   1317:       }
                   1318:       FIB_WALK_END;
                   1319: 
                   1320:     decided:
                   1321:       if (translate && (oa->translate != TRANS_ON))
                   1322:       {
                   1323:        if (oa->translate == TRANS_WAIT)
                   1324:          tm_stop(oa->translator_timer);
                   1325: 
                   1326:        oa->translate = TRANS_ON;
                   1327:       }
                   1328: 
                   1329:       if (!translate && (oa->translate == TRANS_ON))
                   1330:       {
                   1331:        if (oa->translator_timer == NULL)
                   1332:          oa->translator_timer = tm_new_set(p->p.pool, translator_timer_hook, oa, 0, 0);
                   1333: 
                   1334:        /* Schedule the end of translation */
                   1335:        tm_start(oa->translator_timer, oa->ac->transint);
                   1336:        oa->translate = TRANS_WAIT;
                   1337:       }
                   1338:     }
                   1339: 
                   1340: 
                   1341:   /* Compute condensed external networks */
                   1342:   FIB_WALK(&p->rtf, nftmp)
                   1343:   {
                   1344:     nf = (ort *) nftmp;
                   1345:     if (rt_is_nssa(nf) && (nf->n.options & ORTA_PROP))
                   1346:     {
                   1347:       struct area_net *anet = (struct area_net *)
                   1348:        fib_route(&nf->n.oa->enet_fib, nf->fn.prefix, nf->fn.pxlen);
                   1349: 
                   1350:       if (anet)
                   1351:       {
                   1352:        if (!anet->active)
                   1353:        {
                   1354:          anet->active = 1;
                   1355: 
                   1356:          /* Get a RT entry and mark it to know that it is an area network */
                   1357:          nf2 = (ort *) fib_get(&p->rtf, &anet->fn.prefix, anet->fn.pxlen);
                   1358:          nf2->area_net = 1;
                   1359:        }
                   1360: 
                   1361:        u32 metric = (nf->n.type == RTS_OSPF_EXT1) ?
                   1362:          nf->n.metric1 : ((nf->n.metric2 + 1) | LSA_EXT3_EBIT);
                   1363: 
                   1364:        if (anet->metric < metric)
                   1365:          anet->metric = metric;
                   1366:       }
                   1367:     }
                   1368:   }
                   1369:   FIB_WALK_END;
                   1370: 
                   1371: 
                   1372:   FIB_WALK(&p->rtf, nftmp)
                   1373:   {
                   1374:     nf = (ort *) nftmp;
                   1375: 
                   1376:     check_sum_net_lsa(p, nf);
                   1377:     check_nssa_lsa(p, nf);
                   1378:   }
                   1379:   FIB_WALK_END;
                   1380: }
                   1381: 
                   1382: 
                   1383: /* Like fib_route(), but ignores dummy rt entries */
                   1384: static void *
                   1385: ospf_fib_route(struct fib *f, ip_addr a, int len)
                   1386: {
                   1387:   ip_addr a0;
                   1388:   ort *nf;
                   1389: 
                   1390:   while (len >= 0)
                   1391:   {
                   1392:     a0 = ipa_and(a, ipa_mkmask(len));
                   1393:     nf = fib_find(f, &a0, len);
                   1394:     if (nf && nf->n.type)
                   1395:       return nf;
                   1396:     len--;
                   1397:   }
                   1398:   return NULL;
                   1399: }
                   1400: 
                   1401: /* RFC 2328 16.4. calculating external routes */
                   1402: static void
                   1403: ospf_ext_spf(struct ospf_proto *p)
                   1404: {
                   1405:   struct top_hash_entry *en;
                   1406:   struct ospf_lsa_ext_local rt;
                   1407:   ort *nf1, *nf2;
                   1408:   ip_addr rtid;
                   1409:   u32 br_metric;
                   1410:   struct ospf_area *atmp;
                   1411: 
                   1412:   OSPF_TRACE(D_EVENTS, "Starting routing table calculation for ext routes");
                   1413: 
                   1414:   WALK_SLIST(en, p->lsal)
                   1415:   {
                   1416:     orta nfa = {};
                   1417: 
                   1418:     /* 16.4. (1) */
                   1419:     if ((en->lsa_type != LSA_T_EXT) && (en->lsa_type != LSA_T_NSSA))
                   1420:       continue;
                   1421: 
                   1422:     if (en->lsa.age == LSA_MAXAGE)
                   1423:       continue;
                   1424: 
                   1425:     /* 16.4. (2) */
                   1426:     if (en->lsa.rt == p->router_id)
                   1427:       continue;
                   1428: 
                   1429:     DBG("%s: Working on LSA. ID: %R, RT: %R, Type: %u\n",
                   1430:        p->p.name, en->lsa.id, en->lsa.rt, en->lsa_type);
                   1431: 
                   1432:     lsa_parse_ext(en, ospf_is_v2(p), &rt);
                   1433: 
                   1434:     if (rt.metric == LSINFINITY)
                   1435:       continue;
                   1436: 
                   1437:     if (rt.pxopts & OPT_PX_NU)
                   1438:       continue;
                   1439: 
                   1440:     if (rt.pxlen < 0 || rt.pxlen > MAX_PREFIX_LENGTH)
                   1441:     {
                   1442:       log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
                   1443:          p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
                   1444:       continue;
                   1445:     }
                   1446: 
                   1447: 
                   1448:     /* 16.4. (3) */
                   1449:     /* If there are more areas, we already precomputed preferred ASBR
                   1450:        entries in ospf_rt_abr1() and stored them in the backbone
                   1451:        table. For NSSA, we examine the area to which the LSA is assigned */
                   1452:     if (en->lsa_type == LSA_T_EXT)
                   1453:       atmp = ospf_main_area(p);
                   1454:     else /* NSSA */
                   1455:       atmp = ospf_find_area(p, en->domain);
                   1456: 
                   1457:     if (!atmp)
                   1458:       continue;                        /* Should not happen */
                   1459: 
                   1460:     rtid = ipa_from_rid(en->lsa.rt);
                   1461:     nf1 = fib_find(&atmp->rtr, &rtid, MAX_PREFIX_LENGTH);
                   1462: 
                   1463:     if (!nf1 || !nf1->n.type)
                   1464:       continue;                        /* No AS boundary router found */
                   1465: 
                   1466:     if (!(nf1->n.options & ORTA_ASBR))
                   1467:       continue;                        /* It is not ASBR */
                   1468: 
                   1469:     /* 16.4. (3) NSSA - special rule for default routes */
                   1470:     /* ABR should use default only if P-bit is set and summaries are active */
                   1471:     if ((en->lsa_type == LSA_T_NSSA) && ipa_zero(rt.ip) && (rt.pxlen == 0) &&
                   1472:        (p->areano > 1) && !(rt.propagate && atmp->ac->summary))
                   1473:       continue;
                   1474: 
                   1475:     if (!rt.fbit)
                   1476:     {
                   1477:       nf2 = nf1;
                   1478:       nfa.nhs = nf1->n.nhs;
                   1479:       br_metric = nf1->n.metric1;
                   1480:     }
                   1481:     else
                   1482:     {
                   1483:       nf2 = ospf_fib_route(&p->rtf, rt.fwaddr, MAX_PREFIX_LENGTH);
                   1484:       if (!nf2)
                   1485:        continue;
                   1486: 
                   1487:       if (en->lsa_type == LSA_T_EXT)
                   1488:       {
                   1489:        /* For ext routes, we accept intra-area or inter-area routes */
                   1490:        if ((nf2->n.type != RTS_OSPF) && (nf2->n.type != RTS_OSPF_IA))
                   1491:          continue;
                   1492:       }
                   1493:       else /* NSSA */
                   1494:       {
                   1495:        /* For NSSA routes, we accept just intra-area in the same area */
                   1496:        if ((nf2->n.type != RTS_OSPF) || (nf2->n.oa != atmp))
                   1497:          continue;
                   1498:       }
                   1499: 
                   1500:       /* Next-hop is a part of a configured stubnet */
                   1501:       if (!nf2->n.nhs)
                   1502:        continue;
                   1503: 
                   1504:       nfa.nhs = nf2->n.nhs;
                   1505:       br_metric = nf2->n.metric1;
                   1506: 
                   1507:       /* Replace device nexthops with nexthops to forwarding address from LSA */
                   1508:       if (has_device_nexthops(nfa.nhs))
                   1509:       {
                   1510:        nfa.nhs = fix_device_nexthops(p, nfa.nhs, rt.fwaddr);
                   1511:        nfa.nhs_reuse = 1;
                   1512:       }
                   1513:     }
                   1514: 
                   1515:     if (rt.ebit)
                   1516:     {
                   1517:       nfa.type = RTS_OSPF_EXT2;
                   1518:       nfa.metric1 = br_metric;
                   1519:       nfa.metric2 = rt.metric;
                   1520:     }
                   1521:     else
                   1522:     {
                   1523:       nfa.type = RTS_OSPF_EXT1;
                   1524:       nfa.metric1 = br_metric + rt.metric;
                   1525:       nfa.metric2 = LSINFINITY;
                   1526:     }
                   1527: 
                   1528:     /* Mark the LSA as reachable */
                   1529:     en->color = INSPF;
                   1530: 
                   1531:     /* Whether the route is preferred in route selection according to 16.4.1 */
                   1532:     nfa.options = epath_preferred(&nf2->n) ? ORTA_PREF : 0;
                   1533:     if (en->lsa_type == LSA_T_NSSA)
                   1534:     {
                   1535:       nfa.options |= ORTA_NSSA;
                   1536:       if (rt.propagate)
                   1537:        nfa.options |= ORTA_PROP;
                   1538:     }
                   1539: 
                   1540:     nfa.tag = rt.tag;
                   1541:     nfa.rid = en->lsa.rt;
                   1542:     nfa.oa = atmp; /* undefined in RFC 2328 */
                   1543:     nfa.en = en; /* store LSA for later (NSSA processing) */
                   1544: 
                   1545:     ri_install_ext(p, rt.ip, rt.pxlen, &nfa);
                   1546:   }
                   1547: }
                   1548: 
                   1549: /* Cleanup of routing tables and data */
                   1550: void
                   1551: ospf_rt_reset(struct ospf_proto *p)
                   1552: {
                   1553:   struct ospf_area *oa;
                   1554:   struct top_hash_entry *en;
                   1555:   struct area_net *anet;
                   1556:   ort *ri;
                   1557: 
                   1558:   /* Reset old routing table */
                   1559:   FIB_WALK(&p->rtf, nftmp)
                   1560:   {
                   1561:     ri = (ort *) nftmp;
                   1562:     ri->area_net = 0;
                   1563:     ri->keep = 0;
                   1564:     reset_ri(ri);
                   1565:   }
                   1566:   FIB_WALK_END;
                   1567: 
                   1568:   /* Reset SPF data in LSA db */
                   1569:   WALK_SLIST(en, p->lsal)
                   1570:   {
                   1571:     en->color = OUTSPF;
                   1572:     en->dist = LSINFINITY;
                   1573:     en->nhs = NULL;
                   1574:     en->lb = IPA_NONE;
                   1575: 
                   1576:     if (en->mode == LSA_M_RTCALC)
                   1577:       en->mode = LSA_M_STALE;
                   1578:   }
                   1579: 
                   1580:   WALK_LIST(oa, p->area_list)
                   1581:   {
                   1582:     /* Reset ASBR routing tables */
                   1583:     FIB_WALK(&oa->rtr, nftmp)
                   1584:     {
                   1585:       ri = (ort *) nftmp;
                   1586:       reset_ri(ri);
                   1587:     }
                   1588:     FIB_WALK_END;
                   1589: 
                   1590:     /* Reset condensed area networks */
                   1591:     if (p->areano > 1)
                   1592:     {
                   1593:       FIB_WALK(&oa->net_fib, nftmp)
                   1594:       {
                   1595:        anet = (struct area_net *) nftmp;
                   1596:        anet->active = 0;
                   1597:        anet->metric = 0;
                   1598:       }
                   1599:       FIB_WALK_END;
                   1600: 
                   1601:       FIB_WALK(&oa->enet_fib, nftmp)
                   1602:       {
                   1603:        anet = (struct area_net *) nftmp;
                   1604:        anet->active = 0;
                   1605:        anet->metric = 0;
                   1606:       }
                   1607:       FIB_WALK_END;
                   1608:     }
                   1609:   }
                   1610: }
                   1611: 
                   1612: /**
                   1613:  * ospf_rt_spf - calculate internal routes
                   1614:  * @p: OSPF protocol instance
                   1615:  *
                   1616:  * Calculation of internal paths in an area is described in 16.1 of RFC 2328.
                   1617:  * It's based on Dijkstra's shortest path tree algorithms.
                   1618:  * This function is invoked from ospf_disp().
                   1619:  */
                   1620: void
                   1621: ospf_rt_spf(struct ospf_proto *p)
                   1622: {
                   1623:   struct ospf_area *oa;
                   1624: 
                   1625:   if (p->areano == 0)
                   1626:     return;
                   1627: 
                   1628:   OSPF_TRACE(D_EVENTS, "Starting routing table calculation");
                   1629: 
                   1630:   /* 16. (1) */
                   1631:   ospf_rt_reset(p);
                   1632: 
                   1633:   /* 16. (2) */
                   1634:   WALK_LIST(oa, p->area_list)
                   1635:     ospf_rt_spfa(oa);
                   1636: 
                   1637:   /* 16. (3) */
                   1638:   ospf_rt_sum(ospf_main_area(p));
                   1639: 
                   1640:   /* 16. (4) */
                   1641:   WALK_LIST(oa, p->area_list)
                   1642:     if (oa->trcap && (oa->areaid != 0))
                   1643:       ospf_rt_sum_tr(oa);
                   1644: 
                   1645:   if (p->areano > 1)
                   1646:     ospf_rt_abr1(p);
                   1647: 
                   1648:   /* 16. (5) */
                   1649:   ospf_ext_spf(p);
                   1650: 
                   1651:   if (p->areano > 1)
                   1652:     ospf_rt_abr2(p);
                   1653: 
                   1654:   rt_sync(p);
                   1655:   lp_flush(p->nhpool);
                   1656: 
                   1657:   p->calcrt = 0;
                   1658: }
                   1659: 
                   1660: 
                   1661: static inline int
                   1662: inherit_nexthops(struct mpnh *pn)
                   1663: {
                   1664:   /* Proper nexthops (with defined GW) or dummy vlink nexthops (without iface) */
                   1665:   return pn && (ipa_nonzero(pn->gw) || !pn->iface);
                   1666: }
                   1667: 
                   1668: static struct mpnh *
                   1669: calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
                   1670:              struct top_hash_entry *par, int pos)
                   1671: {
                   1672:   struct ospf_proto *p = oa->po;
                   1673:   struct mpnh *pn = par->nhs;
                   1674:   struct ospf_iface *ifa;
                   1675:   u32 rid = en->lsa.rt;
                   1676: 
                   1677:   /* 16.1.1. The next hop calculation */
                   1678:   DBG("     Next hop calculating for id: %R rt: %R type: %u\n",
                   1679:       en->lsa.id, en->lsa.rt, en->lsa_type);
                   1680: 
                   1681:   /* Usually, we inherit parent nexthops */
                   1682:   if (inherit_nexthops(pn))
                   1683:     return pn;
                   1684: 
                   1685:   /*
                   1686:    * There are three cases:
                   1687:    * 1) en is a local network (and par is root)
                   1688:    * 2) en is a ptp or ptmp neighbor (and par is root)
                   1689:    * 3) en is a bcast or nbma neighbor (and par is local network)
                   1690:    */
                   1691: 
                   1692:   /* The first case - local network */
                   1693:   if ((en->lsa_type == LSA_T_NET) && (par == oa->rt))
                   1694:   {
                   1695:     ifa = rt_pos_to_ifa(oa, pos);
                   1696:     if (!ifa)
                   1697:       return NULL;
                   1698: 
                   1699:     return new_nexthop(p, IPA_NONE, ifa->iface, ifa->ecmp_weight);
                   1700:   }
                   1701: 
                   1702:   /* The second case - ptp or ptmp neighbor */
                   1703:   if ((en->lsa_type == LSA_T_RT) && (par == oa->rt))
                   1704:   {
                   1705:     ifa = rt_pos_to_ifa(oa, pos);
                   1706:     if (!ifa)
                   1707:       return NULL;
                   1708: 
                   1709:     if (ifa->type == OSPF_IT_VLINK)
                   1710:       return new_nexthop(p, IPA_NONE, NULL, 0);
                   1711: 
                   1712:     struct ospf_neighbor *m = find_neigh(ifa, rid);
                   1713:     if (!m || (m->state != NEIGHBOR_FULL))
                   1714:       return NULL;
                   1715: 
                   1716:     return new_nexthop(p, m->ip, ifa->iface, ifa->ecmp_weight);
                   1717:   }
                   1718: 
                   1719:   /* The third case - bcast or nbma neighbor */
                   1720:   if ((en->lsa_type == LSA_T_RT) && (par->lsa_type == LSA_T_NET))
                   1721:   {
                   1722:     /* par->nhi should be defined from parent's calc_next_hop() */
                   1723:     if (!pn)
                   1724:       goto bad;
                   1725: 
                   1726:     if (ospf_is_v2(p))
                   1727:     {
                   1728:       /*
                   1729:        * In this case, next-hop is the same as link-back, which is
                   1730:        * already computed in link_back().
                   1731:        */
                   1732:       if (ipa_zero(en->lb))
                   1733:        goto bad;
                   1734: 
                   1735:       return new_nexthop(p, en->lb, pn->iface, pn->weight);
                   1736:     }
                   1737:     else /* OSPFv3 */
                   1738:     {
                   1739:       /*
                   1740:        * Next-hop is taken from lladdr field of Link-LSA, en->lb_id
                   1741:        * is computed in link_back().
                   1742:        */
                   1743:       struct top_hash_entry *lhe;
                   1744:       lhe = ospf_hash_find(p->gr, pn->iface->index, en->lb_id, rid, LSA_T_LINK);
                   1745: 
                   1746:       if (!lhe)
                   1747:        return NULL;
                   1748: 
                   1749:       struct ospf_lsa_link *llsa = lhe->lsa_body;
                   1750: 
                   1751:       if (ip6_zero(llsa->lladdr))
                   1752:        return NULL;
                   1753: 
                   1754:       return new_nexthop(p, ipa_from_ip6(llsa->lladdr), pn->iface, pn->weight);
                   1755:     }
                   1756:   }
                   1757: 
                   1758:  bad:
                   1759:   /* Probably bug or some race condition, we log it */
                   1760:   log(L_ERR "%s: Unexpected case in next hop calculation", p->p.name);
                   1761:   return NULL;
                   1762: }
                   1763: 
                   1764: 
                   1765: /* Add LSA into list of candidates in Dijkstra's algorithm */
                   1766: static void
                   1767: add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par,
                   1768:         u32 dist, struct ospf_area *oa, int pos)
                   1769: {
                   1770:   struct ospf_proto *p = oa->po;
                   1771:   node *prev, *n;
                   1772:   int added = 0;
                   1773:   struct top_hash_entry *act;
                   1774: 
                   1775:   /* 16.1. (2b) */
                   1776:   if (en == NULL)
                   1777:     return;
                   1778:   if (en->lsa.age == LSA_MAXAGE)
                   1779:     return;
                   1780: 
                   1781:   if (ospf_is_v3(p) && (en->lsa_type == LSA_T_RT))
                   1782:   {
                   1783:     /* In OSPFv3, check V6 flag */
                   1784:     struct ospf_lsa_rt *rt = en->lsa_body;
                   1785:     if (!(rt->options & OPT_V6))
                   1786:       return;
                   1787:   }
                   1788: 
                   1789:   /* 16.1. (2c) */
                   1790:   if (en->color == INSPF)
                   1791:     return;
                   1792: 
                   1793:   /* 16.1. (2d), also checks that dist < LSINFINITY */
                   1794:   if (dist > en->dist)
                   1795:     return;
                   1796: 
                   1797:   /* We should check whether there is a reverse link from en to par, */
                   1798:   if (!link_back(oa, en, par))
                   1799:     return;
                   1800: 
                   1801:   struct mpnh *nhs = calc_next_hop(oa, en, par, pos);
                   1802:   if (!nhs)
                   1803:   {
                   1804:     log(L_WARN "%s: Cannot find next hop for LSA (Type: %04x, Id: %R, Rt: %R)",
                   1805:        p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
                   1806:     return;
                   1807:   }
                   1808: 
                   1809:   /* If en->dist > 0, we know that en->color == CANDIDATE and en->nhs is defined. */
                   1810:   if ((dist == en->dist) && !nh_is_vlink(en->nhs))
                   1811:   {
                   1812:     /*
                   1813:      * For multipath, we should merge nexthops. We merge regular nexthops only.
                   1814:      * Dummy vlink nexthops are less preferred and handled as a special case.
                   1815:      *
                   1816:      * During merging, new nexthops (nhs) can be reused if they are not
                   1817:      * inherited from the parent (i.e. they are allocated in calc_next_hop()).
                   1818:      * Current nexthops (en->nhs) can be reused if they weren't inherited in
                   1819:      * previous steps (that is stored in nhs_reuse, i.e. created by merging or
                   1820:      * allocated in calc_next_hop()).
                   1821:      *
                   1822:      * Generally, a node first inherits shared nexthops from its parent and
                   1823:      * later possibly gets reusable (private) copy during merging. This is more
                   1824:      * or less same for both top_hash_entry nodes and orta nodes.
                   1825:      *
                   1826:      * Note that when a child inherits a private nexthop from its parent, it
                   1827:      * should make the nexthop shared for both parent and child, while we only
                   1828:      * update nhs_reuse for the child node. This makes nhs_reuse field for the
                   1829:      * parent technically incorrect, but it is not a problem as parent's nhs
                   1830:      * will not be modified (and nhs_reuse examined) afterwards.
                   1831:      */
                   1832: 
                   1833:     /* Keep old ones */
                   1834:     if (!p->ecmp || nh_is_vlink(nhs) || (nhs == en->nhs))
                   1835:       return;
                   1836: 
                   1837:     /* Merge old and new */
                   1838:     int new_reuse = (par->nhs != nhs);
                   1839:     en->nhs = mpnh_merge(en->nhs, nhs, en->nhs_reuse, new_reuse, p->ecmp, p->nhpool);
                   1840:     en->nhs_reuse = 1;
                   1841:     return;
                   1842:   }
                   1843: 
                   1844:   DBG("     Adding candidate: rt: %R, id: %R, type: %u\n",
                   1845:       en->lsa.rt, en->lsa.id, en->lsa_type);
                   1846: 
                   1847:   if (en->color == CANDIDATE)
                   1848:   {                            /* We found a shorter path */
                   1849:     rem_node(&en->cn);
                   1850:   }
                   1851:   en->nhs = nhs;
                   1852:   en->dist = dist;
                   1853:   en->color = CANDIDATE;
                   1854:   en->nhs_reuse = (par->nhs != nhs);
                   1855: 
                   1856:   prev = NULL;
                   1857: 
                   1858:   if (EMPTY_LIST(*l))
                   1859:   {
                   1860:     add_head(l, &en->cn);
                   1861:   }
                   1862:   else
                   1863:   {
                   1864:     WALK_LIST(n, *l)
                   1865:     {
                   1866:       act = SKIP_BACK(struct top_hash_entry, cn, n);
                   1867:       if ((act->dist > dist) ||
                   1868:          ((act->dist == dist) && (act->lsa_type == LSA_T_RT)))
                   1869:       {
                   1870:        if (prev == NULL)
                   1871:          add_head(l, &en->cn);
                   1872:        else
                   1873:          insert_node(&en->cn, prev);
                   1874:        added = 1;
                   1875:        break;
                   1876:       }
                   1877:       prev = n;
                   1878:     }
                   1879: 
                   1880:     if (!added)
                   1881:     {
                   1882:       add_tail(l, &en->cn);
                   1883:     }
                   1884:   }
                   1885: }
                   1886: 
                   1887: static inline int
                   1888: ort_changed(ort *nf, rta *nr)
                   1889: {
                   1890:   rta *or = nf->old_rta;
                   1891:   return !or ||
                   1892:     (nf->n.metric1 != nf->old_metric1) || (nf->n.metric2 != nf->old_metric2) ||
                   1893:     (nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid) ||
                   1894:     (nr->source != or->source) || (nr->dest != or->dest) ||
                   1895:     (nr->iface != or->iface) || !ipa_equal(nr->gw, or->gw) ||
                   1896:     !mpnh_same(nr->nexthops, or->nexthops);
                   1897: }
                   1898: 
                   1899: static void
                   1900: rt_sync(struct ospf_proto *p)
                   1901: {
                   1902:   struct top_hash_entry *en;
                   1903:   struct fib_iterator fit;
                   1904:   struct fib *fib = &p->rtf;
                   1905:   ort *nf;
                   1906:   struct ospf_area *oa;
                   1907: 
                   1908:   /* This is used for forced reload of routes */
                   1909:   int reload = (p->calcrt == 2);
                   1910: 
                   1911:   OSPF_TRACE(D_EVENTS, "Starting routing table synchronisation");
                   1912: 
                   1913:   DBG("Now syncing my rt table with nest's\n");
                   1914:   FIB_ITERATE_INIT(&fit, fib);
                   1915: again1:
                   1916:   FIB_ITERATE_START(fib, &fit, nftmp)
                   1917:   {
                   1918:     nf = (ort *) nftmp;
                   1919: 
                   1920:     /* Sanity check of next-hop addresses, failure should not happen */
                   1921:     if (nf->n.type)
                   1922:     {
                   1923:       struct mpnh *nh;
                   1924:       for (nh = nf->n.nhs; nh; nh = nh->next)
                   1925:        if (ipa_nonzero(nh->gw))
                   1926:        {
                   1927:          neighbor *ng = neigh_find2(&p->p, &nh->gw, nh->iface, 0);
                   1928:          if (!ng || (ng->scope == SCOPE_HOST))
                   1929:            { reset_ri(nf); break; }
                   1930:        }
                   1931:     }
                   1932: 
                   1933:     /* Remove configured stubnets but keep the entries */
                   1934:     if (nf->n.type && !nf->n.nhs)
                   1935:     {
                   1936:       reset_ri(nf);
                   1937:       nf->keep = 1;
                   1938:     }
                   1939: 
                   1940:     if (nf->n.type) /* Add the route */
                   1941:     {
                   1942:       rta a0 = {
                   1943:        .src = p->p.main_source,
                   1944:        .source = nf->n.type,
                   1945:        .scope = SCOPE_UNIVERSE,
                   1946:        .cast = RTC_UNICAST
                   1947:       };
                   1948: 
                   1949:       if (nf->n.nhs->next)
                   1950:       {
                   1951:        a0.dest = RTD_MULTIPATH;
                   1952:        a0.nexthops = nf->n.nhs;
                   1953:       }
                   1954:       else if (ipa_nonzero(nf->n.nhs->gw))
                   1955:       {
                   1956:        a0.dest = RTD_ROUTER;
                   1957:        a0.iface = nf->n.nhs->iface;
                   1958:        a0.gw = nf->n.nhs->gw;
                   1959:       }
                   1960:       else
                   1961:       {
                   1962:        a0.dest = RTD_DEVICE;
                   1963:        a0.iface = nf->n.nhs->iface;
                   1964:       }
                   1965: 
                   1966:       if (reload || ort_changed(nf, &a0))
                   1967:       {
                   1968:        net *ne = net_get(p->p.table, nf->fn.prefix, nf->fn.pxlen);
                   1969:        rta *a = rta_lookup(&a0);
                   1970:        rte *e = rte_get_temp(a);
                   1971: 
                   1972:        rta_free(nf->old_rta);
                   1973:        nf->old_rta = rta_clone(a);
                   1974:        e->u.ospf.metric1 = nf->old_metric1 = nf->n.metric1;
                   1975:        e->u.ospf.metric2 = nf->old_metric2 = nf->n.metric2;
                   1976:        e->u.ospf.tag = nf->old_tag = nf->n.tag;
                   1977:        e->u.ospf.router_id = nf->old_rid = nf->n.rid;
                   1978:        e->pflags = 0;
                   1979:        e->net = ne;
                   1980:        e->pref = p->p.preference;
                   1981: 
                   1982:        DBG("Mod rte type %d - %I/%d via %I on iface %s, met %d\n",
                   1983:            a0.source, nf->fn.prefix, nf->fn.pxlen, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
                   1984:        rte_update(&p->p, ne, e);
                   1985:       }
                   1986:     }
                   1987:     else if (nf->old_rta)
                   1988:     {
                   1989:       /* Remove the route */
                   1990:       rta_free(nf->old_rta);
                   1991:       nf->old_rta = NULL;
                   1992: 
                   1993:       net *ne = net_get(p->p.table, nf->fn.prefix, nf->fn.pxlen);
                   1994:       rte_update(&p->p, ne, NULL);
                   1995:     }
                   1996: 
                   1997:     /* Remove unused rt entry, some special entries are persistent */
                   1998:     if (!nf->n.type && !nf->external_rte && !nf->area_net && !nf->keep)
                   1999:     {
                   2000:       FIB_ITERATE_PUT(&fit, nftmp);
                   2001:       fib_delete(fib, nftmp);
                   2002:       goto again1;
                   2003:     }
                   2004:   }
                   2005:   FIB_ITERATE_END(nftmp);
                   2006: 
                   2007: 
                   2008:   WALK_LIST(oa, p->area_list)
                   2009:   {
                   2010:     /* Cleanup ASBR hash tables */
                   2011:     FIB_ITERATE_INIT(&fit, &oa->rtr);
                   2012: again2:
                   2013:     FIB_ITERATE_START(&oa->rtr, &fit, nftmp)
                   2014:     {
                   2015:       nf = (ort *) nftmp;
                   2016: 
                   2017:       if (!nf->n.type)
                   2018:       {
                   2019:        FIB_ITERATE_PUT(&fit, nftmp);
                   2020:        fib_delete(&oa->rtr, nftmp);
                   2021:        goto again2;
                   2022:       }
                   2023:     }
                   2024:     FIB_ITERATE_END(nftmp);
                   2025:   }
                   2026: 
                   2027:   /* Cleanup stale LSAs */
                   2028:   WALK_SLIST(en, p->lsal)
                   2029:     if (en->mode == LSA_M_STALE)
                   2030:       ospf_flush_lsa(p, en);
                   2031: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>