aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2017-11-28 22:29:13 -0800
committerNeale Ranns <nranns@cisco.com>2017-11-29 07:42:52 +0000
commita2ee029d0772e894911c84fb8a0cab5f253e145b (patch)
tree167d07ee3b3a482ef494f420ceef13a9657d4274
parente80ae9ea8ed04c82c151a548916926b5dbfe8ecb (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.cpp12
-rw-r--r--src/vpp-api/vom/bridge_domain_entry.cpp14
-rw-r--r--src/vpp-api/vom/dhcp_config_cmds.cpp10
-rw-r--r--src/vpp-api/vom/hw.cpp51
-rw-r--r--src/vpp-api/vom/hw.hpp20
-rw-r--r--src/vpp-api/vom/interface.cpp31
-rw-r--r--src/vpp-api/vom/interface.hpp16
-rw-r--r--src/vpp-api/vom/interface_cmds.cpp63
-rw-r--r--src/vpp-api/vom/interface_cmds.hpp49
-rw-r--r--src/vpp-api/vom/interface_factory.cpp54
-rw-r--r--src/vpp-api/vom/interface_factory.hpp2
-rw-r--r--src/vpp-api/vom/logger.cpp110
-rw-r--r--src/vpp-api/vom/logger.hpp107
-rw-r--r--src/vpp-api/vom/rpc_cmd.hpp2
-rw-r--r--src/vpp-api/vom/sub_interface.cpp14
-rw-r--r--src/vpp-api/vom/sub_interface.hpp14
-rw-r--r--src/vpp-api/vom/tap_interface.cpp10
-rw-r--r--src/vpp-api/vom/tap_interface.hpp10
-rw-r--r--src/vpp-api/vom/tap_interface_cmds.cpp2
-rw-r--r--src/vpp-api/vom/types.cpp5
-rw-r--r--src/vpp-api/vom/types.hpp6
-rw-r--r--src/vpp-api/vom/vxlan_tunnel.cpp21
-rw-r--r--test/ext/vom_test.cpp4
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) {