From 193c47d900bfbc15e4e46ede7c25ecf1ca95b898 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Mon, 10 Dec 2018 06:01:46 -0800 Subject: [PATCH] VOM: vxlan-gbp Change-Id: I5f4464435f1346207f2f9b497369795eb82b58b6 Signed-off-by: Neale Ranns --- extras/vom/vom/CMakeLists.txt | 1 + extras/vom/vom/gbp_bridge_domain.cpp | 57 ++++++++++- extras/vom/vom/gbp_bridge_domain.hpp | 11 ++- extras/vom/vom/gbp_endpoint_group.cpp | 33 ++++++- extras/vom/vom/gbp_endpoint_group.hpp | 3 + extras/vom/vom/gbp_route_domain.cpp | 26 ++++- extras/vom/vom/gbp_route_domain.hpp | 5 + extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp | 158 ++++++++++++++++++++++++++++++ extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp | 134 ++++++++++++++++++++++++++ extras/vom/vom/vxlan_tunnel.cpp | 159 ++++++++++++++++--------------- extras/vom/vom/vxlan_tunnel.hpp | 35 ++++--- test/ext/vom_test.cpp | 2 +- 12 files changed, 523 insertions(+), 101 deletions(-) create mode 100644 extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp create mode 100644 extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp diff --git a/extras/vom/vom/CMakeLists.txt b/extras/vom/vom/CMakeLists.txt index f68a7409362..47e73b6e7a0 100644 --- a/extras/vom/vom/CMakeLists.txt +++ b/extras/vom/vom/CMakeLists.txt @@ -164,6 +164,7 @@ list(APPEND VOM_SOURCES sub_interface.cpp tap_interface.cpp tap_interface_cmds.cpp + vxlan_gbp_tunnel_cmds.cpp vxlan_tunnel_cmds.cpp vxlan_tunnel.cpp ) diff --git a/extras/vom/vom/gbp_bridge_domain.cpp b/extras/vom/vom/gbp_bridge_domain.cpp index 6cad1954e5d..92d1a13062b 100644 --- a/extras/vom/vom/gbp_bridge_domain.cpp +++ b/extras/vom/vom/gbp_bridge_domain.cpp @@ -31,6 +31,14 @@ gbp_bridge_domain::event_handler gbp_bridge_domain::m_evh; /** * Construct a new object matching the desried state */ +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const interface& bvi) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_bvi(bvi.singular()) +{ +} + gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd) : m_id(bd.id()) , m_bd(bd.singular()) @@ -47,9 +55,31 @@ gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, { } +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const std::shared_ptr bvi, + const std::shared_ptr uu_fwd) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_bvi(bvi->singular()) + , m_uu_fwd(uu_fwd->singular()) +{ +} + +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const interface& bvi, + const std::shared_ptr uu_fwd) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_bvi(bvi.singular()) + , m_uu_fwd(uu_fwd->singular()) +{ +} + gbp_bridge_domain::gbp_bridge_domain(const gbp_bridge_domain& bd) : m_id(bd.id()) , m_bd(bd.m_bd) + , m_bvi(bd.m_bvi) + , m_uu_fwd(bd.m_uu_fwd) { } @@ -65,6 +95,18 @@ gbp_bridge_domain::id() const return (m_bd->id()); } +const std::shared_ptr +gbp_bridge_domain::get_bridge_domain() +{ + return m_bd; +} + +const std::shared_ptr +gbp_bridge_domain::get_bvi() +{ + return m_bvi; +} + bool gbp_bridge_domain::operator==(const gbp_bridge_domain& b) const { @@ -121,7 +163,14 @@ std::string gbp_bridge_domain::to_string() const { std::ostringstream s; - s << "gbp-bridge-domain:[" << m_bd->to_string() << "]"; + s << "gbp-bridge-domain:[" << m_bd->to_string(); + + if (m_bvi) + s << " bvi:" << m_bvi->to_string(); + if (m_uu_fwd) + s << " uu-fwd:" << m_uu_fwd->to_string(); + + s << "]"; return (s.str()); } @@ -187,11 +236,11 @@ gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key) interface::find(payload.bd.bvi_sw_if_index); if (uu_fwd && bvi) { - gbp_bridge_domain bd(payload.bd.bd_id, *bvi, *uu_fwd); + gbp_bridge_domain bd(payload.bd.bd_id, bvi, uu_fwd); OM::commit(key, bd); VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); - } else { - gbp_bridge_domain bd(payload.bd.bd_id); + } else if (bvi) { + gbp_bridge_domain bd(payload.bd.bd_id, *bvi); OM::commit(key, bd); VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); } diff --git a/extras/vom/vom/gbp_bridge_domain.hpp b/extras/vom/vom/gbp_bridge_domain.hpp index 0d7d58ecc05..031510aa461 100644 --- a/extras/vom/vom/gbp_bridge_domain.hpp +++ b/extras/vom/vom/gbp_bridge_domain.hpp @@ -37,11 +37,17 @@ public: /** * Construct a GBP bridge_domain */ + gbp_bridge_domain(const bridge_domain& bd, const interface& bvi); gbp_bridge_domain(const bridge_domain& bd); - gbp_bridge_domain(const bridge_domain& bd, const interface& bvi, const interface& uu_fwd); + gbp_bridge_domain(const bridge_domain& bd, + const std::shared_ptr bvi, + const std::shared_ptr uu_fwd); + gbp_bridge_domain(const bridge_domain& bd, + const interface& bvi, + const std::shared_ptr uu_fwd); /** * Copy Construct @@ -93,6 +99,9 @@ public: */ std::string to_string() const; + const std::shared_ptr get_bridge_domain(); + const std::shared_ptr get_bvi(); + private: /** * Class definition for listeners to OM events diff --git a/extras/vom/vom/gbp_endpoint_group.cpp b/extras/vom/vom/gbp_endpoint_group.cpp index bd68d77a064..78fdeeab1c8 100644 --- a/extras/vom/vom/gbp_endpoint_group.cpp +++ b/extras/vom/vom/gbp_endpoint_group.cpp @@ -36,6 +36,17 @@ gbp_endpoint_group::gbp_endpoint_group(epg_id_t epg_id, { } +gbp_endpoint_group::gbp_endpoint_group(epg_id_t epg_id, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd) + : m_hw(false) + , m_epg_id(epg_id) + , m_itf() + , m_rd(rd.singular()) + , m_bd(bd.singular()) +{ +} + gbp_endpoint_group::gbp_endpoint_group(const gbp_endpoint_group& epg) : m_hw(epg.m_hw) , m_epg_id(epg.m_epg_id) @@ -84,7 +95,8 @@ gbp_endpoint_group::replay() { if (m_hw) { HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( - m_hw, m_epg_id, m_bd->id(), m_rd->id(), m_itf->handle())); + m_hw, m_epg_id, m_bd->id(), m_rd->id(), + (m_itf ? m_itf->handle() : handle_t::INVALID))); } } @@ -93,8 +105,8 @@ gbp_endpoint_group::to_string() const { std::ostringstream s; s << "gbp-endpoint-group:[" - << "epg:" << m_epg_id << ", " << m_itf->to_string() << ", " - << m_bd->to_string() << ", " << m_rd->to_string() << "]"; + << "epg:" << m_epg_id << ", " << (m_itf ? m_itf->to_string() : "NULL") + << ", " << m_bd->to_string() << ", " << m_rd->to_string() << "]"; return (s.str()); } @@ -104,7 +116,8 @@ gbp_endpoint_group::update(const gbp_endpoint_group& r) { if (rc_t::OK != m_hw.rc()) { HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( - m_hw, m_epg_id, m_bd->id(), m_rd->id(), m_itf->handle())); + m_hw, m_epg_id, m_bd->id(), m_rd->id(), + (m_itf ? m_itf->handle() : handle_t::INVALID))); } } @@ -132,6 +145,18 @@ gbp_endpoint_group::dump(std::ostream& os) db_dump(m_db, os); } +const std::shared_ptr +gbp_endpoint_group::get_route_domain() +{ + return m_rd; +} + +const std::shared_ptr +gbp_endpoint_group::get_bridge_domain() +{ + return m_bd; +} + gbp_endpoint_group::event_handler::event_handler() { OM::register_listener(this); diff --git a/extras/vom/vom/gbp_endpoint_group.hpp b/extras/vom/vom/gbp_endpoint_group.hpp index d609b89fe2f..ed0d8d93cde 100644 --- a/extras/vom/vom/gbp_endpoint_group.hpp +++ b/extras/vom/vom/gbp_endpoint_group.hpp @@ -102,6 +102,9 @@ public: */ epg_id_t id() const; + const std::shared_ptr get_route_domain(); + const std::shared_ptr get_bridge_domain(); + private: /** * Class definition for listeners to OM events diff --git a/extras/vom/vom/gbp_route_domain.cpp b/extras/vom/vom/gbp_route_domain.cpp index 2786297b0c8..46208b77bf3 100644 --- a/extras/vom/vom/gbp_route_domain.cpp +++ b/extras/vom/vom/gbp_route_domain.cpp @@ -34,6 +34,8 @@ gbp_route_domain::event_handler gbp_route_domain::m_evh; gbp_route_domain::gbp_route_domain(const gbp_route_domain& rd) : m_id(rd.id()) , m_rd(rd.m_rd) + , m_ip4_uu_fwd(rd.m_ip4_uu_fwd) + , m_ip6_uu_fwd(rd.m_ip6_uu_fwd) { } @@ -46,6 +48,15 @@ gbp_route_domain::gbp_route_domain(const route_domain& rd, , m_ip6_uu_fwd(ip6_uu_fwd.singular()) { } +gbp_route_domain::gbp_route_domain(const route_domain& rd, + const std::shared_ptr ip4_uu_fwd, + const std::shared_ptr ip6_uu_fwd) + : m_id(rd.table_id()) + , m_rd(rd.singular()) + , m_ip4_uu_fwd(ip4_uu_fwd->singular()) + , m_ip6_uu_fwd(ip6_uu_fwd->singular()) +{ +} gbp_route_domain::gbp_route_domain(const route_domain& rd) : m_id(rd.table_id()) @@ -65,6 +76,12 @@ gbp_route_domain::id() const return (m_rd->table_id()); } +const std::shared_ptr +gbp_route_domain::get_route_domain() +{ + return m_rd; +} + bool gbp_route_domain::operator==(const gbp_route_domain& b) const { @@ -121,7 +138,14 @@ std::string gbp_route_domain::to_string() const { std::ostringstream s; - s << "gbp-route-domain:[" << m_rd->to_string() << "]"; + s << "gbp-route-domain:[" << m_rd->to_string(); + + if (m_ip4_uu_fwd) + s << " v4-uu:" << m_ip4_uu_fwd->to_string(); + if (m_ip6_uu_fwd) + s << " v6-uu:" << m_ip6_uu_fwd->to_string(); + + s << "]"; return (s.str()); } diff --git a/extras/vom/vom/gbp_route_domain.hpp b/extras/vom/vom/gbp_route_domain.hpp index 6dc37d1981e..ff13d1d6e05 100644 --- a/extras/vom/vom/gbp_route_domain.hpp +++ b/extras/vom/vom/gbp_route_domain.hpp @@ -42,6 +42,9 @@ public: gbp_route_domain(const route_domain& rd, const interface& ip4_uu_fwd, const interface& ip6_uu_fwd); + gbp_route_domain(const route_domain& rd, + const std::shared_ptr ip4_uu_fwd, + const std::shared_ptr ip6_uu_fwd); /** * Copy Construct @@ -93,6 +96,8 @@ public: */ std::string to_string() const; + const std::shared_ptr get_route_domain(); + private: /** * Class definition for listeners to OM events diff --git a/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp b/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp new file mode 100644 index 00000000000..14470806665 --- /dev/null +++ b/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp @@ -0,0 +1,158 @@ +/* + * 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. + */ + +#include "vom/vxlan_gbp_tunnel_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_VXLAN_GBP_API_JSON; + +namespace VOM { +namespace vxlan_gbp_tunnel_cmds { + +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep) + : interface::create_cmd(item, name) + , m_ep(ep) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.is_add = 1; + + to_api(m_ep.src, payload.tunnel.src); + to_api(m_ep.src, payload.tunnel.dst); + payload.tunnel.mcast_sw_if_index = ~0; + payload.tunnel.encap_table_id = 0; + payload.tunnel.vni = m_ep.vni; + + VAPI_CALL(req.execute()); + + wait(); + + if (rc_t::OK == m_hw_item.rc()) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-gbp-tunnel-create: " << m_hw_item.to_string() << m_ep.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const vxlan_tunnel::endpoint_t& ep) + : interface::delete_cmd(item) + , m_ep(ep) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto payload = req.get_request().get_payload(); + + payload.is_add = 0; + + to_api(m_ep.src, payload.tunnel.src); + to_api(m_ep.src, payload.tunnel.dst); + payload.tunnel.mcast_sw_if_index = ~0; + payload.tunnel.encap_table_id = 0; + payload.tunnel.vni = m_ep.vni; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-gbp-tunnel-delete: " << m_hw_item.to_string() << m_ep.to_string(); + + 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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("vxlan-gbp-tunnel-dump"); +} +} // namespace vxlan_tunnel_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp b/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp new file mode 100644 index 00000000000..34407f61bda --- /dev/null +++ b/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp @@ -0,0 +1,134 @@ +/* + * 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_VXLAN_GBP_TUNNEL_CMDS_H__ +#define __VOM_VXLAN_GBP_TUNNEL_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/vxlan_tunnel.hpp" + +#include + +namespace VOM { +namespace vxlan_gbp_tunnel_cmds { + +/** + * A Command class that creates an VXLAN tunnel + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Create command constructor taking HW item to update and the + * endpoint values + */ + create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep); + + /** + * 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 create_cmd& i) const; + +private: + /** + * Enpoint values of the tunnel to be created + */ + const vxlan_tunnel::endpoint_t m_ep; +}; + +/** + * A functor class that creates an VXLAN tunnel + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * delete command constructor taking HW item to update and the + * endpoint values + */ + delete_cmd(HW::item& item, const vxlan_tunnel::endpoint_t& ep); + + /** + * 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 delete_cmd& i) const; + +private: + /** + * Enpoint values of the tunnel to be deleted + */ + const vxlan_tunnel::endpoint_t m_ep; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(); + + /** + * 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; +}; + +}; // namespace vxlan_tunnel_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/vom/vom/vxlan_tunnel.cpp b/extras/vom/vom/vxlan_tunnel.cpp index 9e7c01d01c6..2abff7615eb 100644 --- a/extras/vom/vom/vxlan_tunnel.cpp +++ b/extras/vom/vom/vxlan_tunnel.cpp @@ -14,8 +14,10 @@ */ #include "vom/vxlan_tunnel.hpp" +#include "vom/api_types.hpp" #include "vom/logger.hpp" #include "vom/singular_db_funcs.hpp" +#include "vom/vxlan_gbp_tunnel_cmds.hpp" #include "vom/vxlan_tunnel_cmds.hpp" namespace VOM { @@ -23,12 +25,14 @@ const std::string VXLAN_TUNNEL_NAME = "vxlan-tunnel-itf"; vxlan_tunnel::event_handler vxlan_tunnel::m_evh; -/** - * A DB of all vxlan_tunnels - * this does not register as a listener for replay events, since the tunnels - * are also in the base-class interface DB and so will be poked from there. - */ -singular_db vxlan_tunnel::m_db; +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::STANDARD(0, "standard"); +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GBP(0, "GBP"); +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GPE(0, "GPE"); + +vxlan_tunnel::mode_t::mode_t(int v, const std::string s) + : enum_base(v, s) +{ +} vxlan_tunnel::endpoint_t::endpoint_t(const boost::asio::ip::address& src, const boost::asio::ip::address& dst, @@ -52,19 +56,6 @@ vxlan_tunnel::endpoint_t::operator==(const endpoint_t& other) const return ((src == other.src) && (dst == other.dst) && (vni == other.vni)); } -bool -vxlan_tunnel::endpoint_t::operator<(const vxlan_tunnel::endpoint_t& o) const -{ - if (src < o.src) - return true; - if (dst < o.dst) - return true; - if (vni < o.vni) - return true; - - return false; -} - std::string vxlan_tunnel::endpoint_t::to_string() const { @@ -77,39 +68,36 @@ vxlan_tunnel::endpoint_t::to_string() const return (s.str()); } -std::ostream& -operator<<(std::ostream& os, const vxlan_tunnel::endpoint_t& ep) -{ - os << ep.to_string(); - - return (os); -} - std::string vxlan_tunnel::mk_name(const boost::asio::ip::address& src, const boost::asio::ip::address& dst, + const mode_t& mode, uint32_t vni) { std::ostringstream s; - s << VXLAN_TUNNEL_NAME << "-" << src << "-" << dst << ":" << vni; + s << VXLAN_TUNNEL_NAME << "-" << mode.to_string() << "-" << src << "-" << dst + << ":" << vni; return (s.str()); } vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, const boost::asio::ip::address& dst, - uint32_t vni) - : interface(mk_name(src, dst, vni), + uint32_t vni, + const mode_t& mode) + : interface(mk_name(src, dst, mode, vni), interface::type_t::VXLAN, interface::admin_state_t::UP) , m_tep(src, dst, vni) + , m_mode(mode) { } vxlan_tunnel::vxlan_tunnel(const vxlan_tunnel& o) : interface(o) , m_tep(o.m_tep) + , m_mode(o.m_mode) { } @@ -119,11 +107,20 @@ vxlan_tunnel::handle() const return (m_hdl.data()); } +std::shared_ptr +vxlan_tunnel::find(const interface::key_t& k) +{ + return std::dynamic_pointer_cast(m_db.find(k)); +} + void vxlan_tunnel::sweep() { if (m_hdl) { - HW::enqueue(new vxlan_tunnel_cmds::delete_cmd(m_hdl, m_tep)); + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::delete_cmd(m_hdl, m_tep)); + else if (mode_t::GBP == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::delete_cmd(m_hdl, m_tep)); } HW::write(); } @@ -132,26 +129,25 @@ void vxlan_tunnel::replay() { if (m_hdl) { - HW::enqueue(new vxlan_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); + else if (mode_t::GBP == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); } } vxlan_tunnel::~vxlan_tunnel() { sweep(); - - /* - * release from both DBs - */ release(); - m_db.release(m_tep, this); } std::string vxlan_tunnel::to_string() const { std::ostringstream s; - s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_tep.to_string(); + s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_mode.to_string() << " " + << m_tep.to_string(); return (s.str()); } @@ -163,42 +159,23 @@ vxlan_tunnel::update(const vxlan_tunnel& desired) * the desired state is always that the interface should be created */ if (!m_hdl) { - HW::enqueue(new vxlan_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); + else if (mode_t::GBP == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd(m_hdl, name(), m_tep)); } } -std::shared_ptr -vxlan_tunnel::find_or_add(const vxlan_tunnel& temp) -{ - /* - * a VXLAN tunnel needs to be in both the interface-find-by-name - * and the vxlan_tunnel-find-by-endpoint singular databases - */ - std::shared_ptr sp; - - sp = m_db.find_or_add(temp.m_tep, temp); - - interface::m_db.add(temp.name(), sp); - - return (sp); -} - std::shared_ptr vxlan_tunnel::singular() const { - return (find_or_add(*this)); + return std::dynamic_pointer_cast(singular_i()); } std::shared_ptr vxlan_tunnel::singular_i() const { - return find_or_add(*this); -} - -void -vxlan_tunnel::dump(std::ostream& os) -{ - db_dump(m_db, os); + return m_db.find_or_add(key(), *this); } void @@ -207,27 +184,51 @@ vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key) /* * dump VPP current states */ - std::shared_ptr cmd = - std::make_shared(); + { + std::shared_ptr cmd = + std::make_shared(); - HW::enqueue(cmd); - HW::write(); + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + handle_t hdl(payload.sw_if_index); + boost::asio::ip::address src = + from_bytes(payload.is_ipv6, payload.src_address); + boost::asio::ip::address dst = + from_bytes(payload.is_ipv6, payload.dst_address); + + std::shared_ptr vt = + vxlan_tunnel(src, dst, payload.vni).singular(); + vt->set(hdl); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); + + OM::commit(key, *vt); + } + } + { + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - handle_t hdl(payload.sw_if_index); - boost::asio::ip::address src = - from_bytes(payload.is_ipv6, payload.src_address); - boost::asio::ip::address dst = - from_bytes(payload.is_ipv6, payload.dst_address); + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + handle_t hdl(payload.tunnel.sw_if_index); + boost::asio::ip::address src = from_api(payload.tunnel.src); + boost::asio::ip::address dst = from_api(payload.tunnel.dst); - std::shared_ptr vt = - vxlan_tunnel(src, dst, payload.vni).singular(); - vt->set(hdl); + std::shared_ptr vt = + vxlan_tunnel(src, dst, payload.tunnel.vni, mode_t::GBP).singular(); + vt->set(hdl); - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); - OM::commit(key, *vt); + OM::commit(key, *vt); + } } } diff --git a/extras/vom/vom/vxlan_tunnel.hpp b/extras/vom/vom/vxlan_tunnel.hpp index a0b3e9afa3e..136f0380e6d 100644 --- a/extras/vom/vom/vxlan_tunnel.hpp +++ b/extras/vom/vom/vxlan_tunnel.hpp @@ -49,11 +49,6 @@ public: const boost::asio::ip::address& dst, uint32_t vni); - /** - * less-than operator for map storage - */ - bool operator<(const endpoint_t& o) const; - /** * Comparison operator */ @@ -80,12 +75,28 @@ public: uint32_t vni; }; + /** + * mode for the tunnel + */ + struct mode_t : public enum_base + { + ~mode_t() = default; + const static mode_t STANDARD; + const static mode_t GBP; + const static mode_t GPE; + + private: + mode_t(int v, const std::string s); + mode_t() = default; + }; + /** * Construct a new object matching the desried state */ vxlan_tunnel(const boost::asio::ip::address& src, const boost::asio::ip::address& dst, - uint32_t vni); + uint32_t vni, + const mode_t& mode = mode_t::STANDARD); /** * Construct a new object matching the desried state with a handle @@ -94,7 +105,8 @@ public: vxlan_tunnel(const handle_t& hdl, const boost::asio::ip::address& src, const boost::asio::ip::address& dst, - uint32_t vni); + uint32_t vni, + const mode_t& mode = mode_t::STANDARD); /* * Destructor @@ -122,9 +134,9 @@ public: const handle_t& handle() const; /** - * Dump all L3Configs into the stream provided + * Fond the singular instance of the interface in the DB by key */ - static void dump(std::ostream& os); + static std::shared_ptr find(const interface::key_t& k); private: /** @@ -204,15 +216,16 @@ private: endpoint_t m_tep; /** - * A map of all VLAN tunnela against thier key + * The tunnel mode */ - static singular_db m_db; + mode_t m_mode; /** * Construct a unique name for the tunnel */ static std::string mk_name(const boost::asio::ip::address& src, const boost::asio::ip::address& dst, + const mode_t& mode, uint32_t vni); }; diff --git a/test/ext/vom_test.cpp b/test/ext/vom_test.cpp index b417edeb2c2..f17d749f3f3 100644 --- a/test/ext/vom_test.cpp +++ b/test/ext/vom_test.cpp @@ -98,7 +98,7 @@ class MockListener : public interface::event_listener, void handle_interface_stat(interface_cmds::stats_enable_cmd *cmd) { } - void handle_interface_event(interface_cmds::events_cmd *cmd) + void handle_interface_event(std::vector events) { } }; -- 2.16.6