📄 ospf_opaque_lsa.c
字号:
/* ospf_opaque_lsa.c *//* Copyright 2000-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02e,17jul03,agi Fixed compilation with __OPAQUE_LSA__ flag turned on02d,14may03,agi Changed RWOS semaphores to vxWorks semaphores02c,22apr03,ram SPR#76812 Modifications for OSPF performance enhancements02b,19nov02,mwv Merge TMS code SPR 8428402a,08oct02,agi Fixed compiler warnings01d,19apr02,jkw Fix memory leak for external lsas.01c,16apr02,jkw One copy of external and type 11 lsa01b,09apr02,jkw Sequence number wrap01a,20dec01,jkw Removed sptr_area->sptr_interfaces structure.*//*DESCRIPTIONospf_opaque_lsa.c is used for originating opaque lsas. This file contains theAPIs to originate, retrieve, remove, and register callback functions for opaquelsas.This file is used whenever an opaque lsa needs to be manipulated.*//******************************************************************************//*opaque lsa opaque apis jkw*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ */static void ospf_te_build_router_tlv (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_link_type (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_link_id (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_local_ip_address (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_remote_ip_address (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_metric (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_maximum_bandwidth (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_maximum_reservable_bandwidth (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_unreserved_bandwidth (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_sub_tlv_resource_class_color (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_build_link_tlv (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);static void ospf_te_lsa_body_set (char **new_lsa, USHORT *length, OSPF_TE_PARAMETERS *pTLVparms);#if defined (__OPAQUE_LSA__)/****************************************************************************//* Function: ospfSetOrigOpaqueLsa Input: ULONG - ip_address ULONG - netmask BYTE lsa_type BYTE opaque_type RETURNS: int - 0|-1 Description: This function finds the interfaces to flood an opaque lsa out and calls a callback function to the traffic engineering extension to add the type, length, value field to the opaque lsa.*/int ospfSetOrigOpaqueLsa(ULONG ip_address, ULONG netmask, BYTE lsa_type, BYTE opaque_type){ OSPF_OPAQUE_CALLBACK *sptr_opaque_callback = NULL; OSPF_AREA_ENTRY *sptr_area = NULL; OSPF_AREA_ENTRY *sptr_next_area = NULL; OSPF_INTERFACE *sptr_interface = NULL; OSPF_INTERFACE *sptr_next_interface = NULL; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospfSetOrigOpaqueLsa\r\n"); semTake (ospf_global_mutex , WAIT_FOREVER); if (ospf.opaque_capability == TRUE) { for (sptr_interface = ospf.sptr_interface_list; sptr_interface != NULL; sptr_interface = sptr_next_interface) { sptr_next_interface = sptr_interface->sptr_forward_link; if ((sptr_interface->address & sptr_interface->netmask) == (ip_address & netmask)) { break; } } switch (lsa_type) { case 9: if (sptr_interface != NULL) { for (sptr_area = ospf.sptr_area_list; sptr_area != NULL; sptr_area = sptr_next_area) { sptr_next_area = sptr_area->sptr_forward_link; if (sptr_interface->sptr_area != NULL) { if (sptr_area->area_id == sptr_interface->sptr_area->area_id) { for (sptr_interface = sptr_area->sptr_interfaces; sptr_interface != NULL; sptr_interface = sptr_next_interface) { sptr_next_interface = sptr_interface->sptr_forward_link; if (sptr_interface->area_id == sptr_area->area_id) { sptr_opaque_callback = ospfRetrieveOpaqueCallback(lsa_type, opaque_type); if (sptr_opaque_callback != NULL) { sptr_opaque_callback->opaque_lsa_originate_hook((void *)sptr_interface, lsa_type, opaque_type, 0); } } } } } } } else { semGive (ospf_global_mutex ); return -1; } semGive (ospf_global_mutex ); return 0; case 10: if (sptr_interface != NULL) { for (sptr_area = ospf.sptr_area_list; sptr_area != NULL; sptr_area = sptr_next_area) { sptr_next_area = sptr_area->sptr_forward_link; if (sptr_interface->sptr_area != NULL) { if (sptr_area->area_id == sptr_interface->sptr_area->area_id) { sptr_opaque_callback = ospfRetrieveOpaqueCallback(lsa_type, opaque_type); if (sptr_opaque_callback != NULL) { sptr_opaque_callback->opaque_lsa_originate_hook((void *)sptr_area, lsa_type, opaque_type, 0); } } } } } else { semGive (ospf_global_mutex ); return -1; } semGive (ospf_global_mutex ); return 0; case 11: if (sptr_interface != NULL) { sptr_opaque_callback->opaque_lsa_originate_hook((void *)sptr_interface, lsa_type, opaque_type, 0); } else { semGive (ospf_global_mutex ); return -1; } semGive (ospf_global_mutex ); return 0; default: semGive (ospf_global_mutex ); return -1; } } else { semGive (ospf_global_mutex ); return -1; }}/***********************************************************************************************************************************//* Function: ospfRemoveType9 Input: ULONG - opaque_lsid ULONG - opaque_advertising_router RETURNS: int - 0|-1 Description: This function finds the opaque lsa in the opaque lsdb using the link state id and the advertising router as keys. The link state advertisement is prematurely aged by setting the opaque lsa's age to MAXIMUM_AGE and floods it out its interfaces. It then removes the opaque lsa from the appropriate lists.*/int ospfRemoveType9(ULONG opaque_lsid, ULONG opaque_advertising_router) { OSPF_LS_DATABASE_HEAD *sptr_ls_database_head = NULL ; OSPF_LS_DATABASE_ENTRY *sptr_database_entry = NULL; OSPF_LS_DATABASE_ENTRY *sptr_next_database_entry = NULL; USHORT age =0; enum TEST test_return_type; ULONG index; ULONG advertising_router; ULONG lsid; OSPF_AREA_ENTRY *sptr_area = NULL; OSPF_AREA_ENTRY *sptr_next_area = NULL; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospfRemoveType9 \r\n"); semTake (ospf_global_mutex , WAIT_FOREVER); if (ospf.opaque_capability == TRUE) { for (sptr_area = ospf.sptr_area_list; sptr_area != NULL; sptr_area = sptr_next_area) { sptr_next_area = sptr_area->sptr_forward_link; for (index = 0x00000000L, sptr_ls_database_head = &(sptr_area->opaque_ls_database_hash_table[TYPE_9_LSA][index]); /* for each hash list */ index < OSPF_HASH_TABLE_SIZE; ++index, sptr_ls_database_head = &(sptr_area->opaque_ls_database_hash_table[TYPE_9_LSA][index])) { if (sptr_ls_database_head == NULL) { continue; } /* SPR#76812 */ for (sptr_database_entry = sptr_ls_database_head->sptr_linear_database_entry; sptr_database_entry != NULL; sptr_database_entry = sptr_next_database_entry) { sptr_next_database_entry = sptr_database_entry->sptr_forward_link; advertising_router = sptr_database_entry->advertisement.sptr_router->ls_header.advertising_router; advertising_router = net_to_host_long (advertising_router); lsid = sptr_database_entry->advertisement.sptr_router->ls_header.id; lsid = net_to_host_long(lsid); if ((lsid == opaque_lsid) && (advertising_router == opaque_advertising_router)) { age = OSPF_MAXIMUM_AGE; age = host_to_net_short (age); sptr_database_entry->advertisement.sptr_router->ls_header.age = age; test_return_type = ospf_check_if_advertisements_link_state_id_is_equal_to_one_of_the_routers_own_IP_interface_addresses ( sptr_database_entry->advertisement.sptr_router); if ((sptr_database_entry->ls_database_freeme == FALSE) && ((advertising_router == ospf.router_id) || ((sptr_database_entry->advertisement.sptr_router->ls_header.type == OSPF_LS_NETWORK) && (test_return_type == PASS)) ) ) { (void) ospf_flood_advertisement_out_some_subset_of_the_routers_interfaces (sptr_database_entry->advertisement.sptr_router, sptr_area, NULL, NULL, TRUE); sptr_database_entry->ls_database_freeme = TRUE; ospf_clean_up_retransmit_lists_affiliated_with_this_advertisement (sptr_database_entry); (void) ospf_free_database_entry (sptr_database_entry); sptr_database_entry = NULL; } else if ((sptr_database_entry->sptr_ls_database_retrans == NULL) && (ospf.number_of_neighbors_in_exchange_state == ospf.number_of_neighbors_in_full_state)) { ospf_clean_up_retransmit_lists_affiliated_with_this_advertisement (sptr_database_entry); (void) ospf_free_database_entry (sptr_database_entry); sptr_database_entry = NULL; } } } } } semGive (ospf_global_mutex ); return 0; } else { semGive (ospf_global_mutex ); return -1; }}/***********************************************************************************************************************************//* Function: ospfRemoveType10 Input: ULONG - opaque_lsid ULONG - opaque_advertising_router RETURNS: int - 0|-1 Description: This function finds the opaque lsa in the opaque lsdb using the link state id and the advertising router as keys. The link state advertisement is prematurely aged by setting the opaque lsa's age to MAXIMUM_AGE and floods it out its interfaces. It then removes the opaque lsa from the appropriate lists.*/int ospfRemoveType10(ULONG opaque_lsid, ULONG opaque_advertising_router) { OSPF_LS_DATABASE_HEAD *sptr_ls_database_head = NULL ; OSPF_LS_DATABASE_ENTRY *sptr_database_entry = NULL; OSPF_LS_DATABASE_ENTRY *sptr_next_database_entry = NULL; USHORT age =0; enum TEST test_return_type; ULONG index; ULONG advertising_router; ULONG lsid; OSPF_AREA_ENTRY *sptr_area = NULL; OSPF_AREA_ENTRY *sptr_next_area = NULL; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospfRemoveType10 \r\n"); semTake (ospf_global_mutex , WAIT_FOREVER); if (ospf.opaque_capability == TRUE) { for (sptr_area = ospf.sptr_area_list; sptr_area != NULL; sptr_area = sptr_next_area) { sptr_next_area = sptr_area->sptr_forward_link; for (index = 0x00000000L, sptr_ls_database_head = &(sptr_area->opaque_ls_database_hash_table[TYPE_10_LSA][index]); /* for each hash list */ index < OSPF_HASH_TABLE_SIZE; ++index, sptr_ls_database_head = &(sptr_area->opaque_ls_database_hash_table[TYPE_10_LSA][index])) { if (sptr_ls_database_head == NULL) { continue; } /* SPR#76812 */ for (sptr_database_entry = sptr_ls_database_head->sptr_linear_database_entry; sptr_database_entry != NULL; sptr_database_entry = sptr_next_database_entry) { sptr_next_database_entry = sptr_database_entry->sptr_forward_link; advertising_router = sptr_database_entry->advertisement.sptr_router->ls_header.advertising_router; advertising_router = net_to_host_long (advertising_router); lsid = sptr_database_entry->advertisement.sptr_router->ls_header.id; lsid = net_to_host_long(lsid); if ((lsid == opaque_lsid) && (advertising_router == opaque_advertising_router)) { age = OSPF_MAXIMUM_AGE; age = host_to_net_short (age); sptr_database_entry->advertisement.sptr_router->ls_header.age = age; test_return_type = ospf_check_if_advertisements_link_state_id_is_equal_to_one_of_the_routers_own_IP_interface_addresses ( sptr_database_entry->advertisement.sptr_router); if ((sptr_database_entry->ls_database_freeme == FALSE) && ((advertising_router == ospf.router_id) || ((sptr_database_entry->advertisement.sptr_router->ls_header.type == OSPF_LS_NETWORK) && (test_return_type == PASS)) ) ) { (void) ospf_flood_advertisement_out_some_subset_of_the_routers_interfaces (sptr_database_entry->advertisement.sptr_router, sptr_area, NULL, NULL, TRUE); sptr_database_entry->ls_database_freeme = TRUE; ospf_clean_up_retransmit_lists_affiliated_with_this_advertisement (sptr_database_entry); (void) ospf_free_database_entry (sptr_database_entry); sptr_database_entry = NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -