VPP-1204: Fix coverity warning
[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_cmds.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_VHOST_USER_API_JSON;
24 DEFINE_VAPI_MSG_IDS_STATS_API_JSON;
25
26 namespace VOM {
27 namespace interface_cmds {
28 loopback_create_cmd::loopback_create_cmd(HW::item<handle_t>& item,
29                                          const std::string& name)
30   : create_cmd(item, name)
31 {
32 }
33
34 rc_t
35 loopback_create_cmd::issue(connection& con)
36 {
37   msg_t req(con.ctx(), std::ref(*this));
38
39   VAPI_CALL(req.execute());
40
41   m_hw_item = wait();
42
43   if (m_hw_item.rc() == rc_t::OK) {
44     insert_interface();
45   }
46
47   return rc_t::OK;
48 }
49 std::string
50 loopback_create_cmd::to_string() const
51 {
52   std::ostringstream s;
53   s << "loopback-itf-create: " << m_hw_item.to_string() << " name:" << m_name;
54
55   return (s.str());
56 }
57
58 af_packet_create_cmd::af_packet_create_cmd(HW::item<handle_t>& item,
59                                            const std::string& name)
60   : create_cmd(item, name)
61 {
62 }
63
64 rc_t
65 af_packet_create_cmd::issue(connection& con)
66 {
67   msg_t req(con.ctx(), std::ref(*this));
68
69   auto& payload = req.get_request().get_payload();
70
71   payload.use_random_hw_addr = 1;
72   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
73   memcpy(payload.host_if_name, m_name.c_str(),
74          std::min(m_name.length(), sizeof(payload.host_if_name)));
75
76   VAPI_CALL(req.execute());
77
78   m_hw_item = wait();
79
80   if (m_hw_item.rc() == rc_t::OK) {
81     insert_interface();
82   }
83
84   return rc_t::OK;
85 }
86 std::string
87 af_packet_create_cmd::to_string() const
88 {
89   std::ostringstream s;
90   s << "af-packet-itf-create: " << m_hw_item.to_string() << " name:" << m_name;
91
92   return (s.str());
93 }
94
95 tap_create_cmd::tap_create_cmd(HW::item<handle_t>& item,
96                                const std::string& name)
97   : create_cmd(item, name)
98 {
99 }
100
101 rc_t
102 tap_create_cmd::issue(connection& con)
103 {
104   msg_t req(con.ctx(), std::ref(*this));
105
106   auto& payload = req.get_request().get_payload();
107
108   memset(payload.tap_name, 0, sizeof(payload.tap_name));
109   memcpy(payload.tap_name, m_name.c_str(),
110          std::min(m_name.length(), sizeof(payload.tap_name)));
111   payload.use_random_mac = 1;
112
113   VAPI_CALL(req.execute());
114
115   m_hw_item = wait();
116
117   if (m_hw_item.rc() == rc_t::OK) {
118     insert_interface();
119   }
120
121   return rc_t::OK;
122 }
123
124 std::string
125 tap_create_cmd::to_string() const
126 {
127   std::ostringstream s;
128   s << "tap-intf-create: " << m_hw_item.to_string() << " name:" << m_name;
129
130   return (s.str());
131 }
132
133 vhost_create_cmd::vhost_create_cmd(HW::item<handle_t>& item,
134                                    const std::string& name,
135                                    const std::string& tag)
136   : create_cmd(item, name)
137   , m_tag(tag)
138 {
139 }
140
141 rc_t
142 vhost_create_cmd::issue(connection& con)
143 {
144   msg_t req(con.ctx(), std::ref(*this));
145
146   auto& payload = req.get_request().get_payload();
147   memset(payload.sock_filename, 0, sizeof(payload.sock_filename));
148   memcpy(payload.sock_filename, m_name.c_str(),
149          std::min(m_name.length(), sizeof(payload.sock_filename)));
150   memset(payload.tag, 0, sizeof(payload.tag));
151
152   if (!m_tag.empty())
153     memcpy(payload.tag, m_tag.c_str(),
154            std::min(m_tag.length(), sizeof(payload.tag)));
155
156   payload.is_server = 1;
157   payload.use_custom_mac = 0;
158   payload.renumber = 0;
159
160   VAPI_CALL(req.execute());
161
162   m_hw_item = wait();
163
164   if (m_hw_item.rc() == rc_t::OK) {
165     insert_interface();
166   }
167
168   return rc_t::OK;
169 }
170
171 std::string
172 vhost_create_cmd::to_string() const
173 {
174   std::ostringstream s;
175   s << "vhost-intf-create: " << m_hw_item.to_string() << " name:" << m_name
176     << " tag:" << m_tag;
177
178   return (s.str());
179 }
180
181 loopback_delete_cmd::loopback_delete_cmd(HW::item<handle_t>& item)
182   : delete_cmd(item)
183 {
184 }
185
186 rc_t
187 loopback_delete_cmd::issue(connection& con)
188 {
189   msg_t req(con.ctx(), std::ref(*this));
190
191   auto& payload = req.get_request().get_payload();
192   payload.sw_if_index = m_hw_item.data().value();
193
194   VAPI_CALL(req.execute());
195
196   wait();
197   m_hw_item.set(rc_t::NOOP);
198
199   remove_interface();
200   return rc_t::OK;
201 }
202
203 std::string
204 loopback_delete_cmd::to_string() const
205 {
206   std::ostringstream s;
207   s << "loopback-itf-delete: " << m_hw_item.to_string();
208
209   return (s.str());
210 }
211
212 af_packet_delete_cmd::af_packet_delete_cmd(HW::item<handle_t>& item,
213                                            const std::string& name)
214   : delete_cmd(item, name)
215 {
216 }
217
218 rc_t
219 af_packet_delete_cmd::issue(connection& con)
220 {
221   msg_t req(con.ctx(), std::ref(*this));
222
223   auto& payload = req.get_request().get_payload();
224   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
225   memcpy(payload.host_if_name, m_name.c_str(),
226          std::min(m_name.length(), sizeof(payload.host_if_name)));
227
228   VAPI_CALL(req.execute());
229
230   wait();
231   m_hw_item.set(rc_t::NOOP);
232
233   remove_interface();
234   return rc_t::OK;
235 }
236 std::string
237 af_packet_delete_cmd::to_string() const
238 {
239   std::ostringstream s;
240   s << "af_packet-itf-delete: " << m_hw_item.to_string();
241
242   return (s.str());
243 }
244
245 tap_delete_cmd::tap_delete_cmd(HW::item<handle_t>& item)
246   : delete_cmd(item)
247 {
248 }
249
250 rc_t
251 tap_delete_cmd::issue(connection& con)
252 {
253   // finally... call VPP
254
255   remove_interface();
256   return rc_t::OK;
257 }
258 std::string
259 tap_delete_cmd::to_string() const
260 {
261   std::ostringstream s;
262   s << "tap-itf-delete: " << m_hw_item.to_string();
263
264   return (s.str());
265 }
266
267 vhost_delete_cmd::vhost_delete_cmd(HW::item<handle_t>& item,
268                                    const std::string& name)
269   : delete_cmd(item, name)
270 {
271 }
272
273 rc_t
274 vhost_delete_cmd::issue(connection& con)
275 {
276   msg_t req(con.ctx(), std::ref(*this));
277
278   auto& payload = req.get_request().get_payload();
279   payload.sw_if_index = m_hw_item.data().value();
280
281   VAPI_CALL(req.execute());
282
283   wait();
284
285   return rc_t::OK;
286 }
287 std::string
288 vhost_delete_cmd::to_string() const
289 {
290   std::ostringstream s;
291   s << "vhost-itf-delete: " << m_hw_item.to_string() << " name:" << m_name;
292
293   return (s.str());
294 }
295
296 state_change_cmd::state_change_cmd(HW::item<interface::admin_state_t>& state,
297                                    const HW::item<handle_t>& hdl)
298   : rpc_cmd(state)
299   , m_hdl(hdl)
300 {
301 }
302
303 bool
304 state_change_cmd::operator==(const state_change_cmd& other) const
305 {
306   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
307 }
308
309 rc_t
310 state_change_cmd::issue(connection& con)
311 {
312   msg_t req(con.ctx(), std::ref(*this));
313
314   auto& payload = req.get_request().get_payload();
315   payload.sw_if_index = m_hdl.data().value();
316   payload.admin_up_down = m_hw_item.data().value();
317
318   VAPI_CALL(req.execute());
319
320   m_hw_item.set(wait());
321
322   return rc_t::OK;
323 }
324
325 std::string
326 state_change_cmd::to_string() const
327 {
328   std::ostringstream s;
329   s << "itf-state-change: " << m_hw_item.to_string()
330     << " hdl:" << m_hdl.to_string();
331   return (s.str());
332 }
333
334 set_table_cmd::set_table_cmd(HW::item<route::table_id_t>& table,
335                              const l3_proto_t& proto,
336                              const HW::item<handle_t>& hdl)
337   : rpc_cmd(table)
338   , m_hdl(hdl)
339   , m_proto(proto)
340 {
341 }
342
343 bool
344 set_table_cmd::operator==(const set_table_cmd& other) const
345 {
346   return ((m_hdl == other.m_hdl) && (m_proto == other.m_proto) &&
347           (m_hw_item == other.m_hw_item));
348 }
349
350 rc_t
351 set_table_cmd::issue(connection& con)
352 {
353   msg_t req(con.ctx(), std::ref(*this));
354
355   auto& payload = req.get_request().get_payload();
356   payload.sw_if_index = m_hdl.data().value();
357   payload.is_ipv6 = m_proto.is_ipv6();
358   payload.vrf_id = m_hw_item.data();
359
360   VAPI_CALL(req.execute());
361
362   m_hw_item.set(wait());
363
364   return (rc_t::OK);
365 }
366
367 std::string
368 set_table_cmd::to_string() const
369 {
370   std::ostringstream s;
371   s << "itf-set-table: " << m_hw_item.to_string()
372     << " proto:" << m_proto.to_string() << " hdl:" << m_hdl.to_string();
373   return (s.str());
374 }
375
376 set_mac_cmd::set_mac_cmd(HW::item<l2_address_t>& mac,
377                          const HW::item<handle_t>& hdl)
378   : rpc_cmd(mac)
379   , m_hdl(hdl)
380 {
381 }
382
383 bool
384 set_mac_cmd::operator==(const set_mac_cmd& other) const
385 {
386   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
387 }
388
389 rc_t
390 set_mac_cmd::issue(connection& con)
391 {
392   msg_t req(con.ctx(), std::ref(*this));
393
394   auto& payload = req.get_request().get_payload();
395   payload.sw_if_index = m_hdl.data().value();
396   m_hw_item.data().to_mac().to_bytes(payload.mac_address,
397                                      sizeof(payload.mac_address));
398
399   VAPI_CALL(req.execute());
400
401   m_hw_item.set(wait());
402
403   return (rc_t::OK);
404 }
405
406 std::string
407 set_mac_cmd::to_string() const
408 {
409   std::ostringstream s;
410   s << "itf-set-mac: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string();
411   return (s.str());
412 }
413
414 events_cmd::events_cmd(interface::event_listener& el)
415   : event_cmd(el.status())
416   , m_listener(el)
417 {
418 }
419
420 bool
421 events_cmd::operator==(const events_cmd& other) const
422 {
423   return (true);
424 }
425
426 rc_t
427 events_cmd::issue(connection& con)
428 {
429   /*
430  * First set the call back to handle the interface events
431  */
432   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
433
434   /*
435  * then send the request to enable them
436  */
437   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
438
439   auto& payload = req.get_request().get_payload();
440   payload.enable_disable = 1;
441   payload.pid = getpid();
442
443   VAPI_CALL(req.execute());
444
445   wait();
446
447   return (rc_t::OK);
448 }
449
450 void
451 events_cmd::retire(connection& con)
452 {
453   /*
454  * disable interface events.
455  */
456   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
457
458   auto& payload = req.get_request().get_payload();
459   payload.enable_disable = 0;
460   payload.pid = getpid();
461
462   VAPI_CALL(req.execute());
463
464   wait();
465 }
466
467 void
468 events_cmd::notify()
469 {
470   m_listener.handle_interface_event(this);
471 }
472
473 std::string
474 events_cmd::to_string() const
475 {
476   return ("itf-events");
477 }
478
479 /**
480  * Interface statistics
481  */
482 stats_enable_cmd::stats_enable_cmd(interface::stat_listener& el,
483                                    const handle_t& handle)
484   : event_cmd(el.status())
485   , m_listener(el)
486   , m_swifindex(handle)
487 {
488 }
489
490 bool
491 stats_enable_cmd::operator==(const stats_enable_cmd& other) const
492 {
493   return (true);
494 }
495
496 rc_t
497 stats_enable_cmd::issue(connection& con)
498 {
499   /*
500    * First set the call back to handle the interface stats
501    */
502   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
503
504   /*
505    * then send the request to enable them
506    */
507   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
508
509   auto& payload = req.get_request().get_payload();
510   payload.enable_disable = 1;
511   payload.pid = getpid();
512   payload.num = 1;
513
514   payload.sw_ifs[0] = m_swifindex.value();
515
516   VAPI_CALL(req.execute());
517
518   wait();
519
520   return (rc_t::OK);
521 }
522
523 void
524 stats_enable_cmd::retire(connection& con)
525 {
526   /*
527    * disable interface stats.
528    */
529   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
530
531   auto& payload = req.get_request().get_payload();
532   payload.enable_disable = 0;
533   payload.pid = getpid();
534   payload.num = 1;
535   payload.sw_ifs[0] = m_swifindex.value();
536
537   VAPI_CALL(req.execute());
538
539   wait();
540 }
541
542 void
543 stats_enable_cmd::notify()
544 {
545   m_listener.handle_interface_stat(this);
546 }
547
548 std::string
549 stats_enable_cmd::to_string() const
550 {
551   std::ostringstream s;
552   s << "itf-stats-enable itf:" << m_swifindex.to_string();
553   return (s.str());
554 }
555
556 stats_disable_cmd::stats_disable_cmd(const handle_t& handle)
557   : rpc_cmd(m_res)
558   , m_swifindex(handle)
559 {
560 }
561
562 bool
563 stats_disable_cmd::operator==(const stats_disable_cmd& other) const
564 {
565   return (true);
566 }
567
568 rc_t
569 stats_disable_cmd::issue(connection& con)
570 {
571   /*
572    * then send the request to enable them
573    */
574   msg_t req(con.ctx(), 1, std::ref(*this));
575
576   auto& payload = req.get_request().get_payload();
577   payload.enable_disable = 0;
578   payload.pid = getpid();
579   payload.num = 1;
580
581   payload.sw_ifs[0] = m_swifindex.value();
582
583   VAPI_CALL(req.execute());
584
585   wait();
586
587   return (rc_t::OK);
588 }
589
590 std::string
591 stats_disable_cmd::to_string() const
592 {
593   std::ostringstream s;
594   s << "itf-stats-disable itf:" << m_swifindex.to_string();
595   return (s.str());
596 }
597
598 dump_cmd::dump_cmd()
599 {
600 }
601
602 bool
603 dump_cmd::operator==(const dump_cmd& other) const
604 {
605   return (true);
606 }
607
608 rc_t
609 dump_cmd::issue(connection& con)
610 {
611   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
612
613   auto& payload = m_dump->get_request().get_payload();
614   payload.name_filter_valid = 0;
615
616   VAPI_CALL(m_dump->execute());
617
618   wait();
619
620   return rc_t::OK;
621 }
622
623 std::string
624 dump_cmd::to_string() const
625 {
626   return ("itf-dump");
627 }
628
629 vhost_dump_cmd::vhost_dump_cmd()
630 {
631 }
632
633 bool
634 vhost_dump_cmd::operator==(const vhost_dump_cmd& other) const
635 {
636   return (true);
637 }
638
639 rc_t
640 vhost_dump_cmd::issue(connection& con)
641 {
642   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
643
644   VAPI_CALL(m_dump->execute());
645
646   wait();
647
648   return rc_t::OK;
649 }
650
651 std::string
652 vhost_dump_cmd::to_string() const
653 {
654   return ("vhost-itf-dump");
655 }
656
657 set_tag::set_tag(HW::item<handle_t>& item, const std::string& name)
658   : rpc_cmd(item)
659   , m_name(name)
660 {
661 }
662
663 rc_t
664 set_tag::issue(connection& con)
665 {
666   msg_t req(con.ctx(), std::ref(*this));
667
668   auto& payload = req.get_request().get_payload();
669   payload.is_add = 1;
670   payload.sw_if_index = m_hw_item.data().value();
671   memcpy(payload.tag, m_name.c_str(), m_name.length());
672
673   VAPI_CALL(req.execute());
674
675   wait();
676
677   return rc_t::OK;
678 }
679 std::string
680 set_tag::to_string() const
681 {
682   std::ostringstream s;
683   s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name;
684
685   return (s.str());
686 }
687
688 bool
689 set_tag::operator==(const set_tag& o) const
690 {
691   return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data()));
692 }
693 }; // namespace interface_cmds
694 }; // namespace VOM
695
696 /*
697  * fd.io coding-style-patch-verification: ON
698  *
699  * Local Variables:
700  * eval: (c-set-style "mozilla")
701  * End:
702  */