[libnftnl] expr: osf: add ttl option support

Message ID 20180929101637.1019-1-ffmancera@riseup.net
State Accepted
Delegated to: Pablo Neira
Headers show
Series
  • [libnftnl] expr: osf: add ttl option support
Related show

Commit Message

Fernando Fernandez Mancera Sept. 29, 2018, 10:16 a.m.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
 include/libnftnl/expr.h             |  1 +
 include/linux/netfilter/nf_tables.h |  4 +++-
 src/expr/osf.c                      | 26 +++++++++++++++++++++++++-
 3 files changed, 29 insertions(+), 2 deletions(-)

Patch

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 6285c6f..6988c62 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -281,6 +281,7 @@  enum {
 
 enum {
 	NFTNL_EXPR_OSF_DREG	= NFTNL_EXPR_BASE,
+	NFTNL_EXPR_OSF_TTL,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index da2c291..936687d 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -936,11 +936,13 @@  enum nft_socket_keys {
 /**
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
- * @NFTA_OSF_DREG: OS to match
+ * @NFTA_OSF_DREG: destination register (NLA_U32)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
 	NFTA_OSF_UNSPEC,
 	NFTA_OSF_DREG,
+	NFTA_OSF_TTL,
 	__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/src/expr/osf.c b/src/expr/osf.c
index 6fd62e5..39d7e0c 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -14,6 +14,7 @@ 
 
 struct nftnl_expr_osf {
 	enum nft_registers	dreg;
+	uint8_t			ttl;
 };
 
 static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
@@ -25,6 +26,9 @@  static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
 	case NFTNL_EXPR_OSF_DREG:
 		osf->dreg = *((uint32_t *)data);
 		break;
+	case NFTNL_EXPR_OSF_TTL:
+		osf->ttl = *((uint8_t *)data);
+		break;
 	}
 	return 0;
 }
@@ -39,6 +43,9 @@  nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
 	case NFTNL_EXPR_OSF_DREG:
 		*data_len = sizeof(osf->dreg);
 		return &osf->dreg;
+	case NFTNL_EXPR_OSF_TTL:
+		*data_len = sizeof(osf->ttl);
+		return &osf->ttl;
 	}
 	return NULL;
 }
@@ -56,6 +63,11 @@  static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
 		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
 			abi_breakage();
 		break;
+
+	case NFTNL_EXPR_OSF_TTL:
+		if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+			abi_breakage();
+		break;
 	}
 
 	tb[type] = attr;
@@ -69,6 +81,8 @@  nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
 
 	if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
 		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);
 }
 
 static int
@@ -85,6 +99,11 @@  nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr *attr)
 		e->flags |= (1 << NFTNL_EXPR_OSF_DREG);
 	}
 
+	if (tb[NFTA_OSF_TTL]) {
+		osf->ttl = mnl_attr_get_u8(tb[NFTA_OSF_TTL]);
+		e->flags |= (1 << NFTNL_EXPR_OSF_TTL);
+	}
+
 	return 0;
 }
 
@@ -95,7 +114,7 @@  static int nftnl_expr_osf_snprintf_default(char *buf, size_t size,
 	int ret, offset = 0, len = size;
 
 	if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) {
-		ret = snprintf(buf, len, "dreg %u ", osf->dreg);
+		ret = snprintf(buf, len, "dreg %u ttl %u", osf->dreg, osf->ttl);
 		SNPRINTF_BUFFER_SIZE(ret, len, offset);
 	}
 
@@ -110,6 +129,8 @@  static int nftnl_expr_osf_export(char *buf, size_t size,
 
 	if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
 		nftnl_buf_u32(&b, type, osf->dreg, "dreg");
+	if (e->flags & (1 << NFTNL_EXPR_OSF_TTL))
+		nftnl_buf_u32(&b, type, osf->ttl, "ttl");
 
 	return nftnl_buf_done(&b);
 }
@@ -140,6 +161,9 @@  static bool nftnl_expr_osf_cmp(const struct nftnl_expr *e1,
 	if (e1->flags & (1 << NFTNL_EXPR_OSF_DREG))
 		eq &= (l1->dreg == l2->dreg);
 
+	if (e1->flags & (1 << NFTNL_EXPR_OSF_TTL))
+		eq &= (l1->ttl == l2->ttl);
+
 	return eq;
 }