13 #include <arpa/inet.h> 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;
27 static 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));
46 nftnl_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);
62 static 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)
83 nftnl_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));
94 nftnl_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);
114 static const char *tunnel_key2str_array[NFT_TUNNEL_MAX + 1] = {
115 [NFT_TUNNEL_PATH] =
"path",
116 [NFT_TUNNEL_ID] =
"id",
119 static const char *tunnel_key2str(uint8_t key)
121 if (key <= NFT_TUNNEL_MAX)
122 return tunnel_key2str_array[key];
127 static inline int str2tunnel_key(
const char *str)
131 for (i = 0; i <= NFT_TUNNEL_MAX; i++) {
132 if (strcmp(str, tunnel_key2str_array[i]) == 0)
141 nftnl_expr_tunnel_snprintf_default(
char *buf,
size_t len,
142 const struct nftnl_expr *e)
146 if (e->flags & (1 << NFTNL_EXPR_TUNNEL_DREG)) {
147 return snprintf(buf, len,
"load %s => reg %u ",
148 tunnel_key2str(tunnel->key), tunnel->dreg);
154 nftnl_expr_tunnel_snprintf(
char *buf,
size_t len, uint32_t type,
155 uint32_t flags,
const struct nftnl_expr *e)
158 case NFTNL_OUTPUT_DEFAULT:
159 return nftnl_expr_tunnel_snprintf_default(buf, len, e);
160 case NFTNL_OUTPUT_XML:
161 case NFTNL_OUTPUT_JSON:
168 struct expr_ops expr_ops_tunnel = {
171 .max_attr = NFTA_TUNNEL_MAX,
172 .set = nftnl_expr_tunnel_set,
173 .get = nftnl_expr_tunnel_get,
174 .parse = nftnl_expr_tunnel_parse,
175 .build = nftnl_expr_tunnel_build,
176 .snprintf = nftnl_expr_tunnel_snprintf,