When decrementing TTL the IPv4 checksum can be incrementally updated. Signed-off-by: Matias Elo <matias....@nokia.com> --- example/l3fwd/odp_l3fwd.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/example/l3fwd/odp_l3fwd.c b/example/l3fwd/odp_l3fwd.c index 44778b0..95c3d85 100644 --- a/example/l3fwd/odp_l3fwd.c +++ b/example/l3fwd/odp_l3fwd.c @@ -158,6 +158,22 @@ static void setup_fwd_db(void) } } +/** + * Decrement TTL and incrementally update checksum + * + * @param ip IPv4 header + */ +static inline void ipv4_dec_ttl_csum_update(odph_ipv4hdr_t *ip) +{ + uint16_t a = ~odp_cpu_to_be_16(1 << 8); + + ip->ttl--; + if (ip->chksum >= a) + ip->chksum -= a; + else + ip->chksum += odp_cpu_to_be_16(1 << 8); +} + static int l3fwd_pkt_hash(odp_packet_t pkt, int sif) { fwd_db_entry_t *entry; @@ -186,8 +202,7 @@ static int l3fwd_pkt_hash(odp_packet_t pkt, int sif) key.dst_port = 0; } entry = find_fwd_db_entry(&key); - ip->ttl--; - ip->chksum = odph_ipv4_csum_update(pkt); + ipv4_dec_ttl_csum_update(ip); eth = odp_packet_l2_ptr(pkt, NULL); if (entry) { eth->src = entry->src_mac; @@ -211,8 +226,7 @@ static int l3fwd_pkt_lpm(odp_packet_t pkt, int sif) int ret; ip = odp_packet_l3_ptr(pkt, &len); - ip->ttl--; - ip->chksum = odph_ipv4_csum_update(pkt); + ipv4_dec_ttl_csum_update(ip); eth = odp_packet_l2_ptr(pkt, NULL); /* network byte order maybe different from host */ -- 2.7.4