?? ospf_to_rtm.c
字號:
/* ospf_to_rtm.c *//* Copyright 2000-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02i,11jun03,ram SPR#88825 Added support for policy best match on redistributed routes02h,08may03,asr Changes to make OSPF virtual stack compatible02g,14may03,agi Changed RWOS semaphores to vxWorks semaphores02f,28jan03,ram SPR 85050 Added support for external route redistribution based on OSPF external metric values02e,14jan03,asr SPR 85632 Disallow redistribution of loopback address02d,06jan03,ram SPR 85432 Changes to allow more OSPF external route processing02c,09dec02,ram SPR 83418 Added support for OSPF metric type and value configuration02b,03dec02,ram Modified ospf_export_route_from_rtm to allow static routes with full mask. SPR#8458802a,08oct02,agi Fixed compiler warnings27,22jun02,kc Modified ospf_export_route_from_rtm() to also checked and ignore routes with OSPF_INTERNAL route tag.26,30may02,kc Fixed ospf_export_route_from_rtm() to correctly process the route information from tRtmOspf task. Modified ospf_is_protocol_redistributed() to check for default route redistibution capability.25,24may02,kc Modified ospf_register_with_rtm() for Synth Stack to use ospf_sysctl_input as argument to protocol_rtm_init().24,06april02,kc Properly check the protocol_rtm_init() return value.23,07february02,jkw Fix forwarding address for external lsa.22,27sep01,kc Modified ospf_export_route_from_rtm() so that it no longer reference21,26september00,reshma Added WindRiver CopyRight20,25september00,reshma RFC-1587 implementation for OSPF NSSA Option, also tested against ANVL.19,07july00,reshma Unix compatibility related changes.18,04april00,reshma Added some MIB support (Read only).Passed all important ANVL OSPF tests.17,23december99,reshma Compatibility with VxWorks-IP and VxWorks RTM-interface16,22july99,jack Changes and more checks in export from bgp and export from RTM into OSPF15,19july99,jack RFC 1745 tag related changes14,10may99,jack removed some debug stuff13,22february99,jack Changes in function ospf_is_protocol_redistributed to reflect changes in kroute.h (chnage in definition of OTHER_ROUTING_PROTOCOL_TYPE )12,22february99,jack Changes in ospf_is_protocol_redistributed to reflect changes in kroute.h11,28december98,jack Compiled and added some comments10,11november98,jac 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_to_rtm.c is used for importing and exporting routes to the routing tablemanager. This file registers the OSPF protocol to the routing table manager.This file is used every time a route needs to be exported or imported.*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ */#if defined(__OSPF_ROUTER_STACK__)#include "protocol_rtm_interface.h"#endif /*__OSPF_ROUTER_STACK__*//************************************************************************/#if defined (__RTM__)/**********************************************************************************************************************************/static enum TEST ospf_is_network_redistributed (IP_ROUTE_ENTRY *sptr_ip_route, LINK *sptr_address_mask_pair);/* SPR 83418 -- Begin */static void ospf_set_default_redistribution_metrics (IP_ROUTE_ENTRY *sptr_ip_route);/* SPR 83418 -- End *//**********************************************************************************************************************************/enum TEST ospf_register_with_rtm (void){ RTM_HANDLE protocol_handle = 0;#if defined (__OSPF_ROUTER_STACK__) protocol_handle = protocol_rtm_init(#if defined (VIRTUAL_STACK) ospf.ospf_vsid,#endif /* VIRTUAL_STACK */ ospf_export_route_from_rtm, ospf_sysctl_input, "tRtmOspf" ); if ( protocol_handle == (RTM_HANDLE)NULL ) { OSPF_PRINTF_RTM (OSPF_RTM_PRINTF, "OSPF_RTM_PRINTF: Unable to register the routing call backs \n"); return (FAIL); }#else /*__OSPF_ROUTER_STACK__*/ OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_register_with_rtm\r\n"); OSPF_PRINTF_RTM (OSPF_RTM_PRINTF, "OSPF_RTM_PRINTF: Registering with RTM \r\n"); protocol_handle = rtm_register_protocol (RTM_IP, RTM_OSPF_PROTOCOL_TYPE, 1, &ospf_export_route_from_rtm, 0x00); if (protocol_handle == NULL) { OSPF_PRINTF_RTM (OSPF_RTM_PRINTF, "OSPF_RTM_PRINTF: Failed to register with RTM: error code:%lx \r\n", protocol_handle); return (FAIL); }#endif /* __OSPF_ROUTER_STACK__ */ ospf.ospf_rtm_handle = protocol_handle; return (PASS);}/**********************************************************************************************************************************/STATUS ospf_export_route_from_rtm (int rtm_operation, ROUTE_DESC *sptr_rtm_route){ IP_ROUTE_ENTRY ip_route; enum BOOLEAN mutex_acquired; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_export_route_from_rtm\r\n"); if ( sptr_rtm_route == NULL ) return ERROR; memset( (char *)&ip_route, 0, sizeof(IP_ROUTE_ENTRY) ); rtm_translate_route_desc_to_ip_route_entry (sptr_rtm_route, &ip_route); /* ignore routes that ospf added to the routing table */ if ( (ip_route.ipRouteProto == RTM_OSPF_PROTOCOL_TYPE) || (ip_route.route_tag == OSPF_INTERNAL) ) return OK; /* if the RTF_GATEWAY flag is not set, this is direct connected route. Sanity * check to determine if the route is also a default route. Default route has * destination address 0.0.0.0, netmask 0.0.0.0, next hop of non-zero value * and rtm flags of 0x101 (RTF_CLONING and RTF_UP). */ if ( (sptr_rtm_route->flags & RTF_GATEWAY) != RTF_GATEWAY ) { if ( sptr_rtm_route->flags & (RTF_CLONING | RTF_UP) ) { if ( (ip_route.target != 0x00000000) || (ip_route.mask != 0x00000000) ) return OK; } else return OK; /* direct connected route with other RTF flags set, ignore it */ } mutex_acquired = semTake (ospf_global_mutex, WAIT_FOREVER); /* SPR 85432 -- Begin */ if (ospf_is_protocol_redistributed (&ip_route) == FAIL) { semGive (ospf_global_mutex); return (ERROR); } semGive (ospf_global_mutex); /* SPR 85432 -- End */ switch (rtm_operation) { case RTM_ADD: /* SPR 85050 */ case RTM_ADDEXTRA: { /* * the largest hop count for a RIP route is 15. If the metric value * exceeded the max, ignore this RIP route since RIP will eventually * remove this route when the garbage collection timer kicks in. If * RIP later determines that the route is again reachable, the metric * will be updated and we will receive the route change event via the * routing socket message. */ if ((ip_route.ipRouteProto == RTM_RIP_PROTOCOL_TYPE) && (ip_route.metric == 0x10)) { break; /* ip_route.metric = OSPF_LSInfinity; */ } /* * When an AS external advertisement (LS Type = 5) is describing a default * route, its Link State ID is set to DefaultDestination (0.0.0.0). */ if (ospf.autonomous_system_border_router == TRUE) { /* SPR 85050 */ semTake (ospf_external_route_mutex, WAIT_FOREVER); ospf_queue_export_route_to_ospf (ip_route.target,ip_route.mask,ip_route.metric, /*DefaultDestination*/ ip_route.gateway, ip_route.route_tag, ip_route.ipRouteProto); semGive (ospf_external_route_mutex); } break; } case RTM_DELETE: /* SPR 85050 */ case RTM_DELEXTRA: { delete_exported_route_from_ospf(ip_route.target,ip_route.mask, ip_route.metric, ip_route.gateway, ip_route.route_tag, ip_route.ipRouteProto); break; } default: break; } return (OK);}/**********************************************************************************************************************************/enum TEST ospf_is_protocol_redistributed (IP_ROUTE_ENTRY *sptr_ip_route){ OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_is_protocol_redistributed\r\n"); switch (sptr_ip_route->ipRouteProto) { case IP_ROUTING_PROTOCOL_TYPE: /* covers OTHER_ROUTING_PROTOCOL_TYPE as well - satic both have a value of 1*/ case LOCALLY_CONFIGURED_TYPE: if (ospf.ospf_redistribution_configuration.redistribute_all_static == TRUE) { /* SPR 83418 -- Begin */ /* check first if this subnet is redistributed, if it is then the metric * type and value is set to the configured values else the default type and * value will apply */ if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_static_subnets) == FAIL) { ospf_set_default_redistribution_metrics(sptr_ip_route); } /* SPR 83418 -- End */ return (PASS); } if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_static_subnets) == PASS) { return (PASS); } /* also check if default route redistribution capability is set */ /* SPR 83418 -- Begin */ if ((sptr_ip_route->target == 0x00000000) && (ospf.ospf_redistribution_configuration.redistribute_ip_default_route == TRUE )) { ospf_set_default_redistribution_metrics(sptr_ip_route); return (PASS); } /* SPR 83418 -- End */ break; case RIP_PROTOCOL_TYPE: if (ospf.ospf_redistribution_configuration.redistribute_all_rip == TRUE) { /* SPR 83418 -- Begin */ if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_rip_subnets) == FAIL) { ospf_set_default_redistribution_metrics(sptr_ip_route); } /* SPR 83418 -- End */ return (PASS); } if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_rip_subnets) == PASS) { return (PASS); break; case BGP_PROTOCOL_TYPE: if (ospf.ospf_redistribution_configuration.redistribute_all_bgp == TRUE) { /* SPR 83418 -- Begin */ if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_bgp_subnets) == FAIL) { ospf_set_default_redistribution_metrics(sptr_ip_route); } /* SPR 83418 -- End */ return (PASS); } if (ospf_is_network_redistributed (sptr_ip_route, (LINK *) &ospf.ospf_redistribution_configuration.ospf_imported_bgp_subnets) == PASS) { return (PASS); } break; default: break; } return (FAIL);}/**********************************************************************************************************************************/static enum TEST ospf_is_network_redistributed (IP_ROUTE_ENTRY *sptr_ip_route, LINK *sptr_address_mask_pair){ OSPF_ADDRESS_MASK_PAIRS *sptr_address_mask_pair_to_check; OSPF_ADDRESS_MASK_PAIRS *sptr_best_match_pair = NULL; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_is_network_redistributed\r\n"); /* SPR#88825 */ /* Find the best match for the redistributed route, if there is a match*/ for (sptr_address_mask_pair_to_check = (OSPF_ADDRESS_MASK_PAIRS *) sptr_address_mask_pair->sptr_forward_link; sptr_address_mask_pair_to_check != NULL; sptr_address_mask_pair_to_check = sptr_address_mask_pair_to_check->sptr_forward_link) { /* special consideration for default route. If the redistribution policy * is for default route, the comparison is only meaningful if the target * entry is a default route as well. Otherwise, the present of the * default route in the redistribution policy becomes the catch all for * all the routes and that is not what we want */ if ((sptr_address_mask_pair_to_check->network_address == 0x00000000) && (sptr_address_mask_pair_to_check->network_mask == 0x00000000) && (sptr_ip_route->target != 0x000000000) && (sptr_ip_route->mask != 0x00000000)) continue; if ((sptr_address_mask_pair_to_check->network_address & sptr_address_mask_pair_to_check->network_mask) == (sptr_ip_route->target & sptr_address_mask_pair_to_check->network_mask)) { if(sptr_best_match_pair == NULL) { /* First match found save it*/ sptr_best_match_pair = sptr_address_mask_pair_to_check; } else { /* A match was found before, choose the one with a larger mask*/ if(sptr_best_match_pair->network_mask < sptr_address_mask_pair_to_check->network_mask) { sptr_best_match_pair = sptr_address_mask_pair_to_check; } } } } /* Apply policy if a match was found*/ if(sptr_best_match_pair != NULL) { /* SPR 83418 -- Begin */ /* Set the metric type and value */ if(sptr_best_match_pair->metric_value == 0x00000000) { sptr_ip_route->metric = sptr_ip_route->metric_4; } else { sptr_ip_route->metric = sptr_best_match_pair->metric_value; } sptr_ip_route->metric = (sptr_ip_route->metric & 0x00ffffff); if(sptr_ip_route->metric == 0x00000000) sptr_ip_route->metric = OSPF_EXTERNAL_DEFAULT_METRIC; if(sptr_best_match_pair->metric_type == OSPF_EXTERNAL_METRIC_TYPE_2) { sptr_ip_route->metric = (sptr_ip_route->metric | OSPF_ASE_bit_E); } /* SPR 83418 -- End */ return (PASS); } return (FAIL);}/* SPR 83418 -- Begin *//**********************************************************************************************************************************/static void ospf_set_default_redistribution_metrics (IP_ROUTE_ENTRY *sptr_ip_route){ OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_set_redistribution_metrics\r\n"); /* Set the metric to the value entered by the external protocol, if that is zero * set the metric to 20 (external default) also the default type is type 2 external*/ sptr_ip_route->metric = sptr_ip_route->metric_4; sptr_ip_route->metric = (sptr_ip_route->metric & 0x00ffffff); if (sptr_ip_route->metric == 0x00000000) sptr_ip_route->metric = OSPF_EXTERNAL_DEFAULT_METRIC; sptr_ip_route->metric = (sptr_ip_route->metric | OSPF_ASE_bit_E);}/* SPR 83418 -- End */#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -