summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2018-04-13 19:43:39 +0200
committerDamjan Marion <damarion@cisco.com>2018-04-13 19:45:57 +0200
commitfe7d4a2e31529eed5416b38b520fdc84687df03c (patch)
treedd3e603fc305d486840f844d919c87f5d0b4b101 /src/vnet
parentbca9290056b1ee206a05c13bbb46b1b40a8bd804 (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.c18
-rw-r--r--src/vnet/devices/virtio/vhost-user.c4
-rw-r--r--src/vnet/ethernet/interface.c5
-rw-r--r--src/vnet/gre/interface.c6
-rw-r--r--src/vnet/interface.api4
-rw-r--r--src/vnet/interface.c62
-rw-r--r--src/vnet/interface.h11
-rw-r--r--src/vnet/interface_api.c33
-rw-r--r--src/vnet/interface_cli.c43
-rw-r--r--src/vnet/interface_funcs.h25
-rw-r--r--src/vnet/ip/icmp4.c6
-rw-r--r--src/vnet/ip/icmp6.c7
-rw-r--r--src/vnet/ip/ip4_forward.c98
-rw-r--r--src/vnet/ip/ip6_forward.c104
-rw-r--r--src/vnet/ip/ip6_neighbor.c7
-rw-r--r--src/vnet/ipip/ipip.c7
-rw-r--r--src/vnet/ipip/sixrd.c3
-rw-r--r--src/vnet/ipsec-gre/interface.c5
-rw-r--r--src/vnet/unix/tapcli.c5
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 = &ethernet_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 = &ethernet_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;