ipsec: IPSec protection for multi-point tunnel interfaces
[vpp.git] / src / plugins / lacp / lacp.c
index 4bb50ae..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;
 
@@ -107,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;
@@ -140,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,
@@ -147,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))
       {
@@ -167,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* */
 }
@@ -347,7 +366,6 @@ 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 = 0;
 
   sif->actor_admin = sif->actor;
@@ -357,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);
@@ -375,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);
        }
     }
 
@@ -405,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);
        }
     }