diff options
Diffstat (limited to 'src/vnet/ip/ip4_forward.c')
-rw-r--r-- | src/vnet/ip/ip4_forward.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index b3ae29a2790..ec4eda4e96a 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -2186,10 +2186,11 @@ ip4_ttl_and_checksum_check (vlib_buffer_t * b, ip4_header_t * ip, u16 * next, always_inline uword -ip4_rewrite_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - int do_counters, int is_midchain, int is_mcast) +ip4_rewrite_inline_with_gso (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame, + int do_counters, int is_midchain, int is_mcast, + int do_gso) { ip_lookup_main_t *lm = &ip4_main.lookup_main; u32 *from = vlib_frame_vector_args (frame); @@ -2267,12 +2268,20 @@ ip4_rewrite_inline (vlib_main_t * vm, CLIB_PREFETCH (p, CLIB_CACHE_LINE_BYTES, LOAD); /* Check MTU of outgoing interface. */ - ip4_mtu_check (b[0], clib_net_to_host_u16 (ip0->length), + u16 ip0_len = clib_net_to_host_u16 (ip0->length); + u16 ip1_len = clib_net_to_host_u16 (ip1->length); + + if (do_gso && (b[0]->flags & VNET_BUFFER_F_GSO)) + ip0_len = gso_mtu_sz (b[0]); + if (do_gso && (b[1]->flags & VNET_BUFFER_F_GSO)) + ip1_len = gso_mtu_sz (b[1]); + + ip4_mtu_check (b[0], ip0_len, adj0[0].rewrite_header.max_l3_packet_bytes, ip0->flags_and_fragment_offset & clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT), next + 0, &error0); - ip4_mtu_check (b[1], clib_net_to_host_u16 (ip1->length), + ip4_mtu_check (b[1], ip1_len, adj1[0].rewrite_header.max_l3_packet_bytes, ip1->flags_and_fragment_offset & clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT), @@ -2395,7 +2404,11 @@ ip4_rewrite_inline (vlib_main_t * vm, vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0; /* Check MTU of outgoing interface. */ - ip4_mtu_check (b[0], clib_net_to_host_u16 (ip0->length), + u16 ip0_len = clib_net_to_host_u16 (ip0->length); + if (do_gso && (b[0]->flags & VNET_BUFFER_F_GSO)) + ip0_len = gso_mtu_sz (b[0]); + + ip4_mtu_check (b[0], ip0_len, adj0[0].rewrite_header.max_l3_packet_bytes, ip0->flags_and_fragment_offset & clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT), @@ -2465,6 +2478,23 @@ ip4_rewrite_inline (vlib_main_t * vm, return frame->n_vectors; } +always_inline uword +ip4_rewrite_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame, + int do_counters, int is_midchain, int is_mcast) +{ + vnet_main_t *vnm = vnet_get_main (); + if (PREDICT_FALSE (vnm->interface_main.gso_interface_count > 0)) + return ip4_rewrite_inline_with_gso (vm, node, frame, do_counters, + is_midchain, is_mcast, + 1 /* do_gso */ ); + else + return ip4_rewrite_inline_with_gso (vm, node, frame, do_counters, + is_midchain, is_mcast, + 0 /* no do_gso */ ); +} + /** @brief IPv4 rewrite node. @node ip4-rewrite |