From 573b1fff25af70492deb9e59c0b48d77b0c1ed03 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Sat, 13 Aug 2016 02:11:13 +0300 Subject: trafgen: ipv4: Update csum at runtime if needed Handle 'field_changed' callback to check if IPv4 csum is needed to be recalculated, if so - update it on 'packet_update' event. Added 'is_csum_valid' to proto_hdr struct to check if csum needs to be updated. Signed-off-by: Vadim Kochan Signed-off-by: Tobias Klauser --- trafgen_l3.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'trafgen_l3.c') diff --git a/trafgen_l3.c b/trafgen_l3.c index 2eabef1..9bb0de9 100644 --- a/trafgen_l3.c +++ b/trafgen_l3.c @@ -43,6 +43,30 @@ static void ipv4_header_init(struct proto_hdr *hdr) proto_field_set_default_dev_ipv4(hdr, IP4_SADDR); } +static void ipv4_field_changed(struct proto_field *field) +{ + field->hdr->is_csum_valid = false; +} + +static void ipv4_csum_update(struct proto_hdr *hdr) +{ + struct packet *pkt; + uint16_t csum; + + if (hdr->is_csum_valid) + return; + if (proto_field_is_set(hdr, IP4_CSUM)) + return; + + pkt = packet_get(hdr->pkt_id); + + proto_field_set_default_u16(hdr, IP4_CSUM, 0); + csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], hdr->len)); + proto_field_set_default_u16(hdr, IP4_CSUM, bswap_16(csum)); + + hdr->is_csum_valid = true; +} + static void ipv4_packet_finish(struct proto_hdr *hdr) { struct packet *pkt = current_packet(); @@ -51,12 +75,7 @@ static void ipv4_packet_finish(struct proto_hdr *hdr) total_len = pkt->len - hdr->pkt_offset; proto_field_set_default_be16(hdr, IP4_LEN, total_len); - if (!proto_field_is_set(hdr, IP4_CSUM)) { - uint16_t csum; - - csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], hdr->len)); - proto_field_set_u16(hdr, IP4_CSUM, bswap_16(csum)); - } + ipv4_csum_update(hdr); } static void ipv4_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) @@ -90,6 +109,8 @@ static const struct proto_ops ipv4_proto_ops = { .id = PROTO_IP4, .layer = PROTO_L3, .header_init = ipv4_header_init, + .packet_update = ipv4_csum_update, + .field_changed = ipv4_field_changed, .packet_finish = ipv4_packet_finish, .set_next_proto = ipv4_set_next_proto, }; -- cgit v1.2.3-54-g00ecf