FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
interface.cpp
Go to the documentation of this file.
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.hpp"
20 #include "vom/interface_cmds.hpp"
22 #include "vom/l3_binding_cmds.hpp"
23 #include "vom/logger.hpp"
24 #include "vom/prefix.hpp"
26 
27 namespace VOM {
28 /**
29  * A DB of all the interfaces, key on the name
30  */
31 singular_db<interface::key_t, interface> interface::m_db;
32 
33 /**
34  * A DB of all the interfaces, key on VPP's handle
35  */
36 std::map<handle_t, std::weak_ptr<interface>> interface::m_hdl_db;
37 
38 interface::event_handler interface::m_evh;
39 
40 /**
41  * Construct a new object matching the desried state
42  */
43 interface::interface(const std::string& name,
44  interface::type_t itf_type,
45  interface::admin_state_t itf_state,
46  const std::string& tag)
47  : m_hdl(handle_t::INVALID)
48  , m_name(name)
49  , m_type(itf_type)
50  , m_state(itf_state)
51  , m_table_id(route::DEFAULT_TABLE)
52  , m_l2_address(l2_address_t::ZERO, rc_t::UNSET)
53  , m_stats_type(stats_type_t::NORMAL)
54  , m_oper(oper_state_t::DOWN)
55  , m_tag(tag)
56 {
57 }
58 
59 interface::interface(const std::string& name,
60  interface::type_t itf_type,
61  interface::admin_state_t itf_state,
62  const route_domain& rd,
63  const std::string& tag)
64  : m_hdl(handle_t::INVALID)
65  , m_name(name)
66  , m_type(itf_type)
67  , m_rd(rd.singular())
68  , m_state(itf_state)
69  , m_table_id(m_rd->table_id())
70  , m_l2_address(l2_address_t::ZERO, rc_t::UNSET)
71  , m_stats_type(stats_type_t::NORMAL)
72  , m_oper(oper_state_t::DOWN)
73  , m_tag(tag)
74 {
75 }
76 
78  : m_hdl(o.m_hdl)
79  , m_name(o.m_name)
80  , m_type(o.m_type)
81  , m_rd(o.m_rd)
82  , m_state(o.m_state)
83  , m_table_id(o.m_table_id)
84  , m_l2_address(o.m_l2_address)
85  , m_stats_type(o.m_stats_type)
86  , m_oper(o.m_oper)
87  , m_tag(o.m_tag)
88 {
89 }
90 
91 bool
93 {
94  return ((key() == i.key()) &&
95  (m_l2_address.data() == i.m_l2_address.data()) &&
96  (m_state == i.m_state) && (m_rd == i.m_rd) && (m_type == i.m_type) &&
97  (m_oper == i.m_oper));
98 }
99 
101  : m_status(rc_t::NOOP)
102 {
103 }
104 
107 {
108  return (m_status);
109 }
110 
112  : m_status(rc_t::NOOP)
113 {
114 }
115 
118 {
119  return (m_status);
120 }
121 
122 /**
123  * Return the interface type
124  */
125 const interface::type_t&
127 {
128  return (m_type);
129 }
130 
131 const handle_t&
133 {
134  return (singular()->handle_i());
135 }
136 
137 const handle_t&
138 interface::handle_i() const
139 {
140  return (m_hdl.data());
141 }
142 
143 const l2_address_t&
145 {
146  return (m_l2_address.data());
147 }
148 
151 {
152  return m_db.begin();
153 }
154 
157 {
158  return m_db.end();
159 }
160 
161 void
163 {
164  if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) {
165  m_table_id.data() = route::DEFAULT_TABLE;
166  HW::enqueue(
168  HW::enqueue(
170  }
171 
172  if (m_stats) {
173  if (stats_type_t::DETAILED == m_stats_type) {
175  m_stats_type, handle_i(), false));
176  }
178  m_stats.reset();
179  }
180 
181  // If the interface is up, bring it down
182  if (m_state && interface::admin_state_t::UP == m_state.data()) {
183  m_state.data() = interface::admin_state_t::DOWN;
185  }
186 
187  if (m_hdl) {
188  std::queue<cmd*> cmds;
189  HW::enqueue(mk_delete_cmd(cmds));
190  }
191  HW::write();
192 }
193 
194 void
195 interface::replay()
196 {
197  if (m_hdl) {
198  std::queue<cmd*> cmds;
199  HW::enqueue(mk_create_cmd(cmds));
200  }
201 
202  if (m_state && interface::admin_state_t::UP == m_state.data()) {
204  }
205 
206  if (m_stats) {
207  if (stats_type_t::DETAILED == m_stats_type) {
208  m_stats_type.set(rc_t::NOOP);
210  m_stats_type, handle_i(), true));
211  }
212  stat_listener& listener = m_stats->listener();
213  listener.status().set(rc_t::NOOP);
214  m_stats.reset(new interface_cmds::stats_enable_cmd(listener, handle_i()));
215  HW::enqueue(m_stats);
216  }
217 
218  if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) {
219  HW::enqueue(
221  HW::enqueue(
223  }
224 }
225 
227 {
228  sweep();
229  release();
230 }
231 
232 void
234 {
235  // not in the DB anymore.
236  m_db.release(m_name, this);
237 }
238 
239 std::string
241 {
242  std::ostringstream s;
243  s << "interface:[" << m_name << " type:" << m_type.to_string()
244  << " hdl:" << m_hdl.to_string() << " l2-address:["
245  << m_l2_address.to_string() << "]";
246 
247  if (m_rd) {
248  s << " rd:" << m_rd->to_string();
249  }
250 
251  s << " admin-state:" << m_state.to_string()
252  << " oper-state:" << m_oper.to_string();
253 
254  if (!m_tag.empty()) {
255  s << " tag:[" << m_tag << "]";
256  }
257 
258  s << "]";
259 
260  return (s.str());
261 }
262 
263 const std::string&
265 {
266  return (m_name);
267 }
268 
269 const interface::key_t&
271 {
272  return (name());
273 }
274 
275 std::queue<cmd*>&
276 interface::mk_create_cmd(std::queue<cmd*>& q)
277 {
278  if (type_t::LOOPBACK == m_type) {
279  q.push(new interface_cmds::loopback_create_cmd(m_hdl, m_name));
280  } else if (type_t::BVI == m_type) {
281  q.push(new interface_cmds::loopback_create_cmd(m_hdl, m_name));
282  q.push(new interface_cmds::set_tag(m_hdl, m_name));
283  /*
284  * set the m_tag for pretty-print
285  */
286  m_tag = m_name;
287  } else if (type_t::AFPACKET == m_type) {
288  q.push(new interface_cmds::af_packet_create_cmd(m_hdl, m_name));
289  if (!m_tag.empty())
290  q.push(new interface_cmds::set_tag(m_hdl, m_tag));
291  } else if (type_t::TAP == m_type) {
292  q.push(new interface_cmds::tap_create_cmd(m_hdl, m_name));
293  if (!m_tag.empty())
294  q.push(new interface_cmds::set_tag(m_hdl, m_tag));
295  } else if (type_t::VHOST == m_type) {
296  q.push(new interface_cmds::vhost_create_cmd(m_hdl, m_name, m_tag));
297  } else {
298  m_hdl.set(rc_t::OK);
299  }
300 
301  return (q);
302 }
303 
304 std::queue<cmd*>&
305 interface::mk_delete_cmd(std::queue<cmd*>& q)
306 {
307  if ((type_t::LOOPBACK == m_type) || (type_t::BVI == m_type)) {
309  } else if (type_t::AFPACKET == m_type) {
310  q.push(new interface_cmds::af_packet_delete_cmd(m_hdl, m_name));
311  } else if (type_t::TAP == m_type) {
313  } else if (type_t::VHOST == m_type) {
314  q.push(new interface_cmds::vhost_delete_cmd(m_hdl, m_name));
315  }
316 
317  return (q);
318 }
319 
320 void
321 interface::update(const interface& desired)
322 {
323  /*
324  * the desired state is always that the interface should be created
325  */
326  if (rc_t::OK != m_hdl.rc()) {
327  std::queue<cmd*> cmds;
328  HW::enqueue(mk_create_cmd(cmds));
329  /*
330  * interface create now, so we can barf early if it fails
331  */
332  HW::write();
333  }
334 
335  /*
336  * If the interface is not created do other commands should be issued
337  */
338  if (rc_t::OK != m_hdl.rc())
339  return;
340 
341  /*
342  * change the interface state to that which is deisred
343  */
344  if (m_state.update(desired.m_state)) {
346  }
347 
348  /*
349  * change the interface state to that which is deisred
350  */
351  if (m_l2_address.update(desired.m_l2_address)) {
352  HW::enqueue(new interface_cmds::set_mac_cmd(m_l2_address, m_hdl));
353  }
354 
355  /*
356  * If the interface is mapped into a route domain, set VPP's
357  * table ID
358  */
359  if (m_rd != desired.m_rd) {
360  /*
361  * changing route domains. need to remove all L3 bindings, swap the table
362  * then reapply the bindings.
363  */
364  auto it = l3_binding::cbegin();
365 
366  while (it != l3_binding::cend()) {
367  if (it->second.lock()->itf().key() == key())
368  it->second.lock()->sweep();
369  ++it;
370  }
371  m_rd = desired.m_rd;
372  m_table_id.update(m_rd ? m_rd->table_id() : route::DEFAULT_TABLE);
373  HW::enqueue(
375  HW::enqueue(
377  HW::write();
378 
379  it = l3_binding::cbegin();
380  while (it != l3_binding::cend()) {
381  if (it->second.lock()->itf().key() == key())
382  it->second.lock()->replay(); //(*it->second.lock());
383  ++it;
384  }
385  } else if (!m_table_id && m_rd) {
386  HW::enqueue(
388  HW::enqueue(
390  }
391 }
392 
393 void
395 {
396  m_state = state;
397 }
398 
399 void
401 {
402  assert(rc_t::UNSET == m_l2_address.rc());
403  m_l2_address.set(rc_t::NOOP);
404  m_l2_address.update(addr);
405 }
406 
407 void
409 {
410  m_hdl = hdl;
411 }
412 
413 void
415 {
416  m_oper = state;
417 }
418 
419 void
420 interface::set(const std::string& tag)
421 {
422  m_tag = tag;
423 }
424 
425 void
426 interface::enable_stats_i(interface::stat_listener& el, const stats_type_t& st)
427 {
428  if (!m_stats) {
429  if (stats_type_t::DETAILED == st) {
430  m_stats_type = st;
432  m_stats_type, handle_i(), true));
433  }
434  m_stats.reset(new interface_cmds::stats_enable_cmd(el, handle_i()));
435  HW::enqueue(m_stats);
436  HW::write();
437  }
438 }
439 
440 void
442 {
443  singular()->enable_stats_i(el, st);
444 }
445 
446 std::shared_ptr<interface>
448 {
449  return (m_db.find_or_add(key(), *this));
450 }
451 
452 std::shared_ptr<interface>
454 {
455  return singular_i();
456 }
457 
458 std::shared_ptr<interface>
460 {
461  return (m_db.find(k));
462 }
463 
464 std::shared_ptr<interface>
466 {
467  return (m_hdl_db[handle].lock());
468 }
469 
470 void
472 {
473  std::shared_ptr<interface> sp = find(key);
474 
475  if (sp && item) {
476  m_hdl_db[item.data()] = sp;
477  }
478 }
479 
480 void
482 {
483  m_hdl_db.erase(item.data());
484 }
485 
486 void
487 interface::dump(std::ostream& os)
488 {
489  db_dump(m_db, os);
490 }
491 
492 void
493 interface::event_handler::handle_populate(const client_db::key_t& key)
494 {
495  /*
496  * dump VPP current states
497  */
498  std::shared_ptr<interface_cmds::vhost_dump_cmd> vcmd =
499  std::make_shared<interface_cmds::vhost_dump_cmd>();
500 
501  HW::enqueue(vcmd);
502  HW::write();
503 
504  for (auto& vhost_itf_record : *vcmd) {
505  std::shared_ptr<interface> vitf =
507  vhost_itf_record.get_payload());
508  VOM_LOG(log_level_t::DEBUG) << " vhost-dump: " << vitf->to_string();
509  OM::commit(key, *vitf);
510  }
511 
512  std::shared_ptr<interface_cmds::dump_cmd> cmd =
513  std::make_shared<interface_cmds::dump_cmd>();
514 
515  HW::enqueue(cmd);
516  HW::write();
517 
518  for (auto& itf_record : *cmd) {
519  std::shared_ptr<interface> itf =
520  interface_factory::new_interface(itf_record.get_payload());
521 
522  if (itf && interface::type_t::LOCAL != itf->type()) {
523  VOM_LOG(log_level_t::DEBUG) << "dump: " << itf->to_string();
524  /*
525  * Write each of the discovered interfaces into the OM,
526  * but disable the HW Command q whilst we do, so that no
527  * commands are sent to VPP
528  */
529  OM::commit(key, *itf);
530 
531  /**
532  * Get the address configured on the interface
533  */
534  std::shared_ptr<l3_binding_cmds::dump_v4_cmd> dcmd =
535  std::make_shared<l3_binding_cmds::dump_v4_cmd>(
536  l3_binding_cmds::dump_v4_cmd(itf->handle()));
537 
538  HW::enqueue(dcmd);
539  HW::write();
540 
541  for (auto& l3_record : *dcmd) {
542  auto& payload = l3_record.get_payload();
543  const route::prefix_t pfx(payload.is_ipv6, payload.ip,
544  payload.prefix_length);
545 
546  VOM_LOG(log_level_t::DEBUG) << "dump: " << pfx.to_string();
547 
548  l3_binding l3(*itf, pfx);
549  OM::commit(key, l3);
550  }
551  }
552  }
553 
554  std::shared_ptr<bond_interface_cmds::dump_cmd> bcmd =
555  std::make_shared<bond_interface_cmds::dump_cmd>();
556 
557  HW::enqueue(bcmd);
558  HW::write();
559 
560  for (auto& bond_itf_record : *bcmd) {
561  std::shared_ptr<bond_interface> bond_itf =
562  interface_factory::new_bond_interface(bond_itf_record.get_payload());
563 
564  VOM_LOG(log_level_t::DEBUG) << " bond-dump:" << bond_itf->to_string();
565 
566  /*
567  * Write each of the discovered interfaces into the OM,
568  * but disable the HW Command q whilst we do, so that no
569  * commands are sent to VPP
570  */
571  OM::commit(key, *bond_itf);
572 
573  std::shared_ptr<bond_group_binding_cmds::dump_cmd> scmd =
574  std::make_shared<bond_group_binding_cmds::dump_cmd>(
575  bond_group_binding_cmds::dump_cmd(bond_itf->handle()));
576 
577  HW::enqueue(scmd);
578  HW::write();
579 
581 
582  for (auto& slave_itf_record : *scmd) {
584  slave_itf_record.get_payload());
585 
586  VOM_LOG(log_level_t::DEBUG) << " slave-dump:" << slave_itf.to_string();
587 
588  /*
589  * Write each of the discovered interfaces into the OM,
590  * but disable the HW Command q whilst we do, so that no
591  * commands are sent to VPP
592  */
593  // OM::commit(slave_itf->key(), *slave_itf);
594  enslaved_itfs.insert(slave_itf);
595  }
596 
597  if (!enslaved_itfs.empty()) {
598  bond_group_binding bid(*bond_itf, enslaved_itfs);
599  /*
600  * Write each of the discovered interfaces into the OM,
601  * but disable the HW Command q whilst we do, so that no
602  * commands are sent to VPP
603  */
604  OM::commit(key, bid);
605  }
606  }
607 }
608 
609 interface::event_handler::event_handler()
610 {
611  OM::register_listener(this);
612  inspect::register_handler({ "interface", "intf" }, "interfaces", this);
613 }
614 
615 void
616 interface::event_handler::handle_replay()
617 {
618  m_db.replay();
619 }
620 
622 interface::event_handler::order() const
623 {
624  return (dependency_t::INTERFACE);
625 }
626 
627 void
628 interface::event_handler::show(std::ostream& os)
629 {
630  db_dump(m_db, os);
631 }
632 
633 } // namespace VOM
634 
635 /*
636  * fd.io coding-style-patch-verification: ON
637  *
638  * Local Variables:
639  * eval: (c-set-style "mozilla")
640  * End:
641  */
static const rc_t NOOP
The HW write/update action was/has not been attempted.
Definition: types.hpp:107
void release()
release/remove an interface form the singular store
Definition: interface.cpp:233
A command class represents our desire to recieve interface stats.
virtual ~interface()
Destructor.
Definition: interface.cpp:226
static void dump(std::ostream &os)
Dump all interfaces into the stream provided.
Definition: interface.cpp:487
interface(const std::string &name, type_t type, admin_state_t state, const std::string &tag="")
Construct a new object matching the desried state.
Definition: interface.cpp:43
#define VOM_LOG(lvl)
Definition: logger.hpp:181
static const type_t AFPACKET
AF-Packet interface type.
Definition: interface.hpp:88
void db_dump(const DB &db, std::ostream &os)
Print each of the objects in the DB into the stream provided.
const std::string key_t
In the opflex world each entity is known by a URI which can be converted into a string.
Definition: client_db.hpp:51
static std::shared_ptr< interface > find(const handle_t &h)
The the singular instance of the interface in the DB by handle.
Definition: interface.cpp:465
HW::item< handle_t > m_hdl
The SW interface handle VPP has asigned to the interface.
Definition: interface.hpp:473
virtual void sweep(void)
Sweep/reap the object if still stale.
Definition: interface.cpp:162
static void register_handler(const std::vector< std::string > &cmds, const std::string &help, command_handler *ch)
Register a command handler for inspection.
Definition: inspect.cpp:85
int i
void set(const admin_state_t &state)
Set the admin state of the interface.
Definition: interface.cpp:394
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:236
HW::item< bool > & status()
Return the HW::item representing the status.
Definition: interface.cpp:106
A command class to set tag on interfaces.
Error codes that VPP will return during a HW write.
Definition: types.hpp:90
static const log_level_t DEBUG
Definition: logger.hpp:32
static const_iterator_t cbegin()
Definition: l3_binding.cpp:94
static const stats_type_t DETAILED
Definition: interface.hpp:46
A representation of bond interface binding.
A cmd class that Dumps slave itfs.
A command class to create TAP interfaces in VPP.
A bond-member.
Definition: bond_member.hpp:26
A command class that enables detailed stats collection on an interface.
std::string to_string() const
convert to string format for debug purposes
Definition: hw.hpp:160
const handle_t & handle() const
Return VPP&#39;s handle to this object.
Definition: interface.cpp:132
The oper state of the interface.
Definition: interface.hpp:153
Type def of a L2 address as read from VPP.
Definition: types.hpp:342
A route-domain is a VRF.
T & data()
Return the data read/written.
Definition: hw.hpp:108
static const_iterator_t cbegin()
Definition: interface.cpp:150
static singular_db< key_t, interface > m_db
A map of all interfaces key against the interface&#39;s name.
Definition: interface.hpp:505
static const type_t LOCAL
Local interface type (specific to VPP)
Definition: interface.hpp:96
A command class that changes the MAC address on an interface.
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:118
static const l3_proto_t IPV4
Definition: prefix.hpp:56
static const_iterator_t cend()
Definition: l3_binding.cpp:100
static const l3_proto_t IPV6
Definition: prefix.hpp:57
HW::item< bool > m_status
The status of the subscription.
Definition: interface.hpp:408
A command class to delete TAP interfaces in VPP.
static const table_id_t DEFAULT_TABLE
The table-id for the default table.
Definition: prefix.hpp:88
virtual std::queue< cmd * > & mk_create_cmd(std::queue< cmd * > &cmds)
Virtual functions to construct an interface create commands.
Definition: interface.cpp:276
std::string to_string() const
convert to string format for debug purposes
Definition: prefix.cpp:183
static void remove(const HW::item< handle_t > &item)
remove an interface from the DB keyed on handle
Definition: interface.cpp:481
event_listener()
Default Constructor.
Definition: interface.cpp:100
const l2_address_t & l2_address() const
Return the L2 Address.
Definition: interface.cpp:144
A class that listens to interface Stats.
Definition: interface.hpp:414
stat_listener()
Default Constructor.
Definition: interface.cpp:111
virtual bool operator==(const interface &i) const
Comparison operator - only used for UT.
Definition: interface.cpp:92
static std::shared_ptr< interface > new_interface(const vapi_payload_sw_interface_details &vd)
Factory method to construct a new interface from the VPP record.
void enable_stats(stat_listener &el, const stats_type_t &st=stats_type_t::NORMAL)
Enable stats for this interface.
Definition: interface.cpp:441
A command class to create Loopback interfaces in VPP.
static std::shared_ptr< interface > new_vhost_user_interface(const vapi_payload_sw_interface_vhost_user_details &vd)
A cmd class that changes the admin state.
static void add(const key_t &name, const HW::item< handle_t > &item)
Add an interface to the DB keyed on handle.
Definition: interface.cpp:471
std::set< bond_member > enslaved_itf_t
The container type for enslaved itfs.
A command class that binds an interface to an L3 table.
static bond_member new_bond_member_interface(const vapi_payload_sw_interface_slave_details &vd)
The admin state of the interface.
Definition: interface.hpp:127
A representation of an interface in VPP.
Definition: interface.hpp:41
HW::item< bool > & status()
Return the HW::item representing the status.
Definition: interface.cpp:117
A command class to create af_packet interfaces in VPP.
A type declaration of an interface handle in VPP.
Definition: types.hpp:236
A functor class that deletes a Vhost interface.
std::shared_ptr< interface > singular() const
Return the matching&#39;singular&#39; of the interface.
Definition: interface.cpp:453
static rc_t commit(const client_db::key_t &key, const OBJ &obj)
Make the State in VPP reflect the expressed desired state.
Definition: om.hpp:202
dependency_t
There needs to be a strict order in which object types are read from VPP (at boot time) and replayed ...
Definition: types.hpp:43
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:112
const std::string & name() const
Return the interface type.
Definition: interface.cpp:264
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:194
virtual std::shared_ptr< interface > singular_i() const
Return the matching &#39;singular&#39; of the interface.
Definition: interface.cpp:447
vhost_vring_state_t state
Definition: vhost-user.h:82
A cmd class that Dumps all the IPv4 L3 configs.
A command class represents our desire to recieve interface stats.
An interface type.
Definition: interface.hpp:67
virtual std::queue< cmd * > & mk_delete_cmd(std::queue< cmd * > &cmds)
Virtual functions to construct an interface delete commands.
Definition: interface.cpp:305
A command class to delete af-packet interfaces in VPP.
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
A command class to delete loopback interfaces in VPP.
static const admin_state_t UP
Admin UP state.
Definition: interface.hpp:136
A representation of a method call to VPP.
Definition: cmd.hpp:32
static const rc_t UNSET
The value un-set.
Definition: types.hpp:102
Definition: hash.c:482
void set(const rc_t &rc)
Set the HW return code - should only be called from the family of Command objects.
Definition: hw.hpp:124
static const type_t BVI
A brideged Virtual interface (aka SVI or IRB)
Definition: interface.hpp:76
HW::item< bool > m_status
The status of the subscription.
Definition: interface.hpp:438
A functor class that creates an interface.
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
static const admin_state_t DOWN
Admin DOWN state.
Definition: interface.hpp:132
A representation of L3 configuration on an interface.
Definition: l3_binding.hpp:30
static const type_t TAP
TAP interface type.
Definition: interface.hpp:100
static const_iterator_t cend()
Definition: interface.cpp:156
std::string to_string(void) const
convert to string
Definition: bond_member.cpp:49
singular_db< const std::string, interface >::const_iterator const_iterator_t
The iterator type.
Definition: interface.hpp:62
virtual std::string to_string(void) const
convert to string format for debug purposes
Definition: interface.cpp:240
vhost_vring_addr_t addr
Definition: vhost-user.h:83
static const type_t LOOPBACK
loopback interface type
Definition: interface.hpp:92
std::string key_t
The key for interface&#39;s key.
Definition: interface.hpp:56
static const type_t VHOST
vhost-user interface type
Definition: interface.hpp:105
const type_t & type() const
Return the interface type.
Definition: interface.cpp:126
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127
A prefix defintion.
Definition: prefix.hpp:93
const key_t & key() const
Return the interface type.
Definition: interface.cpp:270
static std::shared_ptr< bond_interface > new_bond_interface(const vapi_payload_sw_interface_bond_details &vd)
interfaces are the root of the dependency graph