#include <vlib/unix/unix.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/bonding/node.h>
+#include <vpp/stats/stat_segment.h>
void
bond_disable_collecting_distributing (vlib_main_t * vm, slave_if_t * sif)
}
clib_spinlock_unlock_if_init (&bif->lockp);
- return;
+ if (bif->mode == BOND_MODE_LACP)
+ stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+ [sif->sw_if_index], sif->actor.state);
}
void
}
clib_spinlock_unlock_if_init (&bif->lockp);
- return;
+ if (bif->mode == BOND_MODE_LACP)
+ stat_segment_set_state_counter (bm->stats[bif->sw_if_index]
+ [sif->sw_if_index], sif->actor.state);
}
int
if ((bif->mode == BOND_MODE_LACP) && bm->lacp_enable_disable)
(*bm->lacp_enable_disable) (vm, bif, sif, 0);
+ if (bif->mode == BOND_MODE_LACP)
+ stat_segment_deregister_state_counter
+ (bm->stats[bif->sw_if_index][sif->sw_if_index]);
+
pool_put (bm->neighbors, sif);
}
clib_error_return (0, "bond interface cannot be enslaved");
return;
}
+ if (bif->mode == BOND_MODE_LACP)
+ {
+ u8 *name = format (0, "/if/lacp/%u/%u/state", bif->sw_if_index,
+ args->slave);
+
+ vec_validate (bm->stats, bif->sw_if_index);
+ vec_validate (bm->stats[bif->sw_if_index], args->slave);
+
+ args->error = stat_segment_register_state_counter
+ (name, &bm->stats[bif->sw_if_index][args->slave]);
+ vec_free (name);
+ if (args->error != 0)
+ {
+ args->rv = VNET_API_ERROR_INVALID_INTERFACE;
+ return;
+ }
+ }
+
pool_get (bm->neighbors, sif);
clib_memset (sif, 0, sizeof (*sif));
sw = pool_elt_at_index (im->sw_interfaces, args->slave);
type_name = "ErrIndex";
break;
+ case STAT_DIR_TYPE_NAME_VECTOR:
+ type_name = "NameVector";
+ break;
+
default:
type_name = "illegal!";
break;
};
/* *INDENT-ON* */
-
clib_error_t *
stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn,
u32 caller_index)
return NULL;
}
+clib_error_t *
+stat_segment_register_state_counter (u8 * name, u32 * index)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ stat_segment_shared_header_t *shared_header = sm->shared_header;
+ void *oldheap;
+ stat_segment_directory_entry_t e;
+
+ ASSERT (shared_header);
+ ASSERT (vlib_get_thread_index () == 0);
+
+ u32 next_vector_index = vec_len (sm->directory_vector);
+ u32 vector_index = lookup_or_create_hash_index (name,
+ next_vector_index);
+
+ if (vector_index < next_vector_index) /* Already registered */
+ return clib_error_return (0, "%v is already registered", name);
+
+ oldheap = vlib_stats_push_heap (NULL);
+ vlib_stat_segment_lock ();
+
+ memset (&e, 0, sizeof (e));
+ e.type = STAT_DIR_TYPE_SCALAR_INDEX;
+
+ memcpy (e.name, name, vec_len (name));
+ vec_add1 (sm->directory_vector, e);
+
+ shared_header->directory_offset =
+ stat_segment_offset (shared_header, sm->directory_vector);
+
+ vlib_stat_segment_unlock ();
+ clib_mem_set_heap (oldheap);
+
+ *index = next_vector_index;
+ return 0;
+}
+
+clib_error_t *
+stat_segment_deregister_state_counter (u32 index)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ stat_segment_shared_header_t *shared_header = sm->shared_header;
+ stat_segment_directory_entry_t *e;
+
+ ASSERT (shared_header);
+
+ if (index > vec_len (sm->directory_vector))
+ return clib_error_return (0, "%u index does not exist", index);
+
+ e = &sm->directory_vector[index];
+ if (e->type != STAT_DIR_TYPE_SCALAR_INDEX)
+ return clib_error_return (0, "%u index cannot be deleted", index);
+
+ hash_unset (sm->directory_vector_by_name, &e->name);
+ vec_del1 (sm->directory_vector, index);
+ return 0;
+}
+
+void
+stat_segment_set_state_counter (u32 index, u64 value)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+
+ ASSERT (index < vec_len (sm->directory_vector));
+ sm->directory_vector[index].index = value;
+}
+
static clib_error_t *
statseg_config (vlib_main_t * vm, unformat_input_t * input)
{