用户态用Generic Netlink传递NLA_NESTED数据至内核报错求助
解决Generic Netlink传递NLA_NESTED数据时的参数错误问题
以下是针对你遇到的Invalid input data or parameter错误的具体排查和修复方案:
1. 修正请求消息的flags参数
genlmsg_put的第6个参数(flags)需要指定NLM_F_REQUEST | NLM_F_ACK,这是用户态向内核发送请求并要求确认的标准标识,缺少会导致内核无法正确识别请求类型,触发参数校验失败。
2. 确保内核端属性策略正确配置
内核注册Generic Netlink家族时,必须为嵌套属性配置匹配的策略,否则会直接返回参数错误。示例内核端配置:
static const struct nla_policy smc_genl_policy[] = { [M_NLA_LOOP_TIMEO_VAL] = { .type = NLA_NESTED }, [SMC_NLA_LOOP_TIMEO_VAL_TX_WAIT] = { .type = NLA_U32 }, };
同时在处理回调中要正确解析嵌套属性:
struct nlattr *nest_attr = nla_find(msg, M_NLA_LOOP_TIMEO_VAL); if (nest_attr) { struct nlattr *sub_attrs[SMC_NLA_LOOP_TIMEO_VAL_MAX + 1]; nla_parse(sub_attrs, SMC_NLA_LOOP_TIMEO_VAL_MAX, nla_data(nest_attr), nla_len(nest_attr), smc_genl_policy); // 处理SMC_NLA_LOOP_TIMEO_VAL_TX_WAIT属性 }
3. 修复错误路径的嵌套属性清理
当nla_put_u32失败时,必须先调用nla_nest_cancel取消未完成的嵌套,再清理消息头部,否则消息会处于非法状态,发送后触发内核校验错误。
修正后的完整代码片段
void *msg_h = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, m_id, 0, NLM_F_REQUEST | NLM_F_ACK, SMC_NETLINK_UPD_LOOP_TIMEO, M_GENL_FAMILY_VERSION); if (!msg_h) { return -1; } struct nlattr *attrs_time = nla_nest_start(msg, M_NLA_LOOP_TIMEO_VAL); if (!attrs_time) { genlmsg_cancel(msg, msg_h); return -1; } if (nla_put_u32(msg, SMC_NLA_LOOP_TIMEO_VAL_TX_WAIT, info->tx_wait_timeo) < 0) { nla_nest_cancel(msg, attrs_time); genlmsg_cancel(msg, msg_h); return -1; } nla_nest_end(msg, attrs_time); rc = nl_send_auto(sk, msg); if (rc < 0) { return -1; } rc = nl_recvmsgs_default(sk); if (rc < 0) { return -1; } return 0;
内容的提问来源于stack exchange,提问作者zyy
相关产品推荐
相关产品推荐

