📄 ip_rte_support.ex.c
字号:
IpT_Dgram_Fields* pk_fd_ptr;
/* IP datagrams maintain an ICI to record information */
/* required for proper routing (e.g., slot on which the */
/* datagram arrived, output interface on which it */
/* should be forwarded, etc.) -- all that information */
/* is stored in a single structure field of the */
/* ip_rte_ind_v4 ICI. */
IpT_Rte_Ind_Ici_Fields *intf_ici_fdstruct_ptr;
Boolean packet_from_lower_layer;
double proxy_delay = 0.0;
Ici* rsvp_ici_ptr = OPC_NIL;
Ici* mcast_ici_ptr;
int mcast_major_port;
int mcast_minor_port;
IpT_Interface_Info* iface_info_ptr = OPC_NIL;
int slot_index = -1;
Ici* intf_ici_ptr = OPC_NIL;
int minor_port_in;
char trace_msg [128];
char intf_addr_str [INETC_ADDR_STR_LEN];
InetT_Address dest_addr;
InetT_Addr_Family addr_family;
InetT_Address next_addr = INETC_ADDRESS_INVALID;
Boolean broadcast = OPC_FALSE;
Boolean higher_layer = OPC_FALSE;
Boolean destroy_pkt = OPC_FALSE;
Boolean multicast_dest_addr;
char dest_addr_str [INETC_ADDR_STR_LEN];
int pkt_dest_type;
Boolean force_fwd;
IpT_Interface_Info* interface_ptr = OPC_NIL;
Compcode got_datagram_info;
double decomp_delay;
double comp_delay = 0.0;
OpT_Packet_Size packet_size;
Boolean car_packet_drop;
char str0 [512];
double vpn_delay = 0.0;
IpT_Address lb_addr;
Boolean packet_is_labeled;
Boolean packet_from_manet = OPC_FALSE;
char* fec_name = OPC_NIL;
int num_tracer_info = 0;
IpT_Tracer_Info * tracer_info_array = OPC_NIL;
int input_intf_tbl_index = IPC_INTF_INDEX_INVALID;
int output_table_index = IPC_INTF_INDEX_INVALID;
char* vrf_name = OPC_NIL;
char* lsp_name_str = OPC_NIL;
char* drop_reason_str = OPC_NIL;
InetT_Address rte_map_next_addr = INETC_ADDRESS_INVALID;
int rte_map_output_table_index = IPC_INTF_INDEX_INVALID;
IpT_Rte_Table_Lookup route_table_lookup = IpC_Rte_Table_Lookup;
IpT_Rte_Proc_Id src_proto = 0;
char* policy_name;
Packet * bgutil_pkptr;
IpT_Port_Info output_port_info;
char msg0 [512];
Compcode status;
Boolean permitted;
Boolean filter_present = OPC_FALSE;
const char* input_intf_name;
Compcode src_nat_status = OPC_COMPCODE_FAILURE;
Compcode dest_nat_status = OPC_COMPCODE_FAILURE;
const char* protocol_name;
Boolean src_xlate_match = OPC_FALSE;
Boolean dest_xlate_match = OPC_FALSE;
int vmac_addr = -1;
Boolean tunnel_pkt_at_src;
IpT_Cmn_Rte_Table_Entry* route_entry_ptr = OPC_NIL;
int member_intf_index;
IpT_Group_Intf_Info* intf_group_info_ptr;
/** Perform the appropriate preprocessing on arriving packets **/
/** to either discard the unwanted packet or gather necessary **/
/** information for further routing. **/
/** The packet is expected to be in the ip_dgram_v4 format **/
FIN (ip_rte_packet_arrival (pkpptr, instrm, intf_ici_fdstruct_pptr,
iface_info_pptr));
/* Make sure that the packet format is valid. */
switch (ip_rte_packet_format_valid (iprmd_ptr, *pkpptr))
{
case IpC_Packet_Format_Lacp_Pdu:
/* Pass the packet to the approprite process. */
ip_rte_lacp_pdu_handle (iprmd_ptr, *pkpptr);
/* Return false to indicate that no further processing */
/* is necessary. */
FRET (OPC_FALSE);
case IpC_Packet_Format_Ip_Dgram:
/* Continue processing. */
break;
case IpC_Packet_Format_Invalid:
/* Invalid packet format. The packet would have been */
/* already destroyed. */
FRET (OPC_FALSE);
}
/* Check if this is a bgutil packet. */
if (op_pk_encap_flag_is_set (*pkpptr, OMSC_BGUTIL_ENCAP_FLAG_INDEX))
{
/* Get a copy of the bgutil packet. */
op_pk_encap_pk_get (*pkpptr, "bgutil_tracer", &bgutil_pkptr);
/* Update the segmentation information in the tracer packet. */
oms_bgutil_segmentation_info_update (bgutil_pkptr, OPC_NIL, OmsC_Tracer_IP,
OMSC_BGUTIL_OVERHEAD_IP, OMSC_BGUTIL_DO_NOT_SEGMENT, 0.0,
oms_bgutil_tracer_segment_func, OPC_FALSE, OPC_NIL);
/* Destroy the copy packet. */
op_pk_destroy (bgutil_pkptr);
}
/* Initialize return information */
*intf_ici_fdstruct_pptr = OPC_NIL;
/* Get a handle to the data structure stored in "fields" */
/* field. This structure contains all the protocol header */
/* information as well as some internal information */
/* attached to each IP datagram for simulation efficiency. */
op_pk_nfd_access (*pkpptr, "fields", &pk_fd_ptr);
/* Find out whether this is an IPv4 packet of an IPv6 packet*/
addr_family = inet_address_family_get (&(pk_fd_ptr->dest_addr));
/* If this is a packet being tunneled from this node, then we */
/* need to bypass policy routing etc. since this packet has */
/* been delivered by this node back to this node, but on the */
/* stream on which the original packet had arrived previously. */
/* Also, if this is a v4 packet that contains a v6 packet, we */
/* must accept this packet even if the interface is not */
/* configured to handle v4 traffic. We must do this because the */
/* packet has been internally delivered to this interface by */
/* the tunneling code and has not actually come from the */
/* network. In order to help in these decisions, we need to */
/* know if this is a tunnel packet at the source. */
tunnel_pkt_at_src = pk_fd_ptr->tunnel_pkt_at_src;
/* Since the packet is going out of the source node, this field */
/* must be reset. */
pk_fd_ptr->tunnel_pkt_at_src = OPC_FALSE;
/* First find out whether or not the packet came from the */
/* lower layer. */
if ((iprmd_ptr->instrm_from_ip_encap == instrm) ||
(IpC_Pk_Instrm_Child == instrm))
{
/* The packet did not come from the lower layer */
packet_from_lower_layer = OPC_FALSE;
/* Check here if the packet is not control packet, */
/* Add the source node stat handler to IP header field */
if (ip_rte_pkt_is_routing_pkt_ext (pk_fd_ptr) == OPC_FALSE)
{
/* Store source stat handle */
pk_fd_ptr->src_num_hops_stat_hndl_ptr = &iprmd_ptr->locl_num_hops_src_hndl;
}
}
else
{
/* Packet is from the lower layer. */
packet_from_lower_layer = OPC_TRUE;
/* This packet came from a lower layer (e.g., ARP.) */
/* Check to see which interface it arrived on, so we */
/* can potentially forward this information to the */
/* higher layer (if the packet is eventually bound for */
/* the higher layer). */
if (ip_rte_pk_rcvd_intf_tbl_indx_get (iprmd_ptr, instrm, pk_fd_ptr, tunnel_pkt_at_src,
&minor_port_in, &input_intf_tbl_index) == OPC_COMPCODE_FAILURE)
{
ip_rte_dgram_discard (iprmd_ptr, *pkpptr, intf_ici_ptr, "Minor port could not be determined");
FRET (OPC_FALSE);
}
/* Get a pointer to the interface information of the */
/* corresponding interface. */
iface_info_ptr = inet_rte_intf_tbl_access (iprmd_ptr, input_intf_tbl_index);
*rcvd_iface_info_pptr = iface_info_ptr;
/* If this packet has come in on a serial interface, adjust */
/* the packet size to model stripping of the PPP header. */
/* Do this before the code branches off in IS-IS packets, */
/* labeled MPLS packets etc. */
ip_rte_link_header_size_adjust (*pkpptr, iface_info_ptr, IpC_Header_Remove);
}
/* Check if this packet came from ISIS */
if (pk_fd_ptr->protocol == IpC_Protocol_Isis)
{
/** If it is an ISIS PDU, don't do any IP processing **/
/** at all -- send the PDU out/up immediately. **/
/** The IP protocol is used only as a delivery **/
/** mechanism from the neighbor. **/
if (packet_from_lower_layer == OPC_FALSE)
{
ip_rte_isis_pdu_send (iprmd_ptr, *pkpptr);
}
else
{
ip_rte_isis_pdu_recv (iprmd_ptr, *pkpptr, iface_info_ptr, instrm, input_intf_tbl_index, minor_port_in);
}
/* Return an OPC_FALSE so that it fools the parent */
/* function into thinking that this pk was dropped */
/* and that no further processing is necessary. */
FRET (OPC_FALSE);
}
/* Mobile IPv6 processing. The following processing just applies */
/* for IPv6 packets if MIPv6 is enabled in the current node. Also */
/* multicast and local link addresses are not currently supported */
/* by MIPv6. */
if (ip_rte_node_is_mipv6_enabled (iprmd_ptr) &&
inet_address_family_get (&(pk_fd_ptr->dest_addr)) == InetC_Addr_Family_v6 &&
!inet_address_is_multicast (pk_fd_ptr->dest_addr) &&
!inet_rte_ipv6_addr_is_link_local (pk_fd_ptr->dest_addr))
{
mipv6_sup_mobile_ipv6_packet_process (iprmd_ptr, &pk_fd_ptr, pkpptr, packet_from_lower_layer);
}
/* obtain whether the label trace for "ip_rte" is enabled */
ip_rte_trace = LTRACE_IP_ACTIVE;
/* Initialize output_port_info. Details are populated while performing */
/* route table lookup for unicast destinations. */
output_port_info = ip_rte_port_info_create (IPC_INTF_INDEX_INVALID, OPC_NIL);
/* If this is a labeled packet none of the IP header fields */
/* would be visible. This will have an effect on the down */
/* the line processing of this packet */
packet_is_labeled = op_pk_nfd_is_set (*pkpptr, "MPLS Shim Header");
/* The cases GTP, L2TP and firewall cases must be handled only */
/* if this is an IP packet and not an MPLS packet. We also need */
/* not consider the following cases if this is a tunnel packet */
/* that has been created by this node and delivered to itself */
/* after encapsulation. These conditions will not hold good for */
/* the GRE/IP-IP tunnel packet. */
if ((!packet_is_labeled) && (!tunnel_pkt_at_src))
{
/* If the node containing this IP module is a firewall then */
/* we need to check whether the arriving packet will be */
/* accepted by the proxy servers. */
if ((iprmd_ptr->firewall_flag == OPC_TRUE) &&
(!oms_dv_firewall_accept (*pkpptr, iprmd_ptr->proxy_info_table_lptr, &proxy_delay)))
{
/* The datagram could not make through the firewall. */
/* Destroy the packet and update the statistics. Also */
/* record that into the simulation log. */
ip_rte_dgram_discard (iprmd_ptr, *pkpptr, OPC_NIL, "Rejected at Firewall");
ipnl_firewall_dgram_reject_log_write ();
/* Indicate that the packet insertion failed. */
FRET (OPC_FALSE);
}
/* Check if this is an UMTS GGSN node. */
if (ip_gtp_is_enabled (iprmd_ptr))
{
/* See if the destination belongs to the UMTS network. */
/* Home Locator Register contains all UEs registered in */
/* the UMTS network. */
if (umts_gtp_support_hlr_entry_find (inet_ipv4_address_get (pk_fd_ptr->dest_addr)) == OPC_TRUE)
{
/* The destnation address belong to a UMTS node, */
/* deliver the datagram to the GTP module to be */
/* transported into GTP tunnels through the UMTS */
/* core network. */
umts_gtp_support_gtp_pdu_send (*pkpptr, iprmd_ptr->gtp_info_ptr->gtp_objid);
/* Return an OPC_FALSE so that it fools the parent */
/* function into thinking that this pk was dropped */
/* and that no further processing is necessary. */
FRET (OPC_FALSE);
}
}
/* Check IP VPN tunneling is enabled, there might be delay */
/* associated with encryption and decryption process. */
if (ip_l2tp_vpn_is_enabled (iprmd_ptr) &&
(OPC_TRUE == packet_from_lower_layer))
{
/* Get delay associated to VPN tunnel */
ip_rte_ip_vpn_tunnel_packet (iprmd_ptr, pkpptr, &vpn_delay);
/* The pkpptr might be replaced by a new IP packet if */
/* compulsory tunnel is used, refresh the pk_fd_ptr */
op_pk_nfd_access (*pkpptr, "fields", &pk_fd_ptr);
}
}
/* Create an ICI and associate it with the datagram. */
/* The ICI will carry information about the datagram */
/* that will be used later when processing the packet */
/* after queueing and forwarding to the output */
/* interface. */
intf_ici_ptr = op_ici_create ("ip_rte_ind_v4");
/* Create ip_rte_ind ICI fields data structure that */
/* contains routing information which is used during */
/* the life-cycle of the ICI in this process. */
intf_ici_fdstruct_ptr = ip_rte_ind_ici_fdstruct_create ();
*intf_ici_fdstruct_pptr = intf_ici_fdstruct_ptr;
intf_ici_fdstruct_ptr->instrm = instrm;
/* Set the rte_info_fields in the ICI. */
ip_rte_ind_ici_fields_set (intf_ici_ptr, intf_ici_fdstruct_ptr);
/* Set the ICI in the packet. */
op_pk_ici_set (*pkpptr, intf_ici_ptr);
/* We have now created the ICI structure and associated */
/* it with the packet. If it is a labeled packet, we */
/* can now exit out of this function, since further */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -