gbp: add anonymous l3-out subnets
[vpp.git] / extras / vom / vom / gbp_subnet.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_GBP_SUBNET_H__
17 #define __VOM_GBP_SUBNET_H__
18
19 #include <ostream>
20
21 #include "vom/gbp_endpoint_group.hpp"
22 #include "vom/gbp_recirc.hpp"
23 #include "vom/gbp_route_domain.hpp"
24 #include "vom/singular_db.hpp"
25
26 namespace VOM {
27 /**
28  * A GBP Enpoint (i.e. a VM)
29  */
30 class gbp_subnet : public object_base
31 {
32 public:
33   /**
34    * The key for a GBP subnet; table and prefix
35    */
36   typedef std::pair<gbp_route_domain::key_t, route::prefix_t> key_t;
37
38   struct type_t : public enum_base<type_t>
39   {
40     /**
41      * Internal subnet is reachable through the source EPG's
42      * uplink interface.
43      */
44     const static type_t STITCHED_INTERNAL;
45
46     /**
47      * External subnet requires NAT translation before egress.
48      */
49     const static type_t STITCHED_EXTERNAL;
50
51     /**
52      * A transport subnet, sent via the RD's UU-fwd interface
53      */
54     const static type_t TRANSPORT;
55
56     /**
57      * A L3-out subnet
58      */
59     const static type_t L3_OUT;
60
61     /**
62      * An anonymous L3-out subnet
63      */
64     const static type_t ANON_L3_OUT;
65
66   private:
67     type_t(int v, const std::string s);
68   };
69
70   /**
71    * Construct an internal GBP subnet
72    */
73   gbp_subnet(const gbp_route_domain& rd,
74              const route::prefix_t& prefix,
75              const type_t& type);
76
77   /**
78    * Construct an stitched external GBP subnet
79    */
80   gbp_subnet(const gbp_route_domain& rd,
81              const route::prefix_t& prefix,
82              const gbp_recirc& recirc,
83              const gbp_endpoint_group& epg);
84
85   /**
86    * Construct an l3-out GBP subnet
87    */
88   gbp_subnet(const gbp_route_domain& rd,
89              const route::prefix_t& prefix,
90              sclass_t sclass,
91              const type_t& type = type_t::L3_OUT);
92
93   /**
94    * Copy Construct
95    */
96   gbp_subnet(const gbp_subnet& r);
97
98   /**
99    * Destructor
100    */
101   ~gbp_subnet();
102
103   /**
104    * Return the object's key
105    */
106   const key_t key() const;
107
108   /**
109    * comparison operator
110    */
111   bool operator==(const gbp_subnet& bdae) const;
112
113   /**
114    * Return the matching 'singular instance'
115    */
116   std::shared_ptr<gbp_subnet> singular() const;
117
118   /**
119    * Find the instnace of the bridge_domain domain in the OM
120    */
121   static std::shared_ptr<gbp_subnet> find(const key_t& k);
122
123   /**
124    * Dump all bridge_domain-doamin into the stream provided
125    */
126   static void dump(std::ostream& os);
127
128   /**
129    * replay the object to create it in hardware
130    */
131   void replay(void);
132
133   /**
134    * Convert to string for debugging
135    */
136   std::string to_string() const;
137
138 private:
139   /**
140    * Class definition for listeners to OM events
141    */
142   class event_handler : public OM::listener, public inspect::command_handler
143   {
144   public:
145     event_handler();
146     virtual ~event_handler() = default;
147
148     /**
149      * Handle a populate event
150      */
151     void handle_populate(const client_db::key_t& key);
152
153     /**
154      * Handle a replay event
155      */
156     void handle_replay();
157
158     /**
159      * Show the object in the Singular DB
160      */
161     void show(std::ostream& os);
162
163     /**
164      * Get the sortable Id of the listener
165      */
166     dependency_t order() const;
167   };
168
169   /**
170    * event_handler to register with OM
171    */
172   static event_handler m_evh;
173
174   /**
175    * Commit the acculmulated changes into VPP. i.e. to a 'HW" write.
176    */
177   void update(const gbp_subnet& obj);
178
179   /**
180    * Find or add the instnace of the bridge_domain domain in the OM
181    */
182   static std::shared_ptr<gbp_subnet> find_or_add(const gbp_subnet& temp);
183
184   /*
185    * It's the VPPHW class that updates the objects in HW
186    */
187   friend class OM;
188
189   /**
190    * It's the singular_db class that calls replay()
191    */
192   friend class singular_db<key_t, gbp_subnet>;
193
194   /**
195    * Sweep/reap the object if still stale
196    */
197   void sweep(void);
198
199   /**
200    * HW configuration for the result of creating the subnet
201    */
202   HW::item<bool> m_hw;
203
204   /**
205    * the route domain the prefix is in
206    */
207   const std::shared_ptr<gbp_route_domain> m_rd;
208
209   /**
210    * prefix to match
211    */
212   const route::prefix_t m_prefix;
213
214   /*
215    * Subnet type
216    */
217   type_t m_type;
218
219   /**
220    * The interface the prefix is reachable through
221    */
222   std::shared_ptr<gbp_recirc> m_recirc;
223
224   /**
225    * The EPG the subnet is in
226    */
227   std::shared_ptr<gbp_endpoint_group> m_epg;
228
229   /**
230    * Sclass for l3-out subnets
231    */
232   sclass_t m_sclass;
233
234   /**
235    * A map of all bridge_domains
236    */
237   static singular_db<key_t, gbp_subnet> m_db;
238 };
239
240 std::ostream& operator<<(std::ostream& os, const gbp_subnet::key_t& key);
241
242 }; // namespace
243
244 /*
245  * fd.io coding-style-patch-verification: ON
246  *
247  * Local Variables:
248  * eval: (c-set-style "mozilla")
249  * End:
250  */
251
252 #endif