+static clib_error_t *
+statseg_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
+ vnet_sw_interface_t *si_sup =
+ vnet_get_sup_sw_interface (vnm, si->sw_if_index);
+ vnet_hw_interface_t *hi_sup;
+ u8 *s = 0;
+ u8 *symlink_name = 0;
+ u32 vector_index;
+
+ void *oldheap = vlib_stats_push_heap (sm->interfaces);
+ vlib_stat_segment_lock ();
+
+ vec_validate (sm->interfaces, sw_if_index);
+
+ ASSERT (si_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE);
+ hi_sup = vnet_get_hw_interface (vnm, si_sup->hw_if_index);
+
+ s = format (s, "%v", hi_sup->name);
+ if (si->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
+ s = format (s, ".%d", si->sub.id);
+ s = format (s, "%c", 0);
+
+ if (is_add)
+ {
+ sm->interfaces[sw_if_index] = s;
+#define _(E, n, p) \
+ clib_mem_set_heap (oldheap); /* Exit stats segment */ \
+ vector_index = lookup_hash_index ((u8 *) "/" #p "/" #n); \
+ clib_mem_set_heap (sm->heap); /* Re-enter stat segment */ \
+ vec_reset_length (symlink_name); \
+ symlink_name = format (symlink_name, "/interfaces/%U/" #n "%c", \
+ format_vlib_stats_symlink, s, 0); \
+ vlib_stats_register_symlink (oldheap, symlink_name, vector_index, \
+ sw_if_index, 0 /* don't lock */);
+ foreach_simple_interface_counter_name
+ foreach_combined_interface_counter_name
+#undef _
+
+ vec_free (symlink_name);
+ }
+ else
+ {
+ vec_free (sm->interfaces[sw_if_index]);
+ sm->interfaces[sw_if_index] = 0;
+#define _(E, n, p) \
+ vec_reset_length (symlink_name); \
+ symlink_name = format (symlink_name, "/interfaces/%U/" #n "%c", \
+ format_vlib_stats_symlink, s, 0); \
+ clib_mem_set_heap (oldheap); /* Exit stats segment */ \
+ vector_index = lookup_hash_index ((u8 *) symlink_name); \
+ clib_mem_set_heap (sm->heap); /* Re-enter stat segment */ \
+ vlib_stats_delete_counter (vector_index, oldheap);
+ foreach_simple_interface_counter_name
+ foreach_combined_interface_counter_name
+#undef _
+
+ vec_free (symlink_name);
+ }
+
+ stat_segment_directory_entry_t *ep;
+ ep = &sm->directory_vector[STAT_COUNTER_INTERFACE_NAMES];
+ ep->data = sm->interfaces;
+
+ vlib_stat_segment_unlock ();
+ clib_mem_set_heap (oldheap);
+
+ return 0;
+}
+
+VNET_SW_INTERFACE_ADD_DEL_FUNCTION (statseg_sw_interface_add_del);
+