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

📄 ip_rte_support.ex.c

📁 备
💻 C
📖 第 1 页 / 共 5 页
字号:
							iface_info_ptr->filter_info_ptr->pre_filter_in->acl_list_id, iface_info_ptr->full_name);

					/* Packet does not pass the packet filter, drop		*/
					/* the packet										*/
					ip_rte_dgram_discard (iprmd_ptr, *pkpptr, intf_ici_ptr, "Dropped by Packet Filter");
						
					/* Return FALSE indicating packet was dropped 		*/
					FRET (OPC_FALSE);
					}
				}
			
			/* If this node is a PIX firewall, then the verify reverse path option may be set.	*/
			/* In that case, the packet must be processed only if a path to the source of the	*/
			/* packet is available. 															*/
			if (IP_PIX_IS_ENABLED (iprmd_ptr))
				{
				status = ip_pix_verify_reverse_path ( *pkpptr, input_intf_tbl_index, iprmd_ptr);
				if (status == OPC_COMPCODE_FAILURE)
					{
					ip_rte_dgram_discard (iprmd_ptr, *pkpptr, intf_ici_ptr, "Dropped by PIX (reverse path verify failure)");
				
					if (ip_rte_trace)
						op_prg_odb_print_major ("Packet is being dropped by PIX ", "Reverse path verify failure", OPC_NIL);
				
					FRET (OPC_FALSE);
					}
				}
		
			/* NAT: Check here if this packet needs to undergo network address translation.	*/
			if (IP_NAT_IS_ENABLED (iprmd_ptr) && IP_FIREWALL_SUPPORTS_PROTOCOL (pk_fd_ptr->protocol))
				{
				/* If network address translation is configured on this node and if this	*/
				/* packet is a candidate for NAT, then any NAT that may apply to the		*/
				/* destination field must be done prior to routing the packet.				*/
				dest_nat_status = ip_nat_xlate_pkt (*pkpptr, IpC_Nat_Hdr_Fd_Dest, input_intf_tbl_index, IPC_INTF_INDEX_INVALID, iprmd_ptr, 
					msg0, filter_present, pk_fd_ptr->frag, &dest_xlate_match);
			
				if (dest_nat_status == OPC_COMPCODE_SUCCESS)
					{
					/* Dest addr may have changed. Update the local variables.	*/
					dest_addr = pk_fd_ptr->dest_addr;
					multicast_dest_addr = inet_address_is_multicast (dest_addr);
					addr_family = inet_address_family_get (&dest_addr);
					}				
				}

			/* Check whether there is any QoS info (such as CAR or marking) 	*/
			/* specified on this interface in the Incoming direction.        	*/
			if (iprmd_ptr->interface_qos_data_pptr [input_intf_tbl_index] != OPC_NIL) 
				{
				IpT_Rte_Iface_QoS_Data * iface_qos_data_ptr; 
			
				/* Cache the qos interface data. */
				iface_qos_data_ptr = iprmd_ptr->interface_qos_data_pptr [input_intf_tbl_index];		
			
				/* IF CAR (Committed Access Rate) is enabled on this interface*/
				/* check whether this packet conforms the traffic contract.	  */
				/* If it doesn't, this packet might be dropped or set to a low*/
				/* type of service (TOS).									  */
			
				/* In case of uni-directional tunnels, a tunnel interface may	*/
				/* not be found in the outgoing direction. In that case, the	*/
				/* received interface table index will correspond to a loopback	*/
				/* interface, which does not have a CAR profile. Hence, we must	*/
				/* check for the presence of a CAR profile on the interface.	*/
			
				if (iface_qos_data_ptr->car_incoming_profile_ptr != OPC_NIL) 
					{
					/* Returns whether the packet has to dropped to follow the*/
					/* policy. If the packet doesn't comply the policy, it is */
					/* necessarily dropped but only set to a lower precedence.*/
					car_packet_drop = Ip_Qos_Car_Policy_Limit (*pkpptr, input_intf_tbl_index,
						iface_qos_data_ptr->car_incoming_profile_ptr, 
						iface_qos_data_ptr->car_incoming_info_ptr);

					/* If the packet did not match a CAR policy specifiyng that	*/	
					/* all non-conforming traffic has to be dropped, the packet	*/
					/* is dropped.												*/
					if (car_packet_drop)
						{
						/* Write a statistic for packet dropped on this interface.	*/
						op_stat_write (iface_qos_data_ptr->car_stat_info_ptr->in_traffic_dropped_in_bps_stathandle, 
							op_pk_total_size_get (*pkpptr));
						op_stat_write (iface_qos_data_ptr->car_stat_info_ptr->in_traffic_dropped_in_bps_stathandle, 0);
						op_stat_write (iface_qos_data_ptr->car_stat_info_ptr->in_traffic_dropped_in_pps_stathandle, 1);
						op_stat_write (iface_qos_data_ptr->car_stat_info_ptr->in_traffic_dropped_in_pps_stathandle, 0);

						if (op_prg_odb_ltrace_active ("car"))
							{
							sprintf (str0, "CAR drops packet " SIMC_PK_ID_FMT " to conform rate policies.", op_pk_id (*pkpptr));
							op_prg_odb_print_major (str0, OPC_NIL);
							}

						/* Drop the current IP datagram.	*/
						ip_rte_dgram_discard (iprmd_ptr, *pkpptr, intf_ici_ptr, "Rejected on CAR policy violation");

						/* Warns that the packet has not been accepted.	*/
						FRET (OPC_FALSE);
						}
					}
				
				/* Check whether any QoS Marking is configured on this interface. */
				/* Apply the marking profile to the incoming packet.              */
				if (iface_qos_data_ptr->marking_incoming_info_ptr != OPC_NIL)
					{
					Ip_Qos_Pk_Marking_Apply (*pkpptr, input_intf_tbl_index, 
						iface_qos_data_ptr->marking_incoming_info_ptr);
					}	
				}
			}

		/* When the stream is found also get the slot	*/
		/* index of the interface.						*/
		slot_index = (OmsC_Dv_Slot_Based == iprmd_ptr->processing_scheme) ?
			ip_rte_input_slot_index_determine (iprmd_ptr, iface_info_ptr, instrm): CENTRAL_CPU;
            	
		/* Store the information about the interface	*/
		/* into the ICI.								*/
		intf_ici_fdstruct_ptr->interface_received = inet_rte_intf_addr_get (iface_info_ptr, addr_family);
		intf_ici_fdstruct_ptr->major_port_received = ip_rte_intf_ip_addr_index_get (iface_info_ptr);
		intf_ici_fdstruct_ptr->intf_recvd_index = input_intf_tbl_index;
		intf_ici_fdstruct_ptr->slot_index = slot_index;

		/* Set additional information about the interface on which this	*/
		/* IP datagram arrived. This information may be used by the		*/
		/* higher layers (e.g., routing protocols like IGRP)			*/
		intf_ici_fdstruct_ptr->mtu 					= inet_rte_intf_mtu_get (iface_info_ptr, addr_family);
		intf_ici_fdstruct_ptr->iface_load 			= ip_rte_intf_load_bps_get (iface_info_ptr);
		intf_ici_fdstruct_ptr->iface_reliability 	= ip_rte_intf_reliability_get (iface_info_ptr);
		intf_ici_fdstruct_ptr->iface_speed 		    = ip_rte_intf_link_bandwidth_get (iface_info_ptr);

		/* Set the minor port information.				*/
		intf_ici_fdstruct_ptr->minor_port_received	= minor_port_in;

		/* Set the packet insertion time.  This will be	*/
		/* later used to compute packet latency.		*/
		intf_ici_fdstruct_ptr->pkt_insertion_time = op_sim_time ();

		/* Set the processed field of ICI to false to	*/
		/* indicate that the packet is freshly received	*/
		/* and not processed yet.						*/
		intf_ici_fdstruct_ptr->processed = OPC_FALSE;

		/*	Issue trace statement.						*/
		if ((ip_rte_trace == OPC_TRUE) && op_prg_odb_pktrace_active (*pkpptr))
			{
			ip_address_print (intf_addr_str, iface_info_ptr->addr_range_ptr->address);
			if (iprmd_ptr->processing_scheme == OmsC_Dv_Slot_Based)
				{
				sprintf (trace_msg, "Packet ID (" SIMC_PK_ID_FMT ") [Tree ID " SIMC_PK_ID_FMT "] arrived on interface %s slot %d",
					op_pk_id (*pkpptr), op_pk_tree_id (*pkpptr), intf_addr_str, slot_index);
				}
			else
				{
				sprintf (trace_msg, "Packet ID (" SIMC_PK_ID_FMT ") [Tree ID " SIMC_PK_ID_FMT "] arrived on interface %s",
					op_pk_id (*pkpptr), op_pk_tree_id (*pkpptr), intf_addr_str);
				}

			/* Print the trace message.					*/
			op_prg_odb_print_minor (trace_msg, OPC_NIL);
			}
		}
	
	/* Store the input interface name in the packet ICI.		*/
	intf_ici_fdstruct_ptr->input_intf_name = input_intf_name;

	/*	If the received packet does not yet have a time-to-live	*/
	/*	field assignment, place the default value in this field	*/
	/*	In this model, TTL is treated as a hop allowance		*/
	/*	decremented by one prior to each transmission. If the	*/
	/*	decremented counter reaches zero, the packet is not		*/
	/*	transmitted.											*/
	if (pk_fd_ptr->ttl == IPC_TTL_UNSET)
		{
		pk_fd_ptr->ttl = IPC_DEFAULT_TTL;
		}

	/* Determine the interface to which the packet should be	*/
	/* forwarded. Store this information within the ICI since	*/
	/* it will be also used in the svc_comp state.				*/
	
   	/* Check if MPLS is enabled on this node or Check if		*/
	/* this node is a PE for any VPN.							*/
	if (ip_mpls_is_enabled (iprmd_ptr) || ip_node_is_pe (iprmd_ptr))
		{
		/* We know that this is not a labeled packet since that	*/
		/* condition has been handled already.					*/

		/* First check if this packet matches any of the FEC 	*/
		/* configured on this router interface					*/
		fec_name = ip_mpls_packet_classify (iprmd_ptr, *pkpptr, 
			intf_ici_fdstruct_ptr->intf_recvd_index, !packet_from_lower_layer);

		/* Duplicate the memory so the mpls_fec_name can be */
		/* freed independently of the source string.        */
		intf_ici_fdstruct_ptr->mpls_fec_name = prg_string_copy (fec_name);

		/* Check if the packet is from a VPN and do it only	*/
		/* if the destination address is not this node's	*/
		/* local address									*/
		if (ip_node_is_pe (iprmd_ptr) &&
			(inet_rte_is_local_address (pk_fd_ptr->dest_addr, iprmd_ptr, OPC_NIL) == OPC_FALSE))
			{
			/* Packet may be coming from a VPN site and 	*/
			/* may be entering the MPLS core.				*/
			/* Find the VRF tabel that it belongs to		*/
			vrf_name = ip_vrf_table_name_get (ip_vrf_table_for_intf_index_get (iprmd_ptr,
													intf_ici_fdstruct_ptr->intf_recvd_index));

			intf_ici_fdstruct_ptr->pe_vrf_name = vrf_name;
			}
		/* This packet will be passed to MPLS only if it matches a FEC or if	*/
		/* if it is a data packet coming from a VRF. Control traffic coming		*/
		/* from a VRF (VPN) must be handed to higher layers. BGP packets are 	*/
		/* handled correctly due to the previous check (is_local_address).		*/	
		if ((fec_name != OPC_NIL) || 
			((vrf_name != OPC_NIL) && !ip_rte_pkt_is_routing_pkt (pk_fd_ptr)))
			{
			/* We are dealing with a packet that is mpls bound	*/
			/* Currently, only MPLS VPNs are supported. Hence	*/
			/* we check for a misconfiguration case where VRFs	*/
			/* are configured but MPLS is not enabled.			*/
			if (ip_mpls_is_enabled (iprmd_ptr))
				intf_ici_fdstruct_ptr->mpls_redirect = OPC_TRUE;
			else
				intf_ici_fdstruct_ptr->destroy_pkt = OPC_TRUE;

#ifndef OPD_NO_DEBUG
			if (op_prg_odb_ltrace_active ("mpls_ip") || op_prg_odb_ltrace_active ("mpls"))
				{
				op_prg_odb_print_major ("<ip_rte_packet_arrival>", OPC_NIL);
				if (fec_name != OPC_NIL)
					op_prg_odb_print_minor ("FEC Name", fec_name, OPC_NIL);
				if (vrf_name != OPC_NIL)
					op_prg_odb_print_minor ("VRF Name", vrf_name, OPC_NIL);

				if (intf_ici_fdstruct_ptr->destroy_pkt)
					op_prg_odb_print_major ("Destroying the packet since MPLS is not enabled",
						"Only MPLS based BGP VPNS are supported in Discrete Event Simulation", OPC_NIL);
				}
#endif
			FRET (OPC_TRUE);
			}
		}

	/* Check if any Policy Routing is to be applied on the packets				*/
	/* If a firewall filter was specified as an input filter and it has already	*/
	/* performed the routing, skip this step. Also, if this packet is a tunnel	*/
	/* packet at the tunnel source, policy routing has already been applied on	*/
	/* the inner packet and hence the outer packet must not be subjected to		*/
	/* policy routing again.													*/
	if (((iprmd_ptr->rte_map_table != OPC_NIL) || (iprmd_ptr->firewall_filter_table != OPC_NIL)) &&
		(IpC_Rte_Table_Lookup == route_table_lookup) &&
		(OPC_FALSE == tunnel_pkt_at_src))
		{
		/* If the packet is from lower layer then get the policy name from		*/
		/* the interface else get the local policy name							*/ 
		policy_name = (packet_from_lower_layer) ? iface_info_ptr->policy_routing_name : iprmd_ptr->local_policy_name; 
		
		/* Apply the Route map configured in Policy Routing						*/
		if (policy_name != OPC_NIL)
			{
			/* Apply the route map policy to the packet							*/	
			Ip_Rte_Map_Packet_Apply (iprmd_ptr, policy_name, *pkpptr,
				ip_rte_support_packet_match, ip_rte_support_packet_alter,
				&rte_map_next_addr, &rte_map_output_table_index, &route_table_lookup, 
				input_intf_name);
			}
		}
		
	if (route_table_lookup != IpC_Bypass_Rte_Table_Lookup)
		{
		/*	Determine the interface the datagram should be forwarded to.	*/
		/*	Also determine whether the datagram should be broadcast, and/or	*/
		/*	the datagram should be forwarded to the higher layer.			*/
		if (multicast_dest_addr)
			{
			got_datagram_info = ip_rte_mcast_datagram_dest_get (iprmd_ptr, *pkpptr, 
				rsvp_ici_ptr, intf_ici_fdstruct_ptr, dest_addr, &next_addr,
				&higher_layer, &destroy_pkt, pk_fd_ptr->protocol, &output_table_index, 
				&interface_ptr);	
		
			/* Set the pkt_dest_type to multicast						*/
			intf_ici_fdstruct_ptr->pkt_dest_type = IPC_PKT_TXTYPE_MCAST;
			
			/* Though there is no broadcast in mcast network, setting	*/
			/* broadcast flag true for a special case, when output tbl	*/
			/* index is set to IP_BROADCAST_ALL_INTERFACES				*/
			/* Set the broadcast flag to false.							*/
			broadcast = (output_table_index == IP_BROADCAST_ALL_INTERFACES) ? OPC_TRUE: OPC_FALSE;
			
			/* Create temporary port_info */
			output_port_info = ip_rte_port_info_create (output_table_index, OPC_NIL);
			}
		else
			{
			got_datagram_info = ip_rte_datagram_dest_get (iprmd_ptr, *pkpptr, 
				rsvp_ici_ptr, force_fwd, dest_addr, input_intf_tbl_index, packet_from_lower_layer, 
				pk_fd_ptr, intf_ici_fdstruct_ptr, &next_addr, &lsp_name_str, &broadcast, 
				&higher_layer, &destroy_pkt, &output_port_info, &interface_ptr, 
				&num_tracer_info, &tracer_info_array, &drop_reason_str, &src_proto, &route_entry_ptr);
					
			/* Cache the output interface index	*/
			output_table_index = output_port_info.intf_tbl_index;
		
			/* set the pkt_dest_type accordingly						*/
			if (broadcast)
				intf_ici_fdstruct_ptr->pkt_dest_type = IPC_PKT_TXTYPE_BCAST;
			else
				intf_ici_fdstruct_ptr->pkt_dest_type = IPC_PKT_TXTYPE_UCAST;
			}
		}
	
	/* If Rte lookup was bypassed or if defaults were not allowed by	*/
	/* rte map and defau

⌨️ 快捷键说明

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