📄 ospf_receive_database.c
字号:
/* ospf_receive_database.c - OSPF receive database *//* Copyright 2000-2003 Wind River Systems, Inc. *//*modification history--------------------02d,26may03,agi Changed rwos_get_system_elapsed_time_second() to ospf_get_system_elapsed_time_second()02c,22apr03,ram SPR#76812 Modifications for OSPF performance enhancements02b,07feb,03,agi Fixed SPR#75769 - ANVL 23.10 and SPR#75772 - ANVL 23.1102a,03dec02,ram SPR 84312 - Change elapsed time to return seconds23,16april02,jkw One copy of external and type 11 lsa22,09april02,jkw Sequence number wrap.21,08februay02,jkw Ignore mtu size if virtual link.20,23january02,jkw Fix receiving of dd packets with opaque.19,03september,jkw Added Mistral updates for RFC 217818,23july01,jkw Added new configuration variables for ignoring tos and demand circuit17,18july01,jkw Return received good on TWO-WAY receive as specified per the RFC16,26september00,reshma Added WindRiver CopyRight15,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-interface11,28december98,jack Compiled and added some comments10,11november98,jack Config changes, linted and big endian changes09,30october98,jack Incorporate changes for compilation on Vxworks08,23august98,jack ANVL tested OSPF with PATRICIA tree route table and no recursion07,10august98,jack PATRICIA Route Table Based OSPF Code Base06,04june98,jack Integration with RTM and BGP05,24april98,jack RTM changes04,10july97,cindy Pre-release v1.52b03,02october97,cindy Release Version 1.5202,22october96,cindy Release Version 1.5001,05june96,cindy First Beta Release*//*DESCRIPTIONospf_receive_database.c is used for processing received database description packets.This file is used whenever a new OSPF database description packet is received.*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ *//**********************************************************************************************************************************/static OSPF_RETURN_TYPE ospf_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header,OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet);static OSPF_RETURN_TYPE ospf_neighbor_exchange_start_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header, ULONG size_of_packet,OSPF_NEIGHBOR *sptr_neighbor,OSPF_INTERFACE *sptr_interface);static void ospf_neighbor_exchange_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header,ULONG size_of_packet, OSPF_NEIGHBOR *sptr_neighbor,OSPF_INTERFACE *sptr_interface);static int check_database_packet_header_options(OSPF_DATABASE_HEADER *sptr_database_packet_header, OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface, seq_t database_description_sequence_number);static void ospf_remove_last_sent_database_summary (OSPF_NEIGHBOR *sptr_neighbor);static enum OSPF_PACKET_STATE ospf_accept_as_next_in_sequence (OSPF_DATABASE_HEADER *sptr_database_packet_header,ULONG size_of_packet, OSPF_NEIGHBOR *sptr_neighbor,OSPF_INTERFACE *sptr_interface);static enum OSPF_PACKET_STATE ospf_parse_database_packet (OSPF_DATABASE_HEADER *sptr_database_header,OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet);static void ospf_neighbor_full_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header,OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface);/****************************************************************************//* section 10.6 of OSPF specification (page 90) */enum OSPF_PACKET_STATE ospf_database_packet_received (OSPF_DATABASE_HEADER *sptr_database_packet_header,OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){ ULONG ls_request_queue_count; OSPF_AREA_ENTRY *sptr_area; OSPF_RETURN_TYPE return_type;#if defined (__RFC_2328__) /* RFC 2178 G.9 */ USHORT interface_mtu; USHORT database_mtu;#endif OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_database_packet_received\r\n"); sptr_area = sptr_interface->sptr_area; ls_request_queue_count = sptr_neighbor->ls_request_queue_count;#if defined (__RFC_2328__) if (sptr_interface->type != OSPF_VIRTUAL_LINK) { /* RFC 2178 G.9 */ interface_mtu = (USHORT)ospf_get_interface_mtu(sptr_interface); database_mtu = sptr_database_packet_header->interface_mtu; /* Mistral Added Changes on July 18th */ database_mtu = net_to_host_short(database_mtu); if (database_mtu > interface_mtu) { return OSPF_ERROR_DATABASE_DESCRIPTION_MTU_MISMATCH; } }#endif /*__RFC_2328__*/ size_of_packet -= (OSPF_PACKET_SIZE + OSPF_DATABASE_HEADER_SIZE); return_type = ospf_process_database_packet (sptr_database_packet_header, sptr_neighbor, sptr_interface, size_of_packet); if (return_type.exit_routine == FALSE) { if (sptr_interface->flags._bit.neighbor_change == TRUE) { ospf_execute_interface_state_machine (OSPF_NEIGHBOR_CHANGE, sptr_interface->state, sptr_interface); } ospf_generate_network_and_router_link_state_advertisements (sptr_interface); /* * During the above packet processing, a node may have been added to the ls request queue. * If a node was added and the list was previously empty, then send out an ls request packet right * away. Otherwise, there is already an ls request packet outstanding. So let the retransmit * process handle all sending of ls request packets (so we don't end up with more than one sent * out at a time). */ if ((sptr_neighbor->state >= OSPF_NEIGHBOR_EXCHANGE) && (ls_request_queue_count == 0x00000000L /* list was previously empty */) && (sptr_neighbor->ls_request_queue_count > 0x00000000L /* list is no longer empty */)) { ospf_send_ls_request_packet (sptr_interface, sptr_neighbor); } } return (return_type.packet_state);}/******************************************************************************************************************************/static OSPF_RETURN_TYPE ospf_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header,OSPF_NEIGHBOR *sptr_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){ OSPF_RETURN_TYPE return_type; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_process_database_packet\r\n"); return_type.exit_routine = FALSE; return_type.packet_state = GOOD_RECEIVE; switch (sptr_neighbor->state) { case OSPF_NEIGHBOR_DOWN: case OSPF_NEIGHBOR_ATTEMPT: { return_type.exit_routine = TRUE; return_type.packet_state = OSPF_ERROR_DATABASE_DESCRIPTION_STATE; return (return_type); /* ignore the packet */ } case OSPF_NEIGHBOR_2_WAY: { return (return_type); /* ignore the packet */ } case OSPF_NEIGHBOR_INITIALIZING: case OSPF_NEIGHBOR_EXCHANGE_START: { if (sptr_neighbor->state == OSPF_NEIGHBOR_INITIALIZING) /* first transition state to NEIGHBOR_EXSTART */ { ospf_execute_neighbor_state_machine (OSPF_TWO_WAY_RECEIVED, sptr_neighbor->state, sptr_interface, sptr_neighbor); if (sptr_neighbor->state != OSPF_NEIGHBOR_EXCHANGE_START) { break; } } return_type = ospf_neighbor_exchange_start_process_database_packet (sptr_database_packet_header, size_of_packet, sptr_neighbor, sptr_interface); break; } case OSPF_NEIGHBOR_EXCHANGE: { ospf_neighbor_exchange_process_database_packet (sptr_database_packet_header, size_of_packet, sptr_neighbor, sptr_interface); break; } case OSPF_NEIGHBOR_LOADING: case OSPF_NEIGHBOR_FULL: { ospf_neighbor_full_process_database_packet (sptr_database_packet_header, sptr_neighbor, sptr_interface); break; } default: { break; } } return (return_type);}/******************************************************************************************************************************/static OSPF_RETURN_TYPE ospf_neighbor_exchange_start_process_database_packet (OSPF_DATABASE_HEADER *sptr_database_packet_header, ULONG size_of_packet,OSPF_NEIGHBOR *sptr_neighbor,OSPF_INTERFACE *sptr_interface){ OSPF_RETURN_TYPE return_type; seq_t database_description_sequence_number; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_neighbor_exchange_start_process_database_packet\r\n"); database_description_sequence_number = sptr_database_packet_header->sequence; database_description_sequence_number = net_to_host_long (database_description_sequence_number); /* first bullet item under ExStart in section 10.6 of OSPF specification (page 90) */ if ((sptr_database_packet_header->flags._bit.initialize == TRUE) && (sptr_database_packet_header->flags._bit.more == TRUE) && (sptr_database_packet_header->flags._bit.master == TRUE) && (size_of_packet == 0x00000000L) && (sptr_neighbor->id > ospf.router_id)) { sptr_neighbor->mode = OSPF_SLAVE; /* router is now OSPF_SLAVE */ sptr_neighbor->flags._byte = 0x0000; /* set to slave */ sptr_neighbor->database_description_sequence_number = database_description_sequence_number; /* set the sequence number to that specified by the master */ } /* second bullet item under ExStart in section 10.6 of OSPF specification (page 90) */ else if ((sptr_database_packet_header->flags._bit.initialize == FALSE) && (sptr_database_packet_header->flags._bit.master == FALSE) && (sptr_neighbor->database_description_sequence_number == database_description_sequence_number) && (sptr_neighbor->id < ospf.router_id)) { sptr_neighbor->mode = OSPF_MASTER; /* router is now OSPF_MASTER */ sptr_neighbor->flags._byte = 0x0000; sptr_neighbor->flags._bit.master = TRUE; /* set to master */ } else if (sptr_neighbor->id == ospf.router_id) { return_type.exit_routine = FALSE; return_type.packet_state = OSPF_ERROR_DATABASE_DESCRIPTION_ROUTER_ID; /* ignore packet */ return (return_type); } else { return_type.exit_routine = FALSE; return_type.packet_state = GOOD_RECEIVE; /* ignore packet */ return (return_type); }#if defined (__OPAQUE_LSA__) /* Check for opaque capability */ if ((sptr_database_packet_header->options._bit.opaque == TRUE) && (ospf.opaque_capability == TRUE)) { sptr_neighbor->opaque_capability = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -