On Tue, Jan 28, 2020 at 11:31:39AM +0000, Jeremy Sowden wrote: > On 2020-01-28, at 11:00:35 +0100, Pablo Neira Ayuso wrote: > > On Mon, Jan 27, 2020 at 11:13:14AM +0000, Jeremy Sowden wrote: > > > On 2020-01-26, at 12:12:51 +0100, Pablo Neira Ayuso wrote: > > > > I've been looking into (ab)using bitwise to implement add/sub. I > > > > would like to not add nft_arith for only this, and it seems to me > > > > much of your code can be reused. > > > > > > > > Do you think something like this would work? > > > > > > Absolutely. > > > > > > A couple of questions. What's the use-case? > > > > inc/dec ip ttl field. > > If it's just a simple addition or subtraction on one value, would > this make more sense? > > for (i = 0; i < words; i++) { > dst[i] = src[i] + delta; > delta = dst[i] < src[i] ? 1 : 0; > } This can be done through _INC / _DEC instead, however... > > > I find the combination of applying the delta to every u32 and having > > > a carry curious. Do you want to support bigendian arithmetic (i.e., > > > carrying to the left) as well? > > > > Userspace should convert to host endianess before doing arithmetics. > > Yes, but if the host is bigendian, the least significant bytes will be > on the right, and we need to carry to the left, don't we? > > for (i = words; i > 0; i--) { > dst[i - 1] = src[i - 1] + delta; > delta = dst[i - 1] < src[i - 1] ? 1 : 0; > } I think some simplified version of bignum add/subtract is needed, something like: for (i = len - 1; i >= 0; i--) { res[i] = a[i] + b[i] + carry; carry = res[i] < a[i] + b[i]; } where 'len' is in bytes. Values in a[] and b[] are u8 and data is represented in big endian.