blob: d175bee80ebd81358d7529b42693807bf5d0ba01 [file] [log] [blame]
Neale Ranns812ed392017-10-16 04:20:13 -07001/*
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_ROUTE_H__
17#define __VOM_ROUTE_H__
18
19#include "vom/interface.hpp"
20#include "vom/prefix.hpp"
21#include "vom/route_domain.hpp"
22#include "vom/singular_db.hpp"
23
24#include <vapi/ip.api.vapi.hpp>
25
26namespace VOM {
27/**
28 * Types belonging to Routing
29 */
30namespace route {
31/**
32 * A path for IP or MPLS routes
33 */
34class path
35{
36public:
37 /**
38 * Special path types
39 */
40 class special_t : public enum_base<special_t>
41 {
42 public:
43 /**
44 * A standard path type. this includes path types
45 * that use the next-hop and interface
46 */
47 const static special_t STANDARD;
48
49 /**
50 * A local/for-us/recieve
51 */
52 const static special_t LOCAL;
53
54 /**
55 * drop path
56 */
57 const static special_t DROP;
58
59 /**
60 * a path will return ICMP unreachables
61 */
62 const static special_t UNREACH;
63
64 /**
65 * a path will return ICMP prohibit
66 */
67 const static special_t PROHIBIT;
68
69 private:
70 /**
71 * Private constructor taking the value and the string name
72 */
73 special_t(int v, const std::string& s);
74 };
75
76 /**
77 * constructor for special paths
78 */
79 path(special_t special);
80
81 /**
82 * Constructor for standard non-recursive paths
83 */
84 path(const boost::asio::ip::address& nh,
85 const interface& interface,
86 uint8_t weight = 1,
87 uint8_t preference = 0);
88
89 /**
90 * Constructor for standard recursive paths
91 */
92 path(const route_domain& rd,
93 const boost::asio::ip::address& nh,
94 uint8_t weight = 1,
95 uint8_t preference = 0);
96
97 /**
98 * Constructor for DVR paths or attached paths.
99 */
100 path(const interface& interface,
101 const nh_proto_t& proto,
102 uint8_t weight = 1,
103 uint8_t preference = 0);
104
105 /**
106 * Copy Constructor
107 */
108 path(const path& p);
109
110 /**
111 * Convert the path into the VPP API representation
112 */
113 void to_vpp(vapi_type_fib_path& path) const;
114 void to_vpp(vapi_payload_ip_add_del_route& payload) const;
115
116 /**
117 * Less than operator for set insertion
118 */
119 bool operator<(const path& p) const;
120
121 /**
122 * convert to string format for debug purposes
123 */
124 std::string to_string() const;
125
126private:
127 /**
128 * The special path tpye
129 */
130 special_t m_type;
131
132 /**
133 * The next-hop protocol
134 */
135 nh_proto_t m_nh_proto;
136
137 /**
138 * The next-hop
139 */
140 boost::asio::ip::address m_nh;
141
142 /**
143 * For recursive routes, this is the table in which the
144 * the next-hop exists.
145 */
146 std::shared_ptr<route_domain> m_rd;
147
148 /**
149 * The next-hop interface [if present].
150 */
151 std::shared_ptr<interface> m_interface;
152
153 /**
154 * UCMP weight
155 */
156 uint8_t m_weight;
157
158 /**
159 * Path preference
160 */
161 uint8_t m_preference;
162};
163
164/**
165 * A path-list is a set of paths
166 */
167typedef std::set<path> path_list_t;
168
169/**
170 * ostream output for iterator
171 */
172std::ostream& operator<<(std::ostream& os, const path_list_t& path_list);
173
174/**
175 * A IP route
176 */
177class ip_route : public object_base
178{
179public:
180 /**
181 * The key for a route
182 */
183 typedef std::pair<route::table_id_t, prefix_t> key_t;
184
185 /**
186 * Construct a route in the default table
187 */
188 ip_route(const prefix_t& prefix);
189
190 /**
191 * Copy Construct
192 */
193 ip_route(const ip_route& r);
194
195 /**
196 * Construct a route in the given route domain
197 */
198 ip_route(const route_domain& rd, const prefix_t& prefix);
199
200 /**
201 * Destructor
202 */
203 ~ip_route();
204
205 /**
206 * Return the matching 'singular instance'
207 */
208 std::shared_ptr<ip_route> singular() const;
209
210 /**
211 * Add a path.
212 */
213 void add(const path& path);
214
215 /**
216 * remove a path.
217 */
218 void remove(const path& path);
219
220 /**
221 * Find the instnace of the route domain in the OM
222 */
223 static std::shared_ptr<ip_route> find(const ip_route& temp);
224
225 /**
226 * Dump all route-doamin into the stream provided
227 */
228 static void dump(std::ostream& os);
229
230 /**
231 * replay the object to create it in hardware
232 */
233 void replay(void);
234
235 /**
236 * Convert to string for debugging
237 */
238 std::string to_string() const;
239
240 /**
241 * A command class that creates or updates the route
242 */
243 class update_cmd
244 : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_add_del_route>
245 {
246 public:
247 /**
248 * Constructor
249 */
250 update_cmd(HW::item<bool>& item,
251 table_id_t id,
252 const prefix_t& prefix,
253 const path_list_t& paths);
254
255 /**
256 * Issue the command to VPP/HW
257 */
258 rc_t issue(connection& con);
259
260 /**
261 * convert to string format for debug purposes
262 */
263 std::string to_string() const;
264
265 /**
266 * Comparison operator - only used for UT
267 */
268 bool operator==(const update_cmd& i) const;
269
270 private:
271 route::table_id_t m_id;
272 prefix_t m_prefix;
273 const path_list_t m_paths;
274 };
275
276 /**
277 * A cmd class that deletes a route
278 */
279 class delete_cmd
280 : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_add_del_route>
281 {
282 public:
283 /**
284 * Constructor
285 */
286 delete_cmd(HW::item<bool>& item, table_id_t id, const prefix_t& prefix);
287
288 /**
289 * Issue the command to VPP/HW
290 */
291 rc_t issue(connection& con);
292
293 /**
294 * convert to string format for debug purposes
295 */
296 std::string to_string() const;
297
298 /**
299 * Comparison operator - only used for UT
300 */
301 bool operator==(const delete_cmd& i) const;
302
303 private:
304 route::table_id_t m_id;
305 prefix_t m_prefix;
306 };
307
308 /**
309 * A cmd class that Dumps ipv4 fib
310 */
311 class dump_v4_cmd : public VOM::dump_cmd<vapi::Ip_fib_dump>
312 {
313 public:
314 /**
315 * Constructor
316 */
317 dump_v4_cmd();
318 dump_v4_cmd(const dump_cmd& d);
319
320 /**
321 * Issue the command to VPP/HW
322 */
323 rc_t issue(connection& con);
324 /**
325 * convert to string format for debug purposes
326 */
327 std::string to_string() const;
328
329 /**
330 * Comparison operator - only used for UT
331 */
332 bool operator==(const dump_v4_cmd& i) const;
333
334 private:
335 /**
336 * HW reutrn code
337 */
338 HW::item<bool> item;
339 };
340
341 /**
342 * A cmd class that Dumps ipv6 fib
343 */
344 class dump_v6_cmd : public VOM::dump_cmd<vapi::Ip6_fib_dump>
345 {
346 public:
347 /**
348 * Constructor
349 */
350 dump_v6_cmd();
351 dump_v6_cmd(const dump_cmd& d);
352
353 /**
354 * Issue the command to VPP/HW
355 */
356 rc_t issue(connection& con);
357 /**
358 * convert to string format for debug purposes
359 */
360 std::string to_string() const;
361
362 /**
363 * Comparison operator - only used for UT
364 */
365 bool operator==(const dump_v6_cmd& i) const;
366
367 private:
368 /**
369 * HW reutrn code
370 */
371 HW::item<bool> item;
372 };
373
374private:
375 /**
376 * Class definition for listeners to OM events
377 */
378 class event_handler : public OM::listener, public inspect::command_handler
379 {
380 public:
381 event_handler();
382 virtual ~event_handler() = default;
383
384 /**
385 * Handle a populate event
386 */
387 void handle_populate(const client_db::key_t& key);
388
389 /**
390 * Handle a replay event
391 */
392 void handle_replay();
393
394 /**
395 * Show the object in the Singular DB
396 */
397 void show(std::ostream& os);
398
399 /**
400 * Get the sortable Id of the listener
401 */
402 dependency_t order() const;
403 };
404
405 /**
406 * event_handler to register with OM
407 */
408 static event_handler m_evh;
409
410 /**
411 * Find or add the instnace of the route domain in the OM
412 */
413 static std::shared_ptr<ip_route> find_or_add(const ip_route& temp);
414
415 /*
416 * It's the OM class that updates the objects in HW
417 */
418 friend class VOM::OM;
419
420 /**
421 * It's the singular_db class that calls replay()
422 */
423 friend class singular_db<key_t, ip_route>;
424
425 /**
426 * Commit the acculmulated changes into VPP. i.e. to a 'HW" write.
427 */
428 void update(const ip_route& obj);
429
430 /**
431 * Sweep/reap the object if still stale
432 */
433 void sweep(void);
434
435 /**
436 * HW configuration for the result of creating the route
437 */
438 HW::item<bool> m_hw;
439
440 /**
441 * The route domain the route is in.
442 */
443 std::shared_ptr<route_domain> m_rd;
444
445 /**
446 * The prefix to match
447 */
448 prefix_t m_prefix;
449
450 /**
451 * The set of paths
452 */
453 path_list_t m_paths;
454
455 /**
456 * A map of all routes
457 */
458 static singular_db<key_t, ip_route> m_db;
459};
460
461std::ostream& operator<<(std::ostream& os, const ip_route::key_t& key);
462};
463};
464
465/*
466 * fd.io coding-style-patch-verification: ON
467 *
468 * Local Variables:
469 * eval: (c-set-style "mozilla")
470 * End:
471 */
472
473#endif