FD.io VPP  v19.04.2-12-g66b1689
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 
29  const ACL::l3_list& acl,
30  const gbp_rules_t& rules,
32  : m_hw(false)
33  , m_sclass(sclass)
34  , m_dclass(dclass)
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_sclass(gbpc.m_sclass)
44  , m_dclass(gbpc.m_dclass)
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_sclass, m_dclass));
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) {
75  HW::enqueue(new gbp_contract_cmds::delete_cmd(m_hw, m_sclass, m_dclass));
76  }
77  HW::write();
78 }
79 
80 void
82 {
83  if (m_hw) {
84  HW::enqueue(new gbp_contract_cmds::create_cmd(m_hw, m_sclass, m_dclass,
85  m_acl->handle(), m_gbp_rules,
86  m_allowed_ethertypes));
87  }
88 }
89 
90 std::string
92 {
93  std::ostringstream s;
94  s << "gbp-contract:[{" << m_sclass << ", " << m_dclass << "}, "
95  << m_acl->to_string();
96  if (m_gbp_rules.size()) {
97  auto it = m_gbp_rules.cbegin();
98  while (it != m_gbp_rules.cend()) {
99  s << it->to_string();
100  ++it;
101  }
102  }
103  s << "[ethertype:";
104  for (auto e : m_allowed_ethertypes)
105  s << " " << e;
106  s << "]]";
107 
108  return (s.str());
109 }
110 
111 void
112 gbp_contract::update(const gbp_contract& r)
113 {
114  /*
115  * create the table if it is not yet created
116  */
117  if (rc_t::OK != m_hw.rc()) {
118  HW::enqueue(new gbp_contract_cmds::create_cmd(m_hw, m_sclass, m_dclass,
119  m_acl->handle(), m_gbp_rules,
120  m_allowed_ethertypes));
121  }
122 }
123 
124 std::shared_ptr<gbp_contract>
125 gbp_contract::find_or_add(const gbp_contract& temp)
126 {
127  return (m_db.find_or_add(temp.key(), temp));
128 }
129 
130 std::shared_ptr<gbp_contract>
132 {
133  return (m_db.find(k));
134 }
135 
136 std::shared_ptr<gbp_contract>
138 {
139  return find_or_add(*this);
140 }
141 
142 void
143 gbp_contract::dump(std::ostream& os)
144 {
145  db_dump(m_db, os);
146 }
147 
149 {
150  OM::register_listener(this);
151  inspect::register_handler({ "gbp-contract" }, "GBP Contract", this);
152 }
153 
154 void
155 gbp_contract::event_handler::handle_replay()
156 {
157  m_db.replay();
158 }
159 
160 void
161 gbp_contract::event_handler::handle_populate(const client_db::key_t& key)
162 {
163  std::shared_ptr<gbp_contract_cmds::dump_cmd> cmd =
164  std::make_shared<gbp_contract_cmds::dump_cmd>();
165 
166  HW::enqueue(cmd);
167  HW::write();
168 
169  for (auto& record : *cmd) {
170  auto& payload = record.get_payload();
171 
172  std::shared_ptr<ACL::l3_list> acl =
173  ACL::l3_list::find(payload.contract.acl_index);
174 
175  if (acl) {
177 
178  for (uint8_t i = 0; i < payload.contract.n_rules; i++) {
179  const gbp_rule::action_t action =
180  gbp_rule::action_t::from_int(payload.contract.rules[i].action);
182  payload.contract.rules[i].nh_set.hash_mode);
184  for (u8 j = 0; j < payload.contract.rules[i].nh_set.n_nhs; j++) {
186  from_api(payload.contract.rules[i].nh_set.nhs[j].ip),
187  from_api(payload.contract.rules[i].nh_set.nhs[j].mac),
188  payload.contract.rules[i].nh_set.nhs[j].bd_id,
189  payload.contract.rules[i].nh_set.nhs[j].rd_id);
190  nhs.insert(nh);
191  }
192  gbp_rule::next_hop_set_t next_hop_set(hm, nhs);
193  gbp_rule gr(i, next_hop_set, action);
194  rules.insert(gr);
195  }
196 
198  u8 *data, n_et;
199  u16* et;
200 
201  data = (((u8*)&payload.contract.n_ether_types) +
202  (sizeof(payload.contract.rules[0]) * payload.contract.n_rules));
203  n_et = *data;
204  et = (u16*)(++data);
205 
206  for (uint8_t i = 0; i < n_et; i++) {
207  allowed_ethertypes.insert(ethertype_t::from_numeric_val(et[i]));
208  }
209 
210  gbp_contract gbpc(payload.contract.sclass, payload.contract.dclass, *acl,
211  rules, allowed_ethertypes);
212  OM::commit(key, gbpc);
213 
214  VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string();
215  } else {
216  VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index;
217  }
218  }
219 }
220 
222 gbp_contract::event_handler::order() const
223 {
224  return (dependency_t::ENTRY);
225 }
226 
227 void
228 gbp_contract::event_handler::show(std::ostream& os)
229 {
230  db_dump(m_db, os);
231 }
232 
233 std::ostream&
234 operator<<(std::ostream& os, const gbp_contract::key_t& key)
235 {
236  os << "{ " << key.first << "," << key.second << "}";
237 
238  return (os);
239 }
240 
241 } // namespace VOM
242 
243 /*
244  * fd.io coding-style-patch-verification: ON
245  *
246  * Local Variables:
247  * eval: (c-set-style "mozilla")
248  * End:
249  */
An L3 ACL list comprises a set of match actions rules to be applied to packets.
Definition: acl_l3_list.hpp:35
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.
uint16_t sclass_t
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
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
u8 data[128]
Definition: ipsec.api:248
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
unsigned char u8
Definition: types.h:56
static std::shared_ptr< l3_list > find(const handle_t &handle)
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
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
u16 sclass
Definition: gbp.api:118
Representation of set of next hops and associated hash mode profile.
Definition: gbp_rule.hpp:144
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:284
A entry in the ARP termination table of a Bridge Domain.
std::pair< sclass_t, sclass_t > key_t
The key for a contract is the pair of EPG-IDs.
~gbp_contract()
Destructor.
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:308
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
const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f)
Definition: api_types.cpp:36
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.
gbp_contract(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.
A cmd class that deletes a GBP contract.
Entries in Tables.
u16 allowed_ethertypes[16]
Definition: gbp.api:306
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
u16 dclass
Definition: gbp.api:303