Skip to content

Commit

Permalink
Merge "Overlay Trace route Request & Respose support is added."
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jun 3, 2016
2 parents d09b6b5 + e0c2aec commit bb14c7a
Show file tree
Hide file tree
Showing 12 changed files with 333 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/vnsw/agent/diag/SConscript
Expand Up @@ -22,6 +22,7 @@ libdiag = env.Library('diag',
'ping.cc',
'traceroute.cc',
'overlay_ping.cc',
'overlay_traceroute.cc',
'diag_pkt_handler.cc'
])

Expand Down
26 changes: 25 additions & 1 deletion src/vnsw/agent/diag/diag.cc
Expand Up @@ -17,7 +17,7 @@


const std::string KDiagName("DiagTimeoutHandler");

using namespace boost::posix_time;
////////////////////////////////////////////////////////////////////////////////

DiagEntry::DiagEntry(const std::string &sip, const std::string &dip,
Expand Down Expand Up @@ -138,3 +138,27 @@ DiagEntry* DiagTable::Find(DiagEntry::DiagKey &key) {
void DiagTable::Enqueue(DiagEntryOp *op) {
entry_op_queue_->Enqueue(op);
}

uint32_t DiagEntry::HashValUdpSourcePort() {
std::size_t seed = 0;
boost::hash_combine(seed, sip_.to_ulong());
boost::hash_combine(seed, dip_.to_ulong());
boost::hash_combine(seed, proto_);
boost::hash_combine(seed, sport_);
boost::hash_combine(seed, dport_);
return seed;
}
void DiagEntry::FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id) {
pktdata->msg_type_ = AgentDiagPktData::DIAG_REQUEST;
pktdata->reply_mode_ = OverlayOamPktData::REPLY_OVERLAY_SEGMENT;
pktdata->org_handle_ = htons(key_);
pktdata->seq_no_ = htonl(seq_no_);
boost::posix_time::ptime time = microsec_clock::universal_time();
boost::posix_time::time_duration td = time.time_of_day();
pktdata->timesent_sec_ = td.total_seconds();
pktdata->timesent_misec_ = td.total_microseconds() -
seconds(pktdata->timesent_sec_).total_microseconds();
pktdata->vxlanoamtlv_.type_ = AgentDiagPktData::DIAG_REQUEST;
pktdata->vxlanoamtlv_.vxlan_id_ = htonl(vxlan_id);
pktdata->vxlanoamtlv_.sip_ = sip_;
}
3 changes: 2 additions & 1 deletion src/vnsw/agent/diag/diag.h
Expand Up @@ -45,7 +45,8 @@ class DiagEntry {
DiagTable* diag_table() const {
return diag_table_;
}

uint32_t HashValUdpSourcePort();
void FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id);
protected:
Ip4Address sip_;
Ip4Address dip_;
Expand Down
18 changes: 18 additions & 0 deletions src/vnsw/agent/diag/diag.sandesh
Expand Up @@ -57,6 +57,24 @@ request sandesh OverlayPingReq {
10: optional i32 interval = 1;
}

/**
* Request message to get Overlay trace route in agent introspect
*
*/

request sandesh OverlayTraceReq {
1: string source_ip;
2: string dest_ip;
3: i16 protocol;
4: string vn_uuid;
5: string vm_remote_mac;
6: i32 source_port;
7: i32 dest_port;
8: optional i16 max_hops = 30;
9: optional i16 max_attempts = 3;
10: optional i32 interval = 1;
}

/**
* Ping response statistics
*/
Expand Down
28 changes: 21 additions & 7 deletions src/vnsw/agent/diag/diag_pkt_handler.cc
Expand Up @@ -65,13 +65,23 @@ bool DiagPktHandler::IsOverlayPingPacket() {

bool DiagPktHandler::HandleTraceRoutePacket() {

uint32_t rabit =0;
if (pkt_info_->ip == NULL) {
// we only send IPv4 trace route packets; ignore other packets
return true;
}

if (pkt_info_->ip->ip_ttl == 0) {
SendTimeExceededPacket();
if (pkt_info_->dport == VXLAN_UDP_DEST_PORT) {
VxlanHdr *vxlan = (VxlanHdr *)(pkt_info_->transp.udp + 1);
rabit = ntohl(vxlan->reserved) & OverlayPing::kVxlanRABit;
}

if (rabit) {
SendOverlayResponse();
} else {
SendTimeExceededPacket();
}
return true;
}

Expand Down Expand Up @@ -125,8 +135,14 @@ bool DiagPktHandler::HandleTraceRouteResponse() {
uint8_t *data = (uint8_t *)(pkt_info_->transp.icmp) + 8;
uint16_t len = pkt_info_->len - (data - pkt_info_->pkt);
DiagEntry::DiagKey key = -1;
if (!ParseIcmpData(data, len, (uint16_t *)&key))
return true;
// if it is Overlay packet get the key from Oam data
if (IsOverlayPingPacket()) {
OverlayOamPktData *oamdata = (OverlayOamPktData * )pkt_info_->data;
key = ntohs(oamdata->org_handle_);
} else {
if (!ParseIcmpData(data, len, (uint16_t *)&key))
return true;
}

DiagEntry *entry = diag_table_->Find(key);
if (!entry) return true;
Expand Down Expand Up @@ -250,7 +266,7 @@ bool DiagPktHandler::Run() {
//and dump the packet back
if (isoverlay_packet) {
// Reply packet with after setting the TLV content.
ReplyOverlayPing();
SendOverlayResponse();
return true;
}
Reply();
Expand All @@ -266,7 +282,6 @@ bool DiagPktHandler::Run() {
if (!entry) {
return true;
}

entry->HandleReply(this);

if (entry->GetSeqNo() == entry->GetMaxAttempts()) {
Expand Down Expand Up @@ -368,7 +383,7 @@ void DiagPktHandler::TunnelHdrSwap() {
IpHdr((char *)ip, sizeof(struct ip), ntohs(ip->ip_len),ip->ip_dst.s_addr,
ip->ip_src.s_addr, ip->ip_p, DEFAULT_IP_ID, DEFAULT_IP_TTL);
}
void DiagPktHandler::ReplyOverlayPing() {
void DiagPktHandler::SendOverlayResponse() {
Agent *agent = Agent::GetInstance();
TunnelHdrSwap();
// Swap();
Expand All @@ -383,7 +398,6 @@ void DiagPktHandler::ReplyOverlayPing() {
oamdata->timerecv_sec_ = td.total_seconds();
oamdata->timerecv_misec_ = td.total_microseconds() -
seconds(oamdata->timerecv_sec_).total_microseconds();;
pkt_info_->set_len(GetLength());
PhysicalInterfaceKey key1(agent->fabric_interface_name());
Interface *intf = static_cast<Interface *>
(agent->interface_table()->Find(&key1, true));
Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/diag/diag_pkt_handler.h
Expand Up @@ -36,7 +36,7 @@ class DiagPktHandler : public ProtoHandler {
void SetReply();
void SetDiagChkSum();
void Reply();
void ReplyOverlayPing();
void SendOverlayResponse();
const std::string &GetAddress() const { return address_; }
uint8_t* GetData() {
return (pkt_info_->data);
Expand Down
43 changes: 9 additions & 34 deletions src/vnsw/agent/diag/overlay_ping.cc
Expand Up @@ -31,8 +31,8 @@ OverlayPing::OverlayPing(const OverlayPingReq *ping_req, DiagTable *diag_table):
/*
* Get the L2 Route entry to find the Tunnel NH
*/
static BridgeRouteEntry * L2RouteGet(VxLanId* vxlan, string remotemac,
Agent *agent)
BridgeRouteEntry *
OverlayPing::L2RouteGet(VxLanId* vxlan, string remotemac, Agent *agent)
{
string vrf_name;
const VrfNH *vrf_nh = dynamic_cast<const VrfNH *>(vxlan->nexthop());
Expand Down Expand Up @@ -94,7 +94,8 @@ void OverlayPingReq::HandleRequest() const {
goto error;
}

BridgeRouteEntry *rt = L2RouteGet(vxlan, get_vm_remote_mac(), agent);
BridgeRouteEntry *rt = OverlayPing::L2RouteGet(vxlan, get_vm_remote_mac(),
agent);
if (!rt) {
err_str = "Invalid remote mac";
goto error;
Expand All @@ -115,21 +116,6 @@ OverlayPing::~OverlayPing() {

}

void OverlayPing::FillOamPktHeader(OverlayOamPktData *pktdata) {
pktdata->msg_type_ = AgentDiagPktData::DIAG_REQUEST;
pktdata->reply_mode_ = OverlayOamPktData::REPLY_OVERLAY_SEGMENT;
pktdata->org_handle_ = htons(key_);
pktdata->seq_no_ = htonl(seq_no_);
boost::posix_time::ptime time = microsec_clock::universal_time();
boost::posix_time::time_duration td = time.time_of_day();
pktdata->timesent_sec_ = td.total_seconds();
pktdata->timesent_misec_ = td.total_microseconds() -
seconds(pktdata->timesent_sec_).total_microseconds();
pktdata->vxlanoamtlv_.type_ = AgentDiagPktData::DIAG_REQUEST;
uint32_t vxlan_id = diag_table_->agent()->vn_table()->Find(vn_uuid_)->GetVxLanId();
pktdata->vxlanoamtlv_.vxlan_id_ = htonl(vxlan_id);
pktdata->vxlanoamtlv_.sip_ = sip_;
}
/*
* Creat Overlay VXlan packet.
* Set the Route alert bit to indicate Overlay OAM packet
Expand All @@ -156,16 +142,16 @@ void OverlayPing::SendRequest() {

tunneldst = *nh->GetDip();
tunnelsrc = *nh->GetSip();
len_ = kOverlayUdpPingHdrLength + data_len_;
len_ = kOverlayUdpHdrLength + data_len_;
boost::shared_ptr<PktInfo> pkt_info(new PktInfo(agent, len_,
PktHandler::DIAG, 0));
uint8_t *buf = pkt_info->packet_buffer()->data();
memset(buf, 0, len_);
OverlayOamPktData *pktdata = NULL;
pktdata = (OverlayOamPktData *)(buf + kOverlayUdpPingHdrLength);
pktdata = (OverlayOamPktData *)(buf + kOverlayUdpHdrLength);
memset(pktdata, 0, sizeof(OverlayOamPktData));

FillOamPktHeader(pktdata);
FillOamPktHeader(pktdata, vxlan_id);
DiagPktHandler *pkt_handler = new DiagPktHandler(diag_table_->agent(), pkt_info,
*(diag_table_->agent()->event_manager())->io_service());
// FIll outer header
Expand All @@ -177,8 +163,8 @@ void OverlayPing::SendRequest() {
uint8_t len;
len = data_len_+2 * sizeof(udphdr)+sizeof(VxlanHdr)+
sizeof(struct ip) + sizeof(struct ether_header);
pkt_handler->UdpHdr(len, ntohl(tunnelsrc.to_ulong()), HashValUdpSourcePort(),
ntohl(tunneldst.to_ulong()), VXLAN_UDP_DEST_PORT);
pkt_handler->UdpHdr(len, ntohl(tunnelsrc.to_ulong()), HashValUdpSourcePort(),
ntohl(tunneldst.to_ulong()), VXLAN_UDP_DEST_PORT);

pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(tunnelsrc.to_ulong()),
ntohl(tunneldst.to_ulong()), IPPROTO_UDP,
Expand Down Expand Up @@ -265,14 +251,3 @@ if (pkt_lost_count_ != GetMaxAttempts()) {
resp->Response();
}


uint32_t OverlayPing::HashValUdpSourcePort() {
std::size_t seed = 0;
boost::hash_combine(seed, sip_.to_ulong());
boost::hash_combine(seed, dip_.to_ulong());
boost::hash_combine(seed, proto_);
boost::hash_combine(seed, sport_);
boost::hash_combine(seed, dport_);
return seed;
}

7 changes: 4 additions & 3 deletions src/vnsw/agent/diag/overlay_ping.h
Expand Up @@ -14,7 +14,7 @@
class DiagTable;
class OverlayPing : public DiagEntry{
public:
static const uint32_t kOverlayUdpPingHdrLength = 2 *(sizeof(struct ether_header) +
static const uint32_t kOverlayUdpHdrLength = 2 *(sizeof(struct ether_header) +
sizeof(struct ip) + sizeof(udphdr))
+ sizeof(VxlanHdr);
static const uint32_t kVxlanRABit = 0x01000000;
Expand All @@ -28,8 +28,9 @@ class OverlayPing : public DiagEntry{
virtual void HandleReply(DiagPktHandler *handler);
virtual void RequestTimedOut(uint32_t seq_no);
virtual void SendSummary();
void FillOamPktHeader(OverlayOamPktData *pkt);
uint32_t HashValUdpSourcePort();
//void FillOamPktHeader(OverlayOamPktData *pkt);
static BridgeRouteEntry *L2RouteGet(VxLanId* vxlan, string remotemac,
Agent *agent);
private:
uuid vn_uuid_;
MacAddress remote_vm_mac_;
Expand Down

0 comments on commit bb14c7a

Please sign in to comment.