Skip to content

Commit

Permalink
Merge "Ignore fragmented packets in agent packet handling."
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 20, 2015
2 parents 02ad53b + c195bcc commit f319187
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/agent_stats.cc
Expand Up @@ -23,6 +23,7 @@ void AgentStats::Reset() {
sandesh_http_sessions_ = nh_count_ = pkt_exceptions_ = 0;
pkt_invalid_agent_hdr_ = pkt_invalid_interface_ = 0;
pkt_no_handler_ = pkt_dropped_ = flow_created_ = 0;
pkt_fragments_dropped_ = 0;
flow_aged_ = flow_active_ = flow_drop_due_to_max_limit_ = 0;
flow_drop_due_to_linklocal_limit_ = ipc_in_msgs_ = 0;
ipc_out_msgs_ = in_tpkts_ = in_bytes_ = out_tpkts_ = 0;
Expand All @@ -46,6 +47,7 @@ void AgentStatsReq::HandleRequest() const {
pkt->set_invalid_interface(stats->pkt_invalid_interface());
pkt->set_no_handler(stats->pkt_no_handler());
pkt->set_pkt_dropped(stats->pkt_dropped());
pkt->set_pkt_fragments_dropped(stats->pkt_fragments_dropped());
pkt->set_context(context());
pkt->set_more(true);
pkt->Response();
Expand Down
14 changes: 9 additions & 5 deletions src/vnsw/agent/pkt/agent_stats.h
Expand Up @@ -14,11 +14,11 @@ class AgentStats {
sandesh_reconnects_(0U), sandesh_in_msgs_(0U), sandesh_out_msgs_(0U),
sandesh_http_sessions_(0U), nh_count_(0U), pkt_exceptions_(0U),
pkt_invalid_agent_hdr_(0U), pkt_invalid_interface_(0U),
pkt_no_handler_(0U), pkt_dropped_(0U), flow_created_(0U),
flow_aged_(0U), flow_active_(0U), flow_drop_due_to_max_limit_(0),
flow_drop_due_to_linklocal_limit_(0), ipc_in_msgs_(0U),
ipc_out_msgs_(0U), in_tpkts_(0U), in_bytes_(0U), out_tpkts_(0U),
out_bytes_(0U) {
pkt_no_handler_(0U), pkt_fragments_dropped_(0U), pkt_dropped_(0U),
flow_created_(0U), flow_aged_(0U), flow_active_(0U),
flow_drop_due_to_max_limit_(0), flow_drop_due_to_linklocal_limit_(0),
ipc_in_msgs_(0U), ipc_out_msgs_(0U), in_tpkts_(0U), in_bytes_(0U),
out_tpkts_(0U), out_bytes_(0U) {
assert(singleton_ == NULL);
singleton_ = this;
}
Expand Down Expand Up @@ -81,6 +81,9 @@ class AgentStats {
void incr_pkt_no_handler() {pkt_no_handler_++;}
uint64_t pkt_no_handler() const {return pkt_no_handler_;}

void incr_pkt_fragments_dropped() {pkt_fragments_dropped_++;}
uint64_t pkt_fragments_dropped() const {return pkt_fragments_dropped_;}

void incr_pkt_dropped() {pkt_dropped_++;}
uint64_t pkt_dropped() const {return pkt_dropped_;}

Expand Down Expand Up @@ -120,6 +123,7 @@ class AgentStats {
uint64_t pkt_invalid_agent_hdr_;
uint64_t pkt_invalid_interface_;
uint64_t pkt_no_handler_;
uint64_t pkt_fragments_dropped_;
uint64_t pkt_dropped_;

// Flow stats
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/pkt.sandesh
Expand Up @@ -18,6 +18,7 @@ response sandesh PktTrapStatsResp {
3: i64 invalid_interface;
4: i64 no_handler;
5: i64 pkt_dropped;
6: i64 pkt_fragments_dropped;
}

response sandesh FlowStatsResp {
Expand Down
17 changes: 17 additions & 0 deletions src/vnsw/agent/pkt/pkt_handler.cc
Expand Up @@ -535,6 +535,13 @@ int PktHandler::ParseUserPkt(PktInfo *pkt_info, Interface *intf,

// IP Packets
len += ParseIpPacket(pkt_info, pkt_type, (pkt + len));

// If packet is an IP fragment and not flow trap, ignore it
if (IgnoreFragmentedPacket(pkt_info)) {
agent_->stats()->incr_pkt_fragments_dropped();
return -1;
}

// If it is a packet from TOR that we serve, dont parse any further
if (IsManagedTORPacket(intf, pkt_info, pkt_type, (pkt + len))) {
return len;
Expand Down Expand Up @@ -602,6 +609,16 @@ void PktHandler::SendMessage(PktModuleName mod, InterTaskMsg *msg) {
}
}

bool PktHandler::IgnoreFragmentedPacket(PktInfo *pkt_info) {
if (pkt_info->ip &&
((pkt_info->ip->ip_off & IP_MF) ||
(pkt_info->ip->ip_off & IP_OFFMASK)) &&
(pkt_info->agent_hdr.cmd != AgentHdr::TRAP_FLOW_MISS) &&
(pkt_info->agent_hdr.cmd != AgentHdr::TRAP_ECMP_RESOLVE))
return true;
return false;
}

bool PktHandler::IsDHCPPacket(PktInfo *pkt_info) {
if (pkt_info->dport == DHCP_SERVER_PORT ||
pkt_info->sport == DHCP_CLIENT_PORT) {
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/pkt_handler.h
Expand Up @@ -310,6 +310,7 @@ class PktHandler {
void ComputeForwardingMode(PktInfo *pkt_info) const;

void SetOuterIp(PktInfo *pkt_info, uint8_t *pkt);
bool IgnoreFragmentedPacket(PktInfo *pkt_info);
bool IsDHCPPacket(PktInfo *pkt_info);
bool IsValidInterface(uint32_t ifindex, Interface **interface);
bool IsToRDevice(uint32_t vrf_id, const IpAddress &ip);
Expand Down
9 changes: 9 additions & 0 deletions src/vnsw/agent/pkt/test/test_pkt_parse.cc
Expand Up @@ -424,6 +424,15 @@ TEST_F(PktParseTest, IP_On_Vnet_1) {
client->WaitForIdle();
EXPECT_TRUE(ValidateIpPktInfo(&pkt_info3, "1.1.1.1", "1.1.1.2", IPPROTO_TCP,
1, 2));

pkt->Reset();
MakeIpPacket(pkt.get(), vnet1->id(), "1.1.1.1", "1.1.1.2", 1, 1, -1, -1, true);
PktInfo pkt_info4(Agent::GetInstance(), 100, 0, 0);
TestPkt(&pkt_info4, 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);

}

TEST_F(PktParseTest, IPv6_On_Vnet_1) {
Expand Down
5 changes: 3 additions & 2 deletions src/vnsw/agent/pkt/test/test_pkt_util.cc
Expand Up @@ -12,11 +12,12 @@
#include <cmn/agent_cmn.h>

void MakeIpPacket(PktGen *pkt, int ifindex, const char *sip,
const char *dip, int proto, int hash_id, int cmd, int vrf) {
const char *dip, int proto, int hash_id, int cmd, int vrf,
bool fragment) {
pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
pkt->AddAgentHdr(ifindex, cmd, hash_id, vrf) ;
pkt->AddEthHdr("00:00:5E:00:01:00", "00:00:00:00:00:01", 0x800);
pkt->AddIpHdr(sip, dip, proto);
pkt->AddIpHdr(sip, dip, proto, fragment);
if (proto == 1) {
pkt->AddIcmpHdr();
}
Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/pkt/test/test_pkt_util.h
Expand Up @@ -9,7 +9,8 @@

extern void MakeIpPacket(PktGen *pkt, int ifindex, const char *sip,
const char *dip, int proto, int hash_id,
int cmd = AgentHdr::TRAP_FLOW_MISS, int vrf = -1);
int cmd = AgentHdr::TRAP_FLOW_MISS, int vrf = -1,
bool fragment = false);

extern void TxIpPacket(int ifindex, const char *sip, const char *dip,
int proto, int hash_id = 1, int vrf = -1);
Expand Down
5 changes: 4 additions & 1 deletion src/vnsw/agent/test/pkt_gen.h
Expand Up @@ -295,7 +295,8 @@ class PktGen {
len += sizeof(struct ether_header);
};

void AddIpHdr(const char *sip, const char *dip, uint16_t proto) {
void AddIpHdr(const char *sip, const char *dip, uint16_t proto,
bool fragment = false) {
struct ip *ip = (struct ip *)(buff + len);

ip->ip_hl = 5;
Expand All @@ -304,6 +305,8 @@ class PktGen {
ip->ip_src.s_addr = inet_addr(sip);
ip->ip_dst.s_addr = inet_addr(dip);
ip->ip_p = proto;
if (fragment)
ip->ip_off = IP_MF;
len += sizeof(struct ip);
};

Expand Down

0 comments on commit f319187

Please sign in to comment.