IPSEC: punt reasons; SPI=0, no-tunnel

Change-Id: If76992e283a27fa193a6865257ab3aa764066e48
Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
Neale Ranns
2019-04-04 12:43:36 +00:00
committed by Damjan Marion
parent 6416e6274d
commit b71fa75d48
6 changed files with 161 additions and 19 deletions

View File

@ -556,6 +556,7 @@ list(APPEND VNET_SOURCES
ipsec/ipsec_input.c
ipsec/ipsec_if.c
ipsec/ipsec_if_in.c
ipsec/ipsec_punt.c
ipsec/ipsec_sa.c
ipsec/ipsec_spd.c
ipsec/ipsec_spd_policy.c

View File

@ -22,12 +22,14 @@
#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/esp.h>
#include <vnet/ipsec/ipsec_io.h>
#include <vnet/ipsec/ipsec_punt.h>
/* Statistics (not really errors) */
#define foreach_ipsec_if_input_error \
_(RX, "good packets received") \
_(DISABLED, "ipsec packets received on disabled interface") \
_(NO_TUNNEL, "no matching tunnel")
_(NO_TUNNEL, "no matching tunnel") \
_(SPI_0, "SPI 0")
static char *ipsec_if_input_error_strings[] = {
#define _(sym,string) string,
@ -61,6 +63,46 @@ format_ipsec_if_input_trace (u8 * s, va_list * args)
return s;
}
always_inline u16
ipsec_ip4_if_no_tunnel (vlib_node_runtime_t * node,
vlib_buffer_t * b,
const esp_header_t * esp,
const ip4_header_t * ip4, u16 offset)
{
if (PREDICT_FALSE (0 == esp->spi))
{
b->error = node->errors[IPSEC_IF_INPUT_ERROR_SPI_0];
b->punt_reason =
ipsec_punt_reason[(ip4->protocol == IP_PROTOCOL_UDP ?
IPSEC_PUNT_IP4_SPI_UDP_0 : IPSEC_PUNT_IP4_SPI_0)];
}
else
{
b->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
b->punt_reason = ipsec_punt_reason[IPSEC_PUNT_IP4_NO_SUCH_TUNNEL];
}
vlib_buffer_advance (b, -offset);
return IPSEC_INPUT_NEXT_PUNT;
}
always_inline u16
ipsec_ip6_if_no_tunnel (vlib_node_runtime_t * node,
vlib_buffer_t * b,
const esp_header_t * esp, u16 offset)
{
if (PREDICT_FALSE (0 == esp->spi))
{
b->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
b->punt_reason = ipsec_punt_reason[IPSEC_PUNT_IP6_SPI_0];
}
else
{
b->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
b->punt_reason = ipsec_punt_reason[IPSEC_PUNT_IP6_NO_SUCH_TUNNEL];
}
vlib_buffer_advance (b, -offset);
return (IPSEC_INPUT_NEXT_PUNT);
}
always_inline uword
ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
@ -197,9 +239,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[0] =
ipsec_ip6_if_no_tunnel (node, b[0], esp0, buf_adv0);
n_no_tunnel++;
next[0] = IPSEC_INPUT_NEXT_DROP;
goto pkt1;
}
}
@ -225,9 +267,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[0] =
ipsec_ip4_if_no_tunnel (node, b[0], esp0, ip40, buf_adv0);
n_no_tunnel++;
next[0] = IPSEC_INPUT_NEXT_DROP;
goto pkt1;
}
}
@ -293,9 +335,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[1]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[1] =
ipsec_ip6_if_no_tunnel (node, b[1], esp1, buf_adv1);
n_no_tunnel++;
next[1] = IPSEC_INPUT_NEXT_DROP;
goto trace1;
}
}
@ -321,9 +363,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[1]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[1] =
ipsec_ip4_if_no_tunnel (node, b[1], esp1, ip41, buf_adv1);
n_no_tunnel++;
next[1] = IPSEC_INPUT_NEXT_DROP;
goto trace1;
}
}
@ -456,9 +498,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[0] =
ipsec_ip6_if_no_tunnel (node, b[0], esp0, buf_adv0);
n_no_tunnel++;
next[0] = IPSEC_INPUT_NEXT_DROP;
goto trace00;
}
}
@ -484,9 +526,9 @@ ipsec_if_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
next[0] =
ipsec_ip4_if_no_tunnel (node, b[0], esp0, ip40, buf_adv0);
n_no_tunnel++;
next[0] = IPSEC_INPUT_NEXT_DROP;
goto trace00;
}
}

View File

@ -27,6 +27,7 @@ typedef enum
} ipsec_output_next_t;
#define foreach_ipsec_input_next \
_ (PUNT, "punt-dispatch") \
_ (DROP, "error-drop")
#define _(v, s) IPSEC_INPUT_NEXT_##v,

View File

@ -0,0 +1,51 @@
/*
* esp_decrypt.c : IPSec ESP decrypt node
*
* Copyright (c) 2015 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.
*/
#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/ipsec_punt.h>
static vlib_punt_hdl_t punt_hdl;
vlib_punt_reason_t ipsec_punt_reason[IPSEC_PUNT_N_REASONS];
static clib_error_t *
ipsec_punt_init (vlib_main_t * vm)
{
clib_error_t *error;
if ((error = vlib_call_init_function (vm, punt_init)))
return (error);
punt_hdl = vlib_punt_client_register ("ipsec");
#define _(s,v) vlib_punt_reason_alloc (punt_hdl, v, \
&ipsec_punt_reason[IPSEC_PUNT_##s]);
foreach_ipsec_punt_reason
#undef _
return (error);
}
VLIB_INIT_FUNCTION (ipsec_punt_init);
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 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.
*/
#ifndef __IPSEC_PUNT_H__
#define __IPSEC_PUNT_H__
#include <vlib/vlib.h>
#define foreach_ipsec_punt_reason \
_(IP4_SPI_0, "ip4-spi-0") \
_(IP6_SPI_0, "ip6-spi-0") \
_(IP4_SPI_UDP_0, "ip4-spi-o-udp-0") \
_(IP4_NO_SUCH_TUNNEL, "ip4-no-such-tunnel") \
_(IP6_NO_SUCH_TUNNEL, "ip6-no-such-tunnel")
typedef enum ipsec_punt_reason_t_
{
#define _(s,v) IPSEC_PUNT_##s,
foreach_ipsec_punt_reason
#undef _
IPSEC_PUNT_N_REASONS,
} ipsec_punt_reason_type_t;
extern u8 *format_ipsec_punt_reason (u8 * s, va_list * args);
extern vlib_punt_reason_t ipsec_punt_reason[IPSEC_PUNT_N_REASONS];
#endif /* __IPSEC_SPD_H__ */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/

View File

@ -760,8 +760,8 @@ class TestPunt(VppTestCase):
self.assertEqual(stats, 130)
stats = self.statistics.get_counter("/net/punt")
self.assertEqual(stats[0][2]['packets'], 65)
self.assertEqual(stats[0][3]['packets'], 65)
self.assertEqual(stats[0][7]['packets'], 65)
self.assertEqual(stats[0][8]['packets'], 65)
#
# use the test CLI to test a client that punts exception
@ -788,8 +788,8 @@ class TestPunt(VppTestCase):
self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
stats = self.statistics.get_counter("/net/punt")
self.assertEqual(stats[0][2]['packets'], 2*65)
self.assertEqual(stats[0][3]['packets'], 2*65)
self.assertEqual(stats[0][7]['packets'], 2*65)
self.assertEqual(stats[0][8]['packets'], 2*65)
#
# add another registration for the same reason to send packets
@ -835,8 +835,8 @@ class TestPunt(VppTestCase):
self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
stats = self.statistics.get_counter("/net/punt")
self.assertEqual(stats[0][2]['packets'], 3*65)
self.assertEqual(stats[0][3]['packets'], 3*65)
self.assertEqual(stats[0][7]['packets'], 3*65)
self.assertEqual(stats[0][8]['packets'], 3*65)
self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
self.logger.info(self.vapi.cli("show punt client"))