blob: 0b1d3d7125b1cef4f74ebcdb40679ff04a996542 [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>
17#include <vnet/fib/fib_entry.h>
Neale Ranns1f50bf82019-07-16 15:28:52 +000018#include <vnet/fib/fib_entry_track.h>
Neale Ranns810086d2017-11-05 16:26:46 -080019#include <vnet/fib/fib_table.h>
20#include <vnet/dpo/drop_dpo.h>
21
22/**
23 * Registered DPO types for the IP header encapsulated, v4 or v6.
24 */
25dpo_type_t udp_encap_dpo_types[FIB_PROTOCOL_MAX];
26
27/**
Neale Ranns810086d2017-11-05 16:26:46 -080028 * Pool of encaps
29 */
30udp_encap_t *udp_encap_pool;
31
Neale Ranns43b1f442018-03-20 01:47:35 -070032/**
33 * Stats for each UDP encap object
34 */
Neale Ranns9c0a3c42018-09-07 08:57:41 -070035vlib_combined_counter_main_t udp_encap_counters = {
36 /**
37 * The counter collection's name.
38 */
39 .name = "udp-encap",
40 /**
41 * Name in stat segment directory
42 */
43 .stat_segment_name = "/net/udp-encap",
44};
Neale Ranns810086d2017-11-05 16:26:46 -080045
46static void
47udp_encap_restack (udp_encap_t * ue)
48{
49 dpo_stack (udp_encap_dpo_types[ue->ue_ip_proto],
50 fib_proto_to_dpo (ue->ue_ip_proto),
51 &ue->ue_dpo,
52 fib_entry_contribute_ip_forwarding (ue->ue_fib_entry_index));
53}
54
55index_t
Neale Ranns9c0a3c42018-09-07 08:57:41 -070056udp_encap_add_and_lock (fib_protocol_t proto,
Neale Ranns810086d2017-11-05 16:26:46 -080057 index_t fib_index,
58 const ip46_address_t * src_ip,
59 const ip46_address_t * dst_ip,
60 u16 src_port,
61 u16 dst_port, udp_encap_fixup_flags_t flags)
62{
63 udp_encap_t *ue;
Neale Ranns9c0a3c42018-09-07 08:57:41 -070064 u8 pfx_len = 0;
Neale Ranns810086d2017-11-05 16:26:46 -080065 index_t uei;
66
Neale Ranns9c0a3c42018-09-07 08:57:41 -070067 pool_get_aligned (udp_encap_pool, ue, CLIB_CACHE_LINE_BYTES);
68 uei = ue - udp_encap_pool;
Neale Ranns810086d2017-11-05 16:26:46 -080069
Neale Ranns9c0a3c42018-09-07 08:57:41 -070070 vlib_validate_combined_counter (&(udp_encap_counters), uei);
71 vlib_zero_combined_counter (&(udp_encap_counters), uei);
72
73 fib_node_init (&ue->ue_fib_node, FIB_NODE_TYPE_UDP_ENCAP);
74 fib_node_lock (&ue->ue_fib_node);
75 ue->ue_fib_index = fib_index;
76 ue->ue_flags = flags;
77 ue->ue_ip_proto = proto;
78
79 switch (proto)
Neale Ranns810086d2017-11-05 16:26:46 -080080 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -070081 case FIB_PROTOCOL_IP4:
82 pfx_len = 32;
83 ue->ue_hdrs.ip4.ue_ip4.ip_version_and_header_length = 0x45;
84 ue->ue_hdrs.ip4.ue_ip4.ttl = 254;
85 ue->ue_hdrs.ip4.ue_ip4.protocol = IP_PROTOCOL_UDP;
86 ue->ue_hdrs.ip4.ue_ip4.src_address.as_u32 = src_ip->ip4.as_u32;
87 ue->ue_hdrs.ip4.ue_ip4.dst_address.as_u32 = dst_ip->ip4.as_u32;
88 ue->ue_hdrs.ip4.ue_ip4.checksum =
89 ip4_header_checksum (&ue->ue_hdrs.ip4.ue_ip4);
90 ue->ue_hdrs.ip4.ue_udp.src_port = clib_host_to_net_u16 (src_port);
91 ue->ue_hdrs.ip4.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);
Neale Ranns810086d2017-11-05 16:26:46 -080092
Neale Ranns9c0a3c42018-09-07 08:57:41 -070093 break;
94 case FIB_PROTOCOL_IP6:
95 pfx_len = 128;
96 ue->ue_hdrs.ip6.ue_ip6.ip_version_traffic_class_and_flow_label =
97 clib_host_to_net_u32 (6 << 28);
98 ue->ue_hdrs.ip6.ue_ip6.hop_limit = 255;
99 ue->ue_hdrs.ip6.ue_ip6.protocol = IP_PROTOCOL_UDP;
100 ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[0] = src_ip->ip6.as_u64[0];
101 ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[1] = src_ip->ip6.as_u64[1];
102 ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[0] = dst_ip->ip6.as_u64[0];
103 ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[1] = dst_ip->ip6.as_u64[1];
104 ue->ue_hdrs.ip6.ue_udp.src_port = clib_host_to_net_u16 (src_port);
105 ue->ue_hdrs.ip6.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);
Neale Ranns810086d2017-11-05 16:26:46 -0800106
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700107 break;
108 default:
109 ASSERT (0);
Neale Ranns810086d2017-11-05 16:26:46 -0800110 }
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700111
112 /*
113 * track the destination address
114 */
115 fib_prefix_t dst_pfx = {
116 .fp_proto = proto,
117 .fp_len = pfx_len,
118 .fp_addr = *dst_ip,
119 };
120
Neale Ranns1f50bf82019-07-16 15:28:52 +0000121 ue->ue_fib_entry_index = fib_entry_track (fib_index,
122 &dst_pfx,
123 FIB_NODE_TYPE_UDP_ENCAP,
124 uei, &ue->ue_fib_sibling);
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700125 udp_encap_restack (ue);
126
Neale Ranns810086d2017-11-05 16:26:46 -0800127 return (uei);
128}
129
130void
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700131udp_encap_contribute_forwarding (index_t uei, dpo_proto_t proto,
132 dpo_id_t * dpo)
Neale Ranns810086d2017-11-05 16:26:46 -0800133{
Neale Ranns810086d2017-11-05 16:26:46 -0800134 if (INDEX_INVALID == uei)
135 {
136 dpo_copy (dpo, drop_dpo_get (proto));
137 }
138 else
139 {
140 udp_encap_t *ue;
141
142 ue = udp_encap_get (uei);
143
144 dpo_set (dpo, udp_encap_dpo_types[ue->ue_ip_proto], proto, uei);
145 }
146}
147
Neale Ranns810086d2017-11-05 16:26:46 -0800148void
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700149udp_encap_lock (index_t uei)
Neale Ranns810086d2017-11-05 16:26:46 -0800150{
151 udp_encap_t *ue;
152
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700153 ue = udp_encap_get (uei);
Neale Ranns810086d2017-11-05 16:26:46 -0800154
155 if (NULL != ue)
156 {
157 fib_node_lock (&ue->ue_fib_node);
158 }
159}
160
161void
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700162udp_encap_unlock (index_t uei)
Neale Ranns810086d2017-11-05 16:26:46 -0800163{
164 udp_encap_t *ue;
165
166 if (INDEX_INVALID == uei)
167 {
168 return;
169 }
170
171 ue = udp_encap_get (uei);
172
173 if (NULL != ue)
174 {
175 fib_node_unlock (&ue->ue_fib_node);
176 }
177}
178
Neale Ranns810086d2017-11-05 16:26:46 -0800179static void
180udp_encap_dpo_lock (dpo_id_t * dpo)
181{
182 udp_encap_t *ue;
183
184 ue = udp_encap_get (dpo->dpoi_index);
185
186 fib_node_lock (&ue->ue_fib_node);
187}
188
189static void
190udp_encap_dpo_unlock (dpo_id_t * dpo)
191{
192 udp_encap_t *ue;
193
194 ue = udp_encap_get (dpo->dpoi_index);
195
196 fib_node_unlock (&ue->ue_fib_node);
197}
198
199static u8 *
200format_udp_encap_i (u8 * s, va_list * args)
201{
202 index_t uei = va_arg (*args, index_t);
203 u32 indent = va_arg (*args, u32);
204 u32 details = va_arg (*args, u32);
Neale Ranns43b1f442018-03-20 01:47:35 -0700205 vlib_counter_t to;
Neale Ranns810086d2017-11-05 16:26:46 -0800206 udp_encap_t *ue;
207
208 ue = udp_encap_get (uei);
209
210 // FIXME
Neale Ranns097fa662018-05-01 05:17:55 -0700211 s = format (s, "udp-encap:[%d]: ip-fib-index:%d ", uei, ue->ue_fib_index);
Neale Ranns810086d2017-11-05 16:26:46 -0800212 if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
213 {
214 s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d, dst:%d]",
215 format_ip4_address,
216 &ue->ue_hdrs.ip4.ue_ip4.src_address,
217 format_ip4_address,
218 &ue->ue_hdrs.ip4.ue_ip4.dst_address,
219 clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.src_port),
220 clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.dst_port));
221 }
222 else
223 {
224 s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d dst:%d]",
225 format_ip6_address,
226 &ue->ue_hdrs.ip6.ue_ip6.src_address,
227 format_ip6_address,
228 &ue->ue_hdrs.ip6.ue_ip6.dst_address,
229 clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.src_port),
230 clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.dst_port));
231 }
Neale Ranns43b1f442018-03-20 01:47:35 -0700232 vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
233 s = format (s, " to:[%Ld:%Ld]]", to.packets, to.bytes);
234
Neale Ranns810086d2017-11-05 16:26:46 -0800235 if (details)
236 {
237 s = format (s, " locks:%d", ue->ue_fib_node.fn_locks);
238 s = format (s, "\n%UStacked on:", format_white_space, indent + 1);
239 s = format (s, "\n%U%U",
240 format_white_space, indent + 2,
241 format_dpo_id, &ue->ue_dpo, indent + 3);
242 }
243 return (s);
244}
245
Neale Ranns43b1f442018-03-20 01:47:35 -0700246void
247udp_encap_get_stats (index_t uei, u64 * packets, u64 * bytes)
248{
249 vlib_counter_t to;
250
251 vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
252
253 *packets = to.packets;
254 *bytes = to.bytes;
255}
256
Neale Ranns810086d2017-11-05 16:26:46 -0800257static u8 *
258format_udp_encap_dpo (u8 * s, va_list * args)
259{
260 index_t uei = va_arg (*args, index_t);
261 u32 indent = va_arg (*args, u32);
262
263 return (format (s, "%U", format_udp_encap_i, uei, indent, 1));
264}
265
266u8 *
267format_udp_encap (u8 * s, va_list * args)
268{
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700269 index_t uei = va_arg (*args, u32);
Neale Ranns810086d2017-11-05 16:26:46 -0800270 u32 details = va_arg (*args, u32);
Neale Ranns810086d2017-11-05 16:26:46 -0800271
272 return (format (s, "%U", format_udp_encap_i, uei, 0, details));
273}
274
275static udp_encap_t *
276udp_encap_from_fib_node (fib_node_t * node)
277{
Neale Ranns810086d2017-11-05 16:26:46 -0800278 ASSERT (FIB_NODE_TYPE_UDP_ENCAP == node->fn_type);
Neale Ranns810086d2017-11-05 16:26:46 -0800279 return ((udp_encap_t *) (((char *) node) -
280 STRUCT_OFFSET_OF (udp_encap_t, ue_fib_node)));
281}
282
283/**
284 * Function definition to backwalk a FIB node
285 */
286static fib_node_back_walk_rc_t
287udp_encap_fib_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
288{
289 udp_encap_restack (udp_encap_from_fib_node (node));
290
291 return (FIB_NODE_BACK_WALK_CONTINUE);
292}
293
294/**
295 * Function definition to get a FIB node from its index
296 */
297static fib_node_t *
298udp_encap_fib_node_get (fib_node_index_t index)
299{
300 udp_encap_t *ue;
301
302 ue = pool_elt_at_index (udp_encap_pool, index);
303
304 return (&ue->ue_fib_node);
305}
306
307/**
308 * Function definition to inform the FIB node that its last lock has gone.
309 */
310static void
311udp_encap_fib_last_lock_gone (fib_node_t * node)
312{
313 udp_encap_t *ue;
314
315 ue = udp_encap_from_fib_node (node);
316
317 /**
318 * reset the stacked DPO to unlock it
319 */
320 dpo_reset (&ue->ue_dpo);
Neale Ranns810086d2017-11-05 16:26:46 -0800321
Neale Ranns1f50bf82019-07-16 15:28:52 +0000322 fib_entry_untrack (ue->ue_fib_entry_index, ue->ue_fib_sibling);
Neale Ranns810086d2017-11-05 16:26:46 -0800323
324 pool_put (udp_encap_pool, ue);
325}
326
327const static char *const udp4_encap_ip4_nodes[] = {
328 "udp4-encap",
329 NULL,
330};
331
332const static char *const udp4_encap_ip6_nodes[] = {
333 "udp4-encap",
334 NULL,
335};
336
337const static char *const udp4_encap_mpls_nodes[] = {
338 "udp4-encap",
339 NULL,
340};
341
Neale Ranns91286372017-12-05 13:24:04 -0800342const static char *const udp4_encap_bier_nodes[] = {
343 "udp4-encap",
344 NULL,
345};
346
Neale Ranns810086d2017-11-05 16:26:46 -0800347const static char *const udp6_encap_ip4_nodes[] = {
348 "udp6-encap",
349 NULL,
350};
351
352const static char *const udp6_encap_ip6_nodes[] = {
353 "udp6-encap",
354 NULL,
355};
356
357const static char *const udp6_encap_mpls_nodes[] = {
358 "udp6-encap",
359 NULL,
360};
361
Neale Ranns91286372017-12-05 13:24:04 -0800362const static char *const udp6_encap_bier_nodes[] = {
363 "udp6-encap",
364 NULL,
365};
366
Neale Ranns810086d2017-11-05 16:26:46 -0800367const static char *const *const udp4_encap_nodes[DPO_PROTO_NUM] = {
368 [DPO_PROTO_IP4] = udp4_encap_ip4_nodes,
369 [DPO_PROTO_IP6] = udp4_encap_ip6_nodes,
370 [DPO_PROTO_MPLS] = udp4_encap_mpls_nodes,
Neale Ranns91286372017-12-05 13:24:04 -0800371 [DPO_PROTO_BIER] = udp4_encap_bier_nodes,
Neale Ranns810086d2017-11-05 16:26:46 -0800372};
373
374const static char *const *const udp6_encap_nodes[DPO_PROTO_NUM] = {
375 [DPO_PROTO_IP4] = udp6_encap_ip4_nodes,
376 [DPO_PROTO_IP6] = udp6_encap_ip6_nodes,
377 [DPO_PROTO_MPLS] = udp6_encap_mpls_nodes,
Neale Ranns91286372017-12-05 13:24:04 -0800378 [DPO_PROTO_BIER] = udp6_encap_bier_nodes,
Neale Ranns810086d2017-11-05 16:26:46 -0800379};
380
381/*
382 * Virtual function table registered by UDP encaps
383 * for participation in the FIB object graph.
384 */
385const static fib_node_vft_t udp_encap_fib_vft = {
386 .fnv_get = udp_encap_fib_node_get,
387 .fnv_last_lock = udp_encap_fib_last_lock_gone,
388 .fnv_back_walk = udp_encap_fib_back_walk,
389};
390
391const static dpo_vft_t udp_encap_dpo_vft = {
392 .dv_lock = udp_encap_dpo_lock,
393 .dv_unlock = udp_encap_dpo_unlock,
394 .dv_format = format_udp_encap_dpo,
Neale Ranns810086d2017-11-05 16:26:46 -0800395};
396
397clib_error_t *
398udp_encap_init (vlib_main_t * vm)
399{
Neale Ranns810086d2017-11-05 16:26:46 -0800400 fib_node_register_type (FIB_NODE_TYPE_UDP_ENCAP, &udp_encap_fib_vft);
401
402 udp_encap_dpo_types[FIB_PROTOCOL_IP4] =
403 dpo_register_new_type (&udp_encap_dpo_vft, udp4_encap_nodes);
404 udp_encap_dpo_types[FIB_PROTOCOL_IP6] =
405 dpo_register_new_type (&udp_encap_dpo_vft, udp6_encap_nodes);
406
407 return (NULL);
408}
409
410VLIB_INIT_FUNCTION (udp_encap_init);
411
412clib_error_t *
413udp_encap_cli (vlib_main_t * vm,
414 unformat_input_t * main_input, vlib_cli_command_t * cmd)
415{
416 unformat_input_t _line_input, *line_input = &_line_input;
417 clib_error_t *error = NULL;
418 ip46_address_t src_ip, dst_ip;
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700419 u32 table_id, src_port, dst_port;
Neale Ranns810086d2017-11-05 16:26:46 -0800420 udp_encap_fixup_flags_t flags;
421 fib_protocol_t fproto;
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700422 index_t uei;
Neale Ranns810086d2017-11-05 16:26:46 -0800423 u8 is_del;
424
425 is_del = 0;
426 table_id = 0;
427 flags = UDP_ENCAP_FIXUP_NONE;
428 fproto = FIB_PROTOCOL_MAX;
429 dst_port = 0;
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700430 uei = ~0;
Neale Ranns810086d2017-11-05 16:26:46 -0800431
432 /* Get a line of input. */
433 if (!unformat_user (main_input, unformat_line_input, line_input))
434 return 0;
435
436 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
437 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700438 if (unformat (line_input, "index %d", &uei))
Neale Ranns810086d2017-11-05 16:26:46 -0800439 ;
440 else if (unformat (line_input, "add"))
441 is_del = 0;
442 else if (unformat (line_input, "del"))
443 is_del = 1;
444 else if (unformat (line_input, "%U %U",
445 unformat_ip4_address,
446 &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
447 fproto = FIB_PROTOCOL_IP4;
448 else if (unformat (line_input, "%U %U",
449 unformat_ip6_address,
450 &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
451 fproto = FIB_PROTOCOL_IP6;
452 else if (unformat (line_input, "%d %d", &src_port, &dst_port))
453 ;
454 else if (unformat (line_input, "%d", &dst_port))
455 ;
456 else if (unformat (line_input, "table-id %d", &table_id))
457 ;
458 else if (unformat (line_input, "src-port-is-entropy"))
459 flags |= UDP_ENCAP_FIXUP_UDP_SRC_PORT_ENTROPY;
460 else
461 {
462 error = unformat_parse_error (line_input);
463 goto done;
464 }
465 }
466
Neale Ranns810086d2017-11-05 16:26:46 -0800467 if (!is_del && fproto != FIB_PROTOCOL_MAX)
468 {
469 u32 fib_index;
470 index_t uei;
471
472 fib_index = fib_table_find (fproto, table_id);
473
474 if (~0 == fib_index)
475 {
476 error = clib_error_return (0, "Nonexistent table id %d", table_id);
477 goto done;
478 }
479
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700480 uei = udp_encap_add_and_lock (fproto, fib_index,
Neale Ranns810086d2017-11-05 16:26:46 -0800481 &src_ip, &dst_ip,
482 src_port, dst_port, flags);
483
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700484 vlib_cli_output (vm, "udp-encap: %d\n", uei);
Neale Ranns810086d2017-11-05 16:26:46 -0800485 }
486 else if (is_del)
487 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700488 if (INDEX_INVALID == uei)
489 {
490 error = clib_error_return (0, "specify udp-encap object index");
491 goto done;
492 }
493 udp_encap_unlock (uei);
Neale Ranns810086d2017-11-05 16:26:46 -0800494 }
495 else
496 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700497 error = clib_error_return (0, "specify some IP addresses");
Neale Ranns810086d2017-11-05 16:26:46 -0800498 }
499
500done:
501 unformat_free (line_input);
502 return error;
503}
504
Neale Ranns43b1f442018-03-20 01:47:35 -0700505void
506udp_encap_walk (udp_encap_walk_cb_t cb, void *ctx)
507{
508 index_t uei;
509
510 /* *INDENT-OFF* */
511 pool_foreach_index(uei, udp_encap_pool,
512 ({
Neale Ranns586479a2018-06-07 02:08:07 -0700513 if (WALK_STOP == cb(uei, ctx))
Neale Ranns43b1f442018-03-20 01:47:35 -0700514 break;
515 }));
516 /* *INDENT-ON* */
517}
518
Neale Ranns810086d2017-11-05 16:26:46 -0800519clib_error_t *
520udp_encap_show (vlib_main_t * vm,
521 unformat_input_t * input, vlib_cli_command_t * cmd)
522{
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700523 index_t uei;
Neale Ranns810086d2017-11-05 16:26:46 -0800524
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700525 uei = INDEX_INVALID;
Neale Ranns810086d2017-11-05 16:26:46 -0800526
527 /* Get a line of input. */
528 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
529 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700530 if (unformat (input, "%d", &uei))
Neale Ranns810086d2017-11-05 16:26:46 -0800531 ;
Swarup Nayak529a4252017-12-21 11:35:33 +0530532 else
533 return clib_error_return (0, "unknown input `%U'",
534 format_unformat_error, input);
Neale Ranns810086d2017-11-05 16:26:46 -0800535 }
536
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700537 if (INDEX_INVALID == uei)
Neale Ranns810086d2017-11-05 16:26:46 -0800538 {
Neale Ranns810086d2017-11-05 16:26:46 -0800539 /* *INDENT-OFF* */
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700540 pool_foreach_index(uei, udp_encap_pool,
Neale Ranns810086d2017-11-05 16:26:46 -0800541 ({
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700542 vlib_cli_output(vm, "%U", format_udp_encap, uei, 0);
Neale Ranns810086d2017-11-05 16:26:46 -0800543 }));
544 /* *INDENT-ON* */
545 }
546 else
547 {
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700548 vlib_cli_output (vm, "%U", format_udp_encap, uei, 1);
Neale Ranns810086d2017-11-05 16:26:46 -0800549 }
550
551 return NULL;
552}
553
554/* *INDENT-OFF* */
555VLIB_CLI_COMMAND (udp_encap_add_command, static) = {
556 .path = "udp encap",
557 .short_help = "udp encap [add|del] <id ID> <src-ip> <dst-ip> [<src-port>] <dst-port> [src-port-is-entropy] [table-id <table>]",
558 .function = udp_encap_cli,
559 .is_mp_safe = 1,
560};
561VLIB_CLI_COMMAND (udp_encap_show_command, static) = {
562 .path = "show udp encap",
563 .short_help = "show udp encap [ID]",
564 .function = udp_encap_show,
565 .is_mp_safe = 1,
566};
567/* *INDENT-ON* */
568
569/*
570 * fd.io coding-style-patch-verification: ON
571 *
572 * Local Variables:
573 * eval: (c-set-style "gnu")
574 * End:
575 */