MT#55283 track human readable messages

Change-Id: I53380194d66591ada7bf48bca3cae5a933eabc79
pull/2043/head
Richard Fuchs 3 weeks ago
parent ff2f73314b
commit 5dcc70c240

@ -167,10 +167,10 @@ static const char *iterate_rules(nfapi_socket *nl, int family, const char *chain
{
g_autoptr(nfapi_buf) b = nfapi_buf_new();
nfapi_add_msg(b, NFT_MSG_GETRULE, family, NLM_F_REQUEST | NLM_F_DUMP);
nfapi_add_msg(b, NFT_MSG_GETRULE, family, NLM_F_REQUEST | NLM_F_DUMP, "get all rules [%d]", family);
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter");
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain);
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter", "table 'filter'");
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain, "chain '%s'", chain);
if (!nfapi_send_buf(nl, b))
return "failed to write to netlink socket for iteration";
@ -190,7 +190,7 @@ static const char *iterate_rules(nfapi_socket *nl, int family, const char *chain
static bool set_rule_handle(nfapi_buf *b, void *data) {
uint64_t *handle = data;
nfapi_add_u64_attr(b, NFTA_RULE_HANDLE, *handle);
nfapi_add_u64_attr(b, NFTA_RULE_HANDLE, *handle, "handle %" PRIu64, *handle);
return true;
}
@ -203,9 +203,9 @@ static const char *delete_rules(nfapi_socket *nl, int family, const char *chain,
nfapi_batch_begin(b);
nfapi_add_msg(b, NFT_MSG_DELRULE, family, NLM_F_REQUEST | NLM_F_ACK);
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter");
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain);
nfapi_add_msg(b, NFT_MSG_DELRULE, family, NLM_F_REQUEST | NLM_F_ACK, "delete rule(s) [%d]", family);
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter", "table 'filter'");
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain, "chain '%s'", chain);
if (callback) {
if (!callback(b, data))
@ -244,12 +244,12 @@ static const char *iterate_delete_rules(nfapi_socket *nl, int family, const char
static const char *local_input_chain(nfapi_buf *b) {
nfapi_nested_begin(b, NFTA_CHAIN_HOOK);
nfapi_add_u32_attr(b, NFTA_HOOK_HOOKNUM, htonl(NF_INET_LOCAL_IN));
nfapi_add_u32_attr(b, NFTA_HOOK_PRIORITY, htonl(0));
nfapi_nested_begin(b, NFTA_CHAIN_HOOK, "hook");
nfapi_add_u32_attr(b, NFTA_HOOK_HOOKNUM, htonl(NF_INET_LOCAL_IN), "hook local-in");
nfapi_add_u32_attr(b, NFTA_HOOK_PRIORITY, htonl(0), "prio 0");
nfapi_nested_end(b);
nfapi_add_u32_attr(b, NFTA_CHAIN_POLICY, htonl(NF_ACCEPT));
nfapi_add_u32_attr(b, NFTA_CHAIN_POLICY, htonl(NF_ACCEPT), "policy accept");
return NULL;
}
@ -265,9 +265,9 @@ static const char *nftables_do_chain(const int8_t *b, size_t l, void *userdata)
static const char *chain_exists(nfapi_socket *nl, int family, const char *chain) {
g_autoptr(nfapi_buf) b = nfapi_buf_new();
nfapi_add_msg(b, NFT_MSG_GETCHAIN, family, NLM_F_REQUEST | NLM_F_ACK);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain);
nfapi_add_msg(b, NFT_MSG_GETCHAIN, family, NLM_F_REQUEST | NLM_F_ACK, "get chain [%d]", family);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter", "table 'filter'");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain, "chain '%s'", chain);
if (!nfapi_send_buf(nl, b))
return "failed to write to netlink socket for chain exists";
@ -291,9 +291,10 @@ static const char *add_chain(nfapi_socket *nl, int family, const char *chain,
nfapi_batch_begin(b);
nfapi_add_msg(b, NFT_MSG_NEWCHAIN, family, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain);
nfapi_add_msg(b, NFT_MSG_NEWCHAIN, family, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK,
"create chain [%d]", family);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter", "table 'filter'");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain, "chain '%s'", chain);
if (callback) {
const char *err = callback(b);
@ -322,8 +323,9 @@ static const char *add_rule(nfapi_socket *nl, int family,
nfapi_batch_begin(b);
nfapi_add_msg(b, NFT_MSG_NEWRULE, family,
NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK | (callbacks.append ? NLM_F_APPEND : 0));
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter");
NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK | (callbacks.append ? NLM_F_APPEND : 0),
"%s new rule [%d]", callbacks.append ? "append" : "insert", family);
nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter", "table 'filter'");
const char *err = callbacks.rule_callback(b, family, &callbacks);
if (err)
@ -345,11 +347,11 @@ static const char *add_rule(nfapi_socket *nl, int family,
static void counter(nfapi_buf *b) {
// buffer is in the nested expressions
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "counter");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "counter", "counter");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_nested_end(b);
@ -362,55 +364,59 @@ static const char *udp_filter(nfapi_buf *b, int family) {
static const uint8_t proto = IPPROTO_UDP;
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
if (family == NFPROTO_INET) {
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "meta");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "meta", "meta");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, NFTA_META_KEY, htonl(NFT_META_L4PROTO));
nfapi_add_u32_attr(b, NFTA_META_DREG, htonl(NFT_REG_1));
nfapi_add_u32_attr(b, NFTA_META_KEY, htonl(NFT_META_L4PROTO), "l4proto");
nfapi_add_u32_attr(b, NFTA_META_DREG, htonl(NFT_REG_1), "reg 1");
nfapi_nested_end(b);
}
else {
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "payload");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "payload", "meta");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, NFTA_PAYLOAD_DREG, htonl(NFT_REG_1));
nfapi_add_u32_attr(b, NFTA_PAYLOAD_BASE, htonl(NFT_PAYLOAD_NETWORK_HEADER));
nfapi_add_u32_attr(b, NFTA_PAYLOAD_DREG, htonl(NFT_REG_1), "reg 1");
nfapi_add_u32_attr(b, NFTA_PAYLOAD_BASE, htonl(NFT_PAYLOAD_NETWORK_HEADER),
"network header");
if (family == NFPROTO_IPV4)
nfapi_add_u32_attr(b, NFTA_PAYLOAD_OFFSET,
htonl(offsetof(struct iphdr, protocol)));
htonl(offsetof(struct iphdr, protocol)),
"offset %zu", offsetof(struct iphdr, protocol));
else if (family == NFPROTO_IPV6)
nfapi_add_u32_attr(b, NFTA_PAYLOAD_OFFSET,
htonl(offsetof(struct ip6_hdr, ip6_nxt)));
htonl(offsetof(struct ip6_hdr, ip6_nxt)),
"offset %zu", offsetof(struct ip6_hdr, ip6_nxt));
else
return "unsupported address family for UDP filter";
nfapi_add_u32_attr(b, NFTA_PAYLOAD_LEN, htonl(sizeof(proto)));
nfapi_add_u32_attr(b, NFTA_PAYLOAD_LEN, htonl(sizeof(proto)),
"len %zu", sizeof(proto));
nfapi_nested_end(b);
}
nfapi_nested_end(b);
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "cmp");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "cmp", "cmp");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, NFTA_CMP_SREG, htonl(NFT_REG_1));
nfapi_add_u32_attr(b, NFTA_CMP_OP, htonl(NFT_CMP_EQ));
nfapi_add_u32_attr(b, NFTA_CMP_SREG, htonl(NFT_REG_1), "reg 1");
nfapi_add_u32_attr(b, NFTA_CMP_OP, htonl(NFT_CMP_EQ), "eq");
nfapi_nested_begin(b, NFTA_CMP_DATA);
nfapi_nested_begin(b, NFTA_CMP_DATA, "data");
nfapi_add_attr(b, NFTA_DATA_VALUE, &proto, sizeof(proto));
nfapi_add_attr(b, NFTA_DATA_VALUE, &proto, sizeof(proto), "%u", proto);
nfapi_nested_end(b);
@ -425,28 +431,29 @@ static const char *udp_filter(nfapi_buf *b, int family) {
static const char *input_immediate(nfapi_buf *b, int family, struct add_rule_callbacks *callbacks) {
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->base_chain);
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->base_chain, "chain '%s'", callbacks->base_chain);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS, "expr");
const char *err = udp_filter(b, family);
if (err)
return err;
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "immediate");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "immediate", "immediate");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, NFTA_IMMEDIATE_DREG, 0);
nfapi_add_u32_attr(b, NFTA_IMMEDIATE_DREG, 0, "reg 0");
nfapi_nested_begin(b, NFTA_IMMEDIATE_DATA);
nfapi_nested_begin(b, NFTA_IMMEDIATE_DATA, "data");
nfapi_nested_begin(b, NFTA_DATA_VERDICT);
nfapi_nested_begin(b, NFTA_DATA_VERDICT, "verdict");
nfapi_add_u32_attr(b, NFTA_VERDICT_CODE, htonl(NFT_JUMP));
nfapi_add_str_attr(b, NFTA_VERDICT_CHAIN, callbacks->chain);
nfapi_add_u32_attr(b, NFTA_VERDICT_CODE, htonl(NFT_JUMP), "jump");
nfapi_add_str_attr(b, NFTA_VERDICT_CHAIN, callbacks->chain,
"chain '%s'", callbacks->chain);
nfapi_nested_end(b);
@ -465,13 +472,14 @@ static const char *input_immediate(nfapi_buf *b, int family, struct add_rule_cal
static const char *target_base_nft_expr(nfapi_buf *b, struct add_rule_callbacks *callbacks) {
// buffer is in the nested expressions
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "rtpengine");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "rtpengine", "rtpengine");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, RTPEA_RTPENGINE_TABLE, callbacks->table);
nfapi_add_u32_attr(b, RTPEA_RTPENGINE_TABLE, callbacks->table,
"table %u", callbacks->table);
nfapi_nested_end(b);
@ -486,15 +494,16 @@ static const char *target_base_xt(nfapi_buf *b, struct add_rule_callbacks *callb
struct xt_rtpengine_info info = { .id = callbacks->table };
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "target");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "target", "target");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_str_attr(b, NFTA_TARGET_NAME, "RTPENGINE");
nfapi_add_u32_attr(b, NFTA_TARGET_REV, htonl(0));
nfapi_add_attr(b, NFTA_TARGET_INFO, &info, sizeof(info));
nfapi_add_str_attr(b, NFTA_TARGET_NAME, "RTPENGINE", "RTPENGINE");
nfapi_add_u32_attr(b, NFTA_TARGET_REV, htonl(0), "rev 0");
nfapi_add_attr(b, NFTA_TARGET_INFO, &info, sizeof(info),
"info table %u", callbacks->table);
nfapi_nested_end(b);
@ -505,24 +514,25 @@ static const char *target_base_xt(nfapi_buf *b, struct add_rule_callbacks *callb
static const char *comment(nfapi_buf *b, int family, struct add_rule_callbacks *callbacks) {
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain);
nfapi_add_binary_str_attr(b, NFTA_RULE_USERDATA, HANDLER_COMMENT);
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain, "chain '%s'", callbacks->chain);
nfapi_add_binary_str_attr(b, NFTA_RULE_USERDATA, HANDLER_COMMENT, "comment '%s'", HANDLER_COMMENT);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS, "expr");
nfapi_nested_begin(b, NFTA_LIST_ELEM);
nfapi_nested_begin(b, NFTA_LIST_ELEM, "element");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "immediate");
nfapi_add_str_attr(b, NFTA_EXPR_NAME, "immediate", "immediate");
nfapi_nested_begin(b, NFTA_EXPR_DATA);
nfapi_nested_begin(b, NFTA_EXPR_DATA, "data");
nfapi_add_u32_attr(b, NFTA_IMMEDIATE_DREG, 0);
nfapi_add_u32_attr(b, NFTA_IMMEDIATE_DREG, 0, "reg 0");
nfapi_nested_begin(b, NFTA_IMMEDIATE_DATA);
nfapi_nested_begin(b, NFTA_IMMEDIATE_DATA, "data");
nfapi_nested_begin(b, NFTA_DATA_VERDICT);
nfapi_nested_begin(b, NFTA_DATA_VERDICT, "verdict");
nfapi_add_u32_attr(b, NFTA_VERDICT_CODE, htonl(NFT_CONTINUE));
nfapi_add_u32_attr(b, NFTA_VERDICT_CODE, htonl(NFT_CONTINUE),
"continue");
nfapi_nested_end(b);
@ -547,9 +557,9 @@ static const char *rtpe_target_base(nfapi_buf *b, struct add_rule_callbacks *cal
static const char *rtpe_target(nfapi_buf *b, int family, struct add_rule_callbacks *callbacks) {
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain);
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain, "chain '%s'", callbacks->chain);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS, "expr");
const char *err = rtpe_target_base(b, callbacks);
if (err)
@ -564,9 +574,9 @@ static const char *rtpe_target(nfapi_buf *b, int family, struct add_rule_callbac
static const char *rtpe_target_filter(nfapi_buf *b, int family, struct add_rule_callbacks *callbacks) {
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain);
nfapi_add_str_attr(b, NFTA_RULE_CHAIN, callbacks->chain, "chain '%s'", callbacks->chain);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS);
nfapi_nested_begin(b, NFTA_RULE_EXPRESSIONS, "expr");
const char *err = rtpe_target_base(b, callbacks);
if (err)
@ -587,10 +597,10 @@ static const char *delete_chain(nfapi_socket *nl, int family, const char *chain)
nfapi_batch_begin(b);
nfapi_add_msg(b, NFT_MSG_DELCHAIN, family, NLM_F_REQUEST | NLM_F_ACK);
nfapi_add_msg(b, NFT_MSG_DELCHAIN, family, NLM_F_REQUEST | NLM_F_ACK, "delete chain [%d]", family);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain);
nfapi_add_str_attr(b, NFTA_CHAIN_TABLE, "filter", "table 'filter'");
nfapi_add_str_attr(b, NFTA_CHAIN_NAME, chain, "chain '%s'", chain);
nfapi_batch_end(b);
@ -672,8 +682,9 @@ static const char *add_table(nfapi_socket *nl, int family) {
nfapi_batch_begin(b);
nfapi_add_msg(b, NFT_MSG_NEWTABLE, family, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK);
nfapi_add_str_attr(b, NFTA_TABLE_NAME, "filter");
nfapi_add_msg(b, NFT_MSG_NEWTABLE, family, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK,
"create table [%d]", family);
nfapi_add_str_attr(b, NFTA_TABLE_NAME, "filter", "table 'filter'");
nfapi_batch_end(b);

@ -24,6 +24,7 @@ struct nfapi_buf {
GString *s; // buffer
ssize_t last_hdr;
GQueue nested;
GString *readable;
};
@ -67,15 +68,29 @@ nfapi_buf *nfapi_buf_new(void) {
nfapi_buf *b = g_new0(__typeof(*b), 1);
b->s = g_string_new("");
b->last_hdr = -1;
b->readable = g_string_new("");
return b;
}
void nfapi_buf_free(nfapi_buf *b) {
g_string_free(b->s, TRUE);
g_string_free(b->readable, TRUE);
g_free(b);
}
static void readable_vadd(GString *r, const char *fmt, va_list va) {
if (r->len > 0)
g_string_append_c(r, ' ');
g_string_append_vprintf(r, fmt, va);
}
static void readable_add(GString *r, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
readable_vadd(r, fmt, va);
va_end(va);
}
static void *buf_add_store(GString *b, size_t s, ssize_t *store) {
size_t cur = b->len;
g_string_set_size(b, cur + s);
@ -122,7 +137,12 @@ static void add_msg(nfapi_buf *b, uint16_t type, uint16_t family, uint16_t flags
};
}
void nfapi_add_msg(nfapi_buf *b, uint16_t type, uint16_t family, uint16_t flags) {
void nfapi_add_msg(nfapi_buf *b, uint16_t type, uint16_t family, uint16_t flags, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
readable_vadd(b->readable, fmt, va);
va_end(va);
return add_msg(b, (NFNL_SUBSYS_NFTABLES << 8) | type, family, flags, 0, 0);
}
@ -135,7 +155,12 @@ void nfapi_batch_end(nfapi_buf *b) {
void nfapi_add_attr(nfapi_buf *b, uint16_t type, const void *data, size_t len) {
void nfapi_add_attr(nfapi_buf *b, uint16_t type, const void *data, size_t len, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
readable_vadd(b->readable, fmt, va);
va_end(va);
struct nlattr *attr = item_add(b, sizeof(*attr));
*attr = (__typeof(*attr)) {
.nla_type = type,
@ -147,12 +172,13 @@ void nfapi_add_attr(nfapi_buf *b, uint16_t type, const void *data, size_t len) {
}
void nfapi_nested_begin(nfapi_buf *b, uint16_t type) {
void nfapi_nested_begin(nfapi_buf *b, uint16_t type, const char *name) {
g_queue_push_tail(&b->nested, (void *) b->s->len);
nfapi_add_attr(b, type | NLA_F_NESTED, NULL, 0);
nfapi_add_attr(b, type | NLA_F_NESTED, NULL, 0, "%s: [", name);
}
void nfapi_nested_end(nfapi_buf *b) {
readable_add(b->readable, "]");
assert(b->nested.length != 0);
g_queue_pop_tail(&b->nested);
}

@ -25,32 +25,36 @@ void nfapi_socket_close(nfapi_socket *);
nfapi_buf *nfapi_buf_new(void);
void nfapi_buf_free(nfapi_buf *);
void nfapi_add_msg(nfapi_buf *, uint16_t type, uint16_t family, uint16_t flags);
__attribute__ ((format(printf, 5, 6)))
void nfapi_add_msg(nfapi_buf *, uint16_t type, uint16_t family, uint16_t flags, const char *fmt, ...);
void nfapi_add_attr(nfapi_buf *b, uint16_t type, const void *data, size_t len);
__attribute__ ((format(printf, 5, 6)))
void nfapi_add_attr(nfapi_buf *b, uint16_t type, const void *data, size_t len, const char *fmt, ...);
static inline void nfapi_add_str_attr(nfapi_buf *b, uint16_t type, const char *s) {
nfapi_add_attr(b, type, s, strlen(s) + 1);
}
static inline void nfapi_add_u32_attr(nfapi_buf *b, uint16_t type, uint32_t u) {
nfapi_add_attr(b, type, &u, sizeof(u));
}
static inline void nfapi_add_u64_attr(nfapi_buf *b, uint16_t type, uint64_t u) {
nfapi_add_attr(b, type, &u, sizeof(u));
}
#define nfapi_add_str_attr(b, t, s, f, ...) \
nfapi_add_attr(b, t, s, strlen(s) + 1, f, ##__VA_ARGS__)
#define nfapi_add_u32_attr(b, t, u, f, ...) do { \
uint32_t __u = (u); \
nfapi_add_attr(b, t, &__u, sizeof(__u), f, ##__VA_ARGS__); \
} while (0)
#define nfapi_add_u64_attr(b, t, u, f, ...) do { \
uint64_t __u = (u); \
nfapi_add_attr(b, t, &__u, sizeof(__u), f, ##__VA_ARGS__); \
} while (0)
#define nfapi_add_binary_str_attr(b, type, s) \
#define nfapi_add_binary_str_attr(b, type, s, fmt, ...) \
nfapi_add_attr(b, type, &(struct { \
uint16_t len; \
char buf[sizeof(s)]; \
}) { \
.len = htons(sizeof(s)), \
.buf = s, \
}, 2 + sizeof(s))
}, 2 + sizeof(s), \
fmt, ##__VA_ARGS__)
void nfapi_nested_begin(nfapi_buf *, uint16_t type);
void nfapi_nested_begin(nfapi_buf *, uint16_t type, const char *name);
void nfapi_nested_end(nfapi_buf *);
void nfapi_batch_begin(nfapi_buf *);

Loading…
Cancel
Save