nat: use correct data types for memory sizes
[vpp.git] / src / plugins / lacp / lacp.c
index 473458a..e789de5 100644 (file)
@@ -21,6 +21,7 @@
 #include <vppinfra/hash.h>
 #include <vnet/bonding/node.h>
 #include <lacp/node.h>
+#include <vpp/stats/stat_segment.h>
 
 lacp_main_t lacp_main;
 
@@ -89,7 +90,8 @@ lacp_send_ethernet_lacp_pdu (slave_if_t * sif)
 
   vlib_put_frame_to_node (vm, hw->output_node_index, f);
 
-  sif->last_lacpdu_time = vlib_time_now (lm->vlib_main);
+  sif->last_lacpdu_sent_time = vlib_time_now (lm->vlib_main);
+  sif->pdu_sent++;
 }
 
 /*
@@ -106,7 +108,7 @@ lacp_pick_packet_template (slave_if_t * sif)
 void
 lacp_send_lacp_pdu (vlib_main_t * vm, slave_if_t * sif)
 {
-  if (sif->mode != BOND_MODE_LACP)
+  if ((sif->mode != BOND_MODE_LACP) || (sif->port_enabled == 0))
     {
       lacp_stop_timer (&sif->periodic_timer);
       return;
@@ -139,6 +141,8 @@ lacp_periodic (vlib_main_t * vm)
   bond_main_t *bm = &bond_main;
   lacp_main_t *lm = &lacp_main;
   slave_if_t *sif;
+  bond_if_t *bif;
+  u8 actor_state, partner_state;
 
   /* *INDENT-OFF* */
   pool_foreach (sif, bm->neighbors,
@@ -146,6 +150,8 @@ lacp_periodic (vlib_main_t * vm)
     if (sif->port_enabled == 0)
       continue;
 
+    actor_state = sif->actor.state;
+    partner_state = sif->partner.state;
     if (lacp_timer_is_running (sif->current_while_timer) &&
        lacp_timer_is_expired (lm->vlib_main, sif->current_while_timer))
       {
@@ -166,6 +172,20 @@ lacp_periodic (vlib_main_t * vm)
         lacp_stop_timer (&sif->wait_while_timer);
         lacp_selection_logic (vm, sif);
       }
+    if (actor_state != sif->actor.state)
+      {
+       bif = bond_get_master_by_dev_instance (sif->bif_dev_instance);
+       stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+                                       [sif->sw_if_index].actor_state,
+                                       sif->actor.state);
+      }
+    if (partner_state != sif->partner.state)
+      {
+       bif = bond_get_master_by_dev_instance (sif->bif_dev_instance);
+       stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+                                       [sif->sw_if_index].partner_state,
+                                       sif->partner.state);
+      }
   }));
   /* *INDENT-ON* */
 }
@@ -179,6 +199,7 @@ lacp_interface_enable_disable (vlib_main_t * vm, bond_if_t * bif,
 
   if (enable)
     {
+      lacp_create_periodic_process ();
       port_number = clib_bitmap_first_clear (bif->port_number_bitmap);
       bif->port_number_bitmap = clib_bitmap_set (bif->port_number_bitmap,
                                                 port_number, 1);
@@ -194,11 +215,23 @@ lacp_interface_enable_disable (vlib_main_t * vm, bond_if_t * bif,
     }
   else
     {
-      lm->lacp_int--;
+      ASSERT (lm->lacp_int >= 1);
       if (lm->lacp_int == 0)
        {
-         vlib_process_signal_event (vm, lm->lacp_process_node_index,
-                                    LACP_PROCESS_EVENT_STOP, 0);
+         /* *INDENT-OFF* */
+         ELOG_TYPE_DECLARE (e) =
+           {
+             .format = "lacp-int-en-dis: BUG lacp_int == 0",
+           };
+         /* *INDENT-ON* */
+         ELOG_DATA (&vlib_global_main.elog_main, e);
+       }
+      else
+       {
+         lm->lacp_int--;
+         if (lm->lacp_int == 0)
+           vlib_process_signal_event (vm, lm->lacp_process_node_index,
+                                      LACP_PROCESS_EVENT_STOP, 0);
        }
     }
 }
@@ -307,7 +340,10 @@ lacp_init_neighbor (slave_if_t * sif, u8 * hw_address, u16 port_number,
   lacp_stop_timer (&sif->actor_churn_timer);
   lacp_stop_timer (&sif->partner_churn_timer);
   lacp_stop_timer (&sif->periodic_timer);
-  lacp_stop_timer (&sif->last_lacpdu_time);
+  lacp_stop_timer (&sif->last_lacpdu_sent_time);
+  lacp_stop_timer (&sif->last_lacpdu_recd_time);
+  lacp_stop_timer (&sif->last_marker_pdu_sent_time);
+  lacp_stop_timer (&sif->last_marker_pdu_recd_time);
   sif->lacp_enabled = 1;
   sif->loopback_port = 0;
   sif->ready = 0;
@@ -330,8 +366,7 @@ lacp_init_neighbor (slave_if_t * sif, u8 * hw_address, u16 port_number,
   sif->partner.key = htons (group);
   sif->partner.port_number = htons (port_number);
   sif->partner.port_priority = htons (LACP_DEFAULT_PORT_PRIORITY);
-  sif->partner.key = htons (group);
-  sif->partner.state = LACP_STATE_LACP_ACTIVITY;
+  sif->partner.state = 0;
 
   sif->actor_admin = sif->actor;
   sif->partner_admin = sif->partner;
@@ -340,10 +375,19 @@ lacp_init_neighbor (slave_if_t * sif, u8 * hw_address, u16 port_number,
 void
 lacp_init_state_machines (vlib_main_t * vm, slave_if_t * sif)
 {
+  bond_main_t *bm = &bond_main;
+  bond_if_t *bif = bond_get_master_by_dev_instance (sif->bif_dev_instance);
+
   lacp_init_tx_machine (vm, sif);
   lacp_init_mux_machine (vm, sif);
   lacp_init_ptx_machine (vm, sif);
   lacp_init_rx_machine (vm, sif);
+  stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+                                 [sif->sw_if_index].actor_state,
+                                 sif->actor.state);
+  stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+                                 [sif->sw_if_index].partner_state,
+                                 sif->partner.state);
 }
 
 VLIB_INIT_FUNCTION (lacp_periodic_init);
@@ -358,16 +402,18 @@ lacp_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
   sif = bond_get_slave_by_sw_if_index (sw_if_index);
   if (sif)
     {
-      sif->port_enabled = flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+      if (sif->lacp_enabled == 0)
+       return 0;
+
+      /* port_enabled is both admin up and hw link up */
+      sif->port_enabled = ((flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) &&
+                          vnet_sw_interface_is_link_up (vnm, sw_if_index));
       if (sif->port_enabled == 0)
        {
-         if (sif->lacp_enabled)
-           {
-             lacp_init_neighbor (sif, sif->actor_admin.system,
-                                 ntohs (sif->actor_admin.port_number),
-                                 ntohs (sif->actor_admin.key));
-             lacp_init_state_machines (vm, sif);
-           }
+         lacp_init_neighbor (sif, sif->actor_admin.system,
+                             ntohs (sif->actor_admin.port_number),
+                             ntohs (sif->actor_admin.key));
+         lacp_init_state_machines (vm, sif);
        }
     }
 
@@ -388,15 +434,19 @@ lacp_hw_interface_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
   sif = bond_get_slave_by_sw_if_index (sw->sw_if_index);
   if (sif)
     {
-      if (!(flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
+      if (sif->lacp_enabled == 0)
+       return 0;
+
+      /* port_enabled is both admin up and hw link up */
+      sif->port_enabled = ((flags & VNET_HW_INTERFACE_FLAG_LINK_UP) &&
+                          vnet_sw_interface_is_admin_up (vnm,
+                                                         sw->sw_if_index));
+      if (sif->port_enabled == 0)
        {
-         if (sif->lacp_enabled)
-           {
-             lacp_init_neighbor (sif, sif->actor_admin.system,
-                                 ntohs (sif->actor_admin.port_number),
-                                 ntohs (sif->actor_admin.key));
-             lacp_init_state_machines (vm, sif);
-           }
+         lacp_init_neighbor (sif, sif->actor_admin.system,
+                             ntohs (sif->actor_admin.port_number),
+                             ntohs (sif->actor_admin.key));
+         lacp_init_state_machines (vm, sif);
        }
     }
 
@@ -408,7 +458,7 @@ VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (lacp_hw_interface_up_down);
 /* *INDENT-OFF* */
 VLIB_PLUGIN_REGISTER () = {
     .version = VPP_BUILD_VER,
-    .description = "Link Aggregation Control Protocol",
+    .description = "Link Aggregation Control Protocol (LACP)",
 };
 /* *INDENT-ON* */