17c626ed0f11786c5d7e08c4fcbbd0a2ffac8c4a
[vpp.git] / extras / vom / vom / dhcp_client.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_DHCP_CLIENT_H__
17 #define __VOM_DHCP_CLIENT_H__
18
19 #include "vom/hw.hpp"
20 #include "vom/inspect.hpp"
21 #include "vom/interface.hpp"
22 #include "vom/object_base.hpp"
23 #include "vom/om.hpp"
24 #include "vom/prefix.hpp"
25 #include "vom/singular_db.hpp"
26
27 namespace VOM {
28 namespace dhcp_client_cmds {
29 class events_cmd;
30 };
31 /**
32  * A representation of DHCP client on an interface
33  */
34 class dhcp_client : public object_base
35 {
36 public:
37   /**
38    * typedef for the DHCP client key type
39    */
40   typedef interface::key_t key_t;
41
42   struct state_t : enum_base<state_t>
43   {
44     const static state_t DISCOVER;
45     const static state_t REQUEST;
46     const static state_t BOUND;
47
48     static const state_t& from_vpp(int i);
49
50   private:
51     /**
52      * Private constructor taking the value and the string name
53      */
54     state_t(int v, const std::string& s);
55   };
56
57   /**
58    * A DHCP lease data
59    */
60   struct lease_t
61   {
62     lease_t();
63     lease_t(const state_t& state,
64             std::shared_ptr<interface> itf,
65             const boost::asio::ip::address& router_address,
66             const route::prefix_t& host_prefix,
67             const std::string& hostname,
68             const mac_address_t& mac);
69
70     std::string to_string() const;
71
72     const state_t& state;
73     std::shared_ptr<interface> itf;
74     boost::asio::ip::address router_address;
75     route::prefix_t host_prefix;
76     std::string hostname;
77     mac_address_t mac;
78   };
79
80   /**
81    * A class that listens to DHCP Events
82    */
83   class event_listener
84   {
85   public:
86     /**
87      * Constructor
88      */
89     event_listener();
90
91     /**
92      * listener's virtual function invoked when a DHCP event is
93      * available to read
94      */
95     virtual void handle_dhcp_event(std::shared_ptr<lease_t> e) = 0;
96
97     /**
98      * Return the HW::item associated with this command
99      */
100     HW::item<bool>& status();
101
102   protected:
103     /**
104      * The HW::item associated with this command
105      */
106     HW::item<bool> m_status;
107   };
108
109   /**
110    * Construct a new object matching the desried state
111    */
112   dhcp_client(const interface& itf,
113               const std::string& hostname,
114               bool set_broadcast_flag = true,
115               event_listener* ev = nullptr);
116
117   /**
118    * Construct a new object matching the desried state
119    */
120   dhcp_client(const interface& itf,
121               const std::string& hostname,
122               const l2_address_t& client_id,
123               bool set_broadcast_flag = true,
124               event_listener* ev = nullptr);
125
126   /**
127    * Copy Constructor
128    */
129   dhcp_client(const dhcp_client& o);
130
131   /**
132    * Destructor
133    */
134   ~dhcp_client();
135
136   /**
137    * Comparison operator - for UT
138    */
139   bool operator==(const dhcp_client& d) const;
140
141   /**
142    * Return the object's key
143    */
144   const key_t& key() const;
145
146   /**
147    * Return the 'singular' of the DHCP client that matches this object
148    */
149   std::shared_ptr<dhcp_client> singular() const;
150
151   /**
152    * convert to string format for debug purposes
153    */
154   std::string to_string() const;
155
156   /**
157    * Dump all DHCP clients into the stream provided
158    */
159   static void dump(std::ostream& os);
160
161   /**
162    * Find a DHCP client from its key
163    */
164   static std::shared_ptr<dhcp_client> find(const key_t& k);
165
166   /**
167    * return the current lease data
168    */
169   const std::shared_ptr<lease_t> lease() const;
170
171 private:
172   /**
173    * Class definition for listeners to OM events
174    */
175   class event_handler : public OM::listener, public inspect::command_handler
176   {
177   public:
178     event_handler();
179     virtual ~event_handler() = default;
180
181     /**
182      * Handle a populate event
183      */
184     void handle_populate(const client_db::key_t& key);
185
186     /**
187      * Handle a replay event
188      */
189     void handle_replay();
190
191     /**
192      * Show the object in the Singular DB
193      */
194     void show(std::ostream& os);
195
196     /**
197      * Get the sortable Id of the listener
198      */
199     dependency_t order() const;
200   };
201
202   /**
203    * event_handler to register with OM
204    */
205   static event_handler m_evh;
206
207   /**
208    * Enquue commonds to the VPP command Q for the update
209    */
210   void update(const dhcp_client& obj);
211
212   /**
213    * Find or add DHCP client to the OM
214    */
215   static std::shared_ptr<dhcp_client> find_or_add(const dhcp_client& temp);
216
217   /*
218    * It's the OM class that calls singular()
219    */
220   friend class OM;
221
222   /**
223    * It's the singular_db class that calls replay()
224    */
225   friend class singular_db<key_t, dhcp_client>;
226
227   /**
228    * Sweep/reap the object if still stale
229    */
230   void sweep(void);
231
232   /**
233    * replay the object to create it in hardware
234    */
235   void replay(void);
236
237   void lease(std::shared_ptr<lease_t> l);
238
239   /**
240    * A reference counting pointer to the interface on which DHCP client
241    * resides. By holding the reference here, we can guarantee that
242    * this object will outlive the interface
243    */
244   const std::shared_ptr<interface> m_itf;
245
246   /**
247    * The hostname in the DHCP client
248    */
249   const std::string m_hostname;
250
251   /**
252    * The option-61 client_id in the DHCP client
253    */
254   const l2_address_t m_client_id;
255
256   /**
257    * Flag to control the setting the of DHCP discover's broadcast flag
258    */
259   const bool m_set_broadcast_flag;
260
261   /**
262    * HW configuration for the binding. The bool representing the
263    * do/don't bind.
264    */
265   HW::item<bool> m_binding;
266
267   /**
268    * A pointer to an event listener for client events
269    */
270   event_listener* m_evl;
271
272   /**
273    * Current lease state for this client
274    */
275   std::shared_ptr<lease_t> m_lease;
276
277   std::shared_ptr<dhcp_client_cmds::events_cmd> m_event_cmd;
278
279   void handle_dhcp_event(std::shared_ptr<lease_t> e);
280
281   /**
282    * A map of all Dhcp clients keyed against the interface.
283    */
284   static singular_db<key_t, dhcp_client> m_db;
285
286   static std::weak_ptr<dhcp_client_cmds::events_cmd> m_s_event_cmd;
287   static std::shared_ptr<dhcp_client_cmds::events_cmd> get_event_cmd();
288
289   class dhcp_client_listener : public event_listener
290   {
291   public:
292     /**
293      * listener's virtual function invoked when a DHCP event is
294      * available to read
295      */
296     void handle_dhcp_event(std::shared_ptr<lease_t> e);
297   };
298   static dhcp_client_listener m_listener;
299 };
300 };
301
302 /*
303  * fd.io coding-style-patch-verification: ON
304  *
305  * Local Variables:
306  * eval: (c-set-style "mozilla")
307  * End:
308  */
309
310 #endif