From 160c923f99c2adc103495fab1bfcefe965fe7fb8 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 19 Jun 2019 06:25:56 -0700 Subject: [PATCH] gbp: VRF scoped contracts Type: feature Change-Id: I01772cfc3a0118a5c49bf346339788824e6931b2 Signed-off-by: Neale Ranns --- extras/vom/CMakeLists.txt | 1 + extras/vom/vom/CMakeLists.txt | 2 + extras/vom/vom/gbp_bridge_domain.cpp | 25 +++- extras/vom/vom/gbp_bridge_domain.hpp | 7 +- extras/vom/vom/gbp_bridge_domain_cmds.cpp | 8 +- extras/vom/vom/gbp_bridge_domain_cmds.hpp | 2 + extras/vom/vom/gbp_contract.cpp | 35 +++--- extras/vom/vom/gbp_contract.hpp | 12 +- extras/vom/vom/gbp_contract_cmds.cpp | 11 +- extras/vom/vom/gbp_contract_cmds.hpp | 8 +- extras/vom/vom/gbp_endpoint_group.hpp | 7 +- extras/vom/vom/gbp_route_domain.cpp | 32 ++--- extras/vom/vom/gbp_route_domain.hpp | 6 +- extras/vom/vom/gbp_route_domain_cmds.cpp | 7 +- extras/vom/vom/gbp_route_domain_cmds.hpp | 2 + extras/vom/vom/gbp_types.hpp | 40 +++++++ src/plugins/gbp/gbp.api | 5 + src/plugins/gbp/gbp_api.c | 13 +- src/plugins/gbp/gbp_api_print.h | 2 + src/plugins/gbp/gbp_bridge_domain.c | 26 +++- src/plugins/gbp/gbp_bridge_domain.h | 15 +++ src/plugins/gbp/gbp_contract.c | 29 +++-- src/plugins/gbp/gbp_contract.h | 11 +- src/plugins/gbp/gbp_endpoint.c | 1 + src/plugins/gbp/gbp_policy_dpo.c | 28 +++-- src/plugins/gbp/gbp_policy_dpo.h | 6 + src/plugins/gbp/gbp_policy_node.c | 24 ++-- src/plugins/gbp/gbp_route_domain.c | 18 ++- src/plugins/gbp/gbp_route_domain.h | 3 + src/plugins/gbp/gbp_subnet.c | 2 + src/plugins/gbp/gbp_types.h | 1 + test/test_gbp.py | 190 +++++++++++++++++------------- test/vpp_papi_provider.py | 7 +- 33 files changed, 413 insertions(+), 173 deletions(-) create mode 100644 extras/vom/vom/gbp_types.hpp diff --git a/extras/vom/CMakeLists.txt b/extras/vom/CMakeLists.txt index 4853196b5fe..3a32117882a 100644 --- a/extras/vom/CMakeLists.txt +++ b/extras/vom/CMakeLists.txt @@ -26,6 +26,7 @@ execute_process( OUTPUT_STRIP_TRAILING_WHITESPACE ) +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) set(CMAKE_INSTALL_MESSAGE NEVER) diff --git a/extras/vom/vom/CMakeLists.txt b/extras/vom/vom/CMakeLists.txt index 26dd3e46574..144749968d5 100644 --- a/extras/vom/vom/CMakeLists.txt +++ b/extras/vom/vom/CMakeLists.txt @@ -94,6 +94,7 @@ if(GBP_FILE) gbp_rule.cpp gbp_subnet_cmds.cpp gbp_subnet.cpp + gbp_types.hpp gbp_vxlan.cpp gbp_vxlan_cmds.cpp ) @@ -220,6 +221,7 @@ if(GBP_FILE) gbp_route_domain.hpp gbp_rule.hpp gbp_subnet.hpp + gbp_types.hpp gbp_vxlan.hpp ) endif() diff --git a/extras/vom/vom/gbp_bridge_domain.cpp b/extras/vom/vom/gbp_bridge_domain.cpp index cfa07681545..3e015c379c2 100644 --- a/extras/vom/vom/gbp_bridge_domain.cpp +++ b/extras/vom/vom/gbp_bridge_domain.cpp @@ -51,10 +51,12 @@ 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 gbp_route_domain& rd, const interface& bvi, const flags_t& flags) : m_id(bd.id()) , m_bd(bd.singular()) + , m_rd(rd.singular()) , m_bvi(bvi.singular()) , m_uu_fwd() , m_bm_flood() @@ -63,12 +65,14 @@ gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, } gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const interface& bvi, const interface& uu_fwd, const interface& bm_flood, const flags_t& flags) : m_id(bd.id()) , m_bd(bd.singular()) + , m_rd(rd.singular()) , m_bvi(bvi.singular()) , m_uu_fwd(uu_fwd.singular()) , m_bm_flood(bm_flood.singular()) @@ -77,12 +81,14 @@ gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, } gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const std::shared_ptr bvi, const std::shared_ptr uu_fwd, const std::shared_ptr bm_flood, const flags_t& flags) : m_id(bd.id()) , m_bd(bd.singular()) + , m_rd(rd.singular()) , m_bvi(bvi) , m_uu_fwd(uu_fwd) , m_bm_flood(bm_flood) @@ -97,12 +103,14 @@ gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, } gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const interface& bvi, const std::shared_ptr uu_fwd, const std::shared_ptr bm_flood, const flags_t& flags) : m_id(bd.id()) , m_bd(bd.singular()) + , m_rd(rd.singular()) , m_bvi(bvi.singular()) , m_uu_fwd(uu_fwd) , m_bm_flood(bm_flood) @@ -117,6 +125,7 @@ gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, gbp_bridge_domain::gbp_bridge_domain(const gbp_bridge_domain& bd) : m_id(bd.id()) , m_bd(bd.m_bd) + , m_rd(bd.m_rd) , m_bvi(bd.m_bvi) , m_uu_fwd(bd.m_uu_fwd) , m_bm_flood(bd.m_bm_flood) @@ -191,7 +200,7 @@ gbp_bridge_domain::replay() { if (rc_t::OK == m_id.rc()) { HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( - m_id, (m_bvi ? m_bvi->handle() : handle_t::INVALID), + m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); } @@ -236,7 +245,7 @@ gbp_bridge_domain::update(const gbp_bridge_domain& desired) */ if (rc_t::OK != m_id.rc()) { HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( - m_id, (m_bvi ? m_bvi->handle() : handle_t::INVALID), + m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); } @@ -281,6 +290,8 @@ gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key) interface::find(payload.bd.bm_flood_sw_if_index); std::shared_ptr bvi = interface::find(payload.bd.bvi_sw_if_index); + std::shared_ptr grd = + gbp_route_domain::find(payload.bd.rd_id); flags_t flags = gbp_bridge_domain::flags_t::NONE; if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN) @@ -292,12 +303,13 @@ gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key) if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP) flags |= gbp_bridge_domain::flags_t::UCAST_ARP; - if (uu_fwd && bm_flood && bvi) { - gbp_bridge_domain bd(payload.bd.bd_id, bvi, uu_fwd, bm_flood, flags); + if (uu_fwd && bm_flood && bvi && grd) { + gbp_bridge_domain bd(payload.bd.bd_id, *grd, bvi, uu_fwd, bm_flood, + flags); OM::commit(key, bd); VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); } else if (bvi) { - gbp_bridge_domain bd(payload.bd.bd_id, *bvi, flags); + gbp_bridge_domain bd(payload.bd.bd_id, *grd, *bvi, flags); OM::commit(key, bd); VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); } else { @@ -323,7 +335,8 @@ gbp_bridge_domain::event_handler::handle_replay() dependency_t gbp_bridge_domain::event_handler::order() const { - return (dependency_t::VIRTUAL_TABLE); + /* order after gbp-route-domains */ + return (dependency_t::ACL); } void diff --git a/extras/vom/vom/gbp_bridge_domain.hpp b/extras/vom/vom/gbp_bridge_domain.hpp index 44cf29956ef..264f8b3c031 100644 --- a/extras/vom/vom/gbp_bridge_domain.hpp +++ b/extras/vom/vom/gbp_bridge_domain.hpp @@ -17,9 +17,9 @@ #define __VOM_GBP_BRIDGE_DOMAIN_H__ #include "vom/bridge_domain.hpp" +#include "vom/gbp_route_domain.hpp" #include "vom/interface.hpp" #include "vom/singular_db.hpp" -#include "vom/types.hpp" namespace VOM { @@ -53,19 +53,23 @@ public: * Construct a GBP bridge_domain */ gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const interface& bvi, const flags_t& flags = flags_t::NONE); gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const interface& bvi, const interface& uu_fwd, const interface& bm_flood, const flags_t& flags = flags_t::NONE); gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const std::shared_ptr bvi, const std::shared_ptr uu_fwd, const std::shared_ptr bm_flood, const flags_t& flags = flags_t::NONE); gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, const interface& bvi, const std::shared_ptr uu_fwd, const std::shared_ptr bm_flood, @@ -192,6 +196,7 @@ private: HW::item m_id; std::shared_ptr m_bd; + std::shared_ptr m_rd; std::shared_ptr m_bvi; std::shared_ptr m_uu_fwd; std::shared_ptr m_bm_flood; diff --git a/extras/vom/vom/gbp_bridge_domain_cmds.cpp b/extras/vom/vom/gbp_bridge_domain_cmds.cpp index 082bd4bb48d..05064df6269 100644 --- a/extras/vom/vom/gbp_bridge_domain_cmds.cpp +++ b/extras/vom/vom/gbp_bridge_domain_cmds.cpp @@ -19,11 +19,13 @@ namespace VOM { namespace gbp_bridge_domain_cmds { create_cmd::create_cmd(HW::item& item, + u32 rd_id, const handle_t bvi, const handle_t uu_fwd, const handle_t bm_flood, const gbp_bridge_domain::flags_t& flags) : rpc_cmd(item) + , m_rd_id(rd_id) , m_bvi(bvi) , m_uu_fwd(uu_fwd) , m_bm_flood(bm_flood) @@ -35,8 +37,9 @@ bool create_cmd::operator==(const create_cmd& other) const { return ((m_hw_item.data() == other.m_hw_item.data()) && - (m_bvi == other.m_bvi) && (m_uu_fwd == other.m_uu_fwd) && - (m_bm_flood == other.m_bm_flood) && (m_flags == other.m_flags)); + (m_rd_id == other.m_rd_id) && (m_bvi == other.m_bvi) && + (m_uu_fwd == other.m_uu_fwd) && (m_bm_flood == other.m_bm_flood) && + (m_flags == other.m_flags)); } rc_t @@ -47,6 +50,7 @@ create_cmd::issue(connection& con) auto& payload = req.get_request().get_payload(); payload.bd.bd_id = m_hw_item.data(); + payload.bd.rd_id = m_rd_id; payload.bd.bvi_sw_if_index = m_bvi.value(); payload.bd.uu_fwd_sw_if_index = m_uu_fwd.value(); payload.bd.bm_flood_sw_if_index = m_bm_flood.value(); diff --git a/extras/vom/vom/gbp_bridge_domain_cmds.hpp b/extras/vom/vom/gbp_bridge_domain_cmds.hpp index a4fd0d51b45..6dbe6dcdfed 100644 --- a/extras/vom/vom/gbp_bridge_domain_cmds.hpp +++ b/extras/vom/vom/gbp_bridge_domain_cmds.hpp @@ -35,6 +35,7 @@ public: * Constructor */ create_cmd(HW::item& item, + u32 rd_id, const handle_t bvi, const handle_t uu_fwd, const handle_t bm_flood, @@ -55,6 +56,7 @@ public: bool operator==(const create_cmd& i) const; private: + u32 m_rd_id; const handle_t m_bvi; const handle_t m_uu_fwd; const handle_t m_bm_flood; diff --git a/extras/vom/vom/gbp_contract.cpp b/extras/vom/vom/gbp_contract.cpp index c95c2e8008e..8fcef02da24 100644 --- a/extras/vom/vom/gbp_contract.cpp +++ b/extras/vom/vom/gbp_contract.cpp @@ -24,12 +24,14 @@ singular_db gbp_contract::m_db; gbp_contract::event_handler gbp_contract::m_evh; -gbp_contract::gbp_contract(sclass_t sclass, +gbp_contract::gbp_contract(scope_t scope, + sclass_t sclass, sclass_t dclass, const ACL::l3_list& acl, const gbp_rules_t& rules, const ethertype_set_t& allowed_ethertypes) : m_hw(false) + , m_scope(scope) , m_sclass(sclass) , m_dclass(dclass) , m_acl(acl.singular()) @@ -40,6 +42,7 @@ gbp_contract::gbp_contract(sclass_t sclass, gbp_contract::gbp_contract(const gbp_contract& gbpc) : m_hw(gbpc.m_hw) + , m_scope(gbpc.m_scope) , m_sclass(gbpc.m_sclass) , m_dclass(gbpc.m_dclass) , m_acl(gbpc.m_acl) @@ -59,7 +62,7 @@ gbp_contract::~gbp_contract() const gbp_contract::key_t gbp_contract::key() const { - return (std::make_pair(m_sclass, m_dclass)); + return (std::make_tuple(m_scope, m_sclass, m_dclass)); } bool @@ -72,7 +75,8 @@ void gbp_contract::sweep() { if (m_hw) { - HW::enqueue(new gbp_contract_cmds::delete_cmd(m_hw, m_sclass, m_dclass)); + HW::enqueue( + new gbp_contract_cmds::delete_cmd(m_hw, m_scope, m_sclass, m_dclass)); } HW::write(); } @@ -81,9 +85,9 @@ void gbp_contract::replay() { if (m_hw) { - HW::enqueue(new gbp_contract_cmds::create_cmd(m_hw, m_sclass, m_dclass, - m_acl->handle(), m_gbp_rules, - m_allowed_ethertypes)); + HW::enqueue(new gbp_contract_cmds::create_cmd( + m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, + m_allowed_ethertypes)); } } @@ -91,8 +95,8 @@ std::string gbp_contract::to_string() const { std::ostringstream s; - s << "gbp-contract:[{" << m_sclass << ", " << m_dclass << "}, " - << m_acl->to_string(); + s << "gbp-contract:[{" << m_scope << ", " << m_sclass << ", " << m_dclass + << "}, " << m_acl->to_string(); if (m_gbp_rules.size()) { auto it = m_gbp_rules.cbegin(); while (it != m_gbp_rules.cend()) { @@ -115,9 +119,9 @@ gbp_contract::update(const gbp_contract& r) * create the table if it is not yet created */ if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_contract_cmds::create_cmd(m_hw, m_sclass, m_dclass, - m_acl->handle(), m_gbp_rules, - m_allowed_ethertypes)); + HW::enqueue(new gbp_contract_cmds::create_cmd( + m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, + m_allowed_ethertypes)); } } @@ -207,10 +211,10 @@ gbp_contract::event_handler::handle_populate(const client_db::key_t& key) allowed_ethertypes.insert(ethertype_t::from_numeric_val(et[i])); } - gbp_contract gbpc(payload.contract.sclass, payload.contract.dclass, *acl, - rules, allowed_ethertypes); + gbp_contract gbpc(payload.contract.scope, payload.contract.sclass, + payload.contract.dclass, *acl, rules, + allowed_ethertypes); OM::commit(key, gbpc); - VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string(); } else { VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index; @@ -233,7 +237,8 @@ gbp_contract::event_handler::show(std::ostream& os) std::ostream& operator<<(std::ostream& os, const gbp_contract::key_t& key) { - os << "{ " << key.first << "," << key.second << "}"; + os << "{ " << std::get<0>(key) << "," << std::get<1>(key) << ", " + << std::get<2>(key) << "}"; return (os); } diff --git a/extras/vom/vom/gbp_contract.hpp b/extras/vom/vom/gbp_contract.hpp index 2e8f9d0bc26..caf5a3c5a0e 100644 --- a/extras/vom/vom/gbp_contract.hpp +++ b/extras/vom/vom/gbp_contract.hpp @@ -17,8 +17,8 @@ #define __VOM_GBP_CONTRACT_H__ #include "vom/acl_l3_list.hpp" -#include "vom/gbp_endpoint.hpp" #include "vom/gbp_rule.hpp" +#include "vom/gbp_types.hpp" #include "vom/interface.hpp" #include "vom/singular_db.hpp" #include "vom/types.hpp" @@ -39,7 +39,7 @@ public: /** * The key for a contract is the pair of EPG-IDs */ - typedef std::pair key_t; + typedef std::tuple key_t; /** * A set of allowed ethertypes @@ -49,7 +49,8 @@ public: /** * Construct a GBP contract */ - gbp_contract(sclass_t sclass, + gbp_contract(scope_t scope, + sclass_t sclass, sclass_t dclass, const ACL::l3_list& acl, const gbp_rules_t& gpb_rules, @@ -166,6 +167,11 @@ private: */ HW::item m_hw; + /* + * The scope of the contract + */ + scope_t m_scope; + /** * The source EPG ID */ diff --git a/extras/vom/vom/gbp_contract_cmds.cpp b/extras/vom/vom/gbp_contract_cmds.cpp index 6aed9998e1e..1bb06bdaa69 100644 --- a/extras/vom/vom/gbp_contract_cmds.cpp +++ b/extras/vom/vom/gbp_contract_cmds.cpp @@ -20,12 +20,14 @@ namespace VOM { namespace gbp_contract_cmds { create_cmd::create_cmd(HW::item& item, + scope_t scope, sclass_t sclass, sclass_t dclass, const handle_t& acl, const gbp_contract::gbp_rules_t& gbp_rules, const gbp_contract::ethertype_set_t& allowed_ethertypes) : rpc_cmd(item) + , m_scope(scope) , m_sclass(sclass) , m_dclass(dclass) , m_acl(acl) @@ -38,7 +40,8 @@ bool create_cmd::operator==(const create_cmd& other) const { return ((m_acl == other.m_acl) && (m_sclass == other.m_sclass) && - (m_dclass == other.m_dclass) && (m_gbp_rules == other.m_gbp_rules) && + (m_scope == other.m_scope) && (m_dclass == other.m_dclass) && + (m_gbp_rules == other.m_gbp_rules) && (m_allowed_ethertypes == other.m_allowed_ethertypes)); } @@ -55,6 +58,7 @@ create_cmd::issue(connection& con) auto& payload = req.get_request().get_payload(); payload.is_add = 1; payload.contract.acl_index = m_acl.value(); + payload.contract.scope = m_scope; payload.contract.sclass = m_sclass; payload.contract.dclass = m_dclass; payload.contract.n_rules = n_rules; @@ -117,9 +121,11 @@ create_cmd::to_string() const } delete_cmd::delete_cmd(HW::item& item, + scope_t scope, sclass_t sclass, sclass_t dclass) : rpc_cmd(item) + , m_scope(scope) , m_sclass(sclass) , m_dclass(dclass) { @@ -139,6 +145,7 @@ delete_cmd::issue(connection& con) auto& payload = req.get_request().get_payload(); payload.is_add = 0; payload.contract.acl_index = ~0; + payload.contract.scope = m_scope; payload.contract.sclass = m_sclass; payload.contract.dclass = m_dclass; @@ -151,7 +158,7 @@ std::string delete_cmd::to_string() const { std::ostringstream s; - s << "gbp-contract-delete: " << m_hw_item.to_string() + s << "gbp-contract-delete: " << m_hw_item.to_string() << " scope: " << m_scope << " sclass:" << m_sclass << " dclass:" << m_dclass; return (s.str()); diff --git a/extras/vom/vom/gbp_contract_cmds.hpp b/extras/vom/vom/gbp_contract_cmds.hpp index 3b3fab97a70..d9fe1d74e37 100644 --- a/extras/vom/vom/gbp_contract_cmds.hpp +++ b/extras/vom/vom/gbp_contract_cmds.hpp @@ -35,6 +35,7 @@ public: * Constructor */ create_cmd(HW::item& item, + scope_t scope, sclass_t sclass, sclass_t dclass, const handle_t& acl, @@ -57,6 +58,7 @@ public: bool operator==(const create_cmd& i) const; private: + const scope_t m_scope; const sclass_t m_sclass; const sclass_t m_dclass; const handle_t m_acl; @@ -74,7 +76,10 @@ public: /** * Constructor */ - delete_cmd(HW::item& item, sclass_t sclass, sclass_t dclass); + delete_cmd(HW::item& item, + scope_t scope, + sclass_t sclass, + sclass_t dclass); /** * Issue the command to VPP/HW @@ -92,6 +97,7 @@ public: bool operator==(const delete_cmd& i) const; private: + const scope_t m_scope; const sclass_t m_sclass; const sclass_t m_dclass; }; diff --git a/extras/vom/vom/gbp_endpoint_group.hpp b/extras/vom/vom/gbp_endpoint_group.hpp index 5c061a900b3..e15a1885317 100644 --- a/extras/vom/vom/gbp_endpoint_group.hpp +++ b/extras/vom/vom/gbp_endpoint_group.hpp @@ -22,15 +22,10 @@ #include "vom/gbp_bridge_domain.hpp" #include "vom/gbp_route_domain.hpp" +#include "vom/gbp_types.hpp" namespace VOM { -/** - * EPG IDs are 32 bit integers - */ -typedef uint32_t vnid_t; -typedef uint16_t sclass_t; - /** * A entry in the ARP termination table of a Bridge Domain */ diff --git a/extras/vom/vom/gbp_route_domain.cpp b/extras/vom/vom/gbp_route_domain.cpp index 8f0eae3b3aa..54b51cf88a3 100644 --- a/extras/vom/vom/gbp_route_domain.cpp +++ b/extras/vom/vom/gbp_route_domain.cpp @@ -34,26 +34,31 @@ 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_scope(rd.m_scope) , m_ip4_uu_fwd(rd.m_ip4_uu_fwd) , m_ip6_uu_fwd(rd.m_ip6_uu_fwd) { } gbp_route_domain::gbp_route_domain(const route_domain& rd, + scope_t scope, const interface& ip4_uu_fwd, const interface& ip6_uu_fwd) : m_id(rd.table_id()) , m_rd(rd.singular()) + , m_scope(scope) , 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, + scope_t scope, const std::shared_ptr ip4_uu_fwd, const std::shared_ptr ip6_uu_fwd) : m_id(rd.table_id()) , m_rd(rd.singular()) + , m_scope(scope) , m_ip4_uu_fwd(ip4_uu_fwd) , m_ip6_uu_fwd(ip6_uu_fwd) { @@ -63,9 +68,10 @@ gbp_route_domain::gbp_route_domain(const route_domain& rd, m_ip6_uu_fwd = m_ip6_uu_fwd->singular(); } -gbp_route_domain::gbp_route_domain(const route_domain& rd) +gbp_route_domain::gbp_route_domain(const route_domain& rd, scope_t scope) : m_id(rd.table_id()) , m_rd(rd.singular()) + , m_scope(scope) , m_ip4_uu_fwd() , m_ip6_uu_fwd() { @@ -120,7 +126,7 @@ gbp_route_domain::operator==(const gbp_route_domain& b) const else equal = false; - return ((m_rd->key() == b.m_rd->key()) && equal); + return ((m_rd->key() == b.m_rd->key()) && m_scope == b.m_scope && equal); } void @@ -138,10 +144,10 @@ gbp_route_domain::replay() if (rc_t::OK == m_id.rc()) { if (m_ip4_uu_fwd && m_ip6_uu_fwd) HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); + m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); else - HW::enqueue(new gbp_route_domain_cmds::create_cmd(m_id, handle_t::INVALID, - handle_t::INVALID)); + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); } } @@ -157,7 +163,7 @@ 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() << "scope:" << m_scope; if (m_ip4_uu_fwd) s << " v4-uu:[" << m_ip4_uu_fwd->to_string() << "]"; @@ -178,16 +184,13 @@ gbp_route_domain::find(const key_t& key) void gbp_route_domain::update(const gbp_route_domain& desired) { - /* - * the desired state is always that the interface should be created - */ if (rc_t::OK != m_id.rc()) { if (m_ip4_uu_fwd && m_ip6_uu_fwd) HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); + m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); else - HW::enqueue(new gbp_route_domain_cmds::create_cmd(m_id, handle_t::INVALID, - handle_t::INVALID)); + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); } } @@ -230,11 +233,12 @@ gbp_route_domain::event_handler::handle_populate(const client_db::key_t& key) interface::find(payload.rd.ip4_uu_sw_if_index); if (ip6_uu_fwd && ip4_uu_fwd) { - gbp_route_domain rd(payload.rd.rd_id, *ip4_uu_fwd, *ip6_uu_fwd); + gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope, *ip4_uu_fwd, + *ip6_uu_fwd); OM::commit(key, rd); VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); } else { - gbp_route_domain rd(payload.rd.rd_id); + gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope); OM::commit(key, rd); VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); } diff --git a/extras/vom/vom/gbp_route_domain.hpp b/extras/vom/vom/gbp_route_domain.hpp index d2dc049deff..dd096738297 100644 --- a/extras/vom/vom/gbp_route_domain.hpp +++ b/extras/vom/vom/gbp_route_domain.hpp @@ -16,6 +16,7 @@ #ifndef __VOM_GBP_ROUTE_DOMAIN_H__ #define __VOM_GBP_ROUTE_DOMAIN_H__ +#include "vom/gbp_types.hpp" #include "vom/interface.hpp" #include "vom/route_domain.hpp" #include "vom/singular_db.hpp" @@ -37,12 +38,14 @@ public: /** * Construct a GBP route_domain */ - gbp_route_domain(const route_domain& rd); + gbp_route_domain(const route_domain& rd, scope_t scope); gbp_route_domain(const route_domain& rd, + scope_t scope, const interface& ip4_uu_fwd, const interface& ip6_uu_fwd); gbp_route_domain(const route_domain& rd, + scope_t scope, const std::shared_ptr ip4_uu_fwd, const std::shared_ptr ip6_uu_fwd); @@ -171,6 +174,7 @@ private: HW::item m_id; std::shared_ptr m_rd; + scope_t m_scope; std::shared_ptr m_ip4_uu_fwd; std::shared_ptr m_ip6_uu_fwd; diff --git a/extras/vom/vom/gbp_route_domain_cmds.cpp b/extras/vom/vom/gbp_route_domain_cmds.cpp index 9b8b4bee3fd..90e81f338e3 100644 --- a/extras/vom/vom/gbp_route_domain_cmds.cpp +++ b/extras/vom/vom/gbp_route_domain_cmds.cpp @@ -19,9 +19,11 @@ namespace VOM { namespace gbp_route_domain_cmds { create_cmd::create_cmd(HW::item& item, + scope_t scope, const handle_t ip4_uu_fwd, const handle_t ip6_uu_fwd) : rpc_cmd(item) + , m_scope(scope) , m_ip4_uu_fwd(ip4_uu_fwd) , m_ip6_uu_fwd(ip6_uu_fwd) { @@ -31,7 +33,7 @@ bool create_cmd::operator==(const create_cmd& other) const { return ((m_hw_item.data() == other.m_hw_item.data()) && - (m_ip4_uu_fwd == other.m_ip4_uu_fwd) && + (m_scope == other.m_scope) && (m_ip4_uu_fwd == other.m_ip4_uu_fwd) && (m_ip6_uu_fwd == other.m_ip6_uu_fwd)); } @@ -43,6 +45,7 @@ create_cmd::issue(connection& con) auto& payload = req.get_request().get_payload(); payload.rd.rd_id = m_hw_item.data(); + payload.rd.scope = m_scope; payload.rd.ip4_table_id = m_hw_item.data(); payload.rd.ip6_table_id = m_hw_item.data(); payload.rd.ip4_uu_sw_if_index = m_ip4_uu_fwd.value(); @@ -57,7 +60,7 @@ std::string create_cmd::to_string() const { std::ostringstream s; - s << "gbp-route-domain: " << m_hw_item.to_string() + s << "gbp-route-domain: " << m_hw_item.to_string() << " scope:" << m_scope << " ip4-uu-fwd:" << m_ip4_uu_fwd.to_string() << " ip6-uu-fwd:" << m_ip6_uu_fwd.to_string(); diff --git a/extras/vom/vom/gbp_route_domain_cmds.hpp b/extras/vom/vom/gbp_route_domain_cmds.hpp index 249ba901329..6ef9fcd3ce9 100644 --- a/extras/vom/vom/gbp_route_domain_cmds.hpp +++ b/extras/vom/vom/gbp_route_domain_cmds.hpp @@ -35,6 +35,7 @@ public: * Constructor */ create_cmd(HW::item& item, + scope_t scope, const handle_t ip4_uu_fwd, const handle_t ip6_uu_fwd); @@ -53,6 +54,7 @@ public: bool operator==(const create_cmd& i) const; private: + const scope_t m_scope; const handle_t m_ip4_uu_fwd; const handle_t m_ip6_uu_fwd; }; diff --git a/extras/vom/vom/gbp_types.hpp b/extras/vom/vom/gbp_types.hpp new file mode 100644 index 00000000000..5b46e08f513 --- /dev/null +++ b/extras/vom/vom/gbp_types.hpp @@ -0,0 +1,40 @@ +/* + * 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_GBP_TYPES_H__ +#define __VOM_GBP_TYPES_H__ + +#include + +namespace VOM { + +/** + * EPG IDs are 32 bit integers + */ +typedef uint32_t vnid_t; +typedef uint16_t sclass_t; +typedef uint16_t scope_t; + +}; // namespace + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/src/plugins/gbp/gbp.api b/src/plugins/gbp/gbp.api index b0b284fcc3e..f6775e7dcd7 100644 --- a/src/plugins/gbp/gbp.api +++ b/src/plugins/gbp/gbp.api @@ -31,6 +31,7 @@ enum gbp_bridge_domain_flags typedef gbp_bridge_domain { u32 bd_id; + u32 rd_id; vl_api_gbp_bridge_domain_flags_t flags; u32 bvi_sw_if_index; u32 uu_fwd_sw_if_index; @@ -60,6 +61,8 @@ define gbp_bridge_domain_details vl_api_gbp_bridge_domain_t bd; }; +typedef u16 gbp_scope; + typedef gbp_route_domain { u32 rd_id; @@ -67,6 +70,7 @@ typedef gbp_route_domain u32 ip6_table_id; u32 ip4_uu_sw_if_index; u32 ip6_uu_sw_if_index; + vl_api_gbp_scope_t scope; }; manual_print autoreply define gbp_route_domain_add @@ -299,6 +303,7 @@ typedef gbp_rule typedef gbp_contract { + vl_api_gbp_scope_t scope; u16 sclass; u16 dclass; u32 acl_index; diff --git a/src/plugins/gbp/gbp_api.c b/src/plugins/gbp/gbp_api.c index db8c8c69ed6..8155a8ff0f1 100644 --- a/src/plugins/gbp/gbp_api.c +++ b/src/plugins/gbp/gbp_api.c @@ -342,6 +342,7 @@ vl_api_gbp_bridge_domain_add_t_handler (vl_api_gbp_bridge_domain_add_t * mp) int rv = 0; rv = gbp_bridge_domain_add_and_lock (ntohl (mp->bd.bd_id), + ntohl (mp->bd.rd_id), gbp_bridge_domain_flags_from_api (mp->bd.flags), ntohl (mp->bd.bvi_sw_if_index), @@ -369,6 +370,7 @@ vl_api_gbp_route_domain_add_t_handler (vl_api_gbp_route_domain_add_t * mp) int rv = 0; rv = gbp_route_domain_add_and_lock (ntohl (mp->rd.rd_id), + ntohs (mp->rd.scope), ntohl (mp->rd.ip4_table_id), ntohl (mp->rd.ip6_table_id), ntohl (mp->rd.ip4_uu_sw_if_index), @@ -559,6 +561,7 @@ static int gbp_bridge_domain_send_details (gbp_bridge_domain_t * gb, void *args) { vl_api_gbp_bridge_domain_details_t *mp; + gbp_route_domain_t *gr; gbp_walk_ctx_t *ctx; ctx = args; @@ -570,7 +573,10 @@ gbp_bridge_domain_send_details (gbp_bridge_domain_t * gb, void *args) mp->_vl_msg_id = ntohs (VL_API_GBP_BRIDGE_DOMAIN_DETAILS + GBP_MSG_BASE); mp->context = ctx->context; + gr = gbp_route_domain_get (gb->gb_rdi); + mp->bd.bd_id = ntohl (gb->gb_bd_id); + mp->bd.rd_id = ntohl (gr->grd_id); mp->bd.bvi_sw_if_index = ntohl (gb->gb_bvi_sw_if_index); mp->bd.uu_fwd_sw_if_index = ntohl (gb->gb_uu_fwd_sw_if_index); mp->bd.bm_flood_sw_if_index = ntohl (gb->gb_bm_flood_sw_if_index); @@ -961,13 +967,15 @@ vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp) allowed_ethertypes[ii] = mp->contract.allowed_ethertypes[ii]; } - rv = gbp_contract_update (ntohs (mp->contract.sclass), + rv = gbp_contract_update (ntohs (mp->contract.scope), + ntohs (mp->contract.sclass), ntohs (mp->contract.dclass), ntohl (mp->contract.acl_index), rules, allowed_ethertypes, &stats_index); } else - rv = gbp_contract_delete (ntohs (mp->contract.sclass), + rv = gbp_contract_delete (ntohs (mp->contract.scope), + ntohs (mp->contract.sclass), ntohs (mp->contract.dclass)); out: @@ -997,6 +1005,7 @@ gbp_contract_send_details (gbp_contract_t * gbpc, void *args) mp->contract.sclass = ntohs (gbpc->gc_key.gck_src); mp->contract.dclass = ntohs (gbpc->gc_key.gck_dst); mp->contract.acl_index = ntohl (gbpc->gc_acl_index); + mp->contract.scope = ntohs (gbpc->gc_key.gck_scope); vl_api_send_msg (ctx->reg, (u8 *) mp); diff --git a/src/plugins/gbp/gbp_api_print.h b/src/plugins/gbp/gbp_api_print.h index 7598306ec5c..67cd30c7da7 100644 --- a/src/plugins/gbp/gbp_api_print.h +++ b/src/plugins/gbp/gbp_api_print.h @@ -32,6 +32,7 @@ vl_api_gbp_bridge_domain_add_t_print (vl_api_gbp_bridge_domain_add_t * a, s = format (s, "SCRIPT: gbp_bridge_domain_add "); s = format (s, "bd_id %d ", ntohl (a->bd.bd_id)); + s = format (s, "rd_id %d ", ntohl (a->bd.rd_id)); s = format (s, "flags %d ", ntohl (a->bd.flags)); s = format (s, "uu-fwd %d ", ntohl (a->bd.uu_fwd_sw_if_index)); s = format (s, "bvi %d ", ntohl (a->bd.bvi_sw_if_index)); @@ -238,6 +239,7 @@ vl_api_gbp_contract_add_del_t_print (vl_api_gbp_contract_add_del_t * a, s = format (s, "add "); else s = format (s, "del "); + s = format (s, "scope %d ", ntohl (a->contract.scope)); s = format (s, "sclass %d ", ntohs (a->contract.sclass)); s = format (s, "dclass %d ", ntohs (a->contract.dclass)); s = format (s, "acl_index %d \n", ntohl (a->contract.acl_index)); diff --git a/src/plugins/gbp/gbp_bridge_domain.c b/src/plugins/gbp/gbp_bridge_domain.c index 53105451d6c..6c14fbcbfdd 100644 --- a/src/plugins/gbp/gbp_bridge_domain.c +++ b/src/plugins/gbp/gbp_bridge_domain.c @@ -14,6 +14,7 @@ */ #include +#include #include #include @@ -34,6 +35,11 @@ gbp_bridge_domain_t *gbp_bridge_domain_pool; */ gbp_bridge_domain_db_t gbp_bridge_domain_db; +/** + * Map of BD index to contract scope + */ +gbp_scope_t *gbp_scope_by_bd_index; + /** * logger */ @@ -170,6 +176,7 @@ format_gbp_bridge_domain (u8 * s, va_list * args) int gbp_bridge_domain_add_and_lock (u32 bd_id, + u32 rd_id, gbp_bridge_domain_flags_t flags, u32 bvi_sw_if_index, u32 uu_fwd_sw_if_index, @@ -182,6 +189,7 @@ gbp_bridge_domain_add_and_lock (u32 bd_id, if (INDEX_INVALID == gbi) { + gbp_route_domain_t *gr; u32 bd_index; bd_index = bd_find_index (&bd_main, bd_id); @@ -205,6 +213,14 @@ gbp_bridge_domain_add_and_lock (u32 bd_id, gb->gb_bm_flood_sw_if_index = bm_flood_sw_if_index; gb->gb_locks = 1; gb->gb_flags = flags; + gb->gb_rdi = gbp_route_domain_find_and_lock (rd_id); + + /* + * set the scope from the BD's RD's scope + */ + gr = gbp_route_domain_get (gb->gb_rdi); + vec_validate (gbp_scope_by_bd_index, gb->gb_bd_index); + gbp_scope_by_bd_index[gb->gb_bd_index] = gr->grd_scope; /* * Set the BVI and uu-flood interfaces into the BD @@ -298,6 +314,7 @@ gbp_bridge_domain_unlock (index_t index) } gbp_bridge_domain_db_remove (gb); + gbp_route_domain_unlock (gb->gb_rdi); pool_put (gbp_bridge_domain_pool, gb); } @@ -344,8 +361,8 @@ gbp_bridge_domain_cli (vlib_main_t * vm, gbp_bridge_domain_flags_t flags; u32 bm_flood_sw_if_index = ~0; u32 uu_fwd_sw_if_index = ~0; + u32 bd_id = ~0, rd_id = ~0; u32 bvi_sw_if_index = ~0; - u32 bd_id = ~0; u8 add = 1; flags = GBP_BD_FLAG_NONE; @@ -369,19 +386,24 @@ gbp_bridge_domain_cli (vlib_main_t * vm, ; else if (unformat (input, "bd %d", &bd_id)) ; + else if (unformat (input, "rd %d", &rd_id)) + ; else break; } if (~0 == bd_id) return clib_error_return (0, "BD-ID must be specified"); + if (~0 == rd_id) + return clib_error_return (0, "RD-ID must be specified"); if (add) { if (~0 == bvi_sw_if_index) return clib_error_return (0, "interface must be specified"); - gbp_bridge_domain_add_and_lock (bd_id, flags, + gbp_bridge_domain_add_and_lock (bd_id, rd_id, + flags, bvi_sw_if_index, uu_fwd_sw_if_index, bm_flood_sw_if_index); diff --git a/src/plugins/gbp/gbp_bridge_domain.h b/src/plugins/gbp/gbp_bridge_domain.h index dd2798fdafa..5bfa099f31d 100644 --- a/src/plugins/gbp/gbp_bridge_domain.h +++ b/src/plugins/gbp/gbp_bridge_domain.h @@ -45,6 +45,12 @@ typedef struct gbp_bridge_domain_t_ u32 gb_bd_id; u32 gb_bd_index; + /** + * Index of the Route-domain this BD is associated with. This is used as the + * 'scope' of the packets for contract matching. + */ + u32 gb_rdi; + /** * Flags conttrolling behaviour */ @@ -79,6 +85,7 @@ typedef struct gbp_bridge_domain_t_ } gbp_bridge_domain_t; extern int gbp_bridge_domain_add_and_lock (u32 bd_id, + u32 rd_id, gbp_bridge_domain_flags_t flags, u32 bvi_sw_if_index, u32 uu_fwd_sw_if_index, @@ -121,6 +128,14 @@ gbp_bridge_domain_get_by_bd_index (u32 bd_index) (gbp_bridge_domain_db.gbd_by_bd_index[bd_index])); } +extern gbp_scope_t *gbp_scope_by_bd_index; + +always_inline gbp_scope_t +gbp_bridge_domain_get_scope (u32 bd_index) +{ + return (gbp_scope_by_bd_index[bd_index]); +} + #endif /* diff --git a/src/plugins/gbp/gbp_contract.c b/src/plugins/gbp/gbp_contract.c index 552201a684b..f0bb00a0154 100644 --- a/src/plugins/gbp/gbp_contract.c +++ b/src/plugins/gbp/gbp_contract.c @@ -444,7 +444,8 @@ gbp_contract_mk_lbs (index_t * guis) } int -gbp_contract_update (sclass_t sclass, +gbp_contract_update (gbp_scope_t scope, + sclass_t sclass, sclass_t dclass, u32 acl_index, index_t * rules, @@ -457,6 +458,7 @@ gbp_contract_update (sclass_t sclass, uword *p; gbp_contract_key_t key = { + .gck_scope = scope, .gck_src = sclass, .gck_dst = dclass, }; @@ -468,7 +470,7 @@ gbp_contract_update (sclass_t sclass, gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg"); } - p = hash_get (gbp_contract_db.gc_hash, key.as_u32); + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); if (p != NULL) { gci = p[0]; @@ -483,7 +485,7 @@ gbp_contract_update (sclass_t sclass, pool_get_zero (gbp_contract_pool, gc); gc->gc_key = key; gci = gc - gbp_contract_pool; - hash_set (gbp_contract_db.gc_hash, key.as_u32, gci); + hash_set (gbp_contract_db.gc_hash, key.as_u64, gci); vlib_validate_combined_counter (&gbp_contract_drop_counters, gci); vlib_zero_combined_counter (&gbp_contract_drop_counters, gci); @@ -513,16 +515,17 @@ gbp_contract_update (sclass_t sclass, } int -gbp_contract_delete (sclass_t sclass, sclass_t dclass) +gbp_contract_delete (gbp_scope_t scope, sclass_t sclass, sclass_t dclass) { gbp_contract_key_t key = { + .gck_scope = scope, .gck_src = sclass, .gck_dst = dclass, }; gbp_contract_t *gc; uword *p; - p = hash_get (gbp_contract_db.gc_hash, key.as_u32); + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); if (p != NULL) { gc = gbp_contract_get (p[0]); @@ -531,7 +534,7 @@ gbp_contract_delete (sclass_t sclass, sclass_t dclass) gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index); vec_free (gc->gc_allowed_ethertypes); - hash_unset (gbp_contract_db.gc_hash, key.as_u32); + hash_unset (gbp_contract_db.gc_hash, key.as_u64); pool_put (gbp_contract_pool, gc); return (0); @@ -559,7 +562,7 @@ gbp_contract_cli (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { sclass_t sclass = SCLASS_INVALID, dclass = SCLASS_INVALID; - u32 acl_index = ~0, stats_index; + u32 acl_index = ~0, stats_index, scope; u8 add = 1; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -568,9 +571,11 @@ gbp_contract_cli (vlib_main_t * vm, add = 1; else if (unformat (input, "del")) add = 0; - else if (unformat (input, "src-epg %d", &sclass)) + else if (unformat (input, "scope %d", &scope)) ; - else if (unformat (input, "dst-epg %d", &dclass)) + else if (unformat (input, "sclass %d", &sclass)) + ; + else if (unformat (input, "dclass %d", &dclass)) ; else if (unformat (input, "acl-index %d", &acl_index)) ; @@ -585,12 +590,12 @@ gbp_contract_cli (vlib_main_t * vm, if (add) { - gbp_contract_update (sclass, dclass, acl_index, + gbp_contract_update (scope, sclass, dclass, acl_index, NULL, NULL, &stats_index); } else { - gbp_contract_delete (sclass, dclass); + gbp_contract_delete (scope, sclass, dclass); } return (NULL); @@ -618,7 +623,7 @@ format_gbp_contract_key (u8 * s, va_list * args) { gbp_contract_key_t *gck = va_arg (*args, gbp_contract_key_t *); - s = format (s, "{%d,%d}", gck->gck_src, gck->gck_dst); + s = format (s, "{%d,%d,%d}", gck->gck_scope, gck->gck_src, gck->gck_dst); return (s); } diff --git a/src/plugins/gbp/gbp_contract.h b/src/plugins/gbp/gbp_contract.h index 9de52eb9806..8e621a47d28 100644 --- a/src/plugins/gbp/gbp_contract.h +++ b/src/plugins/gbp/gbp_contract.h @@ -38,13 +38,14 @@ typedef struct gbp_contract_key_t_ { struct { + gbp_scope_t gck_scope; /** * source and destination EPGs for which the ACL applies */ sclass_t gck_src; sclass_t gck_dst; }; - u32 as_u32; + u64 as_u64; }; } gbp_contract_key_t; @@ -149,12 +150,14 @@ typedef struct gbp_contract_db_t_ uword *gc_hash; } gbp_contract_db_t; -extern int gbp_contract_update (sclass_t sclass, +extern int gbp_contract_update (gbp_scope_t scope, + sclass_t sclass, sclass_t dclass, u32 acl_index, index_t * rules, u16 * allowed_ethertypes, u32 * stats_index); -extern int gbp_contract_delete (sclass_t sclass, sclass_t dclass); +extern int gbp_contract_delete (gbp_scope_t scope, sclass_t sclass, + sclass_t dclass); extern index_t gbp_rule_alloc (gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t * nhs); @@ -177,7 +180,7 @@ gbp_contract_find (gbp_contract_key_t * key) { uword *p; - p = hash_get (gbp_contract_db.gc_hash, key->as_u32); + p = hash_get (gbp_contract_db.gc_hash, key->as_u64); if (NULL != p) return (p[0]); diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c index 2472199e320..da15b49d81b 100644 --- a/src/plugins/gbp/gbp_endpoint.c +++ b/src/plugins/gbp/gbp_endpoint.c @@ -759,6 +759,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge) * is applied */ gbp_policy_dpo_add_or_lock (fib_proto_to_dpo (pfx->fp_proto), + grd->grd_scope, gg->gg_sclass, ~0, &policy_dpo); fib_table_entry_special_dpo_add (fib_index, pfx, diff --git a/src/plugins/gbp/gbp_policy_dpo.c b/src/plugins/gbp/gbp_policy_dpo.c index a7077899fd8..8152315c7b8 100644 --- a/src/plugins/gbp/gbp_policy_dpo.c +++ b/src/plugins/gbp/gbp_policy_dpo.c @@ -93,6 +93,7 @@ gbp_policy_dpo_get_urpf (const dpo_id_t * dpo) void gbp_policy_dpo_add_or_lock (dpo_proto_t dproto, + gbp_scope_t scope, sclass_t sclass, u32 sw_if_index, dpo_id_t * dpo) { gbp_policy_dpo_t *gpd; @@ -103,6 +104,7 @@ gbp_policy_dpo_add_or_lock (dpo_proto_t dproto, gpd->gpd_proto = dproto; gpd->gpd_sw_if_index = sw_if_index; gpd->gpd_sclass = sclass; + gpd->gpd_scope = scope; if (~0 != sw_if_index) { @@ -128,9 +130,9 @@ format_gbp_policy_dpo (u8 * s, va_list * ap) gbp_policy_dpo_t *gpd = gbp_policy_dpo_get (index); vnet_main_t *vnm = vnet_get_main (); - s = format (s, "gbp-policy-dpo: %U, sclass:%d out:%U", + s = format (s, "gbp-policy-dpo: %U, scope:%d sclass:%d out:%U", format_dpo_proto, gpd->gpd_proto, - (int) gpd->gpd_sclass, + gpd->gpd_scope, (int) gpd->gpd_sclass, format_vnet_sw_if_index_name, vnm, gpd->gpd_sw_if_index); s = format (s, "\n%U", format_white_space, indent + 2); s = format (s, "%U", format_dpo_id, &gpd->gpd_dpo, indent + 4); @@ -151,6 +153,7 @@ gbp_policy_dpo_interpose (const dpo_id_t * original, gpd = gbp_policy_dpo_get (original->dpoi_index); gpd_clone->gpd_proto = gpd->gpd_proto; + gpd_clone->gpd_scope = gpd->gpd_scope; gpd_clone->gpd_sclass = gpd->gpd_sclass; gpd_clone->gpd_sw_if_index = gpd->gpd_sw_if_index; @@ -233,11 +236,13 @@ static char *gbp_policy_dpo_error_strings[] = { typedef struct gbp_policy_dpo_trace_t_ { - u32 sclass; - u32 dclass; + gbp_scope_t scope; + sclass_t sclass; + sclass_t dclass; u32 acl_index; u32 flags; u32 action; + u32 gci; } gbp_policy_dpo_trace_t; typedef enum @@ -323,11 +328,13 @@ gbp_policy_dpo_inline (vlib_main_t * vm, if (vnet_buffer2 (b0)->gbp.flags & VXLAN_GBP_GPFLAGS_A) { next0 = gpd0->gpd_dpo.dpoi_next_node; - key0.as_u32 = ~0; + key0.as_u64 = ~0; n_allow_a_bit++; goto trace; } + key0.as_u64 = 0; + key0.gck_scope = gpd0->gpd_scope; key0.gck_src = vnet_buffer2 (b0)->gbp.sclass; key0.gck_dst = gpd0->gpd_sclass; @@ -440,11 +447,14 @@ gbp_policy_dpo_inline (vlib_main_t * vm, gbp_policy_dpo_trace_t *tr; tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); + tr->scope = key0.gck_scope; tr->sclass = key0.gck_src; tr->dclass = key0.gck_dst; tr->acl_index = (gc0 ? gc0->gc_acl_index : ~0); tr->flags = vnet_buffer2 (b0)->gbp.flags; tr->action = action0; + tr->gci = (gc0 ? gc0 - gbp_contract_pool : INDEX_INVALID); + } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, @@ -472,9 +482,11 @@ format_gbp_policy_dpo_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); gbp_policy_dpo_trace_t *t = va_arg (*args, gbp_policy_dpo_trace_t *); - s = format (s, " sclass:%d dclass:%d acl-index:%d flags:%U action:%d", - t->sclass, t->dclass, t->acl_index, - format_vxlan_gbp_header_gpflags, t->flags, t->action); + s = + format (s, + "scope:%d sclass:%d dclass:%d gci:%d acl-index:%d flags:%U action:%d", + t->scope, t->sclass, t->dclass, t->gci, t->acl_index, + format_vxlan_gbp_header_gpflags, t->flags, t->action); return s; } diff --git a/src/plugins/gbp/gbp_policy_dpo.h b/src/plugins/gbp/gbp_policy_dpo.h index 3a4264d9194..6b4f8c57fd0 100644 --- a/src/plugins/gbp/gbp_policy_dpo.h +++ b/src/plugins/gbp/gbp_policy_dpo.h @@ -37,6 +37,11 @@ typedef struct gbp_policy_dpo_t_ */ sclass_t gpd_sclass; + /** + * sclass scope + */ + gbp_scope_t gpd_scope; + /** * output sw_if_index */ @@ -54,6 +59,7 @@ typedef struct gbp_policy_dpo_t_ } gbp_policy_dpo_t; extern void gbp_policy_dpo_add_or_lock (dpo_proto_t dproto, + gbp_scope_t scope, sclass_t sclass, u32 sw_if_index, dpo_id_t * dpo); diff --git a/src/plugins/gbp/gbp_policy_node.c b/src/plugins/gbp/gbp_policy_node.c index 2cffc79cf2d..26f7e9b8c59 100644 --- a/src/plugins/gbp/gbp_policy_node.c +++ b/src/plugins/gbp/gbp_policy_node.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -49,8 +50,9 @@ typedef enum typedef struct gbp_policy_trace_t_ { /* per-pkt trace data */ - u32 sclass; - u32 dst_epg; + gbp_scope_t scope; + sclass_t sclass; + sclass_t dclass; u32 acl_index; u32 allowed; u32 flags; @@ -154,6 +156,9 @@ gbp_policy_inline (vlib_main_t * vm, h0 = vlib_buffer_get_current (b0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + /* zero out the key to ensure the pad space is clear */ + key0.as_u64 = 0; + /* * Reflection check; in and out on an ivxlan tunnel */ @@ -176,7 +181,7 @@ gbp_policy_inline (vlib_main_t * vm, L2OUTPUT_FEAT_GBP_POLICY_PORT : L2OUTPUT_FEAT_GBP_POLICY_MAC)); n_allow_a_bit++; - key0.as_u32 = ~0; + key0.as_u64 = ~0; goto trace; } @@ -190,7 +195,11 @@ gbp_policy_inline (vlib_main_t * vm, vnet_buffer (b0)->l2.bd_index); if (NULL != ge0) - key0.gck_dst = ge0->ge_fwd.gef_sclass; + { + key0.gck_dst = ge0->ge_fwd.gef_sclass; + key0.gck_scope = + gbp_bridge_domain_get_scope (vnet_buffer (b0)->l2.bd_index); + } else { /* If you cannot determine the destination EP then drop */ @@ -373,7 +382,8 @@ gbp_policy_inline (vlib_main_t * vm, gbp_policy_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); t->sclass = key0.gck_src; - t->dst_epg = key0.gck_dst; + t->dclass = key0.gck_dst; + t->scope = key0.gck_scope; t->acl_index = (gc0 ? gc0->gc_acl_index : ~0); t->allowed = (next0 != GBP_POLICY_NEXT_DROP); t->flags = vnet_buffer2 (b0)->gbp.flags; @@ -422,8 +432,8 @@ format_gbp_policy_trace (u8 * s, va_list * args) gbp_policy_trace_t *t = va_arg (*args, gbp_policy_trace_t *); s = - format (s, "sclass:%d, dst:%d, acl:%d allowed:%d flags:%U", - t->sclass, t->dst_epg, t->acl_index, t->allowed, + format (s, "scope:%d sclass:%d, dclass:%d, acl:%d allowed:%d flags:%U", + t->scope, t->sclass, t->dclass, t->acl_index, t->allowed, format_vxlan_gbp_header_gpflags, t->flags); return s; diff --git a/src/plugins/gbp/gbp_route_domain.c b/src/plugins/gbp/gbp_route_domain.c index 7502a253440..90b0155758d 100644 --- a/src/plugins/gbp/gbp_route_domain.c +++ b/src/plugins/gbp/gbp_route_domain.c @@ -126,6 +126,7 @@ gbp_route_domain_db_remove (gbp_route_domain_t * grd) int gbp_route_domain_add_and_lock (u32 rd_id, + gbp_scope_t scope, u32 ip4_table_id, u32 ip6_table_id, u32 ip4_uu_sw_if_index, u32 ip6_uu_sw_if_index) @@ -142,6 +143,7 @@ gbp_route_domain_add_and_lock (u32 rd_id, pool_get_zero (gbp_route_domain_pool, grd); grd->grd_id = rd_id; + grd->grd_scope = scope; grd->grd_table_id[FIB_PROTOCOL_IP4] = ip4_table_id; grd->grd_table_id[FIB_PROTOCOL_IP6] = ip6_table_id; grd->grd_uu_sw_if_index[FIB_PROTOCOL_IP4] = ip4_uu_sw_if_index; @@ -241,6 +243,16 @@ gbp_route_domain_get_rd_id (index_t grdi) return (grd->grd_id); } +gbp_scope_t +gbp_route_domain_get_scope (index_t grdi) +{ + gbp_route_domain_t *grd; + + grd = gbp_route_domain_get (grdi); + + return (grd->grd_scope); +} + int gbp_route_domain_delete (u32 rd_id) { @@ -296,6 +308,7 @@ gbp_route_domain_cli (vlib_main_t * vm, u32 ip6_uu_sw_if_index = ~0; u32 ip4_table_id = ~0; u32 ip6_table_id = ~0; + u32 scope = ~0; u32 rd_id = ~0; u8 add = 1; @@ -317,6 +330,8 @@ gbp_route_domain_cli (vlib_main_t * vm, add = 0; else if (unformat (input, "rd %d", &rd_id)) ; + else if (unformat (input, "scope %d", &scope)) + ; else break; } @@ -331,7 +346,8 @@ gbp_route_domain_cli (vlib_main_t * vm, if (~0 == ip6_table_id) return clib_error_return (0, "IP6 table-ID must be specified"); - gbp_route_domain_add_and_lock (rd_id, ip4_table_id, + gbp_route_domain_add_and_lock (rd_id, scope, + ip4_table_id, ip6_table_id, ip4_uu_sw_if_index, ip6_uu_sw_if_index); } diff --git a/src/plugins/gbp/gbp_route_domain.h b/src/plugins/gbp/gbp_route_domain.h index b83d598ad38..dd7adf096cf 100644 --- a/src/plugins/gbp/gbp_route_domain.h +++ b/src/plugins/gbp/gbp_route_domain.h @@ -32,6 +32,7 @@ typedef struct gpb_route_domain_t_ * Route-domain ID */ u32 grd_id; + gbp_scope_t grd_scope; u32 grd_fib_index[FIB_PROTOCOL_IP_MAX]; u32 grd_table_id[FIB_PROTOCOL_IP_MAX]; @@ -55,6 +56,7 @@ typedef struct gpb_route_domain_t_ } gbp_route_domain_t; extern int gbp_route_domain_add_and_lock (u32 rd_id, + gbp_scope_t scope, u32 ip4_table_id, u32 ip6_table_id, u32 ip4_uu_sw_if_index, @@ -67,6 +69,7 @@ extern index_t gbp_route_domain_index (const gbp_route_domain_t *); extern int gbp_route_domain_delete (u32 rd_id); extern gbp_route_domain_t *gbp_route_domain_get (index_t i); extern u32 gbp_route_domain_get_rd_id (index_t i); +extern gbp_scope_t gbp_route_domain_get_scope (index_t i); typedef int (*gbp_route_domain_cb_t) (gbp_route_domain_t * gb, void *ctx); extern void gbp_route_domain_walk (gbp_route_domain_cb_t bgpe, void *ctx); diff --git a/src/plugins/gbp/gbp_subnet.c b/src/plugins/gbp/gbp_subnet.c index 2daf0ddc684..e2dfd3799b0 100644 --- a/src/plugins/gbp/gbp_subnet.c +++ b/src/plugins/gbp/gbp_subnet.c @@ -163,6 +163,7 @@ gbp_subnet_external_add (gbp_subnet_t * gs, u32 sw_if_index, sclass_t sclass) gs->gs_stitched_external.gs_sw_if_index = sw_if_index; gbp_policy_dpo_add_or_lock (fib_proto_to_dpo (gs->gs_key->gsk_pfx.fp_proto), + gbp_route_domain_get_scope (gs->gs_rd), gs->gs_stitched_external.gs_sclass, gs->gs_stitched_external.gs_sw_if_index, &gpd); @@ -186,6 +187,7 @@ gbp_subnet_l3_out_add (gbp_subnet_t * gs, sclass_t sclass) gs->gs_l3_out.gs_sclass = sclass; gbp_policy_dpo_add_or_lock (fib_proto_to_dpo (gs->gs_key->gsk_pfx.fp_proto), + gbp_route_domain_get_scope (gs->gs_rd), gs->gs_l3_out.gs_sclass, ~0, &gpd); gs->gs_fei = fib_table_entry_special_dpo_add (gs->gs_key->gsk_fib_index, diff --git a/src/plugins/gbp/gbp_types.h b/src/plugins/gbp/gbp_types.h index 5bd9735e08b..ac983b1cdd2 100644 --- a/src/plugins/gbp/gbp_types.h +++ b/src/plugins/gbp/gbp_types.h @@ -21,6 +21,7 @@ typedef u32 vnid_t; #define VNID_INVALID ((u16)~0) +typedef u16 gbp_scope_t; typedef u16 sclass_t; #define SCLASS_INVALID ((u16)~0) diff --git a/test/test_gbp.py b/test/test_gbp.py index ac0fb222633..1b8171313fc 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -321,13 +321,14 @@ class VppGbpBridgeDomain(VppObject): GBP Bridge Domain """ - def __init__(self, test, bd, bvi, uu_fwd=None, + def __init__(self, test, bd, rd, bvi, uu_fwd=None, bm_flood=None, learn=True, uu_drop=False, bm_drop=False): self._test = test self.bvi = bvi self.uu_fwd = uu_fwd self.bm_flood = bm_flood self.bd = bd + self.rd = rd e = VppEnum.vl_api_gbp_bridge_domain_flags_t if (learn): @@ -342,6 +343,7 @@ class VppGbpBridgeDomain(VppObject): def add_vpp_config(self): self._test.vapi.gbp_bridge_domain_add( self.bd.bd_id, + self.rd.rd_id, self.learn, self.bvi.sw_if_index, self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID, @@ -367,9 +369,10 @@ class VppGbpRouteDomain(VppObject): GBP Route Domain """ - def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None): + def __init__(self, test, rd_id, scope, t4, t6, ip4_uu=None, ip6_uu=None): self._test = test self.rd_id = rd_id + self.scope = scope self.t4 = t4 self.t6 = t6 self.ip4_uu = ip4_uu @@ -378,6 +381,7 @@ class VppGbpRouteDomain(VppObject): def add_vpp_config(self): self._test.vapi.gbp_route_domain_add( self.rd_id, + self.scope, self.t4.table_id, self.t6.table_id, self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID, @@ -440,13 +444,14 @@ class VppGbpContract(VppObject): GBP Contract """ - def __init__(self, test, sclass, dclass, acl_index, + def __init__(self, test, scope, sclass, dclass, acl_index, rules, allowed_ethertypes): self._test = test if not isinstance(rules, list): raise ValueError("'rules' must be a list.") if not isinstance(allowed_ethertypes, list): raise ValueError("'allowed_ethertypes' must be a list.") + self.scope = scope self.acl_index = acl_index self.sclass = sclass self.dclass = dclass @@ -463,6 +468,7 @@ class VppGbpContract(VppObject): is_add=1, contract={ 'acl_index': self.acl_index, + 'scope': self.scope, 'sclass': self.sclass, 'dclass': self.dclass, 'n_rules': len(rules), @@ -477,24 +483,26 @@ class VppGbpContract(VppObject): is_add=0, contract={ 'acl_index': self.acl_index, + 'scope': self.scope, 'sclass': self.sclass, 'dclass': self.dclass, 'n_rules': 0, 'rules': [], 'n_ether_types': len(self.allowed_ethertypes), - 'allowed_ethertypes': self.allowed_ethertypes} - ) + 'allowed_ethertypes': self.allowed_ethertypes}) def object_id(self): - return "gbp-contract:[%d:%s:%d]" % (self.sclass, - self.dclass, - self.acl_index) + return "gbp-contract:[%d:%d:%d:%d]" % (self.scope, + self.sclass, + self.dclass, + self.acl_index) def query_vpp_config(self): cs = self._test.vapi.gbp_contract_dump() for c in cs: - if c.contract.sclass == self.sclass \ - and c.contract.dclass == self.dclass: + if c.contract.scope == self.scope \ + and c.contract.sclass == self.sclass \ + and c.contract.dclass == self.dclass: return True return False @@ -738,25 +746,6 @@ class TestGBP(VppTestCase): ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t - # - # Bridge Domains - # - bd1 = VppBridgeDomain(self, 1) - bd2 = VppBridgeDomain(self, 2) - bd20 = VppBridgeDomain(self, 20) - - bd1.add_vpp_config() - bd2.add_vpp_config() - bd20.add_vpp_config() - - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0) - gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1) - gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2) - - gbd1.add_vpp_config() - gbd2.add_vpp_config() - gbd20.add_vpp_config() - # # Route Domains # @@ -769,12 +758,31 @@ class TestGBP(VppTestCase): nt6 = VppIpTable(self, 20, is_ip6=True) nt6.add_vpp_config() - rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None) - rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None) + rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None) + rd20 = VppGbpRouteDomain(self, 20, 420, nt4, nt6, None, None) rd0.add_vpp_config() rd20.add_vpp_config() + # + # Bridge Domains + # + bd1 = VppBridgeDomain(self, 1) + bd2 = VppBridgeDomain(self, 2) + bd20 = VppBridgeDomain(self, 20) + + bd1.add_vpp_config() + bd2.add_vpp_config() + bd20.add_vpp_config() + + gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0) + gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1) + gbd20 = VppGbpBridgeDomain(self, bd20, rd20, self.loop2) + + gbd1.add_vpp_config() + gbd2.add_vpp_config() + gbd20.add_vpp_config() + # # 3 EPGs, 2 of which share a BD. # 2 NAT EPGs, one for floating-IP subnets, the other for internet @@ -1183,7 +1191,7 @@ class TestGBP(VppTestCase): rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule, rule2]) c1 = VppGbpContract( - self, epgs[0].sclass, epgs[1].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[1].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1205,7 +1213,7 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, epgs[1].sclass, epgs[0].sclass, acl_index, + self, 400, epgs[1].sclass, epgs[0].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1249,7 +1257,7 @@ class TestGBP(VppTestCase): # A uni-directional contract from EPG 220 -> 222 'L3 routed' # c3 = VppGbpContract( - self, epgs[0].sclass, epgs[2].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[2].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1356,7 +1364,7 @@ class TestGBP(VppTestCase): acl_index2 = acl2.add_vpp_config([rule, rule2]) c4 = VppGbpContract( - self, epgs[0].sclass, epgs[3].sclass, acl_index2, + self, 400, epgs[0].sclass, epgs[3].sclass, acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1399,7 +1407,7 @@ class TestGBP(VppTestCase): self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS) c5 = VppGbpContract( - self, epgs[3].sclass, epgs[0].sclass, acl_index2, + self, 400, epgs[3].sclass, epgs[0].sclass, acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1529,7 +1537,7 @@ class TestGBP(VppTestCase): gt6 = VppIpTable(self, 1, is_ip6=True) gt6.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 1, gt4, gt6) + rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6) rd1.add_vpp_config() # @@ -1559,7 +1567,8 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, + self.pg3, tun_bm) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -1918,7 +1927,7 @@ class TestGBP(VppTestCase): rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule, rule2]) c1 = VppGbpContract( - self, epg_220.sclass, epg_330.sclass, acl_index, + self, 401, epg_220.sclass, epg_330.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2012,6 +2021,18 @@ class TestGBP(VppTestCase): def test_gbp_contract(self): """ GBP CONTRACTS """ + # + # Route Domains + # + gt4 = VppIpTable(self, 0) + gt4.add_vpp_config() + gt6 = VppIpTable(self, 0, is_ip6=True) + gt6.add_vpp_config() + + rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None) + + rd0.add_vpp_config() + # # Bridge Domains # @@ -2021,24 +2042,12 @@ class TestGBP(VppTestCase): bd1.add_vpp_config() bd2.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0) - gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1) + gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0) + gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1) gbd1.add_vpp_config() gbd2.add_vpp_config() - # - # Route Domains - # - gt4 = VppIpTable(self, 0) - gt4.add_vpp_config() - gt6 = VppIpTable(self, 0, is_ip6=True) - gt6.add_vpp_config() - - rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None) - - rd0.add_vpp_config() - # # 3 EPGs, 2 of which share a BD. # @@ -2141,7 +2150,7 @@ class TestGBP(VppTestCase): rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule, rule2]) c1 = VppGbpContract( - self, epgs[0].sclass, epgs[1].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[1].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2170,7 +2179,7 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, epgs[1].sclass, epgs[0].sclass, acl_index, + self, 400, epgs[1].sclass, epgs[0].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2199,7 +2208,7 @@ class TestGBP(VppTestCase): # contract between 220 and 222 uni-direction # c3 = VppGbpContract( - self, epgs[0].sclass, epgs[2].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[2].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2231,7 +2240,7 @@ class TestGBP(VppTestCase): gt6 = VppIpTable(self, 1, is_ip6=True) gt6.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 1, gt4, gt6) + rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6) rd1.add_vpp_config() # @@ -2257,8 +2266,8 @@ class TestGBP(VppTestCase): bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm, - uu_drop=True, bm_drop=True) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3, + tun_bm, uu_drop=True, bm_drop=True) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -2325,7 +2334,7 @@ class TestGBP(VppTestCase): gt6 = VppIpTable(self, 1, is_ip6=True) gt6.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 1, gt4, gt6) + rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6) rd1.add_vpp_config() # @@ -2358,7 +2367,7 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd, + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd, learn=False) gbd1.add_vpp_config() @@ -2501,7 +2510,7 @@ class TestGBP(VppTestCase): tun_ip4_uu.add_vpp_config() tun_ip6_uu.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu) + rd1 = VppGbpRouteDomain(self, 2, 401, t4, t6, tun_ip4_uu, tun_ip6_uu) rd1.add_vpp_config() self.loop0.set_mac(self.router_mac) @@ -2532,7 +2541,7 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -2933,7 +2942,7 @@ class TestGBP(VppTestCase): t6 = VppIpTable(self, 1, True) t6.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 2, t4, t6) + rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6) rd1.add_vpp_config() self.loop0.set_mac(self.router_mac) @@ -2955,12 +2964,12 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0) gbd1.add_vpp_config() bd2 = VppBridgeDomain(self, 2) bd2.add_vpp_config() - gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1) + gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1) gbd2.add_vpp_config() # ... and has a /32 and /128 applied @@ -3007,11 +3016,13 @@ class TestGBP(VppTestCase): bd3 = VppBridgeDomain(self, 3) bd3.add_vpp_config() - gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False) + gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, + bd_uu1, learn=False) gbd3.add_vpp_config() bd4 = VppBridgeDomain(self, 4) bd4.add_vpp_config() - gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False) + gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3, + bd_uu2, learn=False) gbd4.add_vpp_config() # @@ -3111,7 +3122,7 @@ class TestGBP(VppTestCase): # test the src-ip hash mode # c1 = VppGbpContract( - self, epg_220.sclass, epg_222.sclass, acl_index, + self, 402, epg_220.sclass, epg_222.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3130,7 +3141,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, epg_222.sclass, epg_220.sclass, acl_index, + self, 402, epg_222.sclass, epg_220.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3243,7 +3254,7 @@ class TestGBP(VppTestCase): # test the symmetric hash mode # c1 = VppGbpContract( - self, epg_220.sclass, epg_222.sclass, acl_index, + self, 402, epg_220.sclass, epg_222.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3262,7 +3273,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, epg_222.sclass, epg_220.sclass, acl_index, + self, 402, epg_222.sclass, epg_220.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3327,7 +3338,7 @@ class TestGBP(VppTestCase): Raw('\xa5' * 100))] c3 = VppGbpContract( - self, epg_220.sclass, epg_221.sclass, acl_index, + self, 402, epg_220.sclass, epg_221.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3363,7 +3374,7 @@ class TestGBP(VppTestCase): vx_tun_l3.add_vpp_config() c4 = VppGbpContract( - self, epg_221.sclass, epg_220.sclass, acl_index, + self, 402, epg_221.sclass, epg_220.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3443,7 +3454,7 @@ class TestGBP(VppTestCase): # test the dst-ip hash mode # c5 = VppGbpContract( - self, epg_220.sclass, epg_221.sclass, acl_index, + self, 402, epg_220.sclass, epg_221.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, @@ -3499,7 +3510,7 @@ class TestGBP(VppTestCase): t6 = VppIpTable(self, 1, True) t6.add_vpp_config() - rd1 = VppGbpRouteDomain(self, 2, t4, t6) + rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6) rd1.add_vpp_config() self.loop0.set_mac(self.router_mac) @@ -3530,7 +3541,7 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm) gbd1.add_vpp_config() # @@ -3780,7 +3791,7 @@ class TestGBP(VppTestCase): IP(src="10.220.0.1", dst="10.221.0.1") / ICMP(type='echo-request')) - rxs = self.send_and_assert_no_replies(self.pg0, p * 1) + self.send_and_assert_no_replies(self.pg0, p * 1) # # contract for the external nets to communicate @@ -3790,8 +3801,23 @@ class TestGBP(VppTestCase): rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule4, rule6]) + # + # A contract with the wrong scope is not matched + # + c_44 = VppGbpContract( + self, 44, 4220, 4221, acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + []), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + [])], + [ETH_P_IP, ETH_P_IPV6]) + c_44.add_vpp_config() + self.send_and_assert_no_replies(self.pg0, p * 1) + c1 = VppGbpContract( - self, 4220, 4221, acl_index, + self, 55, 4220, 4221, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3807,7 +3833,7 @@ class TestGBP(VppTestCase): # Contracts allowing ext-net 200 to talk with external EPs # c2 = VppGbpContract( - self, 4220, 113, acl_index, + self, 55, 4220, 113, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3819,7 +3845,7 @@ class TestGBP(VppTestCase): [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() c3 = VppGbpContract( - self, 113, 4220, acl_index, + self, 55, 113, 4220, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3953,7 +3979,7 @@ class TestGBP(VppTestCase): # Add contracts ext-nets for 220 -> 222 # c4 = VppGbpContract( - self, 4220, 4222, acl_index, + self, 55, 4220, 4222, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 29a5716508c..c7390eecaf3 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -2012,7 +2012,7 @@ class VppPapiProvider(object): return self.api(self.papi.gbp_endpoint_group_del, {'sclass': sclass}) - def gbp_bridge_domain_add(self, bd_id, flags, + def gbp_bridge_domain_add(self, bd_id, rd_id, flags, bvi_sw_if_index, uu_fwd_sw_if_index, bm_flood_sw_if_index): @@ -2024,7 +2024,8 @@ class VppPapiProvider(object): 'bvi_sw_if_index': bvi_sw_if_index, 'uu_fwd_sw_if_index': uu_fwd_sw_if_index, 'bm_flood_sw_if_index': bm_flood_sw_if_index, - 'bd_id': bd_id + 'bd_id': bd_id, + 'rd_id': rd_id }}) def gbp_bridge_domain_del(self, bd_id): @@ -2033,6 +2034,7 @@ class VppPapiProvider(object): {'bd_id': bd_id}) def gbp_route_domain_add(self, rd_id, + scope, ip4_table_id, ip6_table_id, ip4_uu_sw_if_index, @@ -2041,6 +2043,7 @@ class VppPapiProvider(object): return self.api(self.papi.gbp_route_domain_add, {'rd': { + 'scope': scope, 'ip4_table_id': ip4_table_id, 'ip6_table_id': ip6_table_id, 'ip4_uu_sw_if_index': ip4_uu_sw_if_index, -- 2.16.6