LCOV - code coverage report
Current view: top level - plugins/lisp/lisp-gpe - lisp_gpe_adjacency.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 93 201 46.3 %
Date: 2023-10-26 01:39:38 Functions: 19 30 63.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 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             :  * @file
      17             :  * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
      18             :  *
      19             :  */
      20             : 
      21             : #include <vnet/dpo/load_balance.h>
      22             : #include <lisp/lisp-cp/control.h>
      23             : #include <lisp/lisp-cp/lisp_types.h>
      24             : #include <lisp/lisp-gpe/lisp_gpe_sub_interface.h>
      25             : #include <lisp/lisp-gpe/lisp_gpe_adjacency.h>
      26             : #include <lisp/lisp-gpe/lisp_gpe_tunnel.h>
      27             : #include <vnet/fib/fib_entry.h>
      28             : #include <vnet/adj/adj_midchain.h>
      29             : #include <vnet/udp/udp_inlines.h>
      30             : #include <vppinfra/bihash_24_8.h>
      31             : #include <vppinfra/bihash_template.h>
      32             : 
      33             : /**
      34             :  * Memory pool of all adjacencies
      35             :  */
      36             : static lisp_gpe_adjacency_t *lisp_adj_pool;
      37             : 
      38             : /**
      39             :  * Hash table of all adjacencies. key:{nh, itf}
      40             :  * We never have an all zeros address since the interfaces are multi-access,
      41             :  * therefore there is no ambiguity between a v4 and v6 next-hop, so we don't
      42             :  * need to add the protocol to the key.
      43             :  */
      44             : static
      45             : BVT (clib_bihash)
      46             :   lisp_adj_db;
      47             : 
      48             : #define LISP_ADJ_SET_KEY(_key, _itf, _nh)       \
      49             : {                                               \
      50             :   _key.key[0] = ip_addr_v6((_nh)).as_u64[0];    \
      51             :   _key.key[1] = ip_addr_v6((_nh)).as_u64[1];    \
      52             :   _key.key[2] = (_itf);                         \
      53             : }
      54             : 
      55           2 :      static index_t lisp_adj_find (const ip_address_t * addr, u32 sw_if_index)
      56             : {
      57             :   BVT (clib_bihash_kv) kv;
      58             : 
      59           2 :   LISP_ADJ_SET_KEY (kv, sw_if_index, addr);
      60             : 
      61           2 :   if (BV (clib_bihash_search) (&lisp_adj_db, &kv, &kv) < 0)
      62             :     {
      63           1 :       return (INDEX_INVALID);
      64             :     }
      65             :   else
      66             :     {
      67           1 :       return (kv.value);
      68             :     }
      69             : }
      70             : 
      71             : static void
      72           1 : lisp_adj_insert (const ip_address_t * addr, u32 sw_if_index, index_t ai)
      73             : {
      74             :   BVT (clib_bihash_kv) kv;
      75             : 
      76           1 :   LISP_ADJ_SET_KEY (kv, sw_if_index, addr);
      77           1 :   kv.value = ai;
      78             : 
      79           1 :   BV (clib_bihash_add_del) (&lisp_adj_db, &kv, 1);
      80           1 : }
      81             : 
      82             : static void
      83           1 : lisp_adj_remove (const ip_address_t * addr, u32 sw_if_index)
      84             : {
      85             :   BVT (clib_bihash_kv) kv;
      86             : 
      87           1 :   LISP_ADJ_SET_KEY (kv, sw_if_index, addr);
      88             : 
      89           1 :   BV (clib_bihash_add_del) (&lisp_adj_db, &kv, 0);
      90           1 : }
      91             : 
      92             : static lisp_gpe_adjacency_t *
      93           4 : lisp_gpe_adjacency_get_i (index_t lai)
      94             : {
      95           4 :   return (pool_elt_at_index (lisp_adj_pool, lai));
      96             : }
      97             : 
      98             : fib_forward_chain_type_t
      99           1 : lisp_gpe_adj_get_fib_chain_type (const lisp_gpe_adjacency_t * ladj)
     100             : {
     101           1 :   switch (ip_addr_version (&ladj->remote_rloc))
     102             :     {
     103           1 :     case AF_IP4:
     104           1 :       return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
     105           0 :     case AF_IP6:
     106           0 :       return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
     107           0 :     default:
     108           0 :       ASSERT (0);
     109           0 :       break;
     110             :     }
     111           0 :   return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
     112             : }
     113             : 
     114             : static void
     115           1 : ip46_address_to_ip_address (const ip46_address_t * a, ip_address_t * b)
     116             : {
     117           1 :   if (ip46_address_is_ip4 (a))
     118             :     {
     119           1 :       clib_memset (b, 0, sizeof (*b));
     120           1 :       ip_address_set (b, &a->ip4, AF_IP4);
     121             :     }
     122             :   else
     123             :     {
     124           0 :       ip_address_set (b, &a->ip6, AF_IP6);
     125             :     }
     126           1 : }
     127             : 
     128             : /**
     129             :  * @brief Stack the tunnel's midchain on the IP forwarding chain of the via
     130             :  */
     131             : static void
     132           1 : lisp_gpe_adj_stack_one (lisp_gpe_adjacency_t * ladj, adj_index_t ai)
     133             : {
     134             :   const lisp_gpe_tunnel_t *lgt;
     135             : 
     136           1 :   lgt = lisp_gpe_tunnel_get (ladj->tunnel_index);
     137             : 
     138           1 :   adj_nbr_midchain_stack_on_fib_entry (ai,
     139             :                                        lgt->fib_entry_index,
     140           1 :                                        lisp_gpe_adj_get_fib_chain_type
     141             :                                        (ladj));
     142           1 : }
     143             : 
     144             : /**
     145             :  * @brief Call back when restacking all adjacencies on a GRE interface
     146             :  */
     147             : static adj_walk_rc_t
     148           0 : lisp_gpe_adj_walk_cb (adj_index_t ai, void *ctx)
     149             : {
     150           0 :   lisp_gpe_adjacency_t *ladj = ctx;
     151             : 
     152           0 :   lisp_gpe_adj_stack_one (ladj, ai);
     153             : 
     154           0 :   return (ADJ_WALK_RC_CONTINUE);
     155             : }
     156             : 
     157             : static void
     158           0 : lisp_gpe_adj_stack (lisp_gpe_adjacency_t * ladj)
     159             : {
     160             :   fib_protocol_t nh_proto;
     161             :   ip46_address_t nh;
     162             : 
     163           0 :   nh_proto = ip_address_to_46 (&ladj->remote_rloc, &nh);
     164             : 
     165             :   /*
     166             :    * walk all the adjacencies on th lisp interface and restack them
     167             :    */
     168           0 :   adj_nbr_walk_nh (ladj->sw_if_index,
     169             :                    nh_proto, &nh, lisp_gpe_adj_walk_cb, ladj);
     170           0 : }
     171             : 
     172             : static lisp_gpe_next_protocol_e
     173           1 : lisp_gpe_adj_proto_from_vnet_link_type (vnet_link_t linkt)
     174             : {
     175           1 :   switch (linkt)
     176             :     {
     177           1 :     case VNET_LINK_IP4:
     178           1 :       return (LISP_GPE_NEXT_PROTO_IP4);
     179           0 :     case VNET_LINK_IP6:
     180           0 :       return (LISP_GPE_NEXT_PROTO_IP6);
     181           0 :     case VNET_LINK_ETHERNET:
     182           0 :       return (LISP_GPE_NEXT_PROTO_ETHERNET);
     183           0 :     case VNET_LINK_NSH:
     184           0 :       return (LISP_GPE_NEXT_PROTO_NSH);
     185           0 :     default:
     186           0 :       ASSERT (0);
     187             :     }
     188           0 :   return (LISP_GPE_NEXT_PROTO_IP4);
     189             : }
     190             : 
     191             : #define is_v4_packet(_h) ((*(u8*) _h) & 0xF0) == 0x40
     192             : 
     193             : static lisp_afi_e
     194           0 : lisp_afi_from_vnet_link_type (vnet_link_t link)
     195             : {
     196           0 :   switch (link)
     197             :     {
     198           0 :     case VNET_LINK_IP4:
     199           0 :       return LISP_AFI_IP;
     200           0 :     case VNET_LINK_IP6:
     201           0 :       return LISP_AFI_IP6;
     202           0 :     case VNET_LINK_ETHERNET:
     203           0 :       return LISP_AFI_MAC;
     204           0 :     default:
     205           0 :       return LISP_AFI_NO_ADDR;
     206             :     }
     207             : }
     208             : 
     209             : static void
     210           0 : lisp_gpe_increment_stats_counters (lisp_cp_main_t * lcm,
     211             :                                    const ip_adjacency_t * adj,
     212             :                                    vlib_buffer_t * b)
     213             : {
     214           0 :   lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
     215             :   lisp_gpe_adjacency_t *ladj;
     216             :   ip_address_t rloc;
     217             :   index_t lai;
     218             :   u32 si, di;
     219             :   gid_address_t src, dst;
     220             :   uword *feip;
     221             : 
     222           0 :   ip46_address_to_ip_address (&adj->sub_type.nbr.next_hop, &rloc);
     223           0 :   si = vnet_buffer (b)->sw_if_index[VLIB_TX];
     224           0 :   lai = lisp_adj_find (&rloc, si);
     225           0 :   ASSERT (INDEX_INVALID != lai);
     226             : 
     227           0 :   ladj = pool_elt_at_index (lisp_adj_pool, lai);
     228             : 
     229           0 :   u8 *lisp_data = (u8 *) vlib_buffer_get_current (b);
     230             : 
     231             :   /* skip IP header */
     232           0 :   if (is_v4_packet (lisp_data))
     233           0 :     lisp_data += sizeof (ip4_header_t);
     234             :   else
     235           0 :     lisp_data += sizeof (ip6_header_t);
     236             : 
     237             :   /* skip UDP header */
     238           0 :   lisp_data += sizeof (udp_header_t);
     239             :   // TODO: skip TCP?
     240             : 
     241             :   /* skip LISP GPE header */
     242           0 :   lisp_data += sizeof (lisp_gpe_header_t);
     243             : 
     244           0 :   i16 saved_current_data = b->current_data;
     245           0 :   b->current_data = lisp_data - b->data;
     246             : 
     247           0 :   lisp_afi_e afi = lisp_afi_from_vnet_link_type (adj->ia_link);
     248           0 :   get_src_and_dst_eids_from_buffer (lcm, b, &src, &dst, afi);
     249           0 :   b->current_data = saved_current_data;
     250           0 :   di = gid_dictionary_sd_lookup (&lcm->mapping_index_by_gid, &dst, &src);
     251           0 :   if (PREDICT_FALSE (~0 == di))
     252             :     {
     253           0 :       clib_warning ("dst mapping not found (%U, %U)", format_gid_address,
     254             :                     &src, format_gid_address, &dst);
     255           0 :       return;
     256             :     }
     257             : 
     258           0 :   feip = hash_get (lcm->fwd_entry_by_mapping_index, di);
     259           0 :   if (PREDICT_FALSE (!feip))
     260           0 :     return;
     261             : 
     262             :   lisp_stats_key_t key;
     263           0 :   clib_memset (&key, 0, sizeof (key));
     264           0 :   key.fwd_entry_index = feip[0];
     265           0 :   key.tunnel_index = ladj->tunnel_index;
     266             : 
     267           0 :   uword *p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
     268           0 :   ALWAYS_ASSERT (p);
     269             : 
     270             :   /* compute payload length starting after GPE */
     271           0 :   u32 bytes = b->current_length - (lisp_data - b->data - b->current_data);
     272           0 :   vlib_increment_combined_counter (&lgm->counters, vlib_get_thread_index (),
     273           0 :                                    p[0], 1, bytes);
     274             : }
     275             : 
     276             : static void
     277           1 : lisp_gpe_fixup (vlib_main_t * vm,
     278             :                 const ip_adjacency_t * adj,
     279             :                 vlib_buffer_t * b, const void *data)
     280             : {
     281           1 :   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
     282             : 
     283           1 :   if (lcm->flags & LISP_FLAG_STATS_ENABLED)
     284           0 :     lisp_gpe_increment_stats_counters (lcm, adj, b);
     285             : 
     286             :   /* Fixup the checksum and len fields in the LISP tunnel encap
     287             :    * that was applied at the midchain node */
     288           1 :   ip_udp_fixup_one (vm, b, is_v4_packet (vlib_buffer_get_current (b)),
     289             :                     UDP_ENCAP_FIXUP_NONE);
     290           1 : }
     291             : 
     292             : /**
     293             :  * @brief The LISP-GPE interface registered function to update, i.e.
     294             :  * provide an rewrite string for, an adjacency.
     295             :  */
     296             : void
     297           1 : lisp_gpe_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
     298             : {
     299             :   const lisp_gpe_tunnel_t *lgt;
     300             :   lisp_gpe_adjacency_t *ladj;
     301             :   ip_adjacency_t *adj;
     302             :   ip_address_t rloc;
     303             :   vnet_link_t linkt;
     304             :   adj_flags_t af;
     305             :   index_t lai;
     306             : 
     307           1 :   adj = adj_get (ai);
     308           1 :   ip46_address_to_ip_address (&adj->sub_type.nbr.next_hop, &rloc);
     309             : 
     310             :   /*
     311             :    * find an existing or create a new adj
     312             :    */
     313           1 :   lai = lisp_adj_find (&rloc, sw_if_index);
     314             : 
     315           1 :   ASSERT (INDEX_INVALID != lai);
     316             : 
     317           1 :   ladj = pool_elt_at_index (lisp_adj_pool, lai);
     318           1 :   lgt = lisp_gpe_tunnel_get (ladj->tunnel_index);
     319           1 :   linkt = adj_get_link_type (ai);
     320           1 :   af = ADJ_FLAG_MIDCHAIN_IP_STACK;
     321             : 
     322           1 :   adj_nbr_midchain_update_rewrite
     323             :     (ai, lisp_gpe_fixup, NULL, af,
     324             :      lisp_gpe_tunnel_build_rewrite (lgt, ladj,
     325             :                                     lisp_gpe_adj_proto_from_vnet_link_type
     326             :                                     (linkt)));
     327             : 
     328           1 :   lisp_gpe_adj_stack_one (ladj, ai);
     329           1 : }
     330             : 
     331             : u8 *
     332           0 : lisp_gpe_build_rewrite (vnet_main_t * vnm,
     333             :                         u32 sw_if_index,
     334             :                         vnet_link_t link_type, const void *dst_address)
     335             : {
     336           0 :   ASSERT (0);
     337           0 :   return (NULL);
     338             : }
     339             : 
     340             : index_t
     341           1 : lisp_gpe_adjacency_find_or_create_and_lock (const locator_pair_t * pair,
     342             :                                             u32 overlay_table_id, u32 vni)
     343             : {
     344             :   const lisp_gpe_sub_interface_t *l3s;
     345             :   const lisp_gpe_tunnel_t *lgt;
     346             :   lisp_gpe_adjacency_t *ladj;
     347             :   index_t lai, l3si;
     348             : 
     349             :   /*
     350             :    * first find the L3 sub-interface that corresponds to the loacl-rloc and vni
     351             :    */
     352           1 :   l3si = lisp_gpe_sub_interface_find_or_create_and_lock (&pair->lcl_loc,
     353             :                                                          overlay_table_id,
     354             :                                                          vni);
     355           1 :   l3s = lisp_gpe_sub_interface_get (l3si);
     356             : 
     357             :   /*
     358             :    * find an existing or create a new adj
     359             :    */
     360           1 :   lai = lisp_adj_find (&pair->rmt_loc, l3s->sw_if_index);
     361             : 
     362           1 :   if (INDEX_INVALID == lai)
     363             :     {
     364             : 
     365           1 :       pool_get (lisp_adj_pool, ladj);
     366           1 :       clib_memset (ladj, 0, sizeof (*ladj));
     367           1 :       lai = (ladj - lisp_adj_pool);
     368             : 
     369           1 :       ip_address_copy (&ladj->remote_rloc, &pair->rmt_loc);
     370           1 :       ladj->vni = vni;
     371             :       /* transfer the lock to the adj */
     372           1 :       ladj->lisp_l3_sub_index = l3si;
     373           1 :       ladj->sw_if_index = l3s->sw_if_index;
     374             : 
     375             :       /* if vni is non-default */
     376           1 :       if (ladj->vni)
     377           0 :         ladj->flags = LISP_GPE_FLAGS_I;
     378             : 
     379             :       /* work in lisp-gpe not legacy mode */
     380           1 :       ladj->flags |= LISP_GPE_FLAGS_P;
     381             : 
     382             :       /*
     383             :        * find the tunnel that will provide the underlying transport
     384             :        * and hence the rewrite.
     385             :        * The RLOC FIB index is default table - always.
     386             :        */
     387           1 :       ladj->tunnel_index = lisp_gpe_tunnel_find_or_create_and_lock (pair, 0);
     388             : 
     389           1 :       lgt = lisp_gpe_tunnel_get (ladj->tunnel_index);
     390             : 
     391             :       /*
     392             :        * become of child of the RLOC FIB entry so we are updated when
     393             :        * its reachability changes, allowing us to re-stack the midcahins
     394             :        */
     395           1 :       ladj->fib_entry_child_index = fib_entry_child_add (lgt->fib_entry_index,
     396             :                                                          FIB_NODE_TYPE_LISP_ADJ,
     397             :                                                          lai);
     398             : 
     399           1 :       lisp_adj_insert (&ladj->remote_rloc, ladj->sw_if_index, lai);
     400             :     }
     401             :   else
     402             :     {
     403             :       /* unlock the interface from the find. */
     404           0 :       lisp_gpe_sub_interface_unlock (l3si);
     405           0 :       ladj = lisp_gpe_adjacency_get_i (lai);
     406             :     }
     407             : 
     408           1 :   ladj->locks++;
     409             : 
     410           1 :   return (lai);
     411             : }
     412             : 
     413             : /**
     414             :  * @brief Get a pointer to a tunnel from a pointer to a FIB node
     415             :  */
     416             : static lisp_gpe_adjacency_t *
     417           0 : lisp_gpe_adjacency_from_fib_node (const fib_node_t * node)
     418             : {
     419           0 :   return ((lisp_gpe_adjacency_t *)
     420             :           ((char *) node -
     421             :            STRUCT_OFFSET_OF (lisp_gpe_adjacency_t, fib_node)));
     422             : }
     423             : 
     424             : static void
     425           1 : lisp_gpe_adjacency_last_lock_gone (lisp_gpe_adjacency_t * ladj)
     426             : {
     427             :   const lisp_gpe_tunnel_t *lgt;
     428             : 
     429             :   /*
     430             :    * no children so we are not counting locks. no-op.
     431             :    * at least not counting
     432             :    */
     433           1 :   lisp_adj_remove (&ladj->remote_rloc, ladj->sw_if_index);
     434             : 
     435             :   /*
     436             :    * unlock the resources this adj holds
     437             :    */
     438           1 :   lgt = lisp_gpe_tunnel_get (ladj->tunnel_index);
     439             : 
     440           1 :   fib_entry_child_remove (lgt->fib_entry_index, ladj->fib_entry_child_index);
     441             : 
     442           1 :   lisp_gpe_tunnel_unlock (ladj->tunnel_index);
     443           1 :   lisp_gpe_sub_interface_unlock (ladj->lisp_l3_sub_index);
     444             : 
     445           1 :   pool_put (lisp_adj_pool, ladj);
     446           1 : }
     447             : 
     448             : void
     449           1 : lisp_gpe_adjacency_unlock (index_t lai)
     450             : {
     451             :   lisp_gpe_adjacency_t *ladj;
     452             : 
     453           1 :   ladj = lisp_gpe_adjacency_get_i (lai);
     454             : 
     455           1 :   ladj->locks--;
     456             : 
     457           1 :   if (0 == ladj->locks)
     458             :     {
     459           1 :       lisp_gpe_adjacency_last_lock_gone (ladj);
     460             :     }
     461           1 : }
     462             : 
     463             : const lisp_gpe_adjacency_t *
     464           3 : lisp_gpe_adjacency_get (index_t lai)
     465             : {
     466           3 :   return (lisp_gpe_adjacency_get_i (lai));
     467             : }
     468             : 
     469             : 
     470             : /**
     471             :  * @brief LISP GPE tunnel back walk
     472             :  *
     473             :  * The FIB entry through which this tunnel resolves has been updated.
     474             :  * re-stack the midchain on the new forwarding.
     475             :  */
     476             : static fib_node_back_walk_rc_t
     477           0 : lisp_gpe_adjacency_back_walk (fib_node_t * node,
     478             :                               fib_node_back_walk_ctx_t * ctx)
     479             : {
     480           0 :   lisp_gpe_adj_stack (lisp_gpe_adjacency_from_fib_node (node));
     481             : 
     482           0 :   return (FIB_NODE_BACK_WALK_CONTINUE);
     483             : }
     484             : 
     485             : static fib_node_t *
     486           0 : lisp_gpe_adjacency_get_fib_node (fib_node_index_t index)
     487             : {
     488             :   lisp_gpe_adjacency_t *ladj;
     489             : 
     490           0 :   ladj = pool_elt_at_index (lisp_adj_pool, index);
     491           0 :   return (&ladj->fib_node);
     492             : }
     493             : 
     494             : static void
     495           0 : lisp_gpe_adjacency_last_fib_lock_gone (fib_node_t * node)
     496             : {
     497           0 :   lisp_gpe_adjacency_last_lock_gone (lisp_gpe_adjacency_from_fib_node (node));
     498           0 : }
     499             : 
     500             : const static fib_node_vft_t lisp_gpe_tuennel_vft = {
     501             :   .fnv_get = lisp_gpe_adjacency_get_fib_node,
     502             :   .fnv_back_walk = lisp_gpe_adjacency_back_walk,
     503             :   .fnv_last_lock = lisp_gpe_adjacency_last_fib_lock_gone,
     504             : };
     505             : 
     506             : u8 *
     507           0 : format_lisp_gpe_adjacency (u8 * s, va_list * args)
     508             : {
     509           0 :   lisp_gpe_adjacency_t *ladj = va_arg (*args, lisp_gpe_adjacency_t *);
     510           0 :   lisp_gpe_adjacency_format_flags_t flags =
     511             :     va_arg (*args, lisp_gpe_adjacency_format_flags_t);
     512             : 
     513           0 :   if (flags & LISP_GPE_ADJ_FORMAT_FLAG_DETAIL)
     514             :     {
     515             :       s =
     516           0 :         format (s, "index %d locks:%d\n", ladj - lisp_adj_pool, ladj->locks);
     517             :     }
     518             : 
     519           0 :   s = format (s, " vni: %d,", ladj->vni);
     520           0 :   s = format (s, " remote-RLOC: %U,", format_ip_address, &ladj->remote_rloc);
     521             : 
     522           0 :   if (flags & LISP_GPE_ADJ_FORMAT_FLAG_DETAIL)
     523             :     {
     524           0 :       s = format (s, " %U\n",
     525             :                   format_lisp_gpe_sub_interface,
     526             :                   lisp_gpe_sub_interface_get (ladj->lisp_l3_sub_index));
     527           0 :       s = format (s, " %U\n",
     528             :                   format_lisp_gpe_tunnel,
     529             :                   lisp_gpe_tunnel_get (ladj->tunnel_index));
     530             :     }
     531             :   else
     532             :     {
     533           0 :       s = format (s, " LISP L3 sub-interface index: %d,",
     534             :                   ladj->lisp_l3_sub_index);
     535           0 :       s = format (s, " LISP tunnel index: %d", ladj->tunnel_index);
     536             :     }
     537             : 
     538             : 
     539           0 :   return (s);
     540             : }
     541             : 
     542             : static clib_error_t *
     543           0 : lisp_gpe_adjacency_show (vlib_main_t * vm,
     544             :                          unformat_input_t * input, vlib_cli_command_t * cmd)
     545             : {
     546             :   lisp_gpe_adjacency_t *ladj;
     547             :   index_t index;
     548             : 
     549           0 :   if (pool_elts (lisp_adj_pool) == 0)
     550           0 :     vlib_cli_output (vm, "No lisp-gpe Adjacencies");
     551             : 
     552           0 :   if (unformat (input, "%d", &index))
     553             :     {
     554           0 :       ladj = lisp_gpe_adjacency_get_i (index);
     555           0 :       vlib_cli_output (vm, "%U", format_lisp_gpe_adjacency, ladj,
     556             :                        LISP_GPE_ADJ_FORMAT_FLAG_DETAIL);
     557             :     }
     558             :   else
     559             :     {
     560             :       /* *INDENT-OFF* */
     561           0 :       pool_foreach (ladj, lisp_adj_pool)
     562             :        {
     563           0 :         vlib_cli_output (vm, "[%d] %U\n",
     564           0 :                          ladj - lisp_adj_pool,
     565             :                          format_lisp_gpe_adjacency, ladj,
     566             :                          LISP_GPE_ADJ_FORMAT_FLAG_NONE);
     567             :       }
     568             :       /* *INDENT-ON* */
     569             :     }
     570             : 
     571           0 :   return 0;
     572             : }
     573             : 
     574             : /* *INDENT-OFF* */
     575      123991 : VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) =
     576             : {
     577             :   .path = "show gpe adjacency",
     578             :   .function = lisp_gpe_adjacency_show,
     579             : };
     580             : /* *INDENT-ON* */
     581             : 
     582             : #define LISP_ADJ_NBR_DEFAULT_HASH_NUM_BUCKETS (256)
     583             : #define LISP_ADJ_NBR_DEFAULT_HASH_MEMORY_SIZE (1<<20)
     584             : 
     585             : static clib_error_t *
     586         575 : lisp_gpe_adj_module_init (vlib_main_t * vm)
     587             : {
     588         575 :   BV (clib_bihash_init) (&lisp_adj_db,
     589             :                          "Adjacency Neighbour table",
     590             :                          LISP_ADJ_NBR_DEFAULT_HASH_NUM_BUCKETS,
     591             :                          LISP_ADJ_NBR_DEFAULT_HASH_MEMORY_SIZE);
     592             : 
     593         575 :   fib_node_register_type (FIB_NODE_TYPE_LISP_ADJ, &lisp_gpe_tuennel_vft);
     594         575 :   return (NULL);
     595             : }
     596             : 
     597        2879 : VLIB_INIT_FUNCTION (lisp_gpe_adj_module_init);
     598             : /*
     599             :  * fd.io coding-style-patch-verification: ON
     600             :  *
     601             :  * Local Variables:
     602             :  * eval: (c-set-style "gnu")
     603             :  * End:
     604             :  */

Generated by: LCOV version 1.14