aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-02-22 00:44:40 -0800
committerNeale Ranns <nranns@cisco.com>2019-02-22 15:41:51 +0000
commit5637e653649692eb04fbec5c97e0fd427404c1dd (patch)
tree72105c0ee0e85ad17305e8cf98cbe0e08294e5e5
parentba94462c42a27f7447e10ca55a3b212970448ceb (diff)
VOM: De-template the ACL code.
there's something going wrong with the dependency ordering. i have added hacks in the past, but these are not reliable across compiler versions. Change-Id: I34b4aae4c7ed7beaa424cd692ff34cba21ba802a Signed-off-by: Neale Ranns <nranns@cisco.com>
-rw-r--r--extras/vom/vom/CMakeLists.txt6
-rw-r--r--extras/vom/vom/acl_binding.hpp3
-rw-r--r--extras/vom/vom/acl_l2_list.cpp283
-rw-r--r--extras/vom/vom/acl_l2_list.hpp (renamed from extras/vom/vom/acl_list.hpp)149
-rw-r--r--extras/vom/vom/acl_l3_list.cpp (renamed from extras/vom/vom/acl_list.cpp)232
-rw-r--r--extras/vom/vom/acl_l3_list.hpp224
-rw-r--r--extras/vom/vom/acl_list_cmds.hpp25
-rw-r--r--extras/vom/vom/gbp_contract.hpp2
-rw-r--r--test/ext/vom_test.cpp3
9 files changed, 711 insertions, 216 deletions
diff --git a/extras/vom/vom/CMakeLists.txt b/extras/vom/vom/CMakeLists.txt
index a0a5f9783e9..26dd3e46574 100644
--- a/extras/vom/vom/CMakeLists.txt
+++ b/extras/vom/vom/CMakeLists.txt
@@ -50,10 +50,11 @@ if(ACL_FILE)
acl_binding.cpp
acl_ethertype_cmds.cpp
acl_ethertype.cpp
+ acl_l2_list.cpp
acl_l2_rule.cpp
+ acl_l3_list.cpp
acl_l3_rule.cpp
acl_list_cmds.cpp
- acl_list.cpp
acl_types.cpp
)
endif()
@@ -189,7 +190,8 @@ if(ACL_FILE)
acl_ethertype.hpp
acl_l2_rule.hpp
acl_l3_rule.hpp
- acl_list.hpp
+ acl_l3_list.hpp
+ acl_l2_list.hpp
acl_types.hpp
)
endif()
diff --git a/extras/vom/vom/acl_binding.hpp b/extras/vom/vom/acl_binding.hpp
index 3a123a853cd..2c9923b8266 100644
--- a/extras/vom/vom/acl_binding.hpp
+++ b/extras/vom/vom/acl_binding.hpp
@@ -18,7 +18,8 @@
#include <ostream>
-#include "vom/acl_list.hpp"
+#include "vom/acl_l2_list.hpp"
+#include "vom/acl_l3_list.hpp"
#include "vom/acl_types.hpp"
#include "vom/hw.hpp"
#include "vom/inspect.hpp"
diff --git a/extras/vom/vom/acl_l2_list.cpp b/extras/vom/vom/acl_l2_list.cpp
new file mode 100644
index 00000000000..939fb348d0b
--- /dev/null
+++ b/extras/vom/vom/acl_l2_list.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "vom/acl_l2_list.hpp"
+#include "vom/acl_list_cmds.hpp"
+#include "vom/logger.hpp"
+#include "vom/singular_db_funcs.hpp"
+
+namespace VOM {
+namespace ACL {
+
+/**
+ * Definition of the static singular_db for ACL Lists
+ */
+singular_db<l2_list::key_t, l2_list> l2_list::m_db;
+
+/**
+ * Definition of the static per-handle DB for ACL Lists
+ */
+std::map<handle_t, std::weak_ptr<l2_list>> l2_list::m_hdl_db;
+
+l2_list::event_handler l2_list::m_evh;
+
+l2_list::event_handler::event_handler()
+{
+ OM::register_listener(this);
+ inspect::register_handler({ "l2-acl-list" }, "L2 ACL lists", this);
+}
+
+l2_list::l2_list(const key_t& key)
+ : m_hdl(handle_t::INVALID)
+ , m_key(key)
+{
+}
+
+l2_list::l2_list(const handle_t& hdl, const key_t& key)
+ : m_hdl(hdl)
+ , m_key(key)
+{
+}
+
+l2_list::l2_list(const key_t& key, const rules_t& rules)
+ : m_hdl(handle_t::INVALID)
+ , m_key(key)
+ , m_rules(rules)
+{
+}
+
+l2_list::l2_list(const l2_list& o)
+ : m_hdl(o.m_hdl)
+ , m_key(o.m_key)
+ , m_rules(o.m_rules)
+{
+}
+
+l2_list::~l2_list()
+{
+ sweep();
+ m_db.release(m_key, this);
+}
+
+std::shared_ptr<l2_list>
+l2_list::singular() const
+{
+ return find_or_add(*this);
+}
+
+/**
+ * Dump all ACLs into the stream provided
+ */
+void
+l2_list::dump(std::ostream& os)
+{
+ db_dump(m_db, os);
+}
+
+/**
+ * convert to string format for debug purposes
+ */
+std::string
+l2_list::to_string() const
+{
+ std::ostringstream s;
+ s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:[";
+
+ for (auto rule : m_rules) {
+ s << rule.to_string() << " ";
+ }
+
+ s << "]]";
+
+ return (s.str());
+}
+
+void
+l2_list::insert(const l2_rule& rule)
+{
+ m_rules.insert(rule);
+}
+
+void
+l2_list::remove(const l2_rule& rule)
+{
+ m_rules.erase(rule);
+}
+
+const handle_t&
+l2_list::handle() const
+{
+ return (singular()->handle_i());
+}
+
+std::shared_ptr<l2_list>
+l2_list::find(const handle_t& handle)
+{
+ return (m_hdl_db[handle].lock());
+}
+
+std::shared_ptr<l2_list>
+l2_list::find(const key_t& key)
+{
+ return (m_db.find(key));
+}
+
+std::shared_ptr<l2_list>
+l2_list::find_or_add(const l2_list& temp)
+{
+ return (m_db.find_or_add(temp.key(), temp));
+}
+
+const handle_t&
+l2_list::handle_i() const
+{
+ return (m_hdl.data());
+}
+
+void
+l2_list::add(const key_t& key, const HW::item<handle_t>& item)
+{
+ std::shared_ptr<l2_list> sp = find(key);
+
+ if (sp && item) {
+ m_hdl_db[item.data()] = sp;
+ }
+}
+
+void
+l2_list::remove(const HW::item<handle_t>& item)
+{
+ m_hdl_db.erase(item.data());
+}
+
+const l2_list::key_t&
+l2_list::key() const
+{
+ return m_key;
+}
+
+const l2_list::rules_t&
+l2_list::rules() const
+{
+ return m_rules;
+}
+
+bool
+l2_list::operator==(const l2_list& l) const
+{
+ return (key() == l.key() && rules() == l.rules());
+}
+
+void
+l2_list::event_handler::handle_populate(const client_db::key_t& key)
+{
+ /*
+ * dump L2 ACLs
+ */
+ std::shared_ptr<list_cmds::l2_dump_cmd> cmd =
+ std::make_shared<list_cmds::l2_dump_cmd>();
+
+ HW::enqueue(cmd);
+ HW::write();
+
+ for (auto& record : *cmd) {
+ auto& payload = record.get_payload();
+
+ const handle_t hdl(payload.acl_index);
+ l2_list acl(hdl, std::string(reinterpret_cast<const char*>(payload.tag)));
+
+ for (unsigned int ii = 0; ii < payload.count; ii++) {
+ const route::prefix_t pfx(payload.r[ii].is_ipv6,
+ payload.r[ii].src_ip_addr,
+ payload.r[ii].src_ip_prefix_len);
+ l2_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), pfx,
+ { payload.r[ii].src_mac }, { payload.r[ii].src_mac_mask });
+
+ acl.insert(rule);
+ }
+ VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string();
+
+ /*
+ * Write each of the discovered ACLs into the OM,
+ * but disable the HW Command q whilst we do, so that no
+ * commands are sent to VPP
+ */
+ OM::commit(key, acl);
+ }
+}
+
+void
+l2_list::event_handler::show(std::ostream& os)
+{
+ db_dump(m_db, os);
+}
+
+dependency_t
+l2_list::event_handler::order() const
+{
+ return (dependency_t::ACL);
+}
+
+void
+l2_list::event_handler::handle_replay()
+{
+ m_db.replay();
+}
+
+void
+l2_list::update(const l2_list& obj)
+{
+ /*
+ * always update the instance with the latest rule set
+ */
+ if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) {
+ HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
+ }
+ /*
+ * We don't, can't, read the priority from VPP,
+ * so the is equals check above does not include the priorty.
+ * but we save it now.
+ */
+ m_rules = obj.m_rules;
+}
+
+void
+l2_list::sweep(void)
+{
+ if (m_hdl) {
+ HW::enqueue(new list_cmds::l2_delete_cmd(m_hdl));
+ }
+ HW::write();
+}
+
+void
+l2_list::replay(void)
+{
+ if (m_hdl) {
+ m_hdl.data().reset();
+ HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
+ }
+}
+
+}; // namespace ACL
+}; // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
diff --git a/extras/vom/vom/acl_list.hpp b/extras/vom/vom/acl_l2_list.hpp
index eff5e1c5a52..82cfd072fe7 100644
--- a/extras/vom/vom/acl_list.hpp
+++ b/extras/vom/vom/acl_l2_list.hpp
@@ -13,13 +13,12 @@
* limitations under the License.
*/
-#ifndef __VOM_ACL_LIST_H__
-#define __VOM_ACL_LIST_H__
+#ifndef __VOM_ACL_L2_LIST_H__
+#define __VOM_ACL_L2_LIST_H__
#include <set>
#include "vom/acl_l2_rule.hpp"
-#include "vom/acl_l3_rule.hpp"
#include "vom/acl_types.hpp"
#include "vom/hw.hpp"
#include "vom/inspect.hpp"
@@ -29,12 +28,11 @@
namespace VOM {
namespace ACL {
/**
- * An ACL list comprises a set of match actions rules to be applied to
+ * An L2 ACL list comprises a set of match actions rules to be applied to
* packets.
* A list is bound to a given interface.
*/
-template <typename RULE>
-class list : public object_base
+class l2_list : public object_base
{
public:
/**
@@ -47,126 +45,72 @@ public:
/**
* The rule container type
*/
- typedef std::multiset<RULE> rules_t;
+ typedef std::multiset<l2_rule> rules_t;
/**
* Construct a new object matching the desried state
*/
- list(const key_t& key)
- : m_hdl(handle_t::INVALID)
- , m_key(key)
- {
- }
+ l2_list(const key_t& key);
- list(const handle_t& hdl, const key_t& key)
- : m_hdl(hdl)
- , m_key(key)
- {
- }
+ l2_list(const handle_t& hdl, const key_t& key);
- list(const key_t& key, const rules_t& rules)
- : m_hdl(handle_t::INVALID)
- , m_key(key)
- , m_rules(rules)
- {
- }
+ l2_list(const key_t& key, const rules_t& rules);
/**
* Copy Constructor
*/
- list(const list& o)
- : m_hdl(o.m_hdl)
- , m_key(o.m_key)
- , m_rules(o.m_rules)
- {
- }
+ l2_list(const l2_list& o);
/**
* Destructor
*/
- ~list()
- {
- sweep();
- m_db.release(m_key, this);
- }
+ ~l2_list();
/**
* Return the 'sigular instance' of the ACL that matches this object
*/
- std::shared_ptr<list> singular() const { return find_or_add(*this); }
+ std::shared_ptr<l2_list> singular() const;
/**
* Dump all ACLs into the stream provided
*/
- static void dump(std::ostream& os) { m_db.dump(os); }
+ static void dump(std::ostream& os);
/**
* convert to string format for debug purposes
*/
- std::string to_string() const
- {
- std::ostringstream s;
- s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:[";
-
- for (auto rule : m_rules) {
- s << rule.to_string() << " ";
- }
-
- s << "]]";
-
- return (s.str());
- }
+ std::string to_string() const;
/**
* Insert priority sorted a rule into the list
*/
- void insert(const RULE& rule) { m_rules.insert(rule); }
+ void insert(const l2_rule& rule);
/**
* Remove a rule from the list
*/
- void remove(const RULE& rule) { m_rules.erase(rule); }
+ void remove(const l2_rule& rule);
/**
* Return the VPP assign handle
*/
- const handle_t& handle() const { return (singular()->handle_i()); }
-
- static std::shared_ptr<list> find(const handle_t& handle)
- {
- return (m_hdl_db[handle].lock());
- }
-
- static std::shared_ptr<list> find(const key_t& key)
- {
- return (m_db.find(key));
- }
+ const handle_t& handle() const;
- static void add(const key_t& key, const HW::item<handle_t>& item)
- {
- std::shared_ptr<list> sp = find(key);
+ static std::shared_ptr<l2_list> find(const handle_t& handle);
- if (sp && item) {
- m_hdl_db[item.data()] = sp;
- }
- }
+ static std::shared_ptr<l2_list> find(const key_t& key);
+ static void add(const key_t& key, const HW::item<handle_t>& item);
- static void remove(const HW::item<handle_t>& item)
- {
- m_hdl_db.erase(item.data());
- }
+ static void remove(const HW::item<handle_t>& item);
- const key_t& key() const { return m_key; }
+ const key_t& key() const;
- const rules_t& rules() const { return m_rules; }
+ const rules_t& rules() const;
/**
* Comparison operator - for UT
*/
- bool operator==(const list& l) const
- {
- return (key() == l.key() && rules() == l.rules());
- }
+ bool operator==(const l2_list& l) const;
private:
/**
@@ -187,7 +131,7 @@ private:
/**
* Handle a replay event
*/
- void handle_replay() { m_db.replay(); }
+ void handle_replay();
/**
* Show the object in the Singular DB
@@ -197,7 +141,7 @@ private:
/**
* Get the sortable Id of the listener
*/
- dependency_t order() const { return (dependency_t::ACL); }
+ dependency_t order() const;
};
/**
@@ -208,7 +152,7 @@ private:
/**
* Enqueue commands to the VPP command Q for the update
*/
- void update(const list& obj);
+ void update(const l2_list& obj);
/**
* HW assigned handle
@@ -218,15 +162,12 @@ private:
/**
* Find or add the sigular instance in the DB
*/
- static std::shared_ptr<list> find_or_add(const list& temp)
- {
- return (m_db.find_or_add(temp.key(), temp));
- }
+ static std::shared_ptr<l2_list> find_or_add(const l2_list& temp);
/**
* return the acl-list's handle in the singular instance
*/
- const handle_t& handle_i() const { return (m_hdl.data()); }
+ const handle_t& handle_i() const;
/*
* It's the VOM::OM class that updates call update
@@ -236,7 +177,7 @@ private:
/**
* It's the VOM::singular_db class that calls replay()
*/
- friend class singular_db<key_t, list>;
+ friend class singular_db<key_t, l2_list>;
/**
* Sweep/reap the object if still stale
@@ -251,12 +192,12 @@ private:
/**
* A map of all ACL's against the client's key
*/
- static singular_db<key_t, list> m_db;
+ static singular_db<key_t, l2_list> m_db;
/**
* A map of all ACLs keyed against VPP's handle
*/
- static std::map<handle_t, std::weak_ptr<list>> m_hdl_db;
+ static std::map<handle_t, std::weak_ptr<l2_list>> m_hdl_db;
/**
* The Key is a user defined identifer for this ACL
@@ -269,32 +210,8 @@ private:
rules_t m_rules;
};
-/**
- * Typedef the L3 ACL type
- */
-typedef list<l3_rule> l3_list;
-
-/**
- * Typedef the L2 ACL type
- */
-typedef list<l2_rule> l2_list;
-
-/**
- * Definition of the static singular_db for ACL Lists
- */
-template <typename RULE>
-singular_db<typename ACL::list<RULE>::key_t, ACL::list<RULE>> list<RULE>::m_db;
-
-/**
- * Definition of the static per-handle DB for ACL Lists
- */
-template <typename RULE>
-std::map<handle_t, std::weak_ptr<ACL::list<RULE>>> list<RULE>::m_hdl_db;
-
-template <typename RULE>
-typename ACL::list<RULE>::event_handler list<RULE>::m_evh;
-};
-};
+}; // namesace ACL
+}; // namespace VOM
/*
* fd.io coding-style-patch-verification: ON
diff --git a/extras/vom/vom/acl_list.cpp b/extras/vom/vom/acl_l3_list.cpp
index 651eb87a4a9..d3e44746ae1 100644
--- a/extras/vom/vom/acl_list.cpp
+++ b/extras/vom/vom/acl_l3_list.cpp
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-#include "vom/acl_list.hpp"
+#include "vom/acl_l3_list.hpp"
#include "vom/acl_list_cmds.hpp"
#include "vom/logger.hpp"
#include "vom/singular_db_funcs.hpp"
@@ -21,76 +21,168 @@
namespace VOM {
namespace ACL {
-template <>
-l2_list::event_handler::event_handler()
+/**
+ * Definition of the static singular_db for ACL Lists
+ */
+singular_db<l3_list::key_t, l3_list> l3_list::m_db;
+
+/**
+ * Definition of the static per-handle DB for ACL Lists
+ */
+std::map<handle_t, std::weak_ptr<l3_list>> l3_list::m_hdl_db;
+
+l3_list::event_handler l3_list::m_evh;
+
+l3_list::event_handler::event_handler()
{
OM::register_listener(this);
- inspect::register_handler({ "l2-acl-list" }, "L2 ACL lists", this);
+ inspect::register_handler({ "l3-acl-list" }, "L3 ACL lists", this);
+}
+
+l3_list::l3_list(const key_t& key)
+ : m_hdl(handle_t::INVALID)
+ , m_key(key)
+{
}
-template <>
+l3_list::l3_list(const handle_t& hdl, const key_t& key)
+ : m_hdl(hdl)
+ , m_key(key)
+{
+}
+
+l3_list::l3_list(const key_t& key, const rules_t& rules)
+ : m_hdl(handle_t::INVALID)
+ , m_key(key)
+ , m_rules(rules)
+{
+}
+
+l3_list::l3_list(const l3_list& o)
+ : m_hdl(o.m_hdl)
+ , m_key(o.m_key)
+ , m_rules(o.m_rules)
+{
+}
+
+l3_list::~l3_list()
+{
+ sweep();
+ m_db.release(m_key, this);
+}
+
+std::shared_ptr<l3_list>
+l3_list::singular() const
+{
+ return find_or_add(*this);
+}
+
+/**
+ * Dump all ACLs into the stream provided
+ */
void
-l2_list::event_handler::handle_populate(const client_db::key_t& key)
+l3_list::dump(std::ostream& os)
{
- /* hack to get this function instantiated */
- m_evh.order();
+ db_dump(m_db, os);
+}
- /*
- * dump VPP Bridge domains
- */
- std::shared_ptr<list_cmds::l2_dump_cmd> cmd =
- std::make_shared<list_cmds::l2_dump_cmd>();
+/**
+ * convert to string format for debug purposes
+ */
+std::string
+l3_list::to_string() const
+{
+ std::ostringstream s;
+ s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:[";
- HW::enqueue(cmd);
- HW::write();
+ for (auto rule : m_rules) {
+ s << rule.to_string() << " ";
+ }
- for (auto& record : *cmd) {
- auto& payload = record.get_payload();
+ s << "]]";
- const handle_t hdl(payload.acl_index);
- l2_list acl(hdl, std::string(reinterpret_cast<const char*>(payload.tag)));
+ return (s.str());
+}
- for (unsigned int ii = 0; ii < payload.count; ii++) {
- const route::prefix_t pfx(payload.r[ii].is_ipv6,
- payload.r[ii].src_ip_addr,
- payload.r[ii].src_ip_prefix_len);
- l2_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), pfx,
- { payload.r[ii].src_mac }, { payload.r[ii].src_mac_mask });
+void
+l3_list::insert(const l3_rule& rule)
+{
+ m_rules.insert(rule);
+}
- acl.insert(rule);
- }
- VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string();
+void
+l3_list::remove(const l3_rule& rule)
+{
+ m_rules.erase(rule);
+}
- /*
- * Write each of the discovered ACLs into the OM,
- * but disable the HW Command q whilst we do, so that no
- * commands are sent to VPP
- */
- OM::commit(key, acl);
+const handle_t&
+l3_list::handle() const
+{
+ return (singular()->handle_i());
+}
+
+std::shared_ptr<l3_list>
+l3_list::find(const handle_t& handle)
+{
+ return (m_hdl_db[handle].lock());
+}
+
+std::shared_ptr<l3_list>
+l3_list::find(const key_t& key)
+{
+ return (m_db.find(key));
+}
+
+std::shared_ptr<l3_list>
+l3_list::find_or_add(const l3_list& temp)
+{
+ return (m_db.find_or_add(temp.key(), temp));
+}
+
+const handle_t&
+l3_list::handle_i() const
+{
+ return (m_hdl.data());
+}
+
+void
+l3_list::add(const key_t& key, const HW::item<handle_t>& item)
+{
+ std::shared_ptr<l3_list> sp = find(key);
+
+ if (sp && item) {
+ m_hdl_db[item.data()] = sp;
}
}
-template <>
void
-l2_list::event_handler::show(std::ostream& os)
+l3_list::remove(const HW::item<handle_t>& item)
{
- db_dump(m_db, os);
+ m_hdl_db.erase(item.data());
}
-template <>
-l3_list::event_handler::event_handler()
+const l3_list::key_t&
+l3_list::key() const
{
- OM::register_listener(this);
- inspect::register_handler({ "l3-acl-list" }, "L3 ACL lists", this);
+ return m_key;
+}
+
+const l3_list::rules_t&
+l3_list::rules() const
+{
+ return m_rules;
+}
+
+bool
+l3_list::operator==(const l3_list& l) const
+{
+ return (key() == l.key() && rules() == l.rules());
}
-template <>
void
l3_list::event_handler::handle_populate(const client_db::key_t& key)
{
- /* hack to get this function instantiated */
- m_evh.order();
-
/*
* dump L3 ACLs Bridge domains
*/
@@ -136,39 +228,32 @@ l3_list::event_handler::handle_populate(const client_db::key_t& key)
}
}
-template <>
void
l3_list::event_handler::show(std::ostream& os)
{
db_dump(m_db, os);
}
-template <>
+dependency_t
+l3_list::event_handler::order() const
+{
+ return (dependency_t::ACL);
+}
+
void
-l3_list::update(const l3_list& obj)
+l3_list::event_handler::handle_replay()
{
- /*
- * always update the instance with the latest rule set
- */
- if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) {
- HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules));
- }
- /*
- * We don't, can't, read the priority from VPP,
- * so the is equals check above does not include the priorty.
- * but we save it now.
- */
- m_rules = obj.m_rules;
+ m_db.replay();
}
-template <>
+
void
-l2_list::update(const l2_list& obj)
+l3_list::update(const l3_list& obj)
{
/*
* always update the instance with the latest rule set
*/
if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) {
- HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
+ HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules));
}
/*
* We don't, can't, read the priority from VPP,
@@ -177,10 +262,10 @@ l2_list::update(const l2_list& obj)
*/
m_rules = obj.m_rules;
}
+
/**
* Sweep/reap the object if still stale
*/
-template <>
void
l3_list::sweep(void)
{
@@ -189,20 +274,10 @@ l3_list::sweep(void)
}
HW::write();
}
-template <>
-void
-l2_list::sweep(void)
-{
- if (m_hdl) {
- HW::enqueue(new list_cmds::l2_delete_cmd(m_hdl));
- }
- HW::write();
-}
/**
* Replay the objects state to HW
*/
-template <>
void
l3_list::replay(void)
{
@@ -211,15 +286,6 @@ l3_list::replay(void)
HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules));
}
}
-template <>
-void
-l2_list::replay(void)
-{
- if (m_hdl) {
- m_hdl.data().reset();
- HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
- }
-}
}; // namespace ACL
}; // namespace VOM
diff --git a/extras/vom/vom/acl_l3_list.hpp b/extras/vom/vom/acl_l3_list.hpp
new file mode 100644
index 00000000000..092bbe37dc0
--- /dev/null
+++ b/extras/vom/vom/acl_l3_list.hpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VOM_ACL_L3_LIST_H__
+#define __VOM_ACL_L3_LIST_H__
+
+#include <set>
+
+#include "vom/acl_l3_rule.hpp"
+#include "vom/acl_types.hpp"
+#include "vom/hw.hpp"
+#include "vom/inspect.hpp"
+#include "vom/om.hpp"
+#include "vom/singular_db.hpp"
+
+namespace VOM {
+namespace ACL {
+/**
+ * An L3 ACL list comprises a set of match actions rules to be applied to
+ * packets.
+ * A list is bound to a given interface.
+ */
+class l3_list : public object_base
+{
+public:
+ /**
+ * The KEY can be used to uniquely identify the ACL.
+ * (other choices for keys, like the summation of the properties
+ * of the rules, are rather too cumbersome to use
+ */
+ typedef std::string key_t;
+
+ /**
+ * The rule container type
+ */
+ typedef std::multiset<l3_rule> rules_t;
+
+ /**
+ * Construct a new object matching the desried state
+ */
+ l3_list(const key_t& key);
+
+ l3_list(const handle_t& hdl, const key_t& key);
+
+ l3_list(const key_t& key, const rules_t& rules);
+
+ /**
+ * Copy Constructor
+ */
+ l3_list(const l3_list& o);
+
+ /**
+ * Destructor
+ */
+ ~l3_list();
+
+ /**
+ * Return the 'sigular instance' of the ACL that matches this object
+ */
+ std::shared_ptr<l3_list> singular() const;
+
+ /**
+ * Dump all ACLs into the stream provided
+ */
+ static void dump(std::ostream& os);
+
+ /**
+ * convert to string format for debug purposes
+ */
+ std::string to_string() const;
+
+ /**
+ * Insert priority sorted a rule into the list
+ */
+ void insert(const l3_rule& rule);
+
+ /**
+ * Remove a rule from the list
+ */
+ void remove(const l3_rule& rule);
+
+ /**
+ * Return the VPP assign handle
+ */
+ const handle_t& handle() const;
+
+ static std::shared_ptr<l3_list> find(const handle_t& handle);
+
+ static std::shared_ptr<l3_list> find(const key_t& key);
+ static void add(const key_t& key, const HW::item<handle_t>& item);
+
+ static void remove(const HW::item<handle_t>& item);
+
+ const key_t& key() const;
+
+ const rules_t& rules() const;
+
+ /**
+ * Comparison operator - for UT
+ */
+ bool operator==(const l3_list& l) const;
+
+private:
+ /**
+ * Class definition for listeners to OM events
+ */
+ class event_handler : public OM::listener, public inspect::command_handler
+ {
+ public:
+ event_handler();
+
+ virtual ~event_handler() = default;
+
+ /**
+ * Handle a populate event
+ */
+ void handle_populate(const client_db::key_t& key);
+
+ /**
+ * Handle a replay event
+ */
+ void handle_replay();
+
+ /**
+ * Show the object in the Singular DB
+ */
+ void show(std::ostream& os);
+
+ /**
+ * Get the sortable Id of the listener
+ */
+ dependency_t order() const;
+ };
+
+ /**
+ * event_handler to register with OM
+ */
+ static event_handler m_evh;
+
+ /**
+ * Enqueue commands to the VPP command Q for the update
+ */
+ void update(const l3_list& obj);
+
+ /**
+ * HW assigned handle
+ */
+ HW::item<handle_t> m_hdl;
+
+ /**
+ * Find or add the sigular instance in the DB
+ */
+ static std::shared_ptr<l3_list> find_or_add(const l3_list& temp);
+
+ /**
+ * return the acl-list's handle in the singular instance
+ */
+ const handle_t& handle_i() const;
+
+ /*
+ * It's the VOM::OM class that updates call update
+ */
+ friend class VOM::OM;
+
+ /**
+ * It's the VOM::singular_db class that calls replay()
+ */
+ friend class singular_db<key_t, l3_list>;
+
+ /**
+ * Sweep/reap the object if still stale
+ */
+ void sweep(void);
+
+ /**
+ * Replay the objects state to HW
+ */
+ void replay(void);
+
+ /**
+ * A map of all ACL's against the client's key
+ */
+ static singular_db<key_t, l3_list> m_db;
+
+ /**
+ * A map of all ACLs keyed against VPP's handle
+ */
+ static std::map<handle_t, std::weak_ptr<l3_list>> m_hdl_db;
+
+ /**
+ * The Key is a user defined identifer for this ACL
+ */
+ const key_t m_key;
+
+ /**
+ * A sorted list of the rules
+ */
+ rules_t m_rules;
+};
+
+}; // namesace ACL
+}; // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
+
+#endif
diff --git a/extras/vom/vom/acl_list_cmds.hpp b/extras/vom/vom/acl_list_cmds.hpp
index ec69773f857..252dec7175d 100644
--- a/extras/vom/vom/acl_list_cmds.hpp
+++ b/extras/vom/vom/acl_list_cmds.hpp
@@ -16,7 +16,8 @@
#ifndef __VOM_ACL_LIST_CMDS_H__
#define __VOM_ACL_LIST_CMDS_H__
-#include "vom/acl_list.hpp"
+#include "vom/acl_l2_list.hpp"
+#include "vom/acl_l3_list.hpp"
#include "vom/dump_cmd.hpp"
#include "vom/rpc_cmd.hpp"
@@ -28,12 +29,12 @@ namespace list_cmds {
/**
* A command class that Create the list
*/
-template <typename RULE, typename UPDATE>
+template <typename LIST, typename UPDATE>
class update_cmd : public rpc_cmd<HW::item<handle_t>, UPDATE>
{
public:
- typedef typename list<RULE>::rules_t cmd_rules_t;
- typedef typename list<RULE>::key_t cmd_key_t;
+ typedef typename LIST::rules_t cmd_rules_t;
+ typedef typename LIST::key_t cmd_key_t;
/**
* Constructor
@@ -78,7 +79,7 @@ public:
void succeeded()
{
rpc_cmd<HW::item<handle_t>, UPDATE>::succeeded();
- list<RULE>::add(m_key, this->item());
+ LIST::add(m_key, this->item());
}
/**
@@ -106,7 +107,7 @@ private:
/**
* add the created acl to the DB
*/
- void insert_acl() { list<RULE>::add(m_key, this->item()); }
+ void insert_acl() { LIST::add(m_key, this->item()); }
/**
* The key.
@@ -122,7 +123,7 @@ private:
/**
* A cmd class that Deletes an ACL
*/
-template <typename RULE, typename DELETE>
+template <typename LIST, typename DELETE>
class delete_cmd : public rpc_cmd<HW::item<handle_t>, DELETE>
{
public:
@@ -162,7 +163,7 @@ private:
/**
* remove the acl from the DB
*/
- void remove_acl() { list<RULE>::remove(this->item()); }
+ void remove_acl() { LIST::remove(this->item()); }
};
/**
@@ -196,15 +197,15 @@ public:
/**
* Typedef the L3 ACL commands
*/
-typedef update_cmd<l3_rule, vapi::Acl_add_replace> l3_update_cmd;
-typedef delete_cmd<l3_rule, vapi::Acl_del> l3_delete_cmd;
+typedef update_cmd<l3_list, vapi::Acl_add_replace> l3_update_cmd;
+typedef delete_cmd<l3_list, vapi::Acl_del> l3_delete_cmd;
typedef dump_cmd<vapi::Acl_dump> l3_dump_cmd;
/**
* Typedef the L2 ACL commands
*/
-typedef update_cmd<l2_rule, vapi::Macip_acl_add> l2_update_cmd;
-typedef delete_cmd<l2_rule, vapi::Macip_acl_del> l2_delete_cmd;
+typedef update_cmd<l2_list, vapi::Macip_acl_add> l2_update_cmd;
+typedef delete_cmd<l2_list, vapi::Macip_acl_del> l2_delete_cmd;
typedef dump_cmd<vapi::Macip_acl_dump> l2_dump_cmd;
}; // namespace list_cmds
diff --git a/extras/vom/vom/gbp_contract.hpp b/extras/vom/vom/gbp_contract.hpp
index e517a3d6428..2f1c3c5a950 100644
--- a/extras/vom/vom/gbp_contract.hpp
+++ b/extras/vom/vom/gbp_contract.hpp
@@ -16,7 +16,7 @@
#ifndef __VOM_GBP_CONTRACT_H__
#define __VOM_GBP_CONTRACT_H__
-#include "vom/acl_list.hpp"
+#include "vom/acl_l3_list.hpp"
#include "vom/gbp_endpoint.hpp"
#include "vom/gbp_rule.hpp"
#include "vom/interface.hpp"
diff --git a/test/ext/vom_test.cpp b/test/ext/vom_test.cpp
index 26653940d2e..569bd8c1fd9 100644
--- a/test/ext/vom_test.cpp
+++ b/test/ext/vom_test.cpp
@@ -48,7 +48,8 @@
#include "vom/sub_interface_cmds.hpp"
#include "vom/acl_ethertype.hpp"
#include "vom/acl_ethertype_cmds.hpp"
-#include "vom/acl_list.hpp"
+#include "vom/acl_l2_list.hpp"
+#include "vom/acl_l3_list.hpp"
#include "vom/acl_binding.hpp"
#include "vom/acl_list_cmds.hpp"
#include "vom/acl_binding_cmds.hpp"