diff options
author | Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org> | 2018-04-02 22:52:11 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2018-04-18 17:39:25 +0300 |
commit | 2c99a9dc1978c9178e711d264aaaca2bc4702352 (patch) | |
tree | 1e00ce0e7991d9aea69c0397a760a063bac8cfd4 | |
parent | 88ba35773c76c871a222fe48a0dac05765c39936 (diff) |
linux-gen: packet: IPv4 checksum insertion
Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r-- | platform/linux-generic/include/odp_packet_internal.h | 2 | ||||
-rw-r--r-- | platform/linux-generic/odp_ipsec.c | 65 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet.c | 58 |
3 files changed, 64 insertions, 61 deletions
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 75b4ce9e5..cb1c3849b 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -303,6 +303,8 @@ int _odp_packet_set_data(odp_packet_t pkt, uint32_t offset, int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset, const void *s, uint32_t len); +int _odp_packet_ipv4_chksum_insert(odp_packet_t pkt); + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 1e90cea0f..65f7361b9 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -162,67 +162,10 @@ static odp_ipsec_packet_result_t *ipsec_pkt_result(odp_packet_t packet) return &packet_hdr(packet)->ipsec_ctx; } -static inline int _odp_ipv4_csum(odp_packet_t pkt, - uint32_t offset, - _odp_ipv4hdr_t *ip, - odp_u16sum_t *chksum) -{ - unsigned nleft = _ODP_IPV4HDR_IHL(ip->ver_ihl) * 4; - uint16_t buf[nleft / 2]; - int res; - - if (odp_unlikely(nleft < sizeof(*ip))) - return -1; - ip->chksum = 0; - memcpy(buf, ip, sizeof(*ip)); - res = odp_packet_copy_to_mem(pkt, offset + sizeof(*ip), - nleft - sizeof(*ip), - buf + sizeof(*ip) / 2); - if (odp_unlikely(res < 0)) - return res; - - *chksum = ~odp_chksum_ones_comp16(buf, nleft); - - return 0; -} - -#define _ODP_IPV4HDR_CSUM_OFFSET ODP_OFFSETOF(_odp_ipv4hdr_t, chksum) #define _ODP_IPV4HDR_PROTO_OFFSET ODP_OFFSETOF(_odp_ipv4hdr_t, proto) #define _ODP_IPV6HDR_NHDR_OFFSET ODP_OFFSETOF(_odp_ipv6hdr_t, next_hdr) #define _ODP_IPV6HDREXT_NHDR_OFFSET ODP_OFFSETOF(_odp_ipv6hdr_ext_t, next_hdr) -/** - * Calculate and fill in IPv4 checksum - * - * @param pkt ODP packet - * - * @retval 0 on success - * @retval <0 on failure - */ -static inline int _odp_ipv4_csum_update(odp_packet_t pkt) -{ - uint32_t offset; - _odp_ipv4hdr_t ip; - odp_u16sum_t chksum; - int res; - - offset = odp_packet_l3_offset(pkt); - if (offset == ODP_PACKET_OFFSET_INVALID) - return -1; - - res = odp_packet_copy_to_mem(pkt, offset, sizeof(ip), &ip); - if (odp_unlikely(res < 0)) - return res; - - res = _odp_ipv4_csum(pkt, offset, &ip, &chksum); - if (odp_unlikely(res < 0)) - return res; - - return odp_packet_copy_from_mem(pkt, - offset + _ODP_IPV4HDR_CSUM_OFFSET, - 2, &chksum); -} - #define ipv4_hdr_len(ip) (_ODP_IPV4HDR_IHL((ip)->ver_ihl) * 4) static const uint8_t ipsec_padding[255] = { @@ -815,7 +758,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt, ipv4hdr->tot_len = _odp_cpu_to_be_16(state.ip_tot_len); else ipv4hdr->ttl -= ipsec_sa->dec_ttl; - _odp_ipv4_csum_update(pkt); + _odp_packet_ipv4_chksum_insert(pkt); } else if (state.is_ipv6 && odp_packet_len(pkt) > _ODP_IPV6HDR_LEN) { _odp_ipv6hdr_t *ipv6hdr = odp_packet_l3_ptr(pkt, NULL); @@ -1238,7 +1181,7 @@ static int ipsec_out_esp(odp_packet_t *pkt, static void ipsec_out_esp_post(ipsec_state_t *state, odp_packet_t pkt) { if (state->is_ipv4) - _odp_ipv4_csum_update(pkt); + _odp_packet_ipv4_chksum_insert(pkt); } static int ipsec_out_ah(odp_packet_t *pkt, @@ -1343,7 +1286,7 @@ static void ipsec_out_ah_post(ipsec_state_t *state, odp_packet_t pkt) ipv4hdr->tos = state->ah_ipv4.tos; ipv4hdr->frag_offset = state->ah_ipv4.frag_offset; - _odp_ipv4_csum_update(pkt); + _odp_packet_ipv4_chksum_insert(pkt); } else { _odp_ipv6hdr_t *ipv6hdr = odp_packet_l3_ptr(pkt, NULL); @@ -1500,7 +1443,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt, else if (ODP_IPSEC_AH == ipsec_sa->proto) ipsec_out_ah_post(&state, pkt); - _odp_ipv4_csum_update(pkt); + _odp_packet_ipv4_chksum_insert(pkt); *pkt_out = pkt; return ipsec_sa; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 462c8a4c7..8170c8125 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2266,6 +2266,64 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, seg_len, layer, ethtype); } +static inline int packet_ipv4_chksum(odp_packet_t pkt, + uint32_t offset, + _odp_ipv4hdr_t *ip, + odp_u16sum_t *chksum) +{ + unsigned int nleft = _ODP_IPV4HDR_IHL(ip->ver_ihl) * 4; + uint16_t buf[nleft / 2]; + int res; + + if (odp_unlikely(nleft < sizeof(*ip))) + return -1; + ip->chksum = 0; + memcpy(buf, ip, sizeof(*ip)); + res = odp_packet_copy_to_mem(pkt, offset + sizeof(*ip), + nleft - sizeof(*ip), + buf + sizeof(*ip) / 2); + if (odp_unlikely(res < 0)) + return res; + + *chksum = ~odp_chksum_ones_comp16(buf, nleft); + + return 0; +} + +#define _ODP_IPV4HDR_CSUM_OFFSET ODP_OFFSETOF(_odp_ipv4hdr_t, chksum) + +/** + * Calculate and fill in IPv4 checksum + * + * @param pkt ODP packet + * + * @retval 0 on success + * @retval <0 on failure + */ +int _odp_packet_ipv4_chksum_insert(odp_packet_t pkt) +{ + uint32_t offset; + _odp_ipv4hdr_t ip; + odp_u16sum_t chksum; + int res; + + offset = odp_packet_l3_offset(pkt); + if (offset == ODP_PACKET_OFFSET_INVALID) + return -1; + + res = odp_packet_copy_to_mem(pkt, offset, sizeof(ip), &ip); + if (odp_unlikely(res < 0)) + return res; + + res = packet_ipv4_chksum(pkt, offset, &ip, &chksum); + if (odp_unlikely(res < 0)) + return res; + + return odp_packet_copy_from_mem(pkt, + offset + _ODP_IPV4HDR_CSUM_OFFSET, + 2, &chksum); +} + /** * Simple packet parser */ |