When decrementing TTL the IPv4 checksum can be incrementally updated.
Signed-off-by: Matias Elo <[email protected]>
---
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