Fix coverity warnings in VOM and VAPI
[vpp.git] / src / vpp-api / vom / interface_cmds.cpp
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/interface.hpp"
17 #include "vom/cmd.hpp"
18
19 DEFINE_VAPI_MSG_IDS_VPE_API_JSON;
20 DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
21 DEFINE_VAPI_MSG_IDS_AF_PACKET_API_JSON;
22 DEFINE_VAPI_MSG_IDS_TAP_API_JSON;
23 DEFINE_VAPI_MSG_IDS_STATS_API_JSON;
24
25 namespace VOM {
26 interface::loopback_create_cmd::loopback_create_cmd(HW::item<handle_t>& item,
27                                                     const std::string& name)
28   : create_cmd(item, name)
29 {
30 }
31
32 rc_t
33 interface::loopback_create_cmd::issue(connection& con)
34 {
35   msg_t req(con.ctx(), std::ref(*this));
36
37   VAPI_CALL(req.execute());
38
39   m_hw_item = wait();
40
41   if (m_hw_item.rc() == rc_t::OK) {
42     interface::add(m_name, m_hw_item);
43   }
44
45   return rc_t::OK;
46 }
47 std::string
48 interface::loopback_create_cmd::to_string() const
49 {
50   std::ostringstream s;
51   s << "loopback-itf-create: " << m_hw_item.to_string() << " name:" << m_name;
52
53   return (s.str());
54 }
55
56 interface::af_packet_create_cmd::af_packet_create_cmd(HW::item<handle_t>& item,
57                                                       const std::string& name)
58   : create_cmd(item, name)
59 {
60 }
61
62 rc_t
63 interface::af_packet_create_cmd::issue(connection& con)
64 {
65   msg_t req(con.ctx(), std::ref(*this));
66
67   auto& payload = req.get_request().get_payload();
68
69   payload.use_random_hw_addr = 1;
70   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
71   memcpy(payload.host_if_name, m_name.c_str(),
72          std::min(m_name.length(), sizeof(payload.host_if_name)));
73
74   VAPI_CALL(req.execute());
75
76   m_hw_item = wait();
77
78   if (m_hw_item.rc() == rc_t::OK) {
79     interface::add(m_name, m_hw_item);
80   }
81
82   return rc_t::OK;
83 }
84 std::string
85 interface::af_packet_create_cmd::to_string() const
86 {
87   std::ostringstream s;
88   s << "af-packet-itf-create: " << m_hw_item.to_string() << " name:" << m_name;
89
90   return (s.str());
91 }
92
93 interface::tap_create_cmd::tap_create_cmd(HW::item<handle_t>& item,
94                                           const std::string& name)
95   : create_cmd(item, name)
96 {
97 }
98
99 rc_t
100 interface::tap_create_cmd::issue(connection& con)
101 {
102   msg_t req(con.ctx(), std::ref(*this));
103
104   auto& payload = req.get_request().get_payload();
105
106   memset(payload.tap_name, 0, sizeof(payload.tap_name));
107   memcpy(payload.tap_name, m_name.c_str(),
108          std::min(m_name.length(), sizeof(payload.tap_name)));
109   payload.use_random_mac = 1;
110
111   VAPI_CALL(req.execute());
112
113   m_hw_item = wait();
114
115   if (m_hw_item.rc() == rc_t::OK) {
116     interface::add(m_name, m_hw_item);
117   }
118
119   return rc_t::OK;
120 }
121
122 std::string
123 interface::tap_create_cmd::to_string() const
124 {
125   std::ostringstream s;
126   s << "tap-intf-create: " << m_hw_item.to_string() << " name:" << m_name;
127
128   return (s.str());
129 }
130
131 interface::loopback_delete_cmd::loopback_delete_cmd(HW::item<handle_t>& item)
132   : delete_cmd(item)
133 {
134 }
135
136 rc_t
137 interface::loopback_delete_cmd::issue(connection& con)
138 {
139   msg_t req(con.ctx(), std::ref(*this));
140
141   auto& payload = req.get_request().get_payload();
142   payload.sw_if_index = m_hw_item.data().value();
143
144   VAPI_CALL(req.execute());
145
146   wait();
147   m_hw_item.set(rc_t::NOOP);
148
149   interface::remove(m_hw_item);
150   return rc_t::OK;
151 }
152
153 std::string
154 interface::loopback_delete_cmd::to_string() const
155 {
156   std::ostringstream s;
157   s << "loopback-itf-delete: " << m_hw_item.to_string();
158
159   return (s.str());
160 }
161
162 interface::af_packet_delete_cmd::af_packet_delete_cmd(HW::item<handle_t>& item,
163                                                       const std::string& name)
164   : delete_cmd(item, name)
165 {
166 }
167
168 rc_t
169 interface::af_packet_delete_cmd::issue(connection& con)
170 {
171   msg_t req(con.ctx(), std::ref(*this));
172
173   auto& payload = req.get_request().get_payload();
174   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
175   memcpy(payload.host_if_name, m_name.c_str(),
176          std::min(m_name.length(), sizeof(payload.host_if_name)));
177
178   VAPI_CALL(req.execute());
179
180   wait();
181   m_hw_item.set(rc_t::NOOP);
182
183   interface::remove(m_hw_item);
184   return rc_t::OK;
185 }
186 std::string
187 interface::af_packet_delete_cmd::to_string() const
188 {
189   std::ostringstream s;
190   s << "af_packet-itf-delete: " << m_hw_item.to_string();
191
192   return (s.str());
193 }
194
195 interface::tap_delete_cmd::tap_delete_cmd(HW::item<handle_t>& item)
196   : delete_cmd(item)
197 {
198 }
199
200 rc_t
201 interface::tap_delete_cmd::issue(connection& con)
202 {
203   // finally... call VPP
204
205   interface::remove(m_hw_item);
206   return rc_t::OK;
207 }
208 std::string
209 interface::tap_delete_cmd::to_string() const
210 {
211   std::ostringstream s;
212   s << "tap-itf-delete: " << m_hw_item.to_string();
213
214   return (s.str());
215 }
216
217 interface::state_change_cmd::state_change_cmd(
218   HW::item<interface::admin_state_t>& state,
219   const HW::item<handle_t>& hdl)
220   : rpc_cmd(state)
221   , m_hdl(hdl)
222 {
223 }
224
225 bool
226 interface::state_change_cmd::operator==(const state_change_cmd& other) const
227 {
228   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
229 }
230
231 rc_t
232 interface::state_change_cmd::issue(connection& con)
233 {
234   msg_t req(con.ctx(), std::ref(*this));
235
236   auto& payload = req.get_request().get_payload();
237   payload.sw_if_index = m_hdl.data().value();
238   payload.admin_up_down = m_hw_item.data().value();
239
240   VAPI_CALL(req.execute());
241
242   m_hw_item.set(wait());
243
244   return rc_t::OK;
245 }
246
247 std::string
248 interface::state_change_cmd::to_string() const
249 {
250   std::ostringstream s;
251   s << "itf-state-change: " << m_hw_item.to_string()
252     << " hdl:" << m_hdl.to_string();
253   return (s.str());
254 }
255
256 interface::set_table_cmd::set_table_cmd(HW::item<route::table_id_t>& table,
257                                         const l3_proto_t& proto,
258                                         const HW::item<handle_t>& hdl)
259   : rpc_cmd(table)
260   , m_hdl(hdl)
261   , m_proto(proto)
262 {
263 }
264
265 bool
266 interface::set_table_cmd::operator==(const set_table_cmd& other) const
267 {
268   return ((m_hdl == other.m_hdl) && (m_proto == other.m_proto) &&
269           (m_hw_item == other.m_hw_item));
270 }
271
272 rc_t
273 interface::set_table_cmd::issue(connection& con)
274 {
275   msg_t req(con.ctx(), std::ref(*this));
276
277   auto& payload = req.get_request().get_payload();
278   payload.sw_if_index = m_hdl.data().value();
279   payload.is_ipv6 = m_proto.is_ipv6();
280   payload.vrf_id = m_hw_item.data();
281
282   VAPI_CALL(req.execute());
283
284   m_hw_item.set(wait());
285
286   return (rc_t::OK);
287 }
288
289 std::string
290 interface::set_table_cmd::to_string() const
291 {
292   std::ostringstream s;
293   s << "itf-set-table: " << m_hw_item.to_string()
294     << " proto:" << m_proto.to_string() << " hdl:" << m_hdl.to_string();
295   return (s.str());
296 }
297
298 interface::set_mac_cmd::set_mac_cmd(HW::item<l2_address_t>& mac,
299                                     const HW::item<handle_t>& hdl)
300   : rpc_cmd(mac)
301   , m_hdl(hdl)
302 {
303 }
304
305 bool
306 interface::set_mac_cmd::operator==(const set_mac_cmd& other) const
307 {
308   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
309 }
310
311 rc_t
312 interface::set_mac_cmd::issue(connection& con)
313 {
314   msg_t req(con.ctx(), std::ref(*this));
315
316   auto& payload = req.get_request().get_payload();
317   payload.sw_if_index = m_hdl.data().value();
318   m_hw_item.data().to_mac().to_bytes(payload.mac_address,
319                                      sizeof(payload.mac_address));
320
321   VAPI_CALL(req.execute());
322
323   m_hw_item.set(wait());
324
325   return (rc_t::OK);
326 }
327
328 std::string
329 interface::set_mac_cmd::to_string() const
330 {
331   std::ostringstream s;
332   s << "itf-set-mac: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string();
333   return (s.str());
334 }
335
336 interface::events_cmd::events_cmd(event_listener& el)
337   : event_cmd(el.status())
338   , m_listener(el)
339 {
340 }
341
342 bool
343 interface::events_cmd::operator==(const events_cmd& other) const
344 {
345   return (true);
346 }
347
348 rc_t
349 interface::events_cmd::issue(connection& con)
350 {
351   /*
352  * First set the call back to handle the interface events
353  */
354   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
355
356   /*
357  * then send the request to enable them
358  */
359   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
360
361   auto& payload = req.get_request().get_payload();
362   payload.enable_disable = 1;
363   payload.pid = getpid();
364
365   VAPI_CALL(req.execute());
366
367   wait();
368
369   return (rc_t::INPROGRESS);
370 }
371
372 void
373 interface::events_cmd::retire(connection& con)
374 {
375   /*
376  * disable interface events.
377  */
378   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
379
380   auto& payload = req.get_request().get_payload();
381   payload.enable_disable = 0;
382   payload.pid = getpid();
383
384   VAPI_CALL(req.execute());
385
386   wait();
387 }
388
389 void
390 interface::events_cmd::notify()
391 {
392   m_listener.handle_interface_event(this);
393 }
394
395 std::string
396 interface::events_cmd::to_string() const
397 {
398   return ("itf-events");
399 }
400
401 /**
402  * Interface statistics
403  */
404 interface::stats_cmd::stats_cmd(stat_listener& el,
405                                 const std::vector<handle_t>& interfaces)
406   : event_cmd(el.status())
407   , m_listener(el)
408   , m_swifindex(interfaces)
409 {
410 }
411
412 bool
413 interface::stats_cmd::operator==(const stats_cmd& other) const
414 {
415   return (true);
416 }
417
418 rc_t
419 interface::stats_cmd::issue(connection& con)
420 {
421   /*
422  * First set the clal back to handle the interface stats
423  */
424   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
425   // m_reg->execute();
426
427   /*
428  * then send the request to enable them
429  */
430   msg_t req(con.ctx(), m_swifindex.size(),
431             std::ref(*(static_cast<rpc_cmd*>(this))));
432
433   auto& payload = req.get_request().get_payload();
434   payload.enable_disable = 1;
435   payload.pid = getpid();
436   payload.num = m_swifindex.size();
437
438   auto it = m_swifindex.cbegin();
439   uint32_t ii = 0;
440   while (it != m_swifindex.cend()) {
441     payload.sw_ifs[ii] = it->value();
442     ++it;
443     ++ii;
444   }
445
446   VAPI_CALL(req.execute());
447
448   wait();
449
450   return (rc_t::INPROGRESS);
451 }
452
453 void
454 interface::stats_cmd::retire(connection& con)
455 {
456 }
457
458 void
459 interface::stats_cmd::notify()
460 {
461   m_listener.handle_interface_stat(this);
462 }
463
464 std::string
465 interface::stats_cmd::to_string() const
466 {
467   return ("itf-stats");
468 }
469
470 interface::dump_cmd::dump_cmd()
471 {
472 }
473
474 bool
475 interface::dump_cmd::operator==(const dump_cmd& other) const
476 {
477   return (true);
478 }
479
480 rc_t
481 interface::dump_cmd::issue(connection& con)
482 {
483   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
484
485   auto& payload = m_dump->get_request().get_payload();
486   payload.name_filter_valid = 0;
487
488   VAPI_CALL(m_dump->execute());
489
490   wait();
491
492   return rc_t::OK;
493 }
494
495 std::string
496 interface::dump_cmd::to_string() const
497 {
498   return ("itf-dump");
499 }
500
501 interface::set_tag::set_tag(HW::item<handle_t>& item, const std::string& name)
502   : rpc_cmd(item)
503   , m_name(name)
504 {
505 }
506
507 rc_t
508 interface::set_tag::issue(connection& con)
509 {
510   msg_t req(con.ctx(), std::ref(*this));
511
512   auto& payload = req.get_request().get_payload();
513   payload.is_add = 1;
514   payload.sw_if_index = m_hw_item.data().value();
515   memcpy(payload.tag, m_name.c_str(), m_name.length());
516
517   VAPI_CALL(req.execute());
518
519   wait();
520
521   return rc_t::OK;
522 }
523 std::string
524 interface::set_tag::to_string() const
525 {
526   std::ostringstream s;
527   s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name;
528
529   return (s.str());
530 }
531
532 bool
533 interface::set_tag::operator==(const set_tag& o) const
534 {
535   return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data()));
536 }
537 }
538 /*
539  * fd.io coding-style-patch-verification: ON
540  *
541  * Local Variables:
542  * eval: (c-set-style "mozilla")
543  * End:
544  */