blob: a86614f54757ff2c167540fdee2c7b136ca9f3d2 [file] [log] [blame]
Neale Ranns810086d2017-11-05 16:26:46 -08001/*
Florin Corasc5df8c72019-04-08 07:42:30 -07002 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
Neale Ranns810086d2017-11-05 16:26:46 -08003 * 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 <vnet/udp/udp_encap.h>
Florin Corasb040f982020-10-20 14:59:43 -070017#include <vnet/udp/udp.h>
Neale Ranns810086d2017-11-05 16:26:46 -080018
19typedef struct udp4_encap_trace_t_
20{
21 udp_header_t udp;
22 ip4_header_t ip;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050023 u32 flow_hash;
24 udp_encap_fixup_flags_t flags;
Neale Ranns810086d2017-11-05 16:26:46 -080025} udp4_encap_trace_t;
26
27typedef struct udp6_encap_trace_t_
28{
29 udp_header_t udp;
30 ip6_header_t ip;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050031 u32 flow_hash;
32 udp_encap_fixup_flags_t flags;
Neale Ranns810086d2017-11-05 16:26:46 -080033} udp6_encap_trace_t;
34
Neale Ranns43b1f442018-03-20 01:47:35 -070035extern vlib_combined_counter_main_t udp_encap_counters;
36
Neale Ranns810086d2017-11-05 16:26:46 -080037static u8 *
38format_udp4_encap_trace (u8 * s, va_list * args)
39{
40 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
41 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050042 u32 indent = format_get_indent (s);
Neale Ranns810086d2017-11-05 16:26:46 -080043 udp4_encap_trace_t *t;
44
45 t = va_arg (*args, udp4_encap_trace_t *);
46
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050047 s = format (s, "flags: %U, flow hash: 0x%08x\n%U%U\n%U%U",
48 format_udp_encap_fixup_flags, t->flags, t->flow_hash,
49 format_white_space, indent, format_ip4_header, &t->ip,
50 sizeof (t->ip), format_white_space, indent, format_udp_header,
51 &t->udp, sizeof (t->udp));
Neale Ranns810086d2017-11-05 16:26:46 -080052 return (s);
53}
54
55static u8 *
56format_udp6_encap_trace (u8 * s, va_list * args)
57{
58 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
59 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050060 u32 indent = format_get_indent (s);
Neale Ranns810086d2017-11-05 16:26:46 -080061 udp6_encap_trace_t *t;
62
63 t = va_arg (*args, udp6_encap_trace_t *);
64
Vladislav Grishenko5c801b32022-06-23 00:45:16 +050065 s = format (s, "flags: %U, flow hash: 0x%08x\n%U%U\n%U%U",
66 format_udp_encap_fixup_flags, t->flags, t->flow_hash,
67 format_white_space, indent, format_ip6_header, &t->ip,
68 sizeof (t->ip), format_white_space, indent, format_udp_header,
69 &t->udp, sizeof (t->udp));
Neale Ranns810086d2017-11-05 16:26:46 -080070 return (s);
71}
72
73always_inline uword
Mauro Sardara95396472022-03-22 17:53:46 +000074udp_encap_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
75 vlib_frame_t *frame, ip_address_family_t encap_family,
76 ip_address_family_t payload_family)
Neale Ranns810086d2017-11-05 16:26:46 -080077{
Neale Ranns43b1f442018-03-20 01:47:35 -070078 vlib_combined_counter_main_t *cm = &udp_encap_counters;
Neale Ranns810086d2017-11-05 16:26:46 -080079 u32 *from = vlib_frame_vector_args (frame);
80 u32 n_left_from, n_left_to_next, *to_next, next_index;
Damjan Marion067cd622018-07-11 12:47:43 +020081 u32 thread_index = vm->thread_index;
Neale Ranns810086d2017-11-05 16:26:46 -080082
83 n_left_from = frame->n_vectors;
84 next_index = node->cached_next_index;
85
86 while (n_left_from > 0)
87 {
88 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
89
90 while (n_left_from >= 4 && n_left_to_next >= 2)
91 {
92 vlib_buffer_t *b0, *b1;
93 udp_encap_t *ue0, *ue1;
94 u32 bi0, next0, uei0;
95 u32 bi1, next1, uei1;
96
97 /* Prefetch next iteration. */
98 {
99 vlib_buffer_t *p2, *p3;
100
101 p2 = vlib_get_buffer (vm, from[2]);
102 p3 = vlib_get_buffer (vm, from[3]);
103
104 vlib_prefetch_buffer_header (p2, STORE);
105 vlib_prefetch_buffer_header (p3, STORE);
106 }
107
108 bi0 = to_next[0] = from[0];
109 bi1 = to_next[1] = from[1];
110
111 from += 2;
112 n_left_from -= 2;
113 to_next += 2;
114 n_left_to_next -= 2;
115
116 b0 = vlib_get_buffer (vm, bi0);
117 b1 = vlib_get_buffer (vm, bi1);
118
119 uei0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
120 uei1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX];
121
Neale Ranns43b1f442018-03-20 01:47:35 -0700122 vlib_increment_combined_counter (cm, thread_index, uei0, 1,
123 vlib_buffer_length_in_chain (vm,
124 b0));
125 vlib_increment_combined_counter (cm, thread_index, uei1, 1,
126 vlib_buffer_length_in_chain (vm,
127 b1));
128
Neale Ranns810086d2017-11-05 16:26:46 -0800129 /* Rewrite packet header and updates lengths. */
130 ue0 = udp_encap_get (uei0);
131 ue1 = udp_encap_get (uei1);
132
133 /* Paint */
Mauro Sardara95396472022-03-22 17:53:46 +0000134 if (encap_family == AF_IP6)
Neale Ranns810086d2017-11-05 16:26:46 -0800135 {
136 const u8 n_bytes =
137 sizeof (udp_header_t) + sizeof (ip6_header_t);
Mauro Sardara95396472022-03-22 17:53:46 +0000138 ip_udp_encap_two (vm, b0, b1, (u8 *) &ue0->ue_hdrs,
139 (u8 *) &ue1->ue_hdrs, n_bytes, encap_family,
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500140 payload_family, ue0->ue_flags, ue1->ue_flags);
141
Neale Ranns810086d2017-11-05 16:26:46 -0800142 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
143 {
144 udp6_encap_trace_t *tr =
145 vlib_add_trace (vm, node, b0, sizeof (*tr));
146 tr->udp = ue0->ue_hdrs.ip6.ue_udp;
147 tr->ip = ue0->ue_hdrs.ip6.ue_ip6;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500148 tr->flags = ue0->ue_flags;
149 tr->flow_hash = vnet_buffer (b0)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800150 }
151 if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
152 {
153 udp6_encap_trace_t *tr =
154 vlib_add_trace (vm, node, b1, sizeof (*tr));
155 tr->udp = ue1->ue_hdrs.ip6.ue_udp;
156 tr->ip = ue1->ue_hdrs.ip6.ue_ip6;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500157 tr->flags = ue1->ue_flags;
158 tr->flow_hash = vnet_buffer (b1)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800159 }
160 }
161 else
162 {
163 const u8 n_bytes =
164 sizeof (udp_header_t) + sizeof (ip4_header_t);
165
Mauro Sardara95396472022-03-22 17:53:46 +0000166 ip_udp_encap_two (vm, b0, b1, (u8 *) &ue0->ue_hdrs,
167 (u8 *) &ue1->ue_hdrs, n_bytes, encap_family,
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500168 payload_family, ue0->ue_flags, ue1->ue_flags);
Neale Ranns810086d2017-11-05 16:26:46 -0800169
170 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
171 {
172 udp4_encap_trace_t *tr =
173 vlib_add_trace (vm, node, b0, sizeof (*tr));
174 tr->udp = ue0->ue_hdrs.ip4.ue_udp;
175 tr->ip = ue0->ue_hdrs.ip4.ue_ip4;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500176 tr->flags = ue0->ue_flags;
177 tr->flow_hash = vnet_buffer (b0)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800178 }
179 if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
180 {
181 udp4_encap_trace_t *tr =
182 vlib_add_trace (vm, node, b1, sizeof (*tr));
183 tr->udp = ue1->ue_hdrs.ip4.ue_udp;
184 tr->ip = ue1->ue_hdrs.ip4.ue_ip4;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500185 tr->flags = ue1->ue_flags;
186 tr->flow_hash = vnet_buffer (b1)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800187 }
188 }
189
190 next0 = ue0->ue_dpo.dpoi_next_node;
191 next1 = ue1->ue_dpo.dpoi_next_node;
192 vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ue0->ue_dpo.dpoi_index;
193 vnet_buffer (b1)->ip.adj_index[VLIB_TX] = ue1->ue_dpo.dpoi_index;
194
195 vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
196 to_next, n_left_to_next,
197 bi0, bi1, next0, next1);
198 }
199
200 while (n_left_from > 0 && n_left_to_next > 0)
201 {
202 u32 bi0, next0, uei0;
203 vlib_buffer_t *b0;
204 udp_encap_t *ue0;
205
206 bi0 = to_next[0] = from[0];
207
208 from += 1;
209 n_left_from -= 1;
210 to_next += 1;
211 n_left_to_next -= 1;
212
213 b0 = vlib_get_buffer (vm, bi0);
214
215 uei0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
216
217 /* Rewrite packet header and updates lengths. */
218 ue0 = udp_encap_get (uei0);
219
Neale Ranns43b1f442018-03-20 01:47:35 -0700220 vlib_increment_combined_counter (cm, thread_index, uei0, 1,
221 vlib_buffer_length_in_chain (vm,
222 b0));
223
Neale Ranns810086d2017-11-05 16:26:46 -0800224 /* Paint */
Mauro Sardara95396472022-03-22 17:53:46 +0000225 if (encap_family == AF_IP6)
Neale Ranns810086d2017-11-05 16:26:46 -0800226 {
227 const u8 n_bytes =
228 sizeof (udp_header_t) + sizeof (ip6_header_t);
Mauro Sardara95396472022-03-22 17:53:46 +0000229 ip_udp_encap_one (vm, b0, (u8 *) &ue0->ue_hdrs.ip6, n_bytes,
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500230 encap_family, payload_family, ue0->ue_flags);
Neale Ranns810086d2017-11-05 16:26:46 -0800231
232 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
233 {
234 udp6_encap_trace_t *tr =
235 vlib_add_trace (vm, node, b0, sizeof (*tr));
236 tr->udp = ue0->ue_hdrs.ip6.ue_udp;
237 tr->ip = ue0->ue_hdrs.ip6.ue_ip6;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500238 tr->flags = ue0->ue_flags;
239 tr->flow_hash = vnet_buffer (b0)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800240 }
241 }
242 else
243 {
244 const u8 n_bytes =
245 sizeof (udp_header_t) + sizeof (ip4_header_t);
246
Mauro Sardara95396472022-03-22 17:53:46 +0000247 ip_udp_encap_one (vm, b0, (u8 *) &ue0->ue_hdrs.ip4, n_bytes,
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500248 encap_family, payload_family, ue0->ue_flags);
Neale Ranns810086d2017-11-05 16:26:46 -0800249
250 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
251 {
252 udp4_encap_trace_t *tr =
253 vlib_add_trace (vm, node, b0, sizeof (*tr));
254 tr->udp = ue0->ue_hdrs.ip4.ue_udp;
255 tr->ip = ue0->ue_hdrs.ip4.ue_ip4;
Vladislav Grishenko5c801b32022-06-23 00:45:16 +0500256 tr->flags = ue0->ue_flags;
257 tr->flow_hash = vnet_buffer (b0)->ip.flow_hash;
Neale Ranns810086d2017-11-05 16:26:46 -0800258 }
259 }
260
261 next0 = ue0->ue_dpo.dpoi_next_node;
262 vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ue0->ue_dpo.dpoi_index;
263
264 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
265 to_next, n_left_to_next,
266 bi0, next0);
267 }
268
269 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
270 }
271
272 return frame->n_vectors;
273}
274
Mauro Sardara95396472022-03-22 17:53:46 +0000275VLIB_NODE_FN (udp4o4_encap_node)
276(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Neale Ranns810086d2017-11-05 16:26:46 -0800277{
Mauro Sardara95396472022-03-22 17:53:46 +0000278 return udp_encap_inline (vm, node, frame, AF_IP4, AF_IP4);
Neale Ranns810086d2017-11-05 16:26:46 -0800279}
280
Mauro Sardara95396472022-03-22 17:53:46 +0000281VLIB_NODE_FN (udp6o4_encap_node)
282(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Neale Ranns810086d2017-11-05 16:26:46 -0800283{
Mauro Sardara95396472022-03-22 17:53:46 +0000284 return udp_encap_inline (vm, node, frame, AF_IP4, AF_IP6);
285}
286
287VLIB_NODE_FN (udp4_encap_node)
288(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
289{
290 return udp_encap_inline (vm, node, frame, AF_IP4, N_AF);
291}
292
293VLIB_NODE_FN (udp6o6_encap_node)
294(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
295{
296 return udp_encap_inline (vm, node, frame, AF_IP6, AF_IP6);
297}
298
299VLIB_NODE_FN (udp4o6_encap_node)
300(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
301{
302 return udp_encap_inline (vm, node, frame, AF_IP6, AF_IP4);
303}
304
305VLIB_NODE_FN (udp6_encap_node)
306(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
307{
308 return udp_encap_inline (vm, node, frame, AF_IP6, N_AF);
Neale Ranns810086d2017-11-05 16:26:46 -0800309}
310
Mauro Sardara95396472022-03-22 17:53:46 +0000311VLIB_REGISTER_NODE (udp4o4_encap_node) = {
312 .name = "udp4o4-encap",
313 .vector_size = sizeof (u32),
314 .format_trace = format_udp4_encap_trace,
315 .n_next_nodes = 0,
316};
317
318VLIB_REGISTER_NODE (udp6o4_encap_node) = {
319 .name = "udp6o4-encap",
320 .vector_size = sizeof (u32),
Dmitry Valter25801d62023-09-21 17:46:26 +0000321 .format_trace = format_udp4_encap_trace,
Mauro Sardara95396472022-03-22 17:53:46 +0000322 .n_next_nodes = 0,
323 .sibling_of = "udp4o4-encap",
324};
325
Neale Ranns810086d2017-11-05 16:26:46 -0800326VLIB_REGISTER_NODE (udp4_encap_node) = {
Neale Ranns810086d2017-11-05 16:26:46 -0800327 .name = "udp4-encap",
328 .vector_size = sizeof (u32),
Neale Ranns810086d2017-11-05 16:26:46 -0800329 .format_trace = format_udp4_encap_trace,
Neale Ranns810086d2017-11-05 16:26:46 -0800330 .n_next_nodes = 0,
Mauro Sardara95396472022-03-22 17:53:46 +0000331 .sibling_of = "udp4o4-encap",
332};
333
334VLIB_REGISTER_NODE (udp6o6_encap_node) = {
335 .name = "udp6o6-encap",
336 .vector_size = sizeof (u32),
337 .format_trace = format_udp6_encap_trace,
338 .n_next_nodes = 0,
339};
340
341VLIB_REGISTER_NODE (udp4o6_encap_node) = {
342 .name = "udp4o6-encap",
343 .vector_size = sizeof (u32),
Dmitry Valter25801d62023-09-21 17:46:26 +0000344 .format_trace = format_udp6_encap_trace,
Mauro Sardara95396472022-03-22 17:53:46 +0000345 .n_next_nodes = 0,
346 .sibling_of = "udp6o6-encap",
Neale Ranns810086d2017-11-05 16:26:46 -0800347};
Neale Ranns810086d2017-11-05 16:26:46 -0800348
349VLIB_REGISTER_NODE (udp6_encap_node) = {
Neale Ranns810086d2017-11-05 16:26:46 -0800350 .name = "udp6-encap",
351 .vector_size = sizeof (u32),
Neale Ranns810086d2017-11-05 16:26:46 -0800352 .format_trace = format_udp6_encap_trace,
Neale Ranns810086d2017-11-05 16:26:46 -0800353 .n_next_nodes = 0,
Mauro Sardara95396472022-03-22 17:53:46 +0000354 .sibling_of = "udp6o6-encap",
Neale Ranns810086d2017-11-05 16:26:46 -0800355};
Neale Ranns810086d2017-11-05 16:26:46 -0800356
357
358/*
359 * fd.io coding-style-patch-verification: ON
360 *
361 * Local Variables:
362 * eval: (c-set-style "gnu")
363 * End:
364 */