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

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