diff options
author | Neale Ranns <nranns@cisco.com> | 2019-01-10 08:56:38 -0800 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2019-01-10 21:01:43 +0000 |
commit | 6ad7231c00287b7c1241c6e1dbbfda86f15798b4 (patch) | |
tree | 84f38e8c6e870c66e3398972b165779f7ef5d366 /extras/vom | |
parent | 1bcad5cdb78fb04d41f97603312161b2bc2e7bae (diff) |
VOM: IP route ECMP support
Change-Id: Iede0c30aacfe7289f428062bb9540410097c40e2
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'extras/vom')
-rw-r--r-- | extras/vom/vom/route.cpp | 45 | ||||
-rw-r--r-- | extras/vom/vom/route_cmds.cpp | 25 | ||||
-rw-r--r-- | extras/vom/vom/route_cmds.hpp | 10 |
3 files changed, 56 insertions, 24 deletions
diff --git a/extras/vom/vom/route.cpp b/extras/vom/vom/route.cpp index c713de9ee99..5aed82bac2a 100644 --- a/extras/vom/vom/route.cpp +++ b/extras/vom/vom/route.cpp @@ -339,8 +339,9 @@ void ip_route::sweep() { if (m_hw) { - HW::enqueue( - new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix)); + for (auto& p : m_paths) + HW::enqueue( + new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix, p)); } HW::write(); } @@ -349,8 +350,9 @@ void ip_route::replay() { if (m_hw) { - HW::enqueue( - new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); + for (auto& p : m_paths) + HW::enqueue( + new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, p)); } } std::string @@ -367,12 +369,37 @@ ip_route::to_string() const void 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 ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); + /* + * 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; } } diff --git a/extras/vom/vom/route_cmds.cpp b/extras/vom/vom/route_cmds.cpp index 26d6593df78..e3f635fe09a 100644 --- a/extras/vom/vom/route_cmds.cpp +++ b/extras/vom/vom/route_cmds.cpp @@ -25,20 +25,19 @@ namespace ip_route_cmds { update_cmd::update_cmd(HW::item<bool>& item, table_id_t id, const prefix_t& prefix, - const path_list_t& paths) + const path& path) : rpc_cmd(item) , m_id(id) , m_prefix(prefix) - , m_paths(paths) + , m_path(path) { - // no multipath yet. - assert(paths.size() == 1); } bool update_cmd::operator==(const update_cmd& other) const { - return ((m_prefix == other.m_prefix) && (m_id == other.m_id)); + return ((m_prefix == other.m_prefix) && (m_id == other.m_id) && + (m_path == other.m_path)); } rc_t @@ -54,9 +53,7 @@ update_cmd::issue(connection& con) m_prefix.to_vpp(&payload.is_ipv6, payload.dst_address, &payload.dst_address_length); - - for (auto& p : m_paths) - to_vpp(p, payload); + to_vpp(m_path, payload); VAPI_CALL(req.execute()); @@ -68,24 +65,27 @@ 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_paths; + << " prefix:" << m_prefix.to_string() << " paths:" << m_path.to_string(); return (s.str()); } delete_cmd::delete_cmd(HW::item<bool>& item, table_id_t id, - const prefix_t& prefix) + const prefix_t& prefix, + const path& path) : 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)); + return ((m_prefix == other.m_prefix) && (m_id == other.m_id) && + (m_path == other.m_path)); } rc_t @@ -99,6 +99,7 @@ delete_cmd::issue(connection& con) m_prefix.to_vpp(&payload.is_ipv6, payload.dst_address, &payload.dst_address_length); + to_vpp(m_path, payload); VAPI_CALL(req.execute()); @@ -113,7 +114,7 @@ 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(); + << " prefix:" << m_prefix.to_string() << " paths:" << m_path.to_string(); return (s.str()); } diff --git a/extras/vom/vom/route_cmds.hpp b/extras/vom/vom/route_cmds.hpp index 2e6ce73068c..6db7b5894ef 100644 --- a/extras/vom/vom/route_cmds.hpp +++ b/extras/vom/vom/route_cmds.hpp @@ -38,7 +38,7 @@ public: update_cmd(HW::item<bool>& item, table_id_t id, const prefix_t& prefix, - const path_list_t& paths); + const path& path); /** * Issue the command to VPP/HW @@ -58,7 +58,7 @@ public: private: route::table_id_t m_id; prefix_t m_prefix; - const path_list_t m_paths; + const path m_path; }; /** @@ -70,7 +70,10 @@ public: /** * Constructor */ - delete_cmd(HW::item<bool>& item, table_id_t id, const prefix_t& prefix); + delete_cmd(HW::item<bool>& item, + table_id_t id, + const prefix_t& prefix, + const path& path); /** * Issue the command to VPP/HW @@ -90,6 +93,7 @@ public: private: route::table_id_t m_id; prefix_t m_prefix; + const path m_path; }; /** |