📄 ip_cmn_rte_table.ex.c
字号:
/** package. **/
FIN (ip_cmn_rte_table_create (node_objid));
/* Allocate memory. */
route_table = (IpT_Cmn_Rte_Table*) op_prg_mem_alloc (
sizeof (IpT_Cmn_Rte_Table));
/* Check if memory has been allocated. */
if (route_table == OPC_NIL)
{
/* Report an error message and terminate the simulation */
op_sim_end ("Error in IP common route table support code: ",
"Could not allocate memory for IpT_Cmn_Rte_Table data structure",
OPC_NIL, OPC_NIL);
}
/* Set the node_objid element. */
route_table->node_objid = node_objid;
/* Set the route table type also. */
route_table->vrf_table_ptr = vrf_table_ptr;
/* Create the Patricia trees. */
if (ip_rte_node_ipv4_active (ip_rmd_ptr))
{
route_table->ptree_ptr_array[InetC_Addr_Family_v4] = oms_ptree_create (32);
/* Initialize the list of default route entries. */
route_table->resolved_default_routes = op_prg_list_create ();
route_table->unresolved_default_routes = op_prg_list_create ();
}
else
{
/* IPv4 is not enabled on this node. */
route_table->ptree_ptr_array[InetC_Addr_Family_v4] = OPC_NIL;
route_table->resolved_default_routes = OPC_NIL;
route_table->unresolved_default_routes = OPC_NIL;
}
if (ip_rte_node_ipv6_active (ip_rmd_ptr))
{
route_table->ptree_ptr_array[InetC_Addr_Family_v6] = oms_ptree_create (128);
}
else
{
route_table->ptree_ptr_array[InetC_Addr_Family_v6] = OPC_NIL;
}
/* Initialize the gateway of last resort */
route_table->gateway_of_last_resort = OPC_NIL;
/* Set the number of entries to 0. */
route_table->num_entries = 0;
/* Set the routes threshold to 1 */
/* This is just in case Passive RIP routing is used */
route_table->usage_threshold = 1;
/* Set the load balancing type, assume per-packet */
route_table->load_type = IpC_Rte_Table_Load_Packet;
/* Create the list of routing protocol process */
/* information. */
route_table->routeproc_vptr = prg_vector_create (0, OPC_NIL, OPC_NIL);
/* Create the redistribution matrix list. */
route_table->redist_matrix_vptr = prg_vector_create (0, OPC_NIL, OPC_NIL);
/* Store the pointer to the Module data of */
/* this router. */
route_table->iprmd_ptr = ip_rmd_ptr;
/* Initialize the time at which the routing table was last updated */
/* using the time at which it is created -- i.e., now. */
route_table->last_update_time = op_sim_time ();
/* Define statistics to track route table updates. */
route_table->update_stathandle [IpC_Rte_Table_Any_Update] =
op_stat_reg ("Route Table.Total Number of Updates", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
route_table->update_stathandle [IpC_Rte_Table_Entry_Add] =
op_stat_reg ("Route Table.Number of Route Additions", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
route_table->update_stathandle [IpC_Rte_Table_Entry_Delete] =
op_stat_reg ("Route Table.Number of Route Deletions", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
route_table->update_stathandle [IpC_Rte_Table_Next_Hop_Update] =
op_stat_reg ("Route Table.Number of Next Hop Updates", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
route_table->update_stathandle [IpC_Rte_Table_Time_Between_Any_Update] =
op_stat_reg ("Route Table.Time Between Updates (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
route_table->update_stathandle [IpC_Rte_Table_Size] =
op_stat_reg ("Route Table.Size (number of entries)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
/* Set the Directly Connected route entry match funtion in IP module memory */
ip_rmd_ptr->rte_map_match_proc_array [IPC_DYN_RTE_DIRECTLY_CONNECTED] =
(IpT_Rte_Map_Entry_Match_Proc) ip_cmn_rte_table_dir_conn_rte_entry_match;
/* Initialize the pool memory object handles. */
if (OPC_FALSE == pmo_handles_init)
{
pmo_handles_init = OPC_TRUE;
ip_cmn_rte_table_entry_pmh = op_prg_pmo_define
("IP Common route table entry", sizeof (IpT_Cmn_Rte_Table_Entry), 256);
ip_cmn_rte_table_next_hop_entry_pmh = op_prg_pmo_define
("IP common route table next hop entry", sizeof (IpT_Next_Hop_Entry), 256);
ip_cmn_rte_table_dest_src_table_entry_pmh = op_prg_pmo_define
("IP common route table dest src entry", sizeof (IpT_Cmn_Rte_Dest_Src_Table_Entry), 256);
}
/* Initialize the dest src table to NIL. */
route_table->dest_src_table = OPC_NIL;
route_table->dest_src_table_size = 0;
FRET (route_table);
}
static void
ip_cmn_rte_table_port_info_verify (IpT_Cmn_Rte_Table* route_table, IpT_Dest_Prefix dest_prefix,
InetT_Address next_hop, IpT_Port_Info* port_info_ptr, IpT_Rte_Proc_Id proto)
{
int tbl_index;
IpT_Interface_Info* intf_ptr;
InetT_Address_Range* addr_range_ptr;
#ifndef OPD_NO_DEBUG
char dest_str [INETC_ADDR_STR_LEN];
char nh_str [INETC_ADDR_STR_LEN];
char src_proto_str [64];
char trace_msg [512];
#endif
/** Verifies the port info information specified by the **/
/** routing protocol is correct. **/
FIN (ip_cmn_rte_table_port_info_verify (route_table, dest_prefix, next_hop, ...));
tbl_index = ip_rte_intf_tbl_index_from_port_info_get (route_table->iprmd_ptr, *port_info_ptr);
/* Skip this check for Null0 or LSP routes. Also routes */
/* that use tunnel interfaces might pass an invalid next hop*/
/* Accept such routes wihtout further checks. */
if ((IPC_INTF_TBL_INDEX_NULL0 == tbl_index) ||
(IPC_INTF_TBL_INDEX_LSP == tbl_index) ||
(IPC_INTF_TBL_INDEX_MPLS == tbl_index) ||
(!inet_address_valid (next_hop)))
{
/* This is either a Null0 route or a LSP. Accept it. */
}
else if (IPC_INTF_INDEX_INVALID != tbl_index)
{
/* The port_info has been specified. Make sure it is */
/* correct. */
/* Get a pointer to the interface information of the */
/* interface specified by the port_info */
intf_ptr = inet_rte_intf_tbl_access_by_port_info (route_table->iprmd_ptr, *port_info_ptr);
/* If the port_info specified was invalid or if the */
/* next hop specified cannot be reached through the */
/* specified interface, print out a log message. */
if ((OPC_NIL == intf_ptr) ||
((OPC_FALSE == ip_rte_intf_unnumbered (intf_ptr)) &&
(OPC_FALSE == inet_rte_intf_addr_range_check (intf_ptr, next_hop, &addr_range_ptr))))
{
#ifndef OPD_NO_DEBUG
/* The port_info specified is incorrect */
/* Create prinatble version of the route attributes */
ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
inet_address_print (nh_str, next_hop);
/* Print out a sim log entry. */
ipnl_invalid_port_info_log_write (dest_str, nh_str, proto, *port_info_ptr, route_table->iprmd_ptr);
/* Print out a trace message also. */
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
ip_cmn_rte_proto_name_print (src_proto_str, proto);
sprintf (trace_msg, "Dest: %s, Next hop: %s, Protocol: %s, Intf tbl index: %d",
dest_str, nh_str, src_proto_str, tbl_index);
op_prg_odb_print_major ("The port info for the following entry was incorrect",
trace_msg, OPC_NIL);
}
#endif
/* Call the function that would set the port_info */
/* appropriately if the next hop is directly */
/* connected. */
inet_rte_addr_local_network (next_hop, route_table->iprmd_ptr, port_info_ptr);
}
}
else
{
/* Either the major_port or the minor_port of the */
/* port_info has not been specified. Make sure that */
/* the next hop is not directly connected. */
if (OPC_COMPCODE_SUCCESS == inet_rte_addr_local_network (next_hop,
route_table->iprmd_ptr, port_info_ptr))
{
#ifndef OPD_NO_DEBUG
/* The next_hop was actually directly connected. */
/* print out a log message. */
ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
inet_address_print (nh_str, next_hop);
/* Print out a sim log entry. */
ipnl_port_info_not_specified_in_rte_log_write (dest_str, nh_str,
proto, *port_info_ptr, route_table->iprmd_ptr);
/* Print out a trace message also. */
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
ip_cmn_rte_proto_name_print (src_proto_str, proto);
sprintf (trace_msg, "Dest: %s, Next hop: %s, Protocol: %s, Intf tbl index: %d",
dest_str, nh_str, src_proto_str,
ip_rte_intf_tbl_index_from_port_info_get (route_table->iprmd_ptr, *port_info_ptr));
op_prg_odb_print_major ("The port info for the following entry was not specified",
trace_msg, OPC_NIL);
}
#endif
}
}
FOUT;
}
static Compcode
ip_cmn_rte_table_dest_prefix_verify (IpT_Cmn_Rte_Table* route_table, IpT_Dest_Prefix dest_prefix)
{
/** Makes sure that the given destination prefix is valid **/
/** for the given route table. **/
FIN (ip_cmn_rte_table_dest_prefix_verify (route_table, dest_prefix));
/* If the destination prefix is not valid or that particular*/
/* IP version is not enabled on this node, return failure. */
if ((!ip_cmn_rte_table_dest_prefix_valid (dest_prefix)) ||
(OPC_NIL == route_table->ptree_ptr_array[ip_cmn_rte_table_dest_prefix_addr_family_get (dest_prefix)]))
{
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
op_prg_odb_print_major ("Attempt to insert an invalid entry into the",
"IP common route table", OPC_NIL);
}
#endif
FRET (OPC_COMPCODE_FAILURE);
}
else
{
/* The prefix is valid. */
FRET (OPC_COMPCODE_SUCCESS);
}
}
Compcode
Inet_Cmn_Rte_Table_Entry_Add_Options (IpT_Cmn_Rte_Table* route_table, void* src_obj_ptr,
IpT_Dest_Prefix dest_prefix, InetT_Address next_hop, IpT_Port_Info port_info,
int metric, IpT_Rte_Proc_Id proto, int admin_distance, int options)
{
InetT_Addr_Family addr_family;
IpT_Cmn_Rte_Table_Entry* route_entry;
IpT_Cmn_Rte_Table_Entry* curr_entry ;
OmsT_Ptree_Entry* new_ptree_entry;
OmsT_Ptree_Entry* curr_ptree_entry;
IpT_Rte_Proc_Id proto_type;
IpT_Rte_Proc_Id removed_proto;
int redist_type;
OmsT_Ptree* ptree_ptr;
OmsT_Ptree_Address address;
int tbl_index;
char convergence_reason [512];
/* Debug vars. */
char dest_str [INETC_ADDR_STR_LEN];
char nh_str [INETC_ADDR_STR_LEN];
char src_proto_str [64];
char trace_msg [512];
/** Check for an existing entry for the entered route. **/
/** If no entry exists, allocate memory for an **/
/** IpT_Cmn_Rte_Table_Entry object and initialize its data **/
/** elements with the values passed in. Add it to the end **/
/** of the route entries list pointed to by the route_table **/
/** argument. **/
/** If an entry does exist, either replace it (if the new **/
/** admin distance is better), register the protocol in the **/
/** backup list (if the current admin distance is better), **/
/** or place this new route as an alternate for the route **/
/** entry (if being entered by protocol currently being **/
/** used in the route table. **/
FIN (Inet_Cmn_Rte_Table_Entry_Add_Options (route_table, src_obj_ptr, dest, mask,
next_hop, port_info, metric, proto, admin_distance, options));
/* Make sure the destination prefix is valid. */
if (OPC_COMPCODE_FAILURE == ip_cmn_rte_table_dest_prefix_verify (route_table, dest_prefix))
{
FRET (OPC_COMPCODE_FAILURE);
}
/* Check if addition for inderect nexthop option is set */
if (!ip_cmn_rte_table_entry_add_option_is_set (options, IPC_CMN_RTE_TABLE_ENTRY_ADD_INDIRECT_NEXTHOP_OPTION))
{
/* Perform the local connectivity check */
/* and make sure port_info is accurate */
ip_cmn_rte_table_port_info_verify (route_table, dest_prefix, next_hop,
&port_info, proto);
}
else
{
/* Skip local connectivity check and add even */
/* indirect nexthop addresses and output port info */
/* This is usually done by MANET routing protocol */
/* where two nodes in different subnet can store */
/* routes and talk directly as they work on /32 */
/* subnet masks. */
/* Verify table index sanity */
tbl_index = ip_rte_intf_tbl_index_from_port_info_get (route_table->iprmd_ptr, port_info);
if (tbl_index == IPC_INTF_INDEX_INVALID)
FRET (OPC_COMPCODE_FAILURE);
}
/* Find out whether we are dealing with an IPv4 or an IPv6 */
/* route. */
addr_family = ip_cmn_rte_table_dest_prefix_addr_family_get (dest_prefix);
/* Initialize the ptree_ptr and address variables based on */
/* the address family. */
ptree_ptr = route_table->ptree_ptr_array[addr_family];
address = ip_cmn_rte_table_dest_prefix_addr_ptr_get (dest_prefix);
/* Get a reference to the type of protocol which is sourcing*/
/* this route. */
proto_type = IP_CMN_RTE_TABLE_ROUTEPROC_PROTOCOL (proto);
/* IPv4 Default routes being inserted into the forwarding */
/* table need to be handled separately. */
if ((0 == ip_cmn_rte_table_dest_prefix_mask_len_get (dest_prefix)) &&
(InetC_Addr_Family_v4 == addr_family) &&
(ip_cmn_rte_table_is_vrf (route_table) == OPC_FALSE))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -