vom: Add support for af-packet dump 65/12965/3
authorMohsin Kazmi <sykazmi@cisco.com>
Fri, 8 Jun 2018 14:57:33 +0000 (16:57 +0200)
committerNeale Ranns <nranns@cisco.com>
Mon, 11 Jun 2018 23:34:18 +0000 (23:34 +0000)
Change-Id: I0a1fc36ac29f6da70334ea3b5a5cf0e841faef76
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
extras/vom/vom/interface.cpp
extras/vom/vom/interface_cmds.cpp
extras/vom/vom/interface_cmds.hpp
extras/vom/vom/interface_factory.cpp
extras/vom/vom/interface_factory.hpp

index 6faf349..009e703 100644 (file)
@@ -507,6 +507,20 @@ interface::event_handler::handle_populate(const client_db::key_t& key)
     OM::commit(key, *vitf);
   }
 
+  std::shared_ptr<interface_cmds::af_packet_dump_cmd> afcmd =
+    std::make_shared<interface_cmds::af_packet_dump_cmd>();
+
+  HW::enqueue(afcmd);
+  HW::write();
+
+  for (auto& af_packet_itf_record : *afcmd) {
+    std::shared_ptr<interface> 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<interface_cmds::dump_cmd> cmd =
     std::make_shared<interface_cmds::dump_cmd>();
 
index f7ddd7e..fc1d71f 100644 (file)
@@ -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<handle_t>& item, const std::string& name)
   : rpc_cmd(item)
   , m_name(name)
index 7a0040d..d5c161d 100644 (file)
@@ -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<vapi::Af_packet_dump>
+{
+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;
+};
 };
 };
 /*
index b56455c..715c3b6 100644 (file)
@@ -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<std::string> parts;
+    std::shared_ptr<interface> 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>
+interface_factory::new_af_packet_interface(
+  const vapi_payload_af_packet_details& vd)
+{
+  std::shared_ptr<interface> sp;
+  std::string name = reinterpret_cast<const char*>(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<bond_interface>
 interface_factory::new_bond_interface(
   const vapi_payload_sw_interface_bond_details& vd)
index dda5275..613c26e 100644 (file)
@@ -21,6 +21,7 @@
 #include "vom/bond_member.hpp"
 #include "vom/interface.hpp"
 
+#include <vapi/af_packet.api.vapi.hpp>
 #include <vapi/bond.api.vapi.hpp>
 #include <vapi/interface.api.vapi.hpp>
 #include <vapi/vhost_user.api.vapi.hpp>
@@ -39,6 +40,9 @@ public:
   static std::shared_ptr<interface> new_vhost_user_interface(
     const vapi_payload_sw_interface_vhost_user_details& vd);
 
+  static std::shared_ptr<interface> new_af_packet_interface(
+    const vapi_payload_af_packet_details& vd);
+
   static std::shared_ptr<bond_interface> new_bond_interface(
     const vapi_payload_sw_interface_bond_details& vd);