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

📄 ip_cmn_rte_table.ex.c

📁 备
💻 C
📖 第 1 页 / 共 5 页
字号:
		{
		ip_cmn_rte_default_route_add (route_table, src_obj_ptr,
			next_hop, port_info, metric, proto, admin_distance);

		/* Nothing more to be done.								*/
		FRET (OPC_COMPCODE_SUCCESS);
		}

	/* Check if a standard routing protocol is adding an entry.	*/
	if ((proto_type < IPC_INITIAL_CUSTOM_RTE_PROTOCOL_ID) && (proto_type != IPC_DYN_RTE_DEFAULT))
		{
		/** A standard routing protocol is adding an entry.		**/
		
		/* Because of support for route redistribution and		*/
		/* route maps/filters, there are several cases which	*/
		/* need to be handled.									*/
		/* 														*/
		/* 1: There is no route to the destination network in	*/
		/* the route table from any protocol.					*/
		/* 2: There is a route to the destination network in	*/
		/* the route table and it is provided from the same		*/
		/* protocol.											*/
		/* 3: There is a route to the destination network in	*/
		/* the route table and it is provided from a protocol	*/
		/* which has a better admin distance.					*/
		/* 3A: The protocol in the table is directly connected.	*/
		/* 4: There is a route to the destination network in	*/
		/* the route table and it is provided from a protocol	*/
		/* which has a worse admin distance.					*/
		/* 4A: The new route's protocol is directly connected.	*/
		/*														*/
		/* Directly connected routes need to be handled			*/
		/* differently because the routing protocols which		*/
		/* provide routes to their networks need to be 			*/
		/* redistributed, even though the route table entry is	*/
		/* a directly connected route.							*/
		
		/* Use the keep route option to make sure that we do	*/
		/* not blindly overwrite the existing entry.			*/
		new_ptree_entry = oms_ptree_entry_add (ptree_ptr, address,
			ip_cmn_rte_table_dest_prefix_mask_len_get (dest_prefix),
			OPC_NIL, OMSC_PTREE_ADD_KEEP_ROUTE, &curr_ptree_entry);
		
		if (PRGC_NIL != curr_ptree_entry)
			{
			/** An entry was found to this destination.			**/

			/* Access the IpT_Cmn_Rte_Table_Entry structure		*/
			/* associated with this entry.						*/
			curr_entry = ip_cmn_rte_table_entry_from_ptree_entry_get (curr_ptree_entry);
			
			if ((curr_entry->admin_distance == admin_distance) && (curr_entry->route_src_proto == proto))
				{
				/** Entry being added is from the same protocol	**/
				/** that is currently being used by IP for this	**/
				/** destination.								**/
				/** This is case number 2						**/
				
				/* Insert the new entry as a new next hop for	*/
				/* this destination.							*/
				ip_cmn_rte_next_hop_add (curr_entry, next_hop, metric, &port_info);
				
				/* Set the last update time.					*/
				if (oms_routing_convergence_status_check (route_table->convg_handle) == OmsC_Convergence_Reached)
					{
					ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
					ip_cmn_rte_proto_name_print (src_proto_str, proto);
					
					if (!strcmp (src_proto_str, "Direct"))
						strcpy (src_proto_str, "Local");
					
					sprintf(convergence_reason, 
						"Added %s route to destination %s.", src_proto_str, dest_str);
					
					ip_cmn_rte_table_last_update_time_set (route_table, convergence_reason);
					}
				else
					{	
					ip_cmn_rte_table_last_update_time_set (route_table, OPC_NIL);
					}

				/* The type of redistribution is different	*/
				/* in the case of directly connected routes	*/
				/* so determine if this route is directly	*/
				/* connected and set the redist type		*/
				/* accordingly.								*/
				if (IP_CMN_RTE_TABLE_PROTOCOL_IS_DIRECT (curr_entry->route_src_proto))
					redist_type = IPC_REDIST_TYPE_UPDATE_DIRECT;
				else
					redist_type = IPC_REDIST_TYPE_UPDATE;
				
				/* The protocol which sources this route	*/
				/* has not changed, so the remove proto		*/
				/* should be set to INVALID.				*/
				removed_proto = IpC_Dyn_Rte_Invalid;
				
				/* Redistribute an update message to other	*/
				/* protocols advertising the new next hop	*/
				ip_cmn_rte_table_entry_redistribute (route_table, curr_entry, redist_type, removed_proto);

				/* Check if this entry is being used to resolve	*/
				/* a default network route.						*/
				if (ip_cmn_rte_table_entry_default_ntwk_flag_is_set (curr_entry))
					{
					/* It is possible that the new next hop		*/
					/* caused the metric to improve. Call the	*/
					/* function that will update the default	*/
					/* network route.							*/
					ip_cmn_rte_table_default_network_route_update (route_table, curr_entry);
					}
				FRET (OPC_COMPCODE_SUCCESS);
				}	
			else if (curr_entry->admin_distance > admin_distance)
				{
				/* Entry being added has a better (lower)		*/
				/* admin distance than the entry currently in	*/
				/* the route table. This is case number 3 and 3A*/
				if (curr_entry->admin_distance != OPC_INT_INFINITY)
					{
					/* The current entry isn't being replaced 	*/
					/* When Route_Delete is called and there	*/
					/* is a backup routing protocol, the		*/
					/* admin distance is set to infinity as a	*/
					/* means of poisoning this protocol.  IP	*/
					/* then calls the backup routing protocols	*/
					/* install proc which in turn calls 		*/
					/* Entry_Add.  This essentially removes		*/
					/* the no longer available protocols route	*/
					
					/* Place the current entry in the backup 	*/
					/* list.									*/
					/* TODO: should we free port info			*/
					/* in this case also?						*/	
					ip_cmn_rte_enter_backup (curr_entry, curr_entry->route_src_proto,
						curr_entry->admin_distance, curr_entry->route_src_obj_ptr);
					}
				
				/* The routing protocol which sources this route*/
				/* is changing.  Set the removed_proto to be	*/
				/* the original protocol.						*/
				/* This needs to be set before the route entry	*/
				/* is replaced in the route table.				*/
				if (((curr_entry->admin_distance == OPC_INT_INFINITY) && (proto_type == IPC_DYN_RTE_DIRECTLY_CONNECTED)) ||
					(proto_type != IPC_DYN_RTE_DIRECTLY_CONNECTED))
					{
					removed_proto = curr_entry->route_src_proto;
					}
				else
					removed_proto = IpC_Dyn_Rte_Invalid;
				
				/* Replace the current entry w/ the new entry.	*/
				ip_cmn_rte_entry_replace (route_table, src_obj_ptr, dest_prefix, 
					next_hop, port_info, metric, proto, admin_distance, curr_entry);
				
				/* Set the last update time.					*/
				if (oms_routing_convergence_status_check (route_table->convg_handle) == OmsC_Convergence_Reached)
					{
					ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
					ip_cmn_rte_proto_name_print (src_proto_str, proto);

					if (!strcmp (src_proto_str, "Direct"))
						strcpy (src_proto_str, "Local");			
					sprintf(convergence_reason, 
						"Added %s route to destination %s", src_proto_str, dest_str);
					
					ip_cmn_rte_table_last_update_time_set (route_table, convergence_reason);
					}
				else
					{	
					ip_cmn_rte_table_last_update_time_set (route_table, OPC_NIL);
					}

				/* The type of redistribution is different	*/
				/* in the case of directly connected routes	*/
				/* so determine if this route is directly	*/
				/* connected and set the redist type		*/
				/* accordingly.								*/
				if (IP_CMN_RTE_TABLE_PROTOCOL_IS_DIRECT (curr_entry->route_src_proto))
					redist_type = IPC_REDIST_TYPE_UPDATE_DIRECT;
				else
					redist_type = IPC_REDIST_TYPE_UPDATE;
				
				/* Redistribute an update message to other	*/
				/* protocols with the changed information	*/
				/* for this destination.					*/
				ip_cmn_rte_table_entry_redistribute (route_table, curr_entry, redist_type, removed_proto);

				/* The administrative distance of an entry has improved. If	*/
				/* this entry is used to resolve a default network route,	*/
				/* the administrative distance of the default network route	*/
				/* also has to be updated.									*/
				if (ip_cmn_rte_table_entry_default_ntwk_flag_is_set (curr_entry))
					{
					ip_cmn_rte_table_default_network_route_update (route_table, curr_entry);
					}
				}
			else
				{
				/** Existing entry has the better (lower) admin	**/
				/** distance.									**/
				/** This is case number 4 and 4A				**/
				
				/* Insert the new entry into the list of		*/
				/* backup routes.								*/
				ip_cmn_rte_enter_backup (curr_entry, proto, admin_distance, src_obj_ptr);

				/* Some additional work needs to be done if this is a	*/
				/* VRF table entry. If this backup entry is promoted to	*/
				/* be the primary entry, the routing protocol is		*/
				/* invoked (via install_proc) to add the route again.	*/
				/* A fresh port_info object with top and bottom labels	*/
				/* will be generated then. The current MPLS label in	*/
				/* the port info can be freed now.						*/
				if (ip_rte_port_info_contains_mpls_info (&port_info))
					ip_cmn_rte_table_port_info_free (&port_info, route_table);

				
				
				/* If the route is to a directly connected		*/
				/* destination, we still need to send			*/
				/* redistribution interrupts.					*/
				if (IP_CMN_RTE_TABLE_PROTOCOL_IS_DIRECT (curr_entry->route_src_proto))
					{
					/* if the route which is in the				*/
					/* table currently is a directly connected	*/
					/* route, then the protocol sourcing the	*/
					/* new route must redistribute this route	*/
					/* into other protocols.					*/
					
					/* In this case, there is only one type of	*/
					/* redistribution.  If the route does get	*/
					/* redistributed, it will be for a directly	*/
					/* connected route and an update.			*/
					redist_type = IPC_REDIST_TYPE_UPDATE_DIRECT;
					
					/* The protocol which sources this route	*/
					/* has not changed, so the remove proto		*/
					/* should be set to INVALID.				*/
					removed_proto = IpC_Dyn_Rte_Invalid;
					
					/* Redistribute an update message to other	*/
					/* protocols with the changed information	*/
					/* for this destination.					*/
					/* This route should only be redistributed	*/
					/* if it is a directly connected route. In	*/
					/* all other cases, the backup list does not*/
					/* affect redistribution.					*/
					ip_cmn_rte_table_entry_redistribute (route_table, curr_entry, redist_type, removed_proto);
					}
				}
			FRET (OPC_COMPCODE_SUCCESS);
			}
		}
	else
		{
		/** A custom routing protocol is adding an entry.		**/

		/* Use the keep route option to make sure that we do	*/
		/* not blindly overwrite the existing entry.			*/
		new_ptree_entry = oms_ptree_entry_add (ptree_ptr, address,
			ip_cmn_rte_table_dest_prefix_mask_len_get (dest_prefix),
			OPC_NIL, OMSC_PTREE_ADD_KEEP_ROUTE, &curr_ptree_entry);

		/* If the entry already exists, don't add it.			*/
		if (PRGC_NIL != curr_ptree_entry)
			{
			FRET (OPC_COMPCODE_FAILURE);
			}
		}

	/** There was no existing entry found in the route table to	**/
	/** this destination.  Create a new entry and add it to the	**/
	/** table.  Then redistribute it to other protocols as a	**/
	/** new route.												**/
	/** This is case number 1									**/

	/* Increment the number of entries in the route table.		*/
	++(route_table->num_entries);

	if (oms_routing_convergence_status_check (route_table->convg_handle) == OmsC_Convergence_Reached)
		{
		ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
		ip_cmn_rte_proto_name_print (src_proto_str, proto);

		if (!strcmp (src_proto_str, "Direct"))
			strcpy (src_proto_str, "Local");
			
		sprintf(convergence_reason, 
			"Added %s route to destination %s", src_proto_str, dest_str);
		ip_cmn_rte_table_last_update_time_set (route_table, convergence_reason);
		}
	else
		{	
		ip_cmn_rte_table_last_update_time_set (route_table, OPC_NIL);
		}

	/* Create a new IpT_Cmn_Rte_Table_Entry structure			*/
	route_entry = ip_cmn_rte_table_entry_create (dest_prefix, proto, admin_distance, src_obj_ptr);

	/* Make the first entry in the "next_hop" list for the new 	*/
	/* entry the new route.										*/
	ip_cmn_rte_next_hop_add (route_entry, next_hop, metric, &port_info);
	
	/* Set this structure as the src object in the new ptree*/
	/* structure.											*/
	oms_ptree_entry_src_obj_set (new_ptree_entry, route_entry);

	/* Update statistics for this route table.				*/
	op_stat_write (route_table->update_stathandle [IpC_Rte_Table_Entry_Add], 1.0);
	op_stat_write (route_table->update_stathandle [IpC_Rte_Table_Any_Update], 1.0);
	op_stat_write (route_table->update_stathandle [IpC_Rte_Table_Size], (double) route_table->num_entries);
	
	/* Print trace information.								*/
#ifndef OPD_NO_DEBUG
	if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
		{
		/* Re-use the destination and protocol */
		/* strings if created previously.      */
		ip_cmn_rte_table_dest_prefix_print (dest_str, dest_prefix);
		ip_cmn_rte_proto_name_print (src_proto_str, proto);
		inet_address_print (nh_str, next_hop);

		/* And now the full message.						*/
		sprintf (trace_msg,
			"Dest |%s|, Next Hop |%s|, O/P Intf. |%d|, Metric |%d| and Src. Proto. |%s|.",
			dest_str, nh_str, ip_rte_intf_tbl_index_from_port_info_get (route_table->iprmd_ptr, port_info), 
			metric, src_proto_str);

		op_prg_odb_print_major ("Adding the following route to the Common IP Routing Table:", OPC_NIL);
		op_prg_odb_print_minor (trace_msg, OPC_NIL);
		}
#endif

	/* In this case, there is only one type of			*/
	/* redistribution.  This is a new route, so the type*/
	/* will be an ADD.									*/
	redist_type = IPC_REDIST_TYPE_ADD;
			
	/* Since there was no route in the table previously	*/
	/* there is no route which can be withdrawn.		*/
	removed_proto = IpC_Dyn_Rte_Invalid;
	
	/* Redistribute this route as a new route to other	*/
	/* routing protocols running on this node.			*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -