FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
wireguard_handoff.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Cisco and/or its affiliates.
3  * Copyright (c) 2020 Doc.ai and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <wireguard/wireguard.h>
19 
20 #define foreach_wg_handoff_error \
21 _(CONGESTION_DROP, "congestion drop")
22 
23 typedef enum
24 {
25 #define _(sym,str) WG_HANDOFF_ERROR_##sym,
27 #undef _
30 
31 static char *wg_handoff_error_strings[] = {
32 #define _(sym,string) string,
34 #undef _
35 };
36 
37 typedef enum
38 {
43 
44 typedef struct wg_handoff_trace_t_
45 {
49 
50 static u8 *
51 format_wg_handoff_trace (u8 * s, va_list * args)
52 {
53  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
54  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
55  wg_handoff_trace_t *t = va_arg (*args, wg_handoff_trace_t *);
56 
57  s = format (s, "next-worker %d peer %d", t->next_worker_index, t->peer);
58 
59  return s;
60 }
61 
66 {
68  u16 thread_indices[VLIB_FRAME_SIZE], *ti;
69  u32 n_enq, n_left_from, *from;
70  wg_main_t *wmp;
71 
72  wmp = &wg_main;
74  n_left_from = frame->n_vectors;
76 
77  b = bufs;
78  ti = thread_indices;
79 
80  while (n_left_from > 0)
81  {
82  const wg_peer_t *peer;
83  index_t peeri = INDEX_INVALID;
84 
86  {
87  ti[0] = 0;
88  }
89  else if (mode == WG_HANDOFF_INP_DATA)
90  {
92  u32 *entry =
93  wg_index_table_lookup (&wmp->index_table, data->receiver_index);
94  peeri = *entry;
95  peer = wg_peer_get (peeri);
96 
97  ti[0] = peer->input_thread_index;
98  }
99  else
100  {
101  peeri =
103  ip.adj_index[VLIB_TX]);
104  peer = wg_peer_get (peeri);
105  ti[0] = peer->output_thread_index;
106  }
107 
108  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
109  {
110  wg_handoff_trace_t *t =
111  vlib_add_trace (vm, node, b[0], sizeof (*t));
112  t->next_worker_index = ti[0];
113  t->peer = peeri;
114  }
115 
116  n_left_from -= 1;
117  ti += 1;
118  b += 1;
119  }
120 
121  n_enq = vlib_buffer_enqueue_to_thread (vm, node, fq_index, from,
122  thread_indices, frame->n_vectors, 1);
123 
124  if (n_enq < frame->n_vectors)
125  vlib_node_increment_counter (vm, node->node_index,
126  WG_HANDOFF_ERROR_CONGESTION_DROP,
127  frame->n_vectors - n_enq);
128 
129  return n_enq;
130 }
131 
135 {
136  wg_main_t *wmp = &wg_main;
137 
138  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
140 }
141 
145 {
146  wg_main_t *wmp = &wg_main;
147 
148  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
150 }
151 
155 {
156  wg_main_t *wmp = &wg_main;
157 
158  return wg_handoff (vm, node, from_frame, wmp->out_fq_index,
160 }
161 
162 /* *INDENT-OFF* */
164 {
165  .name = "wg-handshake-handoff",
166  .vector_size = sizeof (u32),
167  .format_trace = format_wg_handoff_trace,
169  .n_errors = ARRAY_LEN (wg_handoff_error_strings),
170  .error_strings = wg_handoff_error_strings,
171  .n_next_nodes = 1,
172  .next_nodes = {
173  [0] = "error-drop",
174  },
175 };
176 
178 {
179  .name = "wg-input-data-handoff",
180  .vector_size = sizeof (u32),
181  .format_trace = format_wg_handoff_trace,
183  .n_errors = ARRAY_LEN (wg_handoff_error_strings),
184  .error_strings = wg_handoff_error_strings,
185  .n_next_nodes = 1,
186  .next_nodes = {
187  [0] = "error-drop",
188  },
189 };
190 
192 {
193  .name = "wg-output-tun-handoff",
194  .vector_size = sizeof (u32),
195  .format_trace = format_wg_handoff_trace,
197  .n_errors = ARRAY_LEN (wg_handoff_error_strings),
198  .error_strings = wg_handoff_error_strings,
199  .n_next_nodes = 1,
200  .next_nodes = {
201  [0] = "error-drop",
202  },
203 };
204 /* *INDENT-ON* */
205 
206 /*
207  * fd.io coding-style-patch-verification: ON
208  *
209  * Local Variables:
210  * eval: (c-set-style "gnu")
211  * End:
212  */
wg_handoff_trace_t
struct wg_handoff_trace_t_ wg_handoff_trace_t
wg_handshake_handoff
vlib_node_registration_t wg_handshake_handoff
(constructor) VLIB_REGISTER_NODE (wg_handshake_handoff)
Definition: wireguard_handoff.c:163
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:717
wg_input_data_handoff
vlib_node_registration_t wg_input_data_handoff
(constructor) VLIB_REGISTER_NODE (wg_input_data_handoff)
Definition: wireguard_handoff.c:177
vlib_buffer_enqueue_to_thread
static_always_inline u32 vlib_buffer_enqueue_to_thread(vlib_main_t *vm, vlib_node_runtime_t *node, u32 frame_queue_index, u32 *buffer_indices, u16 *thread_indices, u32 n_packets, int drop_on_congestion)
Definition: buffer_node.h:358
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
HANDOFF_N_ERROR
@ HANDOFF_N_ERROR
Definition: wireguard_handoff.c:28
wg_handoff
static_always_inline uword wg_handoff(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 fq_index, wg_handoff_mode_t mode)
Definition: wireguard_handoff.c:63
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
wg_main_t::index_table
wg_index_table_t index_table
Definition: wireguard.h:38
wg_peer_get_by_adj_index
static index_t wg_peer_get_by_adj_index(index_t ai)
Definition: wireguard_peer.h:131
u16
unsigned short u16
Definition: types.h:57
mode
vl_api_tunnel_mode_t mode
Definition: gre.api:48
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
foreach_wg_handoff_error
#define foreach_wg_handoff_error
Definition: wireguard_handoff.c:20
from_frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * from_frame
Definition: esp_encrypt.c:1328
vlib_frame_t
Definition: node.h:372
ti
u32 ti
Definition: interface_output.c:405
wireguard_peer.h
wg_index_table_lookup
u32 * wg_index_table_lookup(const wg_index_table_t *table, u32 key)
Definition: wireguard_index_table.c:48
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
wg_main_t::in_fq_index
u32 in_fq_index
Definition: wireguard.h:40
wg_handoff_trace_t_
Definition: wireguard_handoff.c:44
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
ipsec_handoff_error_t
ipsec_handoff_error_t
Definition: wireguard_handoff.c:23
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
static_always_inline
#define static_always_inline
Definition: clib.h:112
peer
vl_api_address_t peer
Definition: teib.api:28
wg_output_tun_handoff
vlib_node_registration_t wg_output_tun_handoff
(constructor) VLIB_REGISTER_NODE (wg_output_tun_handoff)
Definition: wireguard_handoff.c:191
uword
u64 uword
Definition: types.h:112
wg_peer
Definition: wireguard_peer.h:48
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
wg_main
wg_main_t wg_main
Definition: wireguard.c:26
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
data
u8 data[128]
Definition: ipsec_types.api:92
wg_main_t
Definition: wireguard.h:31
WG_HANDOFF_OUT_TUN
@ WG_HANDOFF_OUT_TUN
Definition: wireguard_handoff.c:41
WG_HANDOFF_INP_DATA
@ WG_HANDOFF_INP_DATA
Definition: wireguard_handoff.c:40
format
description fragment has unexpected format
Definition: map.api:433
wg_main_t::out_fq_index
u32 out_fq_index
Definition: wireguard.h:41
u32
unsigned int u32
Definition: types.h:88
wg_handoff_mode_t
wg_handoff_mode_t
Definition: wireguard_handoff.c:37
n_vectors
return frame n_vectors
Definition: nat44_ei_hairpinning.c:485
vlib_main_t
Definition: main.h:102
wg_handoff_trace_t_::next_worker_index
u32 next_worker_index
Definition: wireguard_handoff.c:46
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
wireguard.h
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip
vl_api_address_t ip
Definition: l2.api:558
wg_peer_get
static wg_peer_t * wg_peer_get(index_t peeri)
Definition: wireguard_peer.h:125
message_data
Definition: wireguard_messages.h:85
vlib_node_runtime_t
Definition: node.h:454
from
from
Definition: nat44_ei_hairpinning.c:415
INDEX_INVALID
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
WG_HANDOFF_HANDSHAKE
@ WG_HANDOFF_HANDSHAKE
Definition: wireguard_handoff.c:39
wg_handoff_trace_t_::peer
index_t peer
Definition: wireguard_handoff.c:47
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
wg_handoff_error_strings
static char * wg_handoff_error_strings[]
Definition: wireguard_handoff.c:31
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
format_wg_handoff_trace
static u8 * format_wg_handoff_trace(u8 *s, va_list *args)
Definition: wireguard_handoff.c:51
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105