8#include <linux/netfilter/nf_tables.h>
12#include <libmnl/libmnl.h>
13#include <libnftnl/expr.h>
14#include <libnftnl/rule.h>
17 enum nft_registers dreg;
18 enum nft_xfrm_keys key;
24nftnl_expr_xfrm_set(
struct nftnl_expr *e, uint16_t type,
25 const void *data, uint32_t data_len)
30 case NFTNL_EXPR_XFRM_KEY:
31 memcpy(&x->key, data, data_len);
33 case NFTNL_EXPR_XFRM_DIR:
34 memcpy(&x->dir, data, data_len);
36 case NFTNL_EXPR_XFRM_SPNUM:
37 memcpy(&x->spnum, data, data_len);
39 case NFTNL_EXPR_XFRM_DREG:
40 memcpy(&x->dreg, data, data_len);
49nftnl_expr_xfrm_get(
const struct nftnl_expr *e, uint16_t type,
55 case NFTNL_EXPR_XFRM_KEY:
56 *data_len =
sizeof(x->key);
58 case NFTNL_EXPR_XFRM_DIR:
59 *data_len =
sizeof(x->dir);
61 case NFTNL_EXPR_XFRM_SPNUM:
62 *data_len =
sizeof(x->spnum);
64 case NFTNL_EXPR_XFRM_DREG:
65 *data_len =
sizeof(x->dreg);
71static int nftnl_expr_xfrm_cb(
const struct nlattr *attr,
void *data)
73 const struct nlattr **tb = data;
74 int type = mnl_attr_get_type(attr);
76 if (mnl_attr_type_valid(attr, NFTA_XFRM_MAX) < 0)
83 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
87 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
97nftnl_expr_xfrm_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
101 if (e->flags & (1 << NFTNL_EXPR_XFRM_KEY))
102 mnl_attr_put_u32(nlh, NFTA_XFRM_KEY, htonl(x->key));
103 if (e->flags & (1 << NFTNL_EXPR_XFRM_DIR))
104 mnl_attr_put_u8(nlh, NFTA_XFRM_DIR, x->dir);
105 if (e->flags & (1 << NFTNL_EXPR_XFRM_SPNUM))
106 mnl_attr_put_u32(nlh, NFTA_XFRM_SPNUM, htonl(x->spnum));
107 if (e->flags & (1 << NFTNL_EXPR_XFRM_DREG))
108 mnl_attr_put_u32(nlh, NFTA_XFRM_DREG, htonl(x->dreg));
112nftnl_expr_xfrm_parse(
struct nftnl_expr *e,
struct nlattr *attr)
115 struct nlattr *tb[NFTA_XFRM_MAX+1] = {};
117 if (mnl_attr_parse_nested(attr, nftnl_expr_xfrm_cb, tb) < 0)
120 if (tb[NFTA_XFRM_KEY]) {
121 x->key = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_KEY]));
122 e->flags |= (1 << NFTNL_EXPR_XFRM_KEY);
124 if (tb[NFTA_XFRM_DIR]) {
125 x->dir = mnl_attr_get_u8(tb[NFTA_XFRM_DIR]);
126 e->flags |= (1 << NFTNL_EXPR_XFRM_DIR);
128 if (tb[NFTA_XFRM_SPNUM]) {
129 x->spnum = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_SPNUM]));
130 e->flags |= (1 << NFTNL_EXPR_XFRM_SPNUM);
132 if (tb[NFTA_XFRM_DREG]) {
133 x->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_DREG]));
134 e->flags |= (1 << NFTNL_EXPR_XFRM_DREG);
139static const char *xfrmkey2str_array[] = {
140 [NFT_XFRM_KEY_DADDR_IP4] =
"daddr4",
141 [NFT_XFRM_KEY_SADDR_IP4] =
"saddr4",
142 [NFT_XFRM_KEY_DADDR_IP6] =
"daddr6",
143 [NFT_XFRM_KEY_SADDR_IP6] =
"saddr6",
144 [NFT_XFRM_KEY_REQID] =
"reqid",
145 [NFT_XFRM_KEY_SPI] =
"spi",
148static const char *xfrmkey2str(uint32_t key)
150 if (key >=
sizeof(xfrmkey2str_array) /
sizeof(xfrmkey2str_array[0]))
153 return xfrmkey2str_array[key];
156static const char *xfrmdir2str_array[] = {
157 [XFRM_POLICY_IN] =
"in",
158 [XFRM_POLICY_OUT] =
"out",
161static const char *xfrmdir2str(uint8_t dir)
163 if (dir >=
sizeof(xfrmdir2str_array) /
sizeof(xfrmdir2str_array[0]))
166 return xfrmdir2str_array[dir];
170nftnl_expr_xfrm_snprintf(
char *buf,
size_t remain,
171 uint32_t flags,
const struct nftnl_expr *e)
176 if (e->flags & (1 << NFTNL_EXPR_XFRM_DREG)) {
177 ret = snprintf(buf, remain,
"load %s %u %s => reg %u ",
180 xfrmkey2str(x->key), x->dreg);
181 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
186static struct attr_policy xfrm_attr_policy[__NFTNL_EXPR_XFRM_MAX] = {
187 [NFTNL_EXPR_XFRM_DREG] = { .maxlen =
sizeof(uint32_t) },
188 [NFTNL_EXPR_XFRM_SREG] = { .maxlen = 0 },
189 [NFTNL_EXPR_XFRM_KEY] = { .maxlen =
sizeof(uint32_t) },
190 [NFTNL_EXPR_XFRM_DIR] = { .maxlen =
sizeof(uint8_t) },
191 [NFTNL_EXPR_XFRM_SPNUM] = { .maxlen =
sizeof(uint32_t) },
194struct expr_ops expr_ops_xfrm = {
197 .nftnl_max_attr = __NFTNL_EXPR_XFRM_MAX - 1,
198 .attr_policy = xfrm_attr_policy,
199 .set = nftnl_expr_xfrm_set,
200 .get = nftnl_expr_xfrm_get,
201 .parse = nftnl_expr_xfrm_parse,
202 .build = nftnl_expr_xfrm_build,
203 .output = nftnl_expr_xfrm_snprintf,