aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/hs_apps/CMakeLists.txt5
-rw-r--r--src/plugins/hs_apps/vcl/vcl_test_cl_udp.c156
-rw-r--r--src/plugins/nat/det44/det44.h1
-rw-r--r--src/plugins/nat/det44/det44_in2out.c2
-rw-r--r--src/plugins/nat/det44/det44_out2in.c2
-rw-r--r--src/plugins/nat/dslite/dslite.h1
-rw-r--r--src/plugins/nat/dslite/dslite_in2out.c1
-rw-r--r--src/plugins/nat/dslite/dslite_out2in.c1
-rw-r--r--src/plugins/nat/lib/inlines.h44
-rw-r--r--src/plugins/nat/lib/ipfix_logging.c1
-rw-r--r--src/plugins/nat/lib/nat_syslog.c1
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.h1
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_inlines.h1
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.c1
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.h1
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_in2out.c1
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_out2in.c1
-rw-r--r--src/plugins/nat/nat64/nat64.c1
-rw-r--r--src/plugins/nat/nat64/nat64.h1
-rw-r--r--src/plugins/nat/nat64/nat64_db.c1
-rw-r--r--src/vcl/vppcom.c24
-rw-r--r--src/vnet/ip/ip4_to_ip6.h21
-rw-r--r--src/vnet/ip/ip6_to_ip4.h14
23 files changed, 222 insertions, 61 deletions
diff --git a/src/plugins/hs_apps/CMakeLists.txt b/src/plugins/hs_apps/CMakeLists.txt
index eae100949d4..7cccf14aee7 100644
--- a/src/plugins/hs_apps/CMakeLists.txt
+++ b/src/plugins/hs_apps/CMakeLists.txt
@@ -74,4 +74,9 @@ if(VPP_BUILD_VCL_TESTS)
NO_INSTALL
)
endforeach()
+
+ add_vpp_executable(vcl_test_cl_udp SOURCES "vcl/vcl_test_cl_udp.c"
+ LINK_LIBRARIES vppcom pthread ${EPOLL_LIB}
+ NO_INSTALL
+ )
endif(VPP_BUILD_VCL_TESTS)
diff --git a/src/plugins/hs_apps/vcl/vcl_test_cl_udp.c b/src/plugins/hs_apps/vcl/vcl_test_cl_udp.c
new file mode 100644
index 00000000000..066635e3d9b
--- /dev/null
+++ b/src/plugins/hs_apps/vcl/vcl_test_cl_udp.c
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2025 Cisco Systems, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <vcl/vppcom.h>
+#include <hs_apps/vcl/vcl_test.h>
+
+typedef enum vt_clu_type_
+{
+ VT_CLU_TYPE_NONE = 0,
+ VT_CLU_TYPE_SERVER,
+ VT_CLU_TYPE_CLIENT,
+} vt_clu_type_t;
+
+typedef struct vtclu_main_
+{
+ vt_clu_type_t app_type;
+ vppcom_endpt_t endpt;
+ union
+ {
+ struct sockaddr_storage srvr_addr;
+ struct sockaddr_storage clnt_addr;
+ };
+ uint16_t port;
+} vt_clu_main_t;
+
+static vt_clu_main_t vt_clu_main;
+
+static void
+vt_clu_parse_args (vt_clu_main_t *vclum, int argc, char **argv)
+{
+ int c;
+
+ memset (vclum, 0, sizeof (*vclum));
+ vclum->port = VCL_TEST_SERVER_PORT;
+
+ opterr = 0;
+ while ((c = getopt (argc, argv, "s:c:")) != -1)
+ switch (c)
+ {
+ case 's':
+ vclum->app_type = VT_CLU_TYPE_SERVER;
+ if (inet_pton (
+ AF_INET, optarg,
+ &((struct sockaddr_in *) &vclum->srvr_addr)->sin_addr) != 1)
+ vtwrn ("couldn't parse ipv4 addr %s", optarg);
+ break;
+ case 'c':
+ vclum->app_type = VT_CLU_TYPE_CLIENT;
+ if (inet_pton (
+ AF_INET, optarg,
+ &((struct sockaddr_in *) &vclum->clnt_addr)->sin_addr) != 1)
+ break;
+ }
+
+ if (vclum->app_type == VT_CLU_TYPE_NONE)
+ {
+ vtwrn ("client or server must be configured");
+ exit (1);
+ }
+
+ vclum->endpt.is_ip4 = 1;
+ vclum->endpt.ip =
+ (uint8_t *) &((struct sockaddr_in *) &vclum->srvr_addr)->sin_addr;
+ vclum->endpt.port = htons (vclum->endpt.port);
+}
+
+int
+main (int argc, char **argv)
+{
+ vt_clu_main_t *vclum = &vt_clu_main;
+ int rv, vcl_sh;
+ const int buflen = 64;
+ char buf[buflen];
+
+ struct sockaddr_in _addr;
+ vppcom_endpt_t rmt_ep = { .ip = (void *) &_addr };
+
+ vt_clu_parse_args (vclum, argc, argv);
+
+ rv = vppcom_app_create ("vcl_test_cl_udp");
+ if (rv)
+ vtfail ("vppcom_app_create()", rv);
+
+ vcl_sh = vppcom_session_create (VPPCOM_PROTO_UDP, 0 /* is_nonblocking */);
+ if (vcl_sh < 0)
+ {
+ vterr ("vppcom_session_create()", vcl_sh);
+ return vcl_sh;
+ }
+
+ if (vclum->app_type == VT_CLU_TYPE_SERVER)
+ {
+ /* Listen is implicit */
+ rv = vppcom_session_bind (vcl_sh, &vclum->endpt);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_bind()", rv);
+ return rv;
+ }
+
+ rv = vppcom_session_recvfrom (vcl_sh, buf, buflen, 0, &rmt_ep);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_recvfrom()", rv);
+ return rv;
+ }
+ buf[rv] = 0;
+ vtinf ("Received message from client: %s", buf);
+
+ char *msg = "hello cl udp client";
+ int msg_len = strnlen (msg, buflen);
+ memcpy (buf, msg, msg_len);
+ /* send 2 times to be sure */
+ for (int i = 0; i < 2; i++)
+ {
+ rv = vppcom_session_sendto (vcl_sh, buf, msg_len, 0, &rmt_ep);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_sendto()", rv);
+ return rv;
+ }
+ usleep (500);
+ }
+ }
+ else if (vclum->app_type == VT_CLU_TYPE_CLIENT)
+ {
+ char *msg = "hello cl udp server";
+ int msg_len = strnlen (msg, buflen);
+ memcpy (buf, msg, msg_len);
+
+ /* send 3 times to be sure */
+ for (int i = 0; i < 3; i++)
+ {
+ rv = vppcom_session_sendto (vcl_sh, buf, msg_len, 0, &vclum->endpt);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_sendto()", rv);
+ return rv;
+ }
+ usleep (500);
+ }
+
+ rv = vppcom_session_recvfrom (vcl_sh, buf, buflen, 0, &rmt_ep);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_recvfrom()", rv);
+ return rv;
+ }
+ buf[rv] = 0;
+ vtinf ("Received message from server: %s", buf);
+ }
+} \ No newline at end of file
diff --git a/src/plugins/nat/det44/det44.h b/src/plugins/nat/det44/det44.h
index e576bfb65e8..683f554f03c 100644
--- a/src/plugins/nat/det44/det44.h
+++ b/src/plugins/nat/det44/det44.h
@@ -38,7 +38,6 @@
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/ipfix_logging.h>
#include <nat/lib/nat_proto.h>
diff --git a/src/plugins/nat/det44/det44_in2out.c b/src/plugins/nat/det44/det44_in2out.c
index 3f5e05a064c..39a9ecabac7 100644
--- a/src/plugins/nat/det44/det44_in2out.c
+++ b/src/plugins/nat/det44/det44_in2out.c
@@ -21,6 +21,7 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/fib/ip4_fib.h>
#include <vppinfra/error.h>
#include <vppinfra/elog.h>
@@ -29,7 +30,6 @@
#include <nat/det44/det44_inlines.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/nat_inlines.h>
typedef enum
diff --git a/src/plugins/nat/det44/det44_out2in.c b/src/plugins/nat/det44/det44_out2in.c
index ab6acd4f8e9..dd89606ff10 100644
--- a/src/plugins/nat/det44/det44_out2in.c
+++ b/src/plugins/nat/det44/det44_out2in.c
@@ -21,6 +21,7 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/fib/ip4_fib.h>
#include <vppinfra/error.h>
#include <vppinfra/elog.h>
@@ -29,7 +30,6 @@
#include <nat/det44/det44_inlines.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/nat_inlines.h>
typedef enum
diff --git a/src/plugins/nat/dslite/dslite.h b/src/plugins/nat/dslite/dslite.h
index f05670c9bf5..979afb476b7 100644
--- a/src/plugins/nat/dslite/dslite.h
+++ b/src/plugins/nat/dslite/dslite.h
@@ -22,7 +22,6 @@
#include <nat/lib/lib.h>
#include <nat/lib/alloc.h>
-#include <nat/lib/inlines.h>
typedef struct
{
diff --git a/src/plugins/nat/dslite/dslite_in2out.c b/src/plugins/nat/dslite/dslite_in2out.c
index 522c3cf4123..806969f5f4d 100644
--- a/src/plugins/nat/dslite/dslite_in2out.c
+++ b/src/plugins/nat/dslite/dslite_in2out.c
@@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <vnet/ip/ip4_to_ip6.h>
#include <nat/dslite/dslite.h>
#include <nat/lib/nat_syslog.h>
diff --git a/src/plugins/nat/dslite/dslite_out2in.c b/src/plugins/nat/dslite/dslite_out2in.c
index 531bbb468bb..9ec48d458e5 100644
--- a/src/plugins/nat/dslite/dslite_out2in.c
+++ b/src/plugins/nat/dslite/dslite_out2in.c
@@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <vnet/ip/ip4_to_ip6.h>
#include <nat/dslite/dslite.h>
typedef enum
diff --git a/src/plugins/nat/lib/inlines.h b/src/plugins/nat/lib/inlines.h
deleted file mode 100644
index 24e3ba83a5b..00000000000
--- a/src/plugins/nat/lib/inlines.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @brief Common NAT inline functions
- */
-#ifndef included_nat_inlines_h__
-#define included_nat_inlines_h__
-
-#include <vnet/ip/icmp46_packet.h>
-
-static_always_inline u64
-icmp_type_is_error_message (u8 icmp_type)
-{
- int bmp = 0;
- bmp |= 1 << ICMP4_destination_unreachable;
- bmp |= 1 << ICMP4_time_exceeded;
- bmp |= 1 << ICMP4_parameter_problem;
- bmp |= 1 << ICMP4_source_quench;
- bmp |= 1 << ICMP4_redirect;
- bmp |= 1 << ICMP4_alternate_host_address;
-
- return (1ULL << icmp_type) & bmp;
-}
-
-#endif /* included_nat_inlines_h__ */
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/nat/lib/ipfix_logging.c b/src/plugins/nat/lib/ipfix_logging.c
index 593fa09f7e2..f569ccd1918 100644
--- a/src/plugins/nat/lib/ipfix_logging.c
+++ b/src/plugins/nat/lib/ipfix_logging.c
@@ -22,7 +22,6 @@
#include <vlibmemory/api.h>
#include <vppinfra/atomics.h>
#include <nat/lib/ipfix_logging.h>
-#include <nat/lib/inlines.h>
vlib_node_registration_t nat_ipfix_flush_node;
nat_ipfix_logging_main_t nat_ipfix_logging_main;
diff --git a/src/plugins/nat/lib/nat_syslog.c b/src/plugins/nat/lib/nat_syslog.c
index 98777ebf280..93756a561bc 100644
--- a/src/plugins/nat/lib/nat_syslog.c
+++ b/src/plugins/nat/lib/nat_syslog.c
@@ -21,7 +21,6 @@
#include <vnet/syslog/syslog.h>
#include <nat/lib/nat_syslog.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/nat_syslog_constants.h>
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h
index 706511475cf..c3a959b0635 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed.h
@@ -31,7 +31,6 @@
#include <vlibapi/api.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
/* default number of worker handoff frame queue elements */
#define NAT_FQ_NELTS_DEFAULT 64
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
index 04e5236b7f9..8cd93f263c6 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
@@ -27,6 +27,7 @@
#include <nat/lib/log.h>
#include <nat/lib/ipfix_logging.h>
#include <nat/nat44-ed/nat44_ed.h>
+#include <vnet/ip/ip4_to_ip6.h>
always_inline void
init_ed_k (clib_bihash_kv_16_8_t *kv, u32 l_addr, u16 l_port, u32 r_addr,
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c
index e16625a2946..d1959f72ae7 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei.c
@@ -21,6 +21,7 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/ip4.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/ip/ip_table.h>
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vnet/fib/fib_table.h>
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.h b/src/plugins/nat/nat44-ei/nat44_ei.h
index b4aa0f26c0b..786fb0cfc2c 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei.h
@@ -35,7 +35,6 @@
#include <vppinfra/hash.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/nat_proto.h>
/* default number of worker handoff frame queue elements */
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
index 3b981d69986..2fbf2832d5e 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
@@ -21,6 +21,7 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/udp/udp_local.h>
#include <vnet/fib/ip4_fib.h>
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
index 5d91cb04f7c..805a6962868 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
@@ -21,6 +21,7 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/udp/udp_local.h>
#include <vnet/fib/ip4_fib.h>
diff --git a/src/plugins/nat/nat64/nat64.c b/src/plugins/nat/nat64/nat64.c
index 950eea60e5e..c59cfbbbd55 100644
--- a/src/plugins/nat/nat64/nat64.c
+++ b/src/plugins/nat/nat64/nat64.c
@@ -15,6 +15,7 @@
#include <vppinfra/crc32.h>
#include <vnet/fib/ip4_fib.h>
+#include <vnet/ip/ip4_to_ip6.h>
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vnet/ip/reass/ip6_sv_reass.h>
diff --git a/src/plugins/nat/nat64/nat64.h b/src/plugins/nat/nat64/nat64.h
index 9eb8d915390..2577880c7a4 100644
--- a/src/plugins/nat/nat64/nat64.h
+++ b/src/plugins/nat/nat64/nat64.h
@@ -30,7 +30,6 @@
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <nat/lib/lib.h>
-#include <nat/lib/inlines.h>
#include <nat/lib/nat_inlines.h>
#include <nat/nat64/nat64_db.h>
diff --git a/src/plugins/nat/nat64/nat64_db.c b/src/plugins/nat/nat64/nat64_db.c
index e4e9febcb12..6ba77c58965 100644
--- a/src/plugins/nat/nat64/nat64_db.c
+++ b/src/plugins/nat/nat64/nat64_db.c
@@ -16,7 +16,6 @@
#include <vnet/fib/fib_table.h>
#include <nat/lib/ipfix_logging.h>
#include <nat/lib/nat_syslog.h>
-#include <nat/lib/inlines.h>
#include <nat/nat64/nat64_db.h>
int
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index b4f985e5562..1e9c915ce39 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -4557,17 +4557,31 @@ vppcom_session_sendto (uint32_t session_handle, void *buffer,
if (ep->app_tlvs)
vcl_handle_ep_app_tlvs (s, ep);
- /* Session not connected/bound in vpp. Create it by 'connecting' it */
+ /* Session not connected/bound in vpp. Create it by binding it */
if (PREDICT_FALSE (s->session_state == VCL_STATE_CLOSED))
{
u32 session_index = s->session_index;
f64 timeout = vcm->cfg.session_timeout;
int rv;
- vcl_send_session_connect (wrk, s);
- rv = vppcom_wait_for_session_state_change (session_index,
- VCL_STATE_READY,
- timeout);
+ /* VPP assumes sockets are bound, not ideal, but for now
+ * connect socket, grab lcl ip:port pair and use it to bind */
+ if (s->transport.rmt_port == 0 ||
+ ip46_address_is_zero (&s->transport.lcl_ip))
+ {
+ vcl_send_session_connect (wrk, s);
+ rv = vppcom_wait_for_session_state_change (
+ session_index, VCL_STATE_READY, timeout);
+ if (rv < 0)
+ return rv;
+ vcl_send_session_disconnect (wrk, s);
+ rv = vppcom_wait_for_session_state_change (
+ session_index, VCL_STATE_DETACHED, timeout);
+ s->session_state = VCL_STATE_CLOSED;
+ }
+ vcl_send_session_listen (wrk, s);
+ rv = vppcom_wait_for_session_state_change (
+ session_index, VCL_STATE_LISTEN, timeout);
if (rv < 0)
return rv;
s = vcl_session_get (wrk, session_index);
diff --git a/src/vnet/ip/ip4_to_ip6.h b/src/vnet/ip/ip4_to_ip6.h
index d356fd5411c..3c14a59f174 100644
--- a/src/vnet/ip/ip4_to_ip6.h
+++ b/src/vnet/ip/ip4_to_ip6.h
@@ -37,6 +37,20 @@ static u8 icmp_to_icmp6_updater_pointer_table[] =
#define frag_id_4to6(id) (id)
+always_inline u64
+icmp_type_is_error_message (u8 icmp_type)
+{
+ int bmp = 0;
+ bmp |= 1 << ICMP4_destination_unreachable;
+ bmp |= 1 << ICMP4_time_exceeded;
+ bmp |= 1 << ICMP4_parameter_problem;
+ bmp |= 1 << ICMP4_source_quench;
+ bmp |= 1 << ICMP4_redirect;
+ bmp |= 1 << ICMP4_alternate_host_address;
+
+ return (1ULL << icmp_type) & bmp;
+}
+
/**
* @brief Get TCP/UDP port number or ICMP id from IPv4 packet.
*
@@ -70,9 +84,14 @@ ip4_get_port (ip4_header_t *ip, u8 sender)
* - outer ICMP header length (2*sizeof (icmp46_header_t))
* - inner IP header length
* - first 8 bytes of payload of original packet in case of ICMP error
+ *
+ * Also make sure we only attempt to parse payload as IP packet if it's
+ * an ICMP error.
*/
else if (clib_net_to_host_u16 (ip->length) >=
- 2 * sizeof (ip4_header_t) + 2 * sizeof (icmp46_header_t) + 8)
+ 2 * sizeof (ip4_header_t) + 2 * sizeof (icmp46_header_t) +
+ 8 &&
+ icmp_type_is_error_message (icmp->type))
{
ip = (ip4_header_t *) (icmp + 2);
if (PREDICT_TRUE ((ip->protocol == IP_PROTOCOL_TCP) ||
diff --git a/src/vnet/ip/ip6_to_ip4.h b/src/vnet/ip/ip6_to_ip4.h
index ebabcd0b797..931d2da0fa3 100644
--- a/src/vnet/ip/ip6_to_ip4.h
+++ b/src/vnet/ip/ip6_to_ip4.h
@@ -168,7 +168,19 @@ 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)
+ /*
+ * if there is enough data and ICMP type indicates ICMP error, then parse
+ * inner packet
+ *
+ * ICMP6 errors are:
+ * 1 - destination_unreachable
+ * 2 - packet_too_big
+ * 3 - time_exceeded
+ * 4 - parameter_problem
+ */
+ else if (clib_net_to_host_u16 (ip6->payload_length) >= 64 &&
+ icmp->type >= ICMP6_destination_unreachable &&
+ icmp->type <= ICMP6_parameter_problem)
{
u16 ip6_pay_len;
ip6_header_t *inner_ip6;