summaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-05-01 05:17:55 -0700
committerOle Trøan <otroan@employees.org>2019-06-18 13:31:39 +0000
commit097fa66b986f06281f603767d321ab13ab6c88c3 (patch)
treeed052819615d08ee4bd0afbc34de7e64e4598105 /extras
parent39baa32186fd3e4b20d9f58afbbfe7b8daebed62 (diff)
fib: fib api updates
Enhance the route add/del APIs to take a set of paths rather than just one. Most unicast routing protocols calcualte all the available paths in one run of the algorithm so updating all the paths at once is beneficial for the client. two knobs control the behaviour: is_multipath - if set the the set of paths passed will be added to those that already exist, otherwise the set will replace them. is_add - add or remove the set is_add=0, is_multipath=1 and an empty set, results in deleting the route. It is also considerably faster to add multiple paths at once, than one at a time: vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.11 100000 routes in .572240 secs, 174751.80 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.12 100000 routes in .528383 secs, 189256.54 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.13 100000 routes in .757131 secs, 132077.52 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.14 100000 routes in .878317 secs, 113854.12 routes/sec vat# ip_route_add_del 1.1.1.1/32 count 100000 multipath via 10.10.10.11 via 10.10.10.12 via 10.10.10.13 via 10.10.10.14 100000 routes in .900212 secs, 111084.93 routes/sec Change-Id: I416b93f7684745099c1adb0b33edac58c9339c1a Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
Diffstat (limited to 'extras')
-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