Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
One of the reasons why `odp_packet_copy_to_mem()` exists is to handle this sort 
of alignment problem since the caller can ensure that the destination memory 
address is aligned properly for intended use. But whenever you use 
`odp_packet_offset()` or similar routines there's no guarantee that the address 
you get back will have any particular alignment associated with it. Packets may 
start out aligned, but once head push/pull operations are issued all bets are 
off. 

Applications are responsible for keeping track of this sort of thing 
themselves, but for ODP internal use we have to be prepared for packets that 
have been manipulated in such a way that individual byte offsets may start on 
any byte boundary.

> Dmitry Eremin-Solenikov(lumag) wrote:
> Hmm. Should we create a list of all possible unaligned access locations?


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> OK, I see what you're saying now. But it looks like we need to consider 
>> both. The `odd_offset` parameter is saying whether the (continued) checksum 
>> needs to insert a leading zero into the calculation, however it's still true 
>> that you have to take into account whether `p` is even or odd since that can 
>> also vary independently. You can't fetch a `uint16_t` value from an odd byte 
>> address unless your CPU supports unaligned data accesses. Even for those 
>> machines that do, this typically results in a significant performance 
>> penalty.
>> 
>> But now we have another problem. If at entry `p` is even and `odd_offset` is 
>> true, meaning that the previous segment contained an odd number of bytes, 
>> then assuming this buffer is `{c, d, e, ...}` and we've added in `{0, c}` to 
>> account for the `odd_offset`, the next 16-bit value we want to sum is `{d, 
>> e}`, but `d` is on an odd address and `e` is on an even address so we can't 
>> fetch them as a `uint16_t` but need to assemble them from two `uint8_t` 
>> values. So it sounds like we need to factor out the logic required to fetch 
>> the next 16 bits to sum from the main loop:
>> ```
>> static inline uint16_t data16(void *p) 
>> {
>> if ((uintptr_t)p % 2)
>> return (*((uint8_t *)p) << 8) + (*((uint8_t *)p + 1));
>> 
>> return *((uint16_t *)p);
>> }
>> ```
>> This can then be added to the main logic:
>> ```
>> static uint32_t _odp_chksum_ones_comp_16_32(const void *p, uint32_t len, 
>> odp_bool_t odd_offset)
>> {
>> void  *data = p;
>> uint32_t sum = 0;
>> 
>> if (len > 0 && odd_offset) {
>>sum = *((uint8_t *)data++);
>>len--;
>> }
>> 
>> while (len > 1) {
>> sum += data16(data);
>> data += 2;
>> len -= 2;
>> }
>> 
>>...etc.
>> }
>> ```


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Calculation of checksum starts at `l4_offset`. If for some reason this 
>>> segment has odd amount of bytes after `l4_offset`, then checksumming will 
>>> use that byte as `{b, 0}` `uint16_t` value. However calculation of checksum 
>>> for the next segment (with first bytes `{c, d, e...}`) can not start as 
>>> usual (`{c ,d}`, `{e, }). It should start as `{0, c}`, `{d, e}`,  
>>> This is an odd offset. An offset in checksum calculation bytestream. Feel 
>>> free to propose better name.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 What offset? The calculation is for `len` bytes starting at address `p`. 
 Whether `p` is the address of an even or odd offset in its containing 
 packet is irrelevant since what matters is whether `p` itself is even or 
 odd, which is an independent question.


> Dmitry Eremin-Solenikov(lumag) wrote:
> Calculation starts at address p, but an offset inside packet might be odd 
> or even. If it is odd, we need to accomodate. Consider the code that uses 
> it.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> The calculation starts from the address passed in as `p`. Whether that 
>> address is odd or even doesn't need a separate parameter to determine. 
>> The various ODP packet routines that return packet addresses, with the 
>> exception of `odp_packet_align()`, make no guarantees as to the 
>> alignment of any address they return.



Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
Hmm. Should we create a list of all possible unaligned access locations?

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> OK, I see what you're saying now. But it looks like we need to consider both. 
> The `odd_offset` parameter is saying whether the (continued) checksum needs 
> to insert a leading zero into the calculation, however it's still true that 
> you have to take into account whether `p` is even or odd since that can also 
> vary independently. You can't fetch a `uint16_t` value from an odd byte 
> address unless your CPU supports unaligned data accesses. Even for those 
> machines that do, this typically results in a significant performance penalty.
> 
> But now we have another problem. If at entry `p` is even and `odd_offset` is 
> true, meaning that the previous segment contained an odd number of bytes, 
> then assuming this buffer is `{c, d, e, ...}` and we've added in `{0, c}` to 
> account for the `odd_offset`, the next 16-bit value we want to sum is `{d, 
> e}`, but `d` is on an odd address and `e` is on an even address so we can't 
> fetch them as a `uint16_t` but need to assemble them from two `uint8_t` 
> values. So it sounds like we need to factor out the logic required to fetch 
> the next 16 bits to sum from the main loop:
> ```
> static inline uint16_t data16(void *p) 
> {
> if ((uintptr_t)p % 2)
> return (*((uint8_t *)p) << 8) + (*((uint8_t *)p + 1));
> 
> return *((uint16_t *)p);
> }
> ```
> This can then be added to the main logic:
> ```
> static uint32_t _odp_chksum_ones_comp_16_32(const void *p, uint32_t len, 
> odp_bool_t odd_offset)
> {
> void  *data = p;
> uint32_t sum = 0;
> 
> if (len > 0 && odd_offset) {
>sum = *((uint8_t *)data++);
>len--;
> }
> 
> while (len > 1) {
> sum += data16(data);
> data += 2;
> len -= 2;
> }
> 
>...etc.
> }
> ```


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> Calculation of checksum starts at `l4_offset`. If for some reason this 
>> segment has odd amount of bytes after `l4_offset`, then checksumming will 
>> use that byte as `{b, 0}` `uint16_t` value. However calculation of checksum 
>> for the next segment (with first bytes `{c, d, e...}`) can not start as 
>> usual (`{c ,d}`, `{e, }). It should start as `{0, c}`, `{d, e}`,  
>> This is an odd offset. An offset in checksum calculation bytestream. Feel 
>> free to propose better name.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> What offset? The calculation is for `len` bytes starting at address `p`. 
>>> Whether `p` is the address of an even or odd offset in its containing 
>>> packet is irrelevant since what matters is whether `p` itself is even or 
>>> odd, which is an independent question.


 Dmitry Eremin-Solenikov(lumag) wrote:
 Calculation starts at address p, but an offset inside packet might be odd 
 or even. If it is odd, we need to accomodate. Consider the code that uses 
 it.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The calculation starts from the address passed in as `p`. Whether that 
> address is odd or even doesn't need a separate parameter to determine. 
> The various ODP packet routines that return packet addresses, with the 
> exception of `odp_packet_align()`, make no guarantees as to the alignment 
> of any address they return.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> This is true. I'll fix this issue.


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Yes. However depending on the endianness of the host, it should be 
>>> converted to a different host u16 value. It is a pair `{0, proto}`. On 
>>> BE it becomes just `proto` u16, on LE it is equal to `proto << 8`.


 Dmitry Eremin-Solenikov(lumag) wrote:
 sorry. odd_offset references to an offset inside the packet. If you 
 start calculating checksum from odd offset, you have to insert 
 additional 0.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The protocol field in the pseudo-header is simply the 8-bit IP 
> protocol field considered as a 16-bit value. It's also in network 
> byte order so these two have the same 

Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
OK, I see what you're saying now. But it looks like we need to consider both. 
The `odd_offset` parameter is saying whether the (continued) checksum needs to 
insert a leading zero into the calculation, however it's still true that you 
have to take into account whether `p` is even or odd since that can also vary 
independently. You can't fetch a `uint16_t` value from an odd byte address 
unless your CPU supports unaligned data accesses. Even for those machines that 
do, this typically results in a significant performance penalty.

But now we have another problem. If at entry `p` is even and `odd_offset` is 
true, meaning that the previous segment contained an odd number of bytes, then 
assuming this buffer is `{c, d, e, ...}` and we've added in `{0, c}` to account 
for the `odd_offset`, the next 16-bit value we want to sum is `{d, e}`, but `d` 
is on an odd address and `e` is on an even address so we can't fetch them as a 
`uint16_t` but need to assemble them from two `uint8_t` values. So it sounds 
like we need to factor out the logic required to fetch the next 16 bits to sum 
from the main loop:
```
static inline uint16_t data16(void *p) 
{
if ((uintptr_t)p % 2)
return (*((uint8_t *)p) << 8) + (*((uint8_t *)p + 1));

return *((uint16_t *)p);
}
```
This can then be added to the main logic:
```
static uint32_t _odp_chksum_ones_comp_16_32(const void *p, uint32_t len, 
odp_bool_t odd_offset)
{
void  *data = p;
uint32_t sum = 0;

if (len > 0 && odd_offset) {
   sum = *((uint8_t *)data++);
   len--;
}

while (len > 1) {
sum += data16(data);
data += 2;
len -= 2;
}

   ...etc.
}
```

> Dmitry Eremin-Solenikov(lumag) wrote:
> Calculation of checksum starts at `l4_offset`. If for some reason this 
> segment has odd amount of bytes after `l4_offset`, then checksumming will use 
> that byte as `{b, 0}` `uint16_t` value. However calculation of checksum for 
> the next segment (with first bytes `{c, d, e...}`) can not start as usual 
> (`{c ,d}`, `{e, }). It should start as `{0, c}`, `{d, e}`,  This is 
> an odd offset. An offset in checksum calculation bytestream. Feel free to 
> propose better name.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> What offset? The calculation is for `len` bytes starting at address `p`. 
>> Whether `p` is the address of an even or odd offset in its containing packet 
>> is irrelevant since what matters is whether `p` itself is even or odd, which 
>> is an independent question.


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Calculation starts at address p, but an offset inside packet might be odd 
>>> or even. If it is odd, we need to accomodate. Consider the code that uses 
>>> it.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 The calculation starts from the address passed in as `p`. Whether that 
 address is odd or even doesn't need a separate parameter to determine. The 
 various ODP packet routines that return packet addresses, with the 
 exception of `odp_packet_align()`, make no guarantees as to the alignment 
 of any address they return.


> Dmitry Eremin-Solenikov(lumag) wrote:
> This is true. I'll fix this issue.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> Yes. However depending on the endianness of the host, it should be 
>> converted to a different host u16 value. It is a pair `{0, proto}`. On 
>> BE it becomes just `proto` u16, on LE it is equal to `proto << 8`.


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> sorry. odd_offset references to an offset inside the packet. If you 
>>> start calculating checksum from odd offset, you have to insert 
>>> additional 0.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 The protocol field in the pseudo-header is simply the 8-bit IP 
 protocol field considered as a 16-bit value. It's also in network byte 
 order so these two have the same bit value.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> I don't understand that response. Can you elaborate?


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> Yes, but the adding word is not (proto is the lat byte 

Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
Calculation of checksum starts at `l4_offset`. If for some reason this segment 
has odd amount of bytes after `l4_offset`, then checksumming will use that byte 
as `{b, 0}` `uint16_t` value. However calculation of checksum for the next 
segment (with first bytes `{c, d, e...}`) can not start as usual (`{c ,d}`, 
`{e, }). It should start as `{0, c}`, `{d, e}`,  This is an odd offset. 
An offset in checksum calculation bytestream. Feel free to propose better name.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> What offset? The calculation is for `len` bytes starting at address `p`. 
> Whether `p` is the address of an even or odd offset in its containing packet 
> is irrelevant since what matters is whether `p` itself is even or odd, which 
> is an independent question.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> Calculation starts at address p, but an offset inside packet might be odd or 
>> even. If it is odd, we need to accomodate. Consider the code that uses it.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The calculation starts from the address passed in as `p`. Whether that 
>>> address is odd or even doesn't need a separate parameter to determine. The 
>>> various ODP packet routines that return packet addresses, with the 
>>> exception of `odp_packet_align()`, make no guarantees as to the alignment 
>>> of any address they return.


 Dmitry Eremin-Solenikov(lumag) wrote:
 This is true. I'll fix this issue.


> Dmitry Eremin-Solenikov(lumag) wrote:
> Yes. However depending on the endianness of the host, it should be 
> converted to a different host u16 value. It is a pair `{0, proto}`. On BE 
> it becomes just `proto` u16, on LE it is equal to `proto << 8`.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> sorry. odd_offset references to an offset inside the packet. If you 
>> start calculating checksum from odd offset, you have to insert 
>> additional 0.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The protocol field in the pseudo-header is simply the 8-bit IP protocol 
>>> field considered as a 16-bit value. It's also in network byte order so 
>>> these two have the same bit value.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 I don't understand that response. Can you elaborate?


> Dmitry Eremin-Solenikov(lumag) wrote:
> Yes, but the adding word is not (proto is the lat byte in pseudo 
> header).


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> It is an offset insite packet.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `ipv4->proto` is a `uint8_t` field here, so why is this needed? 
> These are the same independent of endianness.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 This erroneously increments `data` by 2 when you want to 
 increment it by 1 here so that it points to `p + 1`, not `p + 
 2`. Correct is `data = (const uint16_t *)((uintptr_t)p + 1);`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The `odd_offset` parameter is unnecessary here. What matters 
> is whether `p` starts on an even or odd byte boundary since 
> that determines whether you can fetch `data` as `uint16_t` 
> quantities without making unaligned storage references. Each 
> call to `_odp_chksum_ones_comp16_32()` is independent in this 
> regard, so it must always be determined anew for each call.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `if (len > 1 && (uintptr_t)p % 2) ...`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop use of `odd_offset` as 

Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
sorry. odd_offset references to an offset inside the packet. If you start 
calculating checksum from odd offset, you have to insert additional 0.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The protocol field in the pseudo-header is simply the 8-bit IP protocol field 
> considered as a 16-bit value. It's also in network byte order so these two 
> have the same bit value.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> I don't understand that response. Can you elaborate?


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Yes, but the adding word is not (proto is the lat byte in pseudo header).


 Dmitry Eremin-Solenikov(lumag) wrote:
 It is an offset insite packet.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These 
>>> are the same independent of endianness.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> This erroneously increments `data` by 2 when you want to increment 
>> it by 1 here so that it points to `p + 1`, not `p + 2`. Correct is 
>> `data = (const uint16_t *)((uintptr_t)p + 1);`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The `odd_offset` parameter is unnecessary here. What matters is 
>>> whether `p` starts on an even or odd byte boundary since that 
>>> determines whether you can fetch `data` as `uint16_t` quantities 
>>> without making unaligned storage references. Each call to 
>>> `_odp_chksum_ones_comp16_32()` is independent in this regard, so it 
>>> must always be determined anew for each call.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `if (len > 1 && (uintptr_t)p % 2) ...`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop use of `odd_offset` as noted earlier.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Checkpatch flag:
>> ```
>> WARNING: line over 80 characters
>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>> +ip_proto = parse_ipv4(prs, , , 
>> frame_len, chksums);
>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>> ```


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r162241315
updated_at 2018-01-18 03:23:35


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/odp_packet.c
line 85
@@ -2052,6 +2083,18 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += ihl * 4;
*parseptr += ihl * 4;
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)>src_addr,
+   2 * _ODP_IPV4ADDR_LEN, false);
+#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+   l4_part_sum += ipv4->proto;
+#else
+   l4_part_sum += ((uint16_t)ipv4->proto) << 8;
+#endif


Comment:
Yes. However depending on the endianness of the host, it should be converted to 
a different host u16 value. It is a pair `{0, proto}`. On BE it becomes just 
`proto` u16, on LE it is equal to `proto << 8`.

> Dmitry Eremin-Solenikov(lumag) wrote:
> sorry. odd_offset references to an offset inside the packet. If you start 
> calculating checksum from odd offset, you have to insert additional 0.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> The protocol field in the pseudo-header is simply the 8-bit IP protocol 
>> field considered as a 16-bit value. It's also in network byte order so these 
>> two have the same bit value.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> I don't understand that response. Can you elaborate?


 Dmitry Eremin-Solenikov(lumag) wrote:
 Yes, but the adding word is not (proto is the lat byte in pseudo header).


> Dmitry Eremin-Solenikov(lumag) wrote:
> It is an offset insite packet.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `ipv4->proto` is a `uint8_t` field here, so why is this needed? These 
 are the same independent of endianness.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> This erroneously increments `data` by 2 when you want to increment 
>>> it by 1 here so that it points to `p + 1`, not `p + 2`. Correct is 
>>> `data = (const uint16_t *)((uintptr_t)p + 1);`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 The `odd_offset` parameter is unnecessary here. What matters is 
 whether `p` starts on an even or odd byte boundary since that 
 determines whether you can fetch `data` as `uint16_t` quantities 
 without making unaligned storage references. Each call to 
 `_odp_chksum_ones_comp16_32()` is independent in this regard, so 
 it must always be determined anew for each call.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `if (len > 1 && (uintptr_t)p % 2) ...`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop use of `odd_offset` as noted earlier.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Checkpatch flag:
>>> ```
>>> WARNING: line over 80 characters
>>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>>> +   ip_proto = parse_ipv4(prs, , , 
>>> frame_len, chksums);
>>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>>> ```


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 2018


https://github.com/Linaro/odp/pull/389#discussion_r162241718
updated_at 2018-01-18 03:28:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 85
@@ -2052,6 +2083,18 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += ihl * 4;
*parseptr += ihl * 4;
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)>src_addr,
+   2 * _ODP_IPV4ADDR_LEN, false);
+#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+   l4_part_sum += ipv4->proto;
+#else
+   l4_part_sum += ((uint16_t)ipv4->proto) << 8;
+#endif


Comment:
The protocol field in the pseudo-header is simply the 8-bit IP protocol field 
considered as a 16-bit value. It's also in network byte order so these two have 
the same bit value.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> I don't understand that response. Can you elaborate?


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> Yes, but the adding word is not (proto is the lat byte in pseudo header).


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> It is an offset insite packet.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These 
>> are the same independent of endianness.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> This erroneously increments `data` by 2 when you want to increment it 
> by 1 here so that it points to `p + 1`, not `p + 2`. Correct is `data 
> = (const uint16_t *)((uintptr_t)p + 1);`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> The `odd_offset` parameter is unnecessary here. What matters is 
>> whether `p` starts on an even or odd byte boundary since that 
>> determines whether you can fetch `data` as `uint16_t` quantities 
>> without making unaligned storage references. Each call to 
>> `_odp_chksum_ones_comp16_32()` is independent in this regard, so it 
>> must always be determined anew for each call.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `if (len > 1 && (uintptr_t)p % 2) ...`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop use of `odd_offset` as noted earlier.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Checkpatch flag:
> ```
> WARNING: line over 80 characters
> #102: FILE: platform/linux-generic/odp_packet.c:2204:
> + ip_proto = parse_ipv4(prs, , , 
> frame_len, chksums);
> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
> ```


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r162233042
updated_at 2018-01-18 02:15:45


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
Calculation starts at address p, but an offset inside packet might be odd or 
even. If it is odd, we need to accomodate. Consider the code that uses it.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The calculation starts from the address passed in as `p`. Whether that 
> address is odd or even doesn't need a separate parameter to determine. The 
> various ODP packet routines that return packet addresses, with the exception 
> of `odp_packet_align()`, make no guarantees as to the alignment of any 
> address they return.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> This is true. I'll fix this issue.


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Yes. However depending on the endianness of the host, it should be 
>>> converted to a different host u16 value. It is a pair `{0, proto}`. On BE 
>>> it becomes just `proto` u16, on LE it is equal to `proto << 8`.


 Dmitry Eremin-Solenikov(lumag) wrote:
 sorry. odd_offset references to an offset inside the packet. If you start 
 calculating checksum from odd offset, you have to insert additional 0.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The protocol field in the pseudo-header is simply the 8-bit IP protocol 
> field considered as a 16-bit value. It's also in network byte order so 
> these two have the same bit value.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> I don't understand that response. Can you elaborate?


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Yes, but the adding word is not (proto is the lat byte in pseudo 
>>> header).


 Dmitry Eremin-Solenikov(lumag) wrote:
 It is an offset insite packet.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `ipv4->proto` is a `uint8_t` field here, so why is this needed? 
>>> These are the same independent of endianness.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> This erroneously increments `data` by 2 when you want to 
>> increment it by 1 here so that it points to `p + 1`, not `p + 
>> 2`. Correct is `data = (const uint16_t *)((uintptr_t)p + 1);`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The `odd_offset` parameter is unnecessary here. What matters is 
>>> whether `p` starts on an even or odd byte boundary since that 
>>> determines whether you can fetch `data` as `uint16_t` 
>>> quantities without making unaligned storage references. Each 
>>> call to `_odp_chksum_ones_comp16_32()` is independent in this 
>>> regard, so it must always be determined anew for each call.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `if (len > 1 && (uintptr_t)p % 2) ...`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop use of `odd_offset` as noted earlier.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Checkpatch flag:
>> ```
>> WARNING: line over 80 characters
>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>> +ip_proto = parse_ipv4(prs, , , 
>> frame_len, chksums);
>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>> ```


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r162245601
updated_at 2018-01-18 04:09:04


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-18 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
I don't understand that response. Can you elaborate?

> Dmitry Eremin-Solenikov(lumag) wrote:
> Yes, but the adding word is not (proto is the lat byte in pseudo header).


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> It is an offset insite packet.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These are 
> the same independent of endianness.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 This erroneously increments `data` by 2 when you want to increment it 
 by 1 here so that it points to `p + 1`, not `p + 2`. Correct is `data 
 = (const uint16_t *)((uintptr_t)p + 1);`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The `odd_offset` parameter is unnecessary here. What matters is 
> whether `p` starts on an even or odd byte boundary since that 
> determines whether you can fetch `data` as `uint16_t` quantities 
> without making unaligned storage references. Each call to 
> `_odp_chksum_ones_comp16_32()` is independent in this regard, so it 
> must always be determined anew for each call.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `if (len > 1 && (uintptr_t)p % 2) ...`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop use of `odd_offset` as noted earlier.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Checkpatch flag:
 ```
 WARNING: line over 80 characters
 #102: FILE: platform/linux-generic/odp_packet.c:2204:
 +  ip_proto = parse_ipv4(prs, , , 
 frame_len, chksums);
 total: 0 errors, 1 warnings, 0 checks, 163 lines checked
 ```


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> 2018


https://github.com/Linaro/odp/pull/389#discussion_r162231240
updated_at 2018-01-18 02:15:45


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
It is an offset insite packet.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These are 
>>> the same independent of endianness.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> This erroneously increments `data` by 2 when you want to increment it by 
>> 1 here so that it points to `p + 1`, not `p + 2`. Correct is `data = 
>> (const uint16_t *)((uintptr_t)p + 1);`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The `odd_offset` parameter is unnecessary here. What matters is whether 
>>> `p` starts on an even or odd byte boundary since that determines 
>>> whether you can fetch `data` as `uint16_t` quantities without making 
>>> unaligned storage references. Each call to 
>>> `_odp_chksum_ones_comp16_32()` is independent in this regard, so it 
>>> must always be determined anew for each call.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `if (len > 1 && (uintptr_t)p % 2) ...`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop use of `odd_offset` as noted earlier.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Checkpatch flag:
>> ```
>> WARNING: line over 80 characters
>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>> +ip_proto = parse_ipv4(prs, , , 
>> frame_len, chksums);
>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>> ```


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161940611
updated_at 2018-01-17 02:10:12


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/odp_packet.c
line 85
@@ -2052,6 +2083,18 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += ihl * 4;
*parseptr += ihl * 4;
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)>src_addr,
+   2 * _ODP_IPV4ADDR_LEN, false);
+#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+   l4_part_sum += ipv4->proto;
+#else
+   l4_part_sum += ((uint16_t)ipv4->proto) << 8;
+#endif


Comment:
Yes, but the adding word is not (proto is the lat byte in pseudo header).

> Dmitry Eremin-Solenikov(lumag) wrote:
> It is an offset insite packet.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `ipv4->proto` is a `uint8_t` field here, so why is this needed? These are 
 the same independent of endianness.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> This erroneously increments `data` by 2 when you want to increment it 
>>> by 1 here so that it points to `p + 1`, not `p + 2`. Correct is `data = 
>>> (const uint16_t *)((uintptr_t)p + 1);`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 The `odd_offset` parameter is unnecessary here. What matters is 
 whether `p` starts on an even or odd byte boundary since that 
 determines whether you can fetch `data` as `uint16_t` quantities 
 without making unaligned storage references. Each call to 
 `_odp_chksum_ones_comp16_32()` is independent in this regard, so it 
 must always be determined anew for each call.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `if (len > 1 && (uintptr_t)p % 2) ...`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop use of `odd_offset` as noted earlier.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Checkpatch flag:
>>> ```
>>> WARNING: line over 80 characters
>>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>>> +   ip_proto = parse_ipv4(prs, , , 
>>> frame_len, chksums);
>>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>>> ```


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 2018


https://github.com/Linaro/odp/pull/389#discussion_r161940706
updated_at 2018-01-17 02:11:01


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 160
@@ -2155,14 +2212,35 @@ static inline void parse_tcp(packet_parser_t *prs,
 /**
  * Parser helper function for UDP
  */
-static inline void parse_udp(packet_parser_t *prs,
-const uint8_t **parseptr, uint32_t *offset)
+static inline void parse_udp(packet_parser_t *prs, const uint8_t **parseptr,
+uint32_t *offset, odp_proto_chksums_t chksums)
 {
const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr;
uint32_t udplen = odp_be_to_cpu_16(udp->length);
 
-   if (odp_unlikely(udplen < sizeof(_odp_udphdr_t)))
+   if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) {
prs->error_flags.udp_err = 1;
+   return;
+   }
+
+   if (chksums.chksum.udp &&
+   !prs->input_flags.ipfrag) {
+   if (udp->chksum == 0) {
+   prs->input_flags.l4_chksum_done =
+   (prs->input_flags.ipv4 != 1);
+   prs->error_flags.l4_chksum =
+   (prs->input_flags.ipv4 != 1);
+   } else {
+   prs->input_flags.l4_chksum_done = 1;
+   prs->l4_part_sum += udp->length;
+   /* Do not include checksum into partial sum */
+   prs->l4_part_sum += _odp_chksum_ones_comp16_32(
+   (const void *)udp,
+   _ODP_UDPHDR_LEN - 2,
+   false);


Comment:
Drop last parameter (`odd_offset`)

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These are 
>> the same independent of endianness.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop last parameter (`odd_offset`)


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> This erroneously increments `data` by 2 when you want to increment it by 
> 1 here so that it points to `p + 1`, not `p + 2`. Correct is `data = 
> (const uint16_t *)((uintptr_t)p + 1);`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> The `odd_offset` parameter is unnecessary here. What matters is whether 
>> `p` starts on an even or odd byte boundary since that determines whether 
>> you can fetch `data` as `uint16_t` quantities without making unaligned 
>> storage references. Each call to `_odp_chksum_ones_comp16_32()` is 
>> independent in this regard, so it must always be determined anew for 
>> each call.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `if (len > 1 && (uintptr_t)p % 2) ...`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop use of `odd_offset` as noted earlier.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Checkpatch flag:
> ```
> WARNING: line over 80 characters
> #102: FILE: platform/linux-generic/odp_packet.c:2204:
> + ip_proto = parse_ipv4(prs, , , 
> frame_len, chksums);
> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
> ```


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161937032
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 85
@@ -2052,6 +2083,18 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += ihl * 4;
*parseptr += ihl * 4;
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)>src_addr,
+   2 * _ODP_IPV4ADDR_LEN, false);
+#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+   l4_part_sum += ipv4->proto;
+#else
+   l4_part_sum += ((uint16_t)ipv4->proto) << 8;
+#endif


Comment:
`ipv4->proto` is a `uint8_t` field here, so why is this needed? These are the 
same independent of endianness.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> This erroneously increments `data` by 2 when you want to increment it by 1 
>>> here so that it points to `p + 1`, not `p + 2`. Correct is `data = (const 
>>> uint16_t *)((uintptr_t)p + 1);`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 The `odd_offset` parameter is unnecessary here. What matters is whether 
 `p` starts on an even or odd byte boundary since that determines whether 
 you can fetch `data` as `uint16_t` quantities without making unaligned 
 storage references. Each call to `_odp_chksum_ones_comp16_32()` is 
 independent in this regard, so it must always be determined anew for each 
 call.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `if (len > 1 && (uintptr_t)p % 2) ...`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop use of `odd_offset` as noted earlier.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Checkpatch flag:
>>> ```
>>> WARNING: line over 80 characters
>>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>>> +   ip_proto = parse_ipv4(prs, , , 
>>> frame_len, chksums);
>>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>>> ```


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 2018


https://github.com/Linaro/odp/pull/389#discussion_r161936805
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 121
@@ -2099,6 +2144,18 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += sizeof(_odp_ipv6hdr_t);
*parseptr += sizeof(_odp_ipv6hdr_t);
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)(uintptr_t)>src_addr,
+   2 * _ODP_IPV6ADDR_LEN, false);
+#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+   l4_part_sum += ipv6->next_hdr;
+#else
+   l4_part_sum += ((uint16_t)ipv6->next_hdr) << 8;
+#endif


Comment:
Again `ipv6->next_hdr` is a `uint8_t` field, so is endian-neutral.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `ipv4->proto` is a `uint8_t` field here, so why is this needed? These are the 
> same independent of endianness.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop last parameter (`odd_offset`)


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop last parameter (`odd_offset`)


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 This erroneously increments `data` by 2 when you want to increment it by 1 
 here so that it points to `p + 1`, not `p + 2`. Correct is `data = (const 
 uint16_t *)((uintptr_t)p + 1);`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The `odd_offset` parameter is unnecessary here. What matters is whether 
> `p` starts on an even or odd byte boundary since that determines whether 
> you can fetch `data` as `uint16_t` quantities without making unaligned 
> storage references. Each call to `_odp_chksum_ones_comp16_32()` is 
> independent in this regard, so it must always be determined anew for each 
> call.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `if (len > 1 && (uintptr_t)p % 2) ...`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop use of `odd_offset` as noted earlier.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Checkpatch flag:
 ```
 WARNING: line over 80 characters
 #102: FILE: platform/linux-generic/odp_packet.c:2204:
 +  ip_proto = parse_ipv4(prs, , , 
 frame_len, chksums);
 total: 0 errors, 1 warnings, 0 checks, 163 lines checked
 ```


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161936908
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 80
@@ -2052,6 +2083,18 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += ihl * 4;
*parseptr += ihl * 4;
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)>src_addr,
+   2 * _ODP_IPV4ADDR_LEN, false);


Comment:
Drop last parameter (`odd_offset`)

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> This erroneously increments `data` by 2 when you want to increment it by 1 
> here so that it points to `p + 1`, not `p + 2`. Correct is `data = (const 
> uint16_t *)((uintptr_t)p + 1);`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> The `odd_offset` parameter is unnecessary here. What matters is whether `p` 
>> starts on an even or odd byte boundary since that determines whether you can 
>> fetch `data` as `uint16_t` quantities without making unaligned storage 
>> references. Each call to `_odp_chksum_ones_comp16_32()` is independent in 
>> this regard, so it must always be determined anew for each call.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> `if (len > 1 && (uintptr_t)p % 2) ...`


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Drop use of `odd_offset` as noted earlier.


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Checkpatch flag:
> ```
> WARNING: line over 80 characters
> #102: FILE: platform/linux-generic/odp_packet.c:2204:
> + ip_proto = parse_ipv4(prs, , , frame_len, 
> chksums);
> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
> ```


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161935977
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 116
@@ -2099,6 +2144,18 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, 
const uint8_t **parseptr,
*offset   += sizeof(_odp_ipv6hdr_t);
*parseptr += sizeof(_odp_ipv6hdr_t);
 
+   if (chksums.chksum.udp || chksums.chksum.tcp) {
+   l4_part_sum = _odp_chksum_ones_comp16_32(
+   (const uint16_t *)(uintptr_t)>src_addr,
+   2 * _ODP_IPV6ADDR_LEN, false);


Comment:
Drop last parameter (`odd_offset`)

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop last parameter (`odd_offset`)


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> This erroneously increments `data` by 2 when you want to increment it by 1 
>> here so that it points to `p + 1`, not `p + 2`. Correct is `data = (const 
>> uint16_t *)((uintptr_t)p + 1);`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> The `odd_offset` parameter is unnecessary here. What matters is whether `p` 
>>> starts on an even or odd byte boundary since that determines whether you 
>>> can fetch `data` as `uint16_t` quantities without making unaligned storage 
>>> references. Each call to `_odp_chksum_ones_comp16_32()` is independent in 
>>> this regard, so it must always be determined anew for each call.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 `if (len > 1 && (uintptr_t)p % 2) ...`


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop use of `odd_offset` as noted earlier.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Checkpatch flag:
>> ```
>> WARNING: line over 80 characters
>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>> +ip_proto = parse_ipv4(prs, , , 
>> frame_len, chksums);
>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>> ```


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161936047
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 31
@@ -1948,6 +1949,35 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, 
odp_packet_t dstpkt)
return dst_uarea_size < src_uarea_size;
 }
 
+static uint16_t packet_sum_ones_comp16(odp_packet_hdr_t *pkt_hdr,
+  uint32_t offset,
+  uint32_t len)
+{
+   uint32_t sum = pkt_hdr->p.l4_part_sum;
+   odp_bool_t odd_offset = false;
+
+   if (offset + len > pkt_hdr->frame_len)
+   return 0;
+
+   while (len > 0) {
+   uint32_t seglen = 0; /* GCC */
+   void *mapaddr = packet_map(pkt_hdr, offset, , NULL);
+
+   if (seglen < len)
+   seglen = len;
+
+   len -= seglen;
+   sum += _odp_chksum_ones_comp16_32(mapaddr, seglen, odd_offset);
+   odd_offset ^= (seglen % 2);


Comment:
Drop use of `odd_offset` as noted earlier.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Checkpatch flag:
> ```
> WARNING: line over 80 characters
> #102: FILE: platform/linux-generic/odp_packet.c:2204:
> + ip_proto = parse_ipv4(prs, , , frame_len, 
> chksums);
> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
> ```


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161932843
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 35
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)
+
+{
+   uint32_t sum = 0;
+   const uint16_t *data = p;
+
+   if (odd_offset) {
+   uint16_t left_over = 0;
+
+   *(uint8_t *)_over = *(const uint8_t *)data;
+   sum = left_over;
+   data++;


Comment:
This erroneously increments `data` by 2 when you want to increment it by 1 here 
so that it points to `p + 1`, not `p + 2`. Correct is `data = (const uint16_t 
*)((uintptr_t)p + 1);`

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> The `odd_offset` parameter is unnecessary here. What matters is whether `p` 
> starts on an even or odd byte boundary since that determines whether you can 
> fetch `data` as `uint16_t` quantities without making unaligned storage 
> references. Each call to `_odp_chksum_ones_comp16_32()` is independent in 
> this regard, so it must always be determined anew for each call.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> `if (len > 1 && (uintptr_t)p % 2) ...`


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Drop use of `odd_offset` as noted earlier.


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 Checkpatch flag:
 ```
 WARNING: line over 80 characters
 #102: FILE: platform/linux-generic/odp_packet.c:2204:
 +  ip_proto = parse_ipv4(prs, , , frame_len, 
 chksums);
 total: 0 errors, 1 warnings, 0 checks, 163 lines checked
 ```


> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161935049
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 24
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)


Comment:
The `odd_offset` parameter is unnecessary here. What matters is whether `p` 
starts on an even or odd byte boundary since that determines whether you can 
fetch `data` as `uint16_t` quantities without making unaligned storage 
references. Each call to `_odp_chksum_ones_comp16_32()` is independent in this 
regard, so it must always be determined anew for each call.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `if (len > 1 && (uintptr_t)p % 2) ...`


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Drop use of `odd_offset` as noted earlier.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Checkpatch flag:
>>> ```
>>> WARNING: line over 80 characters
>>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>>> +   ip_proto = parse_ipv4(prs, , , frame_len, 
>>> chksums);
>>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>>> ```


 Bill Fischofer(Bill-Fischofer-Linaro) wrote:
 2018


https://github.com/Linaro/odp/pull/389#discussion_r161934743
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-16 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 30
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP checksum - implementation internal
+ */
+
+#ifndef ODP_CHKSUM_INTERNAL_H_
+#define ODP_CHKSUM_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple implementation of ones complement sum.
+ * Based on RFC1071 and its errata.
+ */
+static uint32_t _odp_chksum_ones_comp16_32(const void *p, uint32_t len,
+  odp_bool_t odd_offset)
+
+{
+   uint32_t sum = 0;
+   const uint16_t *data = p;
+
+   if (odd_offset) {


Comment:
`if (len > 1 && (uintptr_t)p % 2) ...`

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> Drop use of `odd_offset` as noted earlier.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Checkpatch flag:
>> ```
>> WARNING: line over 80 characters
>> #102: FILE: platform/linux-generic/odp_packet.c:2204:
>> +ip_proto = parse_ipv4(prs, , , frame_len, 
>> chksums);
>> total: 0 errors, 1 warnings, 0 checks, 163 lines checked
>> ```


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161933918
updated_at 2018-01-17 01:41:46


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-14 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_packet.c
line 182
@@ -2191,7 +2201,7 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const 
uint8_t *parseptr,
switch (ethtype) {
case _ODP_ETHTYPE_IPV4:
prs->input_flags.ipv4 = 1;
-   ip_proto = parse_ipv4(prs, , , frame_len);
+   ip_proto = parse_ipv4(prs, , , frame_len, 
chksums);


Comment:
Checkpatch flag:
```
WARNING: line over 80 characters
#102: FILE: platform/linux-generic/odp_packet.c:2204:
+   ip_proto = parse_ipv4(prs, , , frame_len, 
chksums);
total: 0 errors, 1 warnings, 0 checks, 163 lines checked
```

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> 2018


https://github.com/Linaro/odp/pull/389#discussion_r161403118
updated_at 2018-01-14 16:39:22


Re: [lng-odp] [PATCH v3][WIP] Validate checksums during packet parsing

2018-01-14 Thread Github ODP bot
Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/include/odp_chksum_internal.h
line 1
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Linaro Limited


Comment:
2018

https://github.com/Linaro/odp/pull/389#discussion_r161402959
updated_at 2018-01-14 16:39:21