gbp: VRF scoped contracts 42/20242/10
authorNeale Ranns <nranns@cisco.com>
Wed, 19 Jun 2019 13:25:56 +0000 (06:25 -0700)
committerDamjan Marion <dmarion@me.com>
Mon, 1 Jul 2019 08:37:53 +0000 (08:37 +0000)
Type: feature

Change-Id: I01772cfc3a0118a5c49bf346339788824e6931b2
Signed-off-by: Neale Ranns <nranns@cisco.com>
33 files changed:
extras/vom/CMakeLists.txt
extras/vom/vom/CMakeLists.txt
extras/vom/vom/gbp_bridge_domain.cpp
extras/vom/vom/gbp_bridge_domain.hpp
extras/vom/vom/gbp_bridge_domain_cmds.cpp
extras/vom/vom/gbp_bridge_domain_cmds.hpp
extras/vom/vom/gbp_contract.cpp
extras/vom/vom/gbp_contract.hpp
extras/vom/vom/gbp_contract_cmds.cpp
extras/vom/vom/gbp_contract_cmds.hpp
extras/vom/vom/gbp_endpoint_group.hpp
extras/vom/vom/gbp_route_domain.cpp
extras/vom/vom/gbp_route_domain.hpp
extras/vom/vom/gbp_route_domain_cmds.cpp
extras/vom/vom/gbp_route_domain_cmds.hpp
extras/vom/vom/gbp_types.hpp [new file with mode: 0644]
src/plugins/gbp/gbp.api
src/plugins/gbp/gbp_api.c
src/plugins/gbp/gbp_api_print.h
src/plugins/gbp/gbp_bridge_domain.c
src/plugins/gbp/gbp_bridge_domain.h
src/plugins/gbp/gbp_contract.c
src/plugins/gbp/gbp_contract.h
src/plugins/gbp/gbp_endpoint.c
src/plugins/gbp/gbp_policy_dpo.c
src/plugins/gbp/gbp_policy_dpo.h
src/plugins/gbp/gbp_policy_node.c
src/plugins/gbp/gbp_route_domain.c
src/plugins/gbp/gbp_route_domain.h
src/plugins/gbp/gbp_subnet.c
src/plugins/gbp/gbp_types.h
test/test_gbp.py
test/vpp_papi_provider.py

index 4853196..3a32117 100644 (file)
@@ -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)
index 26dd3e4..1447499 100644 (file)
@@ -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()
index cfa0768..3e015c3 100644 (file)
@@ -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<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)
@@ -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<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)
@@ -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<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)
@@ -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
index 44cf299..264f8b3 100644 (file)
@@ -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<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,
@@ -192,6 +196,7 @@ private:
   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;
index 082bd4b..05064df 100644 (file)
@@ -19,11 +19,13 @@ namespace VOM {
 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)
@@ -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();
index a4fd0d5..6dbe6dc 100644 (file)
@@ -35,6 +35,7 @@ public:
    * 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,
@@ -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;
index c95c2e8..8fcef02 100644 (file)
@@ -24,12 +24,14 @@ singular_db<gbp_contract::key_t, gbp_contract> 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);
 }
index 2e8f9d0..caf5a3c 100644 (file)
@@ -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<sclass_t, sclass_t> key_t;
+  typedef std::tuple<scope_t, sclass_t, sclass_t> 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<uint32_t> m_hw;
 
+  /*
+   * The scope of the contract
+   */
+  scope_t m_scope;
+
   /**
    * The source EPG ID
    */
index 6aed999..1bb06bd 100644 (file)
@@ -20,12 +20,14 @@ namespace VOM {
 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)
@@ -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<uint32_t>& 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());
index 3b3fab9..d9fe1d7 100644 (file)
@@ -35,6 +35,7 @@ public:
    * Constructor
    */
   create_cmd(HW::item<uint32_t>& 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<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
@@ -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;
 };
index 5c061a9..e15a188 100644 (file)
 
 #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
  */
index 8f0eae3..54b51cf 100644 (file)
@@ -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<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)
 {
@@ -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();
     }
index d2dc049..dd09673 100644 (file)
@@ -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<interface> ip4_uu_fwd,
                    const std::shared_ptr<interface> ip6_uu_fwd);
 
@@ -171,6 +174,7 @@ private:
   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;
 
index 9b8b4be..90e81f3 100644 (file)
@@ -19,9 +19,11 @@ namespace VOM {
 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)
 {
@@ -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();
 
index 249ba90..6ef9fcd 100644 (file)
@@ -35,6 +35,7 @@ public:
    * Constructor
    */
   create_cmd(HW::item<uint32_t>& 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 (file)
index 0000000..5b46e08
--- /dev/null
@@ -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 <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
index b0b284f..f6775e7 100644 (file)
@@ -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;
index db8c8c6..8155a8f 100644 (file)
@@ -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);
 
index 7598306..67cd30c 100644 (file)
@@ -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));
index 5310545..6c14fbc 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #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>
 
@@ -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);
index dd2798f..5bfa099 100644 (file)
@@ -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
 
 /*
index 552201a..f0bb00a 100644 (file)
@@ -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);
 }
index 9de52eb..8e621a4 100644 (file)
@@ -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]);
index 2472199..da15b49 100644 (file)
@@ -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,
index a707789..8152315 100644 (file)
@@ -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;
 }
index 3a4264d..6b4f8c5 100644 (file)
@@ -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);
 
index 2cffc79..26f7e9b 100644 (file)
@@ -15,6 +15,7 @@
 
 #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>
@@ -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;
index 7502a25..90b0155 100644 (file)
@@ -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);
     }
index b83d598..dd7adf0 100644 (file)
@@ -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);
index 2daf0dd..e2dfd37 100644 (file)
@@ -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,
index 5bd9735..ac983b1 100644 (file)
@@ -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)
 
index ac0fb22..1b81713 100644 (file)
@@ -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,
index 29a5716..c7390ee 100644 (file)
@@ -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,