FD.io VPP  v21.01.1
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;
73  from = vlib_frame_vector_args (frame);
74  n_left_from = frame->n_vectors;
75  vlib_get_buffers (vm, from, bufs, n_left_from);
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 
85  if (PREDICT_FALSE (mode == WG_HANDOFF_HANDSHAKE))
86  {
87  ti[0] = 0;
88  }
89  else if (mode == WG_HANDOFF_INP_DATA)
90  {
92  u32 *entry =
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, fq_index, from,
122  thread_indices, frame->n_vectors, 1);
123 
124  if (n_enq < frame->n_vectors)
126  WG_HANDOFF_ERROR_CONGESTION_DROP,
127  frame->n_vectors - n_enq);
128 
129  return n_enq;
130 }
131 
134  vlib_frame_t * from_frame)
135 {
136  wg_main_t *wmp = &wg_main;
137 
138  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
140 }
141 
144  vlib_frame_t * from_frame)
145 {
146  wg_main_t *wmp = &wg_main;
147 
148  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
150 }
151 
154  vlib_frame_t * from_frame)
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  */
#define CLIB_UNUSED(x)
Definition: clib.h:87
static u8 * format_wg_handoff_trace(u8 *s, va_list *args)
vlib_node_registration_t wg_handshake_handoff
(constructor) VLIB_REGISTER_NODE (wg_handshake_handoff)
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
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:41
vlib_main_t * vm
Definition: in2out_ed.c:1580
vlib_node_registration_t wg_output_tun_handoff
(constructor) VLIB_REGISTER_NODE (wg_output_tun_handoff)
#define VLIB_NODE_FN(node)
Definition: node.h:203
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:90
#define static_always_inline
Definition: clib.h:109
static index_t wg_peer_get_by_adj_index(index_t ai)
vlib_node_registration_t wg_input_data_handoff
(constructor) VLIB_REGISTER_NODE (wg_input_data_handoff)
description fragment has unexpected format
Definition: map.api:433
const cJSON *const b
Definition: cJSON.h:255
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:378
vl_api_fib_path_type_t type
Definition: fib_types.api:123
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:233
#define PREDICT_FALSE(x)
Definition: clib.h:121
u32 node_index
Node index.
Definition: node.h:488
vl_api_tunnel_mode_t mode
Definition: gre.api:48
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:170
u16 n_vectors
Definition: node.h:397
#define foreach_wg_handoff_error
wg_handoff_mode_t
u32 out_fq_index
Definition: wireguard.h:41
#define ARRAY_LEN(x)
Definition: clib.h:67
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
wg_index_table_t index_table
Definition: wireguard.h:38
wg_main_t wg_main
Definition: wireguard.c:26
Definition: defs.h:47
vl_api_address_t ip
Definition: l2.api:501
ipsec_handoff_error_t
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1581
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
static_always_inline u32 vlib_buffer_enqueue_to_thread(vlib_main_t *vm, u32 frame_queue_index, u32 *buffer_indices, u16 *thread_indices, u32 n_packets, int drop_on_congestion)
Definition: buffer_node.h:494
#define vnet_buffer(b)
Definition: buffer.h:417
u32 input_thread_index
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:634
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)
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:280
static wg_peer_t * wg_peer_get(index_t peeri)
static char * wg_handoff_error_strings[]
u32 * wg_index_table_lookup(const wg_index_table_t *table, u32 key)
u32 in_fq_index
Definition: wireguard.h:40
u32 output_thread_index
struct wg_handoff_trace_t_ wg_handoff_trace_t