diff options
author | Damjan Marion <damarion@cisco.com> | 2018-04-13 19:43:39 +0200 |
---|---|---|
committer | Damjan Marion <damarion@cisco.com> | 2018-04-13 19:45:57 +0200 |
commit | fe7d4a2e31529eed5416b38b520fdc84687df03c (patch) | |
tree | dd3e603fc305d486840f844d919c87f5d0b4b101 /src/vnet | |
parent | bca9290056b1ee206a05c13bbb46b1b40a8bd804 (diff) |
Revert "MTU: Setting of MTU on software interface (instead of hardware interface)"
This reverts commit 70083ee74c3141bbefb185525315f1b34497dcaa.
Reverting as this patch is causing following crash:
0: /home/damarion/cisco/vpp3/build-data/../src/vnet/devices/devices.h:131 (vnet_get_device_input_thread_index) assertion `queue_id < vec_len (hw->input_node_thread_index_by_queue)' fails
Aborted
Change-Id: Ie2a365032110b1f67be7a9d832885b9899813d39
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/adj/adj.c | 18 | ||||
-rw-r--r-- | src/vnet/devices/virtio/vhost-user.c | 4 | ||||
-rw-r--r-- | src/vnet/ethernet/interface.c | 5 | ||||
-rw-r--r-- | src/vnet/gre/interface.c | 6 | ||||
-rw-r--r-- | src/vnet/interface.api | 4 | ||||
-rw-r--r-- | src/vnet/interface.c | 62 | ||||
-rw-r--r-- | src/vnet/interface.h | 11 | ||||
-rw-r--r-- | src/vnet/interface_api.c | 33 | ||||
-rw-r--r-- | src/vnet/interface_cli.c | 43 | ||||
-rw-r--r-- | src/vnet/interface_funcs.h | 25 | ||||
-rw-r--r-- | src/vnet/ip/icmp4.c | 6 | ||||
-rw-r--r-- | src/vnet/ip/icmp6.c | 7 | ||||
-rw-r--r-- | src/vnet/ip/ip4_forward.c | 98 | ||||
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 104 | ||||
-rw-r--r-- | src/vnet/ip/ip6_neighbor.c | 7 | ||||
-rw-r--r-- | src/vnet/ipip/ipip.c | 7 | ||||
-rw-r--r-- | src/vnet/ipip/sixrd.c | 3 | ||||
-rw-r--r-- | src/vnet/ipsec-gre/interface.c | 5 | ||||
-rw-r--r-- | src/vnet/unix/tapcli.c | 5 |
19 files changed, 221 insertions, 232 deletions
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index 0c9f7468b11..ed4bada6f24 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -353,8 +353,10 @@ adj_mtu_update_walk_cb (adj_index_t ai, return (ADJ_WALK_RC_CONTINUE); } -void -adj_mtu_update (u32 sw_if_index) +static void +adj_sw_mtu_update (vnet_main_t * vnm, + u32 sw_if_index, + void *ctx) { /* * Walk all the adjacencies on the interface to update the cached MTU @@ -362,6 +364,18 @@ adj_mtu_update (u32 sw_if_index) adj_walk (sw_if_index, adj_mtu_update_walk_cb, NULL); } +void +adj_mtu_update (u32 hw_if_index) +{ + /* + * Walk all the SW interfaces on the HW interface to update the cached MTU + */ + vnet_hw_interface_walk_sw(vnet_get_main(), + hw_if_index, + adj_sw_mtu_update, + NULL); +} + /** * @brief Walk the Adjacencies on a given interface */ diff --git a/src/vnet/devices/virtio/vhost-user.c b/src/vnet/devices/virtio/vhost-user.c index 34b131c556f..5460f10b74e 100644 --- a/src/vnet/devices/virtio/vhost-user.c +++ b/src/vnet/devices/virtio/vhost-user.c @@ -2869,8 +2869,8 @@ vhost_user_create_ethernet (vnet_main_t * vnm, vlib_main_t * vm, if (error) clib_error_report (error); - vnet_sw_interface_t *si = vnet_get_hw_sw_interface (vnm, vui->hw_if_index); - vnet_sw_interface_set_mtu (vnm, si->sw_if_index, 9000); + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, vui->hw_if_index); + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000; } /* diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c index 4e1d081635b..2ed20e15c24 100644 --- a/src/vnet/ethernet/interface.c +++ b/src/vnet/ethernet/interface.c @@ -300,9 +300,12 @@ ethernet_register_interface (vnet_main_t * vnm, ETHERNET_MIN_PACKET_BYTES; hi->max_packet_bytes = hi->max_supported_packet_bytes = ETHERNET_MAX_PACKET_BYTES; + hi->per_packet_overhead_bytes = + /* preamble */ 8 + /* inter frame gap */ 12; /* Standard default ethernet MTU. */ - vnet_sw_interface_set_mtu (vnm, hi->sw_if_index, 9000); + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000; + clib_memcpy (ei->address, address, sizeof (ei->address)); vec_free (hi->hw_address); vec_add (hi->hw_address, address, sizeof (ei->address)); diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c index 013dde60af9..5b165c858d3 100644 --- a/src/vnet/gre/interface.c +++ b/src/vnet/gre/interface.c @@ -348,8 +348,12 @@ vnet_gre_tunnel_add (vnet_gre_add_del_tunnel_args_t * a, 64 + sizeof (gre_header_t) + sizeof (ip6_header_t); } + hi->per_packet_overhead_bytes = + /* preamble */ 8 + /* inter frame gap */ 12; + /* Standard default gre MTU. */ - vnet_sw_interface_set_mtu (vnm, sw_if_index, 9000); + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000; + /* * source the FIB entry for the tunnel's destination * and become a child thereof. The tunnel will then get poked diff --git a/src/vnet/interface.api b/src/vnet/interface.api index 0f88863dff3..25ba70342ee 100644 --- a/src/vnet/interface.api +++ b/src/vnet/interface.api @@ -75,7 +75,7 @@ autoreply define want_interface_events @param interface_name - name of the interface @param link_duplex - 1 if half duplex, 2 if full duplex @param link_speed - 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G - @param MTU - max. transmittion unit + @param link_MTU - max. transmittion unit @param sub_if_id - A number 0-N to uniquely identify this subif on super if @param sub_dot1ad - 0 = dot1q, 1 = dot1ad @param sub_dot1ah - 1 = dot1ah, 0 = otherwise @@ -123,7 +123,7 @@ define sw_interface_details u8 link_speed; /* MTU */ - u16 mtu; + u16 link_mtu; /* Subinterface ID. A number 0-N to uniquely identify this subinterface under the super interface */ u32 sub_id; diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 28c46110851..b07a9ba7553 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -122,55 +122,20 @@ unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_list * va) /* helper_flags no redistribution */ 0); } -static void -vnet_sw_interface_set_mtu_cb (vnet_main_t * vnm, u32 sw_if_index, void *ctx) -{ - u32 *mtu = ctx; - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); - ASSERT (si); - - si->max_l3_packet_bytes[VLIB_TX] = si->max_l3_packet_bytes[VLIB_RX] = *mtu; - adj_mtu_update (sw_if_index); -} - -/* - * MTU is set per software interface. Setting MTU on a parent - * interface will override the MTU setting on sub-interfaces. - * TODO: If sub-interface MTU is ~0 inherit from parent? - */ -int -vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu) +void +vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu) { - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); - vnet_hw_interface_t *hi = vnet_get_sw_hw_interface (vnm, sw_if_index); - - if (mtu < hi->min_packet_bytes) - return VNET_API_ERROR_INVALID_VALUE; - if (mtu > hi->max_packet_bytes) - return VNET_API_ERROR_INVALID_VALUE; + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - /* If done on a parent interface */ - if (si->sw_if_index == si->sup_sw_if_index) + if (hi->max_packet_bytes != mtu) { - if (hi->hw_class_index == ethernet_hw_interface_class.index) - { - ethernet_set_flags (vnm, hi->hw_if_index, - ETHERNET_INTERFACE_FLAG_MTU); - } - - /* Override MTU on any sub-interface */ - vnet_hw_interface_walk_sw (vnm, - hi->hw_if_index, - vnet_sw_interface_set_mtu_cb, &mtu); + u16 l3_pad = hi->max_packet_bytes - hi->max_l3_packet_bytes[VLIB_TX]; + hi->max_packet_bytes = mtu; + hi->max_l3_packet_bytes[VLIB_TX] = + hi->max_l3_packet_bytes[VLIB_RX] = mtu - l3_pad; + ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU); + adj_mtu_update (hw_if_index); } - else - { - si->max_l3_packet_bytes[VLIB_TX] = si->max_l3_packet_bytes[VLIB_RX] = - mtu; - adj_mtu_update (sw_if_index); - } - - return 0; } static void @@ -619,9 +584,6 @@ vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE) sw->sup_sw_if_index = sw->sw_if_index; - sw->max_l3_packet_bytes[VLIB_RX] = ~0; - sw->max_l3_packet_bytes[VLIB_TX] = ~0; - /* Allocate counters for this interface. */ { u32 i; @@ -796,7 +758,9 @@ vnet_register_interface (vnet_main_t * vnm, hw->max_rate_bits_per_sec = 0; hw->min_packet_bytes = 0; - hw->max_packet_bytes = 9000; /* default */ + hw->per_packet_overhead_bytes = 0; + hw->max_l3_packet_bytes[VLIB_RX] = ~0; + hw->max_l3_packet_bytes[VLIB_TX] = ~0; if (dev_class->tx_function == 0) goto no_output_nodes; /* No output/tx nodes to create */ diff --git a/src/vnet/interface.h b/src/vnet/interface.h index d462e1e8448..7556bc5544e 100644 --- a/src/vnet/interface.h +++ b/src/vnet/interface.h @@ -512,6 +512,14 @@ typedef struct vnet_hw_interface_t /* Largest packet size for this interface. */ u32 max_packet_bytes; + /* Number of extra bytes that go on the wire. + Packet length on wire + = max (length + per_packet_overhead_bytes, min_packet_bytes). */ + u32 per_packet_overhead_bytes; + + /* Receive and transmit layer 3 packet size limits (MRU/MTU). */ + u32 max_l3_packet_bytes[VLIB_N_RX_TX]; + /* Hash table mapping sub interface id to sw_if_index. */ uword *sub_interface_sw_if_index_by_id; @@ -648,9 +656,6 @@ typedef struct u32 link_speed; - /* Receive and transmit layer 3 packet size limits (MRU/MTU). */ - u32 max_l3_packet_bytes[VLIB_N_RX_TX]; - union { /* VNET_SW_INTERFACE_TYPE_HARDWARE. */ diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index 116ee63bdba..8d982e36b73 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -102,11 +102,40 @@ vl_api_sw_interface_set_mtu_t_handler (vl_api_sw_interface_set_mtu_t * mp) vnet_main_t *vnm = vnet_get_main (); u32 sw_if_index = ntohl (mp->sw_if_index); u16 mtu = ntohs (mp->mtu); + ethernet_main_t *em = ðernet_main; int rv = 0; VALIDATE_SW_IF_INDEX (mp); - rv = vnet_sw_interface_set_mtu (vnm, sw_if_index, mtu); + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + if (si->type != VNET_SW_INTERFACE_TYPE_HARDWARE) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto bad_sw_if_index; + } + + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, si->hw_if_index); + ethernet_interface_t *eif = ethernet_get_interface (em, si->hw_if_index); + + if (!eif) + { + rv = VNET_API_ERROR_FEATURE_DISABLED; + goto bad_sw_if_index; + } + + if (mtu < hi->min_supported_packet_bytes) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto bad_sw_if_index; + } + + if (mtu > hi->max_supported_packet_bytes) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto bad_sw_if_index; + } + + vnet_hw_interface_set_mtu (vnm, si->hw_if_index, mtu); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_SW_INTERFACE_SET_MTU_REPLY); @@ -132,7 +161,7 @@ send_sw_interface_details (vpe_api_main_t * am, VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT); mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >> VNET_HW_INTERFACE_FLAG_SPEED_SHIFT); - mp->mtu = ntohs (swif->max_l3_packet_bytes[VLIB_TX]); + mp->link_mtu = ntohs (hi->max_packet_bytes); mp->context = context; strncpy ((char *) mp->interface_name, diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index fe17c823b36..d151335aa1f 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -1103,29 +1103,32 @@ static clib_error_t * mtu_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vnet_main_t *vnm = vnet_get_main (); - u32 sw_if_index, mtu; + u32 hw_if_index, mtu; + ethernet_main_t *em = ðernet_main; - if (unformat (input, "%d %U", &mtu, unformat_vnet_sw_interface, vnm, - &sw_if_index)) - { - ; - } - else + if (unformat (input, "%d %U", &mtu, + unformat_vnet_hw_interface, vnm, &hw_if_index)) { - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); - } + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); + ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index); - int rv = vnet_sw_interface_set_mtu (vnm, sw_if_index, mtu); - if (rv < 0) - { - vnet_hw_interface_t *hi = vnet_get_sw_hw_interface (vnm, sw_if_index); - ASSERT (hi); - return clib_error_return (0, "Invalid mtu (%d): " - "must be between min pkt bytes (%d) and max pkt bytes (%d)", - mtu, hi->min_packet_bytes, - hi->max_packet_bytes); + if (!eif) + return clib_error_return (0, "not supported"); + + if (mtu < hi->min_supported_packet_bytes) + return clib_error_return (0, "Invalid mtu (%d): " + "must be >= min pkt bytes (%d)", mtu, + hi->min_supported_packet_bytes); + + if (mtu > hi->max_supported_packet_bytes) + return clib_error_return (0, "Invalid mtu (%d): must be <= (%d)", mtu, + hi->max_supported_packet_bytes); + + vnet_hw_interface_set_mtu (vnm, hw_if_index, mtu); } + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); return 0; } @@ -1403,7 +1406,7 @@ set_interface_rx_mode (vlib_main_t * vm, unformat_input_t * input, * @cliexend ?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cmd_set_if_rx_mode, static) = { +VLIB_CLI_COMMAND (cmd_set_if_rx_mode,static) = { .path = "set interface rx-mode", .short_help = "set interface rx-mode <interface> [queue <n>] [polling | interrupt | adaptive]", .function = set_interface_rx_mode, diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h index 42b69bdf789..6e188f7f543 100644 --- a/src/vnet/interface_funcs.h +++ b/src/vnet/interface_funcs.h @@ -87,15 +87,6 @@ vnet_get_sup_hw_interface (vnet_main_t * vnm, u32 sw_if_index) return vnet_get_hw_interface (vnm, sw->hw_if_index); } -always_inline vnet_hw_interface_t * -vnet_get_sw_hw_interface (vnet_main_t * vnm, u32 sw_if_index) -{ - vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index); - if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE) - return vnet_get_hw_interface (vnm, sw->hw_if_index); - return vnet_get_sup_hw_interface (vnm, sw_if_index); -} - always_inline vnet_hw_interface_class_t * vnet_get_hw_interface_class (vnet_main_t * vnm, u32 hw_class_index) { @@ -228,11 +219,19 @@ vnet_hw_interface_get_flags (vnet_main_t * vnm, u32 hw_if_index) } always_inline uword +vnet_hw_interface_get_mtu (vnet_main_t * vnm, u32 hw_if_index, + vlib_rx_or_tx_t dir) +{ + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); + return hw->max_l3_packet_bytes[dir]; +} + +always_inline uword vnet_sw_interface_get_mtu (vnet_main_t * vnm, u32 sw_if_index, vlib_rx_or_tx_t dir) { - vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index); - return (sw->max_l3_packet_bytes[dir]); + vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index); + return (hw->max_l3_packet_bytes[dir]); } always_inline uword @@ -293,8 +292,8 @@ clib_error_t *set_hw_interface_change_rx_mode (vnet_main_t * vnm, vnet_hw_interface_rx_mode mode); -/* Set the MTU on the SW interface */ -int vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu); +/* Set the MTU on the HW interface */ +void vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu); /* update the unnumbered state of an interface */ void vnet_sw_interface_update_unnumbered (u32 sw_if_index, diff --git a/src/vnet/ip/icmp4.c b/src/vnet/ip/icmp4.c index a4808f23271..1fe01e48500 100644 --- a/src/vnet/ip/icmp4.c +++ b/src/vnet/ip/icmp4.c @@ -513,15 +513,13 @@ ip4_icmp_error (vlib_main_t * vm, b->current_length = 0; } } + p0->current_length = + p0->current_length > 576 ? 576 : p0->current_length; /* Add IP header and ICMPv4 header including a 4 byte data field */ vlib_buffer_advance (p0, -sizeof (ip4_header_t) - sizeof (icmp46_header_t) - 4); - - p0->current_length = - p0->current_length > 576 ? 576 : p0->current_length; - out_ip0 = vlib_buffer_get_current (p0); icmp0 = (icmp46_header_t *) & out_ip0[1]; diff --git a/src/vnet/ip/icmp6.c b/src/vnet/ip/icmp6.c index 6beec28c2cf..fd5d0ecba38 100644 --- a/src/vnet/ip/icmp6.c +++ b/src/vnet/ip/icmp6.c @@ -526,14 +526,13 @@ ip6_icmp_error (vlib_main_t * vm, b->current_length = 0; } } + p0->current_length = + p0->current_length > 1280 ? 1280 : p0->current_length; + /* Add IP header and ICMPv6 header including a 4 byte data field */ vlib_buffer_advance (p0, -sizeof (ip6_header_t) - sizeof (icmp46_header_t) - 4); - - p0->current_length = - p0->current_length > 1280 ? 1280 : p0->current_length; - out_ip0 = vlib_buffer_get_current (p0); icmp0 = (icmp46_header_t *) & out_ip0[1]; diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 3dce590c807..7c56a294436 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -1940,29 +1940,6 @@ typedef enum IP4_REWRITE_NEXT_ICMP_ERROR, } ip4_rewrite_next_t; -always_inline void -ip4_mtu_check (vlib_buffer_t * b, u16 buffer_packet_bytes, - u16 adj_packet_bytes, bool df, u32 * next, u32 * error) -{ - if (buffer_packet_bytes > adj_packet_bytes) - { - *error = IP4_ERROR_MTU_EXCEEDED; - if (df) - { - icmp4_error_set_vnet_buffer - (b, ICMP4_destination_unreachable, - ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set, - adj_packet_bytes); - *next = IP4_REWRITE_NEXT_ICMP_ERROR; - } - else - { - /* Add support for fragmentation here */ - *next = IP4_REWRITE_NEXT_DROP; - } - } -} - always_inline uword ip4_rewrite_inline (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -2123,20 +2100,26 @@ ip4_rewrite_inline (vlib_main_t * vm, vnet_buffer (p1)->ip.save_rewrite_length = rw_len1; /* 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); - ip4_mtu_check (p1, vlib_buffer_length_in_chain (vm, p1), - adj1[0].rewrite_header.max_l3_packet_bytes, - ip1->flags_and_fragment_offset & - clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT), - &next1, &error1); - - /* Guess we are only writing on simple Ethernet header. */ - vnet_rewrite_two_headers (adj0[0], adj1[0], - ip0, ip1, sizeof (ethernet_header_t)); + if (vlib_buffer_length_in_chain (vm, p0) > + adj0[0].rewrite_header.max_l3_packet_bytes) + { + error0 = IP4_ERROR_MTU_EXCEEDED; + next0 = IP4_REWRITE_NEXT_ICMP_ERROR; + icmp4_error_set_vnet_buffer + (p0, ICMP4_destination_unreachable, + ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set, + 0); + } + if (vlib_buffer_length_in_chain (vm, p1) > + adj1[0].rewrite_header.max_l3_packet_bytes) + { + error1 = IP4_ERROR_MTU_EXCEEDED; + next1 = IP4_REWRITE_NEXT_ICMP_ERROR; + icmp4_error_set_vnet_buffer + (p1, ICMP4_destination_unreachable, + ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set, + 0); + } if (is_mcast) { @@ -2160,17 +2143,10 @@ ip4_rewrite_inline (vlib_main_t * vm, tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index; vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0; - if (is_midchain) - { - adj0->sub_type.midchain.fixup_func - (vm, adj0, p0, adj0->sub_type.midchain.fixup_data); - } - if (PREDICT_FALSE (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 (PREDICT_TRUE (error1 == IP4_ERROR_NONE)) { @@ -2181,18 +2157,16 @@ ip4_rewrite_inline (vlib_main_t * vm, tx_sw_if_index1 = adj1[0].rewrite_header.sw_if_index; vnet_buffer (p1)->sw_if_index[VLIB_TX] = tx_sw_if_index1; - if (is_midchain) - { - adj1->sub_type.midchain.fixup_func - (vm, adj1, p1, adj0->sub_type.midchain.fixup_data); - } - if (PREDICT_FALSE (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)); + /* * Bump the per-adjacency counters */ @@ -2211,6 +2185,13 @@ ip4_rewrite_inline (vlib_main_t * vm, vlib_buffer_length_in_chain (vm, p1) + rw_len1); } + 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, adj0->sub_type.midchain.fixup_data); + } if (is_mcast) { /* @@ -2291,7 +2272,6 @@ ip4_rewrite_inline (vlib_main_t * vm, /* Guess we are only writing on simple Ethernet header. */ vnet_rewrite_one_header (adj0[0], ip0, sizeof (ethernet_header_t)); - if (is_mcast) { /* @@ -2311,12 +2291,16 @@ ip4_rewrite_inline (vlib_main_t * vm, 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 (vlib_buffer_length_in_chain (vm, p0) > + adj0[0].rewrite_header.max_l3_packet_bytes) + { + error0 = IP4_ERROR_MTU_EXCEEDED; + next0 = IP4_REWRITE_NEXT_ICMP_ERROR; + icmp4_error_set_vnet_buffer + (p0, ICMP4_destination_unreachable, + ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set, + 0); + } if (is_mcast) { error0 = ((adj0[0].rewrite_header.sw_if_index == diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index 7599733fcb5..588cd0675a4 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -1774,19 +1774,6 @@ 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, @@ -1911,14 +1898,9 @@ 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; @@ -1937,12 +1919,16 @@ ip6_rewrite_inline (vlib_main_t * vm, } /* Check MTU of outgoing interface. */ - 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); + 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); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP headerr */ @@ -1959,19 +1945,6 @@ 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)) { @@ -1986,19 +1959,26 @@ 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); + } - 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); - } + /* 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); } vlib_validate_buffer_enqueue_x2 (vm, node, next_index, @@ -2074,9 +2054,11 @@ ip6_rewrite_inline (vlib_main_t * vm, } /* Check MTU of outgoing interface. */ - ip6_mtu_check (p0, vlib_buffer_length_in_chain (vm, p0), - adj0[0].rewrite_header.max_l3_packet_bytes, &next0, - &error0); + error0 = + (vlib_buffer_length_in_chain (vm, p0) > + adj0[0]. + rewrite_header.max_l3_packet_bytes ? IP6_ERROR_MTU_EXCEEDED : + error0); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP headerr */ @@ -2094,16 +2076,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]; diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index a1439faa154..fee4356f5e0 100644 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -2575,6 +2575,10 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, { if (is_add) { + vnet_hw_interface_t *hw_if0; + + hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index); + pool_get (nm->if_radv_pool, a); ri = a - nm->if_radv_pool; @@ -2608,8 +2612,7 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, a->send_radv = 1; /* fill in radv_info for this interface that will be needed later */ - a->adv_link_mtu = - vnet_sw_interface_get_mtu (vnm, sw_if_index, VLIB_TX); + a->adv_link_mtu = hw_if0->max_l3_packet_bytes[VLIB_RX]; clib_memcpy (a->link_layer_address, eth_if0->address, 6); diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c index 9b808d4ac0f..82c961cdddd 100644 --- a/src/vnet/ipip/ipip.c +++ b/src/vnet/ipip/ipip.c @@ -476,16 +476,17 @@ ipip_add_tunnel (ipip_transport_t transport, { vec_validate (im4->fib_index_by_sw_if_index, sw_if_index); hi->min_packet_bytes = 64 + sizeof (ip4_header_t); - hi->max_packet_bytes = 65536 - sizeof (ip4_header_t); } else { vec_validate (im6->fib_index_by_sw_if_index, sw_if_index); hi->min_packet_bytes = 64 + sizeof (ip6_header_t); - hi->max_packet_bytes = 65536 - sizeof (ip6_header_t); } - vnet_sw_interface_set_mtu (vnm, sw_if_index, hi->max_packet_bytes); + hi->per_packet_overhead_bytes = /* preamble */ 8 + /* inter frame gap */ 12; + + /* Standard default ipip MTU. */ + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000; t->tunnel_src = *src; t->tunnel_dst = *dst; diff --git a/src/vnet/ipip/sixrd.c b/src/vnet/ipip/sixrd.c index 998025782fb..cfdd0f87e3a 100644 --- a/src/vnet/ipip/sixrd.c +++ b/src/vnet/ipip/sixrd.c @@ -337,8 +337,7 @@ sixrd_add_tunnel (ip6_address_t * ip6_prefix, u8 ip6_prefix_len, t->dev_instance = t_idx; t->user_instance = t_idx; - /* Set default MTU to 1480 */ - vnet_sw_interface_set_mtu (vnet_get_main (), t->sw_if_index, 1480); + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 1480; ipip_tunnel_db_add (t, &key); diff --git a/src/vnet/ipsec-gre/interface.c b/src/vnet/ipsec-gre/interface.c index fa33684c50d..0772ce73df2 100644 --- a/src/vnet/ipsec-gre/interface.c +++ b/src/vnet/ipsec-gre/interface.c @@ -174,9 +174,12 @@ vnet_ipsec_gre_add_del_tunnel (vnet_ipsec_gre_add_del_tunnel_args_t * a, hi->min_packet_bytes = 64 + sizeof (gre_header_t) + sizeof (ip4_header_t) + sizeof (esp_header_t) + sizeof (esp_footer_t); + hi->per_packet_overhead_bytes = + /* preamble */ 8 + /* inter frame gap */ 12; /* Standard default gre MTU. */ - vnet_sw_interface_set_mtu (vnm, hi->sw_if_index, 9000); + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = + 9000; clib_memcpy (&t->tunnel_src, &a->src, sizeof (t->tunnel_src)); clib_memcpy (&t->tunnel_dst, &a->dst, sizeof (t->tunnel_dst)); diff --git a/src/vnet/unix/tapcli.c b/src/vnet/unix/tapcli.c index 5c550bc3320..10a86a457e8 100644 --- a/src/vnet/unix/tapcli.c +++ b/src/vnet/unix/tapcli.c @@ -1068,9 +1068,8 @@ vnet_tap_connect (vlib_main_t * vm, vnet_tap_connect_args_t * ap) hw = vnet_get_hw_interface (tm->vnet_main, ti->hw_if_index); hw->min_supported_packet_bytes = TAP_MTU_MIN; hw->max_supported_packet_bytes = TAP_MTU_MAX; - vnet_sw_interface_set_mtu (tm->vnet_main, hw->sw_if_index, - hw->max_supported_packet_bytes - - sizeof (ethernet_header_t)); + hw->max_l3_packet_bytes[VLIB_RX] = hw->max_l3_packet_bytes[VLIB_TX] = + hw->max_supported_packet_bytes - sizeof (ethernet_header_t); ti->sw_if_index = hw->sw_if_index; if (ap->sw_if_indexp) *(ap->sw_if_indexp) = hw->sw_if_index; |