aboutsummaryrefslogtreecommitdiffstats
path: root/extras/vom/vom
diff options
context:
space:
mode:
Diffstat (limited to 'extras/vom/vom')
-rw-r--r--extras/vom/vom/api_types.cpp72
-rw-r--r--extras/vom/vom/api_types.hpp15
-rw-r--r--extras/vom/vom/interface.cpp4
-rw-r--r--extras/vom/vom/mroute_cmds.cpp69
-rw-r--r--extras/vom/vom/mroute_cmds.hpp42
-rw-r--r--extras/vom/vom/neighbour.hpp2
-rw-r--r--extras/vom/vom/neighbour_cmds.cpp8
-rw-r--r--extras/vom/vom/neighbour_cmds.hpp11
-rw-r--r--extras/vom/vom/prefix.cpp21
-rw-r--r--extras/vom/vom/prefix.hpp13
-rw-r--r--extras/vom/vom/route.cpp281
-rw-r--r--extras/vom/vom/route.hpp4
-rw-r--r--extras/vom/vom/route_api_types.cpp164
-rw-r--r--extras/vom/vom/route_api_types.hpp8
-rw-r--r--extras/vom/vom/route_cmds.cpp104
-rw-r--r--extras/vom/vom/route_cmds.hpp63
-rw-r--r--extras/vom/vom/route_domain.cpp32
-rw-r--r--extras/vom/vom/route_domain.hpp9
-rw-r--r--extras/vom/vom/route_domain_cmds.cpp37
-rw-r--r--extras/vom/vom/route_domain_cmds.hpp34
-rw-r--r--extras/vom/vom/srpc_cmd.hpp74
21 files changed, 593 insertions, 474 deletions
diff --git a/extras/vom/vom/api_types.cpp b/extras/vom/vom/api_types.cpp
index ea75d7fd8ee..721034fc810 100644
--- a/extras/vom/vom/api_types.cpp
+++ b/extras/vom/vom/api_types.cpp
@@ -45,6 +45,11 @@ from_api(vapi_enum_ip_neighbor_flags f)
return out;
}
+invalid_decode::invalid_decode(const std::string reason)
+ : reason(reason)
+{
+}
+
void
to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v)
{
@@ -82,6 +87,16 @@ to_api(const ip_address_t& a,
}
}
+void
+to_api(const ip_address_t& a, vapi_union_address_union& u)
+{
+ if (a.is_v4()) {
+ memcpy(u.ip4, a.to_v4().to_bytes().data(), 4);
+ } else {
+ memcpy(u.ip6, a.to_v6().to_bytes().data(), 16);
+ }
+}
+
boost::asio::ip::address_v6
from_api(const vapi_type_ip6_address& v)
{
@@ -123,6 +138,26 @@ from_api(const vapi_type_address& v)
}
ip_address_t
+from_api(const vapi_union_address_union& u, vapi_enum_fib_path_nh_proto proto)
+{
+ boost::asio::ip::address addr;
+
+ if (FIB_API_PATH_NH_PROTO_IP6 == proto) {
+ std::array<uint8_t, 16> a;
+ std::copy(u.ip6, u.ip6 + 16, std::begin(a));
+ boost::asio::ip::address_v6 v6(a);
+ addr = v6;
+ } else if (FIB_API_PATH_NH_PROTO_IP4 == proto) {
+ std::array<uint8_t, 4> a;
+ std::copy(u.ip6, u.ip6 + 4, std::begin(a));
+ boost::asio::ip::address_v4 v4(a);
+ addr = v4;
+ }
+
+ return addr;
+}
+
+ip_address_t
from_api(const vapi_union_address_union& u, vapi_enum_address_family af)
{
boost::asio::ip::address addr;
@@ -187,7 +222,42 @@ to_api(const route::mprefix_t& p)
v.af = af;
return v;
}
-};
+
+vapi_enum_fib_path_nh_proto
+to_api(const nh_proto_t& p)
+{
+ if (p == nh_proto_t::IPV4) {
+ return FIB_API_PATH_NH_PROTO_IP4;
+ } else if (p == nh_proto_t::IPV6) {
+ return FIB_API_PATH_NH_PROTO_IP6;
+ } else if (p == nh_proto_t::ETHERNET) {
+ return FIB_API_PATH_NH_PROTO_ETHERNET;
+ } else if (p == nh_proto_t::MPLS) {
+ return FIB_API_PATH_NH_PROTO_MPLS;
+ }
+
+ return FIB_API_PATH_NH_PROTO_IP4;
+}
+const nh_proto_t&
+from_api(vapi_enum_fib_path_nh_proto p)
+{
+ switch (p) {
+ case FIB_API_PATH_NH_PROTO_IP4:
+ return nh_proto_t::IPV4;
+ case FIB_API_PATH_NH_PROTO_IP6:
+ return nh_proto_t::IPV6;
+ case FIB_API_PATH_NH_PROTO_ETHERNET:
+ return nh_proto_t::ETHERNET;
+ case FIB_API_PATH_NH_PROTO_MPLS:
+ return nh_proto_t::MPLS;
+ case FIB_API_PATH_NH_PROTO_BIER:
+ break;
+ }
+
+ return nh_proto_t::IPV4;
+}
+
+}; // VOM
/*
* fd.io coding-style-patch-verification: ON
diff --git a/extras/vom/vom/api_types.hpp b/extras/vom/vom/api_types.hpp
index 789bbb19401..b026ba38db2 100644
--- a/extras/vom/vom/api_types.hpp
+++ b/extras/vom/vom/api_types.hpp
@@ -22,6 +22,12 @@
namespace VOM {
+struct invalid_decode
+{
+ invalid_decode(const std::string reason);
+ const std::string reason;
+};
+
typedef boost::asio::ip::address ip_address_t;
vapi_enum_ip_neighbor_flags to_api(const neighbour::flags_t& f);
@@ -33,12 +39,15 @@ void to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v);
void to_api(const boost::asio::ip::address& a,
vapi_union_address_union& u,
vapi_enum_address_family& af);
+void to_api(const boost::asio::ip::address& a, vapi_union_address_union& u);
boost::asio::ip::address_v4 from_api(const vapi_type_ip4_address& v);
boost::asio::ip::address_v6 from_api(const vapi_type_ip6_address& v);
ip_address_t from_api(const vapi_type_address& v);
ip_address_t from_api(const vapi_union_address_union& u,
vapi_enum_address_family af);
+ip_address_t from_api(const vapi_union_address_union& u,
+ vapi_enum_fib_path_nh_proto proto);
void to_api(const mac_address_t& a, vapi_type_mac_address& m);
@@ -49,7 +58,11 @@ route::mprefix_t from_api(const vapi_type_mprefix&);
vapi_type_prefix to_api(const route::prefix_t&);
vapi_type_mprefix to_api(const route::mprefix_t&);
-};
+
+vapi_enum_fib_path_nh_proto to_api(const nh_proto_t&);
+const nh_proto_t& from_api(vapi_enum_fib_path_nh_proto);
+
+}; // VOM
/*
* fd.io coding-style-patch-verification: ON
diff --git a/extras/vom/vom/interface.cpp b/extras/vom/vom/interface.cpp
index 40f960730d7..1e27d42c7f4 100644
--- a/extras/vom/vom/interface.cpp
+++ b/extras/vom/vom/interface.cpp
@@ -14,6 +14,7 @@
*/
#include "vom/interface.hpp"
+#include "vom/api_types.hpp"
#include "vom/bond_group_binding.hpp"
#include "vom/bond_group_binding_cmds.hpp"
#include "vom/bond_interface_cmds.hpp"
@@ -666,8 +667,7 @@ interface::event_handler::handle_populate(const client_db::key_t& key)
for (auto& l3_record : *dcmd) {
auto& payload = l3_record.get_payload();
- const route::prefix_t pfx(payload.is_ipv6, payload.ip,
- payload.prefix_length);
+ const route::prefix_t pfx = from_api(payload.prefix);
VOM_LOG(log_level_t::DEBUG) << "dump: " << pfx.to_string();
diff --git a/extras/vom/vom/mroute_cmds.cpp b/extras/vom/vom/mroute_cmds.cpp
index 232d786abeb..2f4dd6e1a86 100644
--- a/extras/vom/vom/mroute_cmds.cpp
+++ b/extras/vom/vom/mroute_cmds.cpp
@@ -45,18 +45,17 @@ update_cmd::operator==(const update_cmd& other) const
rc_t
update_cmd::issue(connection& con)
{
- msg_t req(con.ctx(), std::ref(*this));
+ msg_t req(con.ctx(), 1, std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
payload.is_add = 1;
- m_mprefix.to_vpp(&payload.is_ipv6, payload.src_address, payload.grp_address,
- &payload.grp_address_length);
+ payload.route.table_id = m_id;
+ payload.route.prefix = to_api(m_mprefix);
- to_vpp(m_path, payload);
- payload.itf_flags = m_flags.value();
+ to_api(m_path, payload.route.paths[0].path);
+ payload.route.paths[0].itf_flags = to_api(m_flags);
VAPI_CALL(req.execute());
@@ -96,17 +95,16 @@ delete_cmd::operator==(const delete_cmd& other) const
rc_t
delete_cmd::issue(connection& con)
{
- msg_t req(con.ctx(), std::ref(*this));
+ msg_t req(con.ctx(), 1, std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
- payload.is_add = 0;
+ payload.is_add = 1;
- m_mprefix.to_vpp(&payload.is_ipv6, payload.grp_address, payload.src_address,
- &payload.grp_address_length);
+ payload.route.table_id = m_id;
+ payload.route.prefix = to_api(m_mprefix);
- to_vpp(m_path, payload);
- payload.itf_flags = m_flags.value();
+ to_api(m_path, payload.route.paths[0].path);
+ payload.route.paths[0].itf_flags = to_api(m_flags);
VAPI_CALL(req.execute());
@@ -126,48 +124,27 @@ delete_cmd::to_string() const
return (s.str());
}
-dump_v4_cmd::dump_v4_cmd()
+dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto)
+ : m_id(id)
+ , m_proto(proto)
{
}
bool
-dump_v4_cmd::operator==(const dump_v4_cmd& other) const
+dump_cmd::operator==(const dump_cmd& other) const
{
return (true);
}
rc_t
-dump_v4_cmd::issue(connection& con)
+dump_cmd::issue(connection& con)
{
m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
- VAPI_CALL(m_dump->execute());
-
- wait();
-
- return rc_t::OK;
-}
-
-std::string
-dump_v4_cmd::to_string() const
-{
- return ("ip-mroute-v4-dump");
-}
-
-dump_v6_cmd::dump_v6_cmd()
-{
-}
-
-bool
-dump_v6_cmd::operator==(const dump_v6_cmd& other) const
-{
- return (true);
-}
+ auto& payload = m_dump->get_request().get_payload();
-rc_t
-dump_v6_cmd::issue(connection& con)
-{
- m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+ payload.table.table_id = m_id;
+ payload.table.is_ip6 = m_proto.is_ipv6();
VAPI_CALL(m_dump->execute());
@@ -177,10 +154,14 @@ dump_v6_cmd::issue(connection& con)
}
std::string
-dump_v6_cmd::to_string() const
+dump_cmd::to_string() const
{
- return ("ip-mroute-v6-dump");
+ std::ostringstream s;
+ s << "ip-mroute-dump: id:" << m_id << " proto:" << m_proto.to_string();
+
+ return (s.str());
}
+
} // namespace ip_mroute_cmds
} // namespace mroute
} // namespace vom
diff --git a/extras/vom/vom/mroute_cmds.hpp b/extras/vom/vom/mroute_cmds.hpp
index b8f18f6b45b..3392d4a3b2b 100644
--- a/extras/vom/vom/mroute_cmds.hpp
+++ b/extras/vom/vom/mroute_cmds.hpp
@@ -103,14 +103,13 @@ private:
/**
* A cmd class that Dumps ipv4 fib
*/
-class dump_v4_cmd : public VOM::dump_cmd<vapi::Ip_mfib_dump>
+class dump_cmd : public VOM::dump_cmd<vapi::Ip_mroute_dump>
{
public:
/**
* Constructor
*/
- dump_v4_cmd();
- dump_v4_cmd(const dump_cmd& d);
+ dump_cmd(route::table_id_t id, const l3_proto_t& proto);
/**
* Issue the command to VPP/HW
@@ -124,46 +123,15 @@ public:
/**
* Comparison operator - only used for UT
*/
- bool operator==(const dump_v4_cmd& i) const;
-
-private:
- /**
- * HW reutrn code
- */
- HW::item<bool> item;
-};
-
-/**
- * A cmd class that Dumps ipv6 fib
- */
-class dump_v6_cmd : public VOM::dump_cmd<vapi::Ip6_mfib_dump>
-{
-public:
- /**
- * Constructor
- */
- dump_v6_cmd();
- dump_v6_cmd(const dump_cmd& d);
-
- /**
- * 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 dump_v6_cmd& i) const;
+ bool operator==(const dump_cmd& i) const;
private:
/**
* HW reutrn code
*/
HW::item<bool> item;
+ route::table_id_t m_id;
+ const l3_proto_t& m_proto;
};
}; // namespace ip_mroute_cmds
diff --git a/extras/vom/vom/neighbour.hpp b/extras/vom/vom/neighbour.hpp
index 4e074bf7f45..5b1f9c12847 100644
--- a/extras/vom/vom/neighbour.hpp
+++ b/extras/vom/vom/neighbour.hpp
@@ -181,7 +181,7 @@ private:
/**
* HW configuration for the result of creating the bridge_domain
*/
- HW::item<bool> m_hw;
+ HW::item<handle_t> m_hw;
/**
* The bridge_domain domain the bridge_domain is in.
diff --git a/extras/vom/vom/neighbour_cmds.cpp b/extras/vom/vom/neighbour_cmds.cpp
index 5f9e180b01d..758147c49c5 100644
--- a/extras/vom/vom/neighbour_cmds.cpp
+++ b/extras/vom/vom/neighbour_cmds.cpp
@@ -18,12 +18,12 @@
namespace VOM {
namespace neighbour_cmds {
-create_cmd::create_cmd(HW::item<bool>& item,
+create_cmd::create_cmd(HW::item<handle_t>& item,
handle_t itf,
const mac_address_t& mac,
const boost::asio::ip::address& ip_addr,
const neighbour::flags_t& flags)
- : rpc_cmd(item)
+ : srpc_cmd(item)
, m_itf(itf)
, m_mac(mac)
, m_ip_addr(ip_addr)
@@ -67,12 +67,12 @@ create_cmd::to_string() const
return (s.str());
}
-delete_cmd::delete_cmd(HW::item<bool>& item,
+delete_cmd::delete_cmd(HW::item<handle_t>& item,
handle_t itf,
const mac_address_t& mac,
const boost::asio::ip::address& ip_addr,
const neighbour::flags_t& flags)
- : rpc_cmd(item)
+ : srpc_cmd(item)
, m_itf(itf)
, m_mac(mac)
, m_ip_addr(ip_addr)
diff --git a/extras/vom/vom/neighbour_cmds.hpp b/extras/vom/vom/neighbour_cmds.hpp
index d43a6fe8f3b..ac1523d863d 100644
--- a/extras/vom/vom/neighbour_cmds.hpp
+++ b/extras/vom/vom/neighbour_cmds.hpp
@@ -17,6 +17,7 @@
#define __VOM_NEIGHBOUR_CMDS_H__
#include "vom/dump_cmd.hpp"
+#include "vom/srpc_cmd.hpp"
#include "neighbour.hpp"
#include <vapi/ip.api.vapi.hpp>
@@ -27,14 +28,13 @@ namespace neighbour_cmds {
/**
* A command class that creates or updates the bridge domain ARP Entry
*/
-class create_cmd : public rpc_cmd<HW::item<bool>,
- vapi::Ip_neighbor_add_del>
+class create_cmd : public srpc_cmd<vapi::Ip_neighbor_add_del>
{
public:
/**
* Constructor
*/
- create_cmd(HW::item<bool>& item,
+ create_cmd(HW::item<handle_t>& item,
handle_t itf,
const mac_address_t& mac,
const boost::asio::ip::address& ip_addr,
@@ -65,14 +65,13 @@ private:
/**
* A cmd class that deletes a bridge domain ARP entry
*/
-class delete_cmd : public rpc_cmd<HW::item<bool>,
- vapi::Ip_neighbor_add_del>
+class delete_cmd : public srpc_cmd<vapi::Ip_neighbor_add_del>
{
public:
/**
* Constructor
*/
- delete_cmd(HW::item<bool>& item,
+ delete_cmd(HW::item<handle_t>& item,
handle_t itf,
const mac_address_t& mac,
const boost::asio::ip::address& ip_addr,
diff --git a/extras/vom/vom/prefix.cpp b/extras/vom/vom/prefix.cpp
index fdad67998d1..a6305997f53 100644
--- a/extras/vom/vom/prefix.cpp
+++ b/extras/vom/vom/prefix.cpp
@@ -32,13 +32,13 @@ l3_proto_t::l3_proto_t(int v, const std::string& s)
}
bool
-l3_proto_t::is_ipv6()
+l3_proto_t::is_ipv6() const
{
return (*this == IPV6);
}
bool
-l3_proto_t::is_ipv4()
+l3_proto_t::is_ipv4() const
{
return (*this == IPV4);
}
@@ -492,15 +492,16 @@ route::mprefix_t::mask_width() const
return (m_len);
}
-void
-route::mprefix_t::to_vpp(uint8_t* is_ip6,
- uint8_t* saddr,
- uint8_t* gaddr,
- uint16_t* len) const
+l3_proto_t
+route::mprefix_t::l3_proto() const
{
- *len = m_len;
- to_bytes(m_saddr, is_ip6, saddr);
- to_bytes(m_gaddr, is_ip6, gaddr);
+ if (m_gaddr.is_v6()) {
+ return (l3_proto_t::IPV6);
+ } else {
+ return (l3_proto_t::IPV4);
+ }
+
+ return (l3_proto_t::IPV4);
}
route::mprefix_t&
diff --git a/extras/vom/vom/prefix.hpp b/extras/vom/vom/prefix.hpp
index 1b6a06874d3..b75dc66f86e 100644
--- a/extras/vom/vom/prefix.hpp
+++ b/extras/vom/vom/prefix.hpp
@@ -56,8 +56,8 @@ public:
const static l3_proto_t IPV6;
const static l3_proto_t MPLS;
- bool is_ipv4();
- bool is_ipv6();
+ bool is_ipv4() const;
+ bool is_ipv6() const;
static const l3_proto_t& from_address(const boost::asio::ip::address& addr);
@@ -233,8 +233,8 @@ public:
mprefix_t(const boost::asio::ip::address& gaddr, uint8_t len);
/**
-*Constructor for (S,G)
-*/
+ *Constructor for (S,G)
+ */
mprefix_t(const boost::asio::ip::address& saddr,
const boost::asio::ip::address& gaddr,
uint16_t len);
@@ -300,11 +300,6 @@ public:
*/
l3_proto_t l3_proto() const;
- void to_vpp(uint8_t* is_ip6,
- uint8_t* saddr,
- uint8_t* gaddr,
- uint16_t* len) const;
-
private:
/**
* The address
diff --git a/extras/vom/vom/route.cpp b/extras/vom/vom/route.cpp
index b136c251b94..f627629e2c7 100644
--- a/extras/vom/vom/route.cpp
+++ b/extras/vom/vom/route.cpp
@@ -54,14 +54,6 @@ itf_flags_t::itf_flags_t(int v, const std::string& s)
: enum_base<itf_flags_t>(v, s)
{
}
-const itf_flags_t&
-itf_flags_t::from_vpp(uint32_t val)
-{
- if (itf_flags_t::ACCEPT == (int)val)
- return itf_flags_t::ACCEPT;
- else
- return itf_flags_t::FORWARD;
-}
path::path(special_t special, const nh_proto_t& proto)
: m_type(special)
@@ -339,9 +331,8 @@ void
ip_route::sweep()
{
if (m_hw) {
- for (auto& p : m_paths)
- HW::enqueue(
- new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix, p));
+ HW::enqueue(
+ new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix));
}
HW::write();
}
@@ -350,9 +341,8 @@ void
ip_route::replay()
{
if (m_hw) {
- for (auto& p : m_paths)
- HW::enqueue(
- new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, p));
+ HW::enqueue(
+ new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths));
}
}
std::string
@@ -369,38 +359,9 @@ ip_route::to_string() const
void
ip_route::update(const ip_route& r)
{
- if (rc_t::OK != m_hw.rc()) {
- /*
- * route not yet installed. install each of the desired paths
- */
- m_paths = r.m_paths;
-
- for (auto& p : m_paths)
- HW::enqueue(
- new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, p));
- } else {
- /*
- * add each path that is not installed yet and remove each that is no longer
- * wanted
- */
- path_list_t to_add;
- set_difference(r.m_paths.begin(), r.m_paths.end(), m_paths.begin(),
- m_paths.end(), std::inserter(to_add, to_add.begin()));
-
- for (auto& p : to_add)
- HW::enqueue(
- new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, p));
-
- path_list_t to_del;
- set_difference(m_paths.begin(), m_paths.end(), r.m_paths.begin(),
- r.m_paths.end(), std::inserter(to_del, to_del.begin()));
-
- for (auto& p : to_del)
- HW::enqueue(
- new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix, p));
-
- m_paths = r.m_paths;
- }
+ m_paths = r.m_paths;
+ HW::enqueue(
+ new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths));
}
std::shared_ptr<ip_route>
@@ -442,65 +403,84 @@ ip_route::event_handler::handle_replay()
void
ip_route::event_handler::handle_populate(const client_db::key_t& key)
{
- std::shared_ptr<ip_route_cmds::dump_v4_cmd> cmd_v4 =
- std::make_shared<ip_route_cmds::dump_v4_cmd>();
- std::shared_ptr<ip_route_cmds::dump_v6_cmd> cmd_v6 =
- std::make_shared<ip_route_cmds::dump_v6_cmd>();
-
- HW::enqueue(cmd_v4);
- HW::enqueue(cmd_v6);
- HW::write();
-
- for (auto& record : *cmd_v4) {
- auto& payload = record.get_payload();
-
- prefix_t pfx(0, payload.address, payload.address_length);
-
- /**
- * populating the route domain here
- */
- route_domain rd_temp(payload.table_id);
- std::shared_ptr<route_domain> rd = route_domain::find(payload.table_id);
- if (!rd) {
- OM::commit(key, rd_temp);
- }
- ip_route ip_r(rd_temp, pfx);
-
- for (unsigned int i = 0; i < payload.count; i++) {
- ip_r.add(from_vpp(payload.path[i], nh_proto_t::IPV4));
- }
- 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
- */
- OM::commit(key, ip_r);
- }
-
- for (auto& record : *cmd_v6) {
- auto& payload = record.get_payload();
-
- prefix_t pfx(1, payload.address, payload.address_length);
- route_domain rd_temp(payload.table_id);
- std::shared_ptr<route_domain> rd = route_domain::find(payload.table_id);
- if (!rd) {
- OM::commit(key, rd_temp);
- }
- ip_route ip_r(rd_temp, pfx);
-
- for (unsigned int i = 0; i < payload.count; i++) {
- ip_r.add(from_vpp(payload.path[i], nh_proto_t::IPV6));
+ // for each known route-domain
+ auto it = route_domain::cbegin();
+
+ while (it != route_domain::cend()) {
+
+ std::vector<l3_proto_t> l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 };
+
+ for (auto l3 : l3s) {
+ std::shared_ptr<ip_route_cmds::dump_cmd> cmd =
+ std::make_shared<ip_route_cmds::dump_cmd>(it->second.lock()->table_id(),
+ l3);
+
+ HW::enqueue(cmd);
+ HW::write();
+
+ for (auto& record : *cmd) {
+ auto& payload = record.get_payload();
+
+ std::shared_ptr<route_domain> rd =
+ route_domain::find(payload.route.table_id);
+
+ if (!rd) {
+ continue;
+ }
+
+ prefix_t pfx = from_api(payload.route.prefix);
+ ip_route ip_r(*rd, pfx);
+
+ for (unsigned int i = 0; i < payload.route.n_paths; i++) {
+ ip_r.add(from_api(payload.route.paths[i]));
+
+ // vapi_type_fib_path& p = payload.route.paths[i];
+ /* if (p.is_local) { */
+ /* path path_v4(path::special_t::LOCAL); */
+ /* ip_r.add(path_v4); */
+ /* } */
+ /* } else if (p.is_drop) { */
+ /* path path_v4(path::special_t::DROP); */
+ /* ip_r.add(path_v4); */
+ /* } else if (p.is_unreach) { */
+ /* path path_v4(path::special_t::UNREACH); */
+ /* ip_r.add(path_v4); */
+ /* } else if (p.is_prohibit) { */
+ /* path path_v4(path::special_t::PROHIBIT); */
+ /* ip_r.add(path_v4); */
+ /* } else { */
+ /* boost::asio::ip::address address = from_bytes(0, p.next_hop);
+ */
+ /* std::shared_ptr<interface> itf =
+ * interface::find(p.sw_if_index); */
+ /* if (itf) { */
+ /* if (p.is_dvr) { */
+ /* path path_v4(*itf, nh_proto_t::IPV4,
+ * route::path::flags_t::DVR,
+ */
+ /* p.weight, p.preference); */
+ /* ip_r.add(path_v4); */
+ /* } else { */
+ /* path path_v4(address, *itf, p.weight, p.preference); */
+ /* ip_r.add(path_v4); */
+ /* } */
+ /* } else { */
+ /* path path_v4(rd_temp, address, p.weight, p.preference); */
+ /* ip_r.add(path_v4); */
+ /* } */
+ /* } */
+ }
+
+ 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
+ */
+ 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
- */
- OM::commit(key, ip_r);
}
}
@@ -645,76 +625,51 @@ ip_mroute::event_handler::handle_replay()
void
ip_mroute::event_handler::handle_populate(const client_db::key_t& key)
{
- std::shared_ptr<ip_mroute_cmds::dump_v4_cmd> cmd_v4 =
- std::make_shared<ip_mroute_cmds::dump_v4_cmd>();
- std::shared_ptr<ip_mroute_cmds::dump_v6_cmd> cmd_v6 =
- std::make_shared<ip_mroute_cmds::dump_v6_cmd>();
+ // for each known route-domain
+ auto it = route_domain::cbegin();
- HW::enqueue(cmd_v4);
- HW::enqueue(cmd_v6);
- HW::write();
+ while (it != route_domain::cend()) {
- VOM_LOG(log_level_t::INFO) << "ip-mroute-dump: ";
+ std::vector<l3_proto_t> l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 };
- for (auto& record : *cmd_v4) {
- auto& payload = record.get_payload();
+ for (auto l3 : l3s) {
+ std::shared_ptr<ip_mroute_cmds::dump_cmd> cmd =
+ std::make_shared<ip_mroute_cmds::dump_cmd>(
+ it->second.lock()->table_id(), l3);
- ip_address_t gaddr = from_bytes(0, payload.grp_address);
- ip_address_t saddr = from_bytes(0, payload.src_address);
- mprefix_t pfx(saddr, gaddr, payload.address_length);
+ HW::enqueue(cmd);
+ HW::write();
- /**
- * populating the route domain here
- */
- route_domain rd_temp(payload.table_id);
- std::shared_ptr<route_domain> rd = route_domain::find(payload.table_id);
- if (!rd) {
- OM::commit(key, rd_temp);
- }
- ip_mroute ip_r(rd_temp, pfx);
+ VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: ";
- for (unsigned int i = 0; i < payload.count; i++) {
- vapi_type_mfib_path& p = payload.path[i];
- ip_r.add(from_vpp(p.path, nh_proto_t::IPV4),
- itf_flags_t::from_vpp(p.itf_flags));
- }
- VOM_LOG(log_level_t::DEBUG) << "ip-mroute-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
- */
- OM::commit(key, ip_r);
- }
+ for (auto& record : *cmd) {
+ auto& payload = record.get_payload();
- for (auto& record : *cmd_v6) {
- auto& payload = record.get_payload();
+ std::shared_ptr<route_domain> rd =
+ route_domain::find(payload.route.table_id);
- ip_address_t gaddr = from_bytes(1, payload.grp_address);
- ip_address_t saddr = from_bytes(1, payload.src_address);
- mprefix_t pfx(saddr, gaddr, payload.address_length);
+ if (!rd) {
+ continue;
+ }
- route_domain rd_temp(payload.table_id);
- std::shared_ptr<route_domain> rd = route_domain::find(payload.table_id);
- if (!rd) {
- OM::commit(key, rd_temp);
- }
- ip_mroute ip_r(rd_temp, pfx);
+ mprefix_t pfx = from_api(payload.route.prefix);
+ ip_mroute ip_r(*rd, pfx);
+
+ for (unsigned int i = 0; i < payload.route.n_paths; i++) {
+ ip_r.add(from_api(payload.route.paths[i].path),
+ from_api(payload.route.paths[i].itf_flags));
+ }
+
+ VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: " << ip_r.to_string();
- for (unsigned int i = 0; i < payload.count; i++) {
- vapi_type_mfib_path& p = payload.path[i];
- ip_r.add(from_vpp(p.path, nh_proto_t::IPV6),
- itf_flags_t::from_vpp(p.itf_flags));
+ /*
+ * 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-mroute-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
- */
- OM::commit(key, ip_r);
}
}
diff --git a/extras/vom/vom/route.hpp b/extras/vom/vom/route.hpp
index 746ceb29ebc..8b68015f7ba 100644
--- a/extras/vom/vom/route.hpp
+++ b/extras/vom/vom/route.hpp
@@ -218,8 +218,6 @@ public:
*/
const static itf_flags_t FORWARD;
- static const itf_flags_t& from_vpp(uint32_t val);
-
private:
/**
* Private constructor taking the value and the string name
@@ -398,7 +396,7 @@ private:
/**
* HW configuration for the result of creating the route
*/
- HW::item<bool> m_hw;
+ HW::item<handle_t> m_hw;
/**
* The route domain the route is in.
diff --git a/extras/vom/vom/route_api_types.cpp b/extras/vom/vom/route_api_types.cpp
index d2234796beb..31acc84b6fb 100644
--- a/extras/vom/vom/route_api_types.cpp
+++ b/extras/vom/vom/route_api_types.cpp
@@ -13,111 +13,121 @@
* limitations under the License.
*/
+#include <vom/api_types.hpp>
#include <vom/route.hpp>
#include <vom/route_api_types.hpp>
namespace VOM {
+const route::itf_flags_t&
+from_api(vapi_enum_mfib_itf_flags val)
+{
+ if (route::itf_flags_t::ACCEPT == val)
+ return route::itf_flags_t::ACCEPT;
+ else
+ return route::itf_flags_t::FORWARD;
+}
+
+vapi_enum_mfib_itf_flags
+to_api(const route::itf_flags_t& in)
+{
+ vapi_enum_mfib_itf_flags out = MFIB_API_ITF_FLAG_NONE;
+
+ if (route::itf_flags_t::ACCEPT & in)
+ out = static_cast<vapi_enum_mfib_itf_flags>(out | MFIB_API_ITF_FLAG_ACCEPT);
+ if (route::itf_flags_t::FORWARD & in)
+ out =
+ static_cast<vapi_enum_mfib_itf_flags>(out | MFIB_API_ITF_FLAG_FORWARD);
+
+ return (out);
+}
+
void
-to_vpp(const route::path& p, vapi_payload_ip_add_del_route& payload)
+to_api(const route::path& p, vapi_type_fib_path& payload)
{
- payload.is_drop = 0;
- payload.is_unreach = 0;
- payload.is_prohibit = 0;
- payload.is_local = 0;
- payload.is_classify = 0;
- payload.is_resolve_host = 0;
- payload.is_resolve_attached = 0;
+ payload.flags = FIB_API_PATH_FLAG_NONE;
+ payload.proto = to_api(p.nh_proto());
+ payload.sw_if_index = ~0;
if (route::path::flags_t::DVR & p.flags()) {
- payload.is_dvr = 1;
- }
-
- if (route::path::special_t::STANDARD == p.type()) {
- uint8_t path_v6;
- to_bytes(p.nh(), &path_v6, payload.next_hop_address);
- payload.next_hop_sw_if_index = 0xffffffff;
+ payload.type = FIB_API_PATH_TYPE_DVR;
+ } else if (route::path::special_t::STANDARD == p.type()) {
+ to_api(p.nh(), payload.nh.address);
if (p.rd()) {
- payload.next_hop_table_id = p.rd()->table_id();
+ payload.table_id = p.rd()->table_id();
}
if (p.itf()) {
- payload.next_hop_sw_if_index = p.itf()->handle().value();
+ payload.sw_if_index = p.itf()->handle().value();
}
} else if (route::path::special_t::DROP == p.type()) {
- payload.is_drop = 1;
+ payload.type = FIB_API_PATH_TYPE_DROP;
} else if (route::path::special_t::UNREACH == p.type()) {
- payload.is_unreach = 1;
+ payload.type = FIB_API_PATH_TYPE_ICMP_UNREACH;
} else if (route::path::special_t::PROHIBIT == p.type()) {
- payload.is_prohibit = 1;
+ payload.type = FIB_API_PATH_TYPE_ICMP_PROHIBIT;
} else if (route::path::special_t::LOCAL == p.type()) {
- payload.is_local = 1;
+ payload.type = FIB_API_PATH_TYPE_LOCAL;
}
- payload.next_hop_weight = p.weight();
- payload.next_hop_preference = p.preference();
- payload.next_hop_via_label = 0x100000;
- payload.classify_table_index = 0;
+
+ payload.weight = p.weight();
+ payload.preference = p.preference();
+ payload.n_labels = 0;
}
-void
-to_vpp(const route::path& p, vapi_payload_ip_mroute_add_del& payload)
+route::path
+from_api(const vapi_type_fib_path& p)
{
- payload.next_hop_afi = p.nh_proto();
-
- if (route::path::special_t::STANDARD == p.type()) {
- uint8_t path_v6;
- to_bytes(p.nh(), &path_v6, payload.nh_address);
+ switch (p.type) {
+ case FIB_API_PATH_TYPE_DVR: {
+ std::shared_ptr<interface> itf = interface::find(p.sw_if_index);
+ if (!itf)
+ throw invalid_decode("fib-path deocde no interface:" +
+ std::to_string(p.sw_if_index));
- if (p.itf()) {
- payload.next_hop_sw_if_index = p.itf()->handle().value();
+ return (route::path(*itf, from_api(p.proto), route::path::flags_t::DVR,
+ p.weight, p.preference));
}
+ case FIB_API_PATH_TYPE_NORMAL: {
+ boost::asio::ip::address address = from_api(p.nh.address, p.proto);
+ std::shared_ptr<interface> itf = interface::find(p.sw_if_index);
+ if (itf) {
+ return (route::path(address, *itf, p.weight, p.preference));
+ } else {
+ std::shared_ptr<route_domain> rd = route_domain::find(p.table_id);
- payload.next_hop_afi = p.nh_proto();
- } else if (route::path::special_t::LOCAL == p.type()) {
- payload.is_local = 1;
- }
-}
+ if (!rd)
+ throw invalid_decode("fib-path deocde no route-domain:" +
+ std::to_string(p.table_id));
-route::path
-from_vpp(const vapi_type_fib_path& p, const nh_proto_t& nhp)
-{
- if (p.is_local) {
- return route::path(route::path::special_t::LOCAL);
- } else if (p.is_drop) {
- return route::path(route::path::special_t::DROP);
- } else if (p.is_unreach) {
- return route::path(route::path::special_t::UNREACH);
- } else if (p.is_prohibit) {
- return route::path(route::path::special_t::PROHIBIT);
- } else {
- boost::asio::ip::address address =
- from_bytes(nh_proto_t::IPV6 == nhp, p.next_hop);
- std::shared_ptr<interface> itf = interface::find(p.sw_if_index);
- if (itf) {
- if (p.is_dvr) {
- return route::path(*itf, nhp, route::path::flags_t::DVR, p.weight,
- p.preference);
- } else {
- return route::path(address, *itf, p.weight, p.preference);
- }
- } else {
- std::shared_ptr<route_domain> rd = route_domain::find(p.table_id);
- if (rd) {
- return route::path(*rd, address, p.weight, p.preference);
+ return (route::path(*rd, address, p.weight, p.preference));
}
}
- }
-
- VOM_LOG(log_level_t::ERROR) << "cannot decode: ";
+ case FIB_API_PATH_TYPE_LOCAL:
+ return (route::path(route::path::special_t::LOCAL));
+ case FIB_API_PATH_TYPE_DROP:
+ return (route::path(route::path::special_t::DROP));
+ case FIB_API_PATH_TYPE_ICMP_UNREACH:
+ return (route::path(route::path::special_t::PROHIBIT));
+ case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
+ return (route::path(route::path::special_t::UNREACH));
- return route::path(route::path::special_t::DROP);
-}
+ case FIB_API_PATH_TYPE_UDP_ENCAP:
+ case FIB_API_PATH_TYPE_BIER_IMP:
+ case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
+ case FIB_API_PATH_TYPE_INTERFACE_RX:
+ case FIB_API_PATH_TYPE_CLASSIFY:
+ // not done yet
+ break;
+ }
+ return (route::path(route::path::special_t::DROP));
};
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "mozilla")
- * End:
- */
+}; // namespace VOM
+ /*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
diff --git a/extras/vom/vom/route_api_types.hpp b/extras/vom/vom/route_api_types.hpp
index 09015485cdb..25d0902cda1 100644
--- a/extras/vom/vom/route_api_types.hpp
+++ b/extras/vom/vom/route_api_types.hpp
@@ -19,10 +19,12 @@
namespace VOM {
-void to_vpp(const route::path& p, vapi_payload_ip_mroute_add_del& payload);
-void to_vpp(const route::path& p, vapi_payload_ip_add_del_route& payload);
+vapi_enum_mfib_itf_flags to_api(const route::itf_flags_t& flags);
+const route::itf_flags_t& from_api(vapi_enum_mfib_itf_flags flags);
-route::path from_vpp(const vapi_type_fib_path& p, const nh_proto_t& nh);
+void to_api(const route::path& p, vapi_type_fib_path& o);
+
+route::path from_api(const vapi_type_fib_path& p);
}; // namespace VOM
diff --git a/extras/vom/vom/route_cmds.cpp b/extras/vom/vom/route_cmds.cpp
index 24233d9e443..fb1fc2f9933 100644
--- a/extras/vom/vom/route_cmds.cpp
+++ b/extras/vom/vom/route_cmds.cpp
@@ -15,6 +15,7 @@
#include <sstream>
+#include <vom/api_types.hpp>
#include <vom/route_api_types.hpp>
#include <vom/route_cmds.hpp>
@@ -22,14 +23,14 @@ namespace VOM {
namespace route {
namespace ip_route_cmds {
-update_cmd::update_cmd(HW::item<bool>& item,
+update_cmd::update_cmd(HW::item<handle_t>& item,
table_id_t id,
const prefix_t& prefix,
- const path& path)
- : rpc_cmd(item)
+ const path_list_t& pl)
+ : srpc_cmd(item)
, m_id(id)
, m_prefix(prefix)
- , m_path(path)
+ , m_pl(pl)
{
}
@@ -37,23 +38,26 @@ bool
update_cmd::operator==(const update_cmd& other) const
{
return ((m_prefix == other.m_prefix) && (m_id == other.m_id) &&
- (m_path == other.m_path));
+ (m_pl == other.m_pl));
}
rc_t
update_cmd::issue(connection& con)
{
- msg_t req(con.ctx(), 0, std::ref(*this));
+ msg_t req(con.ctx(), m_pl.size(), std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
+ payload.route.table_id = m_id;
payload.is_add = 1;
payload.is_multipath = 1;
- m_prefix.to_vpp(&payload.is_ipv6, payload.dst_address,
- &payload.dst_address_length);
- to_vpp(m_path, payload);
+ payload.route.table_id = m_id;
+ payload.route.prefix = to_api(m_prefix);
+
+ uint32_t ii = 0;
+ for (auto& p : m_pl)
+ to_api(p, payload.route.paths[ii++]);
VAPI_CALL(req.execute());
@@ -65,27 +69,26 @@ update_cmd::to_string() const
{
std::ostringstream s;
s << "ip-route-create: " << m_hw_item.to_string() << " table-id:" << m_id
- << " prefix:" << m_prefix.to_string() << " paths:" << m_path.to_string();
+ << " prefix:" << m_prefix.to_string() << " paths:";
+ for (auto p : m_pl)
+ s << p.to_string() << " ";
return (s.str());
}
-delete_cmd::delete_cmd(HW::item<bool>& item,
+delete_cmd::delete_cmd(HW::item<handle_t>& item,
table_id_t id,
- const prefix_t& prefix,
- const path& path)
+ const prefix_t& prefix)
: rpc_cmd(item)
, m_id(id)
, m_prefix(prefix)
- , m_path(path)
{
}
bool
delete_cmd::operator==(const delete_cmd& other) const
{
- return ((m_prefix == other.m_prefix) && (m_id == other.m_id) &&
- (m_path == other.m_path));
+ return ((m_prefix == other.m_prefix) && (m_id == other.m_id));
}
rc_t
@@ -94,12 +97,12 @@ delete_cmd::issue(connection& con)
msg_t req(con.ctx(), 0, std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
+ payload.route.table_id = m_id;
payload.is_add = 0;
+ payload.is_multipath = 0;
- m_prefix.to_vpp(&payload.is_ipv6, payload.dst_address,
- &payload.dst_address_length);
- to_vpp(m_path, payload);
+ payload.route.table_id = m_id;
+ payload.route.prefix = to_api(m_prefix);
VAPI_CALL(req.execute());
@@ -114,53 +117,32 @@ delete_cmd::to_string() const
{
std::ostringstream s;
s << "ip-route-delete: " << m_hw_item.to_string() << " id:" << m_id
- << " prefix:" << m_prefix.to_string() << " paths:" << m_path.to_string();
+ << " prefix:" << m_prefix.to_string();
return (s.str());
}
-dump_v4_cmd::dump_v4_cmd()
+dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto)
+ : m_id(id)
+ , m_proto(proto)
{
}
bool
-dump_v4_cmd::operator==(const dump_v4_cmd& other) const
+dump_cmd::operator==(const dump_cmd& other) const
{
return (true);
}
rc_t
-dump_v4_cmd::issue(connection& con)
+dump_cmd::issue(connection& con)
{
m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
- VAPI_CALL(m_dump->execute());
+ auto& payload = m_dump->get_request().get_payload();
- wait();
-
- return rc_t::OK;
-}
-
-std::string
-dump_v4_cmd::to_string() const
-{
- return ("ip-route-v4-dump");
-}
-
-dump_v6_cmd::dump_v6_cmd()
-{
-}
-
-bool
-dump_v6_cmd::operator==(const dump_v6_cmd& other) const
-{
- return (true);
-}
-
-rc_t
-dump_v6_cmd::issue(connection& con)
-{
- m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+ payload.table.table_id = m_id;
+ payload.table.is_ip6 = m_proto.is_ipv6();
VAPI_CALL(m_dump->execute());
@@ -170,17 +152,19 @@ dump_v6_cmd::issue(connection& con)
}
std::string
-dump_v6_cmd::to_string() const
+dump_cmd::to_string() const
{
- return ("ip-route-v6-dump");
+ return ("ip-route-v4-dump");
}
+
} // namespace ip_route_cmds
} // namespace route
} // namespace vom
- /*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "mozilla")
- * End:
- */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
diff --git a/extras/vom/vom/route_cmds.hpp b/extras/vom/vom/route_cmds.hpp
index 6db7b5894ef..3c43208f120 100644
--- a/extras/vom/vom/route_cmds.hpp
+++ b/extras/vom/vom/route_cmds.hpp
@@ -18,7 +18,7 @@
#include "vom/dump_cmd.hpp"
#include "vom/route.hpp"
-#include "vom/rpc_cmd.hpp"
+#include "vom/srpc_cmd.hpp"
#include <vapi/ip.api.vapi.hpp>
@@ -29,16 +29,16 @@ namespace ip_route_cmds {
/**
* A command class that creates or updates the route
*/
-class update_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_add_del_route>
+class update_cmd : public srpc_cmd<vapi::Ip_route_add_del>
{
public:
/**
* Constructor
*/
- update_cmd(HW::item<bool>& item,
+ update_cmd(HW::item<handle_t>& item,
table_id_t id,
const prefix_t& prefix,
- const path& path);
+ const path_list_t& pl);
/**
* Issue the command to VPP/HW
@@ -58,22 +58,19 @@ public:
private:
route::table_id_t m_id;
prefix_t m_prefix;
- const path m_path;
+ const path_list_t& m_pl;
};
/**
* A cmd class that deletes a route
*/
-class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_add_del_route>
+class delete_cmd : public rpc_cmd<HW::item<handle_t>, vapi::Ip_route_add_del>
{
public:
/**
* Constructor
*/
- delete_cmd(HW::item<bool>& item,
- table_id_t id,
- const prefix_t& prefix,
- const path& path);
+ delete_cmd(HW::item<handle_t>& item, table_id_t id, const prefix_t& prefix);
/**
* Issue the command to VPP/HW
@@ -93,20 +90,19 @@ public:
private:
route::table_id_t m_id;
prefix_t m_prefix;
- const path m_path;
};
/**
- * A cmd class that Dumps ipv4 fib
+ * A cmd class that Dumps ip fib routes
*/
-class dump_v4_cmd : public VOM::dump_cmd<vapi::Ip_fib_dump>
+class dump_cmd : public VOM::dump_cmd<vapi::Ip_route_dump>
{
public:
/**
* Constructor
*/
- dump_v4_cmd();
- dump_v4_cmd(const dump_cmd& d);
+ dump_cmd(route::table_id_t id, const l3_proto_t& proto);
+ dump_cmd(const dump_cmd& d);
/**
* Issue the command to VPP/HW
@@ -120,46 +116,15 @@ public:
/**
* Comparison operator - only used for UT
*/
- bool operator==(const dump_v4_cmd& i) const;
-
-private:
- /**
- * HW reutrn code
- */
- HW::item<bool> item;
-};
-
-/**
- * A cmd class that Dumps ipv6 fib
- */
-class dump_v6_cmd : public VOM::dump_cmd<vapi::Ip6_fib_dump>
-{
-public:
- /**
- * Constructor
- */
- dump_v6_cmd();
- dump_v6_cmd(const dump_cmd& d);
-
- /**
- * 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 dump_v6_cmd& i) const;
+ bool operator==(const dump_cmd& i) const;
private:
/**
* HW reutrn code
*/
HW::item<bool> item;
+ route::table_id_t m_id;
+ const l3_proto_t& m_proto;
};
}; // namespace ip_route_cmds
diff --git a/extras/vom/vom/route_domain.cpp b/extras/vom/vom/route_domain.cpp
index b97faf6ae49..16bf5f36c90 100644
--- a/extras/vom/vom/route_domain.cpp
+++ b/extras/vom/vom/route_domain.cpp
@@ -62,6 +62,18 @@ route_domain::key() const
return (table_id());
}
+route_domain::const_iterator_t
+route_domain::cbegin()
+{
+ return m_db.begin();
+}
+
+route_domain::const_iterator_t
+route_domain::cend()
+{
+ return m_db.end();
+}
+
void
route_domain::sweep()
{
@@ -159,6 +171,26 @@ route_domain::dump(std::ostream& os)
void
route_domain::event_handler::handle_populate(const client_db::key_t& key)
{
+ std::shared_ptr<route_domain_cmds::dump_cmd> cmd =
+ std::make_shared<route_domain_cmds::dump_cmd>();
+
+ HW::enqueue(cmd);
+ HW::write();
+
+ for (auto& record : *cmd) {
+ auto& payload = record.get_payload();
+
+ route_domain rd(payload.table.table_id);
+
+ VOM_LOG(log_level_t::DEBUG) << "ip-table-dump: " << rd.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
+ */
+ OM::commit(key, rd);
+ }
}
route_domain::event_handler::event_handler()
diff --git a/extras/vom/vom/route_domain.hpp b/extras/vom/vom/route_domain.hpp
index 96e46ce575b..78db63bbe59 100644
--- a/extras/vom/vom/route_domain.hpp
+++ b/extras/vom/vom/route_domain.hpp
@@ -37,6 +37,15 @@ public:
typedef route::table_id_t key_t;
/**
+ * The iterator type
+ */
+ typedef singular_db<const key_t, route_domain>::const_iterator
+ const_iterator_t;
+
+ static const_iterator_t cbegin();
+ static const_iterator_t cend();
+
+ /**
* Construct a new object matching the desried state
*/
route_domain(route::table_id_t id);
diff --git a/extras/vom/vom/route_domain_cmds.cpp b/extras/vom/vom/route_domain_cmds.cpp
index 9eb50436cc2..8f135e50ef5 100644
--- a/extras/vom/vom/route_domain_cmds.cpp
+++ b/extras/vom/vom/route_domain_cmds.cpp
@@ -39,9 +39,9 @@ create_cmd::issue(connection& con)
msg_t req(con.ctx(), std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
+ payload.table.table_id = m_id;
+ payload.table.is_ip6 = m_proto.is_ipv6();
payload.is_add = 1;
- payload.is_ipv6 = m_proto.is_ipv6();
VAPI_CALL(req.execute());
@@ -79,9 +79,9 @@ delete_cmd::issue(connection& con)
msg_t req(con.ctx(), std::ref(*this));
auto& payload = req.get_request().get_payload();
- payload.table_id = m_id;
+ payload.table.table_id = m_id;
+ payload.table.is_ip6 = m_proto.is_ipv6();
payload.is_add = 0;
- payload.is_ipv6 = m_proto.is_ipv6();
VAPI_CALL(req.execute());
@@ -100,6 +100,35 @@ delete_cmd::to_string() const
return (s.str());
}
+
+dump_cmd::dump_cmd()
+{
+}
+
+bool
+dump_cmd::operator==(const dump_cmd& other) const
+{
+ return (true);
+}
+
+rc_t
+dump_cmd::issue(connection& con)
+{
+ m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+
+ VAPI_CALL(m_dump->execute());
+
+ wait();
+
+ return rc_t::OK;
+}
+
+std::string
+dump_cmd::to_string() const
+{
+ return ("ip-table-dump");
+}
+
} // namespace route_domain_cmds
} // namespace VOM
/*
diff --git a/extras/vom/vom/route_domain_cmds.hpp b/extras/vom/vom/route_domain_cmds.hpp
index 6ac679bd343..42546da91b4 100644
--- a/extras/vom/vom/route_domain_cmds.hpp
+++ b/extras/vom/vom/route_domain_cmds.hpp
@@ -16,6 +16,7 @@
#ifndef __VOM_ROUTE_DOMAIN_CMDS_H__
#define __VOM_ROUTE_DOMAIN_CMDS_H__
+#include "vom/dump_cmd.hpp"
#include "vom/route_domain.hpp"
#include "vom/rpc_cmd.hpp"
@@ -100,6 +101,39 @@ private:
l3_proto_t m_proto;
};
+/**
+ * A cmd class that Dumps IP fib tables
+ */
+class dump_cmd : public VOM::dump_cmd<vapi::Ip_table_dump>
+{
+public:
+ /**
+ * Constructor
+ */
+ dump_cmd();
+ dump_cmd(const dump_cmd& d);
+
+ /**
+ * 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 dump_cmd& i) const;
+
+private:
+ /**
+ * HW reutrn code
+ */
+ HW::item<bool> item;
+};
+
}; // namespace route_domain_cmds
}; // namespace VOM
diff --git a/extras/vom/vom/srpc_cmd.hpp b/extras/vom/vom/srpc_cmd.hpp
new file mode 100644
index 00000000000..da6064dafba
--- /dev/null
+++ b/extras/vom/vom/srpc_cmd.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VOM_SRPC_CMD_H__
+#define __VOM_SRPC_CMD_H__
+
+#include "vom/hw.hpp"
+#include "vom/rpc_cmd.hpp"
+
+namespace VOM {
+template <typename MSG>
+class srpc_cmd : public rpc_cmd<HW::item<handle_t>, MSG>
+{
+public:
+ /**
+ * convenient typedef
+ */
+ typedef MSG msg_t;
+
+ /**
+ * Constructor taking the HW item that will be updated by the command
+ */
+ srpc_cmd(HW::item<handle_t>& item)
+ : rpc_cmd<HW::item<handle_t>, MSG>(item)
+ {
+ }
+
+ /**
+ * Desructor
+ */
+ virtual ~srpc_cmd() {}
+
+ virtual vapi_error_e operator()(MSG& reply)
+ {
+ int stats_index = reply.get_response().get_payload().stats_index;
+ int retval = reply.get_response().get_payload().retval;
+
+ VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval;
+
+ rc_t rc = rc_t::from_vpp_retval(retval);
+ handle_t handle = handle_t::INVALID;
+
+ if (rc_t::OK == rc) {
+ handle = stats_index;
+ }
+
+ this->fulfill(HW::item<handle_t>(handle, rc));
+
+ return (VAPI_OK);
+ }
+};
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
+
+#endif