summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2020-03-06 06:11:07 -0500
committerMatthew Smith <mgsmith@netgate.com>2020-03-24 14:28:34 +0000
commit46d0ff3945404f7c95e0e504f98f466e155ab753 (patch)
treea517e9ed68c3afe0d57db62e717ed6e5f32188c0 /src/vnet/ip
parent1839fe165c7ffb834775b8582fe0ee2321ff2ab6 (diff)
map: fix translation of icmp6 error messages
Translation of ICMPv6 error messages to ICMP error messages fails because the sender port is not set that leads to securtiy check failure. With this commit, during ICMPv6 error messages translation, get the sender port value from the inner packet. Type: fix Change-Id: I1ee295a3685fab4837172edfb629a699f49afbee Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip6_to_ip4.h51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/vnet/ip/ip6_to_ip4.h b/src/vnet/ip/ip6_to_ip4.h
index 17a11e6df0a..6a533e3b54e 100644
--- a/src/vnet/ip/ip6_to_ip4.h
+++ b/src/vnet/ip/ip6_to_ip4.h
@@ -170,6 +170,57 @@ ip6_get_port (vlib_main_t * vm, vlib_buffer_t * b, ip6_header_t * ip6,
if (dst_port)
*dst_port = ((u16 *) (icmp))[2];
}
+ else if (clib_net_to_host_u16 (ip6->payload_length) >= 64)
+ {
+ u16 ip6_pay_len;
+ ip6_header_t *inner_ip6;
+ u8 inner_l4_protocol;
+ u16 inner_l4_offset;
+ u16 inner_frag_offset;
+ u8 *inner_l4;
+
+ ip6_pay_len = clib_net_to_host_u16 (ip6->payload_length);
+ inner_ip6 = (ip6_header_t *) u8_ptr_add (icmp, 8);
+
+ if (ip6_parse (vm, b, inner_ip6, ip6_pay_len - 8,
+ &inner_l4_protocol, &inner_l4_offset,
+ &inner_frag_offset))
+ return 0;
+
+ if (inner_frag_offset &&
+ ip6_frag_hdr_offset (((ip6_frag_hdr_t *)
+ u8_ptr_add (inner_ip6,
+ inner_frag_offset))))
+ return 0;
+
+ inner_l4 = u8_ptr_add (inner_ip6, inner_l4_offset);
+ if (inner_l4_protocol == IP_PROTOCOL_TCP ||
+ inner_l4_protocol == IP_PROTOCOL_UDP)
+ {
+ if (src_port)
+ *src_port = ((udp_header_t *) (inner_l4))->dst_port;
+ if (dst_port)
+ *dst_port = ((udp_header_t *) (inner_l4))->src_port;
+ }
+ else if (inner_l4_protocol == IP_PROTOCOL_ICMP6)
+ {
+ icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_l4);
+ if (inner_icmp->type == ICMP6_echo_request)
+ {
+ if (src_port)
+ *src_port = ((u16 *) (inner_icmp))[2];
+ if (dst_port)
+ *dst_port = ((u16 *) (inner_icmp))[2];
+ }
+ else if (inner_icmp->type == ICMP6_echo_reply)
+ {
+ if (src_port)
+ *src_port = ((u16 *) (inner_icmp))[2];
+ if (dst_port)
+ *dst_port = ((u16 *) (inner_icmp))[2];
+ }
+ }
+ }
}
return 1;
}