LCOV - code coverage report
Current view: top level - vnet/bier - bier_bift_table.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 60 87 69.0 %
Date: 2023-07-05 22:20:52 Functions: 8 9 88.9 %

          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             : #include <vnet/bier/bier_bift_table.h>
      17             : #include <vnet/dpo/drop_dpo.h>
      18             : #include <vnet/udp/udp_local.h>
      19             : 
      20             : typedef enum {
      21             : #define bier_error(n,s) BIER_INPUT_ERROR_##n,
      22             : #include <vnet/bier/bier_input_error.def>
      23             : #undef bier_error
      24             :     BIER_INPUT_N_ERROR,
      25             : } bier_input_error_t;
      26             : 
      27             : static char * bier_error_strings[] = {
      28             : #define bier_error(n,s) s,
      29             : #include <vnet/bier/bier_input_error.def>
      30             : #undef bier_error
      31             : };
      32             : 
      33             : /**
      34             :  * Global BIFT table
      35             :  */
      36             : bier_bfit_table_t *bier_bift_table;
      37             : 
      38             : /**
      39             :  * Forward declare the node
      40             :  */
      41             : vlib_node_registration_t bier_bift_input_node;
      42             : 
      43             : void
      44           1 : bier_bift_table_entry_add (bier_bift_id_t id,
      45             :                            const dpo_id_t *dpo)
      46             : {
      47           1 :     if (NULL == bier_bift_table)
      48             :     {
      49             :         u32 ii;
      50             : 
      51             :         /*
      52             :          * allocate the table and
      53             :          * set each of the entries therein to a BIER drop
      54             :          */
      55           1 :         bier_bift_table = clib_mem_alloc_aligned(sizeof(*bier_bift_table),
      56             :                                                  CLIB_CACHE_LINE_BYTES);
      57           1 :         clib_memset(bier_bift_table, 0, sizeof(*bier_bift_table));
      58             : 
      59     1048580 :         for (ii = 0; ii < BIER_BIFT_N_ENTRIES; ii++)
      60             :         {
      61     1048580 :             dpo_stack_from_node(bier_bift_input_node.index,
      62     1048580 :                                 &bier_bift_table->bblt_dpos[ii],
      63             :                                 drop_dpo_get(DPO_PROTO_BIER));
      64             :         }
      65             : 
      66             :         /*
      67             :          * register to handle packets that arrive on the assigned
      68             :          * UDP port
      69             :          */
      70           1 :         udp_register_dst_port(vlib_get_main(),
      71             :                               UDP_DST_PORT_BIER,
      72             :                               bier_bift_input_node.index,
      73             :                               0);
      74           1 :         udp_register_dst_port(vlib_get_main(),
      75             :                               UDP_DST_PORT_BIER,
      76             :                               bier_bift_input_node.index,
      77             :                               1);
      78             :     }
      79             : 
      80           1 :     dpo_stack_from_node(bier_bift_input_node.index,
      81           1 :                         &bier_bift_table->bblt_dpos[id],
      82             :                         dpo);
      83             : 
      84           1 :     bier_bift_table->bblt_n_entries++;
      85           1 : }
      86             : 
      87             : void
      88           1 : bier_bift_table_entry_remove (bier_bift_id_t id)
      89             : {
      90           1 :     ASSERT(NULL != bier_bift_table);
      91             : 
      92           1 :     dpo_reset(&bier_bift_table->bblt_dpos[id]);
      93             : 
      94           1 :     bier_bift_table->bblt_n_entries--;
      95             : 
      96           1 :     if (0 == bier_bift_table->bblt_n_entries)
      97             :     {
      98           1 :         udp_unregister_dst_port(vlib_get_main(),
      99             :                                 UDP_DST_PORT_BIER,
     100             :                                 0);
     101           1 :         udp_unregister_dst_port(vlib_get_main(),
     102             :                                 UDP_DST_PORT_BIER,
     103             :                                 1);
     104             : 
     105           1 :         clib_mem_free(bier_bift_table);
     106           1 :         bier_bift_table = NULL;
     107             :     }
     108           1 : }
     109             : 
     110             : /**
     111             :  * @brief Packet trace record for BIER input
     112             :  */
     113             : typedef struct bier_bift_input_trace_t_
     114             : {
     115             :     u32 bift_id;
     116             : } bier_bift_input_trace_t;
     117             : 
     118             : static uword
     119           1 : bier_bift_input (vlib_main_t * vm,
     120             :                  vlib_node_runtime_t * node,
     121             :                  vlib_frame_t * from_frame)
     122             : {
     123             :     u32 n_left_from, next_index, * from, * to_next;
     124             : 
     125           1 :     from = vlib_frame_vector_args (from_frame);
     126           1 :     n_left_from = from_frame->n_vectors;
     127           1 :     next_index = node->cached_next_index;
     128             : 
     129           2 :     while (n_left_from > 0)
     130             :     {
     131             :         u32 n_left_to_next;
     132             : 
     133           1 :         vlib_get_next_frame (vm, node, next_index,
     134             :                              to_next, n_left_to_next);
     135             : 
     136           2 :         while (n_left_from > 0 && n_left_to_next > 0)
     137             :         {
     138             :             bier_bift_id_t *biftp0, bift0;
     139             :             const dpo_id_t *dpo0;
     140             :             vlib_buffer_t * b0;
     141             :             u32 bi0, next0;
     142             : 
     143           1 :             bi0 = from[0];
     144           1 :             to_next[0] = bi0;
     145           1 :             from += 1;
     146           1 :             to_next += 1;
     147           1 :             n_left_from -= 1;
     148           1 :             n_left_to_next -= 1;
     149             : 
     150           1 :             b0 = vlib_get_buffer (vm, bi0);
     151           1 :             biftp0 = vlib_buffer_get_current (b0);
     152           1 :             vlib_buffer_advance(b0, sizeof(bift0));
     153           1 :             bift0 = clib_net_to_host_u32(*biftp0);
     154             : 
     155             :             /*
     156             :              * Do the lookup based on the first 20 bits, i.e. the
     157             :              * encoding of the set, sub-domain and BSL
     158             :              */
     159           1 :             dpo0 = bier_bift_dp_lookup(bift0);
     160             : 
     161             :             /*
     162             :              * save the TTL for later during egress
     163             :              */
     164           1 :             vnet_buffer(b0)->mpls.ttl = vnet_mpls_uc_get_ttl(bift0);
     165             : 
     166           1 :             next0 = dpo0->dpoi_next_node;
     167           1 :             vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
     168             : 
     169           1 :             if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
     170             :             {
     171             :                 bier_bift_input_trace_t *tr;
     172             : 
     173           1 :                 tr = vlib_add_trace(vm, node, b0, sizeof (*tr));
     174           1 :                 tr->bift_id = bift0;
     175             :             }
     176             : 
     177           1 :             vlib_validate_buffer_enqueue_x1(vm, node, next_index,
     178             :                                             to_next, n_left_to_next,
     179             :                                             bi0, next0);
     180             :         }
     181             : 
     182           1 :         vlib_put_next_frame(vm, node, next_index, n_left_to_next);
     183             :     }
     184             : 
     185           1 :     vlib_node_increment_counter(vm, bier_bift_input_node.index,
     186             :                                 BIER_INPUT_ERROR_PKTS_VALID,
     187           1 :                                 from_frame->n_vectors);
     188           1 :     return (from_frame->n_vectors);
     189             : }
     190             : 
     191             : static u8 *
     192           2 : format_bier_bift_input_trace (u8 * s, va_list * args)
     193             : {
     194           2 :     CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
     195           2 :     CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
     196           2 :     bier_bift_input_trace_t * t = va_arg (*args, bier_bift_input_trace_t *);
     197             : 
     198           2 :     s = format (s, "BIFT-ID:[%U]", format_bier_bift_id,
     199             :                 vnet_mpls_uc_get_label(t->bift_id));
     200           2 :     return s;
     201             : }
     202             : 
     203      178120 : VLIB_REGISTER_NODE (bier_bift_input_node) = {
     204             :     .function = bier_bift_input,
     205             :     .name = "bier-bift-input",
     206             :     /* Takes a vector of packets. */
     207             :     .vector_size = sizeof (u32),
     208             :     .n_errors = BIER_INPUT_N_ERROR,
     209             :     .error_strings = bier_error_strings,
     210             :     .n_next_nodes = 0,
     211             :     .format_trace = format_bier_bift_input_trace,
     212             : };
     213             : 
     214             : clib_error_t *
     215           0 : show_bier_bift_cmd (vlib_main_t * vm,
     216             :                     unformat_input_t * input,
     217             :                     vlib_cli_command_t * cmd)
     218             : {
     219           0 :     clib_error_t * error = NULL;
     220             :     u32 hdr_len, set, sub_domain;
     221             : 
     222           0 :     set = hdr_len = sub_domain = ~0;
     223             : 
     224           0 :     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
     225           0 :         if (unformat (input, "sd %d", &sub_domain)) {
     226             :             ;
     227           0 :         } else if (unformat (input, "set %d", &set)) {
     228             :             ;
     229           0 :         } else if (unformat (input, "bsl %d", &hdr_len)) {
     230             :             ;
     231             :         }
     232             :         else
     233             :         {
     234           0 :             error = unformat_parse_error (input);
     235           0 :             goto done;
     236             :         }
     237             :     }
     238             : 
     239           0 :     if (NULL == bier_bift_table)
     240             :     {
     241           0 :         vlib_cli_output(vm, "no BIFT entries");
     242           0 :         goto done;
     243             :     }
     244             : 
     245           0 :     if (~0 == set)
     246             :     {
     247             :         u32 ii;
     248             : 
     249           0 :         for (ii = 0; ii < BIER_BIFT_N_ENTRIES; ii++)
     250             :         {
     251           0 :             if (!dpo_is_drop(&bier_bift_table->bblt_dpos[ii]))
     252             :             {
     253             :                 bier_hdr_len_id_t bsl;
     254             : 
     255           0 :                 bier_bift_id_decode(ii, &set, &sub_domain, &bsl);
     256             : 
     257           0 :                 vlib_cli_output(vm, "set: %d, sub-domain:%d, BSL:%U",
     258             :                                 set, sub_domain,
     259             :                                 format_bier_hdr_len_id, bsl);
     260           0 :                 vlib_cli_output(vm, "  %U",
     261             :                                 format_dpo_id,
     262           0 :                                 &bier_bift_table->bblt_dpos[ii], 0);
     263             :             }
     264             :         }
     265             :     }
     266             :     else
     267             :     {
     268             :         bier_bift_id_t id;
     269             : 
     270           0 :         id = bier_bift_id_encode(set, sub_domain,
     271           0 :                                  bier_hdr_bit_len_to_id(hdr_len));
     272             : 
     273           0 :         if (!dpo_is_drop(&bier_bift_table->bblt_dpos[id]))
     274             :         {
     275           0 :             vlib_cli_output(vm, "set: %d, sub-domain:%d, BSL:%U",
     276             :                             set, sub_domain,
     277             :                             format_bier_hdr_len_id, hdr_len);
     278           0 :             vlib_cli_output(vm, "  %U",
     279             :                             format_dpo_id,
     280           0 :                             &bier_bift_table->bblt_dpos[id], 0);
     281             :         }
     282             :     }
     283           0 : done:
     284           0 :     return (error);
     285             : }
     286             : 
     287      272887 : VLIB_CLI_COMMAND (show_bier_bift_command, static) = {
     288             :     .path = "show bier bift",
     289             :     .short_help = "show bier bift [set <value>] [sd <value>] [bsl <value>]",
     290             :     .function = show_bier_bift_cmd,
     291             : };

Generated by: LCOV version 1.14