LCOV - code coverage report
Current view: top level - vnet/l2 - l2_uu_fwd.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 71 77 92.2 %
Date: 2023-10-26 01:39:38 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /*
       2             :  * l2_uu_fwd.c : Foward unknown unicast packets to BD's configured interface
       3             :  *
       4             :  * Copyright (c) 2018 Cisco and/or its affiliates.
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include <vnet/l2/l2_bd.h>
      19             : #include <vnet/l2/l2_input.h>
      20             : 
      21             : #define foreach_l2_uu_fwd_error                                 \
      22             : _(L2_UU_FWD,           "L2 UU fwd")
      23             : 
      24             : typedef enum
      25             : {
      26             : #define _(sym,str) L2_UU_FWD_ERROR_##sym,
      27             :   foreach_l2_uu_fwd_error
      28             : #undef _
      29             :     L2_UU_FWD_N_ERROR,
      30             : } l2_uu_fwd_error_t;
      31             : 
      32             : static char *l2_uu_fwd_error_strings[] = {
      33             : #define _(sym,string) string,
      34             :   foreach_l2_uu_fwd_error
      35             : #undef _
      36             : };
      37             : 
      38             : typedef enum
      39             : {
      40             :   L2_UU_FWD_NEXT_DROP,
      41             :   L2_UU_FWD_NEXT_L2_OUTPUT,
      42             :   L2_UU_FWD_N_NEXT,
      43             : } l2_uu_fwd_next_t;
      44             : 
      45             : typedef struct
      46             : {
      47             :   u32 sw_if_index;
      48             : } l2_uu_fwd_trace_t;
      49             : 
      50             : /* packet trace format function */
      51             : static u8 *
      52           0 : format_l2_uu_fwd_trace (u8 * s, va_list * args)
      53             : {
      54           0 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      55           0 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      56           0 :   l2_uu_fwd_trace_t *t = va_arg (*args, l2_uu_fwd_trace_t *);
      57             : 
      58           0 :   s = format (s, "l2-uu-fwd: sw_if_index %d", t->sw_if_index);
      59           0 :   return s;
      60             : }
      61             : 
      62        2302 : VLIB_NODE_FN (l2_uu_fwd_node) (vlib_main_t * vm,
      63             :                                vlib_node_runtime_t * node,
      64             :                                vlib_frame_t * frame)
      65             : {
      66             :   u32 n_left_from, *from, *to_next;
      67             :   l2_uu_fwd_next_t next_index;
      68             : 
      69           2 :   from = vlib_frame_vector_args (frame);
      70           2 :   n_left_from = frame->n_vectors;
      71           2 :   next_index = node->cached_next_index;
      72             : 
      73           4 :   while (n_left_from > 0)
      74             :     {
      75             :       u32 n_left_to_next;
      76             : 
      77           2 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      78             : 
      79          32 :       while (n_left_from >= 8 && n_left_to_next >= 4)
      80             :         {
      81             :           const l2_bridge_domain_t *bdc0, *bdc1, *bdc2, *bdc3;
      82             :           l2_uu_fwd_next_t next0, next1, next2, next3;
      83             :           vlib_buffer_t *b0, *b1, *b2, *b3;
      84             :           u32 bi0, bi1, bi2, bi3;
      85             : 
      86             :           {
      87             :             vlib_buffer_t *b4, *b5, *b6, *b7;
      88             : 
      89          30 :             b4 = vlib_get_buffer (vm, from[4]);
      90          30 :             b5 = vlib_get_buffer (vm, from[5]);
      91          30 :             b6 = vlib_get_buffer (vm, from[6]);
      92          30 :             b7 = vlib_get_buffer (vm, from[7]);
      93             : 
      94          30 :             vlib_prefetch_buffer_header (b4, STORE);
      95          30 :             vlib_prefetch_buffer_header (b5, STORE);
      96          30 :             vlib_prefetch_buffer_header (b6, STORE);
      97          30 :             vlib_prefetch_buffer_header (b7, STORE);
      98             :           }
      99          30 :           bi0 = to_next[0] = from[0];
     100          30 :           bi1 = to_next[1] = from[1];
     101          30 :           bi2 = to_next[2] = from[2];
     102          30 :           bi3 = to_next[3] = from[3];
     103             : 
     104          30 :           from += 4;
     105          30 :           to_next += 4;
     106          30 :           n_left_from -= 4;
     107          30 :           n_left_to_next -= 4;
     108             : 
     109          30 :           next3 = next2 = next1 = next0 = L2_UU_FWD_NEXT_L2_OUTPUT;
     110             : 
     111          30 :           b0 = vlib_get_buffer (vm, bi0);
     112          30 :           b1 = vlib_get_buffer (vm, bi1);
     113          30 :           b2 = vlib_get_buffer (vm, bi2);
     114          30 :           b3 = vlib_get_buffer (vm, bi3);
     115             : 
     116          30 :           bdc0 = vec_elt_at_index (l2input_main.bd_configs,
     117             :                                    vnet_buffer (b0)->l2.bd_index);
     118          30 :           bdc1 = vec_elt_at_index (l2input_main.bd_configs,
     119             :                                    vnet_buffer (b1)->l2.bd_index);
     120          30 :           bdc2 = vec_elt_at_index (l2input_main.bd_configs,
     121             :                                    vnet_buffer (b2)->l2.bd_index);
     122          30 :           bdc3 = vec_elt_at_index (l2input_main.bd_configs,
     123             :                                    vnet_buffer (b3)->l2.bd_index);
     124             : 
     125          30 :           ASSERT (~0 != bdc0->uu_fwd_sw_if_index);
     126             : 
     127          30 :           vnet_buffer (b0)->sw_if_index[VLIB_TX] = bdc0->uu_fwd_sw_if_index;
     128          30 :           vnet_buffer (b1)->sw_if_index[VLIB_TX] = bdc1->uu_fwd_sw_if_index;
     129          30 :           vnet_buffer (b2)->sw_if_index[VLIB_TX] = bdc2->uu_fwd_sw_if_index;
     130          30 :           vnet_buffer (b3)->sw_if_index[VLIB_TX] = bdc3->uu_fwd_sw_if_index;
     131             : 
     132          30 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
     133             :                              (b0->flags & VLIB_BUFFER_IS_TRACED)))
     134             :             {
     135             :               l2_uu_fwd_trace_t *t;
     136             : 
     137          30 :               t = vlib_add_trace (vm, node, b0, sizeof (*t));
     138          30 :               t->sw_if_index = bdc0->uu_fwd_sw_if_index;
     139             :             }
     140          30 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
     141             :                              (b1->flags & VLIB_BUFFER_IS_TRACED)))
     142             :             {
     143             :               l2_uu_fwd_trace_t *t;
     144             : 
     145          30 :               t = vlib_add_trace (vm, node, b1, sizeof (*t));
     146          30 :               t->sw_if_index = bdc1->uu_fwd_sw_if_index;
     147             :             }
     148          30 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
     149             :                              (b1->flags & VLIB_BUFFER_IS_TRACED)))
     150             :             {
     151             :               l2_uu_fwd_trace_t *t;
     152             : 
     153          30 :               t = vlib_add_trace (vm, node, b2, sizeof (*t));
     154          30 :               t->sw_if_index = bdc2->uu_fwd_sw_if_index;
     155             :             }
     156          30 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
     157             :                              (b1->flags & VLIB_BUFFER_IS_TRACED)))
     158             :             {
     159             :               l2_uu_fwd_trace_t *t;
     160             : 
     161          30 :               t = vlib_add_trace (vm, node, b3, sizeof (*t));
     162          30 :               t->sw_if_index = bdc3->uu_fwd_sw_if_index;
     163             :             }
     164          30 :           vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
     165             :                                            to_next, n_left_to_next,
     166             :                                            bi0, bi1, bi2, bi3,
     167             :                                            next0, next1, next2, next3);
     168             :         }
     169             : 
     170          16 :       while (n_left_from > 0 && n_left_to_next > 0)
     171             :         {
     172             :           const l2_bridge_domain_t *bdc0;
     173             :           l2_uu_fwd_next_t next0;
     174             :           vlib_buffer_t *b0;
     175             :           u32 bi0;
     176             : 
     177          14 :           bi0 = from[0];
     178          14 :           to_next[0] = bi0;
     179          14 :           from += 1;
     180          14 :           to_next += 1;
     181          14 :           n_left_from -= 1;
     182          14 :           n_left_to_next -= 1;
     183          14 :           next0 = L2_UU_FWD_NEXT_L2_OUTPUT;
     184          14 :           b0 = vlib_get_buffer (vm, bi0);
     185             : 
     186          14 :           bdc0 = vec_elt_at_index (l2input_main.bd_configs,
     187             :                                    vnet_buffer (b0)->l2.bd_index);
     188          14 :           ASSERT (~0 != bdc0->uu_fwd_sw_if_index);
     189             : 
     190          14 :           vnet_buffer (b0)->sw_if_index[VLIB_TX] = bdc0->uu_fwd_sw_if_index;
     191             : 
     192          14 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
     193             :                              (b0->flags & VLIB_BUFFER_IS_TRACED)))
     194             :             {
     195             :               l2_uu_fwd_trace_t *t;
     196             : 
     197          14 :               t = vlib_add_trace (vm, node, b0, sizeof (*t));
     198          14 :               t->sw_if_index = bdc0->uu_fwd_sw_if_index;
     199             :             }
     200          14 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     201             :                                            to_next, n_left_to_next,
     202             :                                            bi0, next0);
     203             :         }
     204             : 
     205           2 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     206             :     }
     207             : 
     208           2 :   vlib_node_increment_counter (vm, node->node_index,
     209           2 :                                L2_UU_FWD_ERROR_L2_UU_FWD, frame->n_vectors);
     210             : 
     211           2 :   return frame->n_vectors;
     212             : }
     213             : 
     214             : /* *INDENT-OFF* */
     215      183788 : VLIB_REGISTER_NODE (l2_uu_fwd_node) = {
     216             :   .name = "l2-uu-fwd",
     217             :   .vector_size = sizeof (u32),
     218             :   .format_trace = format_l2_uu_fwd_trace,
     219             :   .type = VLIB_NODE_TYPE_INTERNAL,
     220             : 
     221             :   .n_errors = ARRAY_LEN(l2_uu_fwd_error_strings),
     222             :   .error_strings = l2_uu_fwd_error_strings,
     223             : 
     224             :   .n_next_nodes = L2_UU_FWD_N_NEXT,
     225             : 
     226             :   .next_nodes = {
     227             :         [L2_UU_FWD_NEXT_DROP] = "error-drop",
     228             :         [L2_UU_FWD_NEXT_L2_OUTPUT] = "l2-output",
     229             :   },
     230             : };
     231             : /* *INDENT-ON* */
     232             : 
     233             : /*
     234             :  * fd.io coding-style-patch-verification: ON
     235             :  *
     236             :  * Local Variables:
     237             :  * eval: (c-set-style "gnu")
     238             :  * End:
     239             :  */

Generated by: LCOV version 1.14