VOM: acl: Some necessary fixes

It:
  1. changes ethertype_rule_t to hold actual objects instead of
reference to them.
  2. fixes acl_ethertype 'update' function
  3. fixes pretty-print of acl-list-update.
  4. adds l3-acl update unit test.

Change-Id: Iec72212806e96bd0574b46b563de79f0744cb248
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
diff --git a/src/vpp-api/vom/acl_ethertype.cpp b/src/vpp-api/vom/acl_ethertype.cpp
index 2f01633..043f0b0e6 100644
--- a/src/vpp-api/vom/acl_ethertype.cpp
+++ b/src/vpp-api/vom/acl_ethertype.cpp
@@ -70,7 +70,7 @@
 acl_ethertype::event_handler acl_ethertype::m_evh;
 
 acl_ethertype::acl_ethertype(const interface& itf,
-                             acl_ethertype::ethertype_rules_t le)
+                             const acl_ethertype::ethertype_rules_t& le)
   : m_itf(itf.singular())
   , m_le(le)
   , m_binding(true)
@@ -146,15 +146,17 @@
 }
 
 void
-acl_ethertype::update(const acl_ethertype& old)
+acl_ethertype::update(const acl_ethertype& desired)
 {
   /*
    * always update the instance with the latest rules
    */
-  if (!m_binding || old.m_le != m_le) {
+  if (!m_binding || desired.m_le != m_le) {
     HW::enqueue(
       new acl_ethertype_cmds::bind_cmd(m_binding, m_itf->handle(), m_le));
   }
+
+  m_le = desired.m_le;
 }
 
 std::shared_ptr<acl_ethertype>
diff --git a/src/vpp-api/vom/acl_ethertype.hpp b/src/vpp-api/vom/acl_ethertype.hpp
index 42897ae..98d3ce2 100644
--- a/src/vpp-api/vom/acl_ethertype.hpp
+++ b/src/vpp-api/vom/acl_ethertype.hpp
@@ -76,12 +76,12 @@
   /**
    * ethertype for this rule
    */
-  const ethertype_t& m_eth;
+  const ethertype_t m_eth;
 
   /**
    * direction in which ethertype will be applied w.r.t. intf
    */
-  const direction_t& m_dir;
+  const direction_t m_dir;
 };
 
 class acl_ethertype : public object_base
@@ -102,7 +102,7 @@
   /**
    * Construct a new object matching the desried state
    */
-  acl_ethertype(const interface& itf, ethertype_rules_t le);
+  acl_ethertype(const interface& itf, const ethertype_rules_t& le);
 
   /**
    * Copy Constructor
diff --git a/src/vpp-api/vom/acl_list_cmds.hpp b/src/vpp-api/vom/acl_list_cmds.hpp
index e4aa950..23d77c7 100644
--- a/src/vpp-api/vom/acl_list_cmds.hpp
+++ b/src/vpp-api/vom/acl_list_cmds.hpp
@@ -59,7 +59,11 @@
   std::string to_string() const
   {
     std::ostringstream s;
-    s << "ACL-list-update: " << this->item().to_string();
+    s << "ACL-list-update:[ " << this->item().to_string() << " rule-list:[";
+    for (auto rule : m_rules) {
+      s << " " << rule.to_string();
+    }
+    s << "]]";
 
     return (s.str());
   }
diff --git a/test/ext/vom_test.cpp b/test/ext/vom_test.cpp
index d9bd679..4c09ab4 100644
--- a/test/ext/vom_test.cpp
+++ b/test/ext/vom_test.cpp
@@ -1013,6 +1013,13 @@
     ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules));
     TRY_CHECK_RC(OM::write(fyodor, acl1));
 
+    ACL::l3_rule r3(30, ACL::action_t::PERMIT, route::prefix_t::ZERO, route::prefix_t::ZERO);
+    ACL::l3_list acl2(acl_name);
+    acl2.insert(r3);
+    ACL::l3_list::rules_t rules2 = {r3};
+    ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules2));
+    TRY_CHECK_RC(OM::write(fyodor, acl2));
+
     ACL::l3_binding *l3b = new ACL::l3_binding(direction_t::INPUT, itf1, acl1);
     HW::item<bool> hw_binding(true, rc_t::OK);
     ADD_EXPECT(ACL::binding_cmds::l3_bind_cmd(hw_binding, direction_t::INPUT,