dhcp ip: DSCP settings for transmitted DHCP packets
[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               const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0,
116               event_listener* ev = nullptr);
117
118   /**
119    * Construct a new object matching the desried state
120    */
121   dhcp_client(const interface& itf,
122               const std::string& hostname,
123               const l2_address_t& client_id,
124               bool set_broadcast_flag = true,
125               const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0,
126               event_listener* ev = nullptr);
127
128   /**
129    * Copy Constructor
130    */
131   dhcp_client(const dhcp_client& o);
132
133   /**
134    * Destructor
135    */
136   ~dhcp_client();
137
138   /**
139    * Comparison operator - for UT
140    */
141   bool operator==(const dhcp_client& d) const;
142
143   /**
144    * Return the object's key
145    */
146   const key_t& key() const;
147
148   /**
149    * Return the 'singular' of the DHCP client that matches this object
150    */
151   std::shared_ptr<dhcp_client> singular() const;
152
153   /**
154    * convert to string format for debug purposes
155    */
156   std::string to_string() const;
157
158   /**
159    * Dump all DHCP clients into the stream provided
160    */
161   static void dump(std::ostream& os);
162
163   /**
164    * Find a DHCP client from its key
165    */
166   static std::shared_ptr<dhcp_client> find(const key_t& k);
167
168   /**
169    * return the current lease data
170    */
171   const std::shared_ptr<lease_t> lease() const;
172
173 private:
174   /**
175    * Class definition for listeners to OM events
176    */
177   class event_handler : public OM::listener, public inspect::command_handler
178   {
179   public:
180     event_handler();
181     virtual ~event_handler() = default;
182
183     /**
184      * Handle a populate event
185      */
186     void handle_populate(const client_db::key_t& key);
187
188     /**
189      * Handle a replay event
190      */
191     void handle_replay();
192
193     /**
194      * Show the object in the Singular DB
195      */
196     void show(std::ostream& os);
197
198     /**
199      * Get the sortable Id of the listener
200      */
201     dependency_t order() const;
202   };
203
204   /**
205    * event_handler to register with OM
206    */
207   static event_handler m_evh;
208
209   /**
210    * Enquue commonds to the VPP command Q for the update
211    */
212   void update(const dhcp_client& obj);
213
214   /**
215    * Find or add DHCP client to the OM
216    */
217   static std::shared_ptr<dhcp_client> find_or_add(const dhcp_client& temp);
218
219   /*
220    * It's the OM class that calls singular()
221    */
222   friend class OM;
223
224   /**
225    * It's the singular_db class that calls replay()
226    */
227   friend class singular_db<key_t, dhcp_client>;
228
229   /**
230    * Sweep/reap the object if still stale
231    */
232   void sweep(void);
233
234   /**
235    * replay the object to create it in hardware
236    */
237   void replay(void);
238
239   void lease(std::shared_ptr<lease_t> l);
240
241   /**
242    * A reference counting pointer to the interface on which DHCP client
243    * resides. By holding the reference here, we can guarantee that
244    * this object will outlive the interface
245    */
246   const std::shared_ptr<interface> m_itf;
247
248   /**
249    * The hostname in the DHCP client
250    */
251   const std::string m_hostname;
252
253   /**
254    * The option-61 client_id in the DHCP client
255    */
256   const l2_address_t m_client_id;
257
258   /**
259    * Flag to control the setting the of DHCP discover's broadcast flag
260    */
261   const bool m_set_broadcast_flag;
262
263   /**
264    * DSCP setting for generated IP packets
265    */
266   const ip_dscp_t m_dscp;
267
268   /**
269    * HW configuration for the binding. The bool representing the
270    * do/don't bind.
271    */
272   HW::item<bool> m_binding;
273
274   /**
275    * A pointer to an event listener for client events
276    */
277   event_listener* m_evl;
278
279   /**
280    * Current lease state for this client
281    */
282   std::shared_ptr<lease_t> m_lease;
283
284   std::shared_ptr<dhcp_client_cmds::events_cmd> m_event_cmd;
285
286   void handle_dhcp_event(std::shared_ptr<lease_t> e);
287
288   /**
289    * A map of all Dhcp clients keyed against the interface.
290    */
291   static singular_db<key_t, dhcp_client> m_db;
292
293   static std::weak_ptr<dhcp_client_cmds::events_cmd> m_s_event_cmd;
294   static std::shared_ptr<dhcp_client_cmds::events_cmd> get_event_cmd();
295
296   class dhcp_client_listener : public event_listener
297   {
298   public:
299     /**
300      * listener's virtual function invoked when a DHCP event is
301      * available to read
302      */
303     void handle_dhcp_event(std::shared_ptr<lease_t> e);
304   };
305   static dhcp_client_listener m_listener;
306 };
307 };
308
309 /*
310  * fd.io coding-style-patch-verification: ON
311  *
312  * Local Variables:
313  * eval: (c-set-style "mozilla")
314  * End:
315  */
316
317 #endif