17#include <linux/netfilter/nf_tables.h>
20#include <libmnl/libmnl.h>
21#include <libnftnl/object.h>
25static int nftnl_obj_ct_helper_set(
struct nftnl_obj *e, uint16_t type,
26 const void *data, uint32_t data_len)
28 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
31 case NFTNL_OBJ_CT_HELPER_NAME:
32 snprintf(helper->name,
sizeof(helper->name),
"%s", (
const char *)data);
34 case NFTNL_OBJ_CT_HELPER_L3PROTO:
35 memcpy(&helper->l3proto, data,
sizeof(helper->l3proto));
37 case NFTNL_OBJ_CT_HELPER_L4PROTO:
38 memcpy(&helper->l4proto, data,
sizeof(helper->l4proto));
46static const void *nftnl_obj_ct_helper_get(
const struct nftnl_obj *e,
47 uint16_t type, uint32_t *data_len)
49 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
52 case NFTNL_OBJ_CT_HELPER_NAME:
53 *data_len = strlen(helper->name);
55 case NFTNL_OBJ_CT_HELPER_L3PROTO:
56 *data_len =
sizeof(helper->l3proto);
57 return &helper->l3proto;
58 case NFTNL_OBJ_CT_HELPER_L4PROTO:
59 *data_len =
sizeof(helper->l4proto);
60 return &helper->l4proto;
65static int nftnl_obj_ct_helper_cb(
const struct nlattr *attr,
void *data)
67 const struct nftnl_obj_ct_helper *helper = NULL;
68 int type = mnl_attr_get_type(attr);
69 const struct nlattr **tb = data;
71 if (mnl_attr_type_valid(attr, NFTA_CT_HELPER_MAX) < 0)
75 case NFTA_CT_HELPER_NAME:
76 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
78 if (mnl_attr_get_payload_len(attr) >=
sizeof(helper->name))
81 case NFTA_CT_HELPER_L3PROTO:
82 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
85 case NFTA_CT_HELPER_L4PROTO:
86 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
96nftnl_obj_ct_helper_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
98 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
100 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_NAME))
101 mnl_attr_put_str(nlh, NFTA_CT_HELPER_NAME, helper->name);
102 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L3PROTO))
103 mnl_attr_put_u16(nlh, NFTA_CT_HELPER_L3PROTO, htons(helper->l3proto));
104 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L4PROTO))
105 mnl_attr_put_u8(nlh, NFTA_CT_HELPER_L4PROTO, helper->l4proto);
109nftnl_obj_ct_helper_parse(
struct nftnl_obj *e,
struct nlattr *attr)
111 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
112 struct nlattr *tb[NFTA_CT_HELPER_MAX + 1] = {};
114 if (mnl_attr_parse_nested(attr, nftnl_obj_ct_helper_cb, tb) < 0)
117 if (tb[NFTA_CT_HELPER_NAME]) {
118 snprintf(helper->name,
sizeof(helper->name),
"%s",
119 mnl_attr_get_str(tb[NFTA_CT_HELPER_NAME]));
120 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_NAME);
122 if (tb[NFTA_CT_HELPER_L3PROTO]) {
123 helper->l3proto = ntohs(mnl_attr_get_u16(tb[NFTA_CT_HELPER_L3PROTO]));
124 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L3PROTO);
126 if (tb[NFTA_CT_HELPER_L4PROTO]) {
127 helper->l4proto = mnl_attr_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
128 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L4PROTO);
134static int nftnl_obj_ct_helper_snprintf(
char *buf,
size_t len,
136 const struct nftnl_obj *e)
138 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
140 return snprintf(buf, len,
"name %s family %d protocol %d ",
141 helper->name, helper->l3proto, helper->l4proto);
144struct obj_ops obj_ops_ct_helper = {
146 .type = NFT_OBJECT_CT_HELPER,
147 .alloc_len =
sizeof(
struct nftnl_obj_ct_helper),
148 .max_attr = NFTA_CT_HELPER_MAX,
149 .set = nftnl_obj_ct_helper_set,
150 .get = nftnl_obj_ct_helper_get,
151 .parse = nftnl_obj_ct_helper_parse,
152 .build = nftnl_obj_ct_helper_build,
153 .output = nftnl_obj_ct_helper_snprintf,