FD.io VPP  v18.10-32-g1161dda
Vector Packet Processing
acl_list.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/acl_list.hpp"
17 #include "vom/acl_list_cmds.hpp"
18 #include "vom/logger.hpp"
20 
21 namespace VOM {
22 namespace ACL {
23 
24 template <>
26 {
28  inspect::register_handler({ "l2-acl-list" }, "L2 ACL lists", this);
29 }
30 
31 template <>
32 void
33 l2_list::event_handler::handle_populate(const client_db::key_t& key)
34 {
35  /* hack to get this function instantiated */
36  m_evh.order();
37 
38  /*
39  * dump VPP Bridge domains
40  */
41  std::shared_ptr<list_cmds::l2_dump_cmd> cmd =
42  std::make_shared<list_cmds::l2_dump_cmd>();
43 
44  HW::enqueue(cmd);
45  HW::write();
46 
47  for (auto& record : *cmd) {
48  auto& payload = record.get_payload();
49 
50  const handle_t hdl(payload.acl_index);
51  l2_list acl(hdl, std::string(reinterpret_cast<const char*>(payload.tag)));
52 
53  for (unsigned int ii = 0; ii < payload.count; ii++) {
54  const route::prefix_t pfx(payload.r[ii].is_ipv6,
55  payload.r[ii].src_ip_addr,
56  payload.r[ii].src_ip_prefix_len);
57  l2_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), pfx,
58  { payload.r[ii].src_mac }, { payload.r[ii].src_mac_mask });
59 
60  acl.insert(rule);
61  }
62  VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string();
63 
64  /*
65  * Write each of the discovered ACLs into the OM,
66  * but disable the HW Command q whilst we do, so that no
67  * commands are sent to VPP
68  */
69  OM::commit(key, acl);
70  }
71 }
72 
73 template <>
74 void
75 l2_list::event_handler::show(std::ostream& os)
76 {
77  db_dump(m_db, os);
78 }
79 
80 template <>
82 {
84  inspect::register_handler({ "l3-acl-list" }, "L3 ACL lists", this);
85 }
86 
87 template <>
88 void
89 l3_list::event_handler::handle_populate(const client_db::key_t& key)
90 {
91  /* hack to get this function instantiated */
92  m_evh.order();
93 
94  /*
95  * dump L3 ACLs Bridge domains
96  */
97  std::shared_ptr<list_cmds::l3_dump_cmd> cmd =
98  std::make_shared<list_cmds::l3_dump_cmd>();
99 
100  HW::enqueue(cmd);
101  HW::write();
102 
103  for (auto& record : *cmd) {
104  auto& payload = record.get_payload();
105 
106  const handle_t hdl(payload.acl_index);
107  l3_list acl(hdl, std::string(reinterpret_cast<const char*>(payload.tag)));
108 
109  for (unsigned int ii = 0; ii < payload.count; ii++) {
110  const route::prefix_t src(payload.r[ii].is_ipv6,
111  payload.r[ii].src_ip_addr,
112  payload.r[ii].src_ip_prefix_len);
113  const route::prefix_t dst(payload.r[ii].is_ipv6,
114  payload.r[ii].dst_ip_addr,
115  payload.r[ii].dst_ip_prefix_len);
116  l3_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), src, dst);
117 
118  rule.set_proto(payload.r[ii].proto);
119  rule.set_src_from_port(payload.r[ii].srcport_or_icmptype_first);
120  rule.set_src_to_port(payload.r[ii].srcport_or_icmptype_last);
121  rule.set_dst_from_port(payload.r[ii].dstport_or_icmpcode_first);
122  rule.set_dst_to_port(payload.r[ii].dstport_or_icmpcode_last);
123  rule.set_tcp_flags_mask(payload.r[ii].tcp_flags_mask);
124  rule.set_tcp_flags_value(payload.r[ii].tcp_flags_value);
125 
126  acl.insert(rule);
127  }
128  VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string();
129 
130  /*
131  * Write each of the discovered ACLs into the OM,
132  * but disable the HW Command q whilst we do, so that no
133  * commands are sent to VPP
134  */
135  OM::commit(key, acl);
136  }
137 }
138 
139 template <>
140 void
141 l3_list::event_handler::show(std::ostream& os)
142 {
143  db_dump(m_db, os);
144 }
145 
146 template <>
147 void
148 l3_list::update(const l3_list& obj)
149 {
150  /*
151  * always update the instance with the latest rule set
152  */
153  if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) {
154  HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules));
155  }
156  /*
157  * We don't, can't, read the priority from VPP,
158  * so the is equals check above does not include the priorty.
159  * but we save it now.
160  */
161  m_rules = obj.m_rules;
162 }
163 template <>
164 void
165 l2_list::update(const l2_list& obj)
166 {
167  /*
168  * always update the instance with the latest rule set
169  */
170  if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) {
171  HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
172  }
173  /*
174  * We don't, can't, read the priority from VPP,
175  * so the is equals check above does not include the priorty.
176  * but we save it now.
177  */
178  m_rules = obj.m_rules;
179 }
180 /**
181  * Sweep/reap the object if still stale
182  */
183 template <>
184 void
185 l3_list::sweep(void)
186 {
187  if (m_hdl) {
189  }
190  HW::write();
191 }
192 template <>
193 void
194 l2_list::sweep(void)
195 {
196  if (m_hdl) {
198  }
199  HW::write();
200 }
201 
202 /**
203  * Replay the objects state to HW
204  */
205 template <>
206 void
207 l3_list::replay(void)
208 {
209  if (m_hdl) {
210  m_hdl.data().reset();
211  HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules));
212  }
213 }
214 template <>
215 void
216 l2_list::replay(void)
217 {
218  if (m_hdl) {
219  m_hdl.data().reset();
220  HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules));
221  }
222 }
223 
224 }; // namespace ACL
225 }; // namespace VOM
226 
227 /*
228  * fd.io coding-style-patch-verification: ON
229  *
230  * Local Variables:
231  * eval: (c-set-style "mozilla")
232  * End:
233  */
static const action_t & from_int(uint8_t i)
Get the enum type from a VPP integer value.
Definition: acl_types.cpp:30
vl_api_address_t src
Definition: vxlan_gbp.api:33
update_cmd< l3_rule, vapi::Acl_add_replace > l3_update_cmd
Typedef the L3 ACL commands.
#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
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
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:236
static const log_level_t DEBUG
Definition: logger.hpp:32
T & data()
Return the data read/written.
Definition: hw.hpp:108
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:118
vl_api_address_t dst
Definition: vxlan_gbp.api:34
delete_cmd< l3_rule, vapi::Acl_del > l3_delete_cmd
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:339
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:104
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:194
list< l3_rule > l3_list
Typedef the L3 ACL type.
Definition: acl_list.hpp:275
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
delete_cmd< l2_rule, vapi::Macip_acl_del > l2_delete_cmd
update_cmd< l2_rule, vapi::Macip_acl_add > l2_update_cmd
Typedef the L2 ACL commands.
void reset()
reset the value of the handle to ~0
Definition: types.cpp:99
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
list< l2_rule > l2_list
Typedef the L2 ACL type.
Definition: acl_list.hpp:280
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127