📄 ospf_flood.c
字号:
if (continue_flag) continue; /* main for-loop */ /* send to every interface in this area */ for (if_node = listhead (area->oiflist); if_node; nextnode (if_node)) { struct ospf_interface *oi = getdata (if_node); /* Skip virtual links */ if (oi->type != OSPF_IFTYPE_VIRTUALLINK) if (ospf_flood_through_interface (oi, inbr, lsa)) /* lsa */ lsa_ack_flag = 1; } } /* main area for-loop */ return (lsa_ack_flag);}intospf_flood_through (struct ospf *ospf, struct ospf_neighbor *inbr, struct ospf_lsa *lsa){ int lsa_ack_flag = 0; /* Type-7 LSA's for NSSA are flooded throughout the AS here, and upon return are updated in the LSDB for Type-7's. Later, re-fresh will re-send them (and also, if ABR, packet code will translate to Type-5's) As usual, Type-5 LSA's (if not DISCARDED because we are STUB or NSSA) are flooded throughout the AS, and are updated in the global table. */#ifdef ORIGINAL_CODING switch (lsa->data->type) { case OSPF_ROUTER_LSA: case OSPF_NETWORK_LSA: case OSPF_SUMMARY_LSA: case OSPF_ASBR_SUMMARY_LSA:#ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ case OSPF_OPAQUE_AREA_LSA:#endif /* HAVE_OPAQUE_LSA */ lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); break; case OSPF_AS_EXTERNAL_LSA: /* Type-5 */#ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */ lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); break;#ifdef HAVE_NSSA /* Type-7 Only received within NSSA, then flooded */ case OSPF_AS_NSSA_LSA: /* Any P-bit was installed with the Type-7. */ lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); if (IS_DEBUG_OSPF_NSSA) zlog_info ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); break;#endif /* HAVE_NSSA */ default: break; }#else /* ORIGINAL_CODING */ /* * At the common sub-sub-function "ospf_flood_through_interface()", * a parameter "inbr" will be used to distinguish the called context * whether the given LSA was received from the neighbor, or the * flooding for the LSA starts from this node (e.g. the LSA was self- * originated, or the LSA is going to be flushed from routing domain). * * So, for consistency reasons, this function "ospf_flood_through()" * should also allow the usage that the given "inbr" parameter to be * NULL. If we do so, corresponding AREA parameter should be referred * by "lsa->area", instead of "inbr->oi->area". */ switch (lsa->data->type) { case OSPF_AS_EXTERNAL_LSA: /* Type-5 */#ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */ lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); break;#ifdef HAVE_NSSA /* Type-7 Only received within NSSA, then flooded */ case OSPF_AS_NSSA_LSA: /* Any P-bit was installed with the Type-7. */ if (IS_DEBUG_OSPF_NSSA) zlog_info ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); /* Fallthrough */#endif /* HAVE_NSSA */ default: lsa_ack_flag = ospf_flood_through_area (lsa->area, inbr, lsa); break; }#endif /* ORIGINAL_CODING */ return (lsa_ack_flag);}/* Management functions for neighbor's Link State Request list. */voidospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ /* * We cannot make use of the newly introduced callback function * "lsdb->new_lsa_hook" to replace debug output below, just because * it seems no simple and smart way to pass neighbor information to * the common function "ospf_lsdb_add()" -- endo. */ if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) zlog_info ("RqstL(%lu)++, NBR(%s), LSA[%s]", ospf_ls_request_count (nbr), inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); ospf_lsdb_add (&nbr->ls_req, lsa);}unsigned longospf_ls_request_count (struct ospf_neighbor *nbr){ return ospf_lsdb_count_all (&nbr->ls_req);}intospf_ls_request_isempty (struct ospf_neighbor *nbr){ return ospf_lsdb_isempty (&nbr->ls_req);}/* Remove LSA from neighbor's ls-request list. */voidospf_ls_request_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ if (nbr->ls_req_last == lsa) { ospf_lsa_unlock (nbr->ls_req_last); nbr->ls_req_last = NULL; } if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ zlog_info ("RqstL(%lu)--, NBR(%s), LSA[%s]", ospf_ls_request_count (nbr), inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); ospf_lsdb_delete (&nbr->ls_req, lsa);}/* Remove all LSA from neighbor's ls-requenst list. */voidospf_ls_request_delete_all (struct ospf_neighbor *nbr){ ospf_lsa_unlock (nbr->ls_req_last); nbr->ls_req_last = NULL; ospf_lsdb_delete_all (&nbr->ls_req);}/* Lookup LSA from neighbor's ls-request list. */struct ospf_lsa *ospf_ls_request_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ return ospf_lsdb_lookup (&nbr->ls_req, lsa);}struct ospf_lsa *ospf_ls_request_new (struct lsa_header *lsah){ struct ospf_lsa *new; new = ospf_lsa_new (); new->data = ospf_lsa_data_new (OSPF_LSA_HEADER_SIZE); memcpy (new->data, lsah, OSPF_LSA_HEADER_SIZE); return new;}/* Management functions for neighbor's ls-retransmit list. */unsigned longospf_ls_retransmit_count (struct ospf_neighbor *nbr){ return ospf_lsdb_count_all (&nbr->ls_rxmt);}unsigned longospf_ls_retransmit_count_self (struct ospf_neighbor *nbr, int lsa_type){ return ospf_lsdb_count_self (&nbr->ls_rxmt, lsa_type);}intospf_ls_retransmit_isempty (struct ospf_neighbor *nbr){ return ospf_lsdb_isempty (&nbr->ls_rxmt);}/* Add LSA to be retransmitted to neighbor's ls-retransmit list. */voidospf_ls_retransmit_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ struct ospf_lsa *old; old = ospf_ls_retransmit_lookup (nbr, lsa); if (ospf_lsa_more_recent (old, lsa) < 0) { if (old) { old->retransmit_counter--; ospf_lsdb_delete (&nbr->ls_rxmt, old); } lsa->retransmit_counter++; /* * We cannot make use of the newly introduced callback function * "lsdb->new_lsa_hook" to replace debug output below, just because * it seems no simple and smart way to pass neighbor information to * the common function "ospf_lsdb_add()" -- endo. */ if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) zlog_info ("RXmtL(%lu)++, NBR(%s), LSA[%s]", ospf_ls_retransmit_count (nbr), inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); ospf_lsdb_add (&nbr->ls_rxmt, lsa); }}/* Remove LSA from neibghbor's ls-retransmit list. */voidospf_ls_retransmit_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ if (ospf_ls_retransmit_lookup (nbr, lsa)) { lsa->retransmit_counter--; if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ zlog_info ("RXmtL(%lu)--, NBR(%s), LSA[%s]", ospf_ls_retransmit_count (nbr), inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); ospf_lsdb_delete (&nbr->ls_rxmt, lsa); }}/* Clear neighbor's ls-retransmit list. */voidospf_ls_retransmit_clear (struct ospf_neighbor *nbr){ struct ospf_lsdb *lsdb; int i; lsdb = &nbr->ls_rxmt; for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { struct route_table *table = lsdb->type[i].db; struct route_node *rn; struct ospf_lsa *lsa; for (rn = route_top (table); rn; rn = route_next (rn)) if ((lsa = rn->info) != NULL) ospf_ls_retransmit_delete (nbr, lsa); } ospf_lsa_unlock (nbr->ls_req_last); nbr->ls_req_last = NULL;}/* Lookup LSA from neighbor's ls-retransmit list. */struct ospf_lsa *ospf_ls_retransmit_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){ return ospf_lsdb_lookup (&nbr->ls_rxmt, lsa);}voidospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi, struct ospf_lsa *lsa){ struct route_node *rn; struct ospf_neighbor *nbr; struct ospf_lsa *lsr; if (ospf_if_is_enable (oi)) for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) /* If LSA find in LS-retransmit list, then remove it. */ if ((nbr = rn->info) != NULL) { lsr = ospf_ls_retransmit_lookup (nbr, lsa); /* If LSA find in ls-retransmit list, remove it. */ if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum) ospf_ls_retransmit_delete (nbr, lsr); }}voidospf_ls_retransmit_delete_nbr_area (struct ospf_area *area, struct ospf_lsa *lsa){ listnode node; for (node = listhead (area->oiflist); node; nextnode (node)) ospf_ls_retransmit_delete_nbr_if (getdata (node), lsa);}voidospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa){ listnode node; for (node = listhead (ospf->oiflist); node; nextnode (node)) ospf_ls_retransmit_delete_nbr_if (getdata (node), lsa);}/* Sets ls_age to MaxAge and floods throu the area. When we implement ASE routing, there will be anothe function flushing an LSA from the whole domain. */voidospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area){ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); ospf_flood_through_area (area, NULL, lsa); ospf_lsa_maxage (area->ospf, lsa);}voidospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa){ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); ospf_flood_through_as (ospf, NULL, lsa); ospf_lsa_maxage (ospf, lsa);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -