IPSEC: punt reasons; SPI=0, no-tunnel
Change-Id: If76992e283a27fa193a6865257ab3aa764066e48 Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
6416e6274d
commit
b71fa75d48
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
51
src/vnet/ipsec/ipsec_punt.c
Normal file
51
src/vnet/ipsec/ipsec_punt.c
Normal 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:
|
||||
*/
|
47
src/vnet/ipsec/ipsec_punt.h
Normal file
47
src/vnet/ipsec/ipsec_punt.h
Normal 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:
|
||||
*/
|
@ -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"))
|
||||
|
Reference in New Issue
Block a user