15#include <linux/netfilter/nf_tables.h>
18#include <libmnl/libmnl.h>
19#include <libnftnl/expr.h>
20#include <libnftnl/rule.h>
23 enum nft_tunnel_keys key;
24 enum nft_registers dreg;
27static int nftnl_expr_tunnel_set(
struct nftnl_expr *e, uint16_t type,
28 const void *data, uint32_t data_len)
33 case NFTNL_EXPR_TUNNEL_KEY:
34 memcpy(&tunnel->key, data,
sizeof(tunnel->key));
36 case NFTNL_EXPR_TUNNEL_DREG:
37 memcpy(&tunnel->dreg, data,
sizeof(tunnel->dreg));
46nftnl_expr_tunnel_get(
const struct nftnl_expr *e, uint16_t type,
52 case NFTNL_EXPR_TUNNEL_KEY:
53 *data_len =
sizeof(tunnel->key);
55 case NFTNL_EXPR_TUNNEL_DREG:
56 *data_len =
sizeof(tunnel->dreg);
62static int nftnl_expr_tunnel_cb(
const struct nlattr *attr,
void *data)
64 const struct nlattr **tb = data;
65 int type = mnl_attr_get_type(attr);
67 if (mnl_attr_type_valid(attr, NFTA_TUNNEL_MAX) < 0)
72 case NFTA_TUNNEL_DREG:
73 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
83nftnl_expr_tunnel_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
87 if (e->flags & (1 << NFTNL_EXPR_TUNNEL_KEY))
88 mnl_attr_put_u32(nlh, NFTA_TUNNEL_KEY, htonl(tunnel->key));
89 if (e->flags & (1 << NFTNL_EXPR_TUNNEL_DREG))
90 mnl_attr_put_u32(nlh, NFTA_TUNNEL_DREG, htonl(tunnel->dreg));
94nftnl_expr_tunnel_parse(
struct nftnl_expr *e,
struct nlattr *attr)
97 struct nlattr *tb[NFTA_TUNNEL_MAX + 1] = {};
99 if (mnl_attr_parse_nested(attr, nftnl_expr_tunnel_cb, tb) < 0)
102 if (tb[NFTA_TUNNEL_KEY]) {
103 tunnel->key = ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_KEY]));
104 e->flags |= (1 << NFTNL_EXPR_TUNNEL_KEY);
106 if (tb[NFTA_TUNNEL_DREG]) {
107 tunnel->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_TUNNEL_DREG]));
108 e->flags |= (1 << NFTNL_EXPR_TUNNEL_DREG);
114static const char *tunnel_key2str_array[NFT_TUNNEL_MAX + 1] = {
115 [NFT_TUNNEL_PATH] =
"path",
116 [NFT_TUNNEL_ID] =
"id",
119static const char *tunnel_key2str(uint8_t key)
121 if (key <= NFT_TUNNEL_MAX)
122 return tunnel_key2str_array[key];
128nftnl_expr_tunnel_snprintf(
char *buf,
size_t len,
129 uint32_t flags,
const struct nftnl_expr *e)
133 if (e->flags & (1 << NFTNL_EXPR_TUNNEL_DREG)) {
134 return snprintf(buf, len,
"load %s => reg %u ",
135 tunnel_key2str(tunnel->key), tunnel->dreg);
140struct expr_ops expr_ops_tunnel = {
143 .max_attr = NFTA_TUNNEL_MAX,
144 .set = nftnl_expr_tunnel_set,
145 .get = nftnl_expr_tunnel_get,
146 .parse = nftnl_expr_tunnel_parse,
147 .build = nftnl_expr_tunnel_build,
148 .output = nftnl_expr_tunnel_snprintf,