LCOV - code coverage report
Current view: top level - plugins/lacp - cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 199 230 86.5 %
Date: 2023-10-26 01:39:38 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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             : #define _GNU_SOURCE
      17             : #include <vnet/bonding/node.h>
      18             : #include <lacp/node.h>
      19             : 
      20             : int
      21           4 : lacp_dump_ifs (lacp_interface_details_t ** out_lacpifs)
      22             : {
      23           4 :   vnet_main_t *vnm = vnet_get_main ();
      24           4 :   bond_main_t *bm = &bond_main;
      25             :   member_if_t *mif;
      26             :   bond_if_t *bif;
      27             :   vnet_hw_interface_t *hi;
      28           4 :   lacp_interface_details_t *r_lacpifs = NULL;
      29           4 :   lacp_interface_details_t *lacpif = NULL;
      30             : 
      31             :   /* *INDENT-OFF* */
      32          20 :   pool_foreach (mif, bm->neighbors) {
      33          16 :     if (mif->lacp_enabled == 0)
      34           0 :       continue;
      35          16 :     vec_add2(r_lacpifs, lacpif, 1);
      36          16 :     clib_memset (lacpif, 0, sizeof (*lacpif));
      37          16 :     lacpif->sw_if_index = mif->sw_if_index;
      38          16 :     hi = vnet_get_hw_interface (vnm, mif->hw_if_index);
      39          16 :     clib_memcpy(lacpif->interface_name, hi->name,
      40             :                 MIN (ARRAY_LEN (lacpif->interface_name) - 1,
      41             :                      vec_len (hi->name)));
      42          16 :     bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance);
      43          16 :     hi = vnet_get_hw_interface (vnm, bif->hw_if_index);
      44          16 :     clib_memcpy(lacpif->bond_interface_name, hi->name,
      45             :                 MIN (ARRAY_LEN (lacpif->bond_interface_name) - 1,
      46             :                      vec_len (hi->name)));
      47          16 :     clib_memcpy (lacpif->actor_system, mif->actor.system, 6);
      48          16 :     lacpif->actor_system_priority = mif->actor.system_priority;
      49          16 :     lacpif->actor_key = mif->actor.key;
      50          16 :     lacpif->actor_port_priority = mif->actor.port_priority;
      51          16 :     lacpif->actor_port_number = mif->actor.port_number;
      52          16 :     lacpif->actor_state = mif->actor.state;
      53          16 :     clib_memcpy (lacpif->partner_system, mif->partner.system, 6);
      54          16 :     lacpif->partner_system_priority = mif->partner.system_priority;
      55          16 :     lacpif->partner_key = mif->partner.key;
      56          16 :     lacpif->partner_port_priority = mif->partner.port_priority;
      57          16 :     lacpif->partner_port_number = mif->partner.port_number;
      58          16 :     lacpif->partner_state = mif->partner.state;
      59          16 :     lacpif->rx_state = mif->rx_state;
      60          16 :     lacpif->tx_state = mif->tx_state;
      61          16 :     lacpif->ptx_state = mif->ptx_state;
      62          16 :     lacpif->mux_state = mif->mux_state;
      63             :   }
      64             :   /* *INDENT-ON* */
      65             : 
      66           4 :   *out_lacpifs = r_lacpifs;
      67             : 
      68           4 :   return 0;
      69             : }
      70             : 
      71             : static void
      72           1 : show_lacp (vlib_main_t * vm, u32 * sw_if_indices)
      73             : {
      74             :   int i;
      75             :   member_if_t *mif;
      76             :   bond_if_t *bif;
      77             : 
      78           1 :   if (!sw_if_indices)
      79           0 :     return;
      80             : 
      81           1 :   vlib_cli_output (vm, "%-55s %-32s %-32s", " ", "actor state",
      82             :                    "partner state");
      83           1 :   vlib_cli_output (vm, "%-25s %-12s %-16s %-31s  %-31s", "interface name",
      84             :                    "sw_if_index", "bond interface",
      85             :                    "exp/def/dis/col/syn/agg/tim/act",
      86             :                    "exp/def/dis/col/syn/agg/tim/act");
      87             : 
      88           5 :   for (i = 0; i < vec_len (sw_if_indices); i++)
      89             :     {
      90           4 :       mif = bond_get_member_by_sw_if_index (sw_if_indices[i]);
      91           4 :       if (!mif || (mif->lacp_enabled == 0))
      92           0 :         continue;
      93           4 :       bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance);
      94           4 :       vlib_cli_output (vm,
      95             :                        "%-25U %-12d %-16U %3x %3x %3x %3x %3x %3x %3x %3x "
      96             :                        "%4x %3x %3x %3x %3x %3x %3x %3x",
      97             :                        format_vnet_sw_if_index_name, vnet_get_main (),
      98             :                        mif->sw_if_index, mif->sw_if_index,
      99             :                        format_vnet_sw_if_index_name, vnet_get_main (),
     100           4 :                        bif->sw_if_index, lacp_bit_test (mif->actor.state, 7),
     101           4 :                        lacp_bit_test (mif->actor.state, 6),
     102           4 :                        lacp_bit_test (mif->actor.state, 5),
     103           4 :                        lacp_bit_test (mif->actor.state, 4),
     104           4 :                        lacp_bit_test (mif->actor.state, 3),
     105           4 :                        lacp_bit_test (mif->actor.state, 2),
     106           4 :                        lacp_bit_test (mif->actor.state, 1),
     107           4 :                        lacp_bit_test (mif->actor.state, 0),
     108           4 :                        lacp_bit_test (mif->partner.state, 7),
     109           4 :                        lacp_bit_test (mif->partner.state, 6),
     110           4 :                        lacp_bit_test (mif->partner.state, 5),
     111           4 :                        lacp_bit_test (mif->partner.state, 4),
     112           4 :                        lacp_bit_test (mif->partner.state, 3),
     113           4 :                        lacp_bit_test (mif->partner.state, 2),
     114           4 :                        lacp_bit_test (mif->partner.state, 1),
     115           4 :                        lacp_bit_test (mif->partner.state, 0));
     116           4 :       vlib_cli_output (vm,
     117             :                        "  LAG ID: "
     118             :                        "[(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x), "
     119             :                        "(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x)]",
     120           4 :                        ntohs (mif->actor.system_priority),
     121           4 :                        mif->actor.system[0], mif->actor.system[1],
     122           4 :                        mif->actor.system[2], mif->actor.system[3],
     123           4 :                        mif->actor.system[4], mif->actor.system[5],
     124           4 :                        ntohs (mif->actor.key),
     125           4 :                        ntohs (mif->actor.port_priority),
     126           4 :                        ntohs (mif->actor.port_number),
     127           4 :                        ntohs (mif->partner.system_priority),
     128           4 :                        mif->partner.system[0], mif->partner.system[1],
     129           4 :                        mif->partner.system[2], mif->partner.system[3],
     130           4 :                        mif->partner.system[4], mif->partner.system[5],
     131           4 :                        ntohs (mif->partner.key),
     132           4 :                        ntohs (mif->partner.port_priority),
     133           4 :                        ntohs (mif->partner.port_number));
     134           4 :       vlib_cli_output (vm,
     135             :                        "  RX-state: %U, TX-state: %U, "
     136             :                        "MUX-state: %U, PTX-state: %U",
     137             :                        format_rx_sm_state, mif->rx_state, format_tx_sm_state,
     138             :                        mif->tx_state, format_mux_sm_state, mif->mux_state,
     139             :                        format_ptx_sm_state, mif->ptx_state);
     140             :     }
     141             : }
     142             : 
     143             : static void
     144           1 : show_lacp_details (vlib_main_t * vm, u32 * sw_if_indices)
     145             : {
     146           1 :   lacp_main_t *lm = &lacp_main;
     147             :   member_if_t *mif;
     148             :   lacp_state_struct *state_entry;
     149             :   int i;
     150             :   f64 now;
     151             : 
     152           1 :   vlib_cli_output (vm, "Number of interfaces: %d", lm->lacp_int);
     153           1 :   if (!sw_if_indices)
     154           0 :     return;
     155             : 
     156           1 :   now = vlib_time_now (vm);
     157           5 :   for (i = 0; i < vec_len (sw_if_indices); i++)
     158             :     {
     159           4 :       mif = bond_get_member_by_sw_if_index (sw_if_indices[i]);
     160           4 :       if (!mif || (mif->lacp_enabled == 0))
     161           0 :         continue;
     162           4 :       vlib_cli_output (vm, "  %U", format_vnet_sw_if_index_name,
     163             :                        vnet_get_main (), mif->sw_if_index);
     164           4 :       vlib_cli_output (vm, "    Good LACP PDUs received: %llu",
     165             :                        mif->pdu_received);
     166           4 :       vlib_cli_output (vm, "    Bad LACP PDUs received: %llu",
     167             :                        mif->bad_pdu_received);
     168           4 :       vlib_cli_output (vm, "    LACP PDUs sent: %llu", mif->pdu_sent);
     169           4 :       if (lacp_timer_is_running (mif->last_lacpdu_recd_time))
     170           4 :         vlib_cli_output (vm,
     171             :                          "    last LACP PDU received: %10.2f seconds ago",
     172           4 :                          now - mif->last_lacpdu_recd_time);
     173           4 :       if (lacp_timer_is_running (mif->last_lacpdu_sent_time))
     174           4 :         vlib_cli_output (vm, "    last LACP PDU sent: %10.2f seconds ago",
     175           4 :                          now - mif->last_lacpdu_sent_time);
     176           4 :       vlib_cli_output (vm, "    Good Marker PDUs received: %llu",
     177             :                        mif->marker_pdu_received);
     178           4 :       vlib_cli_output (vm, "    Bad Marker PDUs received: %llu",
     179             :                        mif->marker_bad_pdu_received);
     180           4 :       if (lacp_timer_is_running (mif->last_marker_pdu_recd_time))
     181           0 :         vlib_cli_output (vm,
     182             :                          "    last Marker PDU received: %10.2f seconds ago",
     183           0 :                          now - mif->last_marker_pdu_recd_time);
     184           4 :       if (lacp_timer_is_running (mif->last_marker_pdu_sent_time))
     185           0 :         vlib_cli_output (vm, "    last Marker PDU sent: %10.2f seconds ago",
     186           0 :                          now - mif->last_marker_pdu_sent_time);
     187           4 :       vlib_cli_output (vm, "    debug: %d", mif->debug);
     188           4 :       vlib_cli_output (vm, "    loopback port: %d", mif->loopback_port);
     189           4 :       vlib_cli_output (vm, "    port_enabled: %d", mif->port_enabled);
     190           4 :       vlib_cli_output (vm, "    port moved: %d", mif->port_moved);
     191           4 :       vlib_cli_output (vm, "    ready_n: %d", mif->ready_n);
     192           4 :       vlib_cli_output (vm, "    ready: %d", mif->ready);
     193           4 :       vlib_cli_output (vm, "    Actor");
     194           4 :       vlib_cli_output (vm, "      system: %U",
     195           4 :                        format_ethernet_address, mif->actor.system);
     196           4 :       vlib_cli_output (vm, "      system priority: %u",
     197           4 :                        ntohs (mif->actor.system_priority));
     198           4 :       vlib_cli_output (vm, "      key: %u", ntohs (mif->actor.key));
     199           4 :       vlib_cli_output (vm, "      port priority: %u",
     200           4 :                        ntohs (mif->actor.port_priority));
     201           4 :       vlib_cli_output (vm, "      port number: %u",
     202           4 :                        ntohs (mif->actor.port_number));
     203           4 :       vlib_cli_output (vm, "      state: 0x%x", mif->actor.state);
     204             : 
     205           4 :       state_entry = (lacp_state_struct *) & lacp_state_array;
     206          36 :       while (state_entry->str)
     207             :         {
     208          32 :           if (mif->actor.state & (1 << state_entry->bit))
     209          24 :             vlib_cli_output (vm, "        %s (%d)", state_entry->str,
     210          24 :                              state_entry->bit);
     211          32 :           state_entry++;
     212             :         }
     213             : 
     214           4 :       vlib_cli_output (vm, "    Partner");
     215           4 :       vlib_cli_output (vm, "      system: %U",
     216           4 :                        format_ethernet_address, mif->partner.system);
     217           4 :       vlib_cli_output (vm, "      system priority: %u",
     218           4 :                        ntohs (mif->partner.system_priority));
     219           4 :       vlib_cli_output (vm, "      key: %u", ntohs (mif->partner.key));
     220           4 :       vlib_cli_output (vm, "      port priority: %u",
     221           4 :                        ntohs (mif->partner.port_priority));
     222           4 :       vlib_cli_output (vm, "      port number: %u",
     223           4 :                        ntohs (mif->partner.port_number));
     224           4 :       vlib_cli_output (vm, "      state: 0x%x", mif->partner.state);
     225             : 
     226           4 :       state_entry = (lacp_state_struct *) & lacp_state_array;
     227          36 :       while (state_entry->str)
     228             :         {
     229          32 :           if (mif->partner.state & (1 << state_entry->bit))
     230          24 :             vlib_cli_output (vm, "        %s (%d)", state_entry->str,
     231          24 :                              state_entry->bit);
     232          32 :           state_entry++;
     233             :         }
     234             : 
     235           4 :       if (!lacp_timer_is_running (mif->wait_while_timer))
     236           2 :         vlib_cli_output (vm, "      wait while timer: not running");
     237             :       else
     238           2 :         vlib_cli_output (vm, "      wait while timer: %10.2f seconds",
     239           2 :                          mif->wait_while_timer - now);
     240           4 :       if (!lacp_timer_is_running (mif->current_while_timer))
     241           0 :         vlib_cli_output (vm, "      current while timer: not running");
     242             :       else
     243           4 :         vlib_cli_output (vm, "      current while timer: %10.2f seconds",
     244           4 :                          mif->current_while_timer - now);
     245           4 :       if (!lacp_timer_is_running (mif->periodic_timer))
     246           0 :         vlib_cli_output (vm, "      periodic timer: not running");
     247             :       else
     248           4 :         vlib_cli_output (vm, "      periodic timer: %10.2f seconds",
     249           4 :                          mif->periodic_timer - now);
     250           4 :       vlib_cli_output (vm, "    RX-state: %U", format_rx_sm_state,
     251             :                        mif->rx_state);
     252           4 :       vlib_cli_output (vm, "    TX-state: %U", format_tx_sm_state,
     253             :                        mif->tx_state);
     254           4 :       vlib_cli_output (vm, "    MUX-state: %U", format_mux_sm_state,
     255             :                        mif->mux_state);
     256           4 :       vlib_cli_output (vm, "    PTX-state: %U", format_ptx_sm_state,
     257             :                        mif->ptx_state);
     258           4 :       vlib_cli_output (vm, "\n");
     259             :     }
     260             : }
     261             : 
     262             : static clib_error_t *
     263           2 : show_lacp_fn (vlib_main_t * vm, unformat_input_t * input,
     264             :               vlib_cli_command_t * cmd)
     265             : {
     266           2 :   bond_main_t *bm = &bond_main;
     267           2 :   vnet_main_t *vnm = &vnet_main;
     268             :   member_if_t *mif;
     269           2 :   clib_error_t *error = 0;
     270           2 :   u8 details = 0;
     271           2 :   u32 sw_if_index, *sw_if_indices = 0;
     272             : 
     273           3 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     274             :     {
     275           1 :       if (unformat
     276             :           (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
     277             :         {
     278           0 :           mif = bond_get_member_by_sw_if_index (sw_if_index);
     279           0 :           if (!mif)
     280             :             {
     281           0 :               error = clib_error_return (0, "interface is not a member");
     282           0 :               goto done;
     283             :             }
     284           0 :           vec_add1 (sw_if_indices, mif->sw_if_index);
     285             :         }
     286           1 :       else if (unformat (input, "details"))
     287           1 :         details = 1;
     288             :       else
     289             :         {
     290           0 :           error = clib_error_return (0, "unknown input `%U'",
     291             :                                      format_unformat_error, input);
     292           0 :           goto done;
     293             :         }
     294             :     }
     295             : 
     296           2 :   if (vec_len (sw_if_indices) == 0)
     297             :     {
     298          10 :       pool_foreach (mif, bm->neighbors)
     299           8 :         vec_add1 (sw_if_indices, mif->sw_if_index);
     300             :     }
     301             : 
     302           2 :   if (details)
     303           1 :     show_lacp_details (vm, sw_if_indices);
     304             :   else
     305           1 :     show_lacp (vm, sw_if_indices);
     306             : 
     307           2 : done:
     308           2 :   vec_free (sw_if_indices);
     309           2 :   return error;
     310             : }
     311             : 
     312             : /* *INDENT-OFF* */
     313      179305 : VLIB_CLI_COMMAND (show_lacp_command, static) = {
     314             :   .path = "show lacp",
     315             :   .short_help = "show lacp [<interface>] [details]",
     316             :   .function = show_lacp_fn,
     317             :   .is_mp_safe = 1,
     318             : };
     319             : /* *INDENT-ON* */
     320             : 
     321             : static clib_error_t *
     322           1 : debug_lacp_command_fn (vlib_main_t * vm, unformat_input_t * input,
     323             :                        vlib_cli_command_t * cmd)
     324             : {
     325           1 :   unformat_input_t _line_input, *line_input = &_line_input;
     326           1 :   clib_error_t *error = NULL;
     327           1 :   lacp_main_t *lm = &lacp_main;
     328           1 :   u8 onoff = 0;
     329           1 :   u8 input_found = 0;
     330           1 :   u32 sw_if_index = ~0;
     331             :   member_if_t *mif;
     332           1 :   vnet_main_t *vnm = vnet_get_main ();
     333             : 
     334             :   /* Get a line of input. */
     335           1 :   if (!unformat_user (input, unformat_line_input, line_input))
     336           0 :     return clib_error_return (0, "missing argument");
     337             : 
     338           2 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     339             :     {
     340           1 :       if (unformat (line_input, "%U",
     341             :                     unformat_vnet_sw_interface, vnm, &sw_if_index))
     342             :         ;
     343           1 :       if (input_found)
     344             :         {
     345           0 :           error = clib_error_return (0, "unknown input `%U'",
     346             :                                      format_unformat_error, line_input);
     347           0 :           goto done;
     348             :         }
     349           1 :       else if (unformat (line_input, "on"))
     350             :         {
     351           1 :           input_found = 1;
     352           1 :           onoff = 1;
     353             :         }
     354           0 :       else if (unformat (line_input, "off"))
     355             :         {
     356           0 :           input_found = 1;
     357           0 :           onoff = 0;
     358             :         }
     359             :       else
     360             :         {
     361           0 :           error = clib_error_return (0, "unknown input `%U'",
     362             :                                      format_unformat_error, line_input);
     363           0 :           goto done;
     364             :         }
     365             :     }
     366             : 
     367           1 :   if (!input_found)
     368           0 :     return clib_error_return (0, "must specify on or off");
     369             : 
     370           1 :   if (sw_if_index != ~0)
     371             :     {
     372           0 :       mif = bond_get_member_by_sw_if_index (sw_if_index);
     373           0 :       if (!mif)
     374           0 :         return (clib_error_return
     375             :                 (0, "Please add the member interface first"));
     376           0 :       mif->debug = onoff;
     377             :     }
     378             :   else
     379           1 :     lm->debug = onoff;
     380             : 
     381           1 : done:
     382           1 :   unformat_free (line_input);
     383             : 
     384           1 :   return error;
     385             : }
     386             : 
     387             : /* *INDENT-OFF* */
     388      179305 : VLIB_CLI_COMMAND (debug_lacp_command, static) = {
     389             :     .path = "debug lacp",
     390             :     .short_help = "debug lacp <interface> <on | off>",
     391             :     .function = debug_lacp_command_fn,
     392             : };
     393             : /* *INDENT-ON* */
     394             : 
     395             : clib_error_t *
     396         575 : lacp_cli_init (vlib_main_t * vm)
     397             : {
     398         575 :   lacp_main_t *lm = &lacp_main;
     399             : 
     400         575 :   lm->vlib_main = vm;
     401         575 :   lm->vnet_main = vnet_get_main ();
     402             : 
     403         575 :   return 0;
     404             : }
     405             : 
     406        1151 : VLIB_INIT_FUNCTION (lacp_cli_init);
     407             : 
     408             : /*
     409             :  * fd.io coding-style-patch-verification: ON
     410             :  *
     411             :  * Local Variables:
     412             :  * eval: (c-set-style "gnu")
     413             :  * End:
     414             :  */

Generated by: LCOV version 1.14