diff options
Diffstat (limited to 'ospfd/ospf_zebra.c')
| -rw-r--r-- | ospfd/ospf_zebra.c | 259 |
1 files changed, 199 insertions, 60 deletions
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 9fa6a59a72..e7dbdbd9af 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -463,7 +463,7 @@ static int ospf_external_lsa_default_routemap_timer(struct thread *thread) if (ret && !lsa) ospf_external_lsa_originate(ospf, default_ei); else if (ret && lsa && IS_LSA_MAXAGE(lsa)) - ospf_external_lsa_refresh(ospf, lsa, default_ei, true); + ospf_external_lsa_refresh(ospf, lsa, default_ei, true, false); else if (!ret && lsa) ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &default_ei->p, 0); @@ -902,8 +902,7 @@ int ospf_external_info_apply_default_routemap(struct ospf *ospf, if (red && ROUTEMAP_NAME(red)) { route_map_result_t ret; - ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, - RMAP_OSPF, ei); + ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, ei); if (ret == RMAP_DENYMATCH) { ei->route_map_set = save_values; @@ -964,7 +963,7 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, /* If permit and default already advertise then return. */ if (lsa && !IS_LSA_MAXAGE(lsa)) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Defult lsa already originated"); + zlog_debug("Default lsa already originated"); return true; } @@ -973,7 +972,8 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, if (lsa && IS_LSA_MAXAGE(lsa)) /* Refresh lsa.*/ - ospf_external_lsa_refresh(ospf, lsa, default_ei, true); + ospf_external_lsa_refresh(ospf, lsa, default_ei, true, + false); else /* If permit and default not advertised then advertise. */ @@ -1055,8 +1055,7 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, if (red && ROUTEMAP_NAME(red)) { route_map_result_t ret; - ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, - RMAP_OSPF, ei); + ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, ei); if (ret == RMAP_DENYMATCH) { ei->route_map_set = save_values; @@ -1180,23 +1179,100 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) if (is_prefix_default(&p)) ospf_external_lsa_refresh_default(ospf); else { - struct ospf_lsa *current; + struct ospf_external_aggr_rt *aggr; + struct as_external_lsa *al; + struct ospf_lsa *lsa = NULL; + struct in_addr mask; + + aggr = ospf_external_aggr_match(ospf, + &ei->p); + + if (aggr) { + /* Check the AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check( + ospf, ei, NULL)) + return 0; - current = ospf_external_info_find_lsa( - ospf, &ei->p); - if (!current) - ospf_external_lsa_originate( - ospf, ei); - else { if (IS_DEBUG_OSPF( - zebra, - ZEBRA_REDISTRIBUTE)) + lsa, + EXTNL_LSA_AGGR)) zlog_debug( - "ospf_zebra_read_route() : %pI4 refreshing LSA", - &p.prefix); - ospf_external_lsa_refresh( - ospf, current, ei, - LSA_REFRESH_FORCE); + "%s: Send Aggreate LSA (%pI4/%d)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_originate_summary_lsa( + ospf, aggr, ei); + + /* Handling the case where the + * external route prefix + * and aggegate prefix is same + * If same dont flush the + * originated + * external LSA. + */ + if (prefix_same( + (struct prefix + *)&aggr->p, + (struct prefix *)&ei + ->p)) + return 0; + + lsa = ospf_external_info_find_lsa( + ospf, &ei->p); + + if (lsa) { + al = (struct + as_external_lsa *) + lsa->data; + masklen2ip( + ei->p.prefixlen, + &mask); + + if (mask.s_addr + != al->mask.s_addr) + return 0; + + ospf_external_lsa_flush( + ospf, ei->type, + &ei->p, 0); + } + } else { + struct ospf_lsa *current; + + current = + ospf_external_info_find_lsa( + ospf, &ei->p); + if (!current) { + /* Check the + * AS-external-LSA + * should be + * originated. + */ + if (!ospf_redistribute_check( + ospf, ei, + NULL)) + return 0; + + ospf_external_lsa_originate( + ospf, ei); + } else { + if (IS_DEBUG_OSPF( + zebra, + ZEBRA_REDISTRIBUTE)) + zlog_debug( + "%s: %pI4 refreshing LSA", + __func__, + &p.prefix); + ospf_external_lsa_refresh( + ospf, current, + ei, + LSA_REFRESH_FORCE, + false); + } } } } @@ -1210,21 +1286,36 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { - /* - * Check if default-information originate is - * with some routemap prefix/access list match. - * Apply before ei is deleted. - */ + struct ospf_external_aggr_rt *aggr; + ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p); - if (ei) + if (ei == NULL) + return 0; + else + /* + * Check if default-information originate i + * with some routemap prefix/access list match. + * Apply before ei is deleted. + */ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd); - ospf_external_info_delete(ospf, rt_type, api.instance, p); - if (is_prefix_default(&p)) - ospf_external_lsa_refresh_default(ospf); - else - ospf_external_lsa_flush(ospf, rt_type, &p, - ifindex /*, nexthop */); + aggr = ospf_external_aggr_match(ospf, &ei->p); + + if (aggr && (ei->aggr_route == aggr)) { + ospf_unlink_ei_from_aggr(ospf, aggr, ei); + + ospf_external_info_delete(ospf, rt_type, api.instance, + p); + } else { + ospf_external_info_delete(ospf, rt_type, api.instance, + p); + + if (is_prefix_default(&p)) + ospf_external_lsa_refresh_default(ospf); + else + ospf_external_lsa_flush(ospf, rt_type, &p, + ifindex /*, nexthop */); + } } @@ -1316,32 +1407,80 @@ static int ospf_distribute_list_update_timer(struct thread *thread) if ((ei = rn->info) != NULL) { if (is_prefix_default(&ei->p)) default_refresh = 1; - else if ( - (lsa = ospf_external_info_find_lsa( - ospf, &ei->p))) { - int force = - LSA_REFRESH_IF_CHANGED; - /* If this is a MaxAge LSA, we - * need to force refresh it - * because distribute settings - * might have changed and now, - * this LSA needs to be - * originated, not be removed. - * If we don't force refresh it, - * it will remain a MaxAge LSA - * because it will look like it - * hasn't changed. Neighbors - * will not receive updates for - * this LSA. - */ - if (IS_LSA_MAXAGE(lsa)) - force = LSA_REFRESH_FORCE; - - ospf_external_lsa_refresh( - ospf, lsa, ei, force); - } else - ospf_external_lsa_originate( - ospf, ei); + else { + struct ospf_external_aggr_rt + *aggr; + aggr = ospf_external_aggr_match( + ospf, &ei->p); + if (aggr) { + /* Check the + * AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check( + ospf, ei, + NULL)) { + + ospf_unlink_ei_from_aggr( + ospf, + aggr, + ei); + continue; + } + + if (IS_DEBUG_OSPF( + lsa, + EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Send Aggregate LSA (%pI4/%d)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen); + + /* Originate Aggregate + * LSA + */ + ospf_originate_summary_lsa( + ospf, aggr, ei); + } else if ( + (lsa = ospf_external_info_find_lsa( + ospf, + &ei->p))) { + int force = + LSA_REFRESH_IF_CHANGED; + /* If this is a MaxAge + * LSA, we need to + * force refresh it + * because distribute + * settings might have + * changed and now, + * this LSA needs to be + * originated, not be + * removed. + * If we don't force + * refresh it, it will + * remain a MaxAge LSA + * because it will look + * like it hasn't + * changed. Neighbors + * will not receive + * updates for this LSA. + */ + if (IS_LSA_MAXAGE(lsa)) + force = LSA_REFRESH_FORCE; + + ospf_external_lsa_refresh( + ospf, lsa, ei, + force, false); + } else { + if (!ospf_redistribute_check( + ospf, ei, + NULL)) + continue; + ospf_external_lsa_originate( + ospf, ei); + } + } } } } @@ -1776,7 +1915,7 @@ int ospf_zebra_label_manager_connect(void) set_nonblocking(zclient_sync->sock); /* Send hello to notify zebra this is a synchronous client */ - if (zclient_send_hello(zclient_sync) < 0) { + if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) { zlog_warn("%s: failed sending hello for synchronous zclient!", __func__); close(zclient_sync->sock); |
