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