From 801e0e14920b7ad91080fb65b07c9283179eaf31 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Tue, 20 Jan 2015 15:45:36 +0000 Subject: [PATCH] ospfd: Remove the blocking of opaque LSAs origination & flooding 'optimisation' * Opaque support contains some kind of hack/optimisation to origination/flooding to suppress some origins/floods until an opaque LS Acks are received. Previous versions of the code have already been shown to have bugs in them (see e16fd8a5, e.g.). It seems over-complex and fragile, plus its conceptually the wrong place to try implement flooding hacks that, AFAICT, do not depend particularly on the semantics of opaque LSA. Nuke. Tested-by: Olivier Dugeon --- ospfd/ospf_flood.c | 10 --- ospfd/ospf_opaque.c | 205 +------------------------------------------- ospfd/ospf_opaque.h | 20 ----- ospfd/ospf_packet.c | 9 +- ospfd/ospf_vty.c | 7 +- ospfd/ospfd.h | 3 - 6 files changed, 6 insertions(+), 248 deletions(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 05b1724d0d..d0d446f7a6 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -448,16 +448,6 @@ ospf_flood_through_interface (struct ospf_interface *oi, zlog_debug ("Skip this neighbor: Not Opaque-capable."); continue; } - - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (oi->ospf->opaque) - && IS_LSA_SELF (lsa) - && onbr->state == NSM_Full) - { - /* Small attempt to reduce unnecessary retransmission. */ - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("Skip this neighbor: Initial flushing done."); - continue; - } } #endif /* HAVE_OPAQUE_LSA */ diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 00868dd5c1..c8208a1fa6 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1317,13 +1317,7 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0) zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational."); goto out; /* This is not an error. */ } - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_opaque_lsa_originate_schedule: Under blockade."); - goto out; /* This is not an error, too. */ - } - + if (delay0 != NULL) delay = *delay0; @@ -1765,13 +1759,7 @@ ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent, zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Not operational."); goto out; /* This is not an error. */ } - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Under blockade."); - goto out; /* This is not an error, too. */ - } - + /* Generate a dummy lsa to be passed for a lookup function. */ lsa = pseudo_lsa (oi, area, lsa_type, opaque_type); @@ -2132,12 +2120,6 @@ out: *------------------------------------------------------------------------*/ static void ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs, struct ospf_neighbor *inbr, struct ospf_lsa *lsa); -#ifdef BUGGY_UNLOCK -static void ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi); -static void ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area); -static void ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top); -static unsigned long ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type); -#endif /* BUGGY_UNLOCK */ void ospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, struct list *lsas) @@ -2246,13 +2228,10 @@ ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { struct ospf *top; - u_char before; - + if ((top = oi_to_top (nbr->oi)) == NULL) return; - before = IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque); - /* * Since these LSA entries are not yet installed into corresponding * LSDB, just flush them without calling ospf_ls_maxage() afterward. @@ -2261,196 +2240,20 @@ ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, switch (lsa->data->type) { case OSPF_OPAQUE_LINK_LSA: - SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT); ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa); break; case OSPF_OPAQUE_AREA_LSA: - SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT); ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa); break; case OSPF_OPAQUE_AS_LSA: - SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT); ospf_flood_through_as (top, NULL/*inbr*/, lsa); break; default: zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type); return; } - - ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */ - - if (before == 0 && IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Block Opaque-LSA origination: OFF -> ON"); - } -} - -void -ospf_opaque_ls_ack_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) -{ - struct ospf *top; - int delay; - struct ospf_interface *oi; - struct listnode *node, *nnode; - - if ((top = oi_to_top (nbr->oi)) == NULL) - return; - - if (!IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - return; - - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT)) - UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT); - /* BUGGY_UNLOCK: ospf_opaque_type9_lsa_rxmt_nbr_check (nbr->oi); */ - /* Callback function... */ - break; - case OSPF_OPAQUE_AREA_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT)) - UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT); - /* BUGGY_UNLOCK: ospf_opaque_type10_lsa_rxmt_nbr_check (nbr->oi->area); */ - /* Callback function... */ - break; - case OSPF_OPAQUE_AS_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT)) - UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT); - /* BUGGY_UNLOCK: ospf_opaque_type11_lsa_rxmt_nbr_check (top); */ - /* Callback function... */ - break; - default: - zlog_warn ("ospf_opaque_ls_ack_received: Unexpected LSA-type(%u)", lsa->data->type); - return; - } - - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - return; /* Blocking still in progress. */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Block Opaque-LSA origination: ON -> OFF"); - - if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)) - return; /* Opaque capability condition must have changed. */ - - /* Ok, let's start origination of Opaque-LSAs. */ - delay = OSPF_MIN_LS_INTERVAL; - - for (ALL_LIST_ELEMENTS (top->oiflist, node, nnode, oi)) - { - if (! ospf_if_is_enable (oi) - || ospf_nbr_count_opaque_capable (oi) == 0) - continue; - - ospf_opaque_lsa_originate_schedule (oi, &delay); - } - - return; -} - -#ifdef BUGGY_UNLOCK -static void -ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi) -{ - unsigned long n; - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_LINK_LSA); - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-9 Opaque-LSAs: OI(%s): Flush completed", IF_NAME (oi)); - - UNSET_FLAG (oi->area->ospf->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT); - } - return; -} - -static void -ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area) -{ - struct listnode *node; - struct ospf_interface *oi; - unsigned long n = 0; - - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - { - if (area->area_id.s_addr != OSPF_AREA_BACKBONE - && oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AREA_LSA); - if (n > 0) - break; - } - - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-10 Opaque-LSAs: AREA(%s): Flush completed", inet_ntoa (area->area_id)); - - UNSET_FLAG (area->ospf->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT); - } - - return; -} - -static void -ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top) -{ - struct listnode *node; - struct ospf_interface *oi; - unsigned long n = 0; - - for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi)) - { - switch (oi->type) - { - case OSPF_IFTYPE_VIRTUALLINK: - continue; - default: - break; - } - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AS_LSA); - if (n > 0) - goto out; - } - - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-11 Opaque-LSAs: Flush completed"); - - UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT); - } - -out: - return; -} - -static unsigned long -ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type) -{ - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf *top; - unsigned long n = 0; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info) == NULL) - continue; - if ((top = oi_to_top (nbr->oi)) == NULL) - continue; - if (IPV4_ADDR_SAME (&nbr->router_id, &top->router_id)) - continue; - n += ospf_ls_retransmit_count_self (nbr, lsa_type); - } - - return n; + ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */ } -#endif /* BUGGY_UNLOCK */ /*------------------------------------------------------------------------* * Followings are util functions; probably be used by Opaque-LSAs only... diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index 2273064566..077da62747 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -31,23 +31,6 @@ (type) == OSPF_OPAQUE_AREA_LSA || \ (type) == OSPF_OPAQUE_AS_LSA) -/* - * Usage of Opaque-LSA administrative flags in "struct ospf". - * - * 7 6 5 4 3 2 1 0 - * +---+---+---+---+---+---+---+---+ - * |///|///|///|///|B11|B10|B09| O | - * +---+---+---+---+---+---+---+---+ - * |<--------->| A - * | +--- Operation status (operational = 1) - * +----------- Blocking status for each LSA type - */ - -#define IS_OPAQUE_LSA_ORIGINATION_BLOCKED(V) \ - CHECK_FLAG((V), (OPAQUE_BLOCK_TYPE_09_LSA_BIT | \ - OPAQUE_BLOCK_TYPE_10_LSA_BIT | \ - OPAQUE_BLOCK_TYPE_11_LSA_BIT)) - /* * Opaque LSA's link state ID is redefined as follows. * @@ -156,9 +139,6 @@ extern void ospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, extern void ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa); -extern void ospf_opaque_ls_ack_received (struct ospf_neighbor *nbr, - struct ospf_lsa *lsa); - extern void htonf (float *src, float *dst); extern void ntohf (float *src, float *dst); extern struct ospf *oi_to_top (struct ospf_interface *oi); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 78199f6ece..eeed11be9d 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2160,14 +2160,7 @@ ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh, lsr = ospf_ls_retransmit_lookup (nbr, lsa); if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0) - { -#ifdef HAVE_OPAQUE_LSA - if (IS_OPAQUE_LSA (lsr->data->type)) - ospf_opaque_ls_ack_received (nbr, lsr); -#endif /* HAVE_OPAQUE_LSA */ - - ospf_ls_retransmit_delete (nbr, lsr); - } + ospf_ls_retransmit_delete (nbr, lsr); lsa->data = NULL; ospf_lsa_discard (lsa); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index c7137ab524..03cde1c55d 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3373,16 +3373,11 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) { json_object_boolean_true_add(json, "opaqueCapable"); } - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf->opaque)) - { - json_object_boolean_true_add(json, "lsaOpaqueOriginationBlocked"); - } } else { - vty_out (vty, " OpaqueCapability flag is %s%s%s", + vty_out (vty, " OpaqueCapability flag is %s%s", CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE) ? "enabled" : "disabled", - IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf->opaque) ? " (origination blocked)" : "", VTY_NEWLINE); } #endif /* HAVE_OPAQUE_LSA */ diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 4c140cf5bc..0dc90c8ae0 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -169,9 +169,6 @@ struct ospf /* Opaque-LSA administrative flags. */ u_char opaque; #define OPAQUE_OPERATION_READY_BIT (1 << 0) -#define OPAQUE_BLOCK_TYPE_09_LSA_BIT (1 << 1) -#define OPAQUE_BLOCK_TYPE_10_LSA_BIT (1 << 2) -#define OPAQUE_BLOCK_TYPE_11_LSA_BIT (1 << 3) #endif /* HAVE_OPAQUE_LSA */ /* RFC3137 stub router. Configured time to stay stub / max-metric */ -- 2.39.5