⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_cmn_rte_table.ex.c

📁 备
💻 C
📖 第 1 页 / 共 5 页
字号:
	/**			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 + -