diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 1caf8047e4..a5397b5fdb 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -60,6 +60,7 @@ /* OSPF LSA header. */ struct lsa_header { uint16_t ls_age; +#define DO_NOT_AGE 0x8000 uint8_t options; uint8_t type; struct in_addr id; @@ -233,6 +234,9 @@ enum lsid_status { LSID_AVAILABLE = 0, LSID_CHANGE, LSID_NOT_AVAILABLE }; || (type == OSPF_SUMMARY_LSA) || (type == OSPF_ASBR_SUMMARY_LSA) \ || (type == OSPF_AS_EXTERNAL_LSA) || (type == OSPF_AS_NSSA_LSA)) +#define OSPF_FR_CONFIG(o, a) \ + (o->fr_configured || ((a != NULL) ? a->fr_info.configured : 0)) + /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ extern struct timeval int2tv(int); @@ -358,4 +362,24 @@ extern void ospf_check_and_gen_init_seq_lsa(struct ospf_interface *oi, extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, int type); extern void ospf_maxage_lsa_remover(struct thread *thread); +extern bool ospf_check_dna_lsa(const struct ospf_lsa *lsa); +extern void ospf_refresh_area_self_lsas(struct ospf_area *area); + +/** @brief Check if the LSA is an indication LSA. + * @param lsa pointer. + * @return true or false based on lsa info. + */ +static inline bool ospf_check_indication_lsa(struct ospf_lsa *lsa) +{ + struct summary_lsa *sl = NULL; + + if (lsa->data->type == OSPF_ASBR_SUMMARY_LSA) { + sl = (struct summary_lsa *)lsa->data; + if ((GET_METRIC(sl->metric) == OSPF_LS_INFINITY) && + !CHECK_FLAG(lsa->data->options, OSPF_OPTION_DC)) + return true; + } + + return false; +} #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index b22fe5d99b..4680f496e1 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -43,6 +43,7 @@ #include "ospfd/ospf_network.h" #include "ospfd/ospf_interface.h" #include "ospfd/ospf_ism.h" +#include "ospfd/ospf_abr.h" #include "ospfd/ospf_asbr.h" #include "ospfd/ospf_lsa.h" #include "ospfd/ospf_lsdb.h" @@ -3332,6 +3333,14 @@ static int ospf_make_hello(struct ospf_interface *oi, struct stream *s) else stream_putw(s, 0); /* hello-interval of 0 for fast-hellos */ + /* Check if flood-reduction is enabled, + * if yes set the DC bit in the options. + */ + if (OSPF_FR_CONFIG(oi->ospf, oi->area)) + SET_FLAG(OPTIONS(oi), OSPF_OPTION_DC); + else if (CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_DC)) + UNSET_FLAG(OPTIONS(oi), OSPF_OPTION_DC); + if (IS_DEBUG_OSPF_EVENT) zlog_debug("%s: options: %x, int: %s", __func__, OPTIONS(oi), IF_NAME(oi)); @@ -3420,6 +3429,8 @@ static int ospf_make_db_desc(struct ospf_interface *oi, options = OPTIONS(oi); if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) SET_FLAG(options, OSPF_OPTION_O); + if (OSPF_FR_CONFIG(oi->ospf, oi->area)) + SET_FLAG(options, OSPF_OPTION_DC); stream_putc(s, options); /* DD flags */ diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 6360d8ec60..9b9b61bdb3 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -986,6 +986,16 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs) &or->u.std.area_id); } + /* Unset the DNA flag on lsa, if the router + * which generated this lsa is no longer + * reachabele. + */ + (CHECK_FLAG(or->u.std.origin->ls_age, + DO_NOT_AGE)) + ? UNSET_FLAG(or->u.std.origin->ls_age, + DO_NOT_AGE) + : 0; + listnode_delete(paths, or); ospf_route_free(or); }