FD.io VPP  v21.01.1
Vector Packet Processing
hw.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vom/hw.hpp"
17 #include "vom/hw_cmds.hpp"
18 #include "vom/logger.hpp"
19 #include "vom/stat_reader.hpp"
20 
21 namespace VOM {
23  : m_enabled(true)
24  , m_connected(false)
25  , m_conn()
26 {
27 }
28 
30 {
31 }
32 
33 HW::cmd_q&
35 {
36  return (*this);
37 }
38 
39 /**
40  * Run the connect/dispatch thread.
41  */
42 void
43 HW::cmd_q::rx_run()
44 {
45  while (m_connected) {
46  m_conn.ctx().dispatch();
47  }
48 }
49 
50 void
52 {
53  std::shared_ptr<cmd> sp(c);
54 
55  m_queue.push_back(sp);
56 }
57 
58 void
59 HW::cmd_q::enqueue(std::shared_ptr<cmd> c)
60 {
61  m_queue.push_back(c);
62 }
63 
64 void
65 HW::cmd_q::enqueue(std::queue<cmd*>& cmds)
66 {
67  while (cmds.size()) {
68  std::shared_ptr<cmd> sp(cmds.front());
69 
70  m_queue.push_back(sp);
71  cmds.pop();
72  }
73 }
74 
75 bool
77 {
78  if (m_connected)
79  return m_connected;
80 
81  if (0 == m_conn.connect()) {
82  m_connected = true;
83  m_rx_thread.reset(new std::thread(&HW::cmd_q::rx_run, this));
84  }
85  return (m_connected);
86 }
87 
88 void
90 {
91 
92  if (!m_connected)
93  return;
94 
95  m_connected = false;
96 
97  if (m_rx_thread && m_rx_thread->joinable()) {
98  m_rx_thread->join();
99  }
100 
101  m_conn.disconnect();
102 }
103 
104 void
106 {
107  m_enabled = true;
108 }
109 
110 void
112 {
113  m_enabled = false;
114 }
115 
116 rc_t
118 {
119  rc_t rc = rc_t::OK;
120 
121  /*
122  * The queue is enabled, Execute each command in the queue.
123  * If one execution fails, abort the rest
124  */
125  auto it = m_queue.begin();
126 
127  while (it != m_queue.end()) {
128  std::shared_ptr<cmd> c = *it;
129 
131 
132  if (m_enabled) {
133  /*
134  * before we issue the command we must move it to the pending
135  * store
136  * ince a async event can be recieved before the command
137  * completes
138  */
139  rc = c->issue(m_conn);
140 
141  if (rc_t::OK == rc) {
142  /*
143  * move to the next
144  */
145  } else {
146  /*
147  * barf out without issuing the rest
148  */
149  VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string();
150  break;
151  }
152  } else {
153  /*
154  * The HW is disabled, so set each command as succeeded
155  */
156  c->succeeded();
157  }
158 
159  ++it;
160  }
161 
162  /*
163  * erase all objects in the queue
164  */
165  m_queue.erase(m_queue.begin(), m_queue.end());
166 
167  return (rc);
168 }
169 
170 /*
171  * The single Command Queue
172  */
173 HW::cmd_q* HW::m_cmdQ;
174 
175 /*
176  * single stat reader
177  */
178 stat_reader* HW::m_statReader;
179 HW::item<bool> HW::m_poll_state;
180 
181 /**
182  * Initialse the connection to VPP
183  */
184 void
186 {
187  m_cmdQ = f;
188  m_statReader = new stat_reader();
189 }
190 
191 /**
192  * Initialse the connection to VPP
193  */
194 void
196 {
197  m_cmdQ = f;
198  m_statReader = s;
199 }
200 
201 /**
202  * Initialse the connection to VPP
203  */
204 void
206 {
207  m_cmdQ = new cmd_q();
208  m_statReader = new stat_reader();
209 }
210 
211 void
213 {
214  m_cmdQ->enqueue(cmd);
215 }
216 
217 void
218 HW::enqueue(std::shared_ptr<cmd> cmd)
219 {
220  m_cmdQ->enqueue(cmd);
221 }
222 
223 void
224 HW::enqueue(std::queue<cmd*>& cmds)
225 {
226  m_cmdQ->enqueue(cmds);
227 }
228 
229 bool
231 {
232  return (m_cmdQ->connect() && m_statReader->connect());
233 }
234 
235 void
237 {
238  m_statReader->disconnect();
239  m_cmdQ->disconnect();
240 }
241 
242 void
243 HW::enable()
244 {
245  m_cmdQ->enable();
246 }
247 
248 void
249 HW::disable()
250 {
251  m_cmdQ->disable();
252 }
253 
254 rc_t
256 {
257  return (m_cmdQ->write());
258 }
259 
260 bool
262 {
263  std::shared_ptr<cmd> poll(new hw_cmds::poll(m_poll_state));
264 
265  HW::enqueue(poll);
266  HW::write();
267 
268  return (m_poll_state);
269 }
270 
271 void
273 {
274  m_statReader->read();
275 }
276 
277 template <>
280 {
281  std::ostringstream os;
282 
283  os << "hw-item:["
284  << "rc:" << item_rc.to_string() << " data:" << item_data << "]";
285  return (os.str());
286 }
287 
288 template <>
291 {
292  std::ostringstream os;
293 
294  os << "hw-item:["
295  << "rc:" << item_rc.to_string() << " data:" << item_data << "]";
296  return (os.str());
297 }
298 }
299 
300 /*
301  * fd.io coding-style-patch-verification: OFF
302  *
303  * Local Variables:
304  * eval: (c-set-style "mozilla")
305  * End:
306  */
#define VOM_LOG(lvl)
Definition: logger.hpp:181
static void read_stats()
read stats from stat segment
Definition: hw.cpp:272
const char *const string
Definition: cJSON.h:172
cmd_q()
Constructor.
Definition: hw.cpp:22
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
Error codes that VPP will return during a HW write.
Definition: types.hpp:89
static const log_level_t DEBUG
Definition: logger.hpp:32
A command poll the HW for liveness.
Definition: hw_cmds.hpp:30
virtual bool connect()
Blocking Connect to VPP - call once at bootup.
Definition: hw.cpp:76
std::string to_string() const
convert to string format for debug purposes
Definition: hw.hpp:161
#define false
Definition: cJSON.c:70
pthread_t thread[MAX_CONNS]
Definition: main.c:142
static bool connect()
Blocking Connect to VPP.
Definition: hw.cpp:230
virtual rc_t write()
Write all the commands to HW.
Definition: hw.cpp:117
void enable()
Enable the passing of commands to VPP - undoes the disable.
Definition: hw.cpp:105
The pipe to VPP into which we write the commands.
Definition: hw.hpp:187
cmd_q & operator=(const cmd_q &f)
Copy assignement - only used in UT.
Definition: hw.cpp:34
virtual void disconnect()
Disconnect to VPP.
Definition: hw.cpp:89
svmdb_client_t * c
vapi_error_e dispatch(const Common_req *limit=nullptr, u32 time=5)
wait for responses from vpp and assign them to appropriate objects
Definition: vapi.hpp:250
static void init()
Initialise the HW.
Definition: hw.cpp:205
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:109
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:212
static void disconnect()
Disconnect to VPP.
Definition: hw.cpp:236
void disconnect()
Blocking disconnect.
Definition: connection.cpp:32
static const log_level_t ERROR
Definition: logger.hpp:29
vapi::Connection & ctx()
Retrun the VAPI context the commands will use.
Definition: connection.cpp:49
~cmd_q()
Destructor.
Definition: hw.cpp:29
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
Stat reader: single interface to get stats.
Definition: stat_reader.hpp:29
A representation of a method call to VPP.
Definition: cmd.hpp:32
void disable()
Disable the passing of commands to VPP.
Definition: hw.cpp:111
int connect()
Blocking [re]connect call - always eventually succeeds, or the universe expires.
Definition: connection.cpp:38
save_rewrite_length must be aligned so that reass doesn t overwrite it
Definition: buffer.h:401
#define true
Definition: cJSON.c:65
virtual void enqueue(cmd *c)
Enqueue a command into the Q.
Definition: hw.cpp:51
static bool poll()
Blocking pool of the HW connection.
Definition: hw.cpp:261