*
  * Return: -1 on no match, bit position on 'match_only', 0 otherwise.
  */
-int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst,
+int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
+                 unsigned long *dst,
                  const union nft_pipapo_map_bucket *mt, bool match_only)
 {
        unsigned long bitset;
-       int k, ret = -1;
+       unsigned int k;
+       int ret = -1;
 
        for (k = 0; k < len; k++) {
                bitset = map[k];
  *
  * Return: 0 on success, -ENOMEM on allocation failure.
  */
-static int pipapo_resize(struct nft_pipapo_field *f, int old_rules, int rules)
+static int pipapo_resize(struct nft_pipapo_field *f,
+                        unsigned int old_rules, unsigned int rules)
 {
        long *new_lt = NULL, *new_p, *old_lt = f->lt, *old_p;
        union nft_pipapo_map_bucket *new_mt, *old_mt = f->mt;
-       size_t new_bucket_size, copy;
+       unsigned int new_bucket_size, copy;
        int group, bucket;
 
+       if (rules >= NFT_PIPAPO_RULE0_MAX)
+               return -ENOSPC;
+
        new_bucket_size = DIV_ROUND_UP(rules, BITS_PER_LONG);
 #ifdef NFT_PIPAPO_ALIGN
        new_bucket_size = roundup(new_bucket_size,
 
        if (new_lt) {
                f->bsize = new_bucket_size;
-               NFT_PIPAPO_LT_ASSIGN(f, new_lt);
+               f->lt = new_lt;
                kvfree(old_lt);
        }
 
  */
 static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f)
 {
+       unsigned int groups, bb;
        unsigned long *new_lt;
-       int groups, bb;
        size_t lt_size;
 
        lt_size = f->groups * NFT_PIPAPO_BUCKETS(f->bb) * f->bsize *
        f->groups = groups;
        f->bb = bb;
        kvfree(f->lt);
-       NFT_PIPAPO_LT_ASSIGN(f, new_lt);
+       f->lt = new_lt;
 }
 
 /**
 static int pipapo_insert(struct nft_pipapo_field *f, const uint8_t *k,
                         int mask_bits)
 {
-       int rule = f->rules, group, ret, bit_offset = 0;
+       unsigned int rule = f->rules, group, ret, bit_offset = 0;
 
        ret = pipapo_resize(f, f->rules, f->rules + 1);
        if (ret)
        /* Validate */
        start_p = start;
        end_p = end;
+
+       /* some helpers return -1, or 0 >= for valid rule pos,
+        * so we cannot support more than INT_MAX rules at this time.
+        */
+       BUILD_BUG_ON(NFT_PIPAPO_RULE0_MAX > INT_MAX);
+
        nft_pipapo_for_each_field(f, i, m) {
-               if (f->rules >= (unsigned long)NFT_PIPAPO_RULE0_MAX)
+               if (f->rules >= NFT_PIPAPO_RULE0_MAX)
                        return -ENOSPC;
 
                if (memcmp(start_p, end_p,
                if (!new_lt)
                        goto out_lt;
 
-               NFT_PIPAPO_LT_ASSIGN(dst, new_lt);
+               dst->lt = new_lt;
 
                memcpy(NFT_PIPAPO_LT_ALIGN(new_lt),
                       NFT_PIPAPO_LT_ALIGN(src->lt),
  *
  * Return: Number of rules that originated from the same entry as @first.
  */
-static int pipapo_rules_same_key(struct nft_pipapo_field *f, int first)
+static unsigned int pipapo_rules_same_key(struct nft_pipapo_field *f, unsigned int first)
 {
        struct nft_pipapo_elem *e = NULL; /* Keep gcc happy */
-       int r;
+       unsigned int r;
 
        for (r = first; r < f->rules; r++) {
                if (r != first && e != f->mt[r].e)
  *                        0      1      2
  *  element pointers:  0x42   0x42   0x44
  */
-static void pipapo_unmap(union nft_pipapo_map_bucket *mt, int rules,
-                        int start, int n, int to_offset, bool is_last)
+static void pipapo_unmap(union nft_pipapo_map_bucket *mt, unsigned int rules,
+                        unsigned int start, unsigned int n,
+                        unsigned int to_offset, bool is_last)
 {
        int i;
 
 {
        struct nft_pipapo *priv = nft_set_priv(set);
        struct net *net = read_pnet(&set->net);
+       unsigned int rules_f0, first_rule = 0;
        u64 tstamp = nft_net_tstamp(net);
-       int rules_f0, first_rule = 0;
        struct nft_pipapo_elem *e;
        struct nft_trans_gc *gc;
 
        while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
                union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
                const struct nft_pipapo_field *f;
-               int i, start, rules_fx;
+               unsigned int i, start, rules_fx;
 
                start = first_rule;
                rules_fx = rules_f0;
 {
        struct nft_pipapo *priv = nft_set_priv(set);
        struct nft_pipapo_match *m = priv->clone;
-       int rules_f0, first_rule = 0;
+       unsigned int rules_f0, first_rule = 0;
        struct nft_pipapo_elem *e;
        const u8 *data;
 
        struct net *net = read_pnet(&set->net);
        const struct nft_pipapo_match *m;
        const struct nft_pipapo_field *f;
-       int i, r;
+       unsigned int i, r;
 
        rcu_read_lock();
        if (iter->genmask == nft_genmask_cur(net))
 
        field_count = desc->field_count ? : 1;
 
+       BUILD_BUG_ON(NFT_PIPAPO_MAX_FIELDS > 255);
+       BUILD_BUG_ON(NFT_PIPAPO_MAX_FIELDS != NFT_REG32_COUNT);
+
        if (field_count > NFT_PIPAPO_MAX_FIELDS)
                return -EINVAL;
 
        rcu_head_init(&m->rcu);
 
        nft_pipapo_for_each_field(f, i, m) {
-               int len = desc->field_len[i] ? : set->klen;
+               unsigned int len = desc->field_len[i] ? : set->klen;
+
+               /* f->groups is u8 */
+               BUILD_BUG_ON((NFT_PIPAPO_MAX_BYTES *
+                             BITS_PER_BYTE / NFT_PIPAPO_GROUP_BITS_LARGE_SET) >= 256);
 
                f->bb = NFT_PIPAPO_GROUP_BITS_INIT;
                f->groups = len * NFT_PIPAPO_GROUPS_PER_BYTE(f);
 
                f->bsize = 0;
                f->rules = 0;
-               NFT_PIPAPO_LT_ASSIGN(f, NULL);
+               f->lt = NULL;
                f->mt = NULL;
        }
 
                                         struct nft_pipapo_match *m)
 {
        struct nft_pipapo_field *f;
-       int i, r;
+       unsigned int i, r;
 
        for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
                ;
 
 #define NFT_PIPAPO_ALIGN_HEADROOM                                      \
        (NFT_PIPAPO_ALIGN - ARCH_KMALLOC_MINALIGN)
 #define NFT_PIPAPO_LT_ALIGN(lt)                (PTR_ALIGN((lt), NFT_PIPAPO_ALIGN))
-#define NFT_PIPAPO_LT_ASSIGN(field, x)                                 \
-       do {                                                            \
-               (field)->lt_aligned = NFT_PIPAPO_LT_ALIGN(x);           \
-               (field)->lt = (x);                                      \
-       } while (0)
 #else
 #define NFT_PIPAPO_ALIGN_HEADROOM      0
 #define NFT_PIPAPO_LT_ALIGN(lt)                (lt)
-#define NFT_PIPAPO_LT_ASSIGN(field, x) ((field)->lt = (x))
 #endif /* NFT_PIPAPO_ALIGN */
 
 #define nft_pipapo_for_each_field(field, index, match)         \
 
 /**
  * struct nft_pipapo_field - Lookup, mapping tables and related data for a field
- * @groups:    Amount of bit groups
  * @rules:     Number of inserted rules
  * @bsize:     Size of each bucket in lookup table, in longs
+ * @groups:    Amount of bit groups
  * @bb:                Number of bits grouped together in lookup table buckets
  * @lt:                Lookup table: 'groups' rows of buckets
- * @lt_aligned:        Version of @lt aligned to NFT_PIPAPO_ALIGN bytes
  * @mt:                Mapping table: one bucket per rule
  */
 struct nft_pipapo_field {
-       int groups;
-       unsigned long rules;
-       size_t bsize;
-       int bb;
-#ifdef NFT_PIPAPO_ALIGN
-       unsigned long *lt_aligned;
-#endif
+       unsigned int rules;
+       unsigned int bsize;
+       u8 groups;
+       u8 bb;
        unsigned long *lt;
        union nft_pipapo_map_bucket *mt;
 };
 /**
  * struct nft_pipapo_match - Data used for lookup and matching
  * @field_count:       Amount of fields in set
- * @scratch:           Preallocated per-CPU maps for partial matching results
  * @bsize_max:         Maximum lookup table bucket size of all fields, in longs
+ * @scratch:           Preallocated per-CPU maps for partial matching results
  * @rcu:               Matching data is swapped on commits
  * @f:                 Fields, with lookup and mapping tables
  */
 struct nft_pipapo_match {
-       int field_count;
+       u8 field_count;
+       unsigned int bsize_max;
        struct nft_pipapo_scratch * __percpu *scratch;
-       size_t bsize_max;
        struct rcu_head rcu;
        struct nft_pipapo_field f[] __counted_by(field_count);
 };
        struct nft_set_ext      ext;
 };
 
-int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst,
+int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
+                 unsigned long *dst,
                  const union nft_pipapo_map_bucket *mt, bool match_only);
 
 /**