VPP-1283: IPv6 PMTU missing MTU value in ICMP6 message.
Fix GRE/IPv6 setting of ip->payload_length (which has never worked). Change-Id: Ie68f1cc7bbb70489d6ec97356132c783f2345e1e Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
@ -292,8 +292,8 @@ gre6_fixup (vlib_main_t * vm,
|
||||
/* Fixup the payload length field in the GRE tunnel encap that was applied
|
||||
* at the midchain node */
|
||||
ip0->payload_length =
|
||||
clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0))
|
||||
- sizeof (*ip0);
|
||||
clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
|
||||
sizeof (*ip0));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -526,13 +526,15 @@ 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];
|
||||
|
||||
|
@ -1561,6 +1561,19 @@ typedef enum
|
||||
*/
|
||||
#define IP6_MCAST_ADDR_MASK 0xffffffff
|
||||
|
||||
always_inline void
|
||||
ip6_mtu_check (vlib_buffer_t * b, u16 packet_bytes,
|
||||
u16 adj_packet_bytes, u32 * next, u32 * error)
|
||||
{
|
||||
if (adj_packet_bytes >= 1280 && 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,
|
||||
@ -1706,16 +1719,14 @@ 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, clib_net_to_host_u16 (ip0->payload_length) +
|
||||
sizeof (ip6_header_t),
|
||||
adj0[0].rewrite_header.max_l3_packet_bytes,
|
||||
&next0, &error0);
|
||||
ip6_mtu_check (p1, clib_net_to_host_u16 (ip1->payload_length) +
|
||||
sizeof (ip6_header_t),
|
||||
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 */
|
||||
@ -1849,14 +1860,13 @@ 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, clib_net_to_host_u16 (ip0->payload_length) +
|
||||
sizeof (ip6_header_t),
|
||||
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 */
|
||||
* wants to see the IP header */
|
||||
if (PREDICT_TRUE (error0 == IP6_ERROR_NONE))
|
||||
{
|
||||
p0->current_data -= rw_len0;
|
||||
|
@ -165,16 +165,22 @@ class TestMTU(VppTestCase):
|
||||
self.validate(reass_pkt, p4_reply)
|
||||
'''
|
||||
# Reset MTU
|
||||
self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, current_mtu)
|
||||
self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
|
||||
current_mtu + mtu_offset)
|
||||
|
||||
@unittest.skip("Enable when IPv6 fragmentation is added")
|
||||
def test_ip6_mtu(self):
|
||||
""" IP6 MTU test """
|
||||
|
||||
#
|
||||
# TODO: Link MTU is 216 bytes 'off'. Fix when L3 MTU patches committed
|
||||
#
|
||||
mtu_offset = 216
|
||||
current_mtu = self.get_mtu(self.pg1.sw_if_index)
|
||||
current_mtu -= mtu_offset
|
||||
|
||||
p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
|
||||
p_ip6 = IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6)
|
||||
|
||||
current_mtu = self.get_mtu(self.pg1.sw_if_index)
|
||||
p_payload = UDP(sport=1234, dport=1234) / self.payload(
|
||||
current_mtu - 40 - 8)
|
||||
|
||||
@ -186,8 +192,8 @@ class TestMTU(VppTestCase):
|
||||
self.validate(p[1], p6_reply)
|
||||
|
||||
# MTU (only checked on encap)
|
||||
self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, 1280)
|
||||
self.assertEqual(1280, self.get_mtu(self.pg1.sw_if_index))
|
||||
self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, 1280 + mtu_offset)
|
||||
self.assertEqual(1280, self.get_mtu(self.pg1.sw_if_index) - mtu_offset)
|
||||
|
||||
# Should fail. Too large MTU
|
||||
p_icmp6 = ICMPv6PacketTooBig(mtu=1280, cksum=0x4c7a)
|
||||
|
Reference in New Issue
Block a user