Skip to content

Commit

Permalink
Manipulating the TTL of the Packet
Browse files Browse the repository at this point in the history
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.

Change-Id: I4619e81ad324827e29dc487857020ddd9e429f2c
partial-bug: #1567586
  • Loading branch information
divakardhar committed Nov 8, 2016
1 parent 7f5e8b1 commit afbd37c
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 20 deletions.
21 changes: 21 additions & 0 deletions dp-core/vr_flow.c
Expand Up @@ -225,6 +225,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;
}
Expand Down Expand Up @@ -748,6 +749,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;

Expand Down Expand Up @@ -829,6 +832,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);

Expand Down Expand Up @@ -1900,6 +1919,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;

Expand Down
3 changes: 2 additions & 1 deletion dp-core/vr_proto_ip.c
Expand Up @@ -103,7 +103,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);
Expand Down
6 changes: 4 additions & 2 deletions include/vr_flow.h
Expand Up @@ -299,7 +299,8 @@ struct vr_flow_queue {

struct vr_dummy_flow_entry {
vr_hentry_t fe_hentry;
uint8_t fe_hentry_packing[3];
uint8_t fe_pack_hentry[2];
uint8_t fe_ttl;
struct vr_flow fe_key;
uint8_t fe_gen_id;
uint16_t fe_tcp_flags;
Expand All @@ -326,7 +327,8 @@ 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_hentry_packing[3];
uint8_t fe_pack_hentry[2];
uint8_t fe_ttl;
struct vr_flow fe_key;
uint8_t fe_gen_id;
uint16_t fe_tcp_flags;
Expand Down
55 changes: 38 additions & 17 deletions include/vr_packet.h
Expand Up @@ -368,6 +368,44 @@ struct vr_ip {
unsigned int ip_daddr;
} __attribute__((packed));

static inline void
vr_incremental_diff(unsigned int oldval, unsigned int newval,
unsigned int *diff)
{
unsigned int tmp;

tmp = ~oldval + newval;
if (tmp < newval)
tmp += 1;

*diff += tmp;
if (*diff < tmp)
*diff += 1;

return;
}

static inline void
vr_ip_incremental_csum(struct vr_ip *ip, unsigned int diff)
{
unsigned int csum;

diff = (diff >> 16) + (diff & 0xffff);
if (diff >> 16) {
diff &= 0xffff;
diff += 1;
}

csum = ~(ip->ip_csum) & 0xffff;
csum += diff;
csum = (csum >> 16) + (csum & 0xffff);
if (csum >> 16)
csum = (csum & 0xffff) + 1;

ip->ip_csum = (~csum & 0xffff);
return;
}

#define SOURCE_LINK_LAYER_ADDRESS_OPTION 1
#define TARGET_LINK_LAYER_ADDRESS_OPTION 2

Expand Down Expand Up @@ -614,23 +652,6 @@ vr_ip_transport_header_valid(struct vr_ip *iph)
return true;
}

static inline void
vr_incremental_diff(unsigned int oldval, unsigned int newval,
unsigned int *diff)
{
unsigned int tmp;

tmp = ~oldval + newval;
if (tmp < newval)
tmp += 1;

*diff += tmp;
if (*diff < tmp)
*diff += 1;

return;
}

#define VR_TCP_FLAG_FIN 0x0001
#define VR_TCP_FLAG_SYN 0x0002
#define VR_TCP_FLAG_RST 0x0004
Expand Down
1 change: 1 addition & 0 deletions sandesh/vr.sandesh
Expand Up @@ -185,6 +185,7 @@ buffer sandesh vr_flow_req {
35: u32 fr_flow_stats_oflow;
36: i32 fr_oflow_entries;
37: byte fr_gen_id;
38: byte fr_ttl;
}

buffer sandesh vr_vrf_assign_req {
Expand Down
1 change: 1 addition & 0 deletions utils/flow.c
Expand Up @@ -534,6 +534,7 @@ 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(")");
}

Expand Down

0 comments on commit afbd37c

Please sign in to comment.