expr: hash: Add offset to hash value
PATCH 1/1 expr: hash: Add offset to hash value
Add support to pass through an offset to the hash value. With this feature, the sysadmin is able to generate a hash with a given started value.
Example:
meta mark set jhash ip saddr mod 2 seed 0xabcd sum 100
This option generates marks according to the source address from 100 to 101.
Signed-off-by Laura Garcia Liebana <[email protected]>
--- include/libnftnl/expr.h | 1 + include/linux/netfilter/nf_tables.h | 2 ++ src/expr/hash.c | 39 +++++++++++++++++++++++++++++++------ tests/nft-expr_hash-test.c | 4 ++++ 4 files changed, 40 insertions(+), 6 deletions(-)
include/libnftnl/expr.h +1 -0
@@ -211,6 +211,7 @@ enum {NFTNL_EXPR_HASH_LEN ,NFTNL_EXPR_HASH_MODULUS ,NFTNL_EXPR_HASH_SEED , + NFTNL_EXPR_HASH_SUM, };/*
include/linux/netfilter/nf_tables.h +2 -0
@@ -1139,6 +1139,7 @@ enum nft_trace_types {* @NFTA_HASH_LEN: data length (NLA_U32) * @NFTA_HASH_MODULUS: Modulus value (NLA_U32) * @NFTA_HASH_SEED: hash initial value (NLA_U32) +* @NFTA_HASH_SUM: offset value to be added (NLA_U32) */ enum nft_hash_attributes {NFTA_HASH_UNSPEC ,
@@ -1147,6 +1148,7 @@ enum nft_hash_attributes {NFTA_HASH_LEN ,NFTA_HASH_MODULUS ,NFTA_HASH_SEED , +NFTA_HASH_SUM , __NFTA_HASH_MAX };#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
src/expr/hash.c +33 -6
@@ -26,6 +26,7 @@ struct nftnl_expr_hash {unsigned int len;unsigned int modulus;unsigned int seed; +unsigned int sum; }; static int
@@ -50,6 +51,9 @@ nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,case NFTNL_EXPR_HASH_SEED : hash->seed = *((uint32_t *)data);break ; +case NFTNL_EXPR_HASH_SUM : + hash->sum = *((uint32_t *)data); +break ;default :return -1 ; }
@@ -78,6 +82,9 @@ nftnl_expr_hash_get(const struct nftnl_expr *e, uint16_t type,case NFTNL_EXPR_HASH_SEED : *data_len =sizeof (hash->seed);return &hash->seed; +case NFTNL_EXPR_HASH_SUM : + *data_len =sizeof (hash->sum); +return &hash->sum; }return NULL ; }
@@ -96,6 +103,7 @@ static int nftnl_expr_hash_cb(const struct nlattr *attr, void *data)case NFTA_HASH_LEN :case NFTA_HASH_MODULUS :case NFTA_HASH_SEED : +case NFTA_HASH_SUM :if (mnl_attr_validate (attr,MNL_TYPE_U32 ) <0 )abi_breakage ();break ;
@@ -120,7 +128,8 @@ nftnl_expr_hash_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)mnl_attr_put_u32 (nlh,NFTA_HASH_MODULUS ,htonl (hash->modulus));if (e->flags & (1 <<NFTNL_EXPR_HASH_SEED ))mnl_attr_put_u32 (nlh,NFTA_HASH_SEED ,htonl (hash->seed)); - +if (e->flags & (1 <<NFTNL_EXPR_HASH_SUM )) +mnl_attr_put_u32 (nlh,NFTA_HASH_SUM ,htonl (hash->sum)); } static int
@@ -153,6 +162,10 @@ nftnl_expr_hash_parse(struct nftnl_expr *e, struct nlattr *attr) hash->seed =ntohl (mnl_attr_get_u32 (tb[NFTA_HASH_SEED ])); e->flags |= (1 <<NFTNL_EXPR_HASH_SEED ); } +if (tb[NFTA_HASH_SUM ]) { + hash->sum =ntohl (mnl_attr_get_u32 (tb[NFTA_HASH_SUM ])); + e->flags |= (1 <<NFTNL_EXPR_HASH_SUM ); + }return ret; }
@@ -161,7 +174,7 @@ static int nftnl_expr_hash_json_parse(struct nftnl_expr *e, json_t *root, struct nftnl_parse_err *err) {#ifdef JSON_PARSING -uint32_t sreg, dreg, len, modulus, seed; +uint32_t sreg, dreg, len, modulus, seed, sum;if (nftnl_jansson_parse_reg (root,"sreg" ,NFTNL_TYPE_U32 , &sreg, err) ==0 )
@@ -183,6 +196,10 @@ static int nftnl_expr_hash_json_parse(struct nftnl_expr *e, json_t *root, &seed, err) == 0)nftnl_expr_set_u32 (e,NFTNL_EXPR_HASH_SEED , seed); +if (nftnl_jansson_parse_val (root,"sum" ,NFTNL_TYPE_U32 , + &sum, err) ==0 ) +nftnl_expr_set_u32 (e,NFTNL_EXPR_HASH_SUM , sum); +return 0 ;#else errno =EOPNOTSUPP ;
@@ -196,7 +213,7 @@ static int nftnl_expr_hash_xml_parse(struct nftnl_expr *e, struct nftnl_parse_err *err) {#ifdef XML_PARSING -uint32_t sreg, dreg, len, modulus, seed; +uint32_t sreg, dreg, len, modulus, seed, sum;if (nftnl_mxml_reg_parse (tree,"sreg" , &sreg,MXML_DESCEND_FIRST ,NFTNL_XML_MAND , err) ==0 )
@@ -221,6 +238,11 @@ static int nftnl_expr_hash_xml_parse(struct nftnl_expr *e, err) == 0)nftnl_expr_set_u32 (e,NFTNL_EXPR_HASH_SEED , seed); +if (nftnl_mxml_num_parse (tree,"sum" ,MXML_DESCEND_FIRST ,BASE_DEC , + &sum,NFTNL_TYPE_U32 ,NFTNL_XML_MAND , + err) ==0 ) +nftnl_expr_set_u32 (e,NFTNL_EXPR_HASH_SUM , sum); +return 0 ;#else errno =EOPNOTSUPP ;
@@ -235,9 +257,10 @@ nftnl_expr_hash_snprintf_default(char *buf, size_t size,struct nftnl_expr_hash *hash =nftnl_expr_data (e);int len = size, offset =0 , ret; - ret =snprintf (buf, len,"reg %u = jhash(reg %u, %u, 0x%x) %% mod %u " , - hash->dreg, hash->sreg, hash->len, hash->seed, - hash->modulus); + ret =snprintf (buf, len, +"reg %u = %u + jhash(reg %u, %u, 0x%x) %% mod %u " , + hash->sum, hash->dreg, hash->sreg, hash->len, + hash->seed, hash->modulus);SNPRINTF_BUFFER_SIZE (ret, size, len, offset);return offset;
@@ -260,6 +283,8 @@ static int nftnl_expr_hash_export(char *buf, size_t size,nftnl_buf_u32 (&b, type, hash->modulus,MODULUS );if (e->flags & (1 <<NFTNL_EXPR_HASH_SEED ))nftnl_buf_u32 (&b, type, hash->seed,SEED ); +if (e->flags & (1 <<NFTNL_EXPR_HASH_SUM )) +nftnl_buf_u32 (&b, type, hash->sum,SUM );return nftnl_buf_done (&b); }
@@ -297,6 +322,8 @@ static bool nftnl_expr_hash_cmp(const struct nftnl_expr *e1, eq &= (h1->modulus == h2->modulus);if (e1->flags & (1 <<NFTNL_EXPR_HASH_SEED )) eq &= (h1->seed == h2->seed); +if (e1->flags & (1 <<NFTNL_EXPR_HASH_SUM )) + eq &= (h1->sum == h2->sum);return eq; }
tests/nft-expr_hash-test.c +4 -0
@@ -42,6 +42,9 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,if (nftnl_expr_get_u32 (rule_a,NFTNL_EXPR_HASH_SEED ) !=nftnl_expr_get_u32 (rule_b,NFTNL_EXPR_HASH_SEED ))print_err ("Expr NFTNL_EXPR_HASH_SEED mismatches" ); +if (nftnl_expr_get_u32 (rule_a,NFTNL_EXPR_HASH_SUM ) != +nftnl_expr_get_u32 (rule_b,NFTNL_EXPR_HASH_SUM )) +print_err ("Expr NFTNL_EXPR_HASH_SUM mismatches" ); }int main (int argc,char *argv[])
@@ -65,6 +68,7 @@ int main(int argc, char *argv[])nftnl_expr_set_u32 (ex,NFTNL_EXPR_HASH_DREG ,0x78123456 );nftnl_expr_set_u32 (ex,NFTNL_EXPR_HASH_MODULUS ,0x78123456 );nftnl_expr_set_u32 (ex,NFTNL_EXPR_HASH_SEED ,0x78123456 ); +nftnl_expr_set_u32 (ex,NFTNL_EXPR_HASH_SUM ,0x1234568 );nftnl_rule_add_expr (a, ex);
Signature · 1 line
2.8.1