#include <vppinfra/hash.h>
#include <vnet/bonding/node.h>
#include <lacp/node.h>
+#include <vpp/stats/stat_segment.h>
lacp_main_t lacp_main;
vlib_put_frame_to_node (vm, hw->output_node_index, f);
- sif->last_lacpdu_time = vlib_time_now (vm);
+ sif->last_lacpdu_sent_time = vlib_time_now (lm->vlib_main);
+ sif->pdu_sent++;
}
/*
void
lacp_send_lacp_pdu (vlib_main_t * vm, slave_if_t * sif)
{
- lacp_main_t *lm = &lacp_main;
-
- if (sif->mode != BOND_MODE_LACP)
+ if ((sif->mode != BOND_MODE_LACP) || (sif->port_enabled == 0))
{
lacp_stop_timer (&sif->periodic_timer);
return;
default:
ASSERT (0);
}
-
- lacp_start_periodic_timer (lm->vlib_main, sif, sif->is_long_timeout ?
- LACP_SLOW_PERIODIC_TIMER :
- LACP_FAST_PERIODIC_TIMER);
}
void
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,
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))
{
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* */
}
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);
}
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);
}
}
}
/* 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));
/* 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));
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;
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;
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);
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);
}
}
slave_if_t *sif;
vnet_sw_interface_t *sw;
vlib_main_t *vm = lm->vlib_main;
- vnet_interface_main_t *im = &vnm->interface_main;
- sw = pool_elt_at_index (im->sw_interfaces, hw_if_index);
+ sw = vnet_get_hw_sw_interface (vnm, hw_if_index);
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);
}
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
- .description = "Link Aggregation Control Protocol",
+ .description = "Link Aggregation Control Protocol (LACP)",
};
/* *INDENT-ON* */