FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
wireguard_handoff.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Doc.ai and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <wireguard/wireguard.h>
18 
19 #define foreach_wg_handoff_error \
20 _(CONGESTION_DROP, "congestion drop")
21 
22 typedef enum
23 {
24 #define _(sym,str) WG_HANDOFF_ERROR_##sym,
26 #undef _
29 
30 static char *wg_handoff_error_strings[] = {
31 #define _(sym,string) string,
33 #undef _
34 };
35 
36 typedef enum
37 {
42 
43 typedef struct wg_handoff_trace_t_
44 {
48 
49 static u8 *
50 format_wg_handoff_trace (u8 * s, va_list * args)
51 {
52  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
53  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
54  wg_handoff_trace_t *t = va_arg (*args, wg_handoff_trace_t *);
55 
56  s = format (s, "next-worker %d peer %d", t->next_worker_index, t->peer);
57 
58  return s;
59 }
60 
65 {
66  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
67  u16 thread_indices[VLIB_FRAME_SIZE], *ti;
68  u32 n_enq, n_left_from, *from;
69  wg_main_t *wmp;
70 
71  wmp = &wg_main;
72  from = vlib_frame_vector_args (frame);
73  n_left_from = frame->n_vectors;
74  vlib_get_buffers (vm, from, bufs, n_left_from);
75 
76  b = bufs;
77  ti = thread_indices;
78 
79  while (n_left_from > 0)
80  {
81  const wg_peer_t *peer;
82  index_t peeri = INDEX_INVALID;
83 
84  if (PREDICT_FALSE (mode == WG_HANDOFF_HANDSHAKE))
85  {
86  ti[0] = 0;
87  }
88  else if (mode == WG_HANDOFF_INP_DATA)
89  {
91  u32 *entry =
93  peeri = *entry;
94  peer = wg_peer_get (peeri);
95 
96  ti[0] = peer->input_thread_index;
97  }
98  else
99  {
100  peeri =
102  ip.adj_index[VLIB_TX]);
103  peer = wg_peer_get (peeri);
104  ti[0] = peer->output_thread_index;
105  }
106 
107  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
108  {
109  wg_handoff_trace_t *t =
110  vlib_add_trace (vm, node, b[0], sizeof (*t));
111  t->next_worker_index = ti[0];
112  t->peer = peeri;
113  }
114 
115  n_left_from -= 1;
116  ti += 1;
117  b += 1;
118  }
119 
120  n_enq = vlib_buffer_enqueue_to_thread (vm, fq_index, from,
121  thread_indices, frame->n_vectors, 1);
122 
123  if (n_enq < frame->n_vectors)
125  WG_HANDOFF_ERROR_CONGESTION_DROP,
126  frame->n_vectors - n_enq);
127 
128  return n_enq;
129 }
130 
133  vlib_frame_t * from_frame)
134 {
135  wg_main_t *wmp = &wg_main;
136 
137  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
139 }
140 
143  vlib_frame_t * from_frame)
144 {
145  wg_main_t *wmp = &wg_main;
146 
147  return wg_handoff (vm, node, from_frame, wmp->in_fq_index,
149 }
150 
153  vlib_frame_t * from_frame)
154 {
155  wg_main_t *wmp = &wg_main;
156 
157  return wg_handoff (vm, node, from_frame, wmp->out_fq_index,
159 }
160 
162 {
163  .name = "wg-handshake-handoff",.vector_size = sizeof (u32),.format_trace =
165  ARRAY_LEN (wg_handoff_error_strings),.error_strings =
166  wg_handoff_error_strings,.n_next_nodes = 1,.next_nodes =
167  {
168  [0] = "error-drop",}
169 ,};
170 
172 {
173  .name = "wg-input-data-handoff",.vector_size = sizeof (u32),.format_trace =
175  ARRAY_LEN (wg_handoff_error_strings),.error_strings =
176  wg_handoff_error_strings,.n_next_nodes = 1,.next_nodes =
177  {
178  [0] = "error-drop",}
179 ,};
180 
182 {
183  .name = "wg-output-tun-handoff",.vector_size = sizeof (u32),.format_trace =
185  ARRAY_LEN (wg_handoff_error_strings),.error_strings =
186  wg_handoff_error_strings,.n_next_nodes = 1,.next_nodes =
187  {
188  [0] = "error-drop",}
189 ,};
190 
191 /*
192  * fd.io coding-style-patch-verification: ON
193  *
194  * Local Variables:
195  * eval: (c-set-style "gnu")
196  * End:
197  */
#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:103
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:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
vlib_node_registration_t wg_output_tun_handoff
(constructor) VLIB_REGISTER_NODE (wg_output_tun_handoff)
#define VLIB_NODE_FN(node)
Definition: node.h:202
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:89
#define static_always_inline
Definition: clib.h:108
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)
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:377
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:229
#define PREDICT_FALSE(x)
Definition: clib.h:120
u32 node_index
Node index.
Definition: node.h:487
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:169
u16 n_vectors
Definition: node.h:396
#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:1582
wg_index_table_t index_table
Definition: wireguard.h:38
wg_main_t wg_main
Definition: wireguard.c:27
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:1583
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:577
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