papi: Use CMSG_SPACE for sizing ancillary buffer space
[vpp.git] / src / vnet / config.c
index 5937574..c05da66 100644 (file)
@@ -97,7 +97,7 @@ find_config_with_features (vlib_main_t * vm,
   config_string = cm->config_string_temp;
   cm->config_string_temp = 0;
   if (config_string)
-    _vec_len (config_string) = 0;
+    vec_set_len (config_string, 0);
 
   vec_foreach (f, feature_vector)
   {
@@ -119,6 +119,12 @@ find_config_with_features (vlib_main_t * vm,
       vec_add1 (config_string, next_index);
     }
 
+  /* Add the end node index to the config string so that it is part of
+   * the key used to detect string sharing. If this is not included then
+   * a modification of the end node would affect all the user of a shared
+   * string. */
+  vec_add1 (config_string, end_node_index);
+
   /* See if config string is unique. */
   p = hash_get_mem (cm->config_string_hash, config_string);
   if (p)
@@ -241,6 +247,23 @@ vnet_get_config_heap (vnet_config_main_t * cm, u32 ci)
   return heap_elt_at_index (cm->config_string_heap, ci);
 }
 
+void
+vnet_config_del (vnet_config_main_t * cm, u32 config_id)
+{
+  u32 *p = vnet_get_config_heap (cm, config_id);
+  vnet_config_t *old = pool_elt_at_index (cm->config_pool, p[-1]);
+  remove_reference (cm, old);
+}
+
+u32
+vnet_config_reset_end_node (vlib_main_t *vm, vnet_config_main_t *cm, u32 ci)
+{
+  cm->end_node_indices_by_user_index[ci] = cm->default_end_node_index;
+
+  return (
+    vnet_config_modify_end_node (vm, cm, ci, cm->default_end_node_index));
+}
+
 u32
 vnet_config_modify_end_node (vlib_main_t * vm,
                             vnet_config_main_t * cm,
@@ -273,7 +296,7 @@ vnet_config_modify_end_node (vlib_main_t * vm,
       if (new_features[last].node_index == cm->default_end_node_index)
        {
          vec_free (new_features->feature_config);
-         _vec_len (new_features) = last;
+         vec_set_len (new_features, last);
        }
     }
 
@@ -295,6 +318,18 @@ vnet_config_modify_end_node (vlib_main_t * vm,
   return new->config_string_heap_index + 1;
 }
 
+u32
+vnet_config_get_end_node (vlib_main_t *vm, vnet_config_main_t *cm,
+                         u32 config_string_heap_index)
+{
+  if (config_string_heap_index >= vec_len (cm->end_node_indices_by_user_index))
+    return cm->default_end_node_index;
+  if (~0 == cm->end_node_indices_by_user_index[config_string_heap_index])
+    return cm->default_end_node_index;
+
+  return (cm->end_node_indices_by_user_index[config_string_heap_index]);
+}
+
 u32
 vnet_config_add_feature (vlib_main_t * vm,
                         vnet_config_main_t * cm,
@@ -331,11 +366,16 @@ vnet_config_add_feature (vlib_main_t * vm,
   f->feature_index = feature_index;
   f->node_index = node_index;
 
-  n_feature_config_u32s =
-    round_pow2 (n_feature_config_bytes,
-               sizeof (f->feature_config[0])) /
-    sizeof (f->feature_config[0]);
-  vec_add (f->feature_config, feature_config, n_feature_config_u32s);
+  if (n_feature_config_bytes)
+    {
+      n_feature_config_u32s =
+       round_pow2 (n_feature_config_bytes,
+                   sizeof (f->feature_config[0])) /
+       sizeof (f->feature_config[0]);
+      vec_validate (f->feature_config, n_feature_config_u32s - 1);
+      clib_memcpy_fast (f->feature_config, feature_config,
+                       n_feature_config_bytes);
+    }
 
   /* Sort (prioritize) features. */
   if (vec_len (new_features) > 1)