diff options
Diffstat (limited to 'ospfd/ospf_lsa.c')
-rw-r--r-- | ospfd/ospf_lsa.c | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 5d5ad08a..34cbc446 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -615,7 +615,8 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi) link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); links++; - zlog_info ("PointToMultipoint: running ptomultip_set"); + if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) + zlog_info ("PointToMultipoint: running ptomultip_set"); /* Search neighbor, */ for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) @@ -628,8 +629,9 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi) link_info_set (s, nbr->router_id, oi->address->u.prefix4, LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost); links++; - zlog_info ("PointToMultipoint: set link to %s", - inet_ntoa(oi->address->u.prefix4)); + if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) + zlog_info ("PointToMultipoint: set link to %s", + inet_ntoa(oi->address->u.prefix4)); } return links; @@ -648,7 +650,7 @@ router_lsa_link_set (struct stream *s, struct ospf_area *area) struct interface *ifp = oi->ifp; /* Check interface is up, OSPF is enable. */ - if (if_is_up (ifp)) + if (if_is_operative (ifp)) { if (oi->state != ISM_Down) { @@ -1402,7 +1404,7 @@ ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop) { struct ospf_interface *oi = getdata (n1); - if (if_is_up (oi->ifp)) + if (if_is_operative (oi->ifp)) if (oi->address->family == AF_INET) if (prefix_match (oi->address, &nh)) return nexthop; @@ -1423,7 +1425,7 @@ ospf_get_ip_from_ifp (struct ospf_interface *oi) fwd.s_addr = 0; - if (if_is_up (oi->ifp)) + if (if_is_operative (oi->ifp)) return oi->address->u.prefix4; return fwd; @@ -1444,7 +1446,7 @@ ospf_get_nssa_ip (struct ospf_area *area) { struct ospf_interface *oi = getdata (n1); - if (if_is_up (oi->ifp)) + if (if_is_operative (oi->ifp)) if (oi->area->external_routing == OSPF_AREA_NSSA) if (oi->address && oi->address->family == AF_INET) { @@ -1454,6 +1456,8 @@ ospf_get_nssa_ip (struct ospf_area *area) return oi->address->u.prefix4; } } + if (best_default.s_addr != 0) + return best_default; if (best_default.s_addr != 0) return best_default; @@ -1632,7 +1636,6 @@ ospf_install_flood_nssa (struct ospf *ospf, /* make lsa duplicate, lock=1 */ new2 = ospf_lsa_dup (lsa); - new2->area = area; new2->data->type = OSPF_AS_NSSA_LSA; @@ -1662,13 +1665,13 @@ ospf_install_flood_nssa (struct ospf *ospf, if (extlsa->e[0].fwd_addr.s_addr == 0) extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */ - if (IS_DEBUG_OSPF_NSSA) - if (extlsa->e[0].fwd_addr.s_addr == 0) - { - zlog_info ("LSA[Type-7]: Could not build FWD-ADDR"); - ospf_lsa_discard(new2); - return; - } + if (extlsa->e[0].fwd_addr.s_addr == 0) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("LSA[Type-7]: Could not build FWD-ADDR"); + ospf_lsa_discard(new2); + return; + } } /* Re-calculate checksum. */ ospf_lsa_checksum (new2->data); @@ -1857,6 +1860,39 @@ ospf_default_originate_timer (struct thread *thread) return 0; } +#ifdef HAVE_NSSA +/* Flush any NSSA LSAs for given prefix */ +void +ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p) +{ + struct listnode *node; + struct ospf_lsa *lsa; + struct ospf_area *area; + + for (node = listhead (ospf->areas); node; nextnode (node)) + { + if (((area = getdata (node)) != NULL) + && (area->external_routing == OSPF_AREA_NSSA)) + { + if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix, + ospf->router_id))) + { + if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) + zlog_warn ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB", + inet_ntoa (p->prefix), p->prefixlen); + continue; + } + ospf_ls_retransmit_delete_nbr_area (area, lsa); + if (!IS_LSA_MAXAGE (lsa)) + { + ospf_refresher_unregister_lsa (ospf, lsa); + ospf_lsa_flush_area (lsa, area); + } + } + } +} +#endif /* HAVE_NSSA */ + /* Flush an AS-external-LSA from LSDB and routing domain. */ void ospf_external_lsa_flush (struct ospf *ospf, @@ -1877,6 +1913,13 @@ ospf_external_lsa_flush (struct ospf *ospf, inet_ntoa (p->prefix), p->prefixlen); return; } +#ifdef HAVE_NSSA + /* If LSA is selforiginated and there is NSSA area, flush + * Type-7 LSA's at first. */ + + if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)) + ospf_nssa_lsa_flush (ospf, p); +#endif /* HAVE_NSSA */ /* Sweep LSA from Link State Retransmit List. */ ospf_ls_retransmit_delete_nbr_as (ospf, lsa); @@ -2186,6 +2229,13 @@ ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new, ospf_ase_incremental_update (ospf, new); } +#ifdef HAVE_NSSA + /* There is no point to register selforiginate Type-7 LSA for + * refreshing. We rely on refreshing Type-5 LSA's */ + if (IS_LSA_SELF (new) && (new->data->type == OSPF_AS_NSSA_LSA)) + return new; +#endif /* HAVE_NSSA */ + /* Register self-originated LSA to refresh queue. */ if (IS_LSA_SELF (new)) ospf_refresher_register_lsa (ospf, new); @@ -2216,6 +2266,12 @@ ospf_discard_from_db (struct ospf *ospf, ospf_ls_retransmit_delete_nbr_as (ospf, old); ospf_ase_unregister_external_lsa (old, ospf); break; +#ifdef HAVE_NSSA + case OSPF_AS_NSSA_LSA: + ospf_ls_retransmit_delete_nbr_area (old->area, old); + ospf_ase_unregister_external_lsa (old, ospf); + break; +#endif /* HAVE_NSSA */ default: ospf_ls_retransmit_delete_nbr_area (old->area, old); break; @@ -2587,7 +2643,6 @@ ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa) ospf_spf_calculate_schedule (ospf); break; } - ospf_lsa_maxage (ospf, lsa); } @@ -2623,9 +2678,13 @@ ospf_lsa_maxage_walker (struct thread *thread) LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) ospf_lsa_maxage_walker_remover (ospf, lsa); #endif /* HAVE_OPAQUE_LSA */ +#ifdef HAVE_NSSA + LSDB_LOOP (NSSA_LSDB (area), rn, lsa) + ospf_lsa_maxage_walker_remover (ospf, lsa); +#endif /* HAVE_NSSA */ } - /* for AS-eternal-LSAs. */ + /* for AS-external-LSAs. */ if (ospf->lsdb) { LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) @@ -2676,6 +2735,9 @@ struct ospf_lsa * ospf_lsa_lookup (struct ospf_area *area, u_int32_t type, struct in_addr id, struct in_addr adv_router) { + struct ospf *ospf = ospf_lookup(); + assert(ospf); + switch (type) { case OSPF_ROUTER_LSA: @@ -2695,7 +2757,7 @@ ospf_lsa_lookup (struct ospf_area *area, u_int32_t type, #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA: #endif /* HAVE_OPAQUE_LSA */ - return ospf_lsdb_lookup_by_id (area->ospf->lsdb, type, id, adv_router); + return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router); break; default: break; @@ -2840,7 +2902,7 @@ ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2) if (l1->data->length == 0) return 1; - assert (l1->data->length > OSPF_LSA_HEADER_SIZE); + assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE); p1 = (char *) l1->data; p2 = (char *) l2->data; @@ -3218,9 +3280,9 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) case OSPF_OPAQUE_AS_LSA: ospf_opaque_lsa_refresh (lsa); break; +#endif /* HAVE_OPAQUE_LSA */ default: break; -#endif /* HAVE_OPAQUE_LSA */ } } @@ -3260,6 +3322,8 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) ospf->lsa_refresh_queue.qs[index] = list_new (); listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa)); lsa->refresh_list = index; + if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) + zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index); } } @@ -3324,7 +3388,7 @@ ospf_lsa_refresh_walker (struct thread *t) next = node->next; if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p", lsa); + zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i); list_delete_node (refresh_list, node); ospf_lsa_unlock (lsa); |