- ip_adjacency_t *adj0;
- vlib_buffer_t *p0;
- ip4_header_t *ip0;
- u32 pi0, rw_len0, adj_index0, next0, error0, checksum0;
- u32 tx_sw_if_index0;
-
- pi0 = to_next[0] = from[0];
-
- p0 = vlib_get_buffer (vm, pi0);
-
- adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
-
- adj0 = adj_get (adj_index0);
-
- ip0 = vlib_buffer_get_current (p0);
-
- error0 = IP4_ERROR_NONE;
- next0 = IP4_REWRITE_NEXT_DROP; /* drop on error */
-
- /* Decrement TTL & update checksum. */
- if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED)))
- {
- i32 ttl0 = ip0->ttl;
-
- checksum0 = ip0->checksum + clib_host_to_net_u16 (0x0100);
-
- checksum0 += checksum0 >= 0xffff;
-
- ip0->checksum = checksum0;
-
- ASSERT (ip0->ttl > 0);
-
- ttl0 -= 1;
-
- ip0->ttl = ttl0;
-
- ASSERT ((ip0->checksum == ip4_header_checksum (ip0)) ||
- (p0->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM));
-
- if (PREDICT_FALSE (ttl0 <= 0))
- {
- /*
- * If the ttl drops below 1 when forwarding, generate
- * an ICMP response.
- */
- error0 = IP4_ERROR_TIME_EXPIRED;
- next0 = IP4_REWRITE_NEXT_ICMP_ERROR;
- vnet_buffer (p0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
- icmp4_error_set_vnet_buffer (p0, ICMP4_time_exceeded,
- ICMP4_time_exceeded_ttl_exceeded_in_transit,
- 0);
- }
- }
- else
- {
- p0->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED;
- }
-
- if (do_counters)
- vlib_prefetch_combined_counter (&adjacency_counters,
- thread_index, adj_index0);
-
- /* Guess we are only writing on simple Ethernet header. */
- vnet_rewrite_one_header (adj0[0], ip0, sizeof (ethernet_header_t));
-
- if (is_mcast)
- {
- /*
- * copy bytes from the IP address into the MAC rewrite
- */
- vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
- }
-
- /* Update packet buffer attributes/set output interface. */
- rw_len0 = adj0[0].rewrite_header.data_bytes;
- vnet_buffer (p0)->ip.save_rewrite_length = rw_len0;
-
- if (do_counters)
- vlib_increment_combined_counter
- (&adjacency_counters,
- thread_index, adj_index0, 1,
- vlib_buffer_length_in_chain (vm, p0) + rw_len0);
-
- /* Check MTU of outgoing interface. */
- ip4_mtu_check (p0, vlib_buffer_length_in_chain (vm, p0),
- adj0[0].rewrite_header.max_l3_packet_bytes,
- ip0->flags_and_fragment_offset &
- clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
- &next0, &error0);
-
- if (is_mcast)
- {
- error0 = ((adj0[0].rewrite_header.sw_if_index ==
- vnet_buffer (p0)->sw_if_index[VLIB_RX]) ?
- IP4_ERROR_SAME_INTERFACE : error0);
- }
- p0->error = error_node->errors[error0];
-
- /* Don't adjust the buffer for ttl issue; icmp-error node wants
- * to see the IP headerr */
- if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
- {
- p0->current_data -= rw_len0;
- p0->current_length += rw_len0;
- tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
-
- vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
- next0 = adj0[0].rewrite_header.next_index;
-
- if (is_midchain)
- {
- adj0->sub_type.midchain.fixup_func
- (vm, adj0, p0, adj0->sub_type.midchain.fixup_data);
- }