diff options
Diffstat (limited to 'extras/vom')
-rw-r--r-- | extras/vom/vom/api_types.cpp | 72 | ||||
-rw-r--r-- | extras/vom/vom/api_types.hpp | 15 | ||||
-rw-r--r-- | extras/vom/vom/interface.cpp | 4 | ||||
-rw-r--r-- | extras/vom/vom/mroute_cmds.cpp | 69 | ||||
-rw-r--r-- | extras/vom/vom/mroute_cmds.hpp | 42 | ||||
-rw-r--r-- | extras/vom/vom/neighbour.hpp | 2 | ||||
-rw-r--r-- | extras/vom/vom/neighbour_cmds.cpp | 8 | ||||
-rw-r--r-- | extras/vom/vom/neighbour_cmds.hpp | 11 | ||||
-rw-r--r-- | extras/vom/vom/prefix.cpp | 21 | ||||
-rw-r--r-- | extras/vom/vom/prefix.hpp | 13 | ||||
-rw-r--r-- | extras/vom/vom/route.cpp | 281 | ||||
-rw-r--r-- | extras/vom/vom/route.hpp | 4 | ||||
-rw-r--r-- | extras/vom/vom/route_api_types.cpp | 164 | ||||
-rw-r--r-- | extras/vom/vom/route_api_types.hpp | 8 | ||||
-rw-r--r-- | extras/vom/vom/route_cmds.cpp | 104 | ||||
-rw-r--r-- | extras/vom/vom/route_cmds.hpp | 63 | ||||
-rw-r--r-- | extras/vom/vom/route_domain.cpp | 32 | ||||
-rw-r--r-- | extras/vom/vom/route_domain.hpp | 9 | ||||
-rw-r--r-- | extras/vom/vom/route_domain_cmds.cpp | 37 | ||||
-rw-r--r-- | extras/vom/vom/route_domain_cmds.hpp | 34 | ||||
-rw-r--r-- | extras/vom/vom/srpc_cmd.hpp | 74 |
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 |