Skip to content

Commit

Permalink
* In case of IPv6 ICMP errors parse thru inner payload
Browse files Browse the repository at this point in the history
  and frame the flow key.
Closes-bug:#1542207

Change-Id: I66793922b0bba02c43c9eebde86bafa7e8035e9e

Fix Agent UT failures

Fix failures in test_pkt_flowv6 and test_sg_flowv6
For ICMPv6 protocol set the ICMP type as ECHO_REQUEST and
lookup of ICMPv6 flows should be done with destination port
as ECHO_REPLY

(cherry picked from commit 4e6f8c92e80ab0a69dcd8ef710a77fbf7372d152)
Closes-Bug: #1550727
Change-Id: I89c2137fcaac812bcfb517c7c3aa531b2fed5421
  • Loading branch information
naveen-n authored and praveenkv committed Mar 2, 2016
1 parent d302707 commit 2789e04
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 18 deletions.
15 changes: 15 additions & 0 deletions src/vnsw/agent/pkt/pkt_handler.cc
Expand Up @@ -454,6 +454,21 @@ int PktHandler::ParseIpPacket(PktInfo *pkt_info, PktType::Type &pkt_type,
icmp->icmp6_type == ICMP6_ECHO_REPLY) {
pkt_info->dport = ICMP6_ECHO_REPLY;
pkt_info->sport = htons(icmp->icmp6_id);
} else if (IsFlowPacket(pkt_info) &&
icmp->icmp6_type < ICMP6_ECHO_REQUEST) {
//Agent has to look at inner payload
//and recalculate the parameter
//Handle this only for packets requiring flow miss
ParseIpPacket(pkt_info, pkt_type, pkt + len + sizeof(icmp));
//Swap the key parameter, which would be used as key
IpAddress 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_ICMPV6) {
uint16_t port = pkt_info->sport;
pkt_info->sport = pkt_info->dport;
pkt_info->dport = port;
}
} else {
pkt_info->sport = 0;
}
Expand Down
26 changes: 11 additions & 15 deletions src/vnsw/agent/pkt/test/test_flow_util.h
Expand Up @@ -178,7 +178,7 @@ class TestFlowPkt {
};

bool FlowStatus(bool active) {
FlowEntry *fe = FlowGet(vrf_, sip_, dip_, proto_, sport_, dport_, nh_id_);
FlowEntry * fe = FlowFetch();
if (fe == NULL || fe->deleted()) {
return !active;
}
Expand All @@ -201,35 +201,31 @@ class TestFlowPkt {
WAIT_FOR(1000, 3000, FlowStatus(true));

//Get flow
FlowEntry *fe = FlowGet(vrf_, sip_, dip_, proto_, sport_, dport_,
nh_id_);
FlowEntry * fe = FlowFetch();
EXPECT_TRUE(fe != NULL);
return fe;
};

void Delete() {
FlowKey key;
key.nh = nh_id_;
key.src_addr = IpAddress::from_string(sip_);
key.dst_addr = IpAddress::from_string(dip_);
key.src_port = sport_;
key.dst_port = dport_;
key.protocol = proto_;
key.family = Address::INET;

if (Agent::GetInstance()->pkt()->get_flow_proto()->Find(key) == NULL) {
FlowEntry * fe = FlowFetch();
if (fe == NULL) {
return;
}

TaskScheduler *scheduler = TaskScheduler::GetInstance();
FlowDeleteTask * task = new FlowDeleteTask(key);
FlowDeleteTask * task = new FlowDeleteTask(fe->key());
scheduler->Enqueue(task);

WAIT_FOR(1000, 3000, FlowStatus(false));
};

FlowEntry *FlowFetch() {
FlowEntry *fe = FlowGet(vrf_, sip_, dip_, proto_, sport_, dport_, nh_id_);
uint16_t lookup_dport = dport_;
if (proto_ == IPPROTO_ICMPV6) {
lookup_dport = ICMP6_ECHO_REPLY;
}
FlowEntry *fe = FlowGet(vrf_, sip_, dip_, proto_, sport_, lookup_dport,
nh_id_);
return fe;
}

Expand Down
4 changes: 2 additions & 2 deletions src/vnsw/agent/pkt/test/test_pkt_util.cc
Expand Up @@ -219,7 +219,7 @@ void MakeIp6Packet(PktGen *pkt, int ifindex, const char *sip, const char *dip,
pkt->AddEthHdr("00:00:5E:00:01:00", "00:00:00:00:00:01", ETHERTYPE_IPV6);
pkt->AddIp6Hdr(sip, dip, proto);
if (proto == IPPROTO_ICMPV6) {
pkt->AddIcmpHdr();
pkt->AddIcmp6Hdr();
}
}

Expand Down Expand Up @@ -304,7 +304,7 @@ void MakeIp6MplsPacket(PktGen *pkt, int ifindex, const char *out_sip,
pkt->AddMplsHdr(label, true);
pkt->AddIp6Hdr(sip, dip, proto);
if (proto == IPPROTO_ICMPV6) {
pkt->AddIcmpHdr();
pkt->AddIcmp6Hdr();
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/vnsw/agent/pkt/test/test_sg_flowv6.cc
Expand Up @@ -412,7 +412,11 @@ class SgTestV6 : public ::testing::Test {
bool ValidateAction(uint32_t vrfid, char *sip, char *dip, int proto, int sport,
int dport, int action, uint32_t nh_id) {
bool ret = true;
FlowEntry *fe = FlowGet(vrfid, sip, dip, proto, sport, dport, nh_id);
uint16_t lookup_dport = dport;
if (proto == IPPROTO_ICMPV6) {
lookup_dport = ICMP6_ECHO_REPLY;
}
FlowEntry *fe = FlowGet(vrfid, sip, dip, proto, sport, lookup_dport, nh_id);
FlowEntry *rfe = fe->reverse_flow_entry();

EXPECT_TRUE((fe->match_p().sg_action & (1 << action)) != 0);
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/test/pkt_gen.h
Expand Up @@ -9,6 +9,7 @@
#include <netinet/ip.h>
#include <net/ethernet.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>

#include <pkt/pkt_handler.h>
#include <vr_interface.h>
Expand Down Expand Up @@ -352,6 +353,13 @@ class PktGen {
len += sizeof(struct icmp) + len;
};

void AddIcmp6Hdr(uint8_t type=ICMP6_ECHO_REQUEST) {
struct icmp6_hdr *icmp = (struct icmp6_hdr *)(buff + len);
icmp->icmp6_type = type;
icmp->icmp6_code = 0;
len += sizeof(struct icmp6_hdr) + len;
};

void AddGreHdr(uint16_t proto) {
GreHdr *gre = (GreHdr *)(buff + len);
gre->flags = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/vnsw/agent/test/test_util.cc
Expand Up @@ -2837,6 +2837,9 @@ bool FlowDelete(const string &vrf_name, const char *sip, const char *dip,
key.dst_addr = IpAddress::from_string(dip);
key.src_port = sport;
key.dst_port = dport;
if (proto == IPPROTO_ICMPV6) {
key.dst_port = ICMP6_ECHO_REPLY;
}
key.protocol = proto;
key.family = key.src_addr.is_v4() ? Address::INET : Address::INET6;

Expand Down

0 comments on commit 2789e04

Please sign in to comment.