FD.io VPP  v19.01.2-3-gf61a1a8
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 
28  epg_id_t dst_epg_id,
29  const ACL::l3_list& acl,
30  const gbp_rules_t& rules,
32  : m_hw(false)
33  , m_src_epg_id(src_epg_id)
34  , m_dst_epg_id(dst_epg_id)
35  , m_acl(acl.singular())
36  , m_gbp_rules(rules)
37  , m_allowed_ethertypes(allowed_ethertypes)
38 {
39 }
40 
42  : m_hw(gbpc.m_hw)
43  , m_src_epg_id(gbpc.m_src_epg_id)
44  , m_dst_epg_id(gbpc.m_dst_epg_id)
45  , m_acl(gbpc.m_acl)
46  , m_gbp_rules(gbpc.m_gbp_rules)
47  , m_allowed_ethertypes(gbpc.m_allowed_ethertypes)
48 {
49 }
50 
52 {
53  sweep();
54 
55  // not in the DB anymore.
56  m_db.release(key(), this);
57 }
58 
61 {
62  return (std::make_pair(m_src_epg_id, m_dst_epg_id));
63 }
64 
65 bool
67 {
68  return ((key() == gbpc.key()) && (m_acl->handle() == gbpc.m_acl->handle()));
69 }
70 
71 void
72 gbp_contract::sweep()
73 {
74  if (m_hw) {
76  new gbp_contract_cmds::delete_cmd(m_hw, m_src_epg_id, m_dst_epg_id));
77  }
78  HW::write();
79 }
80 
81 void
83 {
84  if (m_hw) {
86  m_hw, m_src_epg_id, m_dst_epg_id, m_acl->handle(), m_gbp_rules,
87  m_allowed_ethertypes));
88  }
89 }
90 
91 std::string
93 {
94  std::ostringstream s;
95  s << "gbp-contract:[{" << m_src_epg_id << ", " << m_dst_epg_id << "}, "
96  << m_acl->to_string();
97  if (m_gbp_rules.size()) {
98  auto it = m_gbp_rules.cbegin();
99  while (it != m_gbp_rules.cend()) {
100  s << it->to_string();
101  ++it;
102  }
103  }
104  s << "]";
105 
106  return (s.str());
107 }
108 
109 void
110 gbp_contract::update(const gbp_contract& r)
111 {
112  /*
113  * create the table if it is not yet created
114  */
115  if (rc_t::OK != m_hw.rc()) {
117  m_hw, m_src_epg_id, m_dst_epg_id, m_acl->handle(), m_gbp_rules,
118  m_allowed_ethertypes));
119  }
120 }
121 
122 std::shared_ptr<gbp_contract>
123 gbp_contract::find_or_add(const gbp_contract& temp)
124 {
125  return (m_db.find_or_add(temp.key(), temp));
126 }
127 
128 std::shared_ptr<gbp_contract>
130 {
131  return (m_db.find(k));
132 }
133 
134 std::shared_ptr<gbp_contract>
136 {
137  return find_or_add(*this);
138 }
139 
140 void
141 gbp_contract::dump(std::ostream& os)
142 {
143  db_dump(m_db, os);
144 }
145 
147 {
148  OM::register_listener(this);
149  inspect::register_handler({ "gbp-contract" }, "GBP Contract", this);
150 }
151 
152 void
153 gbp_contract::event_handler::handle_replay()
154 {
155  m_db.replay();
156 }
157 
158 void
159 gbp_contract::event_handler::handle_populate(const client_db::key_t& key)
160 {
161  std::shared_ptr<gbp_contract_cmds::dump_cmd> cmd =
162  std::make_shared<gbp_contract_cmds::dump_cmd>();
163 
164  HW::enqueue(cmd);
165  HW::write();
166 
167  for (auto& record : *cmd) {
168  auto& payload = record.get_payload();
169 
170  std::shared_ptr<ACL::l3_list> acl =
171  ACL::l3_list::find(payload.contract.acl_index);
172 
173  if (acl) {
175 
176  for (uint8_t i = 0; i < payload.contract.n_rules; i++) {
177  const gbp_rule::action_t action =
178  gbp_rule::action_t::from_int(payload.contract.rules[i].action);
180  payload.contract.rules[i].nh_set.hash_mode);
182  for (u8 j = 0; j < payload.contract.rules[i].nh_set.n_nhs; j++) {
184  from_api(payload.contract.rules[i].nh_set.nhs[j].ip),
185  from_api(payload.contract.rules[i].nh_set.nhs[j].mac),
186  payload.contract.rules[i].nh_set.nhs[j].bd_id,
187  payload.contract.rules[i].nh_set.nhs[j].rd_id);
188  nhs.insert(nh);
189  }
190  gbp_rule::next_hop_set_t next_hop_set(hm, nhs);
191  gbp_rule gr(i, next_hop_set, action);
192  rules.insert(gr);
193  }
194 
196  u8 *data, n_et;
197  u16* et;
198 
199  data = (((u8*)&payload.contract.n_ether_types) +
200  (sizeof(payload.contract.rules[0]) * payload.contract.n_rules));
201  n_et = *data;
202  et = (u16*)(++data);
203 
204  for (uint8_t i = 0; i < n_et; i++) {
205  allowed_ethertypes.insert(ethertype_t::from_numeric_val(et[i]));
206  }
207 
208  gbp_contract gbpc(payload.contract.src_epg, payload.contract.dst_epg,
209  *acl, rules, allowed_ethertypes);
210  OM::commit(key, gbpc);
211 
212  VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string();
213  } else {
214  VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index;
215  }
216  }
217 }
218 
220 gbp_contract::event_handler::order() const
221 {
222  return (dependency_t::ENTRY);
223 }
224 
225 void
226 gbp_contract::event_handler::show(std::ostream& os)
227 {
228  db_dump(m_db, os);
229 }
230 
231 std::ostream&
232 operator<<(std::ostream& os, const gbp_contract::key_t& key)
233 {
234  os << "{ " << key.first << "," << key.second << "}";
235 
236  return (os);
237 }
238 
239 } // namespace VOM
240 
241 /*
242  * fd.io coding-style-patch-verification: ON
243  *
244  * Local Variables:
245  * eval: (c-set-style "mozilla")
246  * End:
247  */
const key_t key() const
Return the object&#39;s key.
#define VOM_LOG(lvl)
Definition: logger.hpp:181
void db_dump(const DB &db, std::ostream &os)
Print each of the objects in the DB into the stream provided.
const 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
An ACL list comprises a set of match actions rules to be applied to packets.
Definition: acl_list.hpp:37
uint32_t epg_id_t
EPG IDs are 32 bit integers.
static void dump(std::ostream &os)
Dump all bridge_domain-doamin into the stream provided.
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
int i
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
static const log_level_t DEBUG
Definition: logger.hpp:32
static const ethertype_t & from_numeric_val(uint16_t numeric)
Get the ethertype from the numeric value.
Definition: types.cpp:300
ip_address_t from_api(const vapi_type_address &v)
Definition: api_types.cpp:53
unsigned char u8
Definition: types.h:56
static std::shared_ptr< list > find(const handle_t &handle)
Definition: acl_list.hpp:135
std::set< ethertype_t > ethertype_set_t
A set of allowed ethertypes.
std::shared_ptr< gbp_contract > singular() const
Return the matching &#39;singular instance&#39;.
ACL rule action enum.
Definition: gbp_rule.hpp:192
u16 allowed_ethertypes[n_ether_types]
Definition: gbp.api:299
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:119
bool operator==(const gbp_contract &bdae) const
comparison operator
void replay(void)
replay the object to create it in hardware
unsigned short u16
Definition: types.h:57
Representation of set of next hops and associated hash mode profile.
Definition: gbp_rule.hpp:144
gbp_contract(epg_id_t src_epg_id, epg_id_t dst_epg_id, const ACL::l3_list &acl, const gbp_rules_t &gpb_rules, const ethertype_set_t &allowed_ethertypes)
Construct a GBP contract.
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:275
A entry in the ARP termination table of a Bridge Domain.
~gbp_contract()
Destructor.
std::pair< epg_id_t, epg_id_t > key_t
The key for a contract is the pari of EPG-IDs.
std::string to_string() const
Convert to string for debugging.
A command class that creates or updates the GBP contract.
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:297
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
void event_handler(void *tls_async)
Definition: tls_async.c:340
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
Representation of next hop.
Definition: gbp_rule.hpp:30
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:109
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:212
static const log_level_t ERROR
Definition: logger.hpp:29
std::set< gbp_rule > gbp_rules_t
set of gbp rules
std::ostream & operator<<(std::ostream &os, const std::pair< direction_t, interface::key_t > &key)
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
A representation of a method call to VPP.
Definition: cmd.hpp:32
std::set< next_hop_t > next_hops_t
unordered set of next hops
Definition: gbp_rule.hpp:138
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
static std::shared_ptr< gbp_contract > find(const key_t &k)
Find the instnace of the bridge_domain domain in the OM.
A cmd class that deletes a GBP contract.
Entries in Tables.
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
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127
static const action_t & from_int(vapi_enum_gbp_rule_action i)
create the action from int value
Definition: gbp_rule.cpp:158