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 =
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 << "]";
/**
* 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
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);
};
/*
/**
* 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;
/**
* 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
/**
* 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;
};
};
{
}
+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()
{
}
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));
}
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
*/
*/
~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::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
/**
* 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
/**
* 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;
};
};
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
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)
{
}
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
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>
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);
* 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
*/
~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'
*/
/**
* 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
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
std::ostream& operator<<(std::ostream& os,
const bridge_domain_arp_entry::key_t& key);
-};
+}; // namespace
/*
* fd.io coding-style-patch-verification: ON
{
}
+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
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>
/**
* 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
*/
~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'
*/
/**
* 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
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
#include "vom/types.hpp"
-#include <vapi/vapi.hpp>
-
namespace VOM {
/**
* Forward declaration of the connection class
* 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")
{
}
void
connection::disconnect()
{
- m_vapi_conn.disconnect();
+ m_vapi_conn->disconnect();
}
void
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);
}
}
#ifndef __VOM_CONNECTION_H__
#define __VOM_CONNECTION_H__
+#include <memory>
#include <string>
-#include <vapi/vapi.hpp>
+/**
+ * Forward declarations
+ */
+namespace vapi {
+class Connection;
+};
namespace VOM {
/**
/**
* The VAPI connection context
*/
- vapi::Connection m_vapi_conn;
+ std::unique_ptr<vapi::Connection> m_vapi_conn;
/**
* The name of this application
/**
* 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;
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()
{
return (m_db.find_or_add(temp.m_itf->key(), 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
{
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();
+ /**
+ * 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
*/
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:
/**
* 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
/**
* 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;
};
};
#include <deque>
#include <map>
+#include <queue>
#include <sstream>
#include <string>
#include <thread>
+#include "vom/cmd.hpp"
#include "vom/connection.hpp"
#include "vom/types.hpp"
/**
* Blocking Connect to VPP - call once at bootup
*/
- void connect();
+ virtual void connect();
/**
* Disable the passing of commands to VPP. Whilst disabled all
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);
/**
* 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
{
}
+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)
{
{
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();
return (m_name);
}
-const interface::key_type&
+const interface::key_t&
interface::key() const
{
return (name());
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>
}
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>
}
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;
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();
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()));
{
m_db.dump(os);
}
-}
+
+} // namespace VOM
+
/*
* fd.io coding-style-patch-verification: ON
*
/**
* The key for interface's key
*/
- typedef std::string key_type;
+ typedef std::string key_t;
/**
* The iterator type
/**
* Return the interface type
*/
- const key_type& key() const;
+ const key_t& key() const;
/**
* Return the L2 Address
*/
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
*/
};
/**
- * 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
/**
* 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
/**
* 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
#include "vom/ra_prefix.hpp"
#include "vom/rpc_cmd.hpp"
#include "vom/singular_db.hpp"
-#include "vom/sub_interface.hpp"
namespace VOM {
/**
/**
* 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
/**
* 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;
}
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 << "]";
/**
* 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
/**
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
* 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);
};
/*
*/
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");
/**
* 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
/**
* 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;
{
}
+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()
{
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());
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>
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;
*/
~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
*/
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
/**
* 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
/**
* 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;
};
};
#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;
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
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());
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>
}
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 << "]";
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();
/**
- * 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();
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
/**
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
* 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);
};
/*
/**
* 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;
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()
{
return (m_db.find_or_add(temp.m_itf->key(), 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
{
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
*/
* 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
*/
*/
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
/**
* 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
/**
* 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;
};
};
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()
{
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>
#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 {
/**
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();
+ /**
+ * 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
*/
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:
/**
/**
* 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
* 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;
};
};
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:
* 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
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)
{
}
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
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>
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);
}
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));
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);
}
}
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
*/
~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);
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);
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
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();) {
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();
OM::replay()
{
/*
- * the listeners are sorted in dependency order
- */
+ * the listeners are sorted in dependency order
+ */
for (listener* l : *m_listeners) {
l->handle_replay();
}
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);
}
#ifndef __VOM_OM_H__
#define __VOM_OM_H__
+#include <algorithm>
#include <memory>
#include <set>
{
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
{
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())
{
}
+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
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>
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) {
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);
}
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);
}
}
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
*/
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 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::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
{
}
+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
{
*/
~route_domain();
+ /**
+ * comparison operator - for UT
+ */
+ bool operator==(const route_domain& r) const;
+
/**
* Return the matching 'singular instance'
*/
/**
* 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;
};
};
{
}
+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)
{
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
*
*/
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
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());
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);
}
}
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
*
#include <iostream>
#include <sstream>
+#include <boost/algorithm/string.hpp>
+
#include "vom/types.hpp"
namespace VOM {
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 });
s.fill('0');
s << std::hex;
- s << "mac:[";
for (auto byte : bytes) {
if (first)
first = false;
s << ":";
s << std::setw(2) << static_cast<unsigned int>(byte);
}
- s << "]";
return (s.str());
}
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
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());
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
*
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));
*/
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));