static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK_EXP, cmd, flags, nfnl_exp_get_family(exp), 0); if (msg == NULL) return -NLE_NOMEM; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_TUPLE)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASTER)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0) goto err_out; if (nfnl_exp_test_src(exp, NFNL_EXP_TUPLE_NAT)) { if ((err = nfnl_exp_build_nat(msg, exp)) < 0) goto err_out; } if (nfnl_exp_test_class(exp)) NLA_PUT_U32(msg, CTA_EXPECT_CLASS, htonl(nfnl_exp_get_class(exp))); if (nfnl_exp_test_fn(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_FN, nfnl_exp_get_fn(exp)); if (nfnl_exp_test_id(exp)) NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp))); if (nfnl_exp_test_timeout(exp)) NLA_PUT_U32(msg, CTA_EXPECT_TIMEOUT, htonl(nfnl_exp_get_timeout(exp))); if (nfnl_exp_test_helper_name(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp)); if (nfnl_exp_test_zone(exp)) NLA_PUT_U16(msg, CTA_EXPECT_ZONE, htons(nfnl_exp_get_zone(exp))); if (nfnl_exp_test_flags(exp)) NLA_PUT_U32(msg, CTA_EXPECT_FLAGS, htonl(nfnl_exp_get_flags(exp))); *result = msg; return 0; nla_put_failure: err_out: nlmsg_free(msg); return err; }
static void exp_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_exp *exp = (struct nfnl_exp *) a; char buf[64]; int fp = 0; exp_dump_line(a, p); nl_dump(p, " id 0x%x ", exp->exp_id); nl_dump_line(p, "family %s ", nl_af2str(exp->exp_family, buf, sizeof(buf))); if (nfnl_exp_test_timeout(exp)) { uint64_t timeout_ms = nfnl_exp_get_timeout(exp) * 1000UL; nl_dump(p, "timeout %s ", nl_msec2str(timeout_ms, buf, sizeof(buf))); } if (nfnl_exp_test_helper_name(exp)) nl_dump(p, "helper %s ", exp->exp_helper_name); if (nfnl_exp_test_fn(exp)) nl_dump(p, "fn %s ", exp->exp_fn); if (nfnl_exp_test_class(exp)) nl_dump(p, "class %u ", nfnl_exp_get_class(exp)); if (nfnl_exp_test_zone(exp)) nl_dump(p, "zone %u ", nfnl_exp_get_zone(exp)); if (nfnl_exp_test_flags(exp)) nl_dump(p, "<"); #define PRINT_FLAG(str) \ { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); } if (exp->exp_flags & NF_CT_EXPECT_PERMANENT) PRINT_FLAG("PERMANENT"); if (exp->exp_flags & NF_CT_EXPECT_INACTIVE) PRINT_FLAG("INACTIVE"); if (exp->exp_flags & NF_CT_EXPECT_USERSPACE) PRINT_FLAG("USERSPACE"); #undef PRINT_FLAG if (nfnl_exp_test_flags(exp)) nl_dump(p, ">"); nl_dump(p, "\n"); }