FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
gbp_contract.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vom/gbp_contract.hpp"
17 #include "vom/api_types.hpp"
20 
21 namespace VOM {
22 
23 singular_db<gbp_contract::key_t, gbp_contract> gbp_contract::m_db;
24 
25 gbp_contract::event_handler gbp_contract::m_evh;
26 
30  const ACL::l3_list& acl,
31  const gbp_rules_t& rules,
33  : m_hw(false)
34  , m_scope(scope)
35  , m_sclass(sclass)
36  , m_dclass(dclass)
37  , m_acl(acl.singular())
38  , m_gbp_rules(rules)
39  , m_allowed_ethertypes(allowed_ethertypes)
40 {
41 }
42 
44  : m_hw(gbpc.m_hw)
45  , m_scope(gbpc.m_scope)
46  , m_sclass(gbpc.m_sclass)
47  , m_dclass(gbpc.m_dclass)
48  , m_acl(gbpc.m_acl)
49  , m_gbp_rules(gbpc.m_gbp_rules)
50  , m_allowed_ethertypes(gbpc.m_allowed_ethertypes)
51 {
52 }
53 
55 {
56  sweep();
57 
58  // not in the DB anymore.
59  m_db.release(key(), this);
60 }
61 
64 {
65  return (std::make_tuple(m_scope, m_sclass, m_dclass));
66 }
67 
68 bool
70 {
71  return ((key() == gbpc.key()) && (m_acl->handle() == gbpc.m_acl->handle()));
72 }
73 
74 void
75 gbp_contract::sweep()
76 {
77  if (m_hw) {
79  new gbp_contract_cmds::delete_cmd(m_hw, m_scope, m_sclass, m_dclass));
80  }
81  HW::write();
82 }
83 
84 void
86 {
87  if (m_hw) {
89  m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules,
90  m_allowed_ethertypes));
91  }
92 }
93 
96 {
97  std::ostringstream s;
98  s << "gbp-contract:[{" << m_scope << ", " << m_sclass << ", " << m_dclass
99  << "}, " << m_acl->to_string();
100  if (m_gbp_rules.size()) {
101  auto it = m_gbp_rules.cbegin();
102  while (it != m_gbp_rules.cend()) {
103  s << it->to_string();
104  ++it;
105  }
106  }
107  s << "[ethertype:";
108  for (auto e : m_allowed_ethertypes)
109  s << " " << e;
110  s << "]]";
111 
112  return (s.str());
113 }
114 
115 void
116 gbp_contract::update(const gbp_contract& r)
117 {
118  /*
119  * create the table if it is not yet created
120  */
121  if (rc_t::OK != m_hw.rc()) {
123  m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules,
124  m_allowed_ethertypes));
125  }
126 }
127 
128 std::shared_ptr<gbp_contract>
129 gbp_contract::find_or_add(const gbp_contract& temp)
130 {
131  return (m_db.find_or_add(temp.key(), temp));
132 }
133 
134 std::shared_ptr<gbp_contract>
136 {
137  return (m_db.find(k));
138 }
139 
140 std::shared_ptr<gbp_contract>
142 {
143  return find_or_add(*this);
144 }
145 
146 void
147 gbp_contract::dump(std::ostream& os)
148 {
149  db_dump(m_db, os);
150 }
151 
153 {
154  OM::register_listener(this);
155  inspect::register_handler({ "gbp-contract" }, "GBP Contract", this);
156 }
157 
158 void
159 gbp_contract::event_handler::handle_replay()
160 {
161  m_db.replay();
162 }
163 
164 void
165 gbp_contract::event_handler::handle_populate(const client_db::key_t& key)
166 {
167  std::shared_ptr<gbp_contract_cmds::dump_cmd> cmd =
168  std::make_shared<gbp_contract_cmds::dump_cmd>();
169 
170  HW::enqueue(cmd);
171  HW::write();
172 
173  for (auto& record : *cmd) {
174  auto& payload = record.get_payload();
175 
176  std::shared_ptr<ACL::l3_list> acl =
177  ACL::l3_list::find(payload.contract.acl_index);
178 
179  if (acl) {
181 
182  for (uint8_t i = 0; i < payload.contract.n_rules; i++) {
183  const gbp_rule::action_t action =
184  gbp_rule::action_t::from_int(payload.contract.rules[i].action);
185  const gbp_rule::hash_mode_t hm = gbp_rule::hash_mode_t::from_int(
186  payload.contract.rules[i].nh_set.hash_mode);
188  for (u8 j = 0; j < payload.contract.rules[i].nh_set.n_nhs; j++) {
189  gbp_rule::next_hop_t nh(
190  from_api(payload.contract.rules[i].nh_set.nhs[j].ip),
191  from_api(payload.contract.rules[i].nh_set.nhs[j].mac),
192  payload.contract.rules[i].nh_set.nhs[j].bd_id,
193  payload.contract.rules[i].nh_set.nhs[j].rd_id);
194  nhs.insert(nh);
195  }
196  gbp_rule::next_hop_set_t next_hop_set(hm, nhs);
197  gbp_rule gr(i, next_hop_set, action);
198  rules.insert(gr);
199  }
200 
201  ethertype_set_t allowed_ethertypes;
202  u8 *data, n_et;
203  u16* et;
204 
205  data = (((u8*)&payload.contract.n_ether_types) +
206  (sizeof(payload.contract.rules[0]) * payload.contract.n_rules));
207  n_et = *data;
208  et = (u16*)(++data);
209 
210  for (uint8_t i = 0; i < n_et; i++) {
212  }
213 
214  gbp_contract gbpc(payload.contract.scope, payload.contract.sclass,
215  payload.contract.dclass, *acl, rules,
217  OM::commit(key, gbpc);
218  VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string();
219  } else {
220  VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index;
221  }
222  }
223 }
224 
226 gbp_contract::event_handler::order() const
227 {
228  return (dependency_t::ENTRY);
229 }
230 
231 void
232 gbp_contract::event_handler::show(std::ostream& os)
233 {
234  db_dump(m_db, os);
235 }
236 
237 std::ostream&
238 operator<<(std::ostream& os, const gbp_contract::key_t& key)
239 {
240  os << "{ " << std::get<0>(key) << "," << std::get<1>(key) << ", "
241  << std::get<2>(key) << "}";
242 
243  return (os);
244 }
245 
246 } // namespace VOM
247 
248 /*
249  * fd.io coding-style-patch-verification: OFF
250  *
251  * Local Variables:
252  * eval: (c-set-style "mozilla")
253  * End:
254  */
VOM::HW::write
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
VOM::OM::commit
static rc_t commit(const client_db::key_t &key, const OBJ &obj)
Make the State in VPP reflect the expressed desired state.
Definition: om.hpp:202
gbp_contract
typedef gbp_contract
Definition: gbp.api:330
VOM_LOG
#define VOM_LOG(lvl)
Definition: logger.hpp:181
VOM
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
VOM::scope_t
uint16_t scope_t
Definition: gbp_types.hpp:28
VOM::inspect::register_handler
static void register_handler(const std::vector< std::string > &cmds, const std::string &help, command_handler *ch)
Register a command handler for inspection.
Definition: inspect.cpp:85
VOM::dependency_t
dependency_t
There needs to be a strict order in which object types are read from VPP (at boot time) and replayed ...
Definition: types.hpp:43
VOM::rc_t::OK
const static rc_t OK
The HW write was successfull.
Definition: types.hpp:109
VOM::gbp_contract::operator==
bool operator==(const gbp_contract &bdae) const
comparison operator
Definition: gbp_contract.cpp:69
VOM::gbp_contract::key
const key_t key() const
Return the object's key.
Definition: gbp_contract.cpp:63
VOM::gbp_rule::next_hops_t
std::set< next_hop_t > next_hops_t
unordered set of next hops
Definition: gbp_rule.hpp:138
VOM::gbp_contract::dump
static void dump(std::ostream &os)
Dump all bridge_domain-doamin into the stream provided.
Definition: gbp_contract.cpp:147
VOM::gbp_contract_cmds::create_cmd
A command class that creates or updates the GBP contract.
Definition: gbp_contract_cmds.hpp:30
u16
unsigned short u16
Definition: types.h:57
nhs
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:313
VOM::dependency_t::ENTRY
@ ENTRY
Entries in Tables.
VOM::sclass_t
uint16_t sclass_t
Definition: gbp_types.hpp:27
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
allowed_ethertypes
u16 allowed_ethertypes[16]
Definition: gbp.api:336
gbp_contract.hpp
key
typedef key
Definition: ipsec_types.api:91
VOM::gbp_contract::to_string
std::string to_string() const
Convert to string for debugging.
Definition: gbp_contract.cpp:95
VOM::db_dump
void db_dump(const DB &db, std::ostream &os)
Print each of the objects in the DB into the stream provided.
Definition: singular_db_funcs.hpp:35
VOM::gbp_contract::ethertype_set_t
std::set< ethertype_t > ethertype_set_t
A set of allowed ethertypes.
Definition: gbp_contract.hpp:47
VOM::ACL::l3_list::find
static std::shared_ptr< l3_list > find(const handle_t &handle)
Definition: acl_l3_list.cpp:123
VOM::OM::register_listener
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127
VOM::ethertype_t::from_numeric_val
static const ethertype_t & from_numeric_val(uint16_t numeric)
Get the ethertype from the numeric value.
Definition: types.cpp:300
VOM::gbp_contract::replay
void replay(void)
replay the object to create it in hardware
Definition: gbp_contract.cpp:85
VOM::gbp_contract_cmds::delete_cmd
A cmd class that deletes a GBP contract.
Definition: gbp_contract_cmds.hpp:72
VOM::gbp_contract::key_t
std::tuple< scope_t, sclass_t, sclass_t > key_t
The key for a contract is the pair of EPG-IDs.
Definition: gbp_contract.hpp:42
VOM::client_db::key_t
const typedef std::string key_t
In the opflex world each entity is known by a URI which can be converted into a string.
Definition: client_db.hpp:51
scope
vl_api_gbp_scope_t scope
Definition: gbp.api:78
VOM::HW::enqueue
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:212
nh
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
it
save_rewrite_length must be aligned so that reass doesn t overwrite it
Definition: buffer.h:425
VOM::gbp_contract::~gbp_contract
~gbp_contract()
Destructor.
Definition: gbp_contract.cpp:54
sclass
u16 sclass
Definition: gbp.api:131
VOM::log_level_t::DEBUG
const static log_level_t DEBUG
Definition: logger.hpp:32
VOM::operator<<
std::ostream & operator<<(std::ostream &os, const std::pair< direction_t, interface::key_t > &key)
Definition: acl_binding.cpp:201
VOM::ACL::l3_list
An L3 ACL list comprises a set of match actions rules to be applied to packets.
Definition: acl_l3_list.hpp:35
data
u8 data[128]
Definition: ipsec_types.api:95
false
#define false
Definition: cJSON.c:70
singular_db_funcs.hpp
VOM::gbp_rule::action_t::from_int
static const action_t & from_int(vapi_enum_gbp_rule_action i)
create the action from int value
Definition: gbp_rule.cpp:158
gbp_contract_cmds.hpp
dclass
u16 dclass
Definition: gbp.api:333
VOM::HW::item::rc
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:119
VOM::gbp_contract::gbp_rules_t
std::set< gbp_rule > gbp_rules_t
set of gbp rules
Definition: gbp_contract.hpp:37
rules
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:338
VOM::gbp_contract::gbp_contract
gbp_contract(scope_t scope, sclass_t sclass, sclass_t dclass, const ACL::l3_list &acl, const gbp_rules_t &gpb_rules, const ethertype_set_t &allowed_ethertypes)
Construct a GBP contract.
Definition: gbp_contract.cpp:27
u8
unsigned char u8
Definition: types.h:56
gbp_rule
typedef gbp_rule
Definition: gbp.api:324
i
int i
Definition: flowhash_template.h:376
VOM::gbp_rule::hash_mode_t::from_int
static const hash_mode_t & from_int(vapi_enum_gbp_hash_mode i)
create the hash mode from int value
Definition: gbp_rule.cpp:91
show
void show(char *chroot_path, int verbose)
Definition: svmtool.c:104
event_handler
void event_handler(void *tls_async)
Definition: tls_async.c:334
VOM::gbp_contract::singular
std::shared_ptr< gbp_contract > singular() const
Return the matching 'singular instance'.
Definition: gbp_contract.cpp:141
VOM::gbp_contract::find
static std::shared_ptr< gbp_contract > find(const key_t &k)
Find the instnace of the bridge_domain domain in the OM.
Definition: gbp_contract.cpp:135
action
vl_api_mac_event_action_t action
Definition: l2.api:211
VOM::gbp_contract
A entry in the ARP termination table of a Bridge Domain.
Definition: gbp_contract.hpp:31
VOM::log_level_t::ERROR
const static log_level_t ERROR
Definition: logger.hpp:29
VOM::from_api
const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f)
Definition: api_types.cpp:36
api_types.hpp
string
const char *const string
Definition: cJSON.h:172