📄 ospf_hello.c
字号:
case OSPF_NBMA: case OSPF_BROADCAST: { if (sptr_new_neighbor != NULL) { if ((sptr_new_neighbor->id == 0x00000000L) || (sptr_new_neighbor->id != router_id)) /* Update neighbor ID */ { sptr_new_neighbor->id = router_id; } } else /* Allocate a new neighbor */ { if ((sptr_interface->type == OSPF_NBMA) && (sptr_interface->priority != 0x0000)) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: OSPF_NBMA Designated Router eligible neighbors should be configured.\r\n"); } sptr_new_neighbor = (OSPF_NEIGHBOR *) table_malloc (1, sizeof (OSPF_NEIGHBOR)); if (sptr_new_neighbor == NULL) { ospf_print_memory_error_message_and_free_buffer_if_necessary ((void *) NULL, "OSPF_NEIGHBOR"); return (NULL); } memset (sptr_new_neighbor, 0x00, sizeof (OSPF_NEIGHBOR)); /* SPR 81628 Begin: We also need to initialize the array which holds LS request*/ for(i=0; i < OSPF_LS_MAX; i++) { sptr_new_neighbor->sptr_ls_request[i] = NULL; } /*SPR 81628: end*/ ospf_set_neighbor_fields (sptr_new_neighbor, router_id, source_address, cryptographic_sequence_number, sptr_interface, sptr_hello->router_priority, sptr_hello->options._byte, OSPF_NEIGHBOR_DOWN); ospf_add_neighbor (sptr_interface, sptr_new_neighbor); } break; } default: { break; } } return (sptr_new_neighbor);}/*************************************************************************** ospf_set_neighbor_fields - set the neighbor fields for the hello packet** This routine will set the neighbor fields of the hello packet.** <sptr_neighbor> Neighbor associated with hello packet** <router_id> Router id of hello packet** <address> Address of neighbor** <cryptographic_sequence_number> Cryptographic sequence number** <sptr_interface> OSPF interface** <priority> Priority of neighbor** <options> Options of neighbor** <state> State of neighbor** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void ospf_set_neighbor_fields (OSPF_NEIGHBOR *sptr_neighbor,ULONG router_id,ULONG address,ULONG cryptographic_sequence_number, OSPF_INTERFACE *sptr_interface,USHORT priority,BYTE options,enum OSPF_NEIGHBOR_STATE state){ OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_set_neighbor_fields\r\n"); sptr_neighbor->id = router_id; sptr_neighbor->address = address; sptr_neighbor->cryptographic_sequence_number = cryptographic_sequence_number; sptr_neighbor->sptr_interface = sptr_interface; sptr_neighbor->priority = priority; sptr_neighbor->state = state; sptr_neighbor->options._byte = options; sptr_neighbor->mib_address_less_index = 0x00000000L; sptr_neighbor->mib_nbma_status = TRUE; sptr_neighbor->mib_nbma_permanence = FALSE; sptr_neighbor->mib_hello_suppressed = FALSE; return;}/*************************************************************************** ospf_examine_rest_of_hello_packet_and_generate_events_as_necessary - examine the rest of the hello packet** This routine will examine the rest of the hello packet and* generate events if necessary. Events such as calculating the* designated router and backup designated router.** <sptr_hello> Hello packet header** <sptr_new_neighbor> New neighbor** <sptr_interface> OSPF interface** <size_of_packet> Size of hello packet** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void ospf_examine_rest_of_hello_packet_and_generate_events_as_necessary (OSPF_HELLO_HEADER *sptr_hello,OSPF_NEIGHBOR *sptr_new_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){ enum BOOLEAN heard_from_router; enum BOOLEAN neighbor_was_declaring_itself_designated_router; enum BOOLEAN neighbor_was_declaring_itself_backup_designated_router; enum BOOLEAN neighbor_is_declaring_itself_designated_router; enum BOOLEAN neighbor_is_declaring_itself_backup_designated_router; ULONG designated_router = 0; ULONG backup_designated_router = 0; OSPF_NEIGHBOR *sptr_neighbor = NULL; OSPF_NEIGHBOR *sptr_next_neighbor = NULL; ULONG both_found; ULONG dr_and_bdr_present; OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_examine_rest_of_hello_packet_and_generate_events_as_necessary\r\n"); both_found = 0x00000000L; dr_and_bdr_present = 0x00000000L; ospf_execute_neighbor_state_machine (OSPF_HELLO_RECEIVED, sptr_new_neighbor->state, sptr_interface, sptr_new_neighbor); heard_from_router = ospf_examine_neighbors_in_hello_packet (sptr_hello, sptr_new_neighbor, sptr_interface, size_of_packet); if (heard_from_router == FALSE) { /* Fix TSR #291468 SPR #83318 Start */ if (sptr_new_neighbor->state >= OSPF_NEIGHBOR_2_WAY) { ospf_execute_neighbor_state_machine (OSPF_INACTIVITY_TIMER, sptr_new_neighbor->state, sptr_interface, sptr_new_neighbor); ospf_originate_router_links_advertisement (sptr_interface->sptr_area); return; } /* Fix TSR #291468 SPR #83318 End */ ospf_execute_neighbor_state_machine (OSPF_ONE_WAY, sptr_new_neighbor->state, sptr_interface, sptr_new_neighbor); return; } else { ospf_update_router_priority_for_neighbor (sptr_new_neighbor, (USHORT) sptr_hello->router_priority, sptr_interface); neighbor_was_declaring_itself_designated_router = ospf_check_if_addresses_match (sptr_new_neighbor->designated_router, sptr_new_neighbor->address); OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: 1 neighbor_was_declaring_itself_designated_router = %d (0: FALSE, 1: TRUE) \r\n", neighbor_was_declaring_itself_designated_router ); neighbor_was_declaring_itself_backup_designated_router = ospf_check_if_addresses_match ( sptr_new_neighbor->backup_designated_router, sptr_new_neighbor->address); designated_router = net_to_host_long (sptr_hello->designated_router); backup_designated_router = net_to_host_long (sptr_hello->backup_designated_router); neighbor_is_declaring_itself_designated_router = ospf_check_if_addresses_match (designated_router, sptr_new_neighbor->address); neighbor_is_declaring_itself_backup_designated_router = ospf_check_if_addresses_match (backup_designated_router, sptr_new_neighbor->address); /* in all cases, the neighbor's designated router and backup designated router items in the neighbor structure are * updated accordingly */ sptr_new_neighbor->designated_router = designated_router; sptr_new_neighbor->backup_designated_router = backup_designated_router; /* if the receiving interface is in state Waiting and this neighbor is declaring itself to be backup designated router * or is declaring itself to be designated router and there is no backup designated router, then the receiving * interface's state machine is scheduled with the event BackupSeen */ OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: 2 neighbor_was_declaring_itself_designated_router = %d (0: FALSE, 1: TRUE)\r\n", neighbor_was_declaring_itself_designated_router ); dr_and_bdr_present = ospf_check_if_only_dr_is_present_and_no_bdr ( sptr_interface, sptr_hello, size_of_packet); if ((sptr_interface->state == OSPF_INTERFACE_WAITING) && ((neighbor_is_declaring_itself_backup_designated_router == TRUE) || ((neighbor_is_declaring_itself_designated_router == TRUE) && (backup_designated_router == 0x00000000L)))) { for (sptr_neighbor = sptr_interface->sptr_neighbor; sptr_neighbor != NULL; sptr_neighbor = sptr_next_neighbor) { sptr_next_neighbor = sptr_neighbor->sptr_forward_link; if ( (sptr_neighbor->address == net_to_host_long (sptr_hello->designated_router)) || (sptr_interface->address == net_to_host_long (sptr_hello->designated_router)) ) { ++both_found; } else if ( (sptr_neighbor->address == net_to_host_long (sptr_hello->backup_designated_router)) || (sptr_interface->address == net_to_host_long (sptr_hello->backup_designated_router)) ) { ++both_found; } } if ( ((dr_and_bdr_present == 0x00000002) && (both_found == 0x00000002)) || /* Both DR and BDR present we found both on neighbor list */ ((dr_and_bdr_present == 0x00000001) && (both_found == 0x00000001)) /* only DR present we found him on neighbor list */ ) { ospf_execute_interface_state_machine (OSPF_BACKUP_SEEN, sptr_interface->state, sptr_interface); } } /* if the neighbor is declaring itself to be designated router and it had not previously, or the neighbor is not * declaring itself designated router where it had previously, then the receiving interface's state machine is scheduled * with the event NeighborChange */ else if (neighbor_is_declaring_itself_designated_router != neighbor_was_declaring_itself_designated_router) { sptr_interface->flags._bit.neighbor_change = TRUE; ospf_execute_interface_state_machine (OSPF_NEIGHBOR_CHANGE, sptr_interface->state, sptr_interface); } /* if the neighbor is declaring itself to be backup designated router and it had not previously, or the neighbor is not * declaring itself backup designated router where it had previously, then the receiving interface's state machine is * scheduled with the event NeighborChange */ else if (neighbor_is_declaring_itself_backup_designated_router != neighbor_was_declaring_itself_backup_designated_router) { sptr_interface->flags._bit.neighbor_change = TRUE; ospf_execute_interface_state_machine (OSPF_NEIGHBOR_CHANGE, sptr_interface->state, sptr_interface); /* SPR 76417 -- Begin */ } else { /* Fix for ANVL test 13.17, RFC 2328, section 9.4, step 2 */ /* This router is DR on this interface and there is a neighbor on the interface that did not elect himself BDR, elect it */ /* SPR86263 */ if ((sptr_interface->designated_router.address == sptr_interface->address) && (ntohl(sptr_hello->backup_designated_router) == 0L) && (sptr_hello->router_priority != 0)) { ospf_run_designated_router_election (sptr_interface); } } /* SPR 76417 -- End */ } OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: 3 neighbor_was_declaring_itself_designated_router = %d (0: FALSE, 1: TRUE)\r\n", neighbor_was_declaring_itself_designated_router ); return;}/*************************************************************************** ospf_examine_neighbors_in_hello_packet - examine neighbors in hello packet** This routine will examine all the neighbors in the hello packet* and check if the neighbor has been heard from before.** <sptr_hello> Hello packet header** <sptr_new_neighbor> New neighbor** <sptr_interface> OSPF interface** <size_of_packet> Size of hello packet** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static enum BOOLEAN ospf_examine_neighbors_in_hello_packet (OSPF_HELLO_HEADER *sptr_hello,OSPF_NEIGHBOR *sptr_new_neighbor, OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){ enum BOOLEAN heard_from_router; ULONG *ulptr_router_heard_from; ULONG size_of_neighbor_optional_fields =0; ULONG router_heard_from =0; OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_examine_neighbors_in_hello_packet\r\n"); heard_from_router = FALSE; ulptr_router_heard_from = &(sptr_hello->backup_designated_router); for (size_of_neighbor_optional_fields = (ULONG) size_of_packet - OSPF_PACKET_SIZE - OSPF_HELLO_HEADER_SIZE; size_of_neighbor_optional_fields > 0x00000000L; size_of_neighbor_optional_fields -= sizeof (ULONG)) { ++ulptr_router_heard_from; router_heard_from = net_to_host_long (*ulptr_router_heard_from); if (router_heard_from == ospf.router_id) { heard_from_router = TRUE; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Seen my self (Router ID (HEX) %lx) in HELLO Setting TWO-WAY for neighbor on interface (address in HEX) %lx with neighbor address (HEX) %lx. Current new neighbor state %lx AND interface state %lx\r\n", ospf.router_id, sptr_interface->address, sptr_new_neighbor->address, sptr_new_neighbor->state, sptr_interface->state ); if (sptr_new_neighbor->state < OSPF_NEIGHBOR_2_WAY) { ospf_execute_neighbor_state_machine (OSPF_TWO_WAY_RECEIVED, sptr_new_neighbor->state, sptr_interface, sptr_new_neighbor); } break; } } return (heard_from_router);}/*************************************************************************** ospf_update_router_priority_for_neighbor - update router priority of neighbor** This routine will update the router priority of the neighbor from the hello* packet.** <sptr_new_neighbor> New neighbor** <router_priority> Router priority** <sptr_interface> OSPF interface** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void ospf_update_router_priority_for_neighbor (OSPF_NEIGHBOR *sptr_new_neighbor,USHORT router_priority, OSPF_INTERFACE *sptr_interface){ OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_update_router_priority_for_neighbor\r\n"); if (sptr_new_neighbor->priority != router_priority) { sptr_new_neighbor->priority = router_priority; sptr_interface->flags._bit.neighbor_change = TRUE; ospf_execute_interface_state_machine (OSPF_NEIGHBOR_CHANGE, sptr_interface->state, sptr_interface); } return;}/*************************************************************************** ospf_check_if_only_dr_is_present_and_no_bdr - check if dr is present and no bdr present** This routine will check if only a designated router is present.** <sptr_interface> OSPF interface** <sptr_hello> Hello packet header** <size_of_packet> Size of hello packet** RETURNS: ULONG** ERRNO: N/A** NOMANUAL*//******************************************************************//* third bullet item in section 10.5 of OSPF spec. (p 89) */static ULONG ospf_check_if_only_dr_is_present_and_no_bdr (OSPF_INTERFACE *sptr_interface, OSPF_HELLO_HEADER *sptr_hello, ULONG size_of_packet ){ ULONG hello_packet_length_with_dr_and_bdr =0; ULONG hello_packet_length_without_dr_bdr_and_neighbors =0; PARAMETER_NOT_USED (sptr_interface); OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_check_if_only_dr_is_present_and_no_bdr\r\n"); hello_packet_length_with_dr_and_bdr = OSPF_PACKET_SIZE + OSPF_HELLO_HEADER_SIZE; hello_packet_length_without_dr_bdr_and_neighbors = hello_packet_length_with_dr_and_bdr - 8; if ( (size_of_packet < hello_packet_length_with_dr_and_bdr) && (size_of_packet > hello_packet_length_without_dr_bdr_and_neighbors) ) { if (sptr_hello->designated_router != 0x00000000L) { return (0x00000001L); /* only DR present */ } } else if (size_of_packet >= hello_packet_length_with_dr_and_bdr) { if ((sptr_hello->designated_router != 0x00000000L) && (sptr_hello->backup_designated_router != 0x00000000L) ) { return (0x00000002L); /* both DR and BDR present */ } else if ((sptr_hello->designated_router != 0x00000000L) && (sptr_hello->backup_designated_router == 0x00000000L) ) { return (0x00000001L); /* BDR is 0.0.0.0 */ } else if ((sptr_hello->designated_router == 0x00000000L) && (sptr_hello->backup_designated_router == 0x00000000L) ) { return (0x00000000L); } } else { return (0x00000000L); /* neither DR nor BDR present */ } return (0x00000000L);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -