From 0af529c4c50bfa52e83cd4190e7d8baa5b20022f Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Fri, 8 Jun 2018 16:57:33 +0200 Subject: vom: Add support for af-packet dump Change-Id: I0a1fc36ac29f6da70334ea3b5a5cf0e841faef76 Signed-off-by: Mohsin Kazmi --- extras/vom/vom/interface.cpp | 14 ++++++++++++ extras/vom/vom/interface_cmds.cpp | 24 ++++++++++++++++++++ extras/vom/vom/interface_cmds.hpp | 26 ++++++++++++++++++++++ extras/vom/vom/interface_factory.cpp | 43 ++++++++++++++++++++++++++++-------- extras/vom/vom/interface_factory.hpp | 4 ++++ 5 files changed, 102 insertions(+), 9 deletions(-) diff --git a/extras/vom/vom/interface.cpp b/extras/vom/vom/interface.cpp index 6faf3491e6f..009e703000f 100644 --- a/extras/vom/vom/interface.cpp +++ b/extras/vom/vom/interface.cpp @@ -507,6 +507,20 @@ interface::event_handler::handle_populate(const client_db::key_t& key) OM::commit(key, *vitf); } + std::shared_ptr afcmd = + std::make_shared(); + + HW::enqueue(afcmd); + HW::write(); + + for (auto& af_packet_itf_record : *afcmd) { + std::shared_ptr afitf = + interface_factory::new_af_packet_interface( + af_packet_itf_record.get_payload()); + VOM_LOG(log_level_t::DEBUG) << " af_packet-dump: " << afitf->to_string(); + OM::commit(key, *afitf); + } + std::shared_ptr cmd = std::make_shared(); diff --git a/extras/vom/vom/interface_cmds.cpp b/extras/vom/vom/interface_cmds.cpp index f7ddd7e34cf..fc1d71fa2d9 100644 --- a/extras/vom/vom/interface_cmds.cpp +++ b/extras/vom/vom/interface_cmds.cpp @@ -709,6 +709,30 @@ vhost_dump_cmd::to_string() const return ("vhost-itf-dump"); } +bool +af_packet_dump_cmd::operator==(const af_packet_dump_cmd& other) const +{ + return (true); +} + +rc_t +af_packet_dump_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +af_packet_dump_cmd::to_string() const +{ + return ("af-packet-itf-dump"); +} + set_tag::set_tag(HW::item& item, const std::string& name) : rpc_cmd(item) , m_name(name) diff --git a/extras/vom/vom/interface_cmds.hpp b/extras/vom/vom/interface_cmds.hpp index 7a0040deb0a..d5c161dd113 100644 --- a/extras/vom/vom/interface_cmds.hpp +++ b/extras/vom/vom/interface_cmds.hpp @@ -603,6 +603,32 @@ public: */ bool operator==(const vhost_dump_cmd& i) const; }; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class af_packet_dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + af_packet_dump_cmd() = default; + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const af_packet_dump_cmd& i) const; +}; }; }; /* diff --git a/extras/vom/vom/interface_factory.cpp b/extras/vom/vom/interface_factory.cpp index b56455c7d48..715c3b6f4db 100644 --- a/extras/vom/vom/interface_factory.cpp +++ b/extras/vom/vom/interface_factory.cpp @@ -38,6 +38,18 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) l2_address_t l2_address(vd.l2_address, vd.l2_address_length); std::string tag = ""; + sp = interface::find(hdl); + if (sp) { + sp->set(state); + sp->set(l2_address); + if (!tag.empty()) + sp->set(tag); + return sp; + } + + /* + * If here, Fall back to old routine + */ if (interface::type_t::AFPACKET == type) { /* * need to strip VPP's "host-" prefix from the interface name @@ -73,10 +85,15 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) * split the name into the parent and VLAN */ std::vector parts; + std::shared_ptr parent; boost::split(parts, name, boost::is_any_of(".")); - interface parent(parts[0], type, state, tag); - sp = sub_interface(parent, state, vd.sub_id).singular(); + if ((parent = interface::find(parts[0]))) + sp = sub_interface(*parent, state, vd.sub_id).singular(); + else { + interface parent_itf(parts[0], type, state, tag); + sp = sub_interface(parent_itf, state, vd.sub_id).singular(); + } } else if (interface::type_t::VXLAN == type) { /* * there's not enough information in a SW interface record to @@ -88,13 +105,6 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) * vhost interface already exist in db, look for it using * sw_if_index */ - sp = interface::find(hdl); - if (sp) { - sp->set(state); - sp->set(l2_address); - if (!tag.empty()) - sp->set(tag); - } } else if (interface::type_t::BOND == type) { sp = bond_interface(name, state, l2_address, bond_interface::mode_t::UNSPECIFIED) @@ -128,6 +138,21 @@ interface_factory::new_vhost_user_interface( return (sp); } +std::shared_ptr +interface_factory::new_af_packet_interface( + const vapi_payload_af_packet_details& vd) +{ + std::shared_ptr sp; + std::string name = reinterpret_cast(vd.host_if_name); + handle_t hdl(vd.sw_if_index); + + sp = + interface(name, interface::type_t::AFPACKET, interface::admin_state_t::DOWN) + .singular(); + sp->set(hdl); + return (sp); +} + std::shared_ptr interface_factory::new_bond_interface( const vapi_payload_sw_interface_bond_details& vd) diff --git a/extras/vom/vom/interface_factory.hpp b/extras/vom/vom/interface_factory.hpp index dda52752352..613c26e98b5 100644 --- a/extras/vom/vom/interface_factory.hpp +++ b/extras/vom/vom/interface_factory.hpp @@ -21,6 +21,7 @@ #include "vom/bond_member.hpp" #include "vom/interface.hpp" +#include #include #include #include @@ -39,6 +40,9 @@ public: static std::shared_ptr new_vhost_user_interface( const vapi_payload_sw_interface_vhost_user_details& vd); + static std::shared_ptr new_af_packet_interface( + const vapi_payload_af_packet_details& vd); + static std::shared_ptr new_bond_interface( const vapi_payload_sw_interface_bond_details& vd); -- cgit 1.2.3-korg