diff options
author | Neale Ranns <neale.ranns@cisco.com> | 2017-11-28 22:29:13 -0800 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2017-11-29 07:42:52 +0000 |
commit | a2ee029d0772e894911c84fb8a0cab5f253e145b (patch) | |
tree | 167d07ee3b3a482ef494f420ceef13a9657d4274 | |
parent | e80ae9ea8ed04c82c151a548916926b5dbfe8ecb (diff) |
VOM: logging, populate and stats fixes
logging: allow a client to register a callback handler to recieve log messages
that way the client can maintain a correctly sequenced log
populate: fix the creation of interface and the setting of the handle
stats: the reset promise idea is not defined behaviour.
Use an eanble/disable command pair
Change-Id: I347720bb65df2874c7619e722d593bc863ee2bf1
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
-rw-r--r-- | src/vpp-api/vom/bridge_domain.cpp | 12 | ||||
-rw-r--r-- | src/vpp-api/vom/bridge_domain_entry.cpp | 14 | ||||
-rw-r--r-- | src/vpp-api/vom/dhcp_config_cmds.cpp | 10 | ||||
-rw-r--r-- | src/vpp-api/vom/hw.cpp | 51 | ||||
-rw-r--r-- | src/vpp-api/vom/hw.hpp | 20 | ||||
-rw-r--r-- | src/vpp-api/vom/interface.cpp | 31 | ||||
-rw-r--r-- | src/vpp-api/vom/interface.hpp | 16 | ||||
-rw-r--r-- | src/vpp-api/vom/interface_cmds.cpp | 63 | ||||
-rw-r--r-- | src/vpp-api/vom/interface_cmds.hpp | 49 | ||||
-rw-r--r-- | src/vpp-api/vom/interface_factory.cpp | 54 | ||||
-rw-r--r-- | src/vpp-api/vom/interface_factory.hpp | 2 | ||||
-rw-r--r-- | src/vpp-api/vom/logger.cpp | 110 | ||||
-rw-r--r-- | src/vpp-api/vom/logger.hpp | 107 | ||||
-rw-r--r-- | src/vpp-api/vom/rpc_cmd.hpp | 2 | ||||
-rw-r--r-- | src/vpp-api/vom/sub_interface.cpp | 14 | ||||
-rw-r--r-- | src/vpp-api/vom/sub_interface.hpp | 14 | ||||
-rw-r--r-- | src/vpp-api/vom/tap_interface.cpp | 10 | ||||
-rw-r--r-- | src/vpp-api/vom/tap_interface.hpp | 10 | ||||
-rw-r--r-- | src/vpp-api/vom/tap_interface_cmds.cpp | 2 | ||||
-rw-r--r-- | src/vpp-api/vom/types.cpp | 5 | ||||
-rw-r--r-- | src/vpp-api/vom/types.hpp | 6 | ||||
-rw-r--r-- | src/vpp-api/vom/vxlan_tunnel.cpp | 21 | ||||
-rw-r--r-- | test/ext/vom_test.cpp | 4 |
23 files changed, 373 insertions, 254 deletions
diff --git a/src/vpp-api/vom/bridge_domain.cpp b/src/vpp-api/vom/bridge_domain.cpp index 583e35d3dad..38cc89b8a30 100644 --- a/src/vpp-api/vom/bridge_domain.cpp +++ b/src/vpp-api/vom/bridge_domain.cpp @@ -159,15 +159,15 @@ bridge_domain::event_handler::handle_populate(const client_db::key_t& key) VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.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 bridge-domains into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, bd); /** - * For each interface in the BD construct an l2_binding - */ + * For each interface in the BD construct an l2_binding + */ for (unsigned int ii = 0; ii < payload.n_sw_ifs; ii++) { std::shared_ptr<interface> itf = interface::find(payload.sw_if_details[ii].sw_if_index); diff --git a/src/vpp-api/vom/bridge_domain_entry.cpp b/src/vpp-api/vom/bridge_domain_entry.cpp index de1c4b7ba1f..9723bde4875 100644 --- a/src/vpp-api/vom/bridge_domain_entry.cpp +++ b/src/vpp-api/vom/bridge_domain_entry.cpp @@ -166,11 +166,21 @@ bridge_domain_entry::event_handler::handle_populate(const client_db::key_t& key) std::shared_ptr<interface> itf = interface::find(payload.sw_if_index); std::shared_ptr<bridge_domain> bd = bridge_domain::find(payload.bd_id); + + if (!bd || !itf) { + VOM_LOG(log_level_t::ERROR) << "bridge-domain-entry dump:" + << " itf:" << payload.sw_if_index + << " bd:" << payload.bd_id; + continue; + } + mac_address_t mac(payload.mac); bridge_domain_entry bd_e(*bd, mac, *itf); - VOM_LOG(log_level_t::DEBUG) << "bd-entry-dump: " << bd->to_string() - << mac.to_string() << itf->to_string(); + VOM_LOG(log_level_t::DEBUG) << "bridge-domain-entry dump:" + << " " << bd->to_string() << " " + << itf->to_string() << " mac:[" + << mac.to_string() << "]"; /* * Write each of the discovered interfaces into the OM, diff --git a/src/vpp-api/vom/dhcp_config_cmds.cpp b/src/vpp-api/vom/dhcp_config_cmds.cpp index 144df986d37..ff24fe2f463 100644 --- a/src/vpp-api/vom/dhcp_config_cmds.cpp +++ b/src/vpp-api/vom/dhcp_config_cmds.cpp @@ -138,14 +138,14 @@ rc_t events_cmd::issue(connection& con) { /* - * Set the call back to handle DHCP complete envets. - */ + * Set the call back to handle DHCP complete envets. + */ m_reg.reset(new reg_t(con.ctx(), std::ref(*this))); /* - * return in-progress so the command stays in the pending list. - */ - return (rc_t::INPROGRESS); + * return in-progress so the command stays in the pending list. + */ + return (rc_t::OK); } void diff --git a/src/vpp-api/vom/hw.cpp b/src/vpp-api/vom/hw.cpp index 4150d5f481f..91faf9d4db0 100644 --- a/src/vpp-api/vom/hw.cpp +++ b/src/vpp-api/vom/hw.cpp @@ -77,20 +77,6 @@ HW::cmd_q::enqueue(std::queue<cmd*>& cmds) } void -HW::cmd_q::dequeue(cmd* c) -{ - c->retire(m_conn); - m_pending.erase(c); -} - -void -HW::cmd_q::dequeue(std::shared_ptr<cmd> c) -{ - c->retire(m_conn); - m_pending.erase(c.get()); -} - -void HW::cmd_q::connect() { if (m_connected) { @@ -144,33 +130,18 @@ HW::cmd_q::write() * ince a async event can be recieved before the command * completes */ - m_pending[c.get()] = c; - rc = c->issue(m_conn); - if (rc_t::INPROGRESS == rc) { + if (rc_t::OK == rc) { /* - * this command completes asynchronously - * leave the command in the pending store + * move to the next */ } else { /* - * the command completed, remove from the pending store + * barf out without issuing the rest */ - m_pending.erase(c.get()); - - if (rc_t::OK == rc) { - /* - * move to the next - */ - } else { - /* - * barf out without issuing the rest - */ - VOM_LOG(log_level_t::ERROR) << "Failed to execute: " - << c->to_string(); - break; - } + VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string(); + break; } } else { /* @@ -233,18 +204,6 @@ HW::enqueue(std::queue<cmd*>& cmds) } void -HW::dequeue(cmd* cmd) -{ - m_cmdQ->dequeue(cmd); -} - -void -HW::dequeue(std::shared_ptr<cmd> cmd) -{ - m_cmdQ->dequeue(cmd); -} - -void HW::connect() { m_cmdQ->connect(); diff --git a/src/vpp-api/vom/hw.hpp b/src/vpp-api/vom/hw.hpp index 7e30b677bff..903aa78fb25 100644 --- a/src/vpp-api/vom/hw.hpp +++ b/src/vpp-api/vom/hw.hpp @@ -215,16 +215,6 @@ public: virtual void enqueue(std::queue<cmd*>& c); /** - * dequeue a command from the Q. - */ - virtual void dequeue(cmd* c); - - /** - * dequeue a command from the Q. - */ - virtual void dequeue(std::shared_ptr<cmd> c); - - /** * Write all the commands to HW */ virtual rc_t write(); @@ -312,16 +302,6 @@ public: static void enqueue(std::queue<cmd*>& c); /** - * dequeue A command for execution - */ - static void dequeue(cmd* f); - - /** - * dequeue A command for execution - */ - static void dequeue(std::shared_ptr<cmd> c); - - /** * Write/Execute all commands hitherto enqueued. */ static rc_t write(); diff --git a/src/vpp-api/vom/interface.cpp b/src/vpp-api/vom/interface.cpp index c7b7e436450..10728ceddc4 100644 --- a/src/vpp-api/vom/interface.cpp +++ b/src/vpp-api/vom/interface.cpp @@ -49,21 +49,6 @@ interface::interface(const std::string& name, { } -interface::interface(const handle_t& handle, - const l2_address_t& l2_address, - const std::string& name, - interface::type_t type, - interface::admin_state_t state) - : m_hdl(handle, rc_t::OK) - , m_name(name) - , m_type(type) - , m_state(state, rc_t::OK) - , m_table_id(route::DEFAULT_TABLE) - , m_l2_address(l2_address) - , m_oper(oper_state_t::DOWN) -{ -} - interface::interface(const std::string& name, interface::type_t itf_type, interface::admin_state_t itf_state, @@ -172,8 +157,10 @@ interface::sweep() new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); } - if (m_stats) - HW::dequeue(m_stats); + if (m_stats) { + HW::enqueue(new interface_cmds::stats_disable_cmd(m_hdl.data())); + m_stats.reset(); + } // If the interface is up, bring it down if (m_state && interface::admin_state_t::UP == m_state.data()) { @@ -364,6 +351,12 @@ interface::set(const l2_address_t& addr) } void +interface::set(const handle_t& hdl) +{ + m_hdl = hdl; +} + +void interface::set(const oper_state_t& state) { m_oper = state; @@ -372,7 +365,7 @@ interface::set(const oper_state_t& state) void interface::enable_stats_i(interface::stat_listener& el) { - m_stats.reset(new interface_cmds::stats_cmd(el, handle_i())); + m_stats.reset(new interface_cmds::stats_enable_cmd(el, handle_i())); HW::enqueue(m_stats); HW::write(); } @@ -442,7 +435,7 @@ interface::event_handler::handle_populate(const client_db::key_t& key) HW::write(); for (auto& itf_record : *cmd) { - std::unique_ptr<interface> itf = + std::shared_ptr<interface> itf = interface_factory::new_interface(itf_record.get_payload()); if (itf && interface::type_t::LOCAL != itf->type()) { diff --git a/src/vpp-api/vom/interface.hpp b/src/vpp-api/vom/interface.hpp index 8cba2fa2c2c..da0db409e62 100644 --- a/src/vpp-api/vom/interface.hpp +++ b/src/vpp-api/vom/interface.hpp @@ -31,7 +31,7 @@ namespace VOM { * Forward declaration of the stats and events command */ namespace interface_cmds { -class stats_cmd; +class stats_enable_cmd; class events_cmd; }; @@ -390,7 +390,8 @@ public: * Virtual function called on the listener when the command has data * ready to process */ - virtual void handle_interface_stat(interface_cmds::stats_cmd* cmd) = 0; + virtual void handle_interface_stat( + interface_cmds::stats_enable_cmd* cmd) = 0; /** * Return the HW::item representing the status @@ -426,13 +427,10 @@ public: protected: /** - * Construct an interface object with a handle and a HW address + * Set the handle of an interface object. Only called by the interface + * factory during the populate */ - interface(const handle_t& handle, - const l2_address_t& l2_address, - const std::string& name, - type_t type, - admin_state_t state); + void set(const handle_t& handle); friend class interface_factory; /** @@ -560,7 +558,7 @@ private: /** * shared pointer to the stats object for this interface. */ - std::shared_ptr<interface_cmds::stats_cmd> m_stats; + std::shared_ptr<interface_cmds::stats_enable_cmd> m_stats; /** * The state of the interface diff --git a/src/vpp-api/vom/interface_cmds.cpp b/src/vpp-api/vom/interface_cmds.cpp index 750ad1f8881..031aaea7288 100644 --- a/src/vpp-api/vom/interface_cmds.cpp +++ b/src/vpp-api/vom/interface_cmds.cpp @@ -366,7 +366,7 @@ events_cmd::issue(connection& con) wait(); - return (rc_t::INPROGRESS); + return (rc_t::OK); } void @@ -401,7 +401,8 @@ events_cmd::to_string() const /** * Interface statistics */ -stats_cmd::stats_cmd(interface::stat_listener& el, const handle_t& handle) +stats_enable_cmd::stats_enable_cmd(interface::stat_listener& el, + const handle_t& handle) : event_cmd(el.status()) , m_listener(el) , m_swifindex(handle) @@ -409,13 +410,13 @@ stats_cmd::stats_cmd(interface::stat_listener& el, const handle_t& handle) } bool -stats_cmd::operator==(const stats_cmd& other) const +stats_enable_cmd::operator==(const stats_enable_cmd& other) const { return (true); } rc_t -stats_cmd::issue(connection& con) +stats_enable_cmd::issue(connection& con) { /* * First set the call back to handle the interface stats @@ -438,11 +439,11 @@ stats_cmd::issue(connection& con) wait(); - return (rc_t::INPROGRESS); + return (rc_t::OK); } void -stats_cmd::retire(connection& con) +stats_enable_cmd::retire(connection& con) { /* * disable interface stats. @@ -461,21 +462,65 @@ stats_cmd::retire(connection& con) } void -stats_cmd::notify() +stats_enable_cmd::notify() { m_listener.handle_interface_stat(this); } std::string -stats_cmd::to_string() const +stats_enable_cmd::to_string() const { - return ("itf-stats"); + std::ostringstream s; + s << "itf-stats-enable itf:" << m_swifindex.to_string(); + return (s.str()); } dump_cmd::dump_cmd() { } +stats_disable_cmd::stats_disable_cmd(const handle_t& handle) + : rpc_cmd(m_res) + , m_swifindex(handle) +{ +} + +bool +stats_disable_cmd::operator==(const stats_disable_cmd& other) const +{ + return (true); +} + +rc_t +stats_disable_cmd::issue(connection& con) +{ + /* + * then send the request to enable them + */ + msg_t req(con.ctx(), 1, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.enable_disable = 0; + payload.pid = getpid(); + payload.num = 1; + + payload.sw_ifs[0] = m_swifindex.value(); + + VAPI_CALL(req.execute()); + + wait(); + + return (rc_t::OK); +} + +std::string +stats_disable_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-stats-disable itf:" << m_swifindex.to_string(); + return (s.str()); +} + bool dump_cmd::operator==(const dump_cmd& other) const { diff --git a/src/vpp-api/vom/interface_cmds.hpp b/src/vpp-api/vom/interface_cmds.hpp index c86df92a4aa..f21a7f3b21c 100644 --- a/src/vpp-api/vom/interface_cmds.hpp +++ b/src/vpp-api/vom/interface_cmds.hpp @@ -370,14 +370,15 @@ private: /** * A command class represents our desire to recieve interface stats */ -class stats_cmd : public event_cmd<vapi::Want_per_interface_combined_stats, - vapi::Vnet_per_interface_combined_counters> +class stats_enable_cmd + : public event_cmd<vapi::Want_per_interface_combined_stats, + vapi::Vnet_per_interface_combined_counters> { public: /** * Constructor taking the listner to notify */ - stats_cmd(interface::stat_listener& el, const handle_t& handle); + stats_enable_cmd(interface::stat_listener& el, const handle_t& handle); /** * Issue the command to VPP/HW @@ -397,7 +398,7 @@ public: /** * Comparison operator - only used for UT */ - bool operator==(const stats_cmd& i) const; + bool operator==(const stats_enable_cmd& i) const; /** * Called when it's time to poke the listeners @@ -410,6 +411,46 @@ private: */ interface::stat_listener& m_listener; + /** + * The interface on which we are enabling states + */ + handle_t m_swifindex; +}; + +/** + * A command class represents our desire to recieve interface stats + */ +class stats_disable_cmd + : public rpc_cmd<HW::item<bool>, + rc_t, + vapi::Want_per_interface_combined_stats> +{ +public: + /** + * Constructor taking the listner to notify + */ + stats_disable_cmd(const handle_t& handle); + + /** + * 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 stats_disable_cmd& i) const; + +private: + HW::item<bool> m_res; + /** + * The interface on which we are disabling states + */ handle_t m_swifindex; }; diff --git a/src/vpp-api/vom/interface_factory.cpp b/src/vpp-api/vom/interface_factory.cpp index cd2d373f0bf..b8815ed7ac9 100644 --- a/src/vpp-api/vom/interface_factory.cpp +++ b/src/vpp-api/vom/interface_factory.cpp @@ -20,14 +20,14 @@ #include "vom/tap_interface.hpp" namespace VOM { -std::unique_ptr<interface> +std::shared_ptr<interface> interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) { - std::unique_ptr<interface> up_itf; + std::shared_ptr<interface> sp; /** - * Determine the interface type from the name and VLAN attributes - */ + * Determine the interface type from the name and VLAN attributes + */ std::string name = reinterpret_cast<const char*>(vd.interface_name); interface::type_t type = interface::type_t::from_string(name); interface::admin_state_t state = @@ -37,48 +37,54 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) if (interface::type_t::AFPACKET == type) { /* - * need to strip VPP's "host-" prefix from the interface name - */ + * need to strip VPP's "host-" prefix from the interface name + */ name = name.substr(5); } /** - * if the tag is set, then we wrote that to specify a name to make - * the interface type more specific - */ + * if the tag is set, then we wrote that to specify a name to make + * the interface type more specific + */ if (vd.tag[0] != 0) { name = std::string(reinterpret_cast<const char*>(vd.tag)); type = interface::type_t::from_string(name); } /* - * pull out the other special cases - */ + * pull out the other special cases + */ if (interface::type_t::TAP == type) { /* - * TAP interface - */ - up_itf.reset(new tap_interface(hdl, name, state, route::prefix_t())); + * TAP interface + */ + sp = tap_interface(name, state, route::prefix_t()).singular(); } else if ((name.find(".") != std::string::npos) && (0 != vd.sub_id)) { /* - * Sub-interface - * split the name into the parent and VLAN - */ + * Sub-interface + * split the name into the parent and VLAN + */ std::vector<std::string> parts; boost::split(parts, name, boost::is_any_of(".")); interface parent(parts[0], type, state); - up_itf.reset(new sub_interface(hdl, parent, state, vd.sub_id)); + sp = sub_interface(parent, state, vd.sub_id).singular(); } else if (interface::type_t::VXLAN == type) { /* - * there's not enough inforation in a SW interface record to - * construct - * a VXLAN tunnel. so skip it. - */ + * there's not enough information in a SW interface record to + * construct a VXLAN tunnel. so skip it. + */ } else { - up_itf.reset(new interface(hdl, l2_address, name, type, state)); + sp = interface(name, type, state).singular(); + sp->set(l2_address); } - return (up_itf); + /* + * set the handle on the intterface - N.B. this is the sigluar instance + * not a stack local. + */ + sp->set(hdl); + + return (sp); } }; // namespace VOM diff --git a/src/vpp-api/vom/interface_factory.hpp b/src/vpp-api/vom/interface_factory.hpp index 47faecc5934..e1cbb38fd83 100644 --- a/src/vpp-api/vom/interface_factory.hpp +++ b/src/vpp-api/vom/interface_factory.hpp @@ -30,7 +30,7 @@ public: /** * Factory method to construct a new interface from the VPP record */ - static std::unique_ptr<interface> new_interface( + static std::shared_ptr<interface> new_interface( const vapi_payload_sw_interface_details& vd); }; }; diff --git a/src/vpp-api/vom/logger.cpp b/src/vpp-api/vom/logger.cpp index 07e27499b59..80f2d92c603 100644 --- a/src/vpp-api/vom/logger.cpp +++ b/src/vpp-api/vom/logger.cpp @@ -43,7 +43,7 @@ logger() log_t::log_t() : m_level(log_level_t::ERROR) - , m_o_stream(&std::cout) + , m_handler(new cout_handler()) { } @@ -54,45 +54,113 @@ log_t::set(const log_level_t& level) } void -log_t::set(const std::string& ofile) +log_t::set(handler* h) { - m_file_stream.open(ofile); - m_o_stream = &m_file_stream; + m_handler = h; +} + +void +log_t::write(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) +{ + m_handler->handle_message(file, line, function, level, message); +} + +/** + * The configured level + */ +const log_level_t& +log_t::level() const +{ + return (m_level); +} + +static std::string +get_filename(const std::string& file) +{ + std::vector<std::string> dirs; + boost::split(dirs, file, boost::is_any_of("/")); + + return dirs.back(); +} + +log_t::entry::entry(const char* file, + const char* function, + int line, + const log_level_t& level) + : m_file(get_filename(file)) + , m_function(function) + , m_level(level) + , m_line(line) +{ +} + +log_t::entry::~entry() +{ + logger().write(m_file, m_line, m_function, m_level, m_stream.str()); +} + +std::stringstream& +log_t::entry::stream() +{ + return (m_stream); } -std::ostream& -log_t::stream(const char* file, int line, const log_level_t& level) +static std::string +get_timestamp() { auto end = std::chrono::system_clock::now(); auto end_time = std::chrono::system_clock::to_time_t(end); /* - * put-time is not support in gcc in 4.8 - * so we play this dance with ctime - */ + * put-time is not support in gcc in 4.8 + * so we play this dance with ctime + */ std::string display = std::ctime(&end_time); display.pop_back(); - std::vector<std::string> dirs; - boost::split(dirs, file, boost::is_any_of("/")); + return (display); +} - *m_o_stream << std::endl - << display << " [" << level.to_string() << "]" - << " " << dirs.back() << ":" << line << ": "; +file_handler::file_handler(const std::string& ofile) +{ + m_file_stream.open(ofile); +} - return (*m_o_stream); +file_handler::~file_handler() +{ + m_file_stream.close(); } -/** - * The configured level - */ -const log_level_t& -log_t::level() const +void +file_handler::handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) { - return (m_level); + m_file_stream << get_timestamp(); + m_file_stream << " [" << level.to_string() << "]" << file << ":" << line + << " " << function << "() " << message << std::endl; } + +void +cout_handler::handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) +{ + std::cout << get_timestamp(); + std::cout << " [" << level.to_string() << "]" << file << ":" << line << " " + << function << "() " << message << std::endl; } +}; // namespace VOM + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp-api/vom/logger.hpp b/src/vpp-api/vom/logger.hpp index 941623e6679..6d2e3dd82f6 100644 --- a/src/vpp-api/vom/logger.hpp +++ b/src/vpp-api/vom/logger.hpp @@ -18,6 +18,7 @@ #include <fstream> #include <iostream> +#include <sstream> #include "vom/enum_base.hpp" @@ -35,6 +36,11 @@ private: * Private constructor taking the value and the string name */ log_level_t(int v, const std::string& s); + + /* + * not allowed to construct + */ + log_level_t() = delete; }; /** @@ -45,14 +51,36 @@ class log_t { public: /** - * Construct a logger + * */ - log_t(); + class handler + { + public: + /** + * Default Constructor + */ + handler() = default; + + /** + * Default Destructor + */ + virtual ~handler() = default; + + /** + * Handle a log message + */ + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) = 0; + }; /** - * Return the stream + * Construct a logger */ - std::ostream& stream(const char* file, int line, const log_level_t& level); + log_t(handler* h); + log_t(); /** * The configured level @@ -67,23 +95,82 @@ public: /** * set a file to receive the logging data */ - void set(const std::string& ofile); + void set(handler* h); + + /** + * An entry in the log + */ + class entry + { + public: + entry(const char* file, + const char* function, + int line, + const log_level_t& level); + ~entry(); + + std::stringstream& stream(); + + private: + const std::string m_file; + const std::string m_function; + const log_level_t m_level; + const int m_line; + + std::stringstream m_stream; + }; + /** + * Register a log handler to receive the log output + */ + void register_handler(handler& h); private: + void write(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); + /** * the configured logging level */ log_level_t m_level; /** - * Opened file for debugging + * Pointer to a registered handler. Null if no handler registerd */ - std::ofstream m_file_stream; + handler* m_handler; +}; +class file_handler : public log_t::handler +{ +public: + file_handler(const std::string& ofile); + ~file_handler(); + + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); + +private: /** - * Pointer to the output stream + * Opened file for debugging */ - std::ostream* m_o_stream; + std::ofstream m_file_stream; +}; + +class cout_handler : public log_t::handler +{ +public: + cout_handler() = default; + ~cout_handler() = default; + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); }; /** @@ -93,7 +180,7 @@ log_t& logger(); #define VOM_LOG(lvl) \ if (lvl >= logger().level()) \ - logger().stream(__FILE__, __LINE__, lvl) + log_t::entry(__FILE__, __FUNCTION__, __LINE__, lvl).stream() }; /* diff --git a/src/vpp-api/vom/rpc_cmd.hpp b/src/vpp-api/vom/rpc_cmd.hpp index ae3c6753d24..bd78978a3cf 100644 --- a/src/vpp-api/vom/rpc_cmd.hpp +++ b/src/vpp-api/vom/rpc_cmd.hpp @@ -79,7 +79,7 @@ public: * we reset the promise after setting the value to reuse it * when we run the retire command from the same cmd object */ - m_promise = std::promise<DATA>(); + // m_promise = std::promise<DATA>(); } /** diff --git a/src/vpp-api/vom/sub_interface.cpp b/src/vpp-api/vom/sub_interface.cpp index 01f4a54a517..94baa3d2ecc 100644 --- a/src/vpp-api/vom/sub_interface.cpp +++ b/src/vpp-api/vom/sub_interface.cpp @@ -29,20 +29,6 @@ sub_interface::sub_interface(const interface& parent, { } -sub_interface::sub_interface(const handle_t& handle, - const interface& parent, - admin_state_t state, - vlan_id_t vlan) - : interface(handle, - l2_address_t::ZERO, - mk_name(parent, vlan), - parent.type(), - state) - , m_parent(parent.singular()) - , m_vlan(vlan) -{ -} - sub_interface::~sub_interface() { sweep(); diff --git a/src/vpp-api/vom/sub_interface.hpp b/src/vpp-api/vom/sub_interface.hpp index 1c65782e980..41786e42ef3 100644 --- a/src/vpp-api/vom/sub_interface.hpp +++ b/src/vpp-api/vom/sub_interface.hpp @@ -60,20 +60,6 @@ public: private: /** - * Construct with handle - */ - sub_interface(const handle_t& handle, - const interface& parent, - admin_state_t state, - vlan_id_t vlan); - friend class interface_factory; - - /** - * The interface class can construct interfaces with handles - */ - friend class interface; - - /** * Return the matching 'instance' of the sub-interface * over-ride from the base class */ diff --git a/src/vpp-api/vom/tap_interface.cpp b/src/vpp-api/vom/tap_interface.cpp index 4f88d3b8fad..1f85ca11507 100644 --- a/src/vpp-api/vom/tap_interface.cpp +++ b/src/vpp-api/vom/tap_interface.cpp @@ -43,16 +43,6 @@ tap_interface::tap_interface(const std::string& name, { } -tap_interface::tap_interface(const handle_t& hdl, - const std::string& name, - admin_state_t state, - route::prefix_t prefix) - : interface(hdl, l2_address_t::ZERO, name, type_t::TAP, state) - , m_prefix(prefix) - , m_l2_address(l2_address_t::ZERO) -{ -} - tap_interface::~tap_interface() { sweep(); diff --git a/src/vpp-api/vom/tap_interface.hpp b/src/vpp-api/vom/tap_interface.hpp index 08dba501572..d9df9a92a8d 100644 --- a/src/vpp-api/vom/tap_interface.hpp +++ b/src/vpp-api/vom/tap_interface.hpp @@ -75,16 +75,6 @@ private: static event_handler m_evh; /** - * Construct with a handle - */ - tap_interface(const handle_t& hdl, - const std::string& name, - admin_state_t state, - route::prefix_t prefix); - - friend class interface_factory; - - /** * Ip Prefix */ route::prefix_t m_prefix; diff --git a/src/vpp-api/vom/tap_interface_cmds.cpp b/src/vpp-api/vom/tap_interface_cmds.cpp index 799b9afd58a..b0885607742 100644 --- a/src/vpp-api/vom/tap_interface_cmds.cpp +++ b/src/vpp-api/vom/tap_interface_cmds.cpp @@ -112,7 +112,7 @@ dump_cmd::issue(connection& con) wait(); - return rc_t::INPROGRESS; + return rc_t::OK; } std::string diff --git a/src/vpp-api/vom/types.cpp b/src/vpp-api/vom/types.cpp index c5325d287a5..cdced0ffb72 100644 --- a/src/vpp-api/vom/types.cpp +++ b/src/vpp-api/vom/types.cpp @@ -49,9 +49,8 @@ rc_t::from_vpp_retval(int32_t rv) const rc_t rc_t::UNSET(0, "un-set"); const rc_t rc_t::NOOP(1, "no-op"); const rc_t rc_t::OK(2, "ok"); -const rc_t rc_t::INPROGRESS(3, "in-progess"); -const rc_t rc_t::INVALID(4, "invalid"); -const rc_t rc_t::TIMEOUT(5, "timeout"); +const rc_t rc_t::INVALID(3, "invalid"); +const rc_t rc_t::TIMEOUT(4, "timeout"); const handle_t handle_t::INVALID(~0); diff --git a/src/vpp-api/vom/types.hpp b/src/vpp-api/vom/types.hpp index b57867f164e..839b29a9702 100644 --- a/src/vpp-api/vom/types.hpp +++ b/src/vpp-api/vom/types.hpp @@ -106,12 +106,6 @@ struct rc_t : public enum_base<rc_t> const static rc_t OK; /** - * HW write is in progress. Also used for the 'want' events - * that never complete - */ - const static rc_t INPROGRESS; - - /** * HW write reported invalid input */ const static rc_t INVALID; diff --git a/src/vpp-api/vom/vxlan_tunnel.cpp b/src/vpp-api/vom/vxlan_tunnel.cpp index 89615893939..f6f3cf586e1 100644 --- a/src/vpp-api/vom/vxlan_tunnel.cpp +++ b/src/vpp-api/vom/vxlan_tunnel.cpp @@ -106,19 +106,6 @@ vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, { } -vxlan_tunnel::vxlan_tunnel(const handle_t& hdl, - const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni) - : interface(hdl, - l2_address_t::ZERO, - mk_name(src, dst, vni), - interface::type_t::VXLAN, - interface::admin_state_t::UP) - , m_tep(src, dst, vni) -{ -} - vxlan_tunnel::vxlan_tunnel(const vxlan_tunnel& o) : interface(o) , m_tep(o.m_tep) @@ -233,11 +220,13 @@ vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key) boost::asio::ip::address dst = from_bytes(payload.is_ipv6, payload.dst_address); - vxlan_tunnel vt(hdl, src, dst, payload.vni); + std::shared_ptr<vxlan_tunnel> vt = + vxlan_tunnel(src, dst, payload.vni).singular(); + vt->set(hdl); - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string(); + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); - OM::commit(key, vt); + OM::commit(key, *vt); } } diff --git a/test/ext/vom_test.cpp b/test/ext/vom_test.cpp index c9ae255a793..91769155040 100644 --- a/test/ext/vom_test.cpp +++ b/test/ext/vom_test.cpp @@ -80,7 +80,7 @@ public: class MockListener : public interface::event_listener, public interface::stat_listener { - void handle_interface_stat(interface_cmds::stats_cmd *cmd) + void handle_interface_stat(interface_cmds::stats_enable_cmd *cmd) { } void handle_interface_event(interface_cmds::events_cmd *cmd) @@ -1463,8 +1463,6 @@ BOOST_AUTO_TEST_CASE(test_interface_events) { HW::enqueue(itf); HW::write(); - - HW::dequeue(itf); } BOOST_AUTO_TEST_CASE(test_interface_route_domain_change) { |