You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用libipset在C语言中创建IpSet失败:提示“Invalid create command: missing settype”,终端命令可行但库调用无效(版本7.24)

Fixing "Invalid create command: missing settype" in libipset IPSET_CMD_CREATE

Let's break down why your libipset code is failing with the "missing settype" error, even though the equivalent terminal command works. The core issue is incorrect data type handling for several libipset options, plus a small oversight with the set name.

Root Causes

  1. Wrong parameter types for numeric options: Libipset's ipset_session_data_set expects specific data types for options like IPSET_OPT_FAMILY, IPSET_OPT_MAXELEM, and IPSET_OPT_TIMEOUT—not string literals. Your terminal command accepts strings like "inet" or "65536" because the ipset CLI parses them, but the library API requires raw numeric values.
  2. Hardcoded set name: You're passing "test_ip_set" to IPSET_SETNAME instead of using the function's ip_set_name parameter, which would create a set with a name different from what you intended.
  3. Missing error checks for ipset_session_data_set: You're not verifying if each option was set successfully, which could hide subtle issues.
  4. Premature session cleanup: You called ipset_session_fini(session) before checking the result of ipset_cmd, which could invalidate the session before retrieving the error message.

Corrected Code

#include <sys/socket.h>  // For AF_INET
#include <stdint.h>      // For uint32_t

IPSetInfo * netlinkhandler_create_ip_set(char *ip_set_name){
    struct ipset_session *session;
    int ret;
    int af_inet = AF_INET;
    uint32_t maxelem = 65536;
    uint32_t timeout = 0;

    // Load ipset types (required before creating sessions)
    ipset_load_types();

    session = ipset_session_init(NULL,NULL);
    if (!session) {
        log_info("FATAL: ipset_session_init failed! Cannot proceed.\n");
        return NULL;
    }

    // Set set name (use function parameter instead of hardcoding)
    ret = ipset_session_data_set(session, IPSET_SETNAME, ip_set_name);
    if (ret != 0) {
        log_info("[ERROR] Failed to set setname: %s", ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    // Set set type (hash:ip,port)
    ret = ipset_session_data_set(session, IPSET_OPT_TYPENAME, "hash:ip,port");
    if (ret != 0) {
        log_info("[ERROR] Failed to set settype: %s", ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    // Set family (use AF_INET integer instead of string "inet")
    ret = ipset_session_data_set(session, IPSET_OPT_FAMILY, &af_inet);
    if (ret != 0) {
        log_info("[ERROR] Failed to set family: %s", ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    // Set maxelem (pass uint32_t value instead of string)
    ret = ipset_session_data_set(session, IPSET_OPT_MAXELEM, &maxelem);
    if (ret != 0) {
        log_info("[ERROR] Failed to set maxelem: %s", ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    // Set timeout (pass uint32_t value instead of string)
    ret = ipset_session_data_set(session, IPSET_OPT_TIMEOUT, &timeout);
    if (ret != 0) {
        log_info("[ERROR] Failed to set timeout: %s", ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    // Execute create command
    ret = ipset_cmd(session, IPSET_CMD_CREATE, 0);
    if(ret !=0){
        log_info("[ERROR][IPSET CREATION FAILED] [IPSET NAME: %s] %s",ip_set_name,ipset_session_report_msg(session));
        ipset_session_fini(session);
        return NULL;
    }

    log_info("[INFO][IPSET CREATION SUCCESSFUL] [IPSET NAME: %s]",ip_set_name);
    IPSetInfo *new_ip_set = (IPSetInfo *)malloc(sizeof(IPSetInfo));
    new_ip_set->ip_set_name=ip_set_name;
    new_ip_set->number_of_ips=0;
    pthread_mutex_init(&new_ip_set->lock, NULL);

    ipset_session_fini(session);
    return new_ip_set;
}

Key Changes Explained

  • Set name alignment: Replaced the hardcoded "test_ip_set" with the function's ip_set_name parameter to match your intended set name.
  • Numeric option fixes:
    • IPSET_OPT_FAMILY: Uses AF_INET (an integer from sys/socket.h) instead of the string "inet".
    • IPSET_OPT_MAXELEM and IPSET_OPT_TIMEOUT: Pass pointers to uint32_t variables holding the actual numeric values, not string literals.
  • Early error handling: Added checks for each ipset_session_data_set call to catch configuration issues early and clean up resources properly.
  • Delayed session cleanup: Moved ipset_session_fini(session) to after validating the ipset_cmd result, ensuring you can retrieve error messages from the session before it's destroyed.

Why This Fixes the "Missing Settype" Error

The original code passed invalid data types for non-string options, which corrupted the session's internal state. This made libipset unable to properly parse the set type you specified, leading to the misleading "missing settype" error. By passing the correct data types, you ensure the session is properly configured, and the set type is recognized correctly.

内容的提问来源于stack exchange,提问作者Vignesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 12:32:32