From bb0e0ad948d01e1bfab3c2a775abc2e3946c8c8d Mon Sep 17 00:00:00 2001 From: harsh Date: Thu, 5 Nov 2015 15:01:35 +0530 Subject: [PATCH] Sctp flow handling changes for agent . Unit Test . Change-Id: Idff7b1ff3be951f8e5270e59eb6ee6a59cb93e6b Closes-Bug: #1505303 --- src/vnsw/agent/pkt/pkt_handler.cc | 10 ++++++++++ src/vnsw/agent/pkt/pkt_handler.h | 10 +++++++++- src/vnsw/agent/pkt/test/test_pkt_parse.cc | 15 ++++++++++++++- src/vnsw/agent/pkt/test/test_pkt_util.cc | 10 ++++++++++ src/vnsw/agent/pkt/test/test_pkt_util.h | 5 +++++ src/vnsw/agent/test/pkt_gen.h | 7 +++++++ 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/vnsw/agent/pkt/pkt_handler.cc b/src/vnsw/agent/pkt/pkt_handler.cc index 469a4f8d15c..e9eb183ec3f 100644 --- a/src/vnsw/agent/pkt/pkt_handler.cc +++ b/src/vnsw/agent/pkt/pkt_handler.cc @@ -352,6 +352,16 @@ int PktHandler::ParseIpPacket(PktInfo *pkt_info, PktType::Type &pkt_type, break; } + case IPPROTO_SCTP : { + pkt_info->transp.sctp = (sctphdr *) (pkt + len); + len += sizeof(sctphdr); + pkt_info->data = (pkt + len); + pkt_info->dport = ntohs(pkt_info->transp.sctp->th_dport); + pkt_info->sport = ntohs(pkt_info->transp.sctp->th_sport); + pkt_type = PktType::SCTP; + break; + } + case IPPROTO_ICMP: { pkt_info->transp.icmp = (struct icmp *) (pkt + len); pkt_type = PktType::ICMP; diff --git a/src/vnsw/agent/pkt/pkt_handler.h b/src/vnsw/agent/pkt/pkt_handler.h index 3d4122b0d2e..cd1c062c5b2 100644 --- a/src/vnsw/agent/pkt/pkt_handler.h +++ b/src/vnsw/agent/pkt/pkt_handler.h @@ -87,10 +87,17 @@ struct PktType { ICMP, ICMPV6, NON_IP, - MESSAGE + MESSAGE, + SCTP }; }; +struct sctphdr { + u_int16_t th_sport; + u_int16_t th_dport; + u_int32_t vtag; +}; + struct AgentHdr { // Packet commands between agent and vrouter. The values must be in-sync // with vrouter/include/vr_defs.h @@ -200,6 +207,7 @@ struct PktInfo { struct udphdr *udp; struct icmp *icmp; struct icmp6_hdr *icmp6; + struct sctphdr *sctp; } transp; PktInfo(Agent *agent, uint32_t buff_len, uint32_t module, uint32_t mdata); diff --git a/src/vnsw/agent/pkt/test/test_pkt_parse.cc b/src/vnsw/agent/pkt/test/test_pkt_parse.cc index 88fc266c9db..bbc466053c0 100644 --- a/src/vnsw/agent/pkt/test/test_pkt_parse.cc +++ b/src/vnsw/agent/pkt/test/test_pkt_parse.cc @@ -312,6 +312,11 @@ static bool ValidateIpPktInfo(PktInfo *pkt_info, const char *sip, if (pkt_info->type != PktType::ICMP) { ret = false; } + } else if (proto == IPPROTO_SCTP) { + EXPECT_EQ(pkt_info->type, PktType::SCTP); + if (pkt_info->type != PktType::SCTP) { + ret = false; + } } else { EXPECT_EQ(pkt_info->type, PktType::IP); if (pkt_info->type != PktType::IP) { @@ -426,10 +431,18 @@ TEST_F(PktParseTest, IP_On_Vnet_1) { 1, 2)); pkt->Reset(); - MakeIpPacket(pkt.get(), vnet1->id(), "1.1.1.1", "1.1.1.2", 1, 1, -1, -1, true); + MakeSctpPacket(pkt.get(), vnet1->id(), "1.1.1.1", "1.1.1.2", 1, 2, 3, -1); PktInfo pkt_info4(Agent::GetInstance(), 100, 0, 0); TestPkt(&pkt_info4, pkt.get()); client->WaitForIdle(); + EXPECT_TRUE(ValidateIpPktInfo(&pkt_info4, "1.1.1.1", "1.1.1.2", IPPROTO_SCTP, + 1, 2)); + + pkt->Reset(); + MakeIpPacket(pkt.get(), vnet1->id(), "1.1.1.1", "1.1.1.2", 1, 1, -1, -1, true); + PktInfo pkt_info5(Agent::GetInstance(), 100, PktHandler::FLOW, 0); + TestPkt(&pkt_info5, pkt.get()); + client->WaitForIdle(); EXPECT_TRUE(ValidateIpPktInfo(&pkt_info1, "1.1.1.1", "1.1.1.2", 1, 0, 0)); EXPECT_EQ(Agent::GetInstance()->stats()->pkt_fragments_dropped(), 1); diff --git a/src/vnsw/agent/pkt/test/test_pkt_util.cc b/src/vnsw/agent/pkt/test/test_pkt_util.cc index 4ec013e5fc7..56ebbac8824 100644 --- a/src/vnsw/agent/pkt/test/test_pkt_util.cc +++ b/src/vnsw/agent/pkt/test/test_pkt_util.cc @@ -89,6 +89,16 @@ void TxUdpPacket(int ifindex, const char *sip, const char *dip, delete pkt; } +void MakeSctpPacket(PktGen *pkt, int ifindex, const char *sip, + const char *dip, uint16_t sport, uint16_t dport, + int hash_id, uint32_t vrf_id) { + 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_id); + pkt->AddEthHdr("00:00:5E:00:01:00", "00:00:00:00:00:01", 0x800); + pkt->AddIpHdr(sip, dip, IPPROTO_SCTP); + pkt->AddSctpHdr(sport, dport, 64); +} + void MakeTcpPacket(PktGen *pkt, int ifindex, const char *sip, const char *dip, uint16_t sport, uint16_t dport, bool ack, int hash_id, uint32_t vrf_id) { diff --git a/src/vnsw/agent/pkt/test/test_pkt_util.h b/src/vnsw/agent/pkt/test/test_pkt_util.h index ee213677e3e..58a9105b39a 100644 --- a/src/vnsw/agent/pkt/test/test_pkt_util.h +++ b/src/vnsw/agent/pkt/test/test_pkt_util.h @@ -32,6 +32,11 @@ extern void TxUdpPacket(int ifindex, const char *sip, const char *dip, extern void MakeTcpPacket(PktGen *pkt, int ifindex, const char *sip, const char *dip, uint16_t sport, uint16_t dport, bool ack, int hash_id, uint32_t vrf_id); + +extern void MakeSctpPacket(PktGen *pkt, int ifindex, const char *sip, + const char *dip, uint16_t sport, uint16_t dport, + int hash_id, uint32_t vrf_id); + extern void TxTcpPacket(int ifindex, const char *sip, const char *dip, uint16_t sport, uint16_t dport, bool ack, int hash_id = 1, uint32_t vrf_id = -1); diff --git a/src/vnsw/agent/test/pkt_gen.h b/src/vnsw/agent/test/pkt_gen.h index 6ffd682f265..6bb0495c117 100644 --- a/src/vnsw/agent/test/pkt_gen.h +++ b/src/vnsw/agent/test/pkt_gen.h @@ -338,6 +338,13 @@ class PktGen { len += sizeof(tcphdr) + plen; }; + void AddSctpHdr(uint16_t sport, uint16_t dport, int plen) { + struct sctphdr *sctp = (struct sctphdr *)(buff + len); + sctp -> th_dport = htons(dport); + sctp -> th_sport = htons(sport); + len += sizeof(sctphdr) + plen; + }; + void AddIcmpHdr() { struct icmp *icmp = (struct icmp *)(buff + len); icmp->icmp_type = 0;