VOM: acl: Add support for acl ethertype unbind and dump 21/11021/6
authorMohsin Kazmi <sykazmi@cisco.com>
Wed, 7 Mar 2018 18:53:51 +0000 (19:53 +0100)
committerNeale Ranns <nranns@cisco.com>
Wed, 14 Mar 2018 09:09:01 +0000 (09:09 +0000)
Change-Id: I667b9ccabe54c8f9cff5b1a2e63864965f5064f5
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/vpp-api/vom/acl_ethertype.cpp
src/vpp-api/vom/acl_ethertype_cmds.cpp
src/vpp-api/vom/acl_ethertype_cmds.hpp
test/ext/vom_test.cpp

index 043f0b0..530a0ae 100644 (file)
@@ -95,6 +95,10 @@ acl_ethertype::~acl_ethertype()
 void
 acl_ethertype::sweep()
 {
+  if (m_binding) {
+    HW::enqueue(new acl_ethertype_cmds::unbind_cmd(m_binding, m_itf->handle()));
+  }
+  HW::write();
 }
 
 const acl_ethertype::key_t&
@@ -187,7 +191,41 @@ acl_ethertype::event_handler::handle_replay()
 void
 acl_ethertype::event_handler::handle_populate(const client_db::key_t& key)
 {
-  // FIXME
+  /*
+   * dump VPP acl ethertypes
+   */
+  std::shared_ptr<acl_ethertype_cmds::dump_cmd> cmd =
+    std::make_shared<acl_ethertype_cmds::dump_cmd>(~0);
+
+  HW::enqueue(cmd);
+  HW::write();
+
+  for (auto& record : *cmd) {
+    auto& payload = record.get_payload();
+    handle_t hdl(payload.sw_if_index);
+    std::shared_ptr<interface> itf = interface::find(hdl);
+    uint8_t n_input = payload.n_input;
+    uint8_t count = payload.count;
+    ethertype_rules_t ler;
+    if (itf) {
+      for (int i = 0; i < count; i++) {
+        ethertype_t e = ethertype_t::from_numeric_val(payload.whitelist[i]);
+        if (n_input) {
+          ethertype_rule_t er(e, direction_t::INPUT);
+          ler.insert(er);
+          n_input--;
+        } else {
+          ethertype_rule_t er(e, direction_t::OUTPUT);
+          ler.insert(er);
+        }
+      }
+      if (!ler.empty()) {
+        acl_ethertype a_e(*itf, ler);
+        VOM_LOG(log_level_t::DEBUG) << "ethertype dump: " << a_e.to_string();
+        OM::commit(key, a_e);
+      }
+    }
+  }
 }
 
 dependency_t
index 91fc7ee..c05a428 100644 (file)
@@ -80,6 +80,82 @@ bind_cmd::to_string() const
   return (s.str());
 }
 
+unbind_cmd::unbind_cmd(HW::item<bool>& item, const handle_t& itf)
+  : rpc_cmd(item)
+  , m_itf(itf)
+{
+}
+
+bool
+unbind_cmd::operator==(const unbind_cmd& other) const
+{
+  return (m_itf == other.m_itf);
+}
+
+rc_t
+unbind_cmd::issue(connection& con)
+{
+  msg_t req(con.ctx(), 0, std::ref(*this));
+
+  auto& payload = req.get_request().get_payload();
+  payload.sw_if_index = m_itf.value();
+  payload.count = 0;
+
+  payload.n_input = 0;
+
+  VAPI_CALL(req.execute());
+
+  wait();
+  m_hw_item.set(rc_t::NOOP);
+
+  return rc_t::OK;
+}
+
+std::string
+unbind_cmd::to_string() const
+{
+  std::ostringstream s;
+  s << "ACL-Ethertype-Unbind: " << m_hw_item.to_string()
+    << " itf:" << m_itf.to_string();
+  return (s.str());
+}
+
+dump_cmd::dump_cmd(const handle_t& hdl)
+  : m_itf(hdl)
+{
+}
+
+dump_cmd::dump_cmd(const dump_cmd& d)
+  : m_itf(d.m_itf)
+{
+}
+
+bool
+dump_cmd::operator==(const dump_cmd& other) const
+{
+  return (true);
+}
+
+rc_t
+dump_cmd::issue(connection& con)
+{
+  m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+
+  auto& payload = m_dump->get_request().get_payload();
+  payload.sw_if_index = m_itf.value();
+
+  VAPI_CALL(m_dump->execute());
+
+  wait();
+
+  return rc_t::OK;
+}
+
+std::string
+dump_cmd::to_string() const
+{
+  return ("acl-ethertype-dump");
+}
 }; // namespace acl_ethertype_cmds
 }; // namespace ACL
 }; // namespace VOM
index a0af50e..f72a3fb 100644 (file)
@@ -65,6 +65,73 @@ private:
    */
   const acl_ethertype::ethertype_rules_t& m_le;
 };
+
+/**
+ * A command class that unbinds the ethertype list to the interface
+ */
+class unbind_cmd : public rpc_cmd<HW::item<bool>,
+                                  rc_t,
+                                  vapi::Acl_interface_set_etype_whitelist>
+{
+public:
+  /**
+   * Constructor
+   */
+  unbind_cmd(HW::item<bool>& item, const handle_t& itf);
+
+  /**
+   * 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 unbind_cmd& i) const;
+
+private:
+  /**
+   * Reference to the HW::item of the interface to bind
+   */
+  const handle_t m_itf;
+};
+
+/**
+ * A cmd class that Dumps all the acl ethertypes on given interface
+ */
+class dump_cmd : public VOM::dump_cmd<vapi::Acl_interface_etype_whitelist_dump>
+{
+public:
+  /**
+   * Constructor
+   */
+  dump_cmd(const handle_t& itf);
+  dump_cmd(const dump_cmd& d);
+
+  /**
+   * 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 dump_cmd& i) const;
+
+private:
+  /**
+   * The interface to get the addresses for
+   */
+  const handle_t m_itf;
+};
 };
 };
 };
index 9f7cfd6..435d8fd 100644 (file)
@@ -294,6 +294,10 @@ public:
                     {
                         rc = handle_derived<ACL::acl_ethertype_cmds::bind_cmd>(f_exp, f_act);
                     }
+                    else if (typeid(*f_exp) == typeid(ACL::acl_ethertype_cmds::unbind_cmd))
+                    {
+                        rc = handle_derived<ACL::acl_ethertype_cmds::unbind_cmd>(f_exp, f_act);
+                    }
                     else if (typeid(*f_exp) == typeid(ACL::list_cmds::l3_update_cmd))
                     {
                         rc = handle_derived<ACL::list_cmds::l3_update_cmd>(f_exp, f_act);
@@ -1095,6 +1099,7 @@ BOOST_AUTO_TEST_CASE(test_acl) {
     ADD_EXPECT(ACL::binding_cmds::l3_unbind_cmd(hw_binding, direction_t::INPUT,
                                          hw_ifh.data(), hw_acl.data()));
     ADD_EXPECT(ACL::list_cmds::l3_delete_cmd(hw_acl));
+    ADD_EXPECT(ACL::acl_ethertype_cmds::unbind_cmd(ae_binding, hw_ifh.data()));
     ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
     ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));