summaryrefslogtreecommitdiff
path: root/ospfd/ospf_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_zebra.c')
-rw-r--r--ospfd/ospf_zebra.c259
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);