Compare commits

...

14 Commits

Author SHA1 Message Date
Andrew Yourtchenko
7911f29c51 misc: VPP 22.02 Release Notes
type: docs
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Change-Id: I32291160f0d22a804929d0a040472ff952f02544
Signed-off-by: Maciek Konstantynowicz <mkonstan@cisco.com>
2022-02-23 13:02:41 +00:00
Dmitry Valter
d3ba176774 fib: fix mpls db label overflow
mpls fib DB size was 2^20 instead of intended 2^21.
Therefore large mpls labels caused DB to overflow and write
to other tables or some random objects. Or crash with ASAN.
Sometimes.

Type: fix

Signed-off-by: Dmitry Valter <d-valter@yandex-team.ru>
Change-Id: I6db65680037a266fe47e8213464a0c16de63c06c
(cherry picked from commit cf2595dfc0b446dd9bd5311d972cfb53b5567df8)
2022-02-23 10:16:51 +00:00
Artem Glazychev
8cd5a1a1e0 vxlan: add l2 mode test
Type: improvement

Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
Change-Id: I214f6fb5b63d97ca4afe3b10fd2d3e3410b5a6e4
2022-02-22 18:05:04 +00:00
Artem Glazychev
83945776cb vnet: add set_max_frame_size callbacks for several interfaces
This is required after distinguishing between max_frame_size and MTU

Type: fix
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
Change-Id: Ie642bee4e30ca76903bb8be5eeb6914c2c09bf35
(cherry picked from commit 66593a6a63fe30ed4b8bed96844244d78274e8f2)
2022-02-22 16:50:14 +00:00
Florin Coras
201830e1b9 lisp: fix ip and udp checksum computation
Type: fix
Fixes: 6fdcc3d

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I820c505482801ff2ab8dac41a0016bb3a741a4ee
(cherry picked from commit d85fe1a2164daf3cb23f48e6b9fd1ec2d97c87bc)
2022-02-22 16:21:52 +00:00
Ed Warnicke
47617a98c8 vxlan: crash on assigning IP address to interface
Revert "vxlan: crash on configuring vxlan tunnel on l3 mode"

This reverts commit b8de7d43e4955bb4025cd0e0e7390279841b6d7d.

Reason for revert: VPP-2014

Type: fix
Fixes: b8de7d43e4955bb4025cd0e0e7390279841b6d7d

Change-Id: Ic4d10f28985ee10e0550a1bbfd465ada915e4aa6
Signed-off-by: Ed Warnicke <hagbard@gmail.com>
2022-02-18 19:52:06 +00:00
akolechk
53ecd05962 dpdk: enable scatter on Rx for net/ena
Type: fix

Since commit e2a6d08bef
DPDK started advertising scattered Rx feature for elastic network adapters. Thus, dpdk
plugin doesn't have to disable it for ENA by default anymore

Signed-off-by: akolechk <akolechk@cisco.com>
Change-Id: I2d4f429be992e3c4edcc0c3adf8c55f3d5381631
2022-02-17 12:34:17 +00:00
Paul Atkins
7b35695c23 ipfix-export: pass ipv4 addr to format fn for show
When the ipfix address was changed to be an ip_address instead of
an ip4_address the output when creating an exporter via the cli
should have been modified to take the address of the v4 part of
the addr.

Type: fix
Signed-off-by: Paul Atkins <patkins@graphiant.com>
Change-Id: I141456cd9092c861a4c4aefba4035dbde23efcd6
(cherry picked from commit bf9918a7e0c6bf116b90780cbc2c111ca7995399)
2022-02-16 11:30:34 +00:00
Gabriel Oginski
9d2db2eb2e wireguard: fix passing argument
Fixed coverity-issue CID 248456.
Originally passing argument of type "uint64_t *" to function:
"memcopy_s_inline".
This patch fixes the problem by changing type of passing argument and
make a portable assumption.

Type: fix

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I17e4583a05ea1263e4d8a4acc9949454e5fd92c0
(cherry picked from commit ffd9057493ba75d157d8fd316f4978b64a6efb30)
2022-01-25 11:36:28 +00:00
Gabriel Oginski
e3d36d18c1 dpdk-cryptodev: add support chacha20-poly1305
Originally cryptodev doesn't support chacha20-poly1305 with aad length
0.

This patch add support in cryptodev for chacha20-poly1305 with aad
length 0. This length is using in Wireguard.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I0608920bb557d7d071e7f9f37c80cf50bad81dcc
2022-01-25 11:32:52 +01:00
Gabriel Oginski
0fb3a93a03 wireguard: add async mode for decryption packets
Originally wireguard doesn't support async mode for decryption packets.

This patch add async mode for decryption in wireguard.
In addition, it contains some performance improvement such as
prefetching packet header and reducing the number of current time
function calls.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: Ieba6ae0078f3ff140c05b517891afb57232b3b7d
(cherry picked from commit 77e69ae2d172dce74f4da4cae52bb63e28daa3ae)
2022-01-25 11:25:16 +01:00
Gabriel Oginski
65c070f9da wireguard: add async mode for encryption packets
Originally wireguard doesn't support async mode for encryption packets.

This patch add async mode for encryption in wireguard and also adds
support chacha20-poly1305 algorithm in cryptodev for async handler.
In addition it contains new command line to activate async mode for wireguard:
  set wireguard async mode on|off

and also add new command to check active mode for wireguard:
  show wireguard mode

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I141d48b42ee8dbff0112b8542ab5205268089da6
(cherry picked from commit 492d7790ff26c569bee81617c662363652891140)
2022-01-25 11:04:23 +01:00
Gabriel Oginski
ab2478ceed wireguard: add burst mode
Originally wireguard does packet by packet encryption and decryption.

This patch adds burst mode for encryption and decryption packets. In
addition, it contains some performance improvement such as prefetching
packet header and reducing the number of current time function calls.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I04c7daa9b6dc56cd15c789661a64ec642b35aa3f
(cherry picked from commit 8ca08496a43e8d98fe2d4130d760c6fb600d0a93)
2022-01-24 10:01:42 +00:00
Andrew Yourtchenko
93e5bea2d3 misc: Initial changes for stable/2202 branch
Change-Id: I23e72a788d6f382601945986c8cb8cfc3bb9da8e
Type: docs
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2022-01-19 13:48:39 +01:00
28 changed files with 2190 additions and 322 deletions

View File

@ -2,3 +2,4 @@
host=gerrit.fd.io
port=29418
project=vpp
defaultbranch=stable/2202

View File

@ -6,6 +6,7 @@ Release notes
.. toctree::
:maxdepth: 2
v22.02
v21.10.1
v21.10
v21.06

File diff suppressed because it is too large Load Diff

View File

@ -51,12 +51,19 @@ prepare_aead_xform (struct rte_crypto_sym_xform *xform,
xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
xform->next = 0;
if (key->alg != VNET_CRYPTO_ALG_AES_128_GCM &&
key->alg != VNET_CRYPTO_ALG_AES_192_GCM &&
key->alg != VNET_CRYPTO_ALG_AES_256_GCM)
if (key->alg == VNET_CRYPTO_ALG_AES_128_GCM ||
key->alg == VNET_CRYPTO_ALG_AES_192_GCM ||
key->alg == VNET_CRYPTO_ALG_AES_256_GCM)
{
aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
}
else if (key->alg == VNET_CRYPTO_ALG_CHACHA20_POLY1305)
{
aead_xform->algo = RTE_CRYPTO_AEAD_CHACHA20_POLY1305;
}
else
return -1;
aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
aead_xform->op = (op_type == CRYPTODEV_OP_TYPE_ENCRYPT) ?
RTE_CRYPTO_AEAD_OP_ENCRYPT : RTE_CRYPTO_AEAD_OP_DECRYPT;
aead_xform->aad_length = aad_len;

View File

@ -43,7 +43,10 @@
_ (AES_192_GCM, AEAD, AES_GCM, 12, 16, 8, 24) \
_ (AES_192_GCM, AEAD, AES_GCM, 12, 16, 12, 24) \
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 8, 32) \
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 12, 32)
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 12, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 0, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 8, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 12, 32)
/**
* crypto (alg, cryptodev_alg, key_size), hash (alg, digest-size)

View File

@ -458,6 +458,13 @@ cryptodev_frame_dequeue (vlib_main_t *vm, u32 *nb_elts_processed,
return frame;
}
static_always_inline int
cryptodev_enqueue_aead_aad_0_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_frame_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT,
0);
}
static_always_inline int
cryptodev_enqueue_aead_aad_8_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
@ -473,6 +480,13 @@ cryptodev_enqueue_aead_aad_12_enc (vlib_main_t *vm,
12);
}
static_always_inline int
cryptodev_enqueue_aead_aad_0_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_frame_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_DECRYPT,
0);
}
static_always_inline int
cryptodev_enqueue_aead_aad_8_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)

View File

@ -349,7 +349,7 @@ cryptodev_raw_aead_enqueue (vlib_main_t *vm, vnet_crypto_async_frame_t *frame,
if (aad_len == 8)
*(u64 *) (cet->aad_buf + aad_offset) = *(u64 *) fe->aad;
else
else if (aad_len != 0)
{
/* aad_len == 12 */
*(u64 *) (cet->aad_buf + aad_offset) = *(u64 *) fe->aad;
@ -591,6 +591,13 @@ end_deq:
return frame_ret;
}
static_always_inline int
cryptodev_raw_enq_aead_aad_0_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT, 0);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_8_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
@ -604,6 +611,13 @@ cryptodev_raw_enq_aead_aad_12_enc (vlib_main_t *vm,
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT, 12);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_0_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_DECRYPT, 0);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_8_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)

View File

@ -108,7 +108,6 @@ static dpdk_driver_t dpdk_drivers[] = {
.drivers = DPDK_DRIVERS ({ "net_ena", "AWS ENA VF" }),
.interface_name_prefix = "VirtualFunctionEthernet",
.enable_rxq_int = 1,
.disable_rx_scatter = 1,
},
{
.drivers = DPDK_DRIVERS ({ "net_vmxnet3", "VMware VMXNET3" }),

View File

@ -92,7 +92,6 @@ VLIB_NODE_FN (lisp_tunnel_output)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
{
u32 n_left_from, next_index, *from, *to_next;
lisp_gpe_main_t *lgm = &lisp_gpe_main;
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
@ -111,7 +110,6 @@ VLIB_NODE_FN (lisp_tunnel_output)
const ip_adjacency_t *adj0;
const dpo_id_t *dpo0;
vlib_buffer_t *b0;
u8 is_v4_0;
bi0 = from[0];
to_next[0] = bi0;
@ -123,11 +121,6 @@ VLIB_NODE_FN (lisp_tunnel_output)
b0 = vlib_get_buffer (vm, bi0);
b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
/* Fixup the checksum and len fields in the LISP tunnel encap
* that was applied at the midchain node */
is_v4_0 = is_v4_packet (vlib_buffer_get_current (b0));
ip_udp_fixup_one (lgm->vlib_main, b0, is_v4_0);
/* Follow the DPO on which the midchain is stacked */
adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
adj0 = adj_get (adj_index0);

View File

@ -50,6 +50,14 @@ memif_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
return 0;
}
static clib_error_t *
memif_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi,
u32 flags)
{
/* nothing for now */
return 0;
}
static void
memif_queue_intfd_close (memif_queue_t * mq)
{
@ -1017,6 +1025,7 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
eir.dev_instance = mif->dev_instance;
eir.address = args->hw_addr;
eir.cb.flag_change = memif_eth_flag_change;
eir.cb.set_max_frame_size = memif_eth_set_max_frame_size;
mif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
}
else if (mif->mode == MEMIF_INTERFACE_MODE_IP)

View File

@ -195,6 +195,17 @@ define wireguard_peers_details {
vl_api_wireguard_peer_t peer;
};
/** \brief Wireguard Set Async mode
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param async_enable - wireguard async mode on or off
*/
autoreply define wg_set_async_mode {
u32 client_index;
u32 context;
bool async_enable;
};
/*
* Local Variables:
* eval: (c-set-style "gnu")

View File

@ -16,6 +16,7 @@
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <vnet/crypto/crypto.h>
#include <wireguard/wireguard_send.h>
#include <wireguard/wireguard_key.h>
@ -23,6 +24,40 @@
#include <wireguard/wireguard.h>
wg_main_t wg_main;
wg_async_post_next_t wg_encrypt_async_next;
wg_async_post_next_t wg_decrypt_async_next;
void
wg_set_async_mode (u32 is_enabled)
{
vnet_crypto_request_async_mode (is_enabled);
if (is_enabled)
wg_op_mode_set_ASYNC ();
else
wg_op_mode_unset_ASYNC ();
}
static void
wireguard_register_post_node (vlib_main_t *vm)
{
wg_async_post_next_t *eit;
wg_async_post_next_t *dit;
eit = &wg_encrypt_async_next;
dit = &wg_decrypt_async_next;
eit->wg4_post_next =
vnet_crypto_register_post_node (vm, "wg4-output-tun-post-node");
eit->wg6_post_next =
vnet_crypto_register_post_node (vm, "wg6-output-tun-post-node");
dit->wg4_post_next =
vnet_crypto_register_post_node (vm, "wg4-input-post-node");
dit->wg6_post_next =
vnet_crypto_register_post_node (vm, "wg6-input-post-node");
}
static clib_error_t *
wg_init (vlib_main_t * vm)
@ -44,6 +79,8 @@ wg_init (vlib_main_t * vm)
CLIB_CACHE_LINE_BYTES);
wg_timer_wheel_init ();
wireguard_register_post_node (vm);
wmp->op_mode_flags = 0;
return (NULL);
}

View File

@ -28,6 +28,9 @@ extern vlib_node_registration_t wg6_output_tun_node;
typedef struct wg_per_thread_data_t_
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
vnet_crypto_op_t *crypto_ops;
vnet_crypto_async_frame_t **async_frames;
u8 data[WG_DEFAULT_DATA_SIZE];
} wg_per_thread_data_t;
typedef struct
@ -48,12 +51,70 @@ typedef struct
u8 feature_init;
tw_timer_wheel_16t_2w_512sl_t timer_wheel;
/* operation mode flags (e.g. async) */
u8 op_mode_flags;
} wg_main_t;
typedef struct
{
/* wg post node index for async crypto */
u32 wg4_post_next;
u32 wg6_post_next;
} wg_async_post_next_t;
extern wg_async_post_next_t wg_encrypt_async_next;
extern wg_async_post_next_t wg_decrypt_async_next;
extern wg_main_t wg_main;
/**
* Wireguard operation mode
**/
#define foreach_wg_op_mode_flags _ (0, ASYNC, "async")
/**
* Helper function to set/unset and check op modes
**/
typedef enum wg_op_mode_flags_t_
{
#define _(v, f, s) WG_OP_MODE_FLAG_##f = 1 << v,
foreach_wg_op_mode_flags
#undef _
} __clib_packed wg_op_mode_flags_t;
#define _(a, v, s) \
always_inline int wg_op_mode_set_##v (void) \
{ \
return (wg_main.op_mode_flags |= WG_OP_MODE_FLAG_##v); \
} \
always_inline int wg_op_mode_unset_##v (void) \
{ \
return (wg_main.op_mode_flags &= ~WG_OP_MODE_FLAG_##v); \
} \
always_inline int wg_op_mode_is_set_##v (void) \
{ \
return (wg_main.op_mode_flags & WG_OP_MODE_FLAG_##v); \
}
foreach_wg_op_mode_flags
#undef _
typedef struct
{
u8 __pad[22];
u16 next_index;
} wg_post_data_t;
STATIC_ASSERT (sizeof (wg_post_data_t) <=
STRUCT_SIZE_OF (vnet_buffer_opaque_t, unused),
"Custom meta-data too large for vnet_buffer_opaque_t");
#define wg_post_data(b) \
((wg_post_data_t *) ((u8 *) ((b)->opaque) + \
STRUCT_OFFSET_OF (vnet_buffer_opaque_t, unused)))
#define WG_START_EVENT 1
void wg_feature_init (wg_main_t * wmp);
void wg_set_async_mode (u32 is_enabled);
#endif /* __included_wg_h__ */

View File

@ -365,6 +365,18 @@ wg_api_peer_event (index_t peeri, wg_peer_flags flags)
};
}
static void
vl_api_wg_set_async_mode_t_handler (vl_api_wg_set_async_mode_t *mp)
{
wg_main_t *wmp = &wg_main;
vl_api_wg_set_async_mode_reply_t *rmp;
int rv = 0;
wg_set_async_mode (mp->async_enable);
REPLY_MACRO (VL_API_WG_SET_ASYNC_MODE_REPLY);
}
/* set tup the API message handling tables */
#include <wireguard/wireguard.api.c>
static clib_error_t *

View File

@ -356,6 +356,61 @@ VLIB_CLI_COMMAND (wg_show_itfs_command, static) =
.short_help = "show wireguard",
.function = wg_show_if_command_fn,
};
static clib_error_t *
wg_set_async_mode_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
int async_enable = 0;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "on"))
async_enable = 1;
else if (unformat (line_input, "off"))
async_enable = 0;
else
return (clib_error_return (0, "unknown input '%U'",
format_unformat_error, line_input));
}
wg_set_async_mode (async_enable);
unformat_free (line_input);
return (NULL);
}
VLIB_CLI_COMMAND (wg_set_async_mode_command, static) = {
.path = "set wireguard async mode",
.short_help = "set wireguard async mode on|off",
.function = wg_set_async_mode_command_fn,
};
static clib_error_t *
wg_show_mode_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
vlib_cli_output (vm, "Wireguard mode");
#define _(v, f, s) \
vlib_cli_output (vm, "\t%s: %s", s, \
(wg_op_mode_is_set_##f () ? "enabled" : "disabled"));
foreach_wg_op_mode_flags
#undef _
return (NULL);
}
VLIB_CLI_COMMAND (wg_show_modemode_command, static) = {
.path = "show wireguard mode",
.short_help = "show wireguard mode",
.function = wg_show_mode_command_fn,
};
/* *INDENT-ON* */
/*

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ static uint32_t noise_remote_handshake_index_get (noise_remote_t *);
static void noise_remote_handshake_index_drop (noise_remote_t *);
static uint64_t noise_counter_send (noise_counter_t *);
static bool noise_counter_recv (noise_counter_t *, uint64_t);
bool noise_counter_recv (noise_counter_t *, uint64_t);
static void noise_kdf (uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
size_t, size_t, size_t, size_t,
@ -407,6 +407,8 @@ noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r)
/* Now we need to add_new_keypair */
clib_rwlock_writer_lock (&r->r_keypair_lock);
/* Activate barrier to synchronization keys between threads */
vlib_worker_thread_barrier_sync (vm);
next = r->r_next;
current = r->r_current;
previous = r->r_previous;
@ -438,6 +440,7 @@ noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r)
r->r_next = noise_remote_keypair_allocate (r);
*r->r_next = kp;
}
vlib_worker_thread_barrier_release (vm);
clib_rwlock_writer_unlock (&r->r_keypair_lock);
secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
@ -591,88 +594,6 @@ error:
return ret;
}
enum noise_state_crypt
noise_remote_decrypt (vlib_main_t * vm, noise_remote_t * r, uint32_t r_idx,
uint64_t nonce, uint8_t * src, size_t srclen,
uint8_t * dst)
{
noise_keypair_t *kp;
enum noise_state_crypt ret = SC_FAILED;
if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
{
kp = r->r_current;
}
else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
{
kp = r->r_previous;
}
else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
{
kp = r->r_next;
}
else
{
goto error;
}
/* We confirm that our values are within our tolerances. These values
* are the same as the encrypt routine.
*
* kp_ctr isn't locked here, we're happy to accept a racy read. */
if (wg_birthdate_has_expired (kp->kp_birthdate, REJECT_AFTER_TIME) ||
kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES)
goto error;
/* Decrypt, then validate the counter. We don't want to validate the
* counter before decrypting as we do not know the message is authentic
* prior to decryption. */
if (!chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, nonce,
VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC,
kp->kp_recv_index))
goto error;
if (!noise_counter_recv (&kp->kp_ctr, nonce))
goto error;
/* If we've received the handshake confirming data packet then move the
* next keypair into current. If we do slide the next keypair in, then
* we skip the REKEY_AFTER_TIME_RECV check. This is safe to do as a
* data packet can't confirm a session that we are an INITIATOR of. */
if (kp == r->r_next)
{
clib_rwlock_writer_lock (&r->r_keypair_lock);
if (kp == r->r_next && kp->kp_local_index == r_idx)
{
noise_remote_keypair_free (vm, r, &r->r_previous);
r->r_previous = r->r_current;
r->r_current = r->r_next;
r->r_next = NULL;
ret = SC_CONN_RESET;
clib_rwlock_writer_unlock (&r->r_keypair_lock);
goto error;
}
clib_rwlock_writer_unlock (&r->r_keypair_lock);
}
/* Similar to when we encrypt, we want to notify the caller when we
* are approaching our tolerances. We notify if:
* - we're the initiator and the current keypair is older than
* REKEY_AFTER_TIME_RECV seconds. */
ret = SC_KEEP_KEY_FRESH;
kp = r->r_current;
if (kp != NULL &&
kp->kp_valid &&
kp->kp_is_initiator &&
wg_birthdate_has_expired (kp->kp_birthdate, REKEY_AFTER_TIME_RECV))
goto error;
ret = SC_OK;
error:
return ret;
}
/* Private functions - these should not be called outside this file under any
* circumstances. */
static noise_keypair_t *
@ -683,21 +604,6 @@ noise_remote_keypair_allocate (noise_remote_t * r)
return kp;
}
static void
noise_remote_keypair_free (vlib_main_t * vm, noise_remote_t * r,
noise_keypair_t ** kp)
{
noise_local_t *local = noise_local_get (r->r_local_idx);
struct noise_upcall *u = &local->l_upcall;
if (*kp)
{
u->u_index_drop ((*kp)->kp_local_index);
vnet_crypto_key_del (vm, (*kp)->kp_send_index);
vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
clib_mem_free (*kp);
}
}
static uint32_t
noise_remote_handshake_index_get (noise_remote_t * r)
{
@ -716,55 +622,6 @@ noise_remote_handshake_index_drop (noise_remote_t * r)
u->u_index_drop (hs->hs_local_index);
}
static uint64_t
noise_counter_send (noise_counter_t * ctr)
{
uint64_t ret;
ret = ctr->c_send++;
return ret;
}
static bool
noise_counter_recv (noise_counter_t * ctr, uint64_t recv)
{
uint64_t i, top, index_recv, index_ctr;
unsigned long bit;
bool ret = false;
/* Check that the recv counter is valid */
if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
goto error;
/* If the packet is out of the window, invalid */
if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
goto error;
/* If the new counter is ahead of the current counter, we'll need to
* zero out the bitmap that has previously been used */
index_recv = recv / COUNTER_BITS;
index_ctr = ctr->c_recv / COUNTER_BITS;
if (recv > ctr->c_recv)
{
top = clib_min (index_recv - index_ctr, COUNTER_NUM);
for (i = 1; i <= top; i++)
ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
ctr->c_recv = recv;
}
index_recv %= COUNTER_NUM;
bit = 1ul << (recv % COUNTER_BITS);
if (ctr->c_backtrack[index_recv] & bit)
goto error;
ctr->c_backtrack[index_recv] |= bit;
ret = true;
error:
return ret;
}
static void
noise_kdf (uint8_t * a, uint8_t * b, uint8_t * c, const uint8_t * x,
size_t a_len, size_t b_len, size_t c_len, size_t x_len,

View File

@ -136,6 +136,14 @@ noise_local_get (uint32_t locali)
return (pool_elt_at_index (noise_local_pool, locali));
}
static_always_inline uint64_t
noise_counter_send (noise_counter_t *ctr)
{
uint64_t ret;
ret = ctr->c_send++;
return ret;
}
void noise_local_init (noise_local_t *, struct noise_upcall *);
bool noise_local_set_private (noise_local_t *,
const uint8_t[NOISE_PUBLIC_KEY_LEN]);
@ -187,12 +195,83 @@ noise_remote_encrypt (vlib_main_t * vm, noise_remote_t *,
uint32_t * r_idx,
uint64_t * nonce,
uint8_t * src, size_t srclen, uint8_t * dst);
enum noise_state_crypt
noise_remote_decrypt (vlib_main_t * vm, noise_remote_t *,
uint32_t r_idx,
uint64_t nonce,
uint8_t * src, size_t srclen, uint8_t * dst);
static_always_inline noise_keypair_t *
wg_get_active_keypair (noise_remote_t *r, uint32_t r_idx)
{
if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
{
return r->r_current;
}
else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
{
return r->r_previous;
}
else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
{
return r->r_next;
}
else
{
return NULL;
}
}
inline bool
noise_counter_recv (noise_counter_t *ctr, uint64_t recv)
{
uint64_t i, top, index_recv, index_ctr;
unsigned long bit;
bool ret = false;
/* Check that the recv counter is valid */
if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
goto error;
/* If the packet is out of the window, invalid */
if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
goto error;
/* If the new counter is ahead of the current counter, we'll need to
* zero out the bitmap that has previously been used */
index_recv = recv / COUNTER_BITS;
index_ctr = ctr->c_recv / COUNTER_BITS;
if (recv > ctr->c_recv)
{
top = clib_min (index_recv - index_ctr, COUNTER_NUM);
for (i = 1; i <= top; i++)
ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
ctr->c_recv = recv;
}
index_recv %= COUNTER_NUM;
bit = 1ul << (recv % COUNTER_BITS);
if (ctr->c_backtrack[index_recv] & bit)
goto error;
ctr->c_backtrack[index_recv] |= bit;
ret = true;
error:
return ret;
}
static_always_inline void
noise_remote_keypair_free (vlib_main_t *vm, noise_remote_t *r,
noise_keypair_t **kp)
{
noise_local_t *local = noise_local_get (r->r_local_idx);
struct noise_upcall *u = &local->l_upcall;
if (*kp)
{
u->u_index_drop ((*kp)->kp_local_index);
vnet_crypto_key_del (vm, (*kp)->kp_send_index);
vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
clib_mem_free (*kp);
}
}
#endif /* __included_wg_noise_h__ */

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,13 @@ get_random_u32_max (u32 max)
return random_u32 (&seed) % max;
}
static u32
get_random_u32_max_opt (u32 max, f64 time)
{
u32 seed = (u32) (time * 1e6);
return random_u32 (&seed) % max;
}
static void
stop_timer (wg_peer_t * peer, u32 timer_id)
{
@ -66,7 +73,7 @@ start_timer_thread_fn (void *arg)
return 0;
}
static void
static_always_inline void
start_timer_from_mt (u32 peer_idx, u32 timer_id, u32 interval_ticks)
{
wg_timers_args a = {
@ -197,8 +204,8 @@ wg_expired_zero_key_material (vlib_main_t * vm, wg_peer_t * peer)
}
}
void
wg_timers_any_authenticated_packet_traversal (wg_peer_t * peer)
inline void
wg_timers_any_authenticated_packet_traversal (wg_peer_t *peer)
{
if (peer->persistent_keepalive_interval)
{
@ -214,6 +221,12 @@ wg_timers_any_authenticated_packet_sent (wg_peer_t * peer)
peer->last_sent_packet = vlib_time_now (vlib_get_main ());
}
inline void
wg_timers_any_authenticated_packet_sent_opt (wg_peer_t *peer, f64 time)
{
peer->last_sent_packet = time;
}
void
wg_timers_handshake_initiated (wg_peer_t * peer)
{
@ -246,6 +259,17 @@ wg_timers_data_sent (wg_peer_t * peer)
peer->new_handshake_interval_tick);
}
inline void
wg_timers_data_sent_opt (wg_peer_t *peer, f64 time)
{
peer->new_handshake_interval_tick =
(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * WHZ +
get_random_u32_max_opt (REKEY_TIMEOUT_JITTER, time);
start_timer_from_mt (peer - wg_peer_pool, WG_TIMER_NEW_HANDSHAKE,
peer->new_handshake_interval_tick);
}
/* Should be called after an authenticated data packet is received. */
void
wg_timers_data_received (wg_peer_t * peer)
@ -275,6 +299,12 @@ wg_timers_any_authenticated_packet_received (wg_peer_t * peer)
peer->last_received_packet = vlib_time_now (vlib_get_main ());
}
inline void
wg_timers_any_authenticated_packet_received_opt (wg_peer_t *peer, f64 time)
{
peer->last_received_packet = time;
}
static vlib_node_registration_t wg_timer_mngr_node;
static void

View File

@ -41,9 +41,13 @@ typedef struct wg_peer wg_peer_t;
void wg_timer_wheel_init ();
void wg_timers_stop (wg_peer_t * peer);
void wg_timers_data_sent (wg_peer_t * peer);
void wg_timers_data_sent_opt (wg_peer_t *peer, f64 time);
void wg_timers_data_received (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_sent (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_sent_opt (wg_peer_t *peer, f64 time);
void wg_timers_any_authenticated_packet_received (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_received_opt (wg_peer_t *peer,
f64 time);
void wg_timers_handshake_initiated (wg_peer_t * peer);
void wg_timers_handshake_complete (wg_peer_t * peer);
void wg_timers_session_derived (wg_peer_t * peer);
@ -57,6 +61,13 @@ wg_birthdate_has_expired (f64 birthday_seconds, f64 expiration_seconds)
return (birthday_seconds + expiration_seconds) < now_seconds;
}
static_always_inline bool
wg_birthdate_has_expired_opt (f64 birthday_seconds, f64 expiration_seconds,
f64 time)
{
return (birthday_seconds + expiration_seconds) < time;
}
#endif /* __included_wg_timer_h__ */
/*

View File

@ -82,15 +82,16 @@ typedef enum
/** async crypto **/
/* CRYPTO_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES, TAG_LEN, AAD_LEN */
#define foreach_crypto_aead_async_alg \
_(AES_128_GCM, "aes-128-gcm-aad8", 16, 16, 8) \
_(AES_128_GCM, "aes-128-gcm-aad12", 16, 16, 12) \
_(AES_192_GCM, "aes-192-gcm-aad8", 24, 16, 8) \
_(AES_192_GCM, "aes-192-gcm-aad12", 24, 16, 12) \
_(AES_256_GCM, "aes-256-gcm-aad8", 32, 16, 8) \
_(AES_256_GCM, "aes-256-gcm-aad12", 32, 16, 12) \
_(CHACHA20_POLY1305, "chacha20-poly1305-aad8", 32, 16, 8) \
_(CHACHA20_POLY1305, "chacha20-poly1305-aad12", 32, 16, 12)
#define foreach_crypto_aead_async_alg \
_ (AES_128_GCM, "aes-128-gcm-aad8", 16, 16, 8) \
_ (AES_128_GCM, "aes-128-gcm-aad12", 16, 16, 12) \
_ (AES_192_GCM, "aes-192-gcm-aad8", 24, 16, 8) \
_ (AES_192_GCM, "aes-192-gcm-aad12", 24, 16, 12) \
_ (AES_256_GCM, "aes-256-gcm-aad8", 32, 16, 8) \
_ (AES_256_GCM, "aes-256-gcm-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad8", 32, 16, 8) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305", 32, 16, 0)
/* CRYPTO_ID, INTEG_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES, DIGEST_LEN */
#define foreach_crypto_link_async_alg \

View File

@ -77,6 +77,14 @@ virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
return 0;
}
static clib_error_t *
virtio_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi,
u32 frame_size)
{
/* nothing for now */
return 0;
}
#define TAP_MAX_INSTANCE 1024
static void
@ -650,6 +658,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
eir.dev_instance = vif->dev_instance;
eir.address = vif->mac_addr;
eir.cb.flag_change = virtio_eth_flag_change;
eir.cb.set_max_frame_size = virtio_eth_set_max_frame_size;
vif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
}
else

View File

@ -31,7 +31,7 @@
* Type exposure is to allow the DP fast/inlined access
*/
#define MPLS_FIB_KEY_SIZE 21
#define MPLS_FIB_DB_SIZE (1 << (MPLS_FIB_KEY_SIZE-1))
#define MPLS_FIB_DB_SIZE (1 << MPLS_FIB_KEY_SIZE)
/**
* There are no options for controlling the MPLS flow hash,

View File

@ -843,9 +843,10 @@ set_ipfix_exporter_command_fn (vlib_main_t * vm,
"fib index %d, path MTU %u, "
"template resend interval %us, "
"udp checksum %s",
format_ip4_address, exp->ipfix_collector,
format_ip4_address, exp->src_address, fib_index, path_mtu,
template_interval, udp_checksum ? "enabled" : "disabled");
format_ip4_address, &exp->ipfix_collector.ip.ip4,
format_ip4_address, &exp->src_address.ip.ip4, fib_index,
path_mtu, template_interval,
udp_checksum ? "enabled" : "disabled");
else
vlib_cli_output (vm, "IPFIX Collector is disabled");

View File

@ -52,6 +52,14 @@ vxlan_eth_flag_change (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
return 0;
}
static clib_error_t *
vxlan_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw,
u32 frame_size)
{
/* nothing for now */
return 0;
}
static u8 *
format_decap_next (u8 * s, va_list * args)
{
@ -82,8 +90,6 @@ format_vxlan_tunnel (u8 * s, va_list * args)
if (PREDICT_FALSE (t->decap_next_index != VXLAN_INPUT_NEXT_L2_INPUT))
s = format (s, "decap-next-%U ", format_decap_next, t->decap_next_index);
s = format (s, "l3 %u ", t->is_l3);
if (PREDICT_FALSE (ip46_address_is_multicast (&t->dst)))
s = format (s, "mcast-sw-if-idx %d ", t->mcast_sw_if_index);
@ -247,8 +253,7 @@ const static fib_node_vft_t vxlan_vft = {
_ (src) \
_ (dst) \
_ (src_port) \
_ (dst_port) \
_ (is_l3)
_ (dst_port)
static void
vxlan_rewrite (vxlan_tunnel_t * t, bool is_ip6)
@ -451,7 +456,7 @@ int vnet_vxlan_add_del_tunnel
t->user_instance = user_instance; /* name */
t->flow_index = ~0;
if (a->is_l3 == 0)
if (a->is_l3)
t->hw_if_index =
vnet_register_interface (vnm, vxlan_device_class.index, dev_instance,
vxlan_hw_class.index, dev_instance);
@ -470,6 +475,7 @@ int vnet_vxlan_add_del_tunnel
eir.dev_instance = dev_instance;
eir.address = hw_addr;
eir.cb.flag_change = vxlan_eth_flag_change;
eir.cb.set_max_frame_size = vxlan_eth_set_max_frame_size;
t->hw_if_index = vnet_eth_register_interface (vnm, &eir);
}
@ -504,7 +510,7 @@ int vnet_vxlan_add_del_tunnel
if (add_failed)
{
if (a->is_l3 == 0)
if (a->is_l3)
vnet_delete_hw_interface (vnm, t->hw_if_index);
else
ethernet_delete_interface (vnm, t->hw_if_index);
@ -657,7 +663,8 @@ int vnet_vxlan_add_del_tunnel
mcast_shared_remove (&t->dst);
}
if (t->is_l3 == 0)
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, t->hw_if_index);
if (hw->dev_class_index == vxlan_device_class.index)
vnet_delete_hw_interface (vnm, t->hw_if_index);
else
ethernet_delete_interface (vnm, t->hw_if_index);
@ -844,6 +851,7 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm,
vnet_vxlan_add_del_tunnel_args_t a = { .is_add = is_add,
.is_ip6 = ipv6_set,
.is_l3 = is_l3,
.instance = instance,
#define _(x) .x = x,
foreach_copy_field

View File

@ -135,7 +135,6 @@ typedef struct
u32 user_instance; /* Instance name being shown to user */
VNET_DECLARE_REWRITE;
u8 is_l3;
} vxlan_tunnel_t;
#define foreach_vxlan_input_next \

View File

@ -7,6 +7,7 @@ from framework import VppTestCase, VppTestRunner
from template_bd import BridgeDomain
from scapy.layers.l2 import Ether
from scapy.layers.l2 import ARP
from scapy.packet import Raw, bind_layers
from scapy.layers.inet import IP, UDP
from scapy.layers.vxlan import VXLAN
@ -15,6 +16,7 @@ import util
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_vxlan_tunnel import VppVxlanTunnel
from vpp_ip import INVALID_INDEX
from vpp_neighbor import VppNeighbor
class TestVxlan(BridgeDomain, VppTestCase):
@ -417,5 +419,62 @@ class TestVxlan2(VppTestCase):
rx = self.send_and_assert_no_replies(self.pg1, [p])
class TestVxlanL2Mode(VppTestCase):
""" VXLAN Test Case """
def setUp(self):
super(TestVxlanL2Mode, self).setUp()
# Create 2 pg interfaces.
self.create_pg_interfaces(range(2))
for pg in self.pg_interfaces:
pg.admin_up()
# Configure IPv4 addresses on VPP pg0.
self.pg0.config_ip4()
self.pg0.resolve_arp()
# Configure IPv4 addresses on VPP pg1.
self.pg1.config_ip4()
def tearDown(self):
super(TestVxlanL2Mode, self).tearDown()
def test_l2_mode(self):
""" VXLAN L2 mode """
t = VppVxlanTunnel(self,
src=self.pg0.local_ip4,
dst=self.pg0.remote_ip4,
vni=1000, is_l3=False)
t.add_vpp_config()
t.config_ip4()
t.admin_up()
dstIP = t.local_ip4[:-1] + "2"
# Create a packet to send
p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
IP(src=self.pg1.local_ip4, dst=dstIP) /
UDP(sport=555, dport=556) /
Raw(b'\x00' * 80))
# Expect ARP request
rx = self.send_and_expect(self.pg1, [p], self.pg0)
for p in rx:
self.assertEqual(p[Ether].dst, self.pg0.remote_mac)
self.assertEqual(p[Ether].src, self.pg0.local_mac)
self.assertEqual(p[ARP].op, 1)
self.assertEqual(p[ARP].pdst, dstIP)
# Resolve ARP
VppNeighbor(self, t.sw_if_index,
self.pg1.remote_mac,
dstIP).add_vpp_config()
# Send packets
NUM_PKTS = 128
rx = self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)
self.assertEqual(NUM_PKTS, len(rx))
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)