diff options
52 files changed, 678 insertions, 297 deletions
diff --git a/src/vpp-api/vom/Makefile.am b/src/vpp-api/vom/Makefile.am index cdeacdfa6f5..8eab140896a 100644 --- a/src/vpp-api/vom/Makefile.am +++ b/src/vpp-api/vom/Makefile.am @@ -15,7 +15,7 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 AM_LIBTOOLFLAGS = --quiet -AM_CXXFLAGS = -Wall -std=gnu++11 -I${top_srcdir} -I${top_builddir}/vpp-api/vapi/ -I$(top_srcdir)/vpp-api/ -I${libdir}/../include +AM_CXXFLAGS = -Wall -std=gnu++11 -I${top_srcdir} -I${top_builddir}/vpp-api/vapi/ -I$(top_srcdir)/vpp-api/ -I${libdir}/../include -O0 AM_LDFLAGS = -shared -no-undefined bin_PROGRAMS = diff --git a/src/vpp-api/vom/acl_binding.cpp b/src/vpp-api/vom/acl_binding.cpp index 832e232f871..267b02a620b 100644 --- a/src/vpp-api/vom/acl_binding.cpp +++ b/src/vpp-api/vom/acl_binding.cpp @@ -144,7 +144,7 @@ l2_binding::replay(void) std::ostream& operator<<(std::ostream& os, - const std::pair<direction_t, interface::key_type>& key) + const std::pair<direction_t, interface::key_t>& key) { os << "[" << key.first.to_string() << " " << key.second << "]"; diff --git a/src/vpp-api/vom/acl_binding.hpp b/src/vpp-api/vom/acl_binding.hpp index 1e87a888ec4..3687503ef06 100644 --- a/src/vpp-api/vom/acl_binding.hpp +++ b/src/vpp-api/vom/acl_binding.hpp @@ -40,7 +40,7 @@ public: /** * The key for a binding is the direction and the interface */ - typedef std::pair<direction_t, interface::key_type> key_t; + typedef std::pair<direction_t, interface::key_t> key_t; /** * Construct a new object matching the desried state @@ -224,9 +224,8 @@ template <typename LIST> typename ACL::binding<LIST>::event_handler binding<LIST>::m_evh; }; -std::ostream& operator<<( - std::ostream& os, - const std::pair<direction_t, interface::key_type>& key); +std::ostream& operator<<(std::ostream& os, + const std::pair<direction_t, interface::key_t>& key); }; /* diff --git a/src/vpp-api/vom/arp_proxy_binding.cpp b/src/vpp-api/vom/arp_proxy_binding.cpp index c44cda3cebf..407436cfc8f 100644 --- a/src/vpp-api/vom/arp_proxy_binding.cpp +++ b/src/vpp-api/vom/arp_proxy_binding.cpp @@ -21,7 +21,7 @@ namespace VOM { /** * A DB of all ARP proxy bindings configs */ -singular_db<interface::key_type, arp_proxy_binding> arp_proxy_binding::m_db; +singular_db<interface::key_t, arp_proxy_binding> arp_proxy_binding::m_db; arp_proxy_binding::event_handler arp_proxy_binding::m_evh; diff --git a/src/vpp-api/vom/arp_proxy_binding.hpp b/src/vpp-api/vom/arp_proxy_binding.hpp index 2ee814aa129..f57f6971991 100644 --- a/src/vpp-api/vom/arp_proxy_binding.hpp +++ b/src/vpp-api/vom/arp_proxy_binding.hpp @@ -116,7 +116,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<interface::key_type, arp_proxy_binding>; + friend class singular_db<interface::key_t, arp_proxy_binding>; /** * Sweep/reap the object if still stale @@ -149,7 +149,7 @@ private: /** * A map of all ArpProxy bindings keyed against the interface. */ - static singular_db<interface::key_type, arp_proxy_binding> m_db; + static singular_db<interface::key_t, arp_proxy_binding> m_db; }; }; diff --git a/src/vpp-api/vom/bridge_domain.cpp b/src/vpp-api/vom/bridge_domain.cpp index 81d83621212..682681988f9 100644 --- a/src/vpp-api/vom/bridge_domain.cpp +++ b/src/vpp-api/vom/bridge_domain.cpp @@ -52,12 +52,24 @@ bridge_domain::bridge_domain(const bridge_domain& o) { } +const bridge_domain::key_t& +bridge_domain::key() const +{ + return (m_id.data()); +} + uint32_t bridge_domain::id() const { return (m_id.data()); } +bool +bridge_domain::operator==(const bridge_domain& b) const +{ + return (id() == b.id()); +} + void bridge_domain::sweep() { @@ -93,41 +105,17 @@ bridge_domain::to_string() const } std::shared_ptr<bridge_domain> -bridge_domain::find(uint32_t id) +bridge_domain::find(const key_t& key) { - /* - * Loop throught the entire map looking for matching interface. - * not the most efficient algorithm, but it will do for now. The - * number of L3 configs is low and this is only called during bootup - */ - std::shared_ptr<bridge_domain> bd; - - auto it = m_db.cbegin(); - - while (it != m_db.cend()) { - /* - * The key in the DB is a pair of the interface's name and prefix. - * If the keys match, save the L3-config - */ - auto key = it->first; - - if (id == key) { - bd = it->second.lock(); - break; - } - - ++it; - } - - return (bd); + return (m_db.find(key)); } void bridge_domain::update(const bridge_domain& desired) { /* - * the desired state is always that the interface should be created - */ + * the desired state is always that the interface should be created + */ if (rc_t::OK != m_id.rc()) { HW::enqueue(new bridge_domain_cmds::create_cmd(m_id, m_learning_mode)); } diff --git a/src/vpp-api/vom/bridge_domain.hpp b/src/vpp-api/vom/bridge_domain.hpp index 2c134f0740b..c7f84e9ec3f 100644 --- a/src/vpp-api/vom/bridge_domain.hpp +++ b/src/vpp-api/vom/bridge_domain.hpp @@ -32,6 +32,11 @@ class bridge_domain : public object_base { public: /** + * Key Type for Bridge Domains in the sigular DB + */ + typedef uint32_t key_t; + + /** * Bridge Domain Learning mode */ struct learning_mode_t : enum_base<learning_mode_t> @@ -68,6 +73,21 @@ public: ~bridge_domain(); /** + * Comparison operator - for UT + */ + bool operator==(const bridge_domain& b) const; + + /** + * Return the bridge domain's VPP ID + */ + uint32_t id() const; + + /** + * Return the bridge domain's key + */ + const key_t& key() const; + + /** * Return the matchin 'singular' instance of the bridge-domain */ std::shared_ptr<bridge_domain> singular() const; @@ -78,14 +98,9 @@ public: std::string to_string(void) const; /** - * Return VPP's handle for this obejct - */ - uint32_t id() const; - - /** * Static function to find the bridge_domain in the model */ - static std::shared_ptr<bridge_domain> find(uint32_t id); + static std::shared_ptr<bridge_domain> find(const key_t& key); /** * Dump all bridge-doamin into the stream provided @@ -146,7 +161,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<uint32_t, bridge_domain>; + friend class singular_db<key_t, bridge_domain>; /** * Sweep/reap the object if still stale @@ -171,7 +186,7 @@ private: /** * A map of all interfaces key against the interface's name */ - static singular_db<uint32_t, bridge_domain> m_db; + static singular_db<key_t, bridge_domain> m_db; }; }; diff --git a/src/vpp-api/vom/bridge_domain_arp_entry.cpp b/src/vpp-api/vom/bridge_domain_arp_entry.cpp index ee34dbbce5b..e8ae30f7642 100644 --- a/src/vpp-api/vom/bridge_domain_arp_entry.cpp +++ b/src/vpp-api/vom/bridge_domain_arp_entry.cpp @@ -25,22 +25,22 @@ bridge_domain_arp_entry::event_handler bridge_domain_arp_entry::m_evh; bridge_domain_arp_entry::bridge_domain_arp_entry( const bridge_domain& bd, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr) + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac) : m_hw(false) , m_bd(bd.singular()) - , m_mac(mac) , m_ip_addr(ip_addr) + , m_mac(mac) { } bridge_domain_arp_entry::bridge_domain_arp_entry( - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr) + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac) : m_hw(false) , m_bd(nullptr) - , m_mac(mac) , m_ip_addr(ip_addr) + , m_mac(mac) { /* * the route goes in the default table @@ -54,8 +54,8 @@ bridge_domain_arp_entry::bridge_domain_arp_entry( const bridge_domain_arp_entry& bde) : m_hw(bde.m_hw) , m_bd(bde.m_bd) - , m_mac(bde.m_mac) , m_ip_addr(bde.m_ip_addr) + , m_mac(bde.m_mac) { } @@ -64,7 +64,19 @@ bridge_domain_arp_entry::~bridge_domain_arp_entry() sweep(); // not in the DB anymore. - m_db.release(std::make_tuple(m_bd->id(), m_mac, m_ip_addr), this); + m_db.release(key(), this); +} + +const bridge_domain_arp_entry::key_t +bridge_domain_arp_entry::key() const +{ + return (std::make_pair(m_bd->key(), m_ip_addr)); +} + +bool +bridge_domain_arp_entry::operator==(const bridge_domain_arp_entry& bdae) const +{ + return ((key() == bdae.key()) && (m_mac == bdae.m_mac)); } void @@ -111,8 +123,13 @@ bridge_domain_arp_entry::update(const bridge_domain_arp_entry& r) std::shared_ptr<bridge_domain_arp_entry> bridge_domain_arp_entry::find_or_add(const bridge_domain_arp_entry& temp) { - return (m_db.find_or_add( - std::make_tuple(temp.m_bd->id(), temp.m_mac, temp.m_ip_addr), temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<bridge_domain_arp_entry> +bridge_domain_arp_entry::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<bridge_domain_arp_entry> @@ -127,15 +144,6 @@ bridge_domain_arp_entry::dump(std::ostream& os) m_db.dump(os); } -std::ostream& -operator<<(std::ostream& os, const bridge_domain_arp_entry::key_t& key) -{ - os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", " - << std::get<2>(key) << "]"; - - return (os); -} - bridge_domain_arp_entry::event_handler::event_handler() { OM::register_listener(this); diff --git a/src/vpp-api/vom/bridge_domain_arp_entry.hpp b/src/vpp-api/vom/bridge_domain_arp_entry.hpp index caad96b88db..b4af6a0f62e 100644 --- a/src/vpp-api/vom/bridge_domain_arp_entry.hpp +++ b/src/vpp-api/vom/bridge_domain_arp_entry.hpp @@ -32,20 +32,20 @@ public: * The key for a bridge_domain ARP entry; * the BD, IP address and MAC address */ - typedef std::tuple<uint32_t, mac_address_t, boost::asio::ip::address> key_t; + typedef std::pair<bridge_domain::key_t, boost::asio::ip::address> key_t; /** - * Construct a bridge_domain in the given bridge domain + * Construct a bridge domain ARP Entry in the given bridge domain */ bridge_domain_arp_entry(const bridge_domain& bd, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr); + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac); /** - * Construct a bridge_domain in the default table + * Construct a bridge domain ARP entry in the default table */ - bridge_domain_arp_entry(const mac_address_t& mac, - const boost::asio::ip::address& ip_addr); + bridge_domain_arp_entry(const boost::asio::ip::address& ip_addr, + const mac_address_t& mac); /** * Copy Construct @@ -58,6 +58,16 @@ public: ~bridge_domain_arp_entry(); /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const bridge_domain_arp_entry& bdae) const; + + /** * Return the matching 'singular instance' */ std::shared_ptr<bridge_domain_arp_entry> singular() const; @@ -65,8 +75,7 @@ public: /** * Find the instnace of the bridge_domain domain in the OM */ - static std::shared_ptr<bridge_domain_arp_entry> find( - const bridge_domain_arp_entry& temp); + static std::shared_ptr<bridge_domain_arp_entry> find(const key_t& k); /** * Dump all bridge_domain-doamin into the stream provided @@ -156,14 +165,14 @@ private: std::shared_ptr<bridge_domain> m_bd; /** - * The mac to match + * The IP address */ - mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; /** - * The IP address + * The mac to return */ - boost::asio::ip::address m_ip_addr; + mac_address_t m_mac; /** * A map of all bridge_domains @@ -173,7 +182,7 @@ private: std::ostream& operator<<(std::ostream& os, const bridge_domain_arp_entry::key_t& key); -}; +}; // namespace /* * fd.io coding-style-patch-verification: ON diff --git a/src/vpp-api/vom/bridge_domain_entry.cpp b/src/vpp-api/vom/bridge_domain_entry.cpp index 343d82d3ffa..79f36f7d947 100644 --- a/src/vpp-api/vom/bridge_domain_entry.cpp +++ b/src/vpp-api/vom/bridge_domain_entry.cpp @@ -55,12 +55,24 @@ bridge_domain_entry::bridge_domain_entry(const bridge_domain_entry& bde) { } +const bridge_domain_entry::key_t +bridge_domain_entry::key() const +{ + return (std::make_pair(m_bd->key(), m_mac)); +} + +bool +bridge_domain_entry::operator==(const bridge_domain_entry& bde) const +{ + return ((key() == bde.key()) && (m_tx_itf == bde.m_tx_itf)); +} + bridge_domain_entry::~bridge_domain_entry() { sweep(); // not in the DB anymore. - m_db.release(std::make_pair(m_bd->id(), m_mac), this); + m_db.release(key(), this); } void @@ -106,7 +118,13 @@ bridge_domain_entry::update(const bridge_domain_entry& r) std::shared_ptr<bridge_domain_entry> bridge_domain_entry::find_or_add(const bridge_domain_entry& temp) { - return (m_db.find_or_add(std::make_pair(temp.m_bd->id(), temp.m_mac), temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<bridge_domain_entry> +bridge_domain_entry::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<bridge_domain_entry> diff --git a/src/vpp-api/vom/bridge_domain_entry.hpp b/src/vpp-api/vom/bridge_domain_entry.hpp index 35ea8b68f50..2aef697ebca 100644 --- a/src/vpp-api/vom/bridge_domain_entry.hpp +++ b/src/vpp-api/vom/bridge_domain_entry.hpp @@ -30,7 +30,7 @@ public: /** * The key for a bridge_domain */ - typedef std::pair<uint32_t, mac_address_t> key_t; + typedef std::pair<bridge_domain::key_t, mac_address_t> key_t; /** * Construct a bridge_domain in the given bridge domain @@ -55,6 +55,16 @@ public: ~bridge_domain_entry(); /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const bridge_domain_entry& be) const; + + /** * Return the matching 'singular instance' */ std::shared_ptr<bridge_domain_entry> singular() const; @@ -62,8 +72,7 @@ public: /** * Find the instnace of the bridge_domain domain in the OM */ - static std::shared_ptr<bridge_domain_entry> find( - const bridge_domain_entry& temp); + static std::shared_ptr<bridge_domain_entry> find(const key_t& k); /** * Dump all bridge_domain-doamin into the stream provided diff --git a/src/vpp-api/vom/client_db.cpp b/src/vpp-api/vom/client_db.cpp index fad2c13be91..41463d1dd74 100644 --- a/src/vpp-api/vom/client_db.cpp +++ b/src/vpp-api/vom/client_db.cpp @@ -25,7 +25,10 @@ client_db::find(const client_db::key_t& k) void client_db::flush(const client_db::key_t& k) { - m_objs.erase(m_objs.find(k)); + auto found = m_objs.find(k); + + if (found != m_objs.end()) + m_objs.erase(found); } void diff --git a/src/vpp-api/vom/cmd.hpp b/src/vpp-api/vom/cmd.hpp index 814355320a7..9c87d31218a 100644 --- a/src/vpp-api/vom/cmd.hpp +++ b/src/vpp-api/vom/cmd.hpp @@ -20,8 +20,6 @@ #include "vom/types.hpp" -#include <vapi/vapi.hpp> - namespace VOM { /** * Forward declaration of the connection class diff --git a/src/vpp-api/vom/connection.cpp b/src/vpp-api/vom/connection.cpp index 3d965ea863f..90c02f943c4 100644 --- a/src/vpp-api/vom/connection.cpp +++ b/src/vpp-api/vom/connection.cpp @@ -13,11 +13,14 @@ * limitations under the License. */ +#include <vapi/vapi.hpp> + #include "vom/connection.hpp" namespace VOM { connection::connection() - : m_app_name("vpp-OM") + : m_vapi_conn(new vapi::Connection()) + , m_app_name("VOM") { } @@ -29,7 +32,7 @@ connection::~connection() void connection::disconnect() { - m_vapi_conn.disconnect(); + m_vapi_conn->disconnect(); } void @@ -38,16 +41,16 @@ connection::connect() vapi_error_e rv; do { - rv = m_vapi_conn.connect(m_app_name.c_str(), - NULL, // m_api_prefix.c_str(), - 128, 128); + rv = m_vapi_conn->connect(m_app_name.c_str(), + NULL, // m_api_prefix.c_str(), + 128, 128); } while (VAPI_OK != rv); } vapi::Connection& connection::ctx() { - return (m_vapi_conn); + return (*m_vapi_conn); } } diff --git a/src/vpp-api/vom/connection.hpp b/src/vpp-api/vom/connection.hpp index 0dc01845eb8..c8acf78cca5 100644 --- a/src/vpp-api/vom/connection.hpp +++ b/src/vpp-api/vom/connection.hpp @@ -16,9 +16,15 @@ #ifndef __VOM_CONNECTION_H__ #define __VOM_CONNECTION_H__ +#include <memory> #include <string> -#include <vapi/vapi.hpp> +/** + * Forward declarations + */ +namespace vapi { +class Connection; +}; namespace VOM { /** @@ -56,7 +62,7 @@ private: /** * The VAPI connection context */ - vapi::Connection m_vapi_conn; + std::unique_ptr<vapi::Connection> m_vapi_conn; /** * The name of this application diff --git a/src/vpp-api/vom/dhcp_config.cpp b/src/vpp-api/vom/dhcp_config.cpp index a7299267334..0b6e2eff0de 100644 --- a/src/vpp-api/vom/dhcp_config.cpp +++ b/src/vpp-api/vom/dhcp_config.cpp @@ -20,7 +20,7 @@ namespace VOM { /** * A DB of all DHCP configs */ -singular_db<interface::key_type, dhcp_config> dhcp_config::m_db; +singular_db<interface::key_t, dhcp_config> dhcp_config::m_db; dhcp_config::event_handler dhcp_config::m_evh; @@ -58,6 +58,19 @@ dhcp_config::~dhcp_config() m_db.release(m_itf->key(), this); } +bool +dhcp_config::operator==(const dhcp_config& l) const +{ + return ((key() == l.key()) && (m_hostname == l.m_hostname) && + (m_client_id == l.m_client_id)); +} + +const dhcp_config::key_t& +dhcp_config::key() const +{ + return (m_itf->key()); +} + void dhcp_config::sweep() { @@ -112,6 +125,12 @@ dhcp_config::find_or_add(const dhcp_config& temp) } std::shared_ptr<dhcp_config> +dhcp_config::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr<dhcp_config> dhcp_config::singular() const { return find_or_add(*this); diff --git a/src/vpp-api/vom/dhcp_config.hpp b/src/vpp-api/vom/dhcp_config.hpp index f64a3c8a2e2..db97af98c19 100644 --- a/src/vpp-api/vom/dhcp_config.hpp +++ b/src/vpp-api/vom/dhcp_config.hpp @@ -34,6 +34,11 @@ class dhcp_config : public object_base { public: /** + * typedef for the DHCP config key type + */ + typedef interface::key_t key_t; + + /** * Construct a new object matching the desried state */ dhcp_config(const interface& itf, const std::string& hostname); @@ -56,6 +61,16 @@ public: ~dhcp_config(); /** + * Comparison operator - for UT + */ + bool operator==(const dhcp_config& d) const; + + /** + * Return the object's key + */ + const key_t& key() const; + + /** * Return the 'singular' of the DHCP config that matches this object */ std::shared_ptr<dhcp_config> singular() const; @@ -71,8 +86,13 @@ public: static void dump(std::ostream& os); /** - * A class that listens to DHCP Events + * Find a DHCP config from its key */ + static std::shared_ptr<dhcp_config> find(const key_t& k); + + /** + * A class that listens to DHCP Events + */ class event_listener { public: @@ -153,7 +173,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<interface::key_type, dhcp_config>; + friend class singular_db<key_t, dhcp_config>; /** * Sweep/reap the object if still stale @@ -191,7 +211,7 @@ private: /** * A map of all Dhcp configs keyed against the interface. */ - static singular_db<interface::key_type, dhcp_config> m_db; + static singular_db<key_t, dhcp_config> m_db; }; }; diff --git a/src/vpp-api/vom/hw.hpp b/src/vpp-api/vom/hw.hpp index 77ae5c36e75..7e30b677bff 100644 --- a/src/vpp-api/vom/hw.hpp +++ b/src/vpp-api/vom/hw.hpp @@ -18,10 +18,12 @@ #include <deque> #include <map> +#include <queue> #include <sstream> #include <string> #include <thread> +#include "vom/cmd.hpp" #include "vom/connection.hpp" #include "vom/types.hpp" @@ -230,7 +232,7 @@ public: /** * Blocking Connect to VPP - call once at bootup */ - void connect(); + virtual void connect(); /** * Disable the passing of commands to VPP. Whilst disabled all diff --git a/src/vpp-api/vom/inspect.cpp b/src/vpp-api/vom/inspect.cpp index 55b533bbbff..605a921b5ac 100644 --- a/src/vpp-api/vom/inspect.cpp +++ b/src/vpp-api/vom/inspect.cpp @@ -60,8 +60,8 @@ inspect::handle_input(const std::string& message, std::ostream& output) OM::dump(results[1], output); } else if (message.find("all") != std::string::npos) { /* - * get the unique set of handlers, then invoke each - */ + * get the unique set of handlers, then invoke each + */ std::set<command_handler*> hdlrs; for (auto h : *m_cmd_handlers) { hdlrs.insert(h.second); diff --git a/src/vpp-api/vom/interface.cpp b/src/vpp-api/vom/interface.cpp index 39ca074920f..aab2eabb91b 100644 --- a/src/vpp-api/vom/interface.cpp +++ b/src/vpp-api/vom/interface.cpp @@ -24,7 +24,7 @@ namespace VOM { /** * A DB of all the interfaces, key on the name */ -singular_db<const std::string, interface> interface::m_db; +singular_db<interface::key_t, interface> interface::m_db; /** * A DB of all the interfaces, key on VPP's handle @@ -91,6 +91,15 @@ interface::interface(const interface& o) { } +bool +interface::operator==(const interface& i) const +{ + return ((key() == i.key()) && + (m_l2_address.data() == i.m_l2_address.data()) && + (m_state == i.m_state) && (m_rd == i.m_rd) && (m_type == i.m_type) && + (m_oper == i.m_oper)); +} + interface::event_listener::event_listener() : m_status(rc_t::NOOP) { @@ -217,8 +226,8 @@ interface::to_string() const { std::ostringstream s; s << "interface:[" << m_name << " type:" << m_type.to_string() - << " hdl:" << m_hdl.to_string() - << " l2-address:" << m_l2_address.to_string(); + << " hdl:" << m_hdl.to_string() << " l2-address:[" + << m_l2_address.to_string() << "]"; if (m_rd) { s << " rd:" << m_rd->to_string(); @@ -236,7 +245,7 @@ interface::name() const return (m_name); } -const interface::key_type& +const interface::key_t& interface::key() const { return (name()); @@ -377,7 +386,7 @@ interface::enable_stats(interface::stat_listener& el) std::shared_ptr<interface> interface::singular_i() const { - return (m_db.find_or_add(name(), *this)); + return (m_db.find_or_add(key(), *this)); } std::shared_ptr<interface> @@ -387,9 +396,9 @@ interface::singular() const } std::shared_ptr<interface> -interface::find(const std::string& name) +interface::find(const key_t& k) { - return (m_db.find(name)); + return (m_db.find(k)); } std::shared_ptr<interface> @@ -399,9 +408,9 @@ interface::find(const handle_t& handle) } void -interface::add(const std::string& name, const HW::item<handle_t>& item) +interface::add(const key_t& key, const HW::item<handle_t>& item) { - std::shared_ptr<interface> sp = find(name); + std::shared_ptr<interface> sp = find(key); if (sp && item) { m_hdl_db[item.data()] = sp; @@ -424,9 +433,9 @@ void interface::event_handler::handle_populate(const client_db::key_t& key) { /* - * dump VPP current states - */ - std::shared_ptr<interface_cmds::dump_cmd> cmd(new interface_cmds::dump_cmd()); + * dump VPP current states + */ + interface_cmds::dump_cmd* cmd = new interface_cmds::dump_cmd(); HW::enqueue(cmd); HW::write(); @@ -438,15 +447,15 @@ interface::event_handler::handle_populate(const client_db::key_t& key) if (itf && interface::type_t::LOCAL != itf->type()) { VOM_LOG(log_level_t::DEBUG) << "dump: " << itf->to_string(); /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, *itf); /** - * Get the address configured on the interface - */ + * Get the address configured on the interface + */ std::shared_ptr<l3_binding_cmds::dump_v4_cmd> dcmd = std::make_shared<l3_binding_cmds::dump_v4_cmd>( l3_binding_cmds::dump_v4_cmd(itf->handle())); @@ -491,7 +500,9 @@ interface::event_handler::show(std::ostream& os) { m_db.dump(os); } -} + +} // namespace VOM + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp-api/vom/interface.hpp b/src/vpp-api/vom/interface.hpp index 76ecf8af0a0..8cba2fa2c2c 100644 --- a/src/vpp-api/vom/interface.hpp +++ b/src/vpp-api/vom/interface.hpp @@ -44,7 +44,7 @@ public: /** * The key for interface's key */ - typedef std::string key_type; + typedef std::string key_t; /** * The iterator type @@ -207,7 +207,7 @@ public: /** * Return the interface type */ - const key_type& key() const; + const key_t& key() const; /** * Return the L2 Address @@ -225,6 +225,11 @@ public: void set(const oper_state_t& state); /** + * Comparison operator - only used for UT + */ + virtual bool operator==(const interface& i) const; + + /** * A base class for interface Create commands */ template <typename MSG> @@ -400,21 +405,14 @@ public: }; /** - * The the singular instance of the interface in the object_base-Model - */ - static std::shared_ptr<interface> find(const interface& temp); - - /** - * The the singular instance of the interface in the object_base-Model - * by handle + * The the singular instance of the interface in the DB by handle */ static std::shared_ptr<interface> find(const handle_t& h); /** - * The the singular instance of the interface in the object_base-Model - * by name + * The the singular instance of the interface in the DB by key */ - static std::shared_ptr<interface> find(const std::string& s); + static std::shared_ptr<interface> find(const key_t& k); /** * Dump all interfaces into the stream provided @@ -472,12 +470,12 @@ protected: /** * A map of all interfaces key against the interface's name */ - static singular_db<const std::string, interface> m_db; + static singular_db<key_t, interface> m_db; /** * Add an interface to the DB keyed on handle */ - static void add(const std::string& name, const HW::item<handle_t>& item); + static void add(const key_t& name, const HW::item<handle_t>& item); /** * remove an interface from the DB keyed on handle @@ -540,7 +538,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<const std::string, interface>; + friend class singular_db<key_t, interface>; /** * The interfaces name diff --git a/src/vpp-api/vom/interface_ip6_nd.hpp b/src/vpp-api/vom/interface_ip6_nd.hpp index 4c7f3915cf2..22f545acdbb 100644 --- a/src/vpp-api/vom/interface_ip6_nd.hpp +++ b/src/vpp-api/vom/interface_ip6_nd.hpp @@ -26,7 +26,6 @@ #include "vom/ra_prefix.hpp" #include "vom/rpc_cmd.hpp" #include "vom/singular_db.hpp" -#include "vom/sub_interface.hpp" namespace VOM { /** @@ -96,7 +95,7 @@ public: /** * The key type for interface ip6 nd */ - typedef interface::key_type key_t; + typedef interface::key_t key_t; /** * Find an singular instance in the DB for the interface passed diff --git a/src/vpp-api/vom/interface_span.cpp b/src/vpp-api/vom/interface_span.cpp index 04c319259c9..5bdbda95a12 100644 --- a/src/vpp-api/vom/interface_span.cpp +++ b/src/vpp-api/vom/interface_span.cpp @@ -20,7 +20,7 @@ namespace VOM { /** * A DB of all interface_span config */ -singular_db<interface_span::key_type_t, interface_span> interface_span::m_db; +singular_db<interface_span::key_t, interface_span> interface_span::m_db; interface_span::event_handler interface_span::m_evh; @@ -96,7 +96,7 @@ interface_span::update(const interface_span& desired) } std::ostream& -operator<<(std::ostream& os, const interface_span::key_type_t& key) +operator<<(std::ostream& os, const interface_span::key_t& key) { os << "[" << key.first << ", " << key.second << "]"; diff --git a/src/vpp-api/vom/interface_span.hpp b/src/vpp-api/vom/interface_span.hpp index 8d3d7cb2532..baa2054a530 100644 --- a/src/vpp-api/vom/interface_span.hpp +++ b/src/vpp-api/vom/interface_span.hpp @@ -103,7 +103,7 @@ public: /** * The key type for interface_spans */ - typedef std::pair<interface::key_type, interface::key_type> key_type_t; + typedef std::pair<interface::key_t, interface::key_t> key_t; /** * Find a singular instance in the DB for the interface passed @@ -165,7 +165,7 @@ private: /** e* It's the singular_db class that calls replay() */ - friend class singular_db<key_type_t, interface_span>; + friend class singular_db<key_t, interface_span>; /** * Sweep/reap the object if still stale @@ -202,14 +202,13 @@ private: * A map of all interface span keyed against the interface to be * mirrored. */ - static singular_db<key_type_t, interface_span> m_db; + static singular_db<key_t, interface_span> m_db; }; /** * Ostream output for the key */ -std::ostream& operator<<(std::ostream& os, - const interface_span::key_type_t& key); +std::ostream& operator<<(std::ostream& os, const interface_span::key_t& key); }; /* diff --git a/src/vpp-api/vom/interface_types.cpp b/src/vpp-api/vom/interface_types.cpp index 6afec8077a5..a089f589f33 100644 --- a/src/vpp-api/vom/interface_types.cpp +++ b/src/vpp-api/vom/interface_types.cpp @@ -21,7 +21,7 @@ namespace VOM { */ const interface::type_t interface::type_t::UNKNOWN(0, "unknown"); const interface::type_t interface::type_t::BVI(1, "BVI"); -const interface::type_t interface::type_t::ETHERNET(2, "Ehternet"); +const interface::type_t interface::type_t::ETHERNET(2, "Ethernet"); const interface::type_t interface::type_t::VXLAN(3, "VXLAN"); const interface::type_t interface::type_t::AFPACKET(4, "AFPACKET"); const interface::type_t interface::type_t::LOOPBACK(5, "LOOPBACK"); diff --git a/src/vpp-api/vom/ip_unnumbered.hpp b/src/vpp-api/vom/ip_unnumbered.hpp index 676c7780b86..b736919744c 100644 --- a/src/vpp-api/vom/ip_unnumbered.hpp +++ b/src/vpp-api/vom/ip_unnumbered.hpp @@ -68,7 +68,7 @@ public: /** * The key type for ip_unnumbereds */ - typedef interface::key_type key_t; + typedef interface::key_t key_t; /** * Find an singular instance in the DB for the interface passed diff --git a/src/vpp-api/vom/l2_binding.cpp b/src/vpp-api/vom/l2_binding.cpp index e380760805c..dd49e570a8e 100644 --- a/src/vpp-api/vom/l2_binding.cpp +++ b/src/vpp-api/vom/l2_binding.cpp @@ -20,7 +20,7 @@ namespace VOM { /** * A DB of all the L2 Configs */ -singular_db<const handle_t, l2_binding> l2_binding::m_db; +singular_db<l2_binding::key_t, l2_binding> l2_binding::m_db; l2_binding::event_handler l2_binding::m_evh; @@ -75,6 +75,24 @@ l2_binding::l2_binding(const l2_binding& o) { } +const l2_binding::key_t& +l2_binding::key() const +{ + return (m_itf->key()); +} + +bool +l2_binding::operator==(const l2_binding& l) const +{ + return ((*m_itf == *l.m_itf) && (*m_bd == *l.m_bd)); +} + +std::shared_ptr<l2_binding> +l2_binding::find(const key_t& key) +{ + return (m_db.find(key)); +} + void l2_binding::sweep() { @@ -108,14 +126,14 @@ l2_binding::~l2_binding() sweep(); // not in the DB anymore. - m_db.release(m_itf->handle(), this); + m_db.release(m_itf->key(), this); } std::string l2_binding::to_string() const { std::ostringstream s; - s << "L2-config:[" << m_itf->to_string() << " " << m_bd->to_string() << " " + s << "L2-binding:[" << m_itf->to_string() << " " << m_bd->to_string() << " " << m_binding.to_string() << "]"; return (s.str()); @@ -154,7 +172,7 @@ l2_binding::update(const l2_binding& desired) std::shared_ptr<l2_binding> l2_binding::find_or_add(const l2_binding& temp) { - return (m_db.find_or_add(temp.m_itf->handle(), temp)); + return (m_db.find_or_add(temp.m_itf->key(), temp)); } std::shared_ptr<l2_binding> diff --git a/src/vpp-api/vom/l2_binding.hpp b/src/vpp-api/vom/l2_binding.hpp index 0e6f7fc0d68..ba97cab512c 100644 --- a/src/vpp-api/vom/l2_binding.hpp +++ b/src/vpp-api/vom/l2_binding.hpp @@ -32,6 +32,11 @@ namespace VOM { class l2_binding : public object_base { public: + /** + * Key type for an L2 binding in the singular DB + */ + typedef interface::key_t key_t; + struct l2_vtr_op_t : public enum_base<l2_vtr_op_t> { l2_vtr_op_t(const l2_vtr_op_t& l) = default; @@ -67,6 +72,16 @@ public: ~l2_binding(); /** + * Return the binding's key + */ + const key_t& key() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l2_binding& l) const; + + /** * Return the 'singular instance' of the L2 config that matches this * object */ @@ -87,6 +102,11 @@ public: */ void set(const l2_vtr_op_t& op, uint16_t tag); + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr<l2_binding> find(const key_t& key); + private: /** * Class definition for listeners to OM events @@ -141,7 +161,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<const handle_t, l2_binding>; + friend class singular_db<key_t, l2_binding>; /** * Sweep/reap the object if still stale @@ -186,7 +206,7 @@ private: /** * A map of all L2 interfaces key against the interface's handle_t */ - static singular_db<const handle_t, l2_binding> m_db; + static singular_db<key_t, l2_binding> m_db; }; }; diff --git a/src/vpp-api/vom/l3_binding.cpp b/src/vpp-api/vom/l3_binding.cpp index 065504cd190..be7c9d1e24b 100644 --- a/src/vpp-api/vom/l3_binding.cpp +++ b/src/vpp-api/vom/l3_binding.cpp @@ -17,7 +17,7 @@ #include "vom/l3_binding_cmds.hpp" namespace VOM { -singular_db<l3_binding::key_type_t, l3_binding> l3_binding::m_db; +singular_db<l3_binding::key_t, l3_binding> l3_binding::m_db; l3_binding::event_handler l3_binding::m_evh; @@ -43,7 +43,19 @@ l3_binding::~l3_binding() sweep(); // not in the DB anymore. - m_db.release(make_pair(m_itf->key(), m_pfx), this); + m_db.release(key(), this); +} + +bool +l3_binding::operator==(const l3_binding& l) const +{ + return ((m_pfx == l.m_pfx) && (*m_itf == *l.m_itf)); +} + +const l3_binding::key_t +l3_binding::key() const +{ + return (make_pair(m_itf->key(), m_pfx)); } void @@ -93,7 +105,7 @@ std::string l3_binding::to_string() const { std::ostringstream s; - s << "L3-config:[" << m_itf->to_string() << " prefix:" << m_pfx.to_string() + s << "L3-binding:[" << m_itf->to_string() << " prefix:" << m_pfx.to_string() << " " << m_binding.to_string() << "]"; return (s.str()); @@ -116,7 +128,13 @@ l3_binding::update(const l3_binding& desired) std::shared_ptr<l3_binding> l3_binding::find_or_add(const l3_binding& temp) { - return (m_db.find_or_add(make_pair(temp.m_itf->key(), temp.m_pfx), temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<l3_binding> +l3_binding::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<l3_binding> @@ -132,7 +150,7 @@ l3_binding::dump(std::ostream& os) } std::ostream& -operator<<(std::ostream& os, const l3_binding::key_type_t& key) +operator<<(std::ostream& os, const l3_binding::key_t& key) { os << "[" << key.first << ", " << key.second << "]"; diff --git a/src/vpp-api/vom/l3_binding.hpp b/src/vpp-api/vom/l3_binding.hpp index a1470587e94..0177e56ea2b 100644 --- a/src/vpp-api/vom/l3_binding.hpp +++ b/src/vpp-api/vom/l3_binding.hpp @@ -31,6 +31,11 @@ class l3_binding : public object_base { public: /** + * The key type for l3_bindings + */ + typedef std::pair<interface::key_t, route::prefix_t> key_t; + + /** * Construct a new object matching the desried state */ l3_binding(const interface& itf, const route::prefix_t& pfx); @@ -46,14 +51,19 @@ public: ~l3_binding(); /** - * The key type for l3_bindings + * Comparison operator */ - typedef std::pair<interface::key_type, route::prefix_t> key_type_t; + bool operator==(const l3_binding& l) const; + + /** + * Get the object's key + */ + const key_t key() const; /** * The iterator type */ - typedef singular_db<key_type_t, l3_binding>::const_iterator const_iterator_t; + typedef singular_db<key_t, l3_binding>::const_iterator const_iterator_t; static const_iterator_t cbegin(); static const_iterator_t cend(); @@ -85,10 +95,15 @@ public: static void dump(std::ostream& os); /** - * Find an singular instance in the DB for the interface passed + * Find all bindings in the DB for the interface passed */ static std::deque<std::shared_ptr<l3_binding>> find(const interface& i); + /** + * Find a binding from its key + */ + static std::shared_ptr<l3_binding> find(const key_t& k); + private: /** * Class definition for listeners to OM events @@ -143,7 +158,7 @@ private: /** e* It's the singular_db class that calls replay() */ - friend class singular_db<key_type_t, l3_binding>; + friend class singular_db<key_t, l3_binding>; /** * Sweep/reap the object if still stale @@ -179,13 +194,13 @@ private: * A map of all L3 configs keyed against a combination of the interface * and subnet's keys. */ - static singular_db<key_type_t, l3_binding> m_db; + static singular_db<key_t, l3_binding> m_db; }; /** * Ostream output for the key */ -std::ostream& operator<<(std::ostream& os, const l3_binding::key_type_t& key); +std::ostream& operator<<(std::ostream& os, const l3_binding::key_t& key); }; /* diff --git a/src/vpp-api/vom/lldp_binding.cpp b/src/vpp-api/vom/lldp_binding.cpp index 05d51bbf0b1..a1d3d9f57ba 100644 --- a/src/vpp-api/vom/lldp_binding.cpp +++ b/src/vpp-api/vom/lldp_binding.cpp @@ -20,7 +20,7 @@ namespace VOM { /** * A DB of all LLDP configs */ -singular_db<interface::key_type, lldp_binding> lldp_binding::m_db; +singular_db<interface::key_t, lldp_binding> lldp_binding::m_db; lldp_binding::event_handler lldp_binding::m_evh; @@ -46,6 +46,18 @@ lldp_binding::~lldp_binding() m_db.release(m_itf->key(), this); } +bool +lldp_binding::operator==(const lldp_binding& l) const +{ + return ((key() == l.key()) && (m_port_desc == l.m_port_desc)); +} + +const lldp_binding::key_t& +lldp_binding::key() const +{ + return (m_itf->key()); +} + void lldp_binding::sweep() { @@ -99,6 +111,12 @@ lldp_binding::find_or_add(const lldp_binding& temp) } std::shared_ptr<lldp_binding> +lldp_binding::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr<lldp_binding> lldp_binding::singular() const { return find_or_add(*this); diff --git a/src/vpp-api/vom/lldp_binding.hpp b/src/vpp-api/vom/lldp_binding.hpp index 896708f699a..0c5610013ac 100644 --- a/src/vpp-api/vom/lldp_binding.hpp +++ b/src/vpp-api/vom/lldp_binding.hpp @@ -31,6 +31,11 @@ class lldp_binding : public object_base { public: /** + * Typedef for the key of a LLDP binding + */ + typedef interface::key_t key_t; + + /** * Construct a new object matching the desried state */ lldp_binding(const interface& itf, const std::string& hostname); @@ -39,12 +44,23 @@ public: * Copy Constructor */ lldp_binding(const lldp_binding& o); + /** * Destructor */ ~lldp_binding(); /** + * Comparison operator + */ + bool operator==(const lldp_binding& b) const; + + /** + * Return this object's key + */ + const key_t& key() const; + + /** * Return the 'singular' of the LLDP binding that matches this object */ std::shared_ptr<lldp_binding> singular() const; @@ -59,6 +75,11 @@ public: */ static void dump(std::ostream& os); + /** + * Find or add LLDP binding based on its key + */ + static std::shared_ptr<lldp_binding> find(const key_t& k); + private: /** * Class definition for listeners to OM events @@ -113,7 +134,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<interface::key_type, lldp_binding>; + friend class singular_db<key_t, lldp_binding>; /** * Sweep/reap the object if still stale @@ -146,7 +167,7 @@ private: /** * A map of all Lldp bindings keyed against the interface. */ - static singular_db<interface::key_type, lldp_binding> m_db; + static singular_db<key_t, lldp_binding> m_db; }; }; diff --git a/src/vpp-api/vom/lldp_global.cpp b/src/vpp-api/vom/lldp_global.cpp index e7d425e12d9..7e701dc4c52 100644 --- a/src/vpp-api/vom/lldp_global.cpp +++ b/src/vpp-api/vom/lldp_global.cpp @@ -48,6 +48,19 @@ lldp_global::~lldp_global() m_db.release(m_system_name, this); } +const lldp_global::key_t& +lldp_global::key() const +{ + return (m_system_name); +} + +bool +lldp_global::operator==(const lldp_global& l) const +{ + return ((key() == l.key()) && (m_tx_hold == l.m_tx_hold) && + (m_tx_interval == l.m_tx_interval)); +} + void lldp_global::sweep() { @@ -92,7 +105,13 @@ lldp_global::update(const lldp_global& desired) std::shared_ptr<lldp_global> lldp_global::find_or_add(const lldp_global& temp) { - return (m_db.find_or_add(temp.m_system_name, temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<lldp_global> +lldp_global::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<lldp_global> diff --git a/src/vpp-api/vom/lldp_global.hpp b/src/vpp-api/vom/lldp_global.hpp index 743f9f72070..f545a2828cc 100644 --- a/src/vpp-api/vom/lldp_global.hpp +++ b/src/vpp-api/vom/lldp_global.hpp @@ -18,13 +18,9 @@ #include "vom/hw.hpp" #include "vom/inspect.hpp" -#include "vom/interface.hpp" #include "vom/object_base.hpp" #include "vom/om.hpp" #include "vom/singular_db.hpp" -#include "vom/sub_interface.hpp" - -#include <vapi/lldp.api.vapi.hpp> namespace VOM { /** @@ -34,6 +30,11 @@ class lldp_global : public object_base { public: /** + * The key for the global conifugration is the 'system' namse + */ + typedef std::string key_t; + + /** * Construct a new object matching the desried state */ lldp_global(const std::string& system_name, @@ -51,6 +52,16 @@ public: ~lldp_global(); /** + * Get this objects key + */ + const key_t& key() const; + + /** + * Comparison operator + */ + bool operator==(const lldp_global& l) const; + + /** * Return the 'singular' of the LLDP global that matches this object */ std::shared_ptr<lldp_global> singular() const; @@ -66,45 +77,9 @@ public: static void dump(std::ostream& os); /** - * A command class that binds the LLDP global to the interface + * Find LLDP global config from its key */ - class config_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Lldp_config> - { - public: - /** - * Constructor - */ - config_cmd(HW::item<bool>& item, - const std::string& system_name, - uint32_t tx_hold, - uint32_t tx_interval); - - /** - * 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 config_cmd& i) const; - - private: - /** - * The system name - */ - const std::string m_system_name; - - /** - * TX timer configs - */ - uint32_t m_tx_hold; - uint32_t m_tx_interval; - }; + static std::shared_ptr<lldp_global> find(const key_t& k); private: /** @@ -160,7 +135,7 @@ private: /** * It's the singular_db class that calls replay() */ - friend class singular_db<interface::key_type, lldp_global>; + friend class singular_db<key_t, lldp_global>; /** * Sweep/reap the object if still stale @@ -193,7 +168,7 @@ private: * A map of all Lldp globals keyed against the system name. * there needs to be some sort of key, that will do. */ - static singular_db<std::string, lldp_global> m_db; + static singular_db<key_t, lldp_global> m_db; }; }; diff --git a/src/vpp-api/vom/lldp_global_cmds.hpp b/src/vpp-api/vom/lldp_global_cmds.hpp index e4f8f37e4e6..621e73ff71d 100644 --- a/src/vpp-api/vom/lldp_global_cmds.hpp +++ b/src/vpp-api/vom/lldp_global_cmds.hpp @@ -26,8 +26,8 @@ namespace VOM { namespace lldp_global_cmds { /** -* A command class that binds the LLDP global to the interface -*/ + * A command class that binds the LLDP global to the interface + */ class config_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Lldp_config> { public: diff --git a/src/vpp-api/vom/nat_binding.hpp b/src/vpp-api/vom/nat_binding.hpp index 2f6d67f907f..77612502680 100644 --- a/src/vpp-api/vom/nat_binding.hpp +++ b/src/vpp-api/vom/nat_binding.hpp @@ -61,7 +61,7 @@ public: * The zoe is not included, since the same interface is never inside * and outside. */ - typedef std::tuple<interface::key_type, direction_t, l3_proto_t> key_t; + typedef std::tuple<interface::key_t, direction_t, l3_proto_t> key_t; /** * Construct a new object matching the desried state diff --git a/src/vpp-api/vom/neighbour.cpp b/src/vpp-api/vom/neighbour.cpp index 12b13ca6559..35e9c46b8e8 100644 --- a/src/vpp-api/vom/neighbour.cpp +++ b/src/vpp-api/vom/neighbour.cpp @@ -21,20 +21,20 @@ singular_db<neighbour::key_t, neighbour> neighbour::m_db; neighbour::event_handler neighbour::m_evh; neighbour::neighbour(const interface& itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr) + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac) : m_hw(false) , m_itf(itf.singular()) - , m_mac(mac) , m_ip_addr(ip_addr) + , m_mac(mac) { } neighbour::neighbour(const neighbour& bde) : m_hw(bde.m_hw) , m_itf(bde.m_itf) - , m_mac(bde.m_mac) , m_ip_addr(bde.m_ip_addr) + , m_mac(bde.m_mac) { } @@ -43,7 +43,19 @@ neighbour::~neighbour() sweep(); // not in the DB anymore. - m_db.release(std::make_tuple(m_itf->key(), m_mac, m_ip_addr), this); + m_db.release(key(), this); +} + +bool +neighbour::operator==(const neighbour& n) const +{ + return ((key() == n.key()) && (m_mac == n.m_mac)); +} + +const neighbour::key_t +neighbour::key() const +{ + return (std::make_pair(m_itf->key(), m_ip_addr)); } void @@ -90,8 +102,13 @@ neighbour::update(const neighbour& r) std::shared_ptr<neighbour> neighbour::find_or_add(const neighbour& temp) { - return (m_db.find_or_add( - std::make_tuple(temp.m_itf->key(), temp.m_mac, temp.m_ip_addr), temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<neighbour> +neighbour::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<neighbour> @@ -109,8 +126,7 @@ neighbour::dump(std::ostream& os) std::ostream& operator<<(std::ostream& os, const neighbour::key_t& key) { - os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", " - << std::get<2>(key) << "]"; + os << "[" << key.first << ", " << key.second << "]"; return (os); } @@ -133,8 +149,8 @@ neighbour::populate_i(const client_db::key_t& key, const l3_proto_t& proto) { /* - * dump VPP current states - */ + * dump VPP current states + */ std::shared_ptr<neighbour_cmds::dump_cmd> cmd = std::make_shared<neighbour_cmds::dump_cmd>( neighbour_cmds::dump_cmd(itf->handle(), proto)); @@ -144,23 +160,23 @@ neighbour::populate_i(const client_db::key_t& key, for (auto& record : *cmd) { /* - * construct a neighbour from each recieved record. - */ + * construct a neighbour from each recieved record. + */ auto& payload = record.get_payload(); mac_address_t mac(payload.mac_address); boost::asio::ip::address ip_addr = from_bytes(payload.is_ipv6, payload.ip_address); - neighbour n(*itf, mac, ip_addr); + neighbour n(*itf, ip_addr, mac); VOM_LOG(log_level_t::DEBUG) << "neighbour-dump: " << itf->to_string() << mac.to_string() << ip_addr.to_string(); /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, n); } } diff --git a/src/vpp-api/vom/neighbour.hpp b/src/vpp-api/vom/neighbour.hpp index 85577f077a9..500f03d0a61 100644 --- a/src/vpp-api/vom/neighbour.hpp +++ b/src/vpp-api/vom/neighbour.hpp @@ -22,26 +22,23 @@ namespace VOM { /** - * A entry in the ARP termination table of a Bridge Domain + * A entry in the neighbour entry (ARP or IPv6 ND) */ class neighbour : public object_base { public: /** - * The key for a bridge_domain ARP entry; - * the BD, IP address and MAC address + * The key for a neighbour entry; + * the interface and IP address */ - typedef std::tuple<interface::key_type, - mac_address_t, - boost::asio::ip::address> - key_t; + typedef std::pair<interface::key_t, boost::asio::ip::address> key_t; /** * Construct an ARP entry */ neighbour(const interface& itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr); + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac); /** * Copy Construct @@ -54,17 +51,27 @@ public: ~neighbour(); /** + * Return the object's key + */ + const key_t key() const; + + /** + * Comparison operator + */ + bool operator==(const neighbour& n) const; + + /** * Return the matching 'singular instance' */ std::shared_ptr<neighbour> singular() const; /** - * Find the instnace of the bridge_domain domain in the OM + * Find the neighbour fromits key */ - static std::shared_ptr<neighbour> find(const neighbour& temp); + static std::shared_ptr<neighbour> find(const key_t& k); /** - * Dump all bridge_domain-doamin into the stream provided + * Dump all neighbours into the stream provided */ static void dump(std::ostream& os); @@ -127,7 +134,7 @@ private: const l3_proto_t& proto); /** - * Find or add the instnace of the bridge_domain domain in the OM + * Find or add the instnace of the neighbour in the OM */ static std::shared_ptr<neighbour> find_or_add(const neighbour& temp); @@ -157,14 +164,14 @@ private: std::shared_ptr<interface> m_itf; /** - * The mac to match + * The IP address */ - mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; /** - * The IP address + * The mac to match */ - boost::asio::ip::address m_ip_addr; + mac_address_t m_mac; /** * A map of all bridge_domains diff --git a/src/vpp-api/vom/om.cpp b/src/vpp-api/vom/om.cpp index f82fee3e376..5f5c26e4eea 100644 --- a/src/vpp-api/vom/om.cpp +++ b/src/vpp-api/vom/om.cpp @@ -49,9 +49,9 @@ void OM::sweep(const client_db::key_t& key) { /* - * Find if the object already stored on behalf of this key. - * and mark them stale - */ + * Find if the object already stored on behalf of this key. + * and mark them stale + */ object_ref_list& objs = m_db->find(key); for (auto it = objs.begin(); it != objs.end();) { @@ -69,11 +69,11 @@ void OM::remove(const client_db::key_t& key) { /* - * Simply reset the list for this key. This will desctruct the - * object list and shared_ptrs therein. When the last shared_ptr - * goes the objects desctructor is called and the object is - * removed from OM - */ + * Simply reset the list for this key. This will desctruct the + * object list and shared_ptrs therein. When the last shared_ptr + * goes the objects desctructor is called and the object is + * removed from OM + */ m_db->flush(key); HW::write(); @@ -83,8 +83,8 @@ void OM::replay() { /* - * the listeners are sorted in dependency order - */ + * the listeners are sorted in dependency order + */ for (listener* l : *m_listeners) { l->handle_replay(); } @@ -108,15 +108,15 @@ void OM::populate(const client_db::key_t& key) { /* - * the listeners are sorted in dependency order - */ + * the listeners are sorted in dependency order + */ for (listener* l : *m_listeners) { l->handle_populate(key); } /* - * once we have it all, mark it stale. - */ + * once we have it all, mark it stale. + */ mark(key); } diff --git a/src/vpp-api/vom/om.hpp b/src/vpp-api/vom/om.hpp index f470c5ee185..e68d5ea0017 100644 --- a/src/vpp-api/vom/om.hpp +++ b/src/vpp-api/vom/om.hpp @@ -16,6 +16,7 @@ #ifndef __VOM_OM_H__ #define __VOM_OM_H__ +#include <algorithm> #include <memory> #include <set> diff --git a/src/vpp-api/vom/route.cpp b/src/vpp-api/vom/route.cpp index e59bfbaaf8c..0da2ebba749 100644 --- a/src/vpp-api/vom/route.cpp +++ b/src/vpp-api/vom/route.cpp @@ -102,16 +102,47 @@ path::operator<(const path& p) const { if (m_type < p.m_type) return true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return true; if (m_rd->table_id() < p.m_rd->table_id()) return true; if (m_nh < p.m_nh) return true; + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return true; if (m_interface->handle() < p.m_interface->handle()) return true; return (false); } +path::~path() +{ +} + +bool +path::operator==(const path& p) const +{ + bool result = true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return false; + if (m_rd && p.m_rd) + result &= (*m_rd == *p.m_rd); + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return false; + if (m_interface && p.m_interface) + result &= (*m_interface == *p.m_interface); + return (result && (m_type == p.m_type) && (m_nh == p.m_nh)); +} + std::string path::to_string() const { @@ -174,6 +205,14 @@ path::preference() const return m_preference; } +ip_route::ip_route(const prefix_t& prefix, const path& p) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + ip_route::ip_route(const prefix_t& prefix) : m_hw(false) , m_rd(route_domain::get_default()) @@ -198,12 +237,35 @@ ip_route::ip_route(const route_domain& rd, const prefix_t& prefix) { } +ip_route::ip_route(const route_domain& rd, + const prefix_t& prefix, + const path& p) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + ip_route::~ip_route() { sweep(); // not in the DB anymore. - m_db.release(std::make_pair(m_rd->table_id(), m_prefix), this); + m_db.release(key(), this); + m_paths.clear(); +} + +const ip_route::key_t +ip_route::key() const +{ + return (std::make_pair(m_rd->table_id(), m_prefix)); +} + +bool +ip_route::operator==(const ip_route& i) const +{ + return ((key() == i.key()) && (m_paths == i.m_paths)); } void @@ -262,8 +324,13 @@ ip_route::update(const ip_route& r) std::shared_ptr<ip_route> ip_route::find_or_add(const ip_route& temp) { - return (m_db.find_or_add(std::make_pair(temp.m_rd->table_id(), temp.m_prefix), - temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr<ip_route> +ip_route::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr<ip_route> @@ -308,8 +375,8 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) prefix_t pfx(0, payload.address, payload.address_length); /** -* populating the route domain here -*/ + * populating the route domain here + */ route_domain rd_temp(payload.table_id); std::shared_ptr<route_domain> rd = route_domain::find(rd_temp); if (!rd) { @@ -341,10 +408,10 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) VOM_LOG(log_level_t::DEBUG) << "ip-route-dump: " << ip_r.to_string(); /* -* Write each of the discovered interfaces into the OM, -* but disable the HW Command q whilst we do, so that no -* commands are sent to VPP -*/ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, ip_r); } @@ -383,10 +450,10 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) VOM_LOG(log_level_t::DEBUG) << "ip-route-dump: " << ip_r.to_string(); /* -* Write each of the discovered interfaces into the OM, -* but disable the HW Command q whilst we do, so that no -* commands are sent to VPP -*/ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, ip_r); } } diff --git a/src/vpp-api/vom/route.hpp b/src/vpp-api/vom/route.hpp index 4f27ff1d20b..2fb855a13eb 100644 --- a/src/vpp-api/vom/route.hpp +++ b/src/vpp-api/vom/route.hpp @@ -106,9 +106,14 @@ public: path(const path& p); /** - * Convert the path into the VPP API representation + * Destructor */ - void to_vpp(vapi_payload_ip_add_del_route& payload) const; + ~path(); + + /** + * comparison operator + */ + bool operator==(const path& p) const; /** * Less than operator for set insertion @@ -196,6 +201,11 @@ public: ip_route(const prefix_t& prefix); /** + * Construct a route with a path + */ + ip_route(const prefix_t& prefix, const path& p); + + /** * Copy Construct */ ip_route(const ip_route& r); @@ -206,11 +216,26 @@ public: ip_route(const route_domain& rd, const prefix_t& prefix); /** + * Construct a route in the given route domain with a path + */ + ip_route(const route_domain& rd, const prefix_t& prefix, const path& p); + + /** * Destructor */ ~ip_route(); /** + * Get the route's key + */ + const key_t key() const; + + /** + * Comparison operator + */ + bool operator==(const ip_route& i) const; + + /** * Return the matching 'singular instance' */ std::shared_ptr<ip_route> singular() const; @@ -245,6 +270,11 @@ public: */ std::string to_string() const; + /** + * Return the matching 'singular instance' + */ + static std::shared_ptr<ip_route> find(const key_t& k); + private: /** * Class definition for listeners to OM events diff --git a/src/vpp-api/vom/route_domain.cpp b/src/vpp-api/vom/route_domain.cpp index 08357faa6c5..c723f9f31b6 100644 --- a/src/vpp-api/vom/route_domain.cpp +++ b/src/vpp-api/vom/route_domain.cpp @@ -43,6 +43,12 @@ route_domain::route_domain(const route_domain& o) { } +bool +route_domain::operator==(const route_domain& r) const +{ + return (m_table_id == r.m_table_id); +} + route::table_id_t route_domain::table_id() const { diff --git a/src/vpp-api/vom/route_domain.hpp b/src/vpp-api/vom/route_domain.hpp index 516271f7f66..7d83154a0f1 100644 --- a/src/vpp-api/vom/route_domain.hpp +++ b/src/vpp-api/vom/route_domain.hpp @@ -54,6 +54,11 @@ public: ~route_domain(); /** + * comparison operator - for UT + */ + bool operator==(const route_domain& r) const; + + /** * Return the matching 'singular instance' */ std::shared_ptr<route_domain> singular() const; diff --git a/src/vpp-api/vom/singular_db.hpp b/src/vpp-api/vom/singular_db.hpp index bc49c88551f..07ea2cb4acf 100644 --- a/src/vpp-api/vom/singular_db.hpp +++ b/src/vpp-api/vom/singular_db.hpp @@ -143,7 +143,7 @@ private: /** * the map of objects against their key */ - std::map<KEY, std::weak_ptr<OBJ>> m_map; + std::map<const KEY, std::weak_ptr<OBJ>> m_map; }; }; diff --git a/src/vpp-api/vom/sub_interface.cpp b/src/vpp-api/vom/sub_interface.cpp index ea7fa419f75..01f4a54a517 100644 --- a/src/vpp-api/vom/sub_interface.cpp +++ b/src/vpp-api/vom/sub_interface.cpp @@ -56,6 +56,13 @@ sub_interface::sub_interface(const sub_interface& o) { } +bool +sub_interface::operator==(const sub_interface& s) const +{ + return (interface::operator==(s) && (m_parent->key() == s.m_parent->key()) && + (m_vlan == s.m_vlan)); +} + std::string sub_interface::mk_name(const interface& parent, vlan_id_t vlan) { @@ -88,10 +95,17 @@ sub_interface::singular() const std::shared_ptr<interface> sub_interface::singular_i() const { - return m_db.find_or_add(name(), *this); + return m_db.find_or_add(key(), *this); } + +std::shared_ptr<sub_interface> +sub_interface::find(const key_t& k) +{ + return std::dynamic_pointer_cast<sub_interface>(m_db.find(k)); } +}; // namespace VOM + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp-api/vom/sub_interface.hpp b/src/vpp-api/vom/sub_interface.hpp index 5878f45e251..1c65782e980 100644 --- a/src/vpp-api/vom/sub_interface.hpp +++ b/src/vpp-api/vom/sub_interface.hpp @@ -44,10 +44,20 @@ public: sub_interface(const sub_interface& o); /** + * comparison operator - for UT + */ + bool operator==(const sub_interface& s) const; + + /** * Return the matching 'singular instance' of the sub-interface */ std::shared_ptr<sub_interface> singular() const; + /** + * Find a subinterface from its key + */ + static std::shared_ptr<sub_interface> find(const key_t& k); + private: /** * Construct with handle diff --git a/src/vpp-api/vom/tap_interface.cpp b/src/vpp-api/vom/tap_interface.cpp index 4b6c7875b32..8314b40420e 100644 --- a/src/vpp-api/vom/tap_interface.cpp +++ b/src/vpp-api/vom/tap_interface.cpp @@ -99,8 +99,8 @@ void tap_interface::event_handler::handle_populate(const client_db::key_t& key) { /* - * dump VPP current states - */ + * dump VPP current states + */ std::shared_ptr<tap_interface_cmds::dump_cmd> cmd( new tap_interface_cmds::dump_cmd()); @@ -118,10 +118,10 @@ tap_interface::event_handler::handle_populate(const client_db::key_t& key) VOM_LOG(log_level_t::DEBUG) << "tap-dump: " << itf.to_string(); /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, itf); } } @@ -147,10 +147,11 @@ tap_interface::event_handler::order() const void tap_interface::event_handler::show(std::ostream& os) { - m_db.dump(os); -} + // dumped by the interface handler } +}; // namespace VOM + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp-api/vom/types.cpp b/src/vpp-api/vom/types.cpp index 128d757e539..c5325d287a5 100644 --- a/src/vpp-api/vom/types.cpp +++ b/src/vpp-api/vom/types.cpp @@ -18,6 +18,8 @@ #include <iostream> #include <sstream> +#include <boost/algorithm/string.hpp> + #include "vom/types.hpp" namespace VOM { @@ -111,6 +113,19 @@ mac_address_t::mac_address_t(std::initializer_list<uint8_t> i) std::copy(i.begin(), i.end(), std::begin(bytes)); } +mac_address_t::mac_address_t(const std::string& str) +{ + std::vector<std::string> parts; + + boost::split(parts, str, boost::is_any_of(":")); + + size_t n_bytes = std::min(bytes.size(), parts.size()); + + for (uint32_t ii = 0; ii < n_bytes; ii++) { + bytes[ii] = std::stoul(parts[ii], nullptr, 16); + } +} + const mac_address_t mac_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }); const mac_address_t mac_address_t::ZERO({ 0x0 }); @@ -131,7 +146,6 @@ mac_address_t::to_string() const s.fill('0'); s << std::hex; - s << "mac:["; for (auto byte : bytes) { if (first) first = false; @@ -139,7 +153,6 @@ mac_address_t::to_string() const s << ":"; s << std::setw(2) << static_cast<unsigned int>(byte); } - s << "]"; return (s.str()); } diff --git a/src/vpp-api/vom/types.hpp b/src/vpp-api/vom/types.hpp index ca488fe4029..b57867f164e 100644 --- a/src/vpp-api/vom/types.hpp +++ b/src/vpp-api/vom/types.hpp @@ -222,6 +222,7 @@ std::ostream& operator<<(std::ostream& os, const handle_t& h); struct mac_address_t { mac_address_t(uint8_t bytes[6]); + mac_address_t(const std::string& str); mac_address_t(std::initializer_list<uint8_t> bytes); /** * Convert to byte array diff --git a/src/vpp-api/vom/vxlan_tunnel.cpp b/src/vpp-api/vom/vxlan_tunnel.cpp index abb278b1882..cf872231d41 100644 --- a/src/vpp-api/vom/vxlan_tunnel.cpp +++ b/src/vpp-api/vom/vxlan_tunnel.cpp @@ -217,8 +217,8 @@ void vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key) { /* - * dump VPP current states - */ + * dump VPP current states + */ std::shared_ptr<vxlan_tunnel_cmds::dump_cmd> cmd( new vxlan_tunnel_cmds::dump_cmd()); @@ -262,9 +262,11 @@ vxlan_tunnel::event_handler::order() const void vxlan_tunnel::event_handler::show(std::ostream& os) { - m_db.dump(os); -} + // dumped by the interface handler } + +}; // namespace VOM + /* * fd.io coding-style-patch-verification: ON * diff --git a/test/ext/vom_test.cpp b/test/ext/vom_test.cpp index 612a2d3a6cf..c9ae255a793 100644 --- a/test/ext/vom_test.cpp +++ b/test/ext/vom_test.cpp @@ -808,7 +808,7 @@ BOOST_AUTO_TEST_CASE(test_bridge) { HW::item<bool> hw_bea1(true, rc_t::OK); boost::asio::ip::address ip1 = boost::asio::ip::address::from_string("10.10.10.10"); - bridge_domain_arp_entry *bea1 = new bridge_domain_arp_entry(bd1, mac1, ip1); + bridge_domain_arp_entry *bea1 = new bridge_domain_arp_entry(bd1, ip1, mac1); ADD_EXPECT(bridge_domain_arp_entry_cmds::create_cmd(hw_be1, bd1.id(), mac1, ip1)); TRY_CHECK_RC(OM::write(dante, *bea1)); @@ -1315,7 +1315,7 @@ BOOST_AUTO_TEST_CASE(test_routing) { */ HW::item<bool> hw_neighbour(true, rc_t::OK); mac_address_t mac_n({0,1,2,4,5,6}); - neighbour *ne = new neighbour(itf1, mac_n, nh_10); + neighbour *ne = new neighbour(itf1, nh_10, mac_n); ADD_EXPECT(neighbour_cmds::create_cmd(hw_neighbour, hw_ifh.data(), mac_n, nh_10)); TRY_CHECK_RC(OM::write(ian, *ne)); |