📄 ospf_receive_acknowledgement.c
字号:
/* ospf_receive_acknowledgement.c *//* Copyright 2000 Wind River Systems, Inc. *//*modification history___________________ 02d,22apr03,ram SPR#76812 Modifications for OSPF performance enhancements 02c,17feb03,ram SPR 85893 Removed check for pending deletion 02b,29jan03,mwv SPR 85893 ospf_ls_acknowledgement_packet_received () check pending deletion for flag for external routes. 02a,06jan03,ram SPR 85432 Changes to allow more OSPF external route processing 18,16april02,jkw One copy of external and type 11 lsa 17,19june01,aos Calling to ospf_clean_up_retransmit_lists_affiliated_with_this_advertisement () function before freeing the LS database entry. 16,26september00,reshma Added WindRiver CopyRight 15,25september00,reshma RFC-1587 implementation for OSPF NSSA Option, also tested against ANVL. 14,07july00,reshma Unix compatibility related changes. 13,04april00,reshma Added some MIB support (Read only).Passed all important ANVL OSPF tests. 12,23december99,reshma Compatibility with VxWorks-IP and VxWorks RTM-interface 11,28december98,jack Compiled and added some comments 10,11november98,jack Config changes, linted and big endian changes 09,30october98,jack Incorporate changes for compilation on Vxworks 08,23august98,jack ANVL tested OSPF with PATRICIA tree route table and no recursion 07,10august98,jack PATRICIA Route Table Based OSPF Code Base 06,04june98,jack Integration with RTM and BGP 05,24april98,jack RTM changes 04,10july97,cindy Pre-release v1.52b 03,02october97,cindy Release Version 1.52 02,22october96,cindy Release Version 1.50 01,05june96,cindy First Beta Release*//*DESCRIPTIONospf_receive_acknowledgement.c is used for processing received link state acknowledgement packets.This file is used whenever a new OSPF link state acknowledgement packet is received.*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ *//*******************************************************************************************************************************/static void ospf_process_advertisement (OSPF_NEIGHBOR *sptr_neighbor,OSPF_LS_DATABASE_ENTRY *sptr_advertisement,OSPF_LS_HEADER *sptr_ls_advertisement_header);/***************************************************************************************************************************** * for each acknowledgement in the Link State Acknowledgement packet, the following steps are performed: * (1) Does the advertisement acknowledged have an instance on the Link State retransmission list for the neighbor? If not, * examine the next acknowledgement. Otherwise: * (2) If the acknowledgement is for the same instance that is contained on the list, remove the item from the list and * examine the next acknowledgment. Otherwise: * (3) Log the questionable acknowledgement, and examine the next one. * ****************************************************************************//* section 13.7 of OSPF specification (page 144) */enum OSPF_PACKET_STATE ospf_ls_acknowledgement_packet_received (OSPF_LS_ACKNOWLEDGEMENT_HEADER *sptr_acknowledgement_packet, OSPF_NEIGHBOR *sptr_neighbor,OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){ OSPF_LS_HEADER *sptr_ls_advertisement_header; OSPF_LS_DATABASE_ENTRY *sptr_advertisement; enum TEST test_return_type; ULONG link_state_id; ULONG advertising_router; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_ls_acknowledgement_packet_received\r\n"); if (sptr_neighbor->state < OSPF_NEIGHBOR_EXCHANGE) /* discard packet if this neighbor is in a lesser state than Exchange */ { return (OSPF_ERROR_ACKNOWLEDGEMENT_STATE); } if ( sptr_acknowledgement_packet == NULL ) return( OSPF_ERROR_ACKNOWLEDGEMENT_BAD ); sptr_ls_advertisement_header = &sptr_acknowledgement_packet->ls_advertisement_header; for (size_of_packet -= OSPF_PACKET_SIZE; size_of_packet > 0x00000000L; size_of_packet -= sizeof (OSPF_LS_HEADER)) { test_return_type = ospf_check_for_valid_ls_type (sptr_interface, sptr_ls_advertisement_header, OSPF_LINK_STATE_ACKNOWLEDGEMENT_PACKET); if (test_return_type == FAIL) { continue; } link_state_id = sptr_ls_advertisement_header->id; link_state_id = net_to_host_long (link_state_id); advertising_router = sptr_ls_advertisement_header->advertising_router; advertising_router = net_to_host_long (advertising_router); /* SPR#76812 */ sptr_advertisement = ospf_find_LSA (sptr_interface->sptr_area, link_state_id, advertising_router, sptr_ls_advertisement_header->type); if (sptr_advertisement == NULL) { continue; /* couldn't find the acknowledged advertisement in the link state database list, so skip it */ } else if (sptr_advertisement->sptr_ls_database_retrans == NULL) { continue; /* found advertisement, but no neighbors on its retransmit list, so nothing to do */ } else { ospf_process_advertisement (sptr_neighbor, sptr_advertisement, sptr_ls_advertisement_header); } sptr_ls_advertisement_header = (OSPF_LS_HEADER *) ((ULONG) sptr_ls_advertisement_header + OSPF_LS_HEADER_SIZE); } return (GOOD_RECEIVE);}/*******************************************************************************************************************************/static void ospf_process_advertisement (OSPF_NEIGHBOR *sptr_neighbor,OSPF_LS_DATABASE_ENTRY *sptr_advertisement,OSPF_LS_HEADER *sptr_ls_advertisement_header){ OSPF_LS_DATABASE_NODE *sptr_retransmission_node; enum TEST test_return_type; USHORT age; ULONG advertising_router; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_process_advertisement\r\n"); sptr_retransmission_node = ospf_find_advertisement_on_neighbors_retransmit_list (sptr_neighbor, sptr_advertisement); if (sptr_retransmission_node == NULL) /* section 13.7, first bullet item (page 144) - couldn't find an instance for the */ { /* acknowledged advertisement on the Link State retransmission list for the neighbor, */ return; /* so skip it. */ } if ( sptr_advertisement->advertisement.sptr_router == NULL ) return; test_return_type = ospf_check_if_same_instance (sptr_ls_advertisement_header, &(sptr_advertisement->advertisement.sptr_router->ls_header), sptr_retransmission_node->periodic_retransmit_time_counter); if (test_return_type == PASS) /* advertisement has been successfully acknowledged by this neighbor */ { /* the advertisement's retransmit list is a list of neighbors that haven't acknowledged the advertisement yet */ ospf_remove_neighbor_from_advertisements_retransmit_list (sptr_advertisement, sptr_neighbor); /* stop retransmitting the advertisement to this neighbor */ ospf_remove_node_from_neighbors_retransmit_queue (sptr_neighbor, sptr_retransmission_node); /* if OSPF_MAXIMUM_AGE, self-originated and the retransmit list is empty, then remove advertisement from link state database */ test_return_type = ospf_check_if_advertisements_link_state_id_is_equal_to_one_of_the_routers_own_IP_interface_addresses ( sptr_advertisement->advertisement.sptr_router); age = sptr_advertisement->advertisement.sptr_router->ls_header.age; age = net_to_host_short (age); advertising_router = sptr_advertisement->advertisement.sptr_router->ls_header.advertising_router; advertising_router = net_to_host_long (advertising_router); /* SPR 85432 -- Begin */ if ((sptr_advertisement->ls_database_freeme == FALSE) && (age >= OSPF_MAXIMUM_AGE) && (sptr_advertisement->sptr_ls_database_retrans == NULL) && (ospf.number_of_neighbors_in_exchange_state == ospf.number_of_neighbors_in_full_state)) /* section 14 (page 145) */ { sptr_advertisement->ls_database_freeme = TRUE; ospf_clean_up_retransmit_lists_affiliated_with_this_advertisement (sptr_advertisement); (void) ospf_free_database_entry (sptr_advertisement); } /* SPR 85432 -- End */ } else { if (ospf_check_if_more_recent (sptr_ls_advertisement_header, &sptr_advertisement->advertisement.sptr_router->ls_header, sptr_retransmission_node->periodic_retransmit_time_counter)) { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: BAD ACKNOWLEDGEMENT\r\n"); } else { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: DUPLICATE ACKNOWLEDGEMENT\r\n"); } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -