Skip to content

Commit

Permalink
Merge "* Try ARP request even when EVPN route is in wait for traffic …
Browse files Browse the repository at this point in the history
…mode" into R3.2
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Dec 10, 2016
2 parents dd977c0 + 22203d9 commit db38148
Show file tree
Hide file tree
Showing 21 changed files with 1,152 additions and 125 deletions.
3 changes: 3 additions & 0 deletions src/vnsw/agent/oper/agent_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@ bool AgentRoute::WaitForTraffic() const {
for(Route::PathList::const_iterator it = GetPathList().begin();
it != GetPathList().end(); it++) {
const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
if (path->peer() && path->peer()->GetType() == Peer::INET_EVPN_PEER) {
continue;
}
if (path->path_preference().wait_for_traffic() == true) {
return true;
}
Expand Down
9 changes: 9 additions & 0 deletions src/vnsw/agent/oper/evpn_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ EvpnRouteEntry *EvpnAgentRouteTable::FindRoute(const MacAddress &mac,
return route;
}

EvpnRouteEntry *EvpnAgentRouteTable::FindRouteNoLock(const MacAddress &mac,
const IpAddress &ip_addr,
uint32_t ethernet_tag) {
EvpnRouteKey key(NULL, vrf_name(), mac, ip_addr, ethernet_tag);
EvpnRouteEntry *route =
static_cast<EvpnRouteEntry *>(FindActiveEntryNoLock(&key));
return route;
}

EvpnRouteEntry *EvpnAgentRouteTable::FindRoute(const Agent *agent,
const string &vrf_name,
const MacAddress &mac,
Expand Down
3 changes: 3 additions & 0 deletions src/vnsw/agent/oper/evpn_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class EvpnAgentRouteTable : public AgentRouteTable {
uint32_t ethernet_tag);
EvpnRouteEntry *FindRoute(const MacAddress &mac, const IpAddress &ip_addr,
uint32_t ethernet_tag);
EvpnRouteEntry *FindRouteNoLock(const MacAddress &mac,
const IpAddress &ip_addr,
uint32_t ethernet_tag);
static EvpnRouteEntry *FindRoute(const Agent *agent,
const std::string &vrf_name,
const MacAddress &mac,
Expand Down
9 changes: 9 additions & 0 deletions src/vnsw/agent/pkt/flow_entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,15 @@ AgentRoute *FlowEntry::GetUcRoute(const VrfEntry *entry,
return rt;
}

AgentRoute *FlowEntry::GetEvpnRoute(const VrfEntry *vrf,
const MacAddress &mac,
const IpAddress &ip,
uint32_t ethernet_tag) {
EvpnAgentRouteTable *table = static_cast<EvpnAgentRouteTable *>(
vrf->GetEvpnRouteTable());
return table->FindRouteNoLock(mac, ip, ethernet_tag);
}

uint32_t FlowEntry::reverse_flow_fip() const {
FlowEntry *rflow = reverse_flow_entry_.get();
if (rflow) {
Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/flow_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ class FlowEntry {

static AgentRoute *GetL2Route(const VrfEntry *entry, const MacAddress &mac);
static AgentRoute *GetUcRoute(const VrfEntry *entry, const IpAddress &addr);
static AgentRoute *GetEvpnRoute(const VrfEntry *entry, const MacAddress &mac,
const IpAddress &addr, uint32_t ethernet_tag);
static const SecurityGroupList &default_sg_list() {
return default_sg_list_;
}
Expand Down
29 changes: 22 additions & 7 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,9 @@ void PktFlowInfo::GenerateTrafficSeen(const PktInfo *pkt,

// TODO : No need for one more route lookup
const AgentRoute *rt = NULL;
bool enqueue_traffic_seen = false;
const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(in->intf_);

IpAddress sip = pkt->ip_saddr;
if (pkt->family == Address::INET ||
pkt->family == Address::INET6) {
Expand All @@ -1551,16 +1554,28 @@ void PktFlowInfo::GenerateTrafficSeen(const PktInfo *pkt,
}
// Generate event if route was waiting for traffic
if (rt && rt->WaitForTraffic()) {
if (pkt->family == Address::INET) {
agent->oper_db()->route_preference_module()->EnqueueTrafficSeen
(sip, 32, in->intf_->id(), pkt->vrf, pkt->smac);
} else if (pkt->family == Address::INET6) {
agent->oper_db()->route_preference_module()->EnqueueTrafficSeen
(sip, 128, in->intf_->id(), pkt->vrf, pkt->smac);
enqueue_traffic_seen = true;
} else if (vm_intf) {
//L3 route is not in wait for traffic state
//EVPN route could be in wait for traffic, if yes
//enqueue traffic seen
rt = FlowEntry::GetEvpnRoute(in->vrf_, pkt->smac, sip,
vm_intf->ethernet_tag());
if (rt && rt->WaitForTraffic()) {
enqueue_traffic_seen = true;
}
}
}

if (enqueue_traffic_seen) {
uint8_t plen = 32;
if (pkt->family == Address::INET6) {
plen = 128;
}
flow_table->agent()->oper_db()->route_preference_module()->
EnqueueTrafficSeen(sip, plen, in->intf_->id(),
pkt->vrf, pkt->smac);
}
}

// Apply flow limits for in and out VMs
void PktFlowInfo::ApplyFlowLimits(const PktControlInfo *in,
Expand Down
29 changes: 29 additions & 0 deletions src/vnsw/agent/pkt/test/test_flow_add.cc
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,35 @@ TEST_F(FlowTest, FlowReval_1) {
client->WaitForIdle();
}

//Create a layer2 flow and verify that we dont add layer2 route
//in prefix length manipulation
TEST_F(FlowTest, WaitForTraffic) {
Ip4Address ip = Ip4Address::from_string(vm1_ip);
MacAddress mac(0, 0, 0, 1, 1, 1);

AgentRoute *ip_rt = RouteGet("vrf5", Ip4Address::from_string(vm1_ip), 32);
AgentRoute *evpn_Rt = EvpnRouteGet("vrf5", mac, ip, 0);

EXPECT_TRUE(ip_rt->WaitForTraffic() == true);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == true);

//Enqueue a flow with wrong mac address
TxL2Packet(flow0->id(),input[2].mac, input[1].mac,
input[0].addr, input[1].addr, 1);
client->WaitForIdle();
//Only IP route should goto wait for traffic
EXPECT_TRUE(ip_rt->WaitForTraffic() == false);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == true);

//Enqueue flow with right mac address
//EVPN route should also goto traffic seen state
TxL2Packet(flow0->id(),input[0].mac, input[1].mac,
input[0].addr, input[1].addr, 1);
client->WaitForIdle();
EXPECT_TRUE(ip_rt->WaitForTraffic() == false);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == false);
}

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

Expand Down
27 changes: 27 additions & 0 deletions src/vnsw/agent/pkt/test/test_pkt_flowv6.cc
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,33 @@ TEST_F(FlowTestV6, FlowAdd_5) {
EXPECT_EQ(2U, out_count);
}

TEST_F(FlowTestV6, FlowAdd_6) {
Ip6Address ip = Ip6Address::from_string(ip6_vm1_ip);
MacAddress mac(0, 0, 0, 1, 1, 1);

AgentRoute *ip_rt = RouteGetV6("vrf5", ip, 128);
AgentRoute *evpn_Rt = EvpnRouteGet("vrf5", mac, ip, 0);

EXPECT_TRUE(ip_rt->WaitForTraffic() == true);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == true);

//Enqueue a flow with wrong mac address
TxL2Ip6Packet(flow0->id(),input[2].mac, input[1].mac,
ip6_vm1_ip, ip6_vm2_ip, IPPROTO_ICMPV6);
client->WaitForIdle();
//Only IP route should goto wait for traffic
EXPECT_TRUE(ip_rt->WaitForTraffic() == false);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == true);

//Enqueue flow with right mac address
//EVPN route should also goto traffic seen state
TxL2Ip6Packet(flow0->id(),input[0].mac, input[1].mac,
ip6_vm1_ip, ip6_vm2_ip, IPPROTO_ICMPV6);
client->WaitForIdle();
EXPECT_TRUE(ip_rt->WaitForTraffic() == false);
EXPECT_TRUE(evpn_Rt->WaitForTraffic() == false);
}

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

Expand Down
22 changes: 22 additions & 0 deletions src/vnsw/agent/pkt/test/test_pkt_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,25 @@ void TxTcp6MplsPacket(int ifindex, const char *out_sip,
pkt->GetBuffLen());
delete pkt;
}

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

pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
pkt->AddAgentHdr(ifindex, AgentHdr::TRAP_FLOW_MISS, hash_id, vrf) ;
pkt->AddEthHdr(dmac, smac, ETHERTYPE_IPV6);
pkt->AddIp6Hdr(sip, dip, proto);
if (proto == IPPROTO_ICMPV6) {
pkt->AddIcmp6Hdr();
} else {
pkt->AddUdpHdr(sport, dport, 64);
}
uint8_t *ptr(new uint8_t[pkt->GetBuffLen()]);
memcpy(ptr, pkt->GetBuff(), pkt->GetBuffLen());
client->agent_init()->pkt0()->ProcessFlowPacket(ptr, pkt->GetBuffLen(),
pkt->GetBuffLen());
delete pkt;
}
5 changes: 4 additions & 1 deletion src/vnsw/agent/pkt/test/test_pkt_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,8 @@ extern void TxTcp6MplsPacket(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);

extern void TxL2Ip6Packet(int ifindex, const char *smac, const char *dmac,
const char *sip, const char *dip, int proto,
int hash_id = 1, int vrf = -1, uint16_t sport = 0,
uint16_t dport = 0);
#endif // __TEST_PKT_UTIL_H__

0 comments on commit db38148

Please sign in to comment.