- }
-
- pkts_processed += next0 == nat_buffer_opaque (b0)->arc_next;
-
- vnet_buffer (b1)->snat.flags = 0;
- ip1 = vlib_buffer_get_current (b1);
-
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
- rx_fib_index1 =
- fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
- sw_if_index1);
-
- if (PREDICT_FALSE (ip1->ttl == 1))
- {
- vnet_buffer (b1)->sw_if_index[VLIB_TX] = (u32) ~ 0;
- icmp4_error_set_vnet_buffer (b1, ICMP4_time_exceeded,
- ICMP4_time_exceeded_ttl_exceeded_in_transit,
- 0);
- next1 = NAT_NEXT_ICMP_ERROR;
- goto trace01;
- }
-
- udp1 = ip4_next_header (ip1);
- tcp1 = (tcp_header_t *) udp1;
- icmp1 = (icmp46_header_t *) udp1;
- proto1 = ip_proto_to_snat_proto (ip1->protocol);
-
- if (is_slow_path)
- {
- if (PREDICT_FALSE (proto1 == ~0))
- {
- s1 =
- nat44_ed_out2in_unknown_proto (sm, b1, ip1, rx_fib_index1,
- thread_index, now, vm,
- node);
- other_packets++;
- if (!sm->forwarding_enabled)
- {
- if (!s1)
- next1 = NAT_NEXT_DROP;
- goto trace01;
- }
- }
-
- if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
- {
- next1 = icmp_out2in_ed_slow_path
- (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
- next1, now, thread_index, &s1);
- icmp_packets++;
- goto trace01;
- }
- }
- else
- {
- if (PREDICT_FALSE (proto1 == ~0))
- {
- next1 = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
- goto trace01;
- }
-
- if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
- {
- next1 = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
- goto trace01;
- }
- }
-
- make_ed_kv (&kv1, &ip1->dst_address, &ip1->src_address,
- ip1->protocol, rx_fib_index1,
- vnet_buffer (b1)->ip.reass.l4_dst_port,
- vnet_buffer (b1)->ip.reass.l4_src_port);
-
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv1, &value1))
- {
- if (is_slow_path)
- {
- /* Try to match static mapping by external address and port,
- destination address and port in packet */
- e_key1.addr = ip1->dst_address;
- e_key1.port = vnet_buffer (b1)->ip.reass.l4_dst_port;
- e_key1.protocol = proto1;
- e_key1.fib_index = rx_fib_index1;
- if (snat_static_mapping_match (sm, e_key1, &l_key1, 1, 0,
- &twice_nat1, &lb_nat1,
- &ip1->src_address,
- &identity_nat1))
- {
- /*
- * Send DHCP packets to the ipv4 stack, or we won't
- * be able to use dhcp client on the outside interface
- */
- if (PREDICT_FALSE
- (proto1 == SNAT_PROTOCOL_UDP
- && (vnet_buffer (b1)->ip.reass.l4_dst_port ==
- clib_host_to_net_u16
- (UDP_DST_PORT_dhcp_to_client))))
- {
- goto trace01;
- }
-
- if (!sm->forwarding_enabled)
- {
- b1->error =
- node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
- next1 = NAT_NEXT_DROP;
- }
- else
- {
- if (next_src_nat
- (sm, ip1, ip1->protocol,
- vnet_buffer (b1)->ip.reass.l4_src_port,
- vnet_buffer (b1)->ip.reass.l4_dst_port,
- thread_index, rx_fib_index1))
- {
- next1 = NAT_NEXT_IN2OUT_ED_FAST_PATH;
- goto trace01;
- }
- if (sm->num_workers > 1)
- create_bypass_for_fwd_worker (sm, b1, ip1,
- rx_fib_index1);
- else
- create_bypass_for_fwd (sm, b1, ip1, rx_fib_index1,
- thread_index);
- }
- goto trace01;
- }
-
- if (PREDICT_FALSE (identity_nat1))
- goto trace01;
-
- if ((proto1 == SNAT_PROTOCOL_TCP)
- && !tcp_flags_is_init (vnet_buffer (b1)->ip.
- reass.icmp_type_or_tcp_flags))
- {
- b1->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
- next1 = NAT_NEXT_DROP;
- goto trace01;
- }
-
- /* Create session initiated by host from external network */
- s1 = create_session_for_static_mapping_ed (sm, b1, l_key1,
- e_key1, node,
- thread_index,
- twice_nat1,
- lb_nat1, now);
-
- if (!s1)
- {
- next1 = NAT_NEXT_DROP;
- goto trace01;
- }
- }