OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pkt0_interface_base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/filesystem.hpp>
6 #include <stdio.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #include <assert.h>
10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 
13 #include <net/if.h>
14 
15 #include "base/logging.h"
16 #include "cmn/agent_cmn.h"
17 #include "sandesh/sandesh_trace.h"
18 #include "pkt/pkt_types.h"
19 #include "pkt/pkt_init.h"
20 #include "pkt0_interface.h"
21 
22 using namespace boost::asio;
23 #define TAP_TRACE(obj, ...) \
24 do { \
25  Tap##obj::TraceMsg(PacketTraceBuf, __FILE__, __LINE__, __VA_ARGS__); \
26 } while (false) \
27 
28 
30 
31 string Pkt0Socket::sSocketDir = "/var/run/vrouter";
32 string Pkt0Socket::sAgentSocketPath = "/var/run/vrouter/agent_pkt0";
33 string Pkt0Socket::sVrouterSocketPath = "/var/run/vrouter/dpdk_pkt0";
34 
35 
36 void Pkt0Socket::CreateMockAgent(const std::string& guid)
37 {
38  sSocketDir = "/tmp/" + guid + sSocketDir ;
39  sAgentSocketPath = "/tmp/" + guid + sAgentSocketPath;
40  sVrouterSocketPath = "/tmp/" + guid + sVrouterSocketPath;
41 }
42 
43 
44 
45 Pkt0Interface::Pkt0Interface(const std::string &name,
46  boost::asio::io_context *io) :
47  name_(name), tap_fd_(-1), input_(*io), read_buff_(NULL), pkt_handler_(NULL) {
48  memset(mac_address_, 0, sizeof(mac_address_));
49 }
50 
52  if (read_buff_) {
53  delete [] read_buff_;
54  }
55 }
56 
58  boost::system::error_code ec;
59  input_.close(ec);
60  tap_fd_ = -1;
61 }
62 
64 }
65 
66 void Pkt0Interface::WriteHandler(const boost::system::error_code &error,
67  std::size_t length,
68  uint8_t *buff) {
69  if (error)
70  TAP_TRACE(Err,
71  "Packet Tap Error <" + error.message() + "> sending packet");
72  delete [] buff;
73 }
74 
75 
77  read_buff_ = new uint8_t[kMaxPacketSize];
78  input_.async_read_some(
79  boost::asio::buffer(read_buff_, kMaxPacketSize),
80  boost::bind(&Pkt0Interface::ReadHandler, this,
81  boost::asio::placeholders::error,
82  boost::asio::placeholders::bytes_transferred));
83 }
84 
85 void Pkt0Interface::ReadHandler(const boost::system::error_code &error,
86  std::size_t length) {
87  if (error) {
88  TAP_TRACE(Err,
89  "Packet Tap Error <" + error.message() + "> reading packet");
90  if (error == boost::system::errc::operation_canceled) {
91  return;
92  }
93 
94  delete [] read_buff_;
95  read_buff_ = NULL;
96  }
97 
98  if (!error) {
99  Agent *agent = pkt_handler()->agent();
102  0));
104  }
105 
106  AsyncRead();
107 }
108 
109 int Pkt0Interface::Send(uint8_t *buff, uint16_t buff_len,
110  const PacketBufferPtr &pkt) {
111  std::vector<boost::asio::const_buffer> buff_list;
112  buff_list.push_back(boost::asio::buffer(buff, buff_len));
113  buff_list.push_back(boost::asio::buffer(pkt->data(), pkt->data_len()));
114 
115  SendImpl(buff, buff_len, pkt, buff_list);
116 
117  return buff_len + pkt->data_len();
118 }
119 
120 Pkt0RawInterface::Pkt0RawInterface(const std::string &name,
121  boost::asio::io_context *io) :
122  Pkt0Interface(name, io) {
123 }
124 
126 }
127 
128 
129 Pkt0Socket::Pkt0Socket(const std::string &name,
130  boost::asio::io_context *io):
131  connected_(false), socket_(*io), timer_(NULL),
132  read_buff_(NULL), pkt_handler_(NULL), name_(name){
133 }
134 
136  if (read_buff_) {
137  delete [] read_buff_;
138  }
139 }
140 
142 
143  //The create_directories does not require for the parent
144  // directories to exist.
145  //They are created recursively if needed
146  //Mock agent needs this
147  boost::filesystem::create_directories(sSocketDir);
148 
149  boost::filesystem::remove(sAgentSocketPath);
150 
151  boost::system::error_code ec;
152  socket_.open();
153  local::datagram_protocol::endpoint ep(sAgentSocketPath);
154  socket_.bind(ep, ec);
155  if (ec) {
156  LOG(DEBUG, "Error binding to the socket " << sAgentSocketPath
157  << ": " << ec.message());
158  }
159  assert(!ec);
160 }
161 
165  AsyncRead();
167 }
168 
170  if (read_buff_) {
171  delete [] read_buff_;
172  }
173 
174  boost::system::error_code ec;
175  socket_.close(ec);
176 }
177 
179 }
180 
182  read_buff_ = new uint8_t[kMaxPacketSize];
183  socket_.async_receive(
184  boost::asio::buffer(read_buff_, kMaxPacketSize),
185  boost::bind(&Pkt0Socket::ReadHandler, this,
186  boost::asio::placeholders::error,
187  boost::asio::placeholders::bytes_transferred));
188 }
189 
191  connected_ = false;
192  Agent *agent = pkt_handler()->agent();
193  if (timer_ == NULL) {
195  *(agent->event_manager()->io_service()),
196  "UnixSocketConnectTimer"));
197  }
198  TAP_TRACE(Err, "Starting connect to vrouter unix socket ");
199  timer_->Start(kConnectTimeout,
200  boost::bind(&Pkt0Socket::OnTimeout, this));
201 }
202 
204 
205  local::datagram_protocol::endpoint ep(sVrouterSocketPath);
206  boost::system::error_code ec;
207  socket_.connect(ep, ec);
208  if (ec.failed()) {
209  TAP_TRACE(Err, "Error connecting to vrouter unix socket " +
210  ec.message());
211  return true;
212  }
213  connected_ = true;
214  return false;
215 }
216 
217 int Pkt0Socket::Send(uint8_t *buff, uint16_t buff_len,
218  const PacketBufferPtr &pkt) {
219  if (connected_ == false) {
220  //queue the data?
221  return (pkt->data_len());
222  }
223 
224  std::vector<boost::asio::const_buffer> buff_list;
225  buff_list.push_back(boost::asio::buffer(buff, buff_len));
226  buff_list.push_back(boost::asio::buffer(pkt->data(), pkt->data_len()));
227 
228  socket_.async_send(buff_list,
229  boost::bind(&Pkt0Socket::WriteHandler, this,
230  boost::asio::placeholders::error,
231  boost::asio::placeholders::bytes_transferred,
232  pkt, buff));
233  return (buff_len + pkt->data_len());
234 }
235 
236 void Pkt0Socket::ReadHandler(const boost::system::error_code &error,
237  std::size_t length) {
238  if (error) {
239  TAP_TRACE(Err,
240  "Packet Error <" + error.message() + "> reading packet");
241  if (error == boost::system::errc::operation_canceled) {
242  return;
243  }
244 
245  delete [] read_buff_;
246  read_buff_ = NULL;
247  }
248 
249  if (!error) {
250  Agent *agent = pkt_handler()->agent();
253  0));
255  }
256 
257  AsyncRead();
258 }
259 
260 void Pkt0Socket::WriteHandler(const boost::system::error_code &error,
261  std::size_t length, PacketBufferPtr pkt,
262  uint8_t *buff) {
263  if (error == boost::system::errc::not_connected) {
265  }
266 
267  if (error) {
268  TAP_TRACE(Err,
269  "Packet Error <" + error.message() + "> sending packet");
270  }
271  delete [] buff;
272 }
273 
boost::shared_ptr< PacketBuffer > PacketBufferPtr
Definition: packet_buffer.h:18
Pkt0RawInterface(const std::string &name, boost::asio::io_context *io)
static string sVrouterSocketPath
uint8_t * read_buff_
Pkt0Interface(const std::string &name, boost::asio::io_context *io)
void WriteHandler(const boost::system::error_code &error, std::size_t length, uint8_t *buff)
unsigned char mac_address_[ETHER_ADDR_LEN]
uint8_t * read_buff_
boost::asio::local::datagram_protocol::socket socket_
boost::asio::io_context * io_service()
Definition: event_manager.h:42
virtual void IoShutdownControlInterface()
#define TAP_TRACE(obj,...)
PktHandler * pkt_handler() const
boost::scoped_ptr< Timer > timer_
static const uint32_t kConnectTimeout
Agent * agent() const
Definition: pkt_handler.h:317
virtual void IoShutdownControlInterface()
static void CreateMockAgent(const string &)
virtual void InitControlInterface()
virtual void InitControlInterface()
Definition: agent.h:358
void ReadHandler(const boost::system::error_code &err, std::size_t length)
virtual ~Pkt0Interface()
EventManager * event_manager() const
Definition: agent.h:1103
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
Definition: timer.cc:201
virtual void ShutdownControlInterface()
boost::asio::posix::stream_descriptor input_
PacketBufferManager * packet_buffer_manager() const
Definition: pkt_init.h:33
void ReadHandler(const boost::system::error_code &err, std::size_t length)
void WriteHandler(const boost::system::error_code &error, std::size_t length, PacketBufferPtr pkt, uint8_t *buff)
void SendImpl(uint8_t *buff, uint16_t buff_len, const PacketBufferPtr &pkt, buffer_list &buff_list)
PacketBufferPtr Allocate(uint32_t module, uint16_t len, uint32_t mdata)
bool Process(const PacketBufferPtr &pkt)
#define LOG(_Level, _Msg)
Definition: logging.h:33
static string sSocketDir
static string sAgentSocketPath
static const uint32_t kMaxPacketSize
int Send(uint8_t *buff, uint16_t buff_len, const PacketBufferPtr &pkt)
PktModule * pkt() const
Definition: agent.cc:965
int Send(uint8_t *buff, uint16_t buff_len, const PacketBufferPtr &pkt)
Pkt0Socket(const std::string &name, boost::asio::io_context *io)
virtual void ShutdownControlInterface()