summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libnftnl/expr.h1
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--src/expr/osf.c17
3 files changed, 20 insertions, 0 deletions
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 3d99d24..b2f8d75 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -280,6 +280,7 @@ enum {
enum {
NFTNL_EXPR_OSF_DREG = NFTNL_EXPR_BASE,
NFTNL_EXPR_OSF_TTL,
+ NFTNL_EXPR_OSF_FLAGS,
};
enum {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index ac6de5e..fd38cdc 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -940,11 +940,13 @@ enum nft_socket_keys {
*
* @NFTA_OSF_DREG: destination register (NLA_U32)
* @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ * @NFTA_OSF_FLAGS: flags (NLA_U32)
*/
enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
NFTA_OSF_TTL,
+ NFTA_OSF_FLAGS,
__NFTA_OSF_MAX,
};
#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/src/expr/osf.c b/src/expr/osf.c
index 52da21f..98d0df9 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -15,6 +15,7 @@
struct nftnl_expr_osf {
enum nft_registers dreg;
uint8_t ttl;
+ uint32_t flags;
};
static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
@@ -29,6 +30,9 @@ static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_OSF_TTL:
memcpy(&osf->ttl, data, sizeof(osf->ttl));
break;
+ case NFTNL_EXPR_OSF_FLAGS:
+ memcpy(&osf->flags, data, sizeof(osf->flags));
+ break;
}
return 0;
}
@@ -46,6 +50,9 @@ nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_OSF_TTL:
*data_len = sizeof(osf->ttl);
return &osf->ttl;
+ case NFTNL_EXPR_OSF_FLAGS:
+ *data_len = sizeof(osf->flags);
+ return &osf->flags;
}
return NULL;
}
@@ -60,6 +67,7 @@ static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
switch(type) {
case NFTNL_EXPR_OSF_DREG:
+ case NFTNL_EXPR_OSF_FLAGS:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -68,6 +76,7 @@ static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
abi_breakage();
break;
+
}
tb[type] = attr;
@@ -83,6 +92,9 @@ nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_DREG, htonl(osf->dreg));
if (e->flags & (1 << NFTNL_EXPR_OSF_TTL))
mnl_attr_put_u8(nlh, NFTNL_EXPR_OSF_TTL, osf->ttl);
+ if (e->flags & (1 << NFTNL_EXPR_OSF_FLAGS))
+ if (osf->flags)
+ mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_FLAGS, htonl(osf->flags));
}
static int
@@ -104,6 +116,11 @@ nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr *attr)
e->flags |= (1 << NFTNL_EXPR_OSF_TTL);
}
+ if (tb[NFTA_OSF_FLAGS]) {
+ osf->flags = ntohl(mnl_attr_get_u32(tb[NFTA_OSF_FLAGS]));
+ e->flags |= (1 << NFTNL_EXPR_OSF_FLAGS);
+ }
+
return 0;
}