API: Cleanup APIs interface.api
[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
24 namespace VOM {
25 namespace interface_cmds {
26 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 loopback_create_cmd::issue(connection& con)
34 {
35   msg_t req(con.ctx(), std::ref(*this));
36
37   VAPI_CALL(req.execute());
38
39   wait();
40
41   if (m_hw_item.rc() == rc_t::OK) {
42     insert_interface();
43   }
44
45   return rc_t::OK;
46 }
47 std::string
48 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 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 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   wait();
77
78   if (m_hw_item.rc() == rc_t::OK) {
79     insert_interface();
80   }
81
82   return rc_t::OK;
83 }
84 std::string
85 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 vhost_create_cmd::vhost_create_cmd(HW::item<handle_t>& item,
94                                    const std::string& name,
95                                    const std::string& tag)
96   : create_cmd(item, name)
97   , m_tag(tag)
98 {
99 }
100
101 rc_t
102 vhost_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   memset(payload.sock_filename, 0, sizeof(payload.sock_filename));
108   memcpy(payload.sock_filename, m_name.c_str(),
109          std::min(m_name.length(), sizeof(payload.sock_filename)));
110   memset(payload.tag, 0, sizeof(payload.tag));
111
112   if (!m_tag.empty())
113     memcpy(payload.tag, m_tag.c_str(),
114            std::min(m_tag.length(), sizeof(payload.tag)));
115
116   payload.is_server = 0;
117   payload.use_custom_mac = 0;
118   payload.renumber = 0;
119
120   VAPI_CALL(req.execute());
121
122   wait();
123
124   if (m_hw_item.rc() == rc_t::OK) {
125     insert_interface();
126   }
127
128   return rc_t::OK;
129 }
130
131 std::string
132 vhost_create_cmd::to_string() const
133 {
134   std::ostringstream s;
135   s << "vhost-intf-create: " << m_hw_item.to_string() << " name:" << m_name
136     << " tag:" << m_tag;
137
138   return (s.str());
139 }
140
141 loopback_delete_cmd::loopback_delete_cmd(HW::item<handle_t>& item)
142   : delete_cmd(item)
143 {
144 }
145
146 rc_t
147 loopback_delete_cmd::issue(connection& con)
148 {
149   msg_t req(con.ctx(), std::ref(*this));
150
151   auto& payload = req.get_request().get_payload();
152   payload.sw_if_index = m_hw_item.data().value();
153
154   VAPI_CALL(req.execute());
155
156   wait();
157   m_hw_item.set(rc_t::NOOP);
158
159   remove_interface();
160   return rc_t::OK;
161 }
162
163 std::string
164 loopback_delete_cmd::to_string() const
165 {
166   std::ostringstream s;
167   s << "loopback-itf-delete: " << m_hw_item.to_string();
168
169   return (s.str());
170 }
171
172 af_packet_delete_cmd::af_packet_delete_cmd(HW::item<handle_t>& item,
173                                            const std::string& name)
174   : delete_cmd(item, name)
175 {
176 }
177
178 rc_t
179 af_packet_delete_cmd::issue(connection& con)
180 {
181   msg_t req(con.ctx(), std::ref(*this));
182
183   auto& payload = req.get_request().get_payload();
184   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
185   memcpy(payload.host_if_name, m_name.c_str(),
186          std::min(m_name.length(), sizeof(payload.host_if_name)));
187
188   VAPI_CALL(req.execute());
189
190   wait();
191   m_hw_item.set(rc_t::NOOP);
192
193   remove_interface();
194   return rc_t::OK;
195 }
196 std::string
197 af_packet_delete_cmd::to_string() const
198 {
199   std::ostringstream s;
200   s << "af_packet-itf-delete: " << m_hw_item.to_string();
201
202   return (s.str());
203 }
204
205 vhost_delete_cmd::vhost_delete_cmd(HW::item<handle_t>& item,
206                                    const std::string& name)
207   : delete_cmd(item, name)
208 {
209 }
210
211 rc_t
212 vhost_delete_cmd::issue(connection& con)
213 {
214   msg_t req(con.ctx(), std::ref(*this));
215
216   auto& payload = req.get_request().get_payload();
217   payload.sw_if_index = m_hw_item.data().value();
218
219   VAPI_CALL(req.execute());
220
221   wait();
222   remove_interface();
223
224   return rc_t::OK;
225 }
226 std::string
227 vhost_delete_cmd::to_string() const
228 {
229   std::ostringstream s;
230   s << "vhost-itf-delete: " << m_hw_item.to_string() << " name:" << m_name;
231
232   return (s.str());
233 }
234
235 state_change_cmd::state_change_cmd(HW::item<interface::admin_state_t>& state,
236                                    const HW::item<handle_t>& hdl)
237   : rpc_cmd(state)
238   , m_hdl(hdl)
239 {
240 }
241
242 bool
243 state_change_cmd::operator==(const state_change_cmd& other) const
244 {
245   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
246 }
247
248 rc_t
249 state_change_cmd::issue(connection& con)
250 {
251   msg_t req(con.ctx(), std::ref(*this));
252
253   auto& payload = req.get_request().get_payload();
254   payload.sw_if_index = m_hdl.data().value();
255   payload.flags = (vapi_enum_if_status_flags)m_hw_item.data().value();
256
257   VAPI_CALL(req.execute());
258
259   return (wait());
260 }
261
262 std::string
263 state_change_cmd::to_string() const
264 {
265   std::ostringstream s;
266   s << "itf-state-change: " << m_hw_item.to_string()
267     << " hdl:" << m_hdl.to_string();
268   return (s.str());
269 }
270
271 set_table_cmd::set_table_cmd(HW::item<route::table_id_t>& table,
272                              const l3_proto_t& proto,
273                              const HW::item<handle_t>& hdl)
274   : rpc_cmd(table)
275   , m_hdl(hdl)
276   , m_proto(proto)
277 {
278 }
279
280 bool
281 set_table_cmd::operator==(const set_table_cmd& other) const
282 {
283   return ((m_hdl == other.m_hdl) && (m_proto == other.m_proto) &&
284           (m_hw_item == other.m_hw_item));
285 }
286
287 rc_t
288 set_table_cmd::issue(connection& con)
289 {
290   msg_t req(con.ctx(), std::ref(*this));
291
292   auto& payload = req.get_request().get_payload();
293   payload.sw_if_index = m_hdl.data().value();
294   payload.is_ipv6 = m_proto.is_ipv6();
295   payload.vrf_id = m_hw_item.data();
296
297   VAPI_CALL(req.execute());
298
299   return (wait());
300 }
301
302 std::string
303 set_table_cmd::to_string() const
304 {
305   std::ostringstream s;
306   s << "itf-set-table: " << m_hw_item.to_string()
307     << " proto:" << m_proto.to_string() << " hdl:" << m_hdl.to_string();
308   return (s.str());
309 }
310
311 set_mac_cmd::set_mac_cmd(HW::item<l2_address_t>& mac,
312                          const HW::item<handle_t>& hdl)
313   : rpc_cmd(mac)
314   , m_hdl(hdl)
315 {
316 }
317
318 bool
319 set_mac_cmd::operator==(const set_mac_cmd& other) const
320 {
321   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item));
322 }
323
324 rc_t
325 set_mac_cmd::issue(connection& con)
326 {
327   msg_t req(con.ctx(), std::ref(*this));
328
329   auto& payload = req.get_request().get_payload();
330   payload.sw_if_index = m_hdl.data().value();
331   m_hw_item.data().to_mac().to_bytes(payload.mac_address,
332                                      sizeof(payload.mac_address));
333
334   VAPI_CALL(req.execute());
335
336   return (wait());
337 }
338
339 std::string
340 set_mac_cmd::to_string() const
341 {
342   std::ostringstream s;
343   s << "itf-set-mac: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string();
344   return (s.str());
345 }
346
347 collect_detail_stats_change_cmd::collect_detail_stats_change_cmd(
348   HW::item<interface::stats_type_t>& item,
349   const handle_t& hdl,
350   bool enable)
351   : rpc_cmd(item)
352   , m_hdl(hdl)
353   , m_enable(enable)
354 {
355 }
356
357 bool
358 collect_detail_stats_change_cmd::operator==(
359   const collect_detail_stats_change_cmd& other) const
360 {
361   return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item) &&
362           (m_enable == other.m_enable));
363 }
364
365 rc_t
366 collect_detail_stats_change_cmd::issue(connection& con)
367 {
368   msg_t req(con.ctx(), std::ref(*this));
369
370   auto& payload = req.get_request().get_payload();
371   payload.sw_if_index = m_hdl.value();
372   payload.enable_disable = m_enable;
373
374   VAPI_CALL(req.execute());
375
376   return (wait());
377 }
378
379 std::string
380 collect_detail_stats_change_cmd::to_string() const
381 {
382   std::ostringstream s;
383   s << "itf-stats: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string();
384   return (s.str());
385 }
386
387 events_cmd::events_cmd(interface::event_listener& el)
388   : event_cmd(el.status())
389   , m_listener(el)
390 {
391 }
392
393 bool
394 events_cmd::operator==(const events_cmd& other) const
395 {
396   return (true);
397 }
398
399 rc_t
400 events_cmd::issue(connection& con)
401 {
402   /*
403    * First set the call back to handle the interface events
404    */
405   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
406
407   /*
408    * then send the request to enable them
409    */
410   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
411
412   auto& payload = req.get_request().get_payload();
413   payload.enable_disable = 1;
414   payload.pid = getpid();
415
416   VAPI_CALL(req.execute());
417
418   wait();
419
420   return (rc_t::OK);
421 }
422
423 void
424 events_cmd::retire(connection& con)
425 {
426   /*
427    * disable interface events.
428    */
429   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
430
431   auto& payload = req.get_request().get_payload();
432   payload.enable_disable = 0;
433   payload.pid = getpid();
434
435   VAPI_CALL(req.execute());
436
437   wait();
438 }
439
440 void
441 events_cmd::notify()
442 {
443   std::lock_guard<interface_cmds::events_cmd> lg(*this);
444   std::vector<interface::event> events;
445
446   for (auto& msg : *this) {
447     auto& payload = msg.get_payload();
448
449     handle_t handle(payload.sw_if_index);
450     std::shared_ptr<interface> sp = interface::find(handle);
451
452     if (sp) {
453       interface::oper_state_t oper_state = interface::oper_state_t::from_int(
454         payload.flags & vapi_enum_if_status_flags::IF_STATUS_API_FLAG_LINK_UP);
455
456       VOM_LOG(log_level_t::DEBUG) << "Interface Event: " << sp->to_string()
457                                   << " state: " << oper_state.to_string();
458
459       sp->set(oper_state);
460       events.push_back({ *sp, oper_state });
461     }
462   }
463
464   flush();
465
466   m_listener.handle_interface_event(events);
467 }
468
469 std::string
470 events_cmd::to_string() const
471 {
472   return ("itf-events");
473 }
474
475 dump_cmd::dump_cmd()
476 {
477 }
478
479 bool
480 dump_cmd::operator==(const dump_cmd& other) const
481 {
482   return (true);
483 }
484
485 rc_t
486 dump_cmd::issue(connection& con)
487 {
488   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
489
490   auto& payload = m_dump->get_request().get_payload();
491   payload.name_filter_valid = 0;
492
493   VAPI_CALL(m_dump->execute());
494
495   wait();
496
497   return rc_t::OK;
498 }
499
500 std::string
501 dump_cmd::to_string() const
502 {
503   return ("itf-dump");
504 }
505
506 vhost_dump_cmd::vhost_dump_cmd()
507 {
508 }
509
510 bool
511 vhost_dump_cmd::operator==(const vhost_dump_cmd& other) const
512 {
513   return (true);
514 }
515
516 rc_t
517 vhost_dump_cmd::issue(connection& con)
518 {
519   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
520
521   VAPI_CALL(m_dump->execute());
522
523   wait();
524
525   return rc_t::OK;
526 }
527
528 std::string
529 vhost_dump_cmd::to_string() const
530 {
531   return ("vhost-itf-dump");
532 }
533
534 bool
535 af_packet_dump_cmd::operator==(const af_packet_dump_cmd& other) const
536 {
537   return (true);
538 }
539
540 rc_t
541 af_packet_dump_cmd::issue(connection& con)
542 {
543   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
544
545   VAPI_CALL(m_dump->execute());
546
547   wait();
548
549   return rc_t::OK;
550 }
551
552 std::string
553 af_packet_dump_cmd::to_string() const
554 {
555   return ("af-packet-itf-dump");
556 }
557
558 set_tag::set_tag(HW::item<handle_t>& item, const std::string& name)
559   : rpc_cmd(item)
560   , m_name(name)
561 {
562 }
563
564 rc_t
565 set_tag::issue(connection& con)
566 {
567   msg_t req(con.ctx(), std::ref(*this));
568
569   auto& payload = req.get_request().get_payload();
570   payload.is_add = 1;
571   payload.sw_if_index = m_hw_item.data().value();
572   memset(payload.tag.buf, 0, payload.tag.length);
573   memcpy(payload.tag.buf, m_name.c_str(), m_name.length());
574
575   VAPI_CALL(req.execute());
576
577   return (wait());
578 }
579 std::string
580 set_tag::to_string() const
581 {
582   std::ostringstream s;
583   s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name;
584
585   return (s.str());
586 }
587
588 bool
589 set_tag::operator==(const set_tag& o) const
590 {
591   return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data()));
592 }
593 }; // namespace interface_cmds
594 }; // namespace VOM
595
596 /*
597  * fd.io coding-style-patch-verification: ON
598  *
599  * Local Variables:
600  * eval: (c-set-style "mozilla")
601  * End:
602  */