📄 ip_rte_support.ex.c
字号:
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 + -