X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fvom%2Froute.cpp;h=247afa008a7e8c410d5a254918da547deed286d0;hb=756cd9441752fc8f84104c9ee19099506ba89f85;hp=e239f8c4f624ccbf3b5ac861be1edf7385de74f8;hpb=812ed39f9da336310e815c361ab5a9f118657d94;p=vpp.git diff --git a/src/vpp-api/vom/route.cpp b/src/vpp-api/vom/route.cpp index e239f8c4f62..247afa008a7 100644 --- a/src/vpp-api/vom/route.cpp +++ b/src/vpp-api/vom/route.cpp @@ -14,12 +14,12 @@ */ #include "vom/route.hpp" -#include "vom/singular_db.hpp" - -#include +#include "vom/route_cmds.hpp" +#include "vom/singular_db_funcs.hpp" namespace VOM { namespace route { +ip_route::event_handler ip_route::m_evh; singular_db ip_route::m_db; const path::special_t path::special_t::STANDARD(0, "standard"); @@ -33,9 +33,18 @@ path::special_t::special_t(int v, const std::string& s) { } +const path::flags_t path::flags_t::NONE(0, "none"); +const path::flags_t path::flags_t::DVR((1 << 0), "dvr"); + +path::flags_t::flags_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + path::path(special_t special) : m_type(special) , m_nh_proto(nh_proto_t::IPV4) + , m_flags(flags_t::NONE) , m_nh() , m_rd(nullptr) , m_interface(nullptr) @@ -50,6 +59,7 @@ path::path(const boost::asio::ip::address& nh, uint8_t preference) : m_type(special_t::STANDARD) , m_nh_proto(nh_proto_t::from_address(nh)) + , m_flags(flags_t::NONE) , m_nh(nh) , m_rd(nullptr) , m_interface(interface.singular()) @@ -64,6 +74,7 @@ path::path(const route_domain& rd, uint8_t preference) : m_type(special_t::STANDARD) , m_nh_proto(nh_proto_t::from_address(nh)) + , m_flags(flags_t::NONE) , m_nh(nh) , m_rd(rd.singular()) , m_interface(nullptr) @@ -74,10 +85,12 @@ path::path(const route_domain& rd, path::path(const interface& interface, const nh_proto_t& proto, + const flags_t& flags, uint8_t weight, uint8_t preference) : m_type(special_t::STANDARD) , m_nh_proto(proto) + , m_flags(flags) , m_nh() , m_rd(nullptr) , m_interface(interface.singular()) @@ -89,6 +102,7 @@ path::path(const interface& interface, path::path(const path& p) : m_type(p.m_type) , m_nh_proto(p.m_nh_proto) + , m_flags(p.m_flags) , m_nh(p.m_nh) , m_rd(p.m_rd) , m_interface(p.m_interface) @@ -100,57 +114,52 @@ path::path(const path& p) bool path::operator<(const path& p) const { + if (m_nh_proto < p.m_nh_proto) + return true; + if (m_flags < p.m_flags) + return true; if (m_type < p.m_type) return true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return true; if (m_rd->table_id() < p.m_rd->table_id()) return true; if (m_nh < p.m_nh) return true; + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return true; if (m_interface->handle() < p.m_interface->handle()) return true; return (false); } -void -path::to_vpp(vapi_payload_ip_add_del_route& payload) const -{ - payload.is_drop = 0; - payload.is_unreach = 0; - payload.is_prohibit = 0; - payload.is_local = 0; - payload.is_classify = 0; - payload.is_multipath = 0; - payload.is_resolve_host = 0; - payload.is_resolve_attached = 0; - - if (nh_proto_t::ETHERNET == m_nh_proto) { - payload.is_l2_bridged = 1; - } - - if (special_t::STANDARD == m_type) { - uint8_t path_v6; - to_bytes(m_nh, &path_v6, payload.next_hop_address); +path::~path() +{ +} - if (m_rd) { - payload.next_hop_table_id = m_rd->table_id(); - } - if (m_interface) { - payload.next_hop_sw_if_index = m_interface->handle().value(); - } - } else if (special_t::DROP == m_type) { - payload.is_drop = 1; - } else if (special_t::UNREACH == m_type) { - payload.is_unreach = 1; - } else if (special_t::PROHIBIT == m_type) { - payload.is_prohibit = 1; - } else if (special_t::LOCAL == m_type) { - payload.is_local = 1; - } - payload.next_hop_weight = m_weight; - payload.next_hop_preference = m_preference; - payload.next_hop_via_label = 0; - payload.classify_table_index = 0; +bool +path::operator==(const path& p) const +{ + bool result = true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return false; + if (m_rd && p.m_rd) + result &= (*m_rd == *p.m_rd); + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return false; + if (m_interface && p.m_interface) + result &= (*m_interface == *p.m_interface); + return (result && (m_type == p.m_type) && (m_nh == p.m_nh) && + (m_nh_proto == p.m_nh_proto) && (m_flags == p.m_flags)); } std::string @@ -160,7 +169,7 @@ path::to_string() const s << "path:[" << "type:" << m_type.to_string() << " proto:" << m_nh_proto.to_string() - << " neighbour:" << m_nh.to_string(); + << " flags:" << m_flags.to_string() << " neighbour:" << m_nh.to_string(); if (m_rd) { s << " " << m_rd->to_string(); } @@ -173,6 +182,62 @@ path::to_string() const return (s.str()); } +path::special_t +path::type() const +{ + return m_type; +} + +nh_proto_t +path::nh_proto() const +{ + return m_nh_proto; +} + +path::flags_t +path::flags() const +{ + return m_flags; +} + +const boost::asio::ip::address& +path::nh() const +{ + return m_nh; +} + +std::shared_ptr +path::rd() const +{ + return m_rd; +} + +std::shared_ptr +path::itf() const +{ + return m_interface; +} + +uint8_t +path::weight() const +{ + return m_weight; +} + +uint8_t +path::preference() const +{ + return m_preference; +} + +ip_route::ip_route(const prefix_t& prefix, const path& p) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + ip_route::ip_route(const prefix_t& prefix) : m_hw(false) , m_rd(route_domain::get_default()) @@ -197,12 +262,35 @@ ip_route::ip_route(const route_domain& rd, const prefix_t& prefix) { } +ip_route::ip_route(const route_domain& rd, + const prefix_t& prefix, + const path& p) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + ip_route::~ip_route() { sweep(); // not in the DB anymore. - m_db.release(std::make_pair(m_rd->table_id(), m_prefix), this); + m_db.release(key(), this); + m_paths.clear(); +} + +const ip_route::key_t +ip_route::key() const +{ + return (std::make_pair(m_rd->table_id(), m_prefix)); +} + +bool +ip_route::operator==(const ip_route& i) const +{ + return ((key() == i.key()) && (m_paths == i.m_paths)); } void @@ -221,7 +309,8 @@ void ip_route::sweep() { if (m_hw) { - HW::enqueue(new delete_cmd(m_hw, m_rd->table_id(), m_prefix)); + HW::enqueue( + new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix)); } HW::write(); } @@ -230,7 +319,8 @@ void ip_route::replay() { if (m_hw) { - HW::enqueue(new update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); + HW::enqueue( + new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); } } std::string @@ -251,15 +341,21 @@ ip_route::update(const ip_route& r) * create the table if it is not yet created */ if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new update_cmd(m_hw, m_rd->table_id(), m_prefix, 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::find_or_add(const ip_route& temp) { - return (m_db.find_or_add(std::make_pair(temp.m_rd->table_id(), temp.m_prefix), - temp)); + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +ip_route::find(const key_t& k) +{ + return (m_db.find(k)); } std::shared_ptr @@ -271,7 +367,7 @@ ip_route::singular() const void ip_route::dump(std::ostream& os) { - m_db.dump(os); + db_dump(m_db, os); } ip_route::event_handler::event_handler() @@ -289,8 +385,10 @@ ip_route::event_handler::handle_replay() void ip_route::event_handler::handle_populate(const client_db::key_t& key) { - std::shared_ptr cmd_v4(new ip_route::dump_v4_cmd()); - std::shared_ptr cmd_v6(new ip_route::dump_v6_cmd()); + std::shared_ptr cmd_v4 = + std::make_shared(); + std::shared_ptr cmd_v6 = + std::make_shared(); HW::enqueue(cmd_v4); HW::enqueue(cmd_v6); @@ -302,10 +400,10 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) prefix_t pfx(0, payload.address, payload.address_length); /** -* populating the route domain here -*/ + * populating the route domain here + */ route_domain rd_temp(payload.table_id); - std::shared_ptr rd = route_domain::find(rd_temp); + std::shared_ptr rd = route_domain::find(payload.table_id); if (!rd) { OM::commit(key, rd_temp); } @@ -326,19 +424,30 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) path path_v4(path::special_t::PROHIBIT); ip_r.add(path_v4); } else { - std::shared_ptr itf = interface::find(p.sw_if_index); boost::asio::ip::address address = from_bytes(0, p.next_hop); - path path_v4(address, *itf, p.weight, p.preference); - ip_r.add(path_v4); + std::shared_ptr 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 -*/ + * 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); } @@ -347,7 +456,7 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) prefix_t pfx(1, payload.address, payload.address_length); route_domain rd_temp(payload.table_id); - std::shared_ptr rd = route_domain::find(rd_temp); + std::shared_ptr rd = route_domain::find(payload.table_id); if (!rd) { OM::commit(key, rd_temp); } @@ -370,17 +479,28 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) } else { std::shared_ptr itf = interface::find(p.sw_if_index); boost::asio::ip::address address = from_bytes(1, p.next_hop); - path path_v6(address, *itf, p.weight, p.preference); - ip_r.add(path_v6); + if (itf) { + if (p.is_dvr) { + path path_v6(*itf, nh_proto_t::IPV6, route::path::flags_t::DVR, + p.weight, p.preference); + ip_r.add(path_v6); + } else { + path path_v6(address, *itf, p.weight, p.preference); + ip_r.add(path_v6); + } + } else { + path path_v6(rd_temp, address, p.weight, p.preference); + ip_r.add(path_v6); + } } } VOM_LOG(log_level_t::DEBUG) << "ip-route-dump: " << ip_r.to_string(); /* -* Write each of the discovered interfaces into the OM, -* but disable the HW Command q whilst we do, so that no -* commands are sent to VPP -*/ + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ OM::commit(key, ip_r); } } @@ -388,13 +508,13 @@ ip_route::event_handler::handle_populate(const client_db::key_t& key) dependency_t ip_route::event_handler::order() const { - return (dependency_t::BINDING); + return (dependency_t::ENTRY); } void ip_route::event_handler::show(std::ostream& os) { - m_db.dump(os); + db_dump(m_db, os); } std::ostream&