|
|
| version 1.1, 2012/02/21 17:26:12 | version 1.1.1.3, 2016/11/02 10:09:12 |
|---|---|
| Line 49 | Line 49 |
| #include "ospfd/ospf_dump.h" | #include "ospfd/ospf_dump.h" |
| extern struct zclient *zclient; | extern struct zclient *zclient; |
| /* Do the LSA acking specified in table 19, Section 13.5, row 2 | /* Do the LSA acking specified in table 19, Section 13.5, row 2 |
| * This get called from ospf_flood_out_interface. Declared inline | * This get called from ospf_flood_out_interface. Declared inline |
| * for speed. */ | * for speed. */ |
| Line 138 ospf_process_self_originated_lsa (struct ospf *ospf, | Line 138 ospf_process_self_originated_lsa (struct ospf *ospf, |
| ospf_router_lsa_update_area (area); | ospf_router_lsa_update_area (area); |
| return; | return; |
| case OSPF_NETWORK_LSA: | case OSPF_NETWORK_LSA: |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_LINK_LSA: | case OSPF_OPAQUE_LINK_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| /* We must find the interface the LSA could belong to. | /* We must find the interface the LSA could belong to. |
| If the interface is no more a broadcast type or we are no more | If the interface is no more a broadcast type or we are no more |
| the DR, we flush the LSA otherwise -- create the new instance and | the DR, we flush the LSA otherwise -- create the new instance and |
| Line 160 ospf_process_self_originated_lsa (struct ospf *ospf, | Line 158 ospf_process_self_originated_lsa (struct ospf *ospf, |
| return; | return; |
| } | } |
| #ifdef HAVE_OPAQUE_LSA | |
| if (new->data->type == OSPF_OPAQUE_LINK_LSA) | if (new->data->type == OSPF_OPAQUE_LINK_LSA) |
| { | { |
| ospf_opaque_lsa_refresh (new); | ospf_opaque_lsa_refresh (new); |
| return; | return; |
| } | } |
| #endif /* HAVE_OPAQUE_LSA */ | |
| if (oi->network_lsa_self) | if (oi->network_lsa_self) |
| oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum; | oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum; |
| Line 193 ospf_process_self_originated_lsa (struct ospf *ospf, | Line 189 ospf_process_self_originated_lsa (struct ospf *ospf, |
| else | else |
| ospf_lsa_flush_as (ospf, new); | ospf_lsa_flush_as (ospf, new); |
| break; | break; |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_AREA_LSA: | case OSPF_OPAQUE_AREA_LSA: |
| ospf_opaque_lsa_refresh (new); | ospf_opaque_lsa_refresh (new); |
| break; | break; |
| case OSPF_OPAQUE_AS_LSA: | case OSPF_OPAQUE_AS_LSA: |
| ospf_opaque_lsa_refresh (new); /* Reconsideration may needed. *//* XXX */ | ospf_opaque_lsa_refresh (new); /* Reconsideration may needed. *//* XXX */ |
| break; | break; |
| #endif /* HAVE_OPAQUE_LSA */ | |
| default: | default: |
| break; | break; |
| } | } |
| Line 244 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n | Line 238 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n |
| zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", | zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", |
| inet_ntoa (nbr->router_id), | inet_ntoa (nbr->router_id), |
| LOOKUP (ospf_nsm_state_msg, nbr->state), | LOOKUP (ospf_nsm_state_msg, nbr->state), |
| current, | (void *)current, |
| dump_lsa_key (new)); | dump_lsa_key (new)); |
| lsa_ack_flag = 0; | lsa_ack_flag = 0; |
| Line 266 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n | Line 260 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n |
| ; /* Accept this LSA for quick LSDB resynchronization. */ | ; /* Accept this LSA for quick LSDB resynchronization. */ |
| } | } |
| else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv), | else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv), |
| int2tv (OSPF_MIN_LS_ARRIVAL)) < 0) | msec2tv (ospf->min_ls_arrival)) < 0) |
| { | { |
| if (IS_DEBUG_OSPF_EVENT) | if (IS_DEBUG_OSPF_EVENT) |
| zlog_debug ("LSA[Flooding]: LSA is received recently."); | zlog_debug ("LSA[Flooding]: LSA is received recently."); |
| Line 281 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n | Line 275 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n |
| interface. */ | interface. */ |
| lsa_ack_flag = ospf_flood_through (ospf, nbr, new); | lsa_ack_flag = ospf_flood_through (ospf, nbr, new); |
| #ifdef HAVE_OPAQUE_LSA | |
| /* Remove the current database copy from all neighbors' Link state | /* Remove the current database copy from all neighbors' Link state |
| retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does | retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does |
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^ |
| not have area ID. | not have area ID. |
| All other (even NSSA's) do have area ID. */ | All other (even NSSA's) do have area ID. */ |
| #else /* HAVE_OPAQUE_LSA */ | |
| /* Remove the current database copy from all neighbors' Link state | |
| retransmission lists. Only AS_EXTERNAL does not have area ID. | |
| All other (even NSSA's) do have area ID. */ | |
| #endif /* HAVE_OPAQUE_LSA */ | |
| if (current) | if (current) |
| { | { |
| switch (current->data->type) | switch (current->data->type) |
| { | { |
| case OSPF_AS_EXTERNAL_LSA: | case OSPF_AS_EXTERNAL_LSA: |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_AS_LSA: | case OSPF_OPAQUE_AS_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| ospf_ls_retransmit_delete_nbr_as (ospf, current); | ospf_ls_retransmit_delete_nbr_as (ospf, current); |
| break; | break; |
| default: | default: |
| Line 320 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n | Line 306 ospf_flood (struct ospf *ospf, struct ospf_neighbor *n |
| MinLSArrival seconds have elapsed. */ | MinLSArrival seconds have elapsed. */ |
| if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) | if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) |
| return 0; /* unknown LSA type */ | return -1; /* unknown LSA type or any other error condition */ |
| /* Acknowledge the receipt of the LSA by sending a Link State | /* Acknowledge the receipt of the LSA by sending a Link State |
| Acknowledgment packet back out the receiving interface. */ | Acknowledgment packet back out the receiving interface. */ |
| Line 421 ospf_flood_through_interface (struct ospf_interface *o | Line 407 ospf_flood_through_interface (struct ospf_interface *o |
| } | } |
| } | } |
| #ifdef HAVE_OPAQUE_LSA | |
| if (IS_OPAQUE_LSA (lsa->data->type)) | if (IS_OPAQUE_LSA (lsa->data->type)) |
| { | { |
| if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O)) | if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O)) |
| Line 430 ospf_flood_through_interface (struct ospf_interface *o | Line 415 ospf_flood_through_interface (struct ospf_interface *o |
| zlog_debug ("Skip this neighbor: Not Opaque-capable."); | zlog_debug ("Skip this neighbor: Not Opaque-capable."); |
| continue; | 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 */ | |
| /* If the new LSA was received from this neighbor, | /* If the new LSA was received from this neighbor, |
| examine the next neighbor. */ | examine the next neighbor. */ |
| Line 576 ospf_flood_through_area (struct ospf_area *area, | Line 550 ospf_flood_through_area (struct ospf_area *area, |
| oi->type == OSPF_IFTYPE_VIRTUALLINK) | oi->type == OSPF_IFTYPE_VIRTUALLINK) |
| continue; | continue; |
| #ifdef HAVE_OPAQUE_LSA | |
| if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi)) | if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi)) |
| { | { |
| /* | /* |
| Line 584 ospf_flood_through_area (struct ospf_area *area, | Line 557 ospf_flood_through_area (struct ospf_area *area, |
| * for the link on which the LSA has received. | * for the link on which the LSA has received. |
| */ | */ |
| if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) |
| zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", lsa->oi, oi); | zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", |
| (void *)lsa->oi, (void *)oi); | |
| continue; | continue; |
| } | } |
| #endif /* HAVE_OPAQUE_LSA */ | |
| if (ospf_flood_through_interface (oi, inbr, lsa)) | if (ospf_flood_through_interface (oi, inbr, lsa)) |
| lsa_ack_flag = 1; | lsa_ack_flag = 1; |
| Line 697 ospf_flood_through (struct ospf *ospf, | Line 670 ospf_flood_through (struct ospf *ospf, |
| case OSPF_NETWORK_LSA: | case OSPF_NETWORK_LSA: |
| case OSPF_SUMMARY_LSA: | case OSPF_SUMMARY_LSA: |
| case OSPF_ASBR_SUMMARY_LSA: | case OSPF_ASBR_SUMMARY_LSA: |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ | case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ |
| case OSPF_OPAQUE_AREA_LSA: | case OSPF_OPAQUE_AREA_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); | lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); |
| break; | break; |
| case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ | case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_AS_LSA: | case OSPF_OPAQUE_AS_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); | lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); |
| break; | break; |
| /* Type-7 Only received within NSSA, then flooded */ | /* Type-7 Only received within NSSA, then flooded */ |
| Line 736 ospf_flood_through (struct ospf *ospf, | Line 705 ospf_flood_through (struct ospf *ospf, |
| switch (lsa->data->type) | switch (lsa->data->type) |
| { | { |
| case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ | case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_AS_LSA: | case OSPF_OPAQUE_AS_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); | lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); |
| break; | break; |
| /* Type-7 Only received within NSSA, then flooded */ | /* Type-7 Only received within NSSA, then flooded */ |
| Line 757 ospf_flood_through (struct ospf *ospf, | Line 724 ospf_flood_through (struct ospf *ospf, |
| return (lsa_ack_flag); | return (lsa_ack_flag); |
| } | } |
| /* Management functions for neighbor's Link State Request list. */ | /* Management functions for neighbor's Link State Request list. */ |
| void | void |
| ospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | ospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) |
| Line 835 ospf_ls_request_new (struct lsa_header *lsah) | Line 802 ospf_ls_request_new (struct lsa_header *lsah) |
| return new; | return new; |
| } | } |
| /* Management functions for neighbor's ls-retransmit list. */ | /* Management functions for neighbor's ls-retransmit list. */ |
| unsigned long | unsigned long |
| ospf_ls_retransmit_count (struct ospf_neighbor *nbr) | ospf_ls_retransmit_count (struct ospf_neighbor *nbr) |
| Line 973 ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, s | Line 940 ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, s |
| ospf_ls_retransmit_delete_nbr_if (oi, lsa); | ospf_ls_retransmit_delete_nbr_if (oi, lsa); |
| } | } |
| /* Sets ls_age to MaxAge and floods throu the area. | /* Sets ls_age to MaxAge and floods throu the area. |
| When we implement ASE routing, there will be anothe function | When we implement ASE routing, there will be anothe function |
| flushing an LSA from the whole domain. */ | flushing an LSA from the whole domain. */ |
| void | void |
| ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area) | ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area) |
| { | { |
| /* Reset the lsa origination time such that it gives | |
| more time for the ACK to be received and avoid | |
| retransmissions */ | |
| lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); | lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); |
| lsa->tv_recv = recent_relative_time (); | |
| lsa->tv_orig = lsa->tv_recv; | |
| ospf_flood_through_area (area, NULL, lsa); | ospf_flood_through_area (area, NULL, lsa); |
| ospf_lsa_maxage (area->ospf, lsa); | ospf_lsa_maxage (area->ospf, lsa); |
| } | } |
| Line 988 ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf | Line 960 ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf |
| void | void |
| ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa) | ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa) |
| { | { |
| /* Reset the lsa origination time such that it gives | |
| more time for the ACK to be received and avoid | |
| retransmissions */ | |
| lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); | lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); |
| lsa->tv_recv = recent_relative_time (); | |
| lsa->tv_orig = lsa->tv_recv; | |
| ospf_flood_through_as (ospf, NULL, lsa); | ospf_flood_through_as (ospf, NULL, lsa); |
| ospf_lsa_maxage (ospf, lsa); | ospf_lsa_maxage (ospf, lsa); |
| } | } |
| Line 1005 ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *ls | Line 982 ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *ls |
| case OSPF_SUMMARY_LSA: | case OSPF_SUMMARY_LSA: |
| case OSPF_ASBR_SUMMARY_LSA: | case OSPF_ASBR_SUMMARY_LSA: |
| case OSPF_AS_NSSA_LSA: | case OSPF_AS_NSSA_LSA: |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_LINK_LSA: | case OSPF_OPAQUE_LINK_LSA: |
| case OSPF_OPAQUE_AREA_LSA: | case OSPF_OPAQUE_AREA_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| ospf_lsa_flush_area (lsa, lsa->area); | ospf_lsa_flush_area (lsa, lsa->area); |
| break; | break; |
| case OSPF_AS_EXTERNAL_LSA: | case OSPF_AS_EXTERNAL_LSA: |
| #ifdef HAVE_OPAQUE_LSA | |
| case OSPF_OPAQUE_AS_LSA: | case OSPF_OPAQUE_AS_LSA: |
| #endif /* HAVE_OPAQUE_LSA */ | |
| ospf_lsa_flush_as (ospf, lsa); | ospf_lsa_flush_as (ospf, lsa); |
| break; | break; |
| default: | default: |