static lagopus_result_t channel_set_dpid(const char *channel_name, uint64_t dpid) { lagopus_result_t ret; struct channel *chan = NULL; struct channel_list *chan_list = NULL; void *valptr = NULL; if (dpid == UNUSED_DPID) { return LAGOPUS_RESULT_INVALID_ARGS; } ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (chan == NULL) { return LAGOPUS_RESULT_NOT_FOUND; } if (channel_dpid_get(chan) != UNUSED_DPID) { return LAGOPUS_RESULT_BUSY; } ret = channel_dpid_set(chan, dpid); if (ret != LAGOPUS_RESULT_OK) { return ret; } ret = lagopus_hashmap_find(&dp_table, (void *)dpid, (void **)&chan_list); if (ret == LAGOPUS_RESULT_NOT_FOUND) { chan_list = channel_list_alloc(); if (chan_list == NULL) { ret = LAGOPUS_RESULT_NO_MEMORY; goto done; } valptr = chan_list; ret = lagopus_hashmap_add(&dp_table, (void *)dpid, (void **)&valptr, false); if (ret != LAGOPUS_RESULT_OK) { goto done; } } else if (ret != LAGOPUS_RESULT_OK) { goto done; } channel_id_set(chan, channel_list_channel_id_get(chan_list)); ret = channel_list_insert(chan_list, chan); done: return ret; }
static inline bool s_is_stage(lagopus_pipeline_stage_t ps) { void *val; lagopus_result_t r = lagopus_hashmap_find(&s_ps_obj_tbl, (void *)ps, &val); return (r == LAGOPUS_RESULT_OK && (bool)val == true) ? true : false; }
lagopus_result_t channel_mgr_channels_lookup_by_dpid(uint64_t dpid, struct channel_list **chan_list) { if (main_table == NULL) { return LAGOPUS_RESULT_ANY_FAILURES; } return lagopus_hashmap_find(&dp_table, (void *)dpid, (void **)chan_list); }
lagopus_result_t channel_mgr_channel_lookup_by_name(const char *channel_name, struct channel **chan) { if (main_table == NULL) { return LAGOPUS_RESULT_ANY_FAILURES; } return lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)chan); }
/** * Get reference of the rib. * @param[in] ifindex Interface index. * @param[in] rib RIB structure. */ static lagopus_result_t ifinfo_rib_get(int ifindex, struct rib **rib) { struct ifinfo_entry *entry; lagopus_result_t rv; rv = lagopus_hashmap_find(&ifinfo_hashmap, (void *)ifindex, (void **)&entry); if (rv == LAGOPUS_RESULT_OK) { *rib = entry->rib; } return rv; }
static lagopus_result_t channel_unset_dpid(const char *channel_name) { uint64_t dpid; lagopus_result_t ret; struct channel *chan = NULL; struct channel_list *chan_list = NULL; ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (chan == NULL) { return LAGOPUS_RESULT_NOT_FOUND; } if (channel_is_alive(chan) == true) { return LAGOPUS_RESULT_BUSY; } dpid = channel_dpid_get(chan); if (dpid == UNUSED_DPID) { return LAGOPUS_RESULT_OK; } ret = lagopus_hashmap_find(&dp_table, (void *)dpid, (void **)&chan_list); if (ret != LAGOPUS_RESULT_OK) { return ret; } ret = channel_list_delete(chan_list, chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } ret = channel_dpid_set(chan, UNUSED_DPID); if (ret != LAGOPUS_RESULT_OK) { return ret; } return ret; }
lagopus_result_t channel_mgr_channel_stop(const char *channel_name) { lagopus_result_t ret; struct channel *chan; ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } channel_disable(chan); return LAGOPUS_RESULT_OK; }
static inline testobj_config_t * s_config_find(const char *name) { testobj_config_t *ret = NULL; if (IS_VALID_STRING(name) == true) { void *val; if (lagopus_hashmap_find(&s_tbl, (void *)name, &val) == LAGOPUS_RESULT_OK) { ret = (testobj_config_t *)val; } } return ret; }
static inline lagopus_pipeline_stage_t s_find_stage(const char *name) { lagopus_pipeline_stage_t ret = NULL; if (IS_VALID_STRING(name) == true) { void *val; if (lagopus_hashmap_find(&s_ps_name_tbl, (void *)name, &val) == LAGOPUS_RESULT_OK) { ret = (lagopus_pipeline_stage_t)val; } } return ret; }
lagopus_result_t channel_mgr_channel_is_alive(const char *channel_name, bool *b) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct channel *chan; ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } *b = channel_session_is_alive(chan); return LAGOPUS_RESULT_OK; }
lagopus_result_t channel_mgr_channel_dpid_get(const char *channel_name, uint64_t *dpid) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct channel *chan; ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } *dpid = channel_dpid_get(chan); return LAGOPUS_RESULT_OK; }
lagopus_result_t channel_mgr_channel_lookup(const char *bridge_name, struct addrunion *addr, struct channel **chan) { char ipaddr[INET6_ADDRSTRLEN+1]; char key[MAIN_KEY_LEN]; if (main_table == NULL) { return LAGOPUS_RESULT_ANY_FAILURES; } if (addrunion_ipaddr_str_get(addr, ipaddr, sizeof(ipaddr)) == NULL) { return LAGOPUS_RESULT_ANY_FAILURES; } MAKE_MAIN_HASH(key, ipaddr, addr, bridge_name); return lagopus_hashmap_find(&main_table, (void *)key, (void **)chan); }
lagopus_result_t channel_mgr_channel_start(const char *channel_name) { lagopus_result_t ret; struct channel *chan; ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } if (channel_dpid_get(chan) == UNUSED_DPID) { return LAGOPUS_RESULT_INVALID_ARGS; } channel_enable(chan); return LAGOPUS_RESULT_OK; }
static lagopus_result_t channel_delete_internal(const char *key) { lagopus_result_t ret; struct channel *chan; ret = lagopus_hashmap_find(&main_table, (void *)key, (void **)&chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } channel_disable(chan); ret = channel_free(chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } return lagopus_hashmap_delete(&main_table, (void *)key, NULL, false); }
static lagopus_result_t channel_add_internal(const char *channel_name, struct addrunion *addr, struct channel **channel) { lagopus_result_t ret; struct channel *chan = NULL; void *valptr = NULL; if (main_table == NULL) { return LAGOPUS_RESULT_ANY_FAILURES; } ret = lagopus_hashmap_find(&main_table, (void *)channel_name, (void **)&chan); if (ret == LAGOPUS_RESULT_OK && chan != NULL) { /* FIXME support auxiliary connections */ return LAGOPUS_RESULT_ALREADY_EXISTS; } else if (ret != LAGOPUS_RESULT_NOT_FOUND) { return ret; } #define UNUSED_DPID 0 chan = channel_alloc(addr, em, UNUSED_DPID); if (chan == NULL) { return LAGOPUS_RESULT_NO_MEMORY; } lagopus_msg_debug(10, "channel allocated %p\n", chan); valptr = chan; ret = lagopus_hashmap_add(&main_table, (void *)channel_name, (void **)&valptr, false); if (ret != LAGOPUS_RESULT_OK) { channel_free(chan); } if (ret != LAGOPUS_RESULT_OK) { channel_delete_internal((const char *) channel_name); } else { *channel = chan; } return ret; }
lagopus_result_t ofp_bridgeq_mgr_bridge_lookup(uint64_t dpid, struct ofp_bridgeq **bridgeq) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (bridgeq != NULL) { if (bridgeq_table != NULL) { ret = lagopus_hashmap_find(&bridgeq_table, (void *)dpid, (void **)bridgeq); if (ret == LAGOPUS_RESULT_OK) { ofp_bridgeq_refs_get(*bridgeq); } } else { ret = LAGOPUS_RESULT_INVALID_OBJECT; lagopus_msg_warning("bridgeq_table is NULL.\n"); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static inline lagopus_result_t s_find_addr(void *addr, size_t *sptr) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (likely(s_tbl != NULL)) { if (likely(addr != NULL && sptr != NULL)) { void *val; *sptr = 0; ret = lagopus_hashmap_find(&s_tbl, addr, &val); if (likely(ret == LAGOPUS_RESULT_OK)) { *sptr = (size_t)val; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } } else { ret = LAGOPUS_RESULT_NOT_OPERATIONAL; } return ret; }
lagopus_result_t lagopus_get_port_statistics(lagopus_hashmap_t *hm, struct ofp_port_stats_request *request, struct port_stats_list *list, struct ofp_error *error) { struct port *port; if (request->port_no == OFPP_ANY) { lagopus_hashmap_iterate(hm, port_do_stats_iterate, list); } else { if (lagopus_hashmap_find(hm, (void *)request->port_no, &port) != LAGOPUS_RESULT_OK) { error->type = OFPET_BAD_REQUEST; error->code = OFPBRC_BAD_PORT; lagopus_msg_info("port stats: %d: no such port (%d:%d)\n", request->port_no, error->type, error->code); return LAGOPUS_RESULT_OFP_ERROR; } port_add_stats(port, list); } return LAGOPUS_RESULT_OK; }
/** * Add route information notified from netlink. */ void rib_notifier_ipv4_route_add(struct in_addr *dest, int prefixlen, struct in_addr *gate, int ifindex, uint8_t scope) { struct rib *rib; lagopus_result_t rv; struct notification_entry *entry = NULL; struct ifinfo_entry *ientry = NULL; rv = ifinfo_rib_get(ifindex, &rib); if (rv == LAGOPUS_RESULT_OK && rib != NULL) { entry = rib_create_notification_entry(NOTIFICATION_TYPE_ROUTE, NOTIFICATION_ACTION_TYPE_ADD); if (entry) { /* get mac address of the interface. */ rv = lagopus_hashmap_find(&ifinfo_hashmap, (void *)ifindex, (void **)&ientry); if (ientry == NULL || rv != LAGOPUS_RESULT_OK) { lagopus_msg_warning("get interface info failed.\n"); return; } /* set data to notification entry object. */ entry->route.ifindex = ifindex; entry->route.dest = *dest; entry->route.gate = *gate; entry->route.scope = scope; entry->route.prefixlen = prefixlen; memcpy(entry->route.mac, ientry->hwaddr, UPDATER_ETH_LEN); /* add notification entry to queue. */ rv = rib_add_notification_entry(rib, entry); } else { lagopus_msg_warning("create notification entry failed\n"); } } return; }
static void check_status_and_send_traps(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct port_stat *port_stat; size_t index; char ifname[IFNAMSIZ + 1]; size_t len = 0; struct ifTable_entry *entry = NULL; int32_t ifAdminStatus, ifOperStatus; int32_t old_ifAdminStatus, old_ifOperStatus; if ((ret = dp_get_port_stat(&port_stat)) == LAGOPUS_RESULT_OK) { /* check each port_stat, send trap if needed! */ for (index = 0; dataplane_interface_get_ifDescr( port_stat, index, ifname, &len) == LAGOPUS_RESULT_OK; index++) { if (len > 0) { int32_t ifIndex = (int32_t) (index + 1); if (dataplane_interface_get_ifAdminStatus( port_stat, index, &ifAdminStatus) == LAGOPUS_RESULT_OK && dataplane_interface_get_ifOperStatus( port_stat, index, &ifOperStatus) == LAGOPUS_RESULT_OK) { /* Note: * index may be changed if a port is attached/detacched to vSwitch, * so use ifName as key. */ ret = lagopus_hashmap_find(&iftable_entry_hash, (void *)ifname, (void *)&entry); if (ret == LAGOPUS_RESULT_OK) { old_ifAdminStatus = entry->ifAdminStatus; old_ifOperStatus = entry->ifOperStatus; entry->ifAdminStatus = ifAdminStatus; entry->ifOperStatus = ifOperStatus; if (ifOperStatus != old_ifOperStatus) { /* operation status prior to administration status */ if (ifOperStatus == up) { /* is up */ (void)send_linkUp_trap(ifIndex, ifAdminStatus, ifOperStatus); } else if (ifOperStatus != up && old_ifOperStatus == up) { (void)send_linkDown_trap(ifIndex, ifAdminStatus, ifOperStatus); } } else if (ifAdminStatus != old_ifAdminStatus) { if (ifAdminStatus == up) { (void)send_linkUp_trap(ifIndex, ifAdminStatus, ifOperStatus); } else if (ifAdminStatus != up && old_ifAdminStatus == up) { (void)send_linkDown_trap(ifIndex, ifAdminStatus, ifOperStatus); } } } else { /* The entry does not exist in previous status checking, */ /* so the port_stat is attached recentry. */ if (ifOperStatus == up) { (void)send_linkUp_trap(ifIndex, ifAdminStatus, ifOperStatus); } if ((entry = (struct ifTable_entry *) malloc (sizeof(*entry))) != NULL) { entry->ifAdminStatus = ifAdminStatus; entry->ifOperStatus = ifOperStatus; if ((ret = lagopus_hashmap_add(&iftable_entry_hash, (void *)ifname, (void **)&entry, false)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); free(entry); } } else { lagopus_perror(LAGOPUS_RESULT_NO_MEMORY); } } } } } } }
lagopus_result_t ofp_bridgeq_mgr_bridge_register(uint64_t dpid) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct ofp_bridge *ofp_bridge = NULL; struct ofp_bridgeq *bridgeq; lagopus_msg_debug(1, "called. (dpid: %"PRIu64")\n", dpid); if (bridgeq_table != NULL) { /* check not exists */ ret = lagopus_hashmap_find(&bridgeq_table, (void *)dpid, (void **)&bridgeq); if (ret == LAGOPUS_RESULT_NOT_FOUND) { /* allocate bridgeq */ if ((bridgeq = (struct ofp_bridgeq *)malloc(sizeof(struct ofp_bridgeq))) == NULL) { ret = LAGOPUS_RESULT_NO_MEMORY; } else if ((ret = ofp_bridge_create(&ofp_bridge, dpid)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); free(bridgeq); } else { /* init bridgeq */ bridgeq->ofp_bridge = ofp_bridge; bridgeq->refs = 1; bridgeq->lock = NULL; memset(bridgeq->polls, 0, sizeof(bridgeq->polls)); memset(bridgeq->dp_polls, 0, sizeof(bridgeq->dp_polls)); if ((ret = lagopus_mutex_create(&(bridgeq->lock))) != LAGOPUS_RESULT_OK) { /* create lock */ lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); } else if ((ret = lagopus_qmuxer_poll_create( &(bridgeq->polls[EVENTQ_POLL]), ofp_bridge->eventq, LAGOPUS_QMUXER_POLL_READABLE)) != LAGOPUS_RESULT_OK) { /* create eventq poll */ lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); } else if ((ret = lagopus_qmuxer_poll_create( &(bridgeq->polls[DATAQ_POLL]), ofp_bridge->dataq, LAGOPUS_QMUXER_POLL_READABLE)) != LAGOPUS_RESULT_OK) { /* create dataq poll */ lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); #ifdef OFPH_POLL_WRITING } else if ((ret = lagopus_qmuxer_poll_create( &(bridgeq->polls[EVENT_DATAQ_POLL]), ofp_bridge->event_dataq, LAGOPUS_QMUXER_POLL_WRITABLE)) != LAGOPUS_RESULT_OK) { /* create event_dataq poll */ lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); #endif /* OFPH_POLL_WRITING */ } else if ((ret = lagopus_qmuxer_poll_create( &(bridgeq->dp_polls[EVENT_DATAQ_DP_POLL]), ofp_bridge->event_dataq, LAGOPUS_QMUXER_POLL_READABLE)) != LAGOPUS_RESULT_OK) { /* create dataq poll for DataPlen */ lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); } else { /* succeeded all create. */ /* register. */ if ((ret = bridge_register(dpid, bridgeq)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); ofp_bridgeq_free(bridgeq, true); } else { /* update array. */ ret = bridgeq_mgr_map_to_array(); if (ret != LAGOPUS_RESULT_OK) { lagopus_perror(ret); (void) bridge_unregister(dpid, true); } } } } } else if (ret == LAGOPUS_RESULT_OK) { ret = LAGOPUS_RESULT_ALREADY_EXISTS; } } else { ret = LAGOPUS_RESULT_INVALID_OBJECT; lagopus_msg_warning("bridgeq_table is NULL.\n"); } return ret; }
STATIC lagopus_result_t flow_cmd_parse(datastore_interp_t *iptr, datastore_interp_state_t state, size_t argc, const char *const argv[], lagopus_hashmap_t *hptr, datastore_update_proc_t u_proc, datastore_enable_proc_t e_proc, datastore_serialize_proc_t s_proc, datastore_destroy_proc_t d_proc, lagopus_dstring_t *result) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; lagopus_result_t ret_for_json = LAGOPUS_RESULT_ANY_FAILURES; size_t i; void *sub_cmd_proc; char *name = NULL; char *fullname = NULL; char *str = NULL; flow_conf_t conf = {NULL, OFPTT_ALL}; configs_t out_configs = {false, false}; lagopus_dstring_t conf_result = NULL; (void) u_proc; (void) e_proc; (void) s_proc; (void) d_proc; for (i = 0; i < argc; i++) { lagopus_msg_debug(1, "argv[" PFSZS(4, u) "]:\t'%s'\n", i, argv[i]); } if (iptr != NULL && argv != NULL && result != NULL) { if ((ret = lagopus_dstring_create(&conf_result)) == LAGOPUS_RESULT_OK) { argv++; if (IS_VALID_STRING(*argv) == true) { if ((ret = lagopus_hashmap_find( &sub_cmd_not_name_table, (void *)(*argv), &sub_cmd_proc)) == LAGOPUS_RESULT_OK) { /* parse sub cmd. */ if (sub_cmd_proc != NULL) { ret_for_json = ((sub_cmd_proc_t) sub_cmd_proc)(iptr, state, argc, argv, NULL, hptr, u_proc, (void *) &out_configs, result); } } if (ret == LAGOPUS_RESULT_NOT_FOUND && ret_for_json != LAGOPUS_RESULT_OK) { if ((ret = lagopus_str_unescape(*argv, "\"'", &name)) < 0) { goto done; } else { argv++; if ((ret = namespace_get_fullname(name, &fullname)) == LAGOPUS_RESULT_OK) { if (IS_VALID_STRING(*argv) == true) { if ((ret = lagopus_hashmap_find( &sub_cmd_table, (void *)(*argv), &sub_cmd_proc)) == LAGOPUS_RESULT_OK) { /* parse sub cmd. */ if (sub_cmd_proc != NULL) { ret_for_json = ((sub_cmd_proc_t) sub_cmd_proc)(iptr, state, argc, argv, fullname, hptr, u_proc, (void *) &out_configs, result); } else { ret = LAGOPUS_RESULT_NOT_FOUND; lagopus_perror(ret); goto done; } } else if (ret == LAGOPUS_RESULT_NOT_FOUND) { /* parse dump cmd. */ ret_for_json = dump_sub_cmd_parse(iptr, argv, fullname, &conf, &out_configs, result); } else { ret_for_json = datastore_json_result_string_setf( result, LAGOPUS_RESULT_INVALID_ARGS, "sub_cmd = %s.", *argv); } } else { /* parse dump cmd. */ ret_for_json = dump_sub_cmd_parse(iptr, argv, fullname, &conf, &out_configs, result); } } else { ret_for_json = datastore_json_result_string_setf( result, ret, "Can't get fullname %s.", name); } } } } else { /* parse dump all cmd. */ ret_for_json = dump_sub_cmd_parse(iptr, argv, NULL, &conf, &out_configs, result); } /* create jsno for LAGOPUS_RESULT_OK. */ if (ret_for_json == LAGOPUS_RESULT_OK && out_configs.is_dump == false) { ret = lagopus_dstring_str_get(result, &str); if (ret != LAGOPUS_RESULT_OK) { goto done; } if (IS_VALID_STRING(str) == true) { ret = datastore_json_result_set(result, LAGOPUS_RESULT_OK, str); } else { ret = datastore_json_result_set(result, LAGOPUS_RESULT_OK, NULL); } } else { ret = ret_for_json; } } done: /* free. */ free(name); free(fullname); free(str); lagopus_dstring_destroy(&conf_result); } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static inline lagopus_result_t dump_sub_cmd_parse(datastore_interp_t *iptr, const char *const argv[], char *name, flow_conf_t *conf, configs_t *configs, lagopus_dstring_t *result) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; char *str = NULL; void *opt_proc; if (argv != NULL && conf != NULL && configs != NULL && result != NULL) { configs->is_dump = true; if (name == NULL) { ret = LAGOPUS_RESULT_OK; } else { if (bridge_exists(name) == true) { conf->name = name; if (*argv != NULL) { while (*argv != NULL) { if (IS_VALID_STRING(*(argv)) == true) { if ((ret = lagopus_hashmap_find(&dump_opt_table, (void *)(*argv), &opt_proc)) == LAGOPUS_RESULT_OK) { /* parse opt. */ if (opt_proc != NULL) { ret = ((opt_proc_t) opt_proc)(&argv, (void *) conf, (void *) configs, result); if (ret != LAGOPUS_RESULT_OK) { goto done; } } else { ret = LAGOPUS_RESULT_NOT_FOUND; lagopus_perror(ret); goto done; } } else { ret = datastore_json_result_string_setf(result, LAGOPUS_RESULT_INVALID_ARGS, "opt = %s.", *argv); goto done; } } else { ret = datastore_json_result_set(result, LAGOPUS_RESULT_INVALID_ARGS, NULL); goto done; } argv++; } } else { ret = LAGOPUS_RESULT_OK; } } else { ret = datastore_json_result_string_setf(result, LAGOPUS_RESULT_NOT_FOUND, "name = %s", name); } } if (ret == LAGOPUS_RESULT_OK) { /* dump flow. */ if ((ret = flow_cmd_dump_thread_start(conf, configs, iptr, result)) != LAGOPUS_RESULT_OK) { ret = datastore_json_result_string_setf( result,ret, "Can't start flow dump thread."); } } } else { ret = datastore_json_result_set(result, LAGOPUS_RESULT_INVALID_ARGS, NULL); } done: free(str); return ret; }
static lagopus_result_t config_sub_cmd_parse(datastore_interp_t *iptr, datastore_interp_state_t state, size_t argc, const char *const argv[], char *name, lagopus_hashmap_t *hptr, datastore_update_proc_t proc, void *out_configs, lagopus_dstring_t *result) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; configs_t *configs = NULL; void *opt_proc; (void) state; (void) argc; (void) name; (void) hptr; (void) proc; if (iptr != NULL && argv != NULL && out_configs != NULL && result != NULL) { configs = (configs_t *) out_configs; if (*(argv + 1) != NULL) { argv++; while (*argv != NULL) { if (IS_VALID_STRING(*(argv)) == true) { if ((ret = lagopus_hashmap_find(&config_opt_table, (void *)(*argv), &opt_proc)) == LAGOPUS_RESULT_OK) { /* parse opt. */ if (opt_proc != NULL) { ret = ((opt_proc_t) opt_proc)(&argv, (void *) NULL, (void *) configs, result); if (ret != LAGOPUS_RESULT_OK) { goto done; } } else { ret = LAGOPUS_RESULT_NOT_FOUND; lagopus_perror(ret); goto done; } } else if (ret == LAGOPUS_RESULT_NOT_FOUND) { goto done; } else { ret = datastore_json_result_string_setf(result, LAGOPUS_RESULT_INVALID_ARGS, "opt = %s.", *argv); goto done; } } else { ret = datastore_json_result_set(result, LAGOPUS_RESULT_INVALID_ARGS, NULL); goto done; } argv++; } } else { ret = tmp_dir_opt_parse(&argv, (void *) NULL, (void *) configs, result); } } else { ret = datastore_json_result_set(result, LAGOPUS_RESULT_INVALID_ARGS, NULL); } done: return ret; }