{
        uint32_t i = resource->actions_num;
        struct mlx5_modification_cmd *actions = resource->actions;
+       uint32_t carry_b = 0;
 
        /*
         * The item and mask are provided in big-endian format.
        MLX5_ASSERT(item->mask);
        MLX5_ASSERT(field->size);
        do {
-               unsigned int size_b;
-               unsigned int off_b;
+               uint32_t size_b;
+               uint32_t off_b;
                uint32_t mask;
                uint32_t data;
                bool next_field = true;
                        continue;
                }
                /* Deduce actual data width in bits from mask value. */
-               off_b = rte_bsf32(mask);
+               off_b = rte_bsf32(mask) + carry_b;
                size_b = sizeof(uint32_t) * CHAR_BIT -
                         off_b - __builtin_clz(mask);
                MLX5_ASSERT(size_b);
                         * Destination field overflow. Copy leftovers of
                         * a source field to the next destination field.
                         */
-                       if ((size_b > dcopy->size * CHAR_BIT) && dcopy->size) {
-                               actions[i].length = dcopy->size * CHAR_BIT;
-                               field->offset += dcopy->size;
+                       carry_b = 0;
+                       if ((size_b > dcopy->size * CHAR_BIT - dcopy->offset) &&
+                           dcopy->size != 0) {
+                               actions[i].length =
+                                       dcopy->size * CHAR_BIT - dcopy->offset;
+                               carry_b = actions[i].length;
                                next_field = false;
                        }
                        /*
                         * Not enough bits in a source filed to fill a
                         * destination field. Switch to the next source.
                         */
-                       if (dcopy->size > field->size &&
-                           (size_b == field->size * CHAR_BIT)) {
-                               actions[i].length = field->size * CHAR_BIT;
-                               dcopy->offset += field->size * CHAR_BIT;
+                       if ((size_b < dcopy->size * CHAR_BIT - dcopy->offset) &&
+                           (size_b == field->size * CHAR_BIT - off_b)) {
+                               actions[i].length =
+                                       field->size * CHAR_BIT - off_b;
+                               dcopy->offset += actions[i].length;
                                next_dcopy = false;
                        }
                        if (next_dcopy)