Message ID | 1398071709-5807-3-git-send-email-weilong.chen@linaro.org |
---|---|
State | Accepted |
Commit | d081f612b65a4d392aeb7e29469649852597a59f |
Headers | show |
Why is the checksum both set in the UDP header and returned? Isn't it better just to compute and return the checksum, then the caller can decide whether to set the checksum field in the header (and the caller is responsible for clearing this field before computing the checksum) or whether to just verify an existing checksum. On 21 April 2014 11:15, Weilong Chen <weilong.chen@linaro.org> wrote: > > Signed-off-by: Weilong Chen <weilong.chen@linaro.org> > --- > include/helper/odp_udp.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 49 insertions(+) > > diff --git a/include/helper/odp_udp.h b/include/helper/odp_udp.h > index 738470e..2070861 100644 > --- a/include/helper/odp_udp.h > +++ b/include/helper/odp_udp.h > @@ -33,6 +33,55 @@ typedef struct ODP_PACKED { > uint16be_t chksum; /**< UDP header and data checksum (0 if not used)*/ > } odp_udphdr_t; > > +static inline uint16be_t odp_ipv4_udp_chksum(odp_packet_t pkt) > +{ > + unsigned long sum = 0; > + odp_udphdr_t *udph; > + odp_ipv4hdr_t *iph; > + unsigned short *buf; > + unsigned short udplen; > + > + if (!odp_packet_l3_offset(pkt)) > + return 0; > + > + if (!odp_packet_l4_offset(pkt)) > + return 0; > + > + iph = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > + udph = (odp_udphdr_t *)odp_packet_l4(pkt); > + buf = (unsigned short *)udph; > + udplen = odp_be_to_cpu_16(udph->length); > + > + /* the source ip */ > + sum += (iph->src_addr >> 16) & 0xFFFF; > + sum += (iph->src_addr) & 0xFFFF; > + /* the dest ip */ > + sum += (iph->dst_addr >> 16) & 0xFFFF; > + sum += (iph->dst_addr) & 0xFFFF; > + sum += odp_cpu_to_be_16(ODP_IPPROTO_UDP); > + /* the length */ > + sum += udph->length; > + > + /* initialize checksum to 0 */ > + udph->chksum = 0; > + while (udplen > 1) { > + sum += *buf++; > + udplen -= 2; > + } > + /* if any bytes left, pad the bytes and add */ > + if (udplen > 0) > + sum += ((*buf)&odp_cpu_to_be_16(0xFF00)); > + > + /* Fold sum to 16 bits: add carrier to result */ > + while (sum >> 16) > + sum = (sum & 0xFFFF) + (sum >> 16); > + sum = ~sum; > + /* set computation result */ > + udph->chksum = ((unsigned short)sum == 0x0) ? 0xFFFF > + : (unsigned short)sum; > + > + return udph->chksum; > +} > > /** @internal Compile time assert */ > ODP_ASSERT(sizeof(odp_udphdr_t) == ODP_UDPHDR_LEN, ODP_UDPHDR_T__SIZE_ERROR); > -- > 1.7.9.5 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp
OK, Thanks! On 22 April 2014 21:37, Ola Liljedahl <ola.liljedahl@linaro.org> wrote: > Why is the checksum both set in the UDP header and returned? > Isn't it better just to compute and return the checksum, then the > caller can decide whether to set the checksum field in the header (and > the caller is responsible for clearing this field before computing the > checksum) or whether to just verify an existing checksum. > > > > On 21 April 2014 11:15, Weilong Chen <weilong.chen@linaro.org> wrote: > > > > Signed-off-by: Weilong Chen <weilong.chen@linaro.org> > > --- > > include/helper/odp_udp.h | 49 > ++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 49 insertions(+) > > > > diff --git a/include/helper/odp_udp.h b/include/helper/odp_udp.h > > index 738470e..2070861 100644 > > --- a/include/helper/odp_udp.h > > +++ b/include/helper/odp_udp.h > > @@ -33,6 +33,55 @@ typedef struct ODP_PACKED { > > uint16be_t chksum; /**< UDP header and data checksum (0 if not > used)*/ > > } odp_udphdr_t; > > > > +static inline uint16be_t odp_ipv4_udp_chksum(odp_packet_t pkt) > > +{ > > + unsigned long sum = 0; > > + odp_udphdr_t *udph; > > + odp_ipv4hdr_t *iph; > > + unsigned short *buf; > > + unsigned short udplen; > > + > > + if (!odp_packet_l3_offset(pkt)) > > + return 0; > > + > > + if (!odp_packet_l4_offset(pkt)) > > + return 0; > > + > > + iph = (odp_ipv4hdr_t *)odp_packet_l3(pkt); > > + udph = (odp_udphdr_t *)odp_packet_l4(pkt); > > + buf = (unsigned short *)udph; > > + udplen = odp_be_to_cpu_16(udph->length); > > + > > + /* the source ip */ > > + sum += (iph->src_addr >> 16) & 0xFFFF; > > + sum += (iph->src_addr) & 0xFFFF; > > + /* the dest ip */ > > + sum += (iph->dst_addr >> 16) & 0xFFFF; > > + sum += (iph->dst_addr) & 0xFFFF; > > + sum += odp_cpu_to_be_16(ODP_IPPROTO_UDP); > > + /* the length */ > > + sum += udph->length; > > + > > + /* initialize checksum to 0 */ > > + udph->chksum = 0; > > + while (udplen > 1) { > > + sum += *buf++; > > + udplen -= 2; > > + } > > + /* if any bytes left, pad the bytes and add */ > > + if (udplen > 0) > > + sum += ((*buf)&odp_cpu_to_be_16(0xFF00)); > > + > > + /* Fold sum to 16 bits: add carrier to result */ > > + while (sum >> 16) > > + sum = (sum & 0xFFFF) + (sum >> 16); > > + sum = ~sum; > > + /* set computation result */ > > + udph->chksum = ((unsigned short)sum == 0x0) ? 0xFFFF > > + : (unsigned short)sum; > > + > > + return udph->chksum; > > +} > > > > /** @internal Compile time assert */ > > ODP_ASSERT(sizeof(odp_udphdr_t) == ODP_UDPHDR_LEN, > ODP_UDPHDR_T__SIZE_ERROR); > > -- > > 1.7.9.5 > > > > > > _______________________________________________ > > lng-odp mailing list > > lng-odp@lists.linaro.org > > http://lists.linaro.org/mailman/listinfo/lng-odp >
diff --git a/include/helper/odp_udp.h b/include/helper/odp_udp.h index 738470e..2070861 100644 --- a/include/helper/odp_udp.h +++ b/include/helper/odp_udp.h @@ -33,6 +33,55 @@ typedef struct ODP_PACKED { uint16be_t chksum; /**< UDP header and data checksum (0 if not used)*/ } odp_udphdr_t; +static inline uint16be_t odp_ipv4_udp_chksum(odp_packet_t pkt) +{ + unsigned long sum = 0; + odp_udphdr_t *udph; + odp_ipv4hdr_t *iph; + unsigned short *buf; + unsigned short udplen; + + if (!odp_packet_l3_offset(pkt)) + return 0; + + if (!odp_packet_l4_offset(pkt)) + return 0; + + iph = (odp_ipv4hdr_t *)odp_packet_l3(pkt); + udph = (odp_udphdr_t *)odp_packet_l4(pkt); + buf = (unsigned short *)udph; + udplen = odp_be_to_cpu_16(udph->length); + + /* the source ip */ + sum += (iph->src_addr >> 16) & 0xFFFF; + sum += (iph->src_addr) & 0xFFFF; + /* the dest ip */ + sum += (iph->dst_addr >> 16) & 0xFFFF; + sum += (iph->dst_addr) & 0xFFFF; + sum += odp_cpu_to_be_16(ODP_IPPROTO_UDP); + /* the length */ + sum += udph->length; + + /* initialize checksum to 0 */ + udph->chksum = 0; + while (udplen > 1) { + sum += *buf++; + udplen -= 2; + } + /* if any bytes left, pad the bytes and add */ + if (udplen > 0) + sum += ((*buf)&odp_cpu_to_be_16(0xFF00)); + + /* Fold sum to 16 bits: add carrier to result */ + while (sum >> 16) + sum = (sum & 0xFFFF) + (sum >> 16); + sum = ~sum; + /* set computation result */ + udph->chksum = ((unsigned short)sum == 0x0) ? 0xFFFF + : (unsigned short)sum; + + return udph->chksum; +} /** @internal Compile time assert */ ODP_ASSERT(sizeof(odp_udphdr_t) == ODP_UDPHDR_LEN, ODP_UDPHDR_T__SIZE_ERROR);
Signed-off-by: Weilong Chen <weilong.chen@linaro.org> --- include/helper/odp_udp.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)