vxlan: vxlan/vxlan.api API cleanup
[vpp.git] / extras / vom / vom / acl_binding.hpp
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 #ifndef __VOM_ACL_BINDING_H__
17 #define __VOM_ACL_BINDING_H__
18
19 #include <ostream>
20
21 #include "vom/acl_l2_list.hpp"
22 #include "vom/acl_l3_list.hpp"
23 #include "vom/acl_types.hpp"
24 #include "vom/hw.hpp"
25 #include "vom/inspect.hpp"
26 #include "vom/interface.hpp"
27 #include "vom/object_base.hpp"
28 #include "vom/om.hpp"
29 #include "vom/singular_db.hpp"
30 #include "vom/singular_db_funcs.hpp"
31
32 namespace VOM {
33 namespace ACL {
34 /**
35  * A binding between an ACL and an interface.
36  * A representation of the application of the ACL to the interface.
37  */
38 template <typename LIST>
39 class binding : public object_base
40 {
41 public:
42   /**
43    * The key for a binding is the direction and the interface
44    */
45   typedef std::pair<direction_t, interface::key_t> key_t;
46
47   /**
48    * Construct a new object matching the desried state
49    */
50   binding(const direction_t& direction, const interface& itf, const LIST& acl)
51     : m_direction(direction)
52     , m_itf(itf.singular())
53     , m_acl(acl.singular())
54     , m_binding(false)
55   {
56     m_evh.order();
57   }
58
59   /**
60    * Copy Constructor
61    */
62   binding(const binding& o)
63     : m_direction(o.m_direction)
64     , m_itf(o.m_itf)
65     , m_acl(o.m_acl)
66     , m_binding(o.m_binding)
67   {
68   }
69
70   /**
71    * Destructor
72    */
73   ~binding()
74   {
75     sweep();
76     m_db.release(std::make_pair(m_direction, m_itf->key()), this);
77   }
78
79   /**
80    * Return the 'singular instance' of the L2 config that matches this
81    * object
82    */
83   std::shared_ptr<binding> singular() const { return find_or_add(*this); }
84
85   /**
86    * convert to string format for debug purposes
87    */
88   std::string to_string() const
89   {
90     std::ostringstream s;
91     s << "acl-binding:[" << m_direction.to_string() << " " << m_itf->to_string()
92       << " " << m_acl->to_string() << " " << m_binding.to_string() << "]";
93
94     return (s.str());
95   }
96
97   /**
98    * Dump all bindings into the stream provided
99    */
100   static void dump(std::ostream& os) { m_db.dump(os); }
101
102   static dependency_t order() { return m_evh.order(); }
103
104 private:
105   /**
106    * Class definition for listeners to OM events
107    */
108   class event_handler : public OM::listener, public inspect::command_handler
109   {
110   public:
111     event_handler();
112
113     virtual ~event_handler() = default;
114
115     /**
116      * Handle a populate event
117      */
118     void handle_populate(const client_db::key_t& key);
119
120     /**
121      * Handle a replay event
122      */
123     void handle_replay() { m_db.replay(); }
124
125     /**
126      * Show the object in the Singular DB
127      */
128     void show(std::ostream& os) { db_dump(m_db, os); }
129
130     /**
131      * Get the sortable Id of the listener
132      */
133     dependency_t order() const;
134   };
135
136   /**
137    * event_handler to register with OM
138    */
139   static event_handler m_evh;
140
141   /**
142    * Enquue commonds to the VPP command Q for the update
143    */
144   void update(const binding& obj);
145
146   /**
147    * Find or Add the instance in the DB
148    */
149   static std::shared_ptr<binding> find_or_add(const binding& temp)
150   {
151     return (m_db.find_or_add(
152       std::make_pair(temp.m_direction, temp.m_itf->key()), temp));
153   }
154
155   /*
156    * It's the OM class that calls singular()
157    */
158   friend class VOM::OM;
159
160   /**
161    * It's the singular_db class that calls replay()
162    */
163   friend class singular_db<key_t, binding>;
164
165   /**
166    * Sweep/reap the object if still stale
167    */
168   void sweep(void);
169
170   /**
171    * Replay the objects state to HW
172    */
173   void replay(void);
174
175   /**
176    * The direction the of the packets on which to apply the ACL
177    * input or output
178    */
179   const direction_t m_direction;
180
181   /**
182    * A reference counting pointer the interface that this L3 layer
183    * represents. By holding the reference here, we can guarantee that
184    * this object will outlive the interface
185    */
186   const std::shared_ptr<interface> m_itf;
187
188   /**
189    * A reference counting pointer the ACL that this
190    * interface is bound to. By holding the reference here, we can
191    * guarantee that this object will outlive the BD.
192    */
193   const std::shared_ptr<LIST> m_acl;
194
195   /**
196    * HW configuration for the binding. The bool representing the
197    * do/don't bind.
198    */
199   HW::item<bool> m_binding;
200
201   /**
202    * A map of all L2 interfaces key against the interface's handle_t
203    */
204   static singular_db<key_t, binding> m_db;
205 };
206
207 /**
208  * Typedef the L3 binding type
209  */
210 typedef binding<l3_list> l3_binding;
211
212 /**
213  * Typedef the L2 binding type
214  */
215 typedef binding<l2_list> l2_binding;
216
217 /**
218  * Definition of the static Singular DB for ACL bindings
219  */
220 template <typename LIST>
221 singular_db<typename ACL::binding<LIST>::key_t, ACL::binding<LIST>>
222   binding<LIST>::m_db;
223
224 template <typename LIST>
225 typename ACL::binding<LIST>::event_handler binding<LIST>::m_evh;
226
227 namespace {
228 const static dependency_t __attribute__((unused)) l2o = l2_binding::order();
229 const static dependency_t __attribute__((unused)) l3o = l3_binding::order();
230 };
231 };
232
233 std::ostream& operator<<(std::ostream& os,
234                          const std::pair<direction_t, interface::key_t>& key);
235 };
236
237 /*
238  * fd.io coding-style-patch-verification: ON
239  *
240  * Local Variables:
241  * eval: (c-set-style "mozilla")
242  * End:
243  */
244
245 #endif