VOM: logging, populate and stats fixes
[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_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 tap_create_cmd::tap_create_cmd(HW::item<handle_t>& item,
95                                const std::string& name)
96   : create_cmd(item, name)
97 {
98 }
99
100 rc_t
101 tap_create_cmd::issue(connection& con)
102 {
103   msg_t req(con.ctx(), std::ref(*this));
104
105   auto& payload = req.get_request().get_payload();
106
107   memset(payload.tap_name, 0, sizeof(payload.tap_name));
108   memcpy(payload.tap_name, m_name.c_str(),
109          std::min(m_name.length(), sizeof(payload.tap_name)));
110   payload.use_random_mac = 1;
111
112   VAPI_CALL(req.execute());
113
114   m_hw_item = wait();
115
116   if (m_hw_item.rc() == rc_t::OK) {
117     insert_interface();
118   }
119
120   return rc_t::OK;
121 }
122
123 std::string
124 tap_create_cmd::to_string() const
125 {
126   std::ostringstream s;
127   s << "tap-intf-create: " << m_hw_item.to_string() << " name:" << m_name;
128
129   return (s.str());
130 }
131
132 loopback_delete_cmd::loopback_delete_cmd(HW::item<handle_t>& item)
133   : delete_cmd(item)
134 {
135 }
136
137 rc_t
138 loopback_delete_cmd::issue(connection& con)
139 {
140   msg_t req(con.ctx(), std::ref(*this));
141
142   auto& payload = req.get_request().get_payload();
143   payload.sw_if_index = m_hw_item.data().value();
144
145   VAPI_CALL(req.execute());
146
147   wait();
148   m_hw_item.set(rc_t::NOOP);
149
150   remove_interface();
151   return rc_t::OK;
152 }
153
154 std::string
155 loopback_delete_cmd::to_string() const
156 {
157   std::ostringstream s;
158   s << "loopback-itf-delete: " << m_hw_item.to_string();
159
160   return (s.str());
161 }
162
163 af_packet_delete_cmd::af_packet_delete_cmd(HW::item<handle_t>& item,
164                                            const std::string& name)
165   : delete_cmd(item, name)
166 {
167 }
168
169 rc_t
170 af_packet_delete_cmd::issue(connection& con)
171 {
172   msg_t req(con.ctx(), std::ref(*this));
173
174   auto& payload = req.get_request().get_payload();
175   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
176   memcpy(payload.host_if_name, m_name.c_str(),
177          std::min(m_name.length(), sizeof(payload.host_if_name)));
178
179   VAPI_CALL(req.execute());
180
181   wait();
182   m_hw_item.set(rc_t::NOOP);
183
184   remove_interface();
185   return rc_t::OK;
186 }
187 std::string
188 af_packet_delete_cmd::to_string() const
189 {
190   std::ostringstream s;
191   s << "af_packet-itf-delete: " << m_hw_item.to_string();
192
193   return (s.str());
194 }
195
196 tap_delete_cmd::tap_delete_cmd(HW::item<handle_t>& item)
197   : delete_cmd(item)
198 {
199 }
200
201 rc_t
202 tap_delete_cmd::issue(connection& con)
203 {
204   // finally... call VPP
205
206   remove_interface();
207   return rc_t::OK;
208 }
209 std::string
210 tap_delete_cmd::to_string() const
211 {
212   std::ostringstream s;
213   s << "tap-itf-delete: " << m_hw_item.to_string();
214
215   return (s.str());
216 }
217
218 state_change_cmd::state_change_cmd(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 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 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 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 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 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 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 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 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 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 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 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 events_cmd::events_cmd(interface::event_listener& el)
337   : event_cmd(el.status())
338   , m_listener(el)
339 {
340 }
341
342 bool
343 events_cmd::operator==(const events_cmd& other) const
344 {
345   return (true);
346 }
347
348 rc_t
349 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::OK);
370 }
371
372 void
373 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 events_cmd::notify()
391 {
392   m_listener.handle_interface_event(this);
393 }
394
395 std::string
396 events_cmd::to_string() const
397 {
398   return ("itf-events");
399 }
400
401 /**
402  * Interface statistics
403  */
404 stats_enable_cmd::stats_enable_cmd(interface::stat_listener& el,
405                                    const handle_t& handle)
406   : event_cmd(el.status())
407   , m_listener(el)
408   , m_swifindex(handle)
409 {
410 }
411
412 bool
413 stats_enable_cmd::operator==(const stats_enable_cmd& other) const
414 {
415   return (true);
416 }
417
418 rc_t
419 stats_enable_cmd::issue(connection& con)
420 {
421   /*
422    * First set the call back to handle the interface stats
423    */
424   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
425
426   /*
427    * then send the request to enable them
428    */
429   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
430
431   auto& payload = req.get_request().get_payload();
432   payload.enable_disable = 1;
433   payload.pid = getpid();
434   payload.num = 1;
435
436   payload.sw_ifs[0] = m_swifindex.value();
437
438   VAPI_CALL(req.execute());
439
440   wait();
441
442   return (rc_t::OK);
443 }
444
445 void
446 stats_enable_cmd::retire(connection& con)
447 {
448   /*
449    * disable interface stats.
450    */
451   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
452
453   auto& payload = req.get_request().get_payload();
454   payload.enable_disable = 0;
455   payload.pid = getpid();
456   payload.num = 1;
457   payload.sw_ifs[0] = m_swifindex.value();
458
459   VAPI_CALL(req.execute());
460
461   wait();
462 }
463
464 void
465 stats_enable_cmd::notify()
466 {
467   m_listener.handle_interface_stat(this);
468 }
469
470 std::string
471 stats_enable_cmd::to_string() const
472 {
473   std::ostringstream s;
474   s << "itf-stats-enable itf:" << m_swifindex.to_string();
475   return (s.str());
476 }
477
478 dump_cmd::dump_cmd()
479 {
480 }
481
482 stats_disable_cmd::stats_disable_cmd(const handle_t& handle)
483   : rpc_cmd(m_res)
484   , m_swifindex(handle)
485 {
486 }
487
488 bool
489 stats_disable_cmd::operator==(const stats_disable_cmd& other) const
490 {
491   return (true);
492 }
493
494 rc_t
495 stats_disable_cmd::issue(connection& con)
496 {
497   /*
498    * then send the request to enable them
499    */
500   msg_t req(con.ctx(), 1, std::ref(*this));
501
502   auto& payload = req.get_request().get_payload();
503   payload.enable_disable = 0;
504   payload.pid = getpid();
505   payload.num = 1;
506
507   payload.sw_ifs[0] = m_swifindex.value();
508
509   VAPI_CALL(req.execute());
510
511   wait();
512
513   return (rc_t::OK);
514 }
515
516 std::string
517 stats_disable_cmd::to_string() const
518 {
519   std::ostringstream s;
520   s << "itf-stats-disable itf:" << m_swifindex.to_string();
521   return (s.str());
522 }
523
524 bool
525 dump_cmd::operator==(const dump_cmd& other) const
526 {
527   return (true);
528 }
529
530 rc_t
531 dump_cmd::issue(connection& con)
532 {
533   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
534
535   auto& payload = m_dump->get_request().get_payload();
536   payload.name_filter_valid = 0;
537
538   VAPI_CALL(m_dump->execute());
539
540   wait();
541
542   return rc_t::OK;
543 }
544
545 std::string
546 dump_cmd::to_string() const
547 {
548   return ("itf-dump");
549 }
550
551 set_tag::set_tag(HW::item<handle_t>& item, const std::string& name)
552   : rpc_cmd(item)
553   , m_name(name)
554 {
555 }
556
557 rc_t
558 set_tag::issue(connection& con)
559 {
560   msg_t req(con.ctx(), std::ref(*this));
561
562   auto& payload = req.get_request().get_payload();
563   payload.is_add = 1;
564   payload.sw_if_index = m_hw_item.data().value();
565   memcpy(payload.tag, m_name.c_str(), m_name.length());
566
567   VAPI_CALL(req.execute());
568
569   wait();
570
571   return rc_t::OK;
572 }
573 std::string
574 set_tag::to_string() const
575 {
576   std::ostringstream s;
577   s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name;
578
579   return (s.str());
580 }
581
582 bool
583 set_tag::operator==(const set_tag& o) const
584 {
585   return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data()));
586 }
587 }; // namespace interface_cmds
588 }; // namespace VOM
589
590 /*
591  * fd.io coding-style-patch-verification: ON
592  *
593  * Local Variables:
594  * eval: (c-set-style "mozilla")
595  * End:
596  */