LCOV - code coverage report
Current view: top level - vnet/udp - udp_encap.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 131 200 65.5 %
Date: 2023-10-26 01:39:38 Functions: 22 26 84.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017-2019 Cisco 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 <vnet/udp/udp_encap.h>
      17             : #include <vnet/fib/fib_entry.h>
      18             : #include <vnet/fib/fib_entry_track.h>
      19             : #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             :  */
      25             : dpo_type_t udp_encap_dpo_types[FIB_PROTOCOL_MAX];
      26             : 
      27             : /**
      28             :  * Pool of encaps
      29             :  */
      30             : udp_encap_t *udp_encap_pool;
      31             : 
      32             : /**
      33             :  * Stats for each UDP encap object
      34             :  */
      35             : vlib_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             : };
      45             : 
      46             : static void
      47          42 : udp_encap_restack (udp_encap_t * ue)
      48             : {
      49          84 :   dpo_stack (udp_encap_dpo_types[ue->ue_ip_proto],
      50          42 :              fib_proto_to_dpo (ue->ue_ip_proto), &ue->ue_dpo,
      51             :              fib_entry_contribute_ip_forwarding (ue->ue_fib_entry_index));
      52          42 : }
      53             : 
      54             : index_t
      55          10 : udp_encap_add_and_lock (fib_protocol_t proto,
      56             :                         index_t fib_index,
      57             :                         const ip46_address_t * src_ip,
      58             :                         const ip46_address_t * dst_ip,
      59             :                         u16 src_port,
      60             :                         u16 dst_port, udp_encap_fixup_flags_t flags)
      61             : {
      62             :   udp_encap_t *ue;
      63          10 :   u8 pfx_len = 0;
      64             :   index_t uei;
      65             : 
      66          10 :   pool_get_aligned_zero (udp_encap_pool, ue, CLIB_CACHE_LINE_BYTES);
      67          10 :   uei = ue - udp_encap_pool;
      68             : 
      69          10 :   vlib_validate_combined_counter (&(udp_encap_counters), uei);
      70          10 :   vlib_zero_combined_counter (&(udp_encap_counters), uei);
      71             : 
      72          10 :   fib_node_init (&ue->ue_fib_node, FIB_NODE_TYPE_UDP_ENCAP);
      73          10 :   fib_node_lock (&ue->ue_fib_node);
      74          10 :   ue->ue_fib_index = fib_index;
      75          10 :   ue->ue_flags = flags;
      76          10 :   ue->ue_ip_proto = proto;
      77             : 
      78          10 :   switch (proto)
      79             :     {
      80           6 :     case FIB_PROTOCOL_IP4:
      81           6 :       pfx_len = 32;
      82           6 :       ue->ue_hdrs.ip4.ue_ip4.ip_version_and_header_length = 0x45;
      83           6 :       ue->ue_hdrs.ip4.ue_ip4.ttl = 254;
      84           6 :       ue->ue_hdrs.ip4.ue_ip4.protocol = IP_PROTOCOL_UDP;
      85           6 :       ue->ue_hdrs.ip4.ue_ip4.src_address.as_u32 = src_ip->ip4.as_u32;
      86           6 :       ue->ue_hdrs.ip4.ue_ip4.dst_address.as_u32 = dst_ip->ip4.as_u32;
      87          12 :       ue->ue_hdrs.ip4.ue_ip4.checksum =
      88           6 :         ip4_header_checksum (&ue->ue_hdrs.ip4.ue_ip4);
      89           6 :       ue->ue_hdrs.ip4.ue_udp.src_port = clib_host_to_net_u16 (src_port);
      90           6 :       ue->ue_hdrs.ip4.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);
      91             : 
      92           6 :       break;
      93           4 :     case FIB_PROTOCOL_IP6:
      94           4 :       pfx_len = 128;
      95           8 :       ue->ue_hdrs.ip6.ue_ip6.ip_version_traffic_class_and_flow_label =
      96           4 :         clib_host_to_net_u32 (6 << 28);
      97           4 :       ue->ue_hdrs.ip6.ue_ip6.hop_limit = 255;
      98           4 :       ue->ue_hdrs.ip6.ue_ip6.protocol = IP_PROTOCOL_UDP;
      99           4 :       ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[0] = src_ip->ip6.as_u64[0];
     100           4 :       ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[1] = src_ip->ip6.as_u64[1];
     101           4 :       ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[0] = dst_ip->ip6.as_u64[0];
     102           4 :       ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[1] = dst_ip->ip6.as_u64[1];
     103           4 :       ue->ue_hdrs.ip6.ue_udp.src_port = clib_host_to_net_u16 (src_port);
     104           4 :       ue->ue_hdrs.ip6.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);
     105             : 
     106           4 :       break;
     107           0 :     default:
     108           0 :       ASSERT (0);
     109             :     }
     110             : 
     111             :   /*
     112             :    * track the destination address
     113             :    */
     114          10 :   fib_prefix_t dst_pfx = {
     115             :     .fp_proto = proto,
     116             :     .fp_len = pfx_len,
     117             :     .fp_addr = *dst_ip,
     118             :   };
     119             : 
     120          20 :   ue->ue_fib_entry_index = fib_entry_track (fib_index,
     121             :                                             &dst_pfx,
     122             :                                             FIB_NODE_TYPE_UDP_ENCAP,
     123          10 :                                             uei, &ue->ue_fib_sibling);
     124          10 :   udp_encap_restack (ue);
     125             : 
     126          10 :   return (uei);
     127             : }
     128             : 
     129             : void
     130          13 : udp_encap_contribute_forwarding (index_t uei, dpo_proto_t proto,
     131             :                                  dpo_id_t * dpo)
     132             : {
     133          13 :   if (INDEX_INVALID == uei)
     134             :     {
     135           0 :       dpo_copy (dpo, drop_dpo_get (proto));
     136             :     }
     137             :   else
     138             :     {
     139             :       udp_encap_t *ue;
     140             : 
     141          13 :       ue = udp_encap_get (uei);
     142             : 
     143          13 :       dpo_set (dpo, udp_encap_dpo_types[ue->ue_ip_proto], proto, uei);
     144             :     }
     145          13 : }
     146             : 
     147             : void
     148          11 : udp_encap_lock (index_t uei)
     149             : {
     150             :   udp_encap_t *ue;
     151             : 
     152          11 :   ue = udp_encap_get (uei);
     153             : 
     154          11 :   if (NULL != ue)
     155             :     {
     156          11 :       fib_node_lock (&ue->ue_fib_node);
     157             :     }
     158          11 : }
     159             : 
     160             : void
     161          21 : udp_encap_unlock (index_t uei)
     162             : {
     163             :   udp_encap_t *ue;
     164             : 
     165          21 :   if (INDEX_INVALID == uei)
     166             :     {
     167           0 :       return;
     168             :     }
     169             : 
     170          21 :   ue = udp_encap_get (uei);
     171             : 
     172          21 :   if (NULL != ue)
     173             :     {
     174          21 :       fib_node_unlock (&ue->ue_fib_node);
     175             :     }
     176             : }
     177             : 
     178             : static void
     179          49 : udp_encap_dpo_lock (dpo_id_t * dpo)
     180             : {
     181             :   udp_encap_t *ue;
     182             : 
     183          49 :   ue = udp_encap_get (dpo->dpoi_index);
     184             : 
     185          49 :   fib_node_lock (&ue->ue_fib_node);
     186          49 : }
     187             : 
     188             : static void
     189          49 : udp_encap_dpo_unlock (dpo_id_t * dpo)
     190             : {
     191             :   udp_encap_t *ue;
     192             : 
     193          49 :   ue = udp_encap_get (dpo->dpoi_index);
     194             : 
     195          49 :   fib_node_unlock (&ue->ue_fib_node);
     196          49 : }
     197             : 
     198             : u8 *
     199         594 : format_udp_encap_fixup_flags (u8 *s, va_list *args)
     200             : {
     201         594 :   udp_encap_fixup_flags_t flags = va_arg (*args, udp_encap_fixup_flags_t);
     202             : 
     203         594 :   if (flags == UDP_ENCAP_FIXUP_NONE)
     204         323 :     return format (s, "none");
     205             : 
     206         271 :   if (flags & UDP_ENCAP_FIXUP_UDP_SRC_PORT_ENTROPY)
     207         271 :     s = format (s, "%s", "src-port-is-entropy");
     208             : 
     209         271 :   return (s);
     210             : }
     211             : 
     212             : static u8 *
     213           9 : format_udp_encap_i (u8 * s, va_list * args)
     214             : {
     215           9 :   index_t uei = va_arg (*args, index_t);
     216           9 :   u32 indent = va_arg (*args, u32);
     217           9 :   u32 details = va_arg (*args, u32);
     218             :   vlib_counter_t to;
     219             :   udp_encap_t *ue;
     220             : 
     221           9 :   ue = udp_encap_get (uei);
     222             : 
     223             :   // FIXME
     224           9 :   s = format (s, "udp-encap:[%d]: ip-fib-index:%d ", uei, ue->ue_fib_index);
     225           9 :   if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
     226             :     {
     227           5 :       s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d, dst:%d] flags:%U",
     228             :                   format_ip4_address, &ue->ue_hdrs.ip4.ue_ip4.src_address,
     229             :                   format_ip4_address, &ue->ue_hdrs.ip4.ue_ip4.dst_address,
     230           5 :                   clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.src_port),
     231           5 :                   clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.dst_port),
     232           5 :                   format_udp_encap_fixup_flags, ue->ue_flags);
     233             :     }
     234             :   else
     235             :     {
     236           4 :       s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d dst:%d] flags:%U",
     237             :                   format_ip6_address, &ue->ue_hdrs.ip6.ue_ip6.src_address,
     238             :                   format_ip6_address, &ue->ue_hdrs.ip6.ue_ip6.dst_address,
     239           4 :                   clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.src_port),
     240           4 :                   clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.dst_port),
     241           4 :                   format_udp_encap_fixup_flags, ue->ue_flags);
     242             :     }
     243           9 :   vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
     244           9 :   s = format (s, " to:[%Ld:%Ld]]", to.packets, to.bytes);
     245             : 
     246           9 :   if (details)
     247             :     {
     248           0 :       s = format (s, " locks:%d", ue->ue_fib_node.fn_locks);
     249           0 :       s = format (s, "\n%UStacked on:", format_white_space, indent + 1);
     250           0 :       s = format (s, "\n%U%U",
     251             :                   format_white_space, indent + 2,
     252             :                   format_dpo_id, &ue->ue_dpo, indent + 3);
     253             :     }
     254           9 :   return (s);
     255             : }
     256             : 
     257             : void
     258           0 : udp_encap_get_stats (index_t uei, u64 * packets, u64 * bytes)
     259             : {
     260             :   vlib_counter_t to;
     261             : 
     262           0 :   vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
     263             : 
     264           0 :   *packets = to.packets;
     265           0 :   *bytes = to.bytes;
     266           0 : }
     267             : 
     268             : static u8 *
     269           0 : format_udp_encap_dpo (u8 * s, va_list * args)
     270             : {
     271           0 :   index_t uei = va_arg (*args, index_t);
     272           0 :   u32 indent = va_arg (*args, u32);
     273             : 
     274           0 :   return (format (s, "%U", format_udp_encap_i, uei, indent, 1));
     275             : }
     276             : 
     277             : u8 *
     278           9 : format_udp_encap (u8 * s, va_list * args)
     279             : {
     280           9 :   index_t uei = va_arg (*args, u32);
     281           9 :   u32 details = va_arg (*args, u32);
     282             : 
     283           9 :   return (format (s, "%U", format_udp_encap_i, uei, 0, details));
     284             : }
     285             : 
     286             : static udp_encap_t *
     287          42 : udp_encap_from_fib_node (fib_node_t * node)
     288             : {
     289          42 :   ASSERT (FIB_NODE_TYPE_UDP_ENCAP == node->fn_type);
     290          42 :   return ((udp_encap_t *) (((char *) node) -
     291             :                            STRUCT_OFFSET_OF (udp_encap_t, ue_fib_node)));
     292             : }
     293             : 
     294             : /**
     295             :  * Function definition to backwalk a FIB node
     296             :  */
     297             : static fib_node_back_walk_rc_t
     298          32 : udp_encap_fib_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
     299             : {
     300          32 :   udp_encap_restack (udp_encap_from_fib_node (node));
     301             : 
     302          32 :   return (FIB_NODE_BACK_WALK_CONTINUE);
     303             : }
     304             : 
     305             : /**
     306             :  * Function definition to get a FIB node from its index
     307             :  */
     308             : static fib_node_t *
     309          32 : udp_encap_fib_node_get (fib_node_index_t index)
     310             : {
     311             :   udp_encap_t *ue;
     312             : 
     313          32 :   ue = pool_elt_at_index (udp_encap_pool, index);
     314             : 
     315          32 :   return (&ue->ue_fib_node);
     316             : }
     317             : 
     318             : /**
     319             :  * Function definition to inform the FIB node that its last lock has gone.
     320             :  */
     321             : static void
     322          10 : udp_encap_fib_last_lock_gone (fib_node_t * node)
     323             : {
     324             :   udp_encap_t *ue;
     325             : 
     326          10 :   ue = udp_encap_from_fib_node (node);
     327             : 
     328             :     /**
     329             :      * reset the stacked DPO to unlock it
     330             :      */
     331          10 :   dpo_reset (&ue->ue_dpo);
     332             : 
     333          10 :   fib_entry_untrack (ue->ue_fib_entry_index, ue->ue_fib_sibling);
     334             : 
     335          10 :   pool_put (udp_encap_pool, ue);
     336          10 : }
     337             : 
     338             : const static char *const udp4_encap_ip4_nodes[] = {
     339             :   "udp4o4-encap",
     340             :   NULL,
     341             : };
     342             : 
     343             : const static char *const udp4_encap_ip6_nodes[] = {
     344             :   "udp6o4-encap",
     345             :   NULL,
     346             : };
     347             : 
     348             : const static char *const udp4_encap_mpls_nodes[] = {
     349             :   "udp4-encap",
     350             :   NULL,
     351             : };
     352             : 
     353             : const static char *const udp4_encap_bier_nodes[] = {
     354             :   "udp4-encap",
     355             :   NULL,
     356             : };
     357             : 
     358             : const static char *const udp6_encap_ip4_nodes[] = {
     359             :   "udp4o6-encap",
     360             :   NULL,
     361             : };
     362             : 
     363             : const static char *const udp6_encap_ip6_nodes[] = {
     364             :   "udp6o6-encap",
     365             :   NULL,
     366             : };
     367             : 
     368             : const static char *const udp6_encap_mpls_nodes[] = {
     369             :   "udp6-encap",
     370             :   NULL,
     371             : };
     372             : 
     373             : const static char *const udp6_encap_bier_nodes[] = {
     374             :   "udp6-encap",
     375             :   NULL,
     376             : };
     377             : 
     378             : const static char *const *const udp4_encap_nodes[DPO_PROTO_NUM] = {
     379             :   [DPO_PROTO_IP4] = udp4_encap_ip4_nodes,
     380             :   [DPO_PROTO_IP6] = udp4_encap_ip6_nodes,
     381             :   [DPO_PROTO_MPLS] = udp4_encap_mpls_nodes,
     382             :   [DPO_PROTO_BIER] = udp4_encap_bier_nodes,
     383             : };
     384             : 
     385             : const static char *const *const udp6_encap_nodes[DPO_PROTO_NUM] = {
     386             :   [DPO_PROTO_IP4] = udp6_encap_ip4_nodes,
     387             :   [DPO_PROTO_IP6] = udp6_encap_ip6_nodes,
     388             :   [DPO_PROTO_MPLS] = udp6_encap_mpls_nodes,
     389             :   [DPO_PROTO_BIER] = udp6_encap_bier_nodes,
     390             : };
     391             : 
     392             : /*
     393             :  * Virtual function table registered by UDP encaps
     394             :  * for participation in the FIB object graph.
     395             :  */
     396             : const static fib_node_vft_t udp_encap_fib_vft = {
     397             :   .fnv_get = udp_encap_fib_node_get,
     398             :   .fnv_last_lock = udp_encap_fib_last_lock_gone,
     399             :   .fnv_back_walk = udp_encap_fib_back_walk,
     400             : };
     401             : 
     402             : const static dpo_vft_t udp_encap_dpo_vft = {
     403             :   .dv_lock = udp_encap_dpo_lock,
     404             :   .dv_unlock = udp_encap_dpo_unlock,
     405             :   .dv_format = format_udp_encap_dpo,
     406             : };
     407             : 
     408             : clib_error_t *
     409         575 : udp_encap_init (vlib_main_t * vm)
     410             : {
     411         575 :   fib_node_register_type (FIB_NODE_TYPE_UDP_ENCAP, &udp_encap_fib_vft);
     412             : 
     413         575 :   udp_encap_dpo_types[FIB_PROTOCOL_IP4] =
     414         575 :     dpo_register_new_type (&udp_encap_dpo_vft, udp4_encap_nodes);
     415         575 :   udp_encap_dpo_types[FIB_PROTOCOL_IP6] =
     416         575 :     dpo_register_new_type (&udp_encap_dpo_vft, udp6_encap_nodes);
     417             : 
     418         575 :   return (NULL);
     419             : }
     420             : 
     421       61631 : VLIB_INIT_FUNCTION (udp_encap_init);
     422             : 
     423             : clib_error_t *
     424           0 : udp_encap_cli (vlib_main_t * vm,
     425             :                unformat_input_t * main_input, vlib_cli_command_t * cmd)
     426             : {
     427           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     428           0 :   clib_error_t *error = NULL;
     429             :   ip46_address_t src_ip, dst_ip;
     430             :   u32 table_id, src_port, dst_port;
     431             :   udp_encap_fixup_flags_t flags;
     432             :   fib_protocol_t fproto;
     433             :   index_t uei;
     434             :   u8 is_del;
     435             : 
     436           0 :   is_del = 0;
     437           0 :   table_id = 0;
     438           0 :   flags = UDP_ENCAP_FIXUP_NONE;
     439           0 :   fproto = FIB_PROTOCOL_MAX;
     440           0 :   dst_port = 0;
     441           0 :   uei = ~0;
     442             : 
     443             :   /* Get a line of input. */
     444           0 :   if (!unformat_user (main_input, unformat_line_input, line_input))
     445           0 :     return 0;
     446             : 
     447           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     448             :     {
     449           0 :       if (unformat (line_input, "index %d", &uei))
     450             :         ;
     451           0 :       else if (unformat (line_input, "add"))
     452           0 :         is_del = 0;
     453           0 :       else if (unformat (line_input, "del"))
     454           0 :         is_del = 1;
     455           0 :       else if (unformat (line_input, "%U %U",
     456             :                          unformat_ip4_address,
     457             :                          &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
     458           0 :         fproto = FIB_PROTOCOL_IP4;
     459           0 :       else if (unformat (line_input, "%U %U",
     460             :                          unformat_ip6_address,
     461             :                          &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
     462           0 :         fproto = FIB_PROTOCOL_IP6;
     463           0 :       else if (unformat (line_input, "%d %d", &src_port, &dst_port))
     464             :         ;
     465           0 :       else if (unformat (line_input, "%d", &dst_port))
     466             :         ;
     467           0 :       else if (unformat (line_input, "table-id %d", &table_id))
     468             :         ;
     469           0 :       else if (unformat (line_input, "src-port-is-entropy"))
     470           0 :         flags |= UDP_ENCAP_FIXUP_UDP_SRC_PORT_ENTROPY;
     471             :       else
     472             :         {
     473           0 :           error = unformat_parse_error (line_input);
     474           0 :           goto done;
     475             :         }
     476             :     }
     477             : 
     478           0 :   if (!is_del && fproto != FIB_PROTOCOL_MAX)
     479           0 :     {
     480             :       u32 fib_index;
     481             :       index_t uei;
     482             : 
     483           0 :       fib_index = fib_table_find (fproto, table_id);
     484             : 
     485           0 :       if (~0 == fib_index)
     486             :         {
     487           0 :           error = clib_error_return (0, "Nonexistent table id %d", table_id);
     488           0 :           goto done;
     489             :         }
     490             : 
     491           0 :       uei = udp_encap_add_and_lock (fproto, fib_index,
     492             :                                     &src_ip, &dst_ip,
     493             :                                     src_port, dst_port, flags);
     494             : 
     495           0 :       vlib_cli_output (vm, "udp-encap: %d\n", uei);
     496             :     }
     497           0 :   else if (is_del)
     498             :     {
     499           0 :       if (INDEX_INVALID == uei)
     500             :         {
     501           0 :           error = clib_error_return (0, "specify udp-encap object index");
     502           0 :           goto done;
     503             :         }
     504           0 :       udp_encap_unlock (uei);
     505             :     }
     506             :   else
     507             :     {
     508           0 :       error = clib_error_return (0, "specify some IP addresses");
     509             :     }
     510             : 
     511           0 : done:
     512           0 :   unformat_free (line_input);
     513           0 :   return error;
     514             : }
     515             : 
     516             : void
     517           0 : udp_encap_walk (udp_encap_walk_cb_t cb, void *ctx)
     518             : {
     519             :   index_t uei;
     520             : 
     521             :   /* *INDENT-OFF* */
     522           0 :   pool_foreach_index (uei, udp_encap_pool)
     523             :    {
     524           0 :     if (WALK_STOP == cb(uei, ctx))
     525           0 :       break;
     526             :   }
     527             :   /* *INDENT-ON* */
     528           0 : }
     529             : 
     530             : clib_error_t *
     531           2 : udp_encap_show (vlib_main_t * vm,
     532             :                 unformat_input_t * input, vlib_cli_command_t * cmd)
     533             : {
     534             :   index_t uei;
     535             : 
     536           2 :   uei = INDEX_INVALID;
     537             : 
     538             :   /* Get a line of input. */
     539           2 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     540             :     {
     541           0 :       if (unformat (input, "%d", &uei))
     542             :         ;
     543             :       else
     544           0 :         return clib_error_return (0, "unknown input `%U'",
     545             :                                   format_unformat_error, input);
     546             :     }
     547             : 
     548           2 :   if (INDEX_INVALID == uei)
     549             :     {
     550             :       /* *INDENT-OFF* */
     551          11 :       pool_foreach_index (uei, udp_encap_pool)
     552             :        {
     553           9 :         vlib_cli_output(vm, "%U", format_udp_encap, uei, 0);
     554             :       }
     555             :       /* *INDENT-ON* */
     556             :     }
     557             :   else
     558             :     {
     559           0 :       vlib_cli_output (vm, "%U", format_udp_encap, uei, 1);
     560             :     }
     561             : 
     562           2 :   return NULL;
     563             : }
     564             : 
     565             : /* *INDENT-OFF* */
     566      285289 : VLIB_CLI_COMMAND (udp_encap_add_command, static) = {
     567             :   .path = "udp encap",
     568             :   .short_help = "udp encap [add|del] <id ID> <src-ip> <dst-ip> [<src-port>] "
     569             :                 "<dst-port> [src-port-is-entropy] [table-id <table>]",
     570             :   .function = udp_encap_cli,
     571             :   .is_mp_safe = 1,
     572             : };
     573             : 
     574      285289 : VLIB_CLI_COMMAND (udp_encap_show_command, static) = {
     575             :   .path = "show udp encap",
     576             :   .short_help = "show udp encap [ID]",
     577             :   .function = udp_encap_show,
     578             :   .is_mp_safe = 1,
     579             : };
     580             : /* *INDENT-ON* */
     581             : 
     582             : /*
     583             :  * fd.io coding-style-patch-verification: ON
     584             :  *
     585             :  * Local Variables:
     586             :  * eval: (c-set-style "gnu")
     587             :  * End:
     588             :  */

Generated by: LCOV version 1.14