From 42bd7ddcf68897f9cede4099052cf162ea396404 Mon Sep 17 00:00:00 2001 From: Divakar Date: Fri, 27 May 2016 15:15:23 +0530 Subject: [PATCH] Manipulating the TTL of the Packet Right now the TTL of the packet is not overwritten by Vrouter. It is only decremented like a hop, for the required packets. But BGP packets in VM (due to BGP as service), can come to Vrouter to with ttl of 1. In a multi hop environment, we require this ttl to be more than 1. For this purpose flow entry is added with another ttl field and if Agent sets this, vrouter unconditionally sets this ttl in the packet and calculates the checksum again. partial-bug: #1567586 Change-Id: I53a192666731f4c3662e3791006dd7294bccf116 --- dp-core/vr_flow.c | 21 +++++++++++++++++++++ dp-core/vr_proto_ip.c | 3 ++- include/vr_flow.h | 4 ++-- include/vr_packet.h | 8 +++++++- sandesh/vr.sandesh | 1 + utils/flow.c | 1 + 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index 2d690c3d2..a91bc01d7 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -222,6 +222,7 @@ __vr_flow_reset_entry(struct vrouter *router, struct vr_flow_entry *fe) fe->fe_flags &= (VR_FLOW_FLAG_ACTIVE | VR_FLOW_FLAG_EVICTED | VR_FLOW_FLAG_NEW_FLOW | VR_FLOW_FLAG_DELETE_MARKED); + fe->fe_ttl = 0; return; } @@ -778,6 +779,8 @@ vr_flow_action(struct vrouter *router, struct vr_flow_entry *fe, struct vr_forwarding_md *fmd) { int valid_src; + unsigned int ip_inc_diff_cksum = 0; + struct vr_ip *ip; flow_result_t result; @@ -861,6 +864,22 @@ vr_flow_action(struct vrouter *router, struct vr_flow_entry *fe, break; } + if (result == FLOW_FORWARD) { + if (pkt->vp_type == VP_TYPE_IP) { + ip = (struct vr_ip *)pkt_network_header(pkt); + if (ip) { + if (fe->fe_ttl && (fe->fe_ttl != ip->ip_ttl)) { + vr_incremental_diff(ip->ip_ttl, fe->fe_ttl, &ip_inc_diff_cksum); + ip->ip_ttl = fe->fe_ttl; + + if (ip_inc_diff_cksum) + vr_ip_incremental_csum(ip, ip_inc_diff_cksum); + } + } + } + } + + if (fe->fe_tcp_flags & VR_FLOW_TCP_DEAD) vr_flow_mark_evict(router, fe, index); @@ -1956,6 +1975,8 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req) fe->fe_action = req->fr_action; } + fe->fe_ttl = req->fr_ttl; + if (fe->fe_action == VR_FLOW_ACTION_DROP) fe->fe_drop_reason = (uint8_t)req->fr_drop_reason; diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index f5ae578b2..1f6d133b1 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -97,7 +97,8 @@ vr_ip_update_csum(struct vr_packet *pkt, unsigned int ip_inc, unsigned int inc) unsigned short *csump; ip = (struct vr_ip *)pkt_network_header(pkt); - ip->ip_csum = vr_ip_csum(ip); + if (ip_inc) + vr_ip_incremental_csum(ip, ip_inc); if (ip->ip_proto == VR_IP_PROTO_TCP) { tcp = (struct vr_tcp *)((unsigned char *)ip + ip->ip_hl * 4); diff --git a/include/vr_flow.h b/include/vr_flow.h index c0c6a031a..bd8e2a666 100644 --- a/include/vr_flow.h +++ b/include/vr_flow.h @@ -301,7 +301,7 @@ struct vr_flow_queue { struct vr_dummy_flow_entry { vr_hentry_t fe_hentry; - uint8_t fe_pack_hentry; + uint8_t fe_ttl; int16_t fe_qos_id; struct vr_flow fe_key; uint8_t fe_gen_id; @@ -329,7 +329,7 @@ struct vr_dummy_flow_entry { /* do not change. any field positions as it might lead to incompatibility */ struct vr_flow_entry { vr_hentry_t fe_hentry; - uint8_t fe_pack_hentry; + uint8_t fe_ttl; int16_t fe_qos_id; struct vr_flow fe_key; uint8_t fe_gen_id; diff --git a/include/vr_packet.h b/include/vr_packet.h index 1c35f8dc7..3dbd11da7 100644 --- a/include/vr_packet.h +++ b/include/vr_packet.h @@ -412,7 +412,12 @@ vr_ip_incremental_csum(struct vr_ip *ip, unsigned int diff) { unsigned int csum; - diff &= 0xffff; + diff = (diff >> 16) + (diff & 0xffff); + if (diff >> 16) { + diff &= 0xffff; + diff += 1; + } + csum = ~(ip->ip_csum) & 0xffff; csum += diff; csum = (csum >> 16) + (csum & 0xffff); @@ -707,6 +712,7 @@ vr_ip_transport_header_valid(struct vr_ip *iph) } + #define VR_TCP_FLAG_FIN 0x0001 #define VR_TCP_FLAG_SYN 0x0002 #define VR_TCP_FLAG_RST 0x0004 diff --git a/sandesh/vr.sandesh b/sandesh/vr.sandesh index 1862b7055..76c46992b 100644 --- a/sandesh/vr.sandesh +++ b/sandesh/vr.sandesh @@ -191,6 +191,7 @@ buffer sandesh vr_flow_req { 36: i32 fr_oflow_entries; 37: byte fr_gen_id; 38: i16 fr_qos_id; + 39: byte fr_ttl; } buffer sandesh vr_vrf_assign_req { diff --git a/utils/flow.c b/utils/flow.c index 4cc4367b4..069bea332 100644 --- a/utils/flow.c +++ b/utils/flow.c @@ -1401,6 +1401,7 @@ flow_dump_table(struct flow_table *ft) printf(", %d, ", fe->fe_sec_mirror_id); } printf(" SPort %d", fe->fe_udp_src_port); + printf(" TTL %d", fe->fe_ttl); printf(")"); }