13 #include <arpa/inet.h>
17 #include <linux/netfilter/nf_tables.h>
20 #include <libmnl/libmnl.h>
21 #include <libnftnl/object.h>
25 static 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, data_len);
37 case NFTNL_OBJ_CT_HELPER_L4PROTO:
38 memcpy(&helper->l4proto, data, data_len);
44 static const void *nftnl_obj_ct_helper_get(
const struct nftnl_obj *e,
45 uint16_t type, uint32_t *data_len)
47 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
50 case NFTNL_OBJ_CT_HELPER_NAME:
51 *data_len = strlen(helper->name);
53 case NFTNL_OBJ_CT_HELPER_L3PROTO:
54 *data_len =
sizeof(helper->l3proto);
55 return &helper->l3proto;
56 case NFTNL_OBJ_CT_HELPER_L4PROTO:
57 *data_len =
sizeof(helper->l4proto);
58 return &helper->l4proto;
63 static int nftnl_obj_ct_helper_cb(
const struct nlattr *attr,
void *data)
65 const struct nftnl_obj_ct_helper *helper = NULL;
66 int type = mnl_attr_get_type(attr);
67 const struct nlattr **tb = data;
69 if (mnl_attr_type_valid(attr, NFTA_CT_HELPER_MAX) < 0)
73 case NFTA_CT_HELPER_NAME:
74 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
76 if (mnl_attr_get_payload_len(attr) >=
sizeof(helper->name))
79 case NFTA_CT_HELPER_L3PROTO:
80 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
83 case NFTA_CT_HELPER_L4PROTO:
84 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
94 nftnl_obj_ct_helper_build(
struct nlmsghdr *nlh,
const struct nftnl_obj *e)
96 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
98 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_NAME))
99 mnl_attr_put_str(nlh, NFTA_CT_HELPER_NAME, helper->name);
100 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L3PROTO))
101 mnl_attr_put_u16(nlh, NFTA_CT_HELPER_L3PROTO, htons(helper->l3proto));
102 if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L4PROTO))
103 mnl_attr_put_u8(nlh, NFTA_CT_HELPER_L4PROTO, helper->l4proto);
107 nftnl_obj_ct_helper_parse(
struct nftnl_obj *e,
struct nlattr *attr)
109 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
110 struct nlattr *tb[NFTA_CT_HELPER_MAX + 1] = {};
112 if (mnl_attr_parse_nested(attr, nftnl_obj_ct_helper_cb, tb) < 0)
115 if (tb[NFTA_CT_HELPER_NAME]) {
116 snprintf(helper->name,
sizeof(helper->name),
"%s",
117 mnl_attr_get_str(tb[NFTA_CT_HELPER_NAME]));
118 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_NAME);
120 if (tb[NFTA_CT_HELPER_L3PROTO]) {
121 helper->l3proto = ntohs(mnl_attr_get_u16(tb[NFTA_CT_HELPER_L3PROTO]));
122 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L3PROTO);
124 if (tb[NFTA_CT_HELPER_L4PROTO]) {
125 helper->l4proto = mnl_attr_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
126 e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L4PROTO);
132 static int nftnl_obj_ct_helper_snprintf(
char *buf,
size_t len,
134 const struct nftnl_obj *e)
136 struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
138 return snprintf(buf, len,
"name %s family %d protocol %d ",
139 helper->name, helper->l3proto, helper->l4proto);
143 #define NF_CT_HELPER_NAME_LEN 16
145 static struct attr_policy
146 obj_ct_helper_attr_policy[__NFTNL_OBJ_CT_HELPER_MAX] = {
147 [NFTNL_OBJ_CT_HELPER_NAME] = { .maxlen = NF_CT_HELPER_NAME_LEN },
148 [NFTNL_OBJ_CT_HELPER_L3PROTO] = { .maxlen =
sizeof(uint16_t) },
149 [NFTNL_OBJ_CT_HELPER_L4PROTO] = { .maxlen =
sizeof(uint8_t) },
152 struct obj_ops obj_ops_ct_helper = {
154 .type = NFT_OBJECT_CT_HELPER,
155 .alloc_len =
sizeof(
struct nftnl_obj_ct_helper),
156 .nftnl_max_attr = __NFTNL_OBJ_CT_HELPER_MAX - 1,
157 .attr_policy = obj_ct_helper_attr_policy,
158 .set = nftnl_obj_ct_helper_set,
159 .get = nftnl_obj_ct_helper_get,
160 .parse = nftnl_obj_ct_helper_parse,
161 .build = nftnl_obj_ct_helper_build,
162 .output = nftnl_obj_ct_helper_snprintf,