Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : #include "base/os.h" 7 : #include "pkt/proto.h" 8 : #include "pkt/proto_handler.h" 9 : #include "pkt/pkt_init.h" 10 : #include "cmn/agent_stats.h" 11 : 12 : //////////////////////////////////////////////////////////////////////////////// 13 : 14 26 : Proto::Proto(Agent *agent, const char *task_name, PktHandler::PktModuleName mod, 15 26 : boost::asio::io_context &io) 16 26 : : agent_(agent), module_(mod), trace_(true), free_buffer_(false), io_(io), 17 26 : work_queue_(TaskScheduler::GetInstance()->GetTaskId(task_name), mod, 18 26 : boost::bind(&Proto::ProcessProto, this, _1)) { 19 26 : agent->pkt()->pkt_handler()->Register(mod, this); 20 26 : std::ostringstream str; 21 26 : str << "Proto work queue. Module " << mod; 22 26 : work_queue_.set_name(str.str()); 23 26 : } 24 : 25 26 : Proto::~Proto() { 26 26 : work_queue_.Shutdown(); 27 26 : } 28 : 29 75 : void Proto::FreeBuffer(PktInfo *msg) { 30 75 : msg->pkt = NULL; 31 75 : msg->eth = NULL; 32 75 : msg->arp = NULL; 33 75 : msg->ip = NULL; 34 75 : msg->transp.tcp = NULL; 35 75 : msg->data = NULL; 36 75 : msg->reset_packet_buffer(); 37 75 : } 38 : 39 1074 : bool Proto::Enqueue(boost::shared_ptr<PktInfo> msg) { 40 1074 : if (Validate(msg.get()) == false) { 41 0 : return true; 42 : } 43 : 44 1074 : if (free_buffer_) { 45 0 : FreeBuffer(msg.get()); 46 : } 47 : 48 1074 : return work_queue_.Enqueue(msg); 49 : } 50 : 51 1186 : bool Proto::RunProtoHandler(ProtoHandler *handler) { 52 1186 : if (handler->Run()) 53 1062 : delete handler; 54 1186 : return true; 55 : } 56 : 57 : // PktHandler enqueues the packet as-is without decoding based on "cmd" in 58 : // agent_hdr. Decode the pacekt first. Its possible that protocol handler may 59 : // change based on packet decode 60 1149 : bool Proto::ProcessProto(boost::shared_ptr<PktInfo> msg_info) { 61 1149 : PktHandler *pkt_handler = agent_->pkt()->pkt_handler(); 62 1149 : if (trace_) { 63 1074 : pkt_handler->AddPktTrace(module_, PktTrace::In, msg_info.get()); 64 : } 65 : 66 1149 : ProtoHandler *handler = AllocProtoHandler(msg_info, io_); 67 1149 : return RunProtoHandler(handler); 68 : }