11 #include <arpa/inet.h>
13 #include <linux/netfilter/nf_tables.h>
14 #include <linux/xfrm.h>
17 #include <libmnl/libmnl.h>
18 #include <libnftnl/expr.h>
19 #include <libnftnl/rule.h>
22 enum nft_registers dreg;
23 enum nft_xfrm_keys key;
29 nftnl_expr_xfrm_set(
struct nftnl_expr *e, uint16_t type,
30 const void *data, uint32_t data_len)
35 case NFTNL_EXPR_XFRM_KEY:
36 memcpy(&x->key, data,
sizeof(x->key));
38 case NFTNL_EXPR_XFRM_DIR:
39 memcpy(&x->dir, data,
sizeof(x->dir));
41 case NFTNL_EXPR_XFRM_SPNUM:
42 memcpy(&x->spnum, data,
sizeof(x->spnum));
44 case NFTNL_EXPR_XFRM_DREG:
45 memcpy(&x->dreg, data,
sizeof(x->dreg));
54 nftnl_expr_xfrm_get(
const struct nftnl_expr *e, uint16_t type,
60 case NFTNL_EXPR_XFRM_KEY:
61 *data_len =
sizeof(x->key);
63 case NFTNL_EXPR_XFRM_DIR:
64 *data_len =
sizeof(x->dir);
66 case NFTNL_EXPR_XFRM_SPNUM:
67 *data_len =
sizeof(x->spnum);
69 case NFTNL_EXPR_XFRM_DREG:
70 *data_len =
sizeof(x->dreg);
76 static int nftnl_expr_xfrm_cb(
const struct nlattr *attr,
void *data)
78 const struct nlattr **tb = data;
79 int type = mnl_attr_get_type(attr);
81 if (mnl_attr_type_valid(attr, NFTA_XFRM_MAX) < 0)
88 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
92 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
102 nftnl_expr_xfrm_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
106 if (e->flags & (1 << NFTNL_EXPR_XFRM_KEY))
107 mnl_attr_put_u32(nlh, NFTA_XFRM_KEY, htonl(x->key));
108 if (e->flags & (1 << NFTNL_EXPR_XFRM_DIR))
109 mnl_attr_put_u8(nlh, NFTA_XFRM_DIR, x->dir);
110 if (e->flags & (1 << NFTNL_EXPR_XFRM_SPNUM))
111 mnl_attr_put_u32(nlh, NFTA_XFRM_SPNUM, htonl(x->spnum));
112 if (e->flags & (1 << NFTNL_EXPR_XFRM_DREG))
113 mnl_attr_put_u32(nlh, NFTA_XFRM_DREG, htonl(x->dreg));
117 nftnl_expr_xfrm_parse(
struct nftnl_expr *e,
struct nlattr *attr)
120 struct nlattr *tb[NFTA_XFRM_MAX+1] = {};
122 if (mnl_attr_parse_nested(attr, nftnl_expr_xfrm_cb, tb) < 0)
125 if (tb[NFTA_XFRM_KEY]) {
126 x->key = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_KEY]));
127 e->flags |= (1 << NFTNL_EXPR_XFRM_KEY);
129 if (tb[NFTA_XFRM_DIR]) {
130 x->dir = mnl_attr_get_u8(tb[NFTA_XFRM_DIR]);
131 e->flags |= (1 << NFTNL_EXPR_XFRM_DIR);
133 if (tb[NFTA_XFRM_SPNUM]) {
134 x->spnum = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_SPNUM]));
135 e->flags |= (1 << NFTNL_EXPR_XFRM_SPNUM);
137 if (tb[NFTA_XFRM_DREG]) {
138 x->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_XFRM_DREG]));
139 e->flags |= (1 << NFTNL_EXPR_XFRM_DREG);
144 static const char *xfrmkey2str_array[] = {
145 [NFT_XFRM_KEY_DADDR_IP4] =
"daddr4",
146 [NFT_XFRM_KEY_SADDR_IP4] =
"saddr4",
147 [NFT_XFRM_KEY_DADDR_IP6] =
"daddr6",
148 [NFT_XFRM_KEY_SADDR_IP6] =
"saddr6",
149 [NFT_XFRM_KEY_REQID] =
"reqid",
150 [NFT_XFRM_KEY_SPI] =
"spi",
153 static const char *xfrmkey2str(uint32_t key)
155 if (key >=
sizeof(xfrmkey2str_array) /
sizeof(xfrmkey2str_array[0]))
158 return xfrmkey2str_array[key];
161 static const char *xfrmdir2str_array[] = {
162 [XFRM_POLICY_IN] =
"in",
163 [XFRM_POLICY_OUT] =
"out",
166 static const char *xfrmdir2str(uint8_t dir)
168 if (dir >=
sizeof(xfrmdir2str_array) /
sizeof(xfrmdir2str_array[0]))
171 return xfrmdir2str_array[dir];
175 static uint32_t str2xfrmkey(
const char *s)
180 i <
sizeof(xfrmkey2str_array) /
sizeof(xfrmkey2str_array[0]);
182 if (strcmp(xfrmkey2str_array[i], s) == 0)
188 static int str2xfmrdir(
const char *s)
193 i <
sizeof(xfrmdir2str_array) /
sizeof(xfrmdir2str_array[0]);
195 if (strcmp(xfrmkey2str_array[i], s) == 0)
203 nftnl_expr_xfrm_snprintf_default(
char *buf,
size_t size,
204 const struct nftnl_expr *e)
207 int ret, remain = size, offset = 0;
209 if (e->flags & (1 << NFTNL_EXPR_XFRM_DREG)) {
210 ret = snprintf(buf, remain,
"load %s %u %s => reg %u ",
213 xfrmkey2str(x->key), x->dreg);
214 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
220 nftnl_expr_xfrm_snprintf(
char *buf,
size_t len, uint32_t type,
221 uint32_t flags,
const struct nftnl_expr *e)
224 case NFTNL_OUTPUT_DEFAULT:
225 return nftnl_expr_xfrm_snprintf_default(buf, len, e);
226 case NFTNL_OUTPUT_XML:
227 case NFTNL_OUTPUT_JSON:
234 struct expr_ops expr_ops_xfrm = {
237 .max_attr = NFTA_XFRM_MAX,
238 .set = nftnl_expr_xfrm_set,
239 .get = nftnl_expr_xfrm_get,
240 .parse = nftnl_expr_xfrm_parse,
241 .build = nftnl_expr_xfrm_build,
242 .snprintf = nftnl_expr_xfrm_snprintf,