13 #include <linux/netfilter/nf_tables.h>
16 #include <libmnl/libmnl.h>
17 #include <libnftnl/object.h>
21 static int nftnl_obj_ct_helper_set(
struct nftnl_obj *e, uint16_t type,
22 const void *data, uint32_t data_len)
24 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
27 case NFTNL_OBJ_CT_HELPER_NAME:
28 snprintf(helper->name,
sizeof(helper->name),
"%s", (
const char *)data);
30 case NFTNL_OBJ_CT_HELPER_L3PROTO:
31 memcpy(&helper->l3proto, data, data_len);
33 case NFTNL_OBJ_CT_HELPER_L4PROTO:
34 memcpy(&helper->l4proto, data, data_len);
40 static const void *nftnl_obj_ct_helper_get(
const struct nftnl_obj *e,
41 uint16_t type, uint32_t *data_len)
43 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
46 case NFTNL_OBJ_CT_HELPER_NAME:
47 *data_len = strlen(helper->name);
49 case NFTNL_OBJ_CT_HELPER_L3PROTO:
50 *data_len =
sizeof(helper->l3proto);
51 return &helper->l3proto;
52 case NFTNL_OBJ_CT_HELPER_L4PROTO:
53 *data_len =
sizeof(helper->l4proto);
54 return &helper->l4proto;
59 static int nftnl_obj_ct_helper_cb(
const struct nlattr *attr,
void *data)
61 const struct nftnl_obj_ct_helper *helper = NULL;
62 int type = mnl_attr_get_type(attr);
63 const struct nlattr **tb = data;
65 if (mnl_attr_type_valid(attr, NFTA_CT_HELPER_MAX) < 0)
69 case NFTA_CT_HELPER_NAME:
70 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
72 if (mnl_attr_get_payload_len(attr) >=
sizeof(helper->name))
75 case NFTA_CT_HELPER_L3PROTO:
76 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
79 case NFTA_CT_HELPER_L4PROTO:
80 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
90 nftnl_obj_ct_helper_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
92 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
94 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_NAME))
95 mnl_attr_put_str(nlh, NFTA_CT_HELPER_NAME, helper->name);
96 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L3PROTO))
97 mnl_attr_put_u16(nlh, NFTA_CT_HELPER_L3PROTO, htons(helper->l3proto));
98 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L4PROTO))
99 mnl_attr_put_u8(nlh, NFTA_CT_HELPER_L4PROTO, helper->l4proto);
103 nftnl_obj_ct_helper_parse(
struct nftnl_obj *e,
struct nlattr *attr)
105 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
106 struct nlattr *tb[NFTA_CT_HELPER_MAX + 1] = {};
108 if (mnl_attr_parse_nested(attr, nftnl_obj_ct_helper_cb, tb) < 0)
111 if (tb[NFTA_CT_HELPER_NAME]) {
112 snprintf(helper->name,
sizeof(helper->name),
"%s",
113 mnl_attr_get_str(tb[NFTA_CT_HELPER_NAME]));
114 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_NAME);
116 if (tb[NFTA_CT_HELPER_L3PROTO]) {
117 helper->l3proto = ntohs(mnl_attr_get_u16(tb[NFTA_CT_HELPER_L3PROTO]));
118 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L3PROTO);
120 if (tb[NFTA_CT_HELPER_L4PROTO]) {
121 helper->l4proto = mnl_attr_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
122 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L4PROTO);
128 static int nftnl_obj_ct_helper_snprintf(
char *buf,
size_t len,
130 const struct nftnl_obj *e)
132 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
134 return snprintf(buf, len,
"name %s family %d protocol %d ",
135 helper->name, helper->l3proto, helper->l4proto);
139 #define NF_CT_HELPER_NAME_LEN 16
141 static struct attr_policy
142 obj_ct_helper_attr_policy[__NFTNL_OBJ_CT_HELPER_MAX] = {
143 [NFTNL_OBJ_CT_HELPER_NAME] = { .maxlen = NF_CT_HELPER_NAME_LEN },
144 [NFTNL_OBJ_CT_HELPER_L3PROTO] = { .maxlen =
sizeof(uint16_t) },
145 [NFTNL_OBJ_CT_HELPER_L4PROTO] = { .maxlen =
sizeof(uint8_t) },
148 struct obj_ops obj_ops_ct_helper = {
150 .type = NFT_OBJECT_CT_HELPER,
151 .alloc_len =
sizeof(
struct nftnl_obj_ct_helper),
152 .nftnl_max_attr = __NFTNL_OBJ_CT_HELPER_MAX - 1,
153 .attr_policy = obj_ct_helper_attr_policy,
154 .set = nftnl_obj_ct_helper_set,
155 .get = nftnl_obj_ct_helper_get,
156 .parse = nftnl_obj_ct_helper_parse,
157 .build = nftnl_obj_ct_helper_build,
158 .output = nftnl_obj_ct_helper_snprintf,