xfree(obj->table);
if (obj->flags & (1 << NFTNL_OBJ_NAME))
xfree(obj->name);
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ xfree(obj->user.data);
xfree(obj);
}
case NFTNL_OBJ_HANDLE:
memcpy(&obj->handle, data, sizeof(obj->handle));
break;
+ case NFTNL_OBJ_USERDATA:
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ xfree(obj->user.data);
+
+ obj->user.data = malloc(data_len);
+ if (!obj->user.data)
+ return;
+ memcpy(obj->user.data, data, data_len);
+ obj->user.len = data_len;
+ break;
default:
if (obj->ops)
obj->ops->set(obj, attr, data, data_len);
case NFTNL_OBJ_HANDLE:
*data_len = sizeof(uint64_t);
return &obj->handle;
+ case NFTNL_OBJ_USERDATA:
+ *data_len = obj->user.len;
+ return obj->user.data;
default:
if (obj->ops)
return obj->ops->get(obj, attr, data_len);
mnl_attr_put_u32(nlh, NFTA_OBJ_TYPE, htonl(obj->ops->type));
if (obj->flags & (1 << NFTNL_OBJ_HANDLE))
mnl_attr_put_u64(nlh, NFTA_OBJ_HANDLE, htobe64(obj->handle));
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ mnl_attr_put(nlh, NFTA_OBJ_USERDATA, obj->user.len, obj->user.data);
if (obj->ops) {
struct nlattr *nest = mnl_attr_nest_start(nlh, NFTA_OBJ_DATA);
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+ case NFTA_OBJ_USERDATA:
+ if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+ abi_breakage();
+ break;
}
tb[type] = attr;
obj->handle = be64toh(mnl_attr_get_u64(tb[NFTA_OBJ_HANDLE]));
obj->flags |= (1 << NFTNL_OBJ_HANDLE);
}
+ if (tb[NFTA_OBJ_USERDATA]) {
+ nftnl_obj_set_data(obj, NFTNL_OBJ_USERDATA,
+ mnl_attr_get_payload(tb[NFTA_OBJ_USERDATA]),
+ mnl_attr_get_payload_len(tb[NFTA_OBJ_USERDATA]));
+ }
obj->family = nfg->nfgen_family;
obj->flags |= (1 << NFTNL_OBJ_FAMILY);