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)
gbp_rule.cpp
gbp_subnet_cmds.cpp
gbp_subnet.cpp
+ gbp_types.hpp
gbp_vxlan.cpp
gbp_vxlan_cmds.cpp
)
gbp_route_domain.hpp
gbp_rule.hpp
gbp_subnet.hpp
+ gbp_types.hpp
gbp_vxlan.hpp
)
endif()
* 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()
}
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())
}
gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
+ const gbp_route_domain& rd,
const std::shared_ptr<interface> bvi,
const std::shared_ptr<interface> uu_fwd,
const std::shared_ptr<interface> 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)
}
gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
+ const gbp_route_domain& rd,
const interface& bvi,
const std::shared_ptr<interface> uu_fwd,
const std::shared_ptr<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)
, m_bm_flood(bm_flood)
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)
{
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));
}
*/
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));
}
interface::find(payload.bd.bm_flood_sw_if_index);
std::shared_ptr<interface> bvi =
interface::find(payload.bd.bvi_sw_if_index);
+ std::shared_ptr<gbp_route_domain> 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)
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 {
dependency_t
gbp_bridge_domain::event_handler::order() const
{
- return (dependency_t::VIRTUAL_TABLE);
+ /* order after gbp-route-domains */
+ return (dependency_t::ACL);
}
void
#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 {
* 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<interface> bvi,
const std::shared_ptr<interface> uu_fwd,
const std::shared_ptr<interface> 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<interface> uu_fwd,
const std::shared_ptr<interface> bm_flood,
HW::item<uint32_t> m_id;
std::shared_ptr<bridge_domain> m_bd;
+ std::shared_ptr<gbp_route_domain> m_rd;
std::shared_ptr<interface> m_bvi;
std::shared_ptr<interface> m_uu_fwd;
std::shared_ptr<interface> m_bm_flood;
namespace gbp_bridge_domain_cmds {
create_cmd::create_cmd(HW::item<uint32_t>& 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)
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
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();
* Constructor
*/
create_cmd(HW::item<uint32_t>& item,
+ u32 rd_id,
const handle_t bvi,
const handle_t uu_fwd,
const handle_t bm_flood,
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;
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())
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)
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
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();
}
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));
}
}
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()) {
* 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));
}
}
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;
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);
}
#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"
/**
* The key for a contract is the pair of EPG-IDs
*/
- typedef std::pair<sclass_t, sclass_t> key_t;
+ typedef std::tuple<scope_t, sclass_t, sclass_t> key_t;
/**
* A set of allowed ethertypes
/**
* 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,
*/
HW::item<uint32_t> m_hw;
+ /*
+ * The scope of the contract
+ */
+ scope_t m_scope;
+
/**
* The source EPG ID
*/
namespace gbp_contract_cmds {
create_cmd::create_cmd(HW::item<uint32_t>& 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)
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));
}
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;
}
delete_cmd::delete_cmd(HW::item<uint32_t>& item,
+ scope_t scope,
sclass_t sclass,
sclass_t dclass)
: rpc_cmd(item)
+ , m_scope(scope)
, m_sclass(sclass)
, m_dclass(dclass)
{
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;
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());
* Constructor
*/
create_cmd(HW::item<uint32_t>& item,
+ scope_t scope,
sclass_t sclass,
sclass_t dclass,
const handle_t& acl,
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;
/**
* Constructor
*/
- delete_cmd(HW::item<uint32_t>& item, sclass_t sclass, sclass_t dclass);
+ delete_cmd(HW::item<uint32_t>& item,
+ scope_t scope,
+ sclass_t sclass,
+ sclass_t dclass);
/**
* Issue the command to VPP/HW
bool operator==(const delete_cmd& i) const;
private:
+ const scope_t m_scope;
const sclass_t m_sclass;
const sclass_t m_dclass;
};
#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
*/
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<interface> ip4_uu_fwd,
const std::shared_ptr<interface> 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)
{
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()
{
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
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));
}
}
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() << "]";
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));
}
}
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();
}
#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"
/**
* 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<interface> ip4_uu_fwd,
const std::shared_ptr<interface> ip6_uu_fwd);
HW::item<uint32_t> m_id;
std::shared_ptr<route_domain> m_rd;
+ scope_t m_scope;
std::shared_ptr<interface> m_ip4_uu_fwd;
std::shared_ptr<interface> m_ip6_uu_fwd;
namespace gbp_route_domain_cmds {
create_cmd::create_cmd(HW::item<uint32_t>& 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)
{
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));
}
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();
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();
* Constructor
*/
create_cmd(HW::item<uint32_t>& item,
+ scope_t scope,
const handle_t ip4_uu_fwd,
const handle_t ip6_uu_fwd);
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;
};
--- /dev/null
+/*
+ * 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 <stdint.h>
+
+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
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;
vl_api_gbp_bridge_domain_t bd;
};
+typedef u16 gbp_scope;
+
typedef gbp_route_domain
{
u32 rd_id;
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
typedef gbp_contract
{
+ vl_api_gbp_scope_t scope;
u16 sclass;
u16 dclass;
u32 acl_index;
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),
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),
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;
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);
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:
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);
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));
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));
*/
#include <plugins/gbp/gbp_bridge_domain.h>
+#include <plugins/gbp/gbp_route_domain.h>
#include <plugins/gbp/gbp_endpoint.h>
#include <plugins/gbp/gbp_learn.h>
*/
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
*/
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,
if (INDEX_INVALID == gbi)
{
+ gbp_route_domain_t *gr;
u32 bd_index;
bd_index = bd_find_index (&bd_main, 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
}
gbp_bridge_domain_db_remove (gb);
+ gbp_route_domain_unlock (gb->gb_rdi);
pool_put (gbp_bridge_domain_pool, gb);
}
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;
;
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);
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
*/
} 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,
(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
/*
}
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,
uword *p;
gbp_contract_key_t key = {
+ .gck_scope = scope,
.gck_src = sclass,
.gck_dst = dclass,
};
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];
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);
}
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]);
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);
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)
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))
;
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);
{
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);
}
{
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;
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);
{
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]);
* 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,
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;
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)
{
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);
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;
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
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;
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,
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;
}
*/
sclass_t gpd_sclass;
+ /**
+ * sclass scope
+ */
+ gbp_scope_t gpd_scope;
+
/**
* output sw_if_index
*/
} 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);
#include <plugins/gbp/gbp.h>
#include <plugins/gbp/gbp_policy_dpo.h>
+#include <plugins/gbp/gbp_bridge_domain.h>
#include <vnet/vxlan-gbp/vxlan_gbp_packet.h>
#include <vnet/vxlan-gbp/vxlan_gbp.h>
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;
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
*/
L2OUTPUT_FEAT_GBP_POLICY_PORT :
L2OUTPUT_FEAT_GBP_POLICY_MAC));
n_allow_a_bit++;
- key0.as_u32 = ~0;
+ key0.as_u64 = ~0;
goto trace;
}
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 */
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;
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;
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)
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;
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)
{
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;
add = 0;
else if (unformat (input, "rd %d", &rd_id))
;
+ else if (unformat (input, "scope %d", &scope))
+ ;
else
break;
}
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);
}
* 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];
} 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,
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);
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);
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,
typedef u32 vnid_t;
#define VNID_INVALID ((u16)~0)
+typedef u16 gbp_scope_t;
typedef u16 sclass_t;
#define SCLASS_INVALID ((u16)~0)
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):
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,
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
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,
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
is_add=1,
contract={
'acl_index': self.acl_index,
+ 'scope': self.scope,
'sclass': self.sclass,
'dclass': self.dclass,
'n_rules': len(rules),
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
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
#
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
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,
# 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,
# 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,
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,
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,
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()
#
#
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"))
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,
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
#
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.
#
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,
# 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,
# 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,
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()
#
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"))
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()
#
#
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()
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)
#
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"))
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)
#
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
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()
#
# 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,
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,
# 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,
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,
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,
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,
# 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,
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)
#
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()
#
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
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,
# 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,
[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,
# 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,
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):
'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):
{'bd_id': bd_id})
def gbp_route_domain_add(self, rd_id,
+ scope,
ip4_table_id,
ip6_table_id,
ip4_uu_sw_if_index,
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,