LCOV - code coverage report
Current view: top level - plugins/lacp - ptx_machine.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 58 65 89.2 %
Date: 2023-07-05 22:20:52 Functions: 7 7 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             : 
      18             : #include <vnet/bonding/node.h>
      19             : #include <lacp/node.h>
      20             : 
      21             : /*
      22             :  *  LACP State = NO_PERIODIC
      23             :  */
      24             : static lacp_fsm_state_t lacp_ptx_state_no_periodic[] = {
      25             :   {LACP_ACTION_NO_PERIODIC, LACP_PTX_STATE_NO_PERIODIC},        // event 0 NO_PERIODIC
      26             :   {LACP_ACTION_SLOW_PERIODIC, LACP_PTX_STATE_SLOW_PERIODIC},    // event 1 LONG_TIMEOUT
      27             :   {LACP_ACTION_NO_PERIODIC, LACP_PTX_STATE_NO_PERIODIC},        // event 2 TIMER_EXPIRED
      28             :   {LACP_ACTION_FAST_PERIODIC, LACP_PTX_STATE_FAST_PERIODIC},    // event 3 SHORT_TIMEOUT
      29             : };
      30             : 
      31             : /*
      32             :  *  LACP State = FAST_PERIODIC
      33             :  */
      34             : static lacp_fsm_state_t lacp_ptx_state_fast_periodic[] = {
      35             :   {LACP_ACTION_NO_PERIODIC, LACP_PTX_STATE_NO_PERIODIC},        // event 0 NO_PERIODIC
      36             :   {LACP_ACTION_SLOW_PERIODIC, LACP_PTX_STATE_SLOW_PERIODIC},    // event 1 LONG_TIMEOUT
      37             :   {LACP_ACTION_TIMER_EXPIRED, LACP_PTX_STATE_PERIODIC_TX},      // event 2 TIMER_EXPIRED
      38             :   {LACP_ACTION_FAST_PERIODIC, LACP_PTX_STATE_FAST_PERIODIC},    // event 3 SHORT_TIMEOUT
      39             : };
      40             : 
      41             : /*
      42             :  *  LACP State = SLOW_PERIODIC
      43             :  */
      44             : static lacp_fsm_state_t lacp_ptx_state_slow_periodic[] = {
      45             :   {LACP_ACTION_NO_PERIODIC, LACP_PTX_STATE_NO_PERIODIC},        // event 0 NO_PERIODIC
      46             :   {LACP_ACTION_SLOW_PERIODIC, LACP_PTX_STATE_SLOW_PERIODIC},    // event 1 LONG_TIMEOUT
      47             :   {LACP_ACTION_TIMER_EXPIRED, LACP_PTX_STATE_PERIODIC_TX},      // event 2 TIMER_EXPIRED
      48             :   {LACP_ACTION_FAST_PERIODIC, LACP_PTX_STATE_FAST_PERIODIC},    // event 3 SHORT_TIMEOUT
      49             : };
      50             : 
      51             : /*
      52             :  *  LACP State = PERIODIC_TX
      53             :  */
      54             : static lacp_fsm_state_t lacp_ptx_state_periodic_tx[] = {
      55             :   {LACP_ACTION_NO_PERIODIC, LACP_PTX_STATE_NO_PERIODIC},        // event 0 NO_PERIODIC
      56             :   {LACP_NOACTION, LACP_PTX_STATE_PERIODIC_TX},  // event 1 LONG_TIMEOUT
      57             :   {LACP_ACTION_TIMER_EXPIRED, LACP_PTX_STATE_PERIODIC_TX},      // event 2 TIMER_EXPIRED
      58             :   {LACP_NOACTION, LACP_PTX_STATE_PERIODIC_TX},  // event 3 SHORT_TIMEOUT
      59             : };
      60             : 
      61             : 
      62             : static lacp_fsm_machine_t lacp_ptx_fsm_table[] = {
      63             :   {lacp_ptx_state_no_periodic},
      64             :   {lacp_ptx_state_fast_periodic},
      65             :   {lacp_ptx_state_slow_periodic},
      66             :   {lacp_ptx_state_periodic_tx},
      67             : };
      68             : 
      69             : lacp_machine_t lacp_ptx_machine = {
      70             :   lacp_ptx_fsm_table,
      71             :   lacp_ptx_debug_func,
      72             : };
      73             : 
      74             : int
      75          13 : lacp_ptx_action_no_periodic (void *p1, void *p2)
      76             : {
      77          13 :   vlib_main_t *vm = p1;
      78          13 :   member_if_t *mif = p2;
      79             : 
      80          13 :   lacp_stop_timer (&mif->periodic_timer);
      81          13 :   lacp_ptx_post_short_timeout_event (vm, mif);
      82          13 :   return 0;
      83             : }
      84             : 
      85             : int
      86           9 : lacp_ptx_action_slow_periodic (void *p1, void *p2)
      87             : {
      88           9 :   vlib_main_t *vm = p1;
      89           9 :   member_if_t *mif = p2;
      90             :   u8 timer_expired;
      91             : 
      92           9 :   if (!(mif->partner.state & LACP_STATE_LACP_ACTIVITY) &&
      93           9 :       !(mif->actor.state & LACP_STATE_LACP_ACTIVITY))
      94           0 :     lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
      95             :                            LACP_PTX_EVENT_NO_PERIODIC, &mif->ptx_state);
      96             :   else
      97             :     {
      98          18 :       if (lacp_timer_is_running (mif->periodic_timer) &&
      99           9 :           lacp_timer_is_expired (vm, mif->periodic_timer))
     100           0 :         timer_expired = 1;
     101             :       else
     102           9 :         timer_expired = 0;
     103             : 
     104           9 :       lacp_schedule_periodic_timer (vm, mif);
     105             : 
     106           9 :       if (timer_expired || (mif->partner.state & LACP_STATE_LACP_TIMEOUT))
     107           0 :         lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     108             :                                LACP_PTX_EVENT_TIMER_EXPIRED, &mif->ptx_state);
     109             :     }
     110             : 
     111           9 :   return 0;
     112             : }
     113             : 
     114             : int
     115          20 : lacp_ptx_action_fast_periodic (void *p1, void *p2)
     116             : {
     117          20 :   vlib_main_t *vm = p1;
     118          20 :   member_if_t *mif = p2;
     119             :   u8 timer_expired;
     120             : 
     121          20 :   if (!(mif->partner.state & LACP_STATE_LACP_ACTIVITY) &&
     122          20 :       !(mif->actor.state & LACP_STATE_LACP_ACTIVITY))
     123           0 :     lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     124             :                            LACP_PTX_EVENT_NO_PERIODIC, &mif->ptx_state);
     125             :   else
     126             :     {
     127          29 :       if (lacp_timer_is_running (mif->periodic_timer) &&
     128           9 :           lacp_timer_is_expired (vm, mif->periodic_timer))
     129           9 :         timer_expired = 1;
     130             :       else
     131          11 :         timer_expired = 0;
     132             : 
     133          20 :       lacp_start_periodic_timer (vm, mif, LACP_FAST_PERIODIC_TIMER);
     134             : 
     135          20 :       if (timer_expired)
     136           9 :         lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     137             :                                LACP_PTX_EVENT_TIMER_EXPIRED, &mif->ptx_state);
     138             : 
     139          20 :       if (!(mif->partner.state & LACP_STATE_LACP_TIMEOUT))
     140           9 :         lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     141             :                                LACP_PTX_EVENT_LONG_TIMEOUT, &mif->ptx_state);
     142             :     }
     143             : 
     144          20 :   return 0;
     145             : }
     146             : 
     147             : int
     148          33 : lacp_ptx_action_timer_expired (void *p1, void *p2)
     149             : {
     150          33 :   vlib_main_t *vm = p1;
     151          33 :   member_if_t *mif = p2;
     152             : 
     153          33 :   if (!(mif->partner.state & LACP_STATE_LACP_ACTIVITY) &&
     154          11 :       !(mif->actor.state & LACP_STATE_LACP_ACTIVITY))
     155           0 :     lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     156             :                            LACP_PTX_EVENT_NO_PERIODIC, &mif->ptx_state);
     157             :   else
     158             :     {
     159          33 :       mif->ntt = 1;
     160          33 :       lacp_machine_dispatch (&lacp_tx_machine, vm, mif, LACP_TX_EVENT_NTT,
     161             :                              &mif->tx_state);
     162          33 :       if (mif->partner.state & LACP_STATE_LACP_TIMEOUT)
     163          33 :         lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     164             :                                LACP_PTX_EVENT_SHORT_TIMEOUT, &mif->ptx_state);
     165             :       else
     166           0 :         lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     167             :                                LACP_PTX_EVENT_LONG_TIMEOUT, &mif->ptx_state);
     168             :     }
     169             : 
     170          33 :   return 0;
     171             : }
     172             : 
     173             : static u8 *
     174          70 : format_ptx_event (u8 * s, va_list * args)
     175             : {
     176             :   static lacp_event_struct lacp_ptx_event_array[] = {
     177             : #define _(b, s, n) {.bit = b, .str = #s, },
     178             :     foreach_lacp_ptx_event
     179             : #undef _
     180             :     {.str = NULL}
     181             :   };
     182          70 :   int e = va_arg (*args, int);
     183          70 :   lacp_event_struct *event_entry = lacp_ptx_event_array;
     184             : 
     185          70 :   if (e >= (sizeof (lacp_ptx_event_array) / sizeof (*event_entry)))
     186           0 :     s = format (s, "Bad event %d", e);
     187             :   else
     188          70 :     s = format (s, "%s", event_entry[e].str);
     189             : 
     190          70 :   return s;
     191             : }
     192             : 
     193             : void
     194          70 : lacp_ptx_debug_func (member_if_t * mif, int event, int state,
     195             :                      lacp_fsm_state_t * transition)
     196             : {
     197          70 :   vlib_worker_thread_t *w = vlib_worker_threads + os_get_thread_index ();
     198             :   /* *INDENT-OFF* */
     199             :   ELOG_TYPE_DECLARE (e) =
     200             :     {
     201             :       .format = "%s",
     202             :       .format_args = "T4",
     203             :     };
     204             :   /* *INDENT-ON* */
     205             :   struct
     206             :   {
     207             :     u32 event;
     208          70 :   } *ed = 0;
     209             : 
     210          70 :   ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, w->elog_track);
     211          70 :   ed->event =
     212          70 :     elog_string (&vlib_global_main.elog_main, "%U-PTX: %U, %U->%U%c",
     213             :                  format_vnet_sw_if_index_name, vnet_get_main (),
     214             :                  mif->sw_if_index, format_ptx_event, event,
     215             :                  format_ptx_sm_state, state, format_ptx_sm_state,
     216             :                  transition->next_state, 0);
     217          70 : }
     218             : 
     219             : void
     220          11 : lacp_init_ptx_machine (vlib_main_t * vm, member_if_t * mif)
     221             : {
     222          11 :   lacp_machine_dispatch (&lacp_ptx_machine, vm, mif,
     223             :                          LACP_PTX_EVENT_NO_PERIODIC, &mif->ptx_state);
     224          11 : }
     225             : 
     226             : /*
     227             :  * fd.io coding-style-patch-verification: ON
     228             :  *
     229             :  * Local Variables:
     230             :  * eval: (c-set-style "gnu")
     231             :  * End:
     232             :  */

Generated by: LCOV version 1.14