Skip to content

Commit

Permalink
* Whenever ICMP error packet is trapped for flow setup,
Browse files Browse the repository at this point in the history
  parse the inner payload and frame the flow key.
  Test case for same
Closes-bug:#1423848

Change-Id: I9c088888487b45bcf3ef34156adb64a83260264c
  • Loading branch information
naveen-n committed Apr 3, 2015
1 parent 15be7ac commit a856fa4
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 2 deletions.
16 changes: 16 additions & 0 deletions src/vnsw/agent/pkt/pkt_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,22 @@ uint8_t *PktHandler::ParseIpPacket(PktInfo *pkt_info,
if (icmp->type == ICMP_ECHO || icmp->type == ICMP_ECHOREPLY) {
pkt_info->dport = ICMP_ECHOREPLY;
pkt_info->sport = htons(icmp->un.echo.id);
} else if ((pkt_info->agent_hdr.cmd == AGENT_TRAP_FLOW_MISS ||
pkt_info->agent_hdr.cmd == AGENT_TRAP_ECMP_RESOLVE) &&
(icmp->type == ICMP_DEST_UNREACH ||
icmp->type == ICMP_TIME_EXCEEDED)) {
//Agent has to look at inner payload
//and recalculate the parameter
ParseIpPacket(pkt_info, pkt_type, pkt + sizeof(icmphdr));
//Swap the key parameter, which would be used as key
uint32_t src_ip = pkt_info->ip_saddr;
pkt_info->ip_saddr = pkt_info->ip_daddr;
pkt_info->ip_daddr = src_ip;
if (pkt_info->ip_proto != IPPROTO_ICMP) {
uint16_t port = pkt_info->sport;
pkt_info->sport = pkt_info->dport;
pkt_info->dport = port;
}
} else {
pkt_info->sport = 0;
}
Expand Down
56 changes: 56 additions & 0 deletions src/vnsw/agent/pkt/test/test_pkt_flow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3452,6 +3452,62 @@ TEST_F(FlowTest, FlowPolicyUuid_16) {
client->WaitForIdle();
}

TEST_F(FlowTest, FlowIcmpError_1) {
//Send a ICMP error packet with payload
//of icmp, verify flow is setup properly
TxIpIcmpErrorPacket(flow1->id(), vm1_ip, vm2_ip, IPPROTO_ICMP, 1000, 0,
10, flow1->vrf()->vrf_id(), ICMP_DEST_UNREACH);
client->WaitForIdle();

uint32_t vrf_id = VrfGet("vrf5")->vrf_id();
uint32_t nh_id = flow0->flow_key_nh()->id();
uint32_t rev_nh_id = flow1->flow_key_nh()->id();

FlowEntry *fe = FlowGet(vrf_id, vm1_ip, vm2_ip, IPPROTO_ICMP, 1000, 0, nh_id);
EXPECT_TRUE(fe != NULL);

FlowEntry *rfe = FlowGet(vrf_id, vm2_ip, vm1_ip, IPPROTO_ICMP, 1000, 0, rev_nh_id);
EXPECT_TRUE(rfe != NULL);
}

TEST_F(FlowTest, FlowIcmpError_2) {
//Send a ICMP error packet with payload
//of UDP, verify flow is setup properly
TxIpIcmpErrorPacket(flow1->id(), vm1_ip, vm2_ip, IPPROTO_UDP, 10, 20,
11, flow1->vrf()->vrf_id(), ICMP_DEST_UNREACH);
client->WaitForIdle();

uint32_t vrf_id = VrfGet("vrf5")->vrf_id();
uint32_t nh_id = flow0->flow_key_nh()->id();
uint32_t rev_nh_id = flow1->flow_key_nh()->id();

FlowEntry *fe = FlowGet(vrf_id, vm1_ip, vm2_ip, IPPROTO_UDP, 10, 20, nh_id);
EXPECT_TRUE(fe != NULL);

FlowEntry *rfe = FlowGet(vrf_id, vm2_ip, vm1_ip, IPPROTO_UDP, 20, 10,
rev_nh_id);
EXPECT_TRUE(rfe != NULL);
}

TEST_F(FlowTest, FlowIcmpError_3) {
//Send a ICMP error packet with payload
//of TCP, verify flow is setup properly
TxIpIcmpErrorPacket(flow1->id(), vm1_ip, vm2_ip, IPPROTO_TCP, 10, 20,
12, flow1->vrf()->vrf_id(), ICMP_TIME_EXCEEDED);
client->WaitForIdle();

uint32_t vrf_id = VrfGet("vrf5")->vrf_id();
uint32_t nh_id = flow0->flow_key_nh()->id();
uint32_t rev_nh_id = flow1->flow_key_nh()->id();

FlowEntry *fe = FlowGet(vrf_id, vm1_ip, vm2_ip, IPPROTO_TCP, 10, 20, nh_id);
EXPECT_TRUE(fe != NULL);

FlowEntry *rfe = FlowGet(vrf_id, vm2_ip, vm1_ip, IPPROTO_TCP, 20, 10,
rev_nh_id);
EXPECT_TRUE(rfe != NULL);
}

int main(int argc, char *argv[]) {
GETUSERARGS();

Expand Down
26 changes: 26 additions & 0 deletions src/vnsw/agent/pkt/test/test_pkt_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,29 @@ void TxTcpMplsPacket(int ifindex, const char *out_sip,
delete pkt;
}

void TxIpIcmpErrorPacket(int ifindex, const char *sip, const char *dip,
int proto, uint16_t sport, uint16_t dport,
int hash_id, int vrf, int icmp_err) {
PktGen *pkt = new PktGen();

pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
pkt->AddAgentHdr(ifindex, AGENT_TRAP_FLOW_MISS, hash_id, vrf) ;
pkt->AddEthHdr("00:00:5E:00:01:00", "00:00:00:00:00:01", 0x800);
pkt->AddIpHdr(dip, sip, 1);
pkt->AddIcmpHdr(icmp_err, 0);

pkt->AddIpHdr(sip, dip, proto);
if (proto == IPPROTO_ICMP) {
pkt->AddIcmpHdr(ICMP_ECHO, sport);
} else if (proto == IPPROTO_TCP) {
pkt->AddTcpHdr(sport, dport, false, false, true, 64);
} else if (proto == IPPROTO_UDP) {
pkt->AddUdpHdr(sport, dport, 64);
}
uint8_t *ptr(new uint8_t[pkt->GetBuffLen()]);
memcpy(ptr, pkt->GetBuff(), pkt->GetBuffLen());
Agent::GetInstance()->pkt()->pkt_handler()->HandleRcvPkt(ptr,
pkt->GetBuffLen(),
pkt->GetBuffLen());
delete pkt;
}
4 changes: 3 additions & 1 deletion src/vnsw/agent/pkt/test/test_pkt_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,7 @@ extern void TxTcpMplsPacket(int ifindex, const char *out_sip,
const char *out_dip, uint32_t label,
const char *sip, const char *dip, uint16_t sport,
uint16_t dport, bool ack, int hash_id = 1);

void TxIpIcmpErrorPacket(int ifindex, const char *sip, const char *dip,
int proto, uint16_t sport, uint16_t dport,
int hash_id, int vrf, int icmp_err);
#endif // __TEST_PKT_UTIL_H__
10 changes: 9 additions & 1 deletion src/vnsw/agent/test/pkt_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,17 @@ class PktGen {
struct icmphdr *icmp = (struct icmphdr *)(buff + len);
icmp->type = 0;
icmp->un.echo.id = 0;
len += sizeof(icmphdr) + len;
len += sizeof(icmphdr);
};

void AddIcmpHdr(uint8_t type, uint16_t id) {
struct icmphdr *icmp = (struct icmphdr *)(buff + len);
icmp->type = type;
icmp->un.echo.id = htons(id);
len += sizeof(icmphdr);
};


void AddGreHdr(uint16_t proto) {
GreHdr *gre = (GreHdr *)(buff + len);
gre->flags = 0;
Expand Down

0 comments on commit a856fa4

Please sign in to comment.