GBP: add allowed ethertypes to contracts
[vpp.git] / extras / vom / vom / hw.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_HW_H__
17 #define __VOM_HW_H__
18
19 #include <deque>
20 #include <map>
21 #include <queue>
22 #include <sstream>
23 #include <string>
24 #include <thread>
25
26 #include "vom/cmd.hpp"
27 #include "vom/connection.hpp"
28 #include "vom/types.hpp"
29
30 namespace VOM {
31
32 class stat_reader;
33 class cmd;
34 class HW
35 {
36 public:
37   /**
38    * A HW::item is data that is either to be written to or read from
39    * VPP/HW.
40    * The item is a pair of the data written/read and the result of that
41    * operation.
42    */
43   template <typename T>
44   class item
45   {
46   public:
47     /**
48      * Constructor
49      */
50     item(const T& data)
51       : item_data(data)
52       , item_rc(rc_t::NOOP)
53     {
54     }
55     /**
56      * Constructor
57      */
58     item()
59       : item_data()
60       , item_rc(rc_t::UNSET)
61     {
62     }
63
64     /**
65      * Constructor
66      */
67     item(rc_t rc)
68       : item_data()
69       , item_rc(rc)
70     {
71     }
72
73     /**
74      * Constructor
75      */
76     item(const T& data, rc_t rc)
77       : item_data(data)
78       , item_rc(rc)
79     {
80     }
81
82     /**
83      * Destructor
84      */
85     ~item() = default;
86
87     /**
88      * Comparison operator
89      */
90     bool operator==(const item<T>& i) const
91     {
92       return (item_data == i.item_data);
93     }
94
95     /**
96      * Copy assignment
97      */
98     item& operator=(const item& other)
99     {
100       item_data = other.item_data;
101       item_rc = other.item_rc;
102
103       return (*this);
104     }
105
106     /**
107      * Return the data read/written
108      */
109     T& data() { return (item_data); }
110
111     /**
112      * Const reference to the data
113      */
114     const T& data() const { return (item_data); }
115
116     /**
117      * Get the HW return code
118      */
119     rc_t rc() const { return (item_rc); }
120
121     /**
122      * Set the HW return code - should only be called from the
123      * family of Command objects
124      */
125     void set(const rc_t& rc) { item_rc = rc; }
126
127     /**
128      * Return true if the HW item is configred in HW
129      */
130     operator bool() const { return (rc_t::OK == item_rc); }
131
132     /**
133      * update the item to the desired state.
134      *  return true if a HW update is required
135      */
136     bool update(const item& desired)
137     {
138       bool need_hw_update = false;
139
140       /*
141        * if the deisred set is unset (i.e. defaulted, we've
142        * no update to make
143        */
144       if (rc_t::UNSET == desired.rc()) {
145         return (false);
146       }
147       /*
148        * A HW update is needed if thestate is different
149        * or the state is not yet in HW
150        */
151       need_hw_update = (item_data != desired.data() || rc_t::OK != rc());
152
153       item_data = desired.data();
154
155       return (need_hw_update);
156     }
157
158     /**
159      * convert to string format for debug purposes
160      */
161     std::string to_string() const
162     {
163       std::ostringstream os;
164
165       os << "hw-item:["
166          << "rc:" << item_rc.to_string() << " data:" << item_data.to_string()
167          << "]";
168
169       return (os.str());
170     }
171
172   private:
173     /**
174      * The data
175      */
176     T item_data;
177
178     /**
179      * The result when the item was written
180      */
181     rc_t item_rc;
182   };
183
184   /**
185    * The pipe to VPP into which we write the commands
186    */
187   class cmd_q
188   {
189   public:
190     /**
191      * Constructor
192      */
193     cmd_q();
194     /**
195      * Destructor
196      */
197     ~cmd_q();
198
199     /**
200      * Copy assignement - only used in UT
201      */
202     cmd_q& operator=(const cmd_q& f);
203
204     /**
205      * Enqueue a command into the Q.
206      */
207     virtual void enqueue(cmd* c);
208     /**
209      * Enqueue a command into the Q.
210      */
211     virtual void enqueue(std::shared_ptr<cmd> c);
212
213     /**
214      * Enqueue a set of commands
215      */
216     virtual void enqueue(std::queue<cmd*>& c);
217
218     /**
219      * Write all the commands to HW
220      */
221     virtual rc_t write();
222
223     /**
224      * Blocking Connect to VPP - call once at bootup
225      */
226     virtual bool connect();
227
228     /**
229      * Disconnect to VPP
230      */
231     virtual void disconnect();
232
233     /**
234      * Disable the passing of commands to VPP. Whilst disabled all
235      * writes will be discarded. Use this during the reset phase.
236      */
237     void disable();
238
239     /**
240      * Enable the passing of commands to VPP - undoes the disable.
241      * The Q is enabled by default.
242      */
243     void enable();
244
245   private:
246     /**
247      * A queue of enqueued commands, ready to be written
248      */
249     std::deque<std::shared_ptr<cmd>> m_queue;
250
251     /**
252      * A map of issued, but uncompleted, commands.
253      *  i.e. those that we are waiting, async stylee,
254      * for VPP to complete
255      */
256     std::map<cmd*, std::shared_ptr<cmd>> m_pending;
257
258     /**
259      * VPP Q poll function
260      */
261     void rx_run();
262
263     /**
264      * The thread object running the poll/dispatch/connect thread
265      */
266     std::unique_ptr<std::thread> m_rx_thread;
267
268     /**
269      * A flag indicating the client has disabled the cmd Q.
270      */
271     bool m_enabled;
272
273     /**
274      * A flag for the thread to poll to see if the queue is still alive
275      */
276     bool m_connected;
277
278     /**
279      * The connection to VPP
280      */
281     connection m_conn;
282   };
283
284   /**
285    * Initialise the HW connection to VPP - the UT version passing
286    * a mock Q.
287    */
288   static void init(cmd_q* f);
289
290   /**
291    * Initialise the HW connection to VPP - the UT version passing
292    * a mock Q.
293    */
294   static void init(cmd_q* f, stat_reader* s);
295
296   /**
297    * Initialise the HW
298    */
299   static void init();
300
301   /**
302    * Enqueue A command for execution
303    */
304   static void enqueue(cmd* f);
305
306   /**
307    * Enqueue A command for execution
308    */
309   static void enqueue(std::shared_ptr<cmd> c);
310
311   /**
312    * Enqueue A set of commands for execution
313    */
314   static void enqueue(std::queue<cmd*>& c);
315
316   /**
317    * Write/Execute all commands hitherto enqueued.
318    */
319   static rc_t write();
320
321   /**
322    * Blocking Connect to VPP
323    */
324   static bool connect();
325
326   /**
327    * Disconnect to VPP
328    */
329   static void disconnect();
330
331   /**
332    * Blocking pool of the HW connection
333    */
334   static bool poll();
335
336   /**
337    * read stats from stat segment
338    */
339   static void read_stats();
340
341 private:
342   /**
343    * The command Q toward HW
344    */
345   static cmd_q* m_cmdQ;
346
347   /**
348    * The stat reader toward HW
349    */
350   static stat_reader* m_statReader;
351
352   /**
353    * HW::item representing the connection state as determined by polling
354    */
355   static HW::item<bool> m_poll_state;
356
357   /**
358    * Disable the passing of commands to VPP. Whilst disabled all writes
359    * will be discarded. Use this during the reset phase.
360    */
361   static void disable();
362
363   /**
364    * Enable the passing of commands to VPP - undoes the disable.
365    * The Q is enabled by default.
366    */
367   static void enable();
368
369   /**
370    * Only the OM can enable/disable HW
371    */
372   friend class OM;
373 };
374
375 /**
376  * bool Specialisation for HW::item to_string
377  */
378 template <>
379 std::string HW::item<bool>::to_string() const;
380
381 /**
382  * uint Specialisation for HW::item to_string
383  */
384 template <>
385 std::string HW::item<unsigned int>::to_string() const;
386 };
387
388 /*
389  * fd.io coding-style-patch-verification: ON
390  *
391  * Local Variables:
392  * eval: (c-set-style "mozilla")
393  * End:
394  */
395
396 #endif