diff options
Diffstat (limited to 'src/vnet/ip/ip6_forward.c')
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 104 |
1 files changed, 61 insertions, 43 deletions
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index 588cd0675a4..7599733fcb5 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -1774,6 +1774,19 @@ typedef enum IP6_REWRITE_NEXT_ICMP_ERROR, } ip6_rewrite_next_t; +always_inline void +ip6_mtu_check (vlib_buffer_t * b, u16 buffer_packet_bytes, + u16 adj_packet_bytes, u32 * next, u32 * error) +{ + if (adj_packet_bytes >= 1280 && buffer_packet_bytes > adj_packet_bytes) + { + *error = IP6_ERROR_MTU_EXCEEDED; + icmp6_error_set_vnet_buffer (b, ICMP6_packet_too_big, 0, + adj_packet_bytes); + *next = IP6_REWRITE_NEXT_ICMP_ERROR; + } +} + always_inline uword ip6_rewrite_inline (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -1898,9 +1911,14 @@ ip6_rewrite_inline (vlib_main_t * vm, { p1->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED; } + adj0 = adj_get (adj_index0); adj1 = adj_get (adj_index1); + /* Guess we are only writing on simple Ethernet header. */ + vnet_rewrite_two_headers (adj0[0], adj1[0], + ip0, ip1, sizeof (ethernet_header_t)); + rw_len0 = adj0[0].rewrite_header.data_bytes; rw_len1 = adj1[0].rewrite_header.data_bytes; vnet_buffer (p0)->ip.save_rewrite_length = rw_len0; @@ -1919,16 +1937,12 @@ ip6_rewrite_inline (vlib_main_t * vm, } /* Check MTU of outgoing interface. */ - error0 = - (vlib_buffer_length_in_chain (vm, p0) > - adj0[0]. - rewrite_header.max_l3_packet_bytes ? IP6_ERROR_MTU_EXCEEDED : - error0); - error1 = - (vlib_buffer_length_in_chain (vm, p1) > - adj1[0]. - rewrite_header.max_l3_packet_bytes ? IP6_ERROR_MTU_EXCEEDED : - error1); + ip6_mtu_check (p0, vlib_buffer_length_in_chain (vm, p0), + adj0[0].rewrite_header.max_l3_packet_bytes, &next0, + &error0); + ip6_mtu_check (p1, vlib_buffer_length_in_chain (vm, p1), + adj1[0].rewrite_header.max_l3_packet_bytes, &next1, + &error1); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP headerr */ @@ -1945,6 +1959,19 @@ ip6_rewrite_inline (vlib_main_t * vm, (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) vnet_feature_arc_start (lm->output_feature_arc_index, tx_sw_if_index0, &next0, p0); + + if (is_midchain) + { + adj0->sub_type.midchain.fixup_func + (vm, adj0, p0, adj0->sub_type.midchain.fixup_data); + } + if (is_mcast) + { + /* + * copy bytes from the IP address into the MAC rewrite + */ + vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0); + } } if (PREDICT_TRUE (error1 == IP6_ERROR_NONE)) { @@ -1959,26 +1986,19 @@ ip6_rewrite_inline (vlib_main_t * vm, (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) vnet_feature_arc_start (lm->output_feature_arc_index, tx_sw_if_index1, &next1, p1); - } - /* Guess we are only writing on simple Ethernet header. */ - vnet_rewrite_two_headers (adj0[0], adj1[0], - ip0, ip1, sizeof (ethernet_header_t)); - - if (is_midchain) - { - adj0->sub_type.midchain.fixup_func - (vm, adj0, p0, adj0->sub_type.midchain.fixup_data); - adj1->sub_type.midchain.fixup_func - (vm, adj1, p1, adj1->sub_type.midchain.fixup_data); - } - if (is_mcast) - { - /* - * copy bytes from the IP address into the MAC rewrite - */ - vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0); - vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1); + if (is_midchain) + { + adj1->sub_type.midchain.fixup_func + (vm, adj1, p1, adj1->sub_type.midchain.fixup_data); + } + if (is_mcast) + { + /* + * copy bytes from the IP address into the MAC rewrite + */ + vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1); + } } vlib_validate_buffer_enqueue_x2 (vm, node, next_index, @@ -2054,11 +2074,9 @@ ip6_rewrite_inline (vlib_main_t * vm, } /* Check MTU of outgoing interface. */ - error0 = - (vlib_buffer_length_in_chain (vm, p0) > - adj0[0]. - rewrite_header.max_l3_packet_bytes ? IP6_ERROR_MTU_EXCEEDED : - error0); + ip6_mtu_check (p0, vlib_buffer_length_in_chain (vm, p0), + adj0[0].rewrite_header.max_l3_packet_bytes, &next0, + &error0); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP headerr */ @@ -2076,16 +2094,16 @@ ip6_rewrite_inline (vlib_main_t * vm, (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) vnet_feature_arc_start (lm->output_feature_arc_index, tx_sw_if_index0, &next0, p0); - } - if (is_midchain) - { - adj0->sub_type.midchain.fixup_func - (vm, adj0, p0, adj0->sub_type.midchain.fixup_data); - } - if (is_mcast) - { - vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0); + if (is_midchain) + { + adj0->sub_type.midchain.fixup_func + (vm, adj0, p0, adj0->sub_type.midchain.fixup_data); + } + if (is_mcast) + { + vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0); + } } p0->error = error_node->errors[error0]; |