+ value_map_t *map;
+ int status;
+ char *key;
+
+ if ((ci->values_num < 2) || (ci->values_num > 3) ||
+ (ci->values[0].type != OCONFIG_TYPE_STRING) ||
+ (ci->values[1].type != OCONFIG_TYPE_STRING) ||
+ ((ci->values_num == 3) && (ci->values[2].type != OCONFIG_TYPE_STRING))) {
+ ERROR("ethstat plugin: The %s option requires "
+ "two or three string arguments.",
+ ci->key);
+ return -1;
+ }
+
+ key = strdup(ci->values[0].value.string);
+ if (key == NULL) {
+ ERROR("ethstat plugin: strdup(3) failed.");
+ return ENOMEM;
+ }
+
+ map = calloc(1, sizeof(*map));
+ if (map == NULL) {
+ sfree(key);
+ ERROR("ethstat plugin: calloc failed.");
+ return ENOMEM;
+ }
+
+ sstrncpy(map->type, ci->values[1].value.string, sizeof(map->type));
+ if (ci->values_num == 3)
+ sstrncpy(map->type_instance, ci->values[2].value.string,
+ sizeof(map->type_instance));
+
+ if (value_map == NULL) {
+ value_map = c_avl_create((int (*)(const void *, const void *))strcmp);
+ if (value_map == NULL) {
+ sfree(map);
+ sfree(key);
+ ERROR("ethstat plugin: c_avl_create() failed.");
+ return -1;
+ }
+ }
+
+ status = c_avl_insert(value_map,
+ /* key = */ key,
+ /* value = */ map);
+ if (status != 0) {
+ if (status > 0)
+ ERROR("ethstat plugin: Multiple mappings for \"%s\".", key);
+ else
+ ERROR("ethstat plugin: c_avl_insert(\"%s\") failed.", key);
+
+ sfree(map);
+ sfree(key);
+ return -1;
+ }
+
+ return 0;
+} /* }}} int ethstat_add_map */
+
+static int ethstat_config(oconfig_item_t *ci) /* {{{ */
+{
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Interface", child->key) == 0)
+ ethstat_add_interface(child);
+ else if (strcasecmp("Map", child->key) == 0)
+ ethstat_add_map(child);
+ else if (strcasecmp("MappedOnly", child->key) == 0)
+ (void)cf_util_get_boolean(child, &collect_mapped_only);
+ else
+ WARNING("ethstat plugin: The config option \"%s\" is unknown.",
+ child->key);
+ }
+
+ return 0;
+} /* }}} */
+
+static void ethstat_submit_value(const char *device, const char *type_instance,
+ derive_t value) {
+ static c_complain_t complain_no_map = C_COMPLAIN_INIT_STATIC;
+
+ value_list_t vl = VALUE_LIST_INIT;
+ value_map_t *map = NULL;