lacp: continuing input packet trace from device driver
[vpp.git] / src / plugins / lacp / lacp.c
index dfe11b1..dba6cb1 100644 (file)
@@ -89,7 +89,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 +107,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;
@@ -179,6 +180,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 +196,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);
        }
     }
 }
@@ -216,7 +230,7 @@ lacp_periodic_init (vlib_main_t * vm)
 
   /* Create the ethernet lacp packet template */
 
-  memset (&h, 0, sizeof (h));
+  clib_memset (&h, 0, sizeof (h));
 
   memcpy (h.ethernet.dst_address, dst, sizeof (h.ethernet.dst_address));
 
@@ -253,7 +267,7 @@ lacp_periodic_init (vlib_main_t * vm)
 
   /* Create the ethernet marker protocol packet template */
 
-  memset (&m, 0, sizeof (m));
+  clib_memset (&m, 0, sizeof (m));
 
   memcpy (m.ethernet.dst_address, dst, sizeof (m.ethernet.dst_address));
 
@@ -307,7 +321,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 +347,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;
@@ -358,16 +374,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_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_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 +406,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_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_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 +430,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* */