750ad1f888161e3f28d2c704b6fce5e80a3c130c
[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::INPROGRESS);
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_cmd::stats_cmd(interface::stat_listener& el, const handle_t& handle)
405   : event_cmd(el.status())
406   , m_listener(el)
407   , m_swifindex(handle)
408 {
409 }
410
411 bool
412 stats_cmd::operator==(const stats_cmd& other) const
413 {
414   return (true);
415 }
416
417 rc_t
418 stats_cmd::issue(connection& con)
419 {
420   /*
421    * First set the call back to handle the interface stats
422    */
423   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
424
425   /*
426    * then send the request to enable them
427    */
428   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
429
430   auto& payload = req.get_request().get_payload();
431   payload.enable_disable = 1;
432   payload.pid = getpid();
433   payload.num = 1;
434
435   payload.sw_ifs[0] = m_swifindex.value();
436
437   VAPI_CALL(req.execute());
438
439   wait();
440
441   return (rc_t::INPROGRESS);
442 }
443
444 void
445 stats_cmd::retire(connection& con)
446 {
447   /*
448    * disable interface stats.
449    */
450   msg_t req(con.ctx(), 1, std::ref(*(static_cast<rpc_cmd*>(this))));
451
452   auto& payload = req.get_request().get_payload();
453   payload.enable_disable = 0;
454   payload.pid = getpid();
455   payload.num = 1;
456   payload.sw_ifs[0] = m_swifindex.value();
457
458   VAPI_CALL(req.execute());
459
460   wait();
461 }
462
463 void
464 stats_cmd::notify()
465 {
466   m_listener.handle_interface_stat(this);
467 }
468
469 std::string
470 stats_cmd::to_string() const
471 {
472   return ("itf-stats");
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 set_tag::set_tag(HW::item<handle_t>& item, const std::string& name)
507   : rpc_cmd(item)
508   , m_name(name)
509 {
510 }
511
512 rc_t
513 set_tag::issue(connection& con)
514 {
515   msg_t req(con.ctx(), std::ref(*this));
516
517   auto& payload = req.get_request().get_payload();
518   payload.is_add = 1;
519   payload.sw_if_index = m_hw_item.data().value();
520   memcpy(payload.tag, m_name.c_str(), m_name.length());
521
522   VAPI_CALL(req.execute());
523
524   wait();
525
526   return rc_t::OK;
527 }
528 std::string
529 set_tag::to_string() const
530 {
531   std::ostringstream s;
532   s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name;
533
534   return (s.str());
535 }
536
537 bool
538 set_tag::operator==(const set_tag& o) const
539 {
540   return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data()));
541 }
542 }; // namespace interface_cmds
543 }; // namespace VOM
544
545 /*
546  * fd.io coding-style-patch-verification: ON
547  *
548  * Local Variables:
549  * eval: (c-set-style "mozilla")
550  * End:
551  */