Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #ifndef vnsw_agent_vrf_hpp
7 : #define vnsw_agent_vrf_hpp
8 :
9 : #include <atomic>
10 : #include <mutex>
11 :
12 : #include <cmn/agent_cmn.h>
13 : #include <cmn/index_vector.h>
14 : #include <cmn/agent.h>
15 : #include <oper/agent_types.h>
16 : #include <oper/oper_db.h>
17 : #include <oper/agent_route_walker.h>
18 : #include <oper/interface.h>
19 :
20 : class LifetimeActor;
21 : class LifetimeManager;
22 : class ComponentNHData;
23 : class AgentRouteWalker;
24 : class AgentRouteResync;
25 :
26 : struct VrfKey : public AgentOperDBKey {
27 39779 : VrfKey(const string &name) : AgentOperDBKey(), name_(name) { }
28 41863 : virtual ~VrfKey() { }
29 :
30 : void Init(const string &vrf_name) {name_ = vrf_name;};
31 2731 : bool IsLess(const VrfKey &rhs) const {
32 2731 : return name_ < rhs.name_;
33 : }
34 :
35 1309 : bool IsEqual(const VrfKey &rhs) const {
36 1309 : if ((IsLess(rhs) == false) && (rhs.IsLess(*this) == false)) {
37 947 : return true;
38 : }
39 362 : return false;
40 : }
41 :
42 : string name_;
43 : };
44 :
45 : struct VrfData : public AgentOperDBData {
46 : enum VrfEntryFlags {
47 : ConfigVrf = 1 << 0, // vrf is received from config
48 : GwVrf = 1 << 1, // GW configured for this VRF
49 : MirrorVrf = 1 << 2, // internally Created VRF
50 : PbbVrf = 1 << 3, // Per ISID VRF
51 : //Note addition of new flag may need update in
52 : //ConfigFlags() API, if flag being added is a property
53 : //flag(Ex PbbVrf) and not flag indicating Config origination(ex: GwVrf)
54 : };
55 :
56 : enum VrfId {
57 : FABRIC_VRF_ID,
58 : LINKLOCAL_VRF_ID
59 : };
60 :
61 789 : VrfData(Agent *agent, IFMapNode *node, uint32_t flags,
62 : const boost::uuids::uuid &vn_uuid, uint32_t isid,
63 : const std::string bmac_vrf_name,
64 : uint32_t mac_aging_time, bool learning_enabled,
65 : uint32_t hbf_rintf = Interface::kInvalidIndex,
66 789 : uint32_t hbf_lintf = Interface::kInvalidIndex) :
67 789 : AgentOperDBData(agent, node), flags_(flags), vn_uuid_(vn_uuid),
68 789 : isid_(isid), bmac_vrf_name_(bmac_vrf_name),
69 789 : mac_aging_time_(mac_aging_time), learning_enabled_(learning_enabled),
70 789 : forwarding_vrf_name_(""), hbf_rintf_(hbf_rintf),
71 1578 : hbf_lintf_(hbf_lintf) {}
72 1578 : virtual ~VrfData() {}
73 :
74 148 : uint32_t ConfigFlags() {
75 148 : return ~(PbbVrf);
76 : }
77 :
78 : uint32_t flags_;
79 : boost::uuids::uuid vn_uuid_;
80 : boost::uuids::uuid si_vn_ref_uuid_;
81 : uint32_t isid_;
82 : std::string bmac_vrf_name_;
83 : uint32_t mac_aging_time_;
84 : bool learning_enabled_;
85 : std::string forwarding_vrf_name_;
86 : uint32_t hbf_rintf_;
87 : uint32_t hbf_lintf_;
88 : };
89 :
90 : class VrfEntry : AgentRefCount<VrfEntry>, public AgentOperDBEntry {
91 : public:
92 : static const uint32_t kInvalidIndex = 0xFFFFFFFF;
93 : static const uint32_t kDeleteTimeout = 900 * 1000;
94 :
95 : VrfEntry(const string &name, uint32_t flags, Agent *agent);
96 : virtual ~VrfEntry();
97 :
98 : virtual bool IsLess(const DBEntry &rhs) const;
99 : virtual KeyPtr GetDBRequestKey() const;
100 : virtual void SetKey(const DBRequestKey *key);
101 : virtual string ToString() const;
102 :
103 49085 : const uint32_t vrf_id() const {return id_;};
104 118925 : const string &GetName() const {return name_;};
105 25641 : VnEntry *vn() const { return vn_.get(); }
106 30 : VnEntry *si_vn_ref() const { return si_vn_ref_.get(); }
107 :
108 74 : uint32_t GetRefCount() const {
109 74 : return AgentRefCount<VrfEntry>::GetRefCount();
110 : }
111 :
112 0 : uint32_t flags() const { return flags_; }
113 573 : void set_flags(uint32_t flags) { flags_ |= flags; }
114 2864 : bool are_flags_set(const VrfData::VrfEntryFlags &flags) const {
115 2864 : return (flags_ & flags);
116 : }
117 :
118 0 : void set_table_label(uint32_t label) {
119 0 : table_label_ = label;
120 0 : }
121 78 : uint32_t table_label() const {
122 78 : return table_label_;
123 : }
124 :
125 187 : const std::string& GetExportName() {
126 187 : if (are_flags_set(VrfData::PbbVrf)) {
127 0 : return bmac_vrf_name_;
128 : }
129 187 : return name_;
130 : }
131 :
132 144 : bool learning_enabled() const {
133 144 : return learning_enabled_;
134 : }
135 :
136 1801 : bool ShouldExportRoute() const {
137 1801 : if (are_flags_set(VrfData::PbbVrf)) {
138 0 : return false;
139 : }
140 1801 : return true;
141 : }
142 :
143 5318 : bool layer2_control_word() const {
144 5318 : return layer2_control_word_;
145 : }
146 :
147 715 : const uint32_t hbf_rintf() const { return hbf_rintf_; }
148 715 : const uint32_t hbf_lintf() const { return hbf_lintf_; }
149 :
150 : bool DBEntrySandesh(Sandesh *sresp, std::string &name) const;
151 : InetUnicastRouteEntry *GetUcRoute(const IpAddress &addr) const;
152 : InetUnicastRouteEntry *GetUcRoute(const InetUnicastRouteEntry &rt_key)const;
153 : bool UpdateVxlanId(Agent *agent, uint32_t new_vxlan_id);
154 :
155 : LifetimeActor *deleter();
156 : virtual void RetryDelete();
157 : bool AllRouteTablesEmpty() const;
158 : void SendObjectLog(AgentLogEvent::type event) const;
159 : void StartDeleteTimer();
160 : bool DeleteTimeout();
161 : void CancelDeleteTimer();
162 : bool ResetVrfDelete();
163 : void PostAdd();
164 : void AddNH(Ip4Address ip, uint8_t plen, ComponentNHData *nh_data) ;
165 : void DeleteNH(Ip4Address ip, uint8_t plen, ComponentNHData *nh_data) ;
166 : uint32_t GetNHCount(Ip4Address ip, uint8_t plen) ;
167 : void UpdateLabel(Ip4Address ip, uint8_t plen, uint32_t label);
168 : uint32_t GetLabel(Ip4Address ip, uint8_t plen);
169 0 : uint32_t vxlan_id() const {return vxlan_id_;}
170 : std::vector<ComponentNHData>* GetNHList(Ip4Address ip, uint8_t plen);
171 : bool FindNH(const Ip4Address &ip, uint8_t plen,
172 : const ComponentNHData &nh_data);
173 :
174 : InetUnicastAgentRouteTable *GetInet4UnicastRouteTable() const;
175 : InetUnicastAgentRouteTable *GetInet4MplsUnicastRouteTable() const;
176 : AgentRouteTable *GetInet4MulticastRouteTable() const;
177 : AgentRouteTable *GetEvpnRouteTable() const;
178 : AgentRouteTable *GetBridgeRouteTable() const;
179 : InetUnicastAgentRouteTable *GetInet6UnicastRouteTable() const;
180 : AgentRouteTable *GetRouteTable(uint8_t table_type) const;
181 : void CreateTableLabel(bool learning_enabled, bool l2,
182 : bool flod_unknown_unicast,
183 : bool layer2_control_word);
184 : const std::string GetTableTypeString(uint8_t table_type) const;
185 : bool AllRouteTableDeleted() const;
186 : bool RouteTableDeleted(uint8_t table_type) const;
187 : void SetRouteTableDeleted(uint8_t table_type);
188 : void DeleteRouteTables();
189 : void ResyncRoutes();
190 0 : bool allow_route_add_on_deleted_vrf() const {
191 0 : return allow_route_add_on_deleted_vrf_;
192 : }
193 :
194 : //To be set in test cases only
195 : void set_allow_route_add_on_deleted_vrf(bool val) {
196 : allow_route_add_on_deleted_vrf_ = val;
197 : }
198 : InetUnicastAgentRouteTable *GetInetUnicastRouteTable(const IpAddress &addr) const;
199 : void ReleaseWalker();
200 :
201 270 : uint32_t isid() const {
202 270 : return isid_;
203 : }
204 :
205 0 : const std::string bmac_vrf_name() const {
206 0 : return bmac_vrf_name_;
207 : }
208 :
209 229 : bool IsPbbVrf() const {
210 229 : return are_flags_set(VrfData::PbbVrf);
211 : }
212 :
213 0 : uint32_t mac_aging_time() const {
214 0 : return mac_aging_time_;
215 : }
216 :
217 7 : void set_mac_aging_time(uint32_t aging_time) {
218 7 : mac_aging_time_ = aging_time;
219 7 : }
220 :
221 3009 : VrfEntry* forwarding_vrf() const {
222 3009 : return forwarding_vrf_.get();
223 : }
224 1827 : int rd() const {return rd_;}
225 74 : void set_rd(int rd) {rd_ = rd;}
226 4 : void set_routing_vrf(bool val) {routing_vrf_ = val;}
227 36 : bool routing_vrf() const {return routing_vrf_;}
228 74 : void set_hbf_rintf(uint32_t idx) {hbf_rintf_ = idx;}
229 74 : void set_hbf_lintf(uint32_t idx) {hbf_lintf_ = idx;}
230 :
231 : private:
232 : friend class VrfTable;
233 : void CreateRouteTables();
234 : void SetNotify();
235 : int RDInstanceId(bool tor_agent_enabled) const;
236 :
237 : class DeleteActor;
238 : string name_;
239 : uint32_t id_;
240 : uint32_t flags_;
241 : VnEntryRef vn_;
242 : // service-instance primary VN reference
243 : VnEntryRef si_vn_ref_;
244 : NextHopRef nh_;
245 : DBTableWalker::WalkId walkid_;
246 : boost::scoped_ptr<DeleteActor> deleter_;
247 : AgentRouteTable *rt_table_db_[Agent::ROUTE_TABLE_MAX];
248 : Timer *delete_timeout_timer_;
249 : uint32_t table_label_;
250 : uint32_t vxlan_id_;
251 : uint32_t rt_table_delete_bmap_;
252 : IFMapDependencyManager::IFMapNodePtr vrf_node_ptr_;
253 : AgentRouteWalkerPtr route_resync_walker_;
254 : bool allow_route_add_on_deleted_vrf_;
255 : string bmac_vrf_name_;
256 : uint32_t isid_;
257 : std::atomic<uint32_t> mac_aging_time_;
258 : std::mutex delete_reuse_mutex_;
259 : bool learning_enabled_;
260 : bool layer2_control_word_;
261 : bool l2_;
262 : VrfEntryRef forwarding_vrf_;
263 : int rd_;
264 : bool routing_vrf_;
265 : uint32_t retries_;
266 : uint32_t hbf_rintf_;
267 : uint32_t hbf_lintf_;
268 : bool deleted_;
269 : DISALLOW_COPY_AND_ASSIGN(VrfEntry);
270 : };
271 :
272 : class VrfTable : public AgentOperDBTable {
273 : public:
274 : const static uint32_t kDefaultMacAgingTime = 300;
275 : // Map from VRF Name to VRF Entry
276 : typedef map<string, VrfEntry *> VrfNameTree;
277 : typedef pair<string, VrfEntry *> VrfNamePair;
278 :
279 : // Config tree of VRF to VMI entries. Tree used to track the VMIs that are
280 : // already processed after VRF has been added
281 : typedef std::set<std::string, boost::uuids::uuid> CfgVmiTree;
282 :
283 : // Map from VRF Name to Route Table
284 : typedef map<string, RouteTable *> VrfDbTree;
285 : typedef pair<string, RouteTable *> VrfDbPair;
286 :
287 2 : VrfTable(DB *db, const std::string &name) :
288 2 : AgentOperDBTable(db, name), db_(db),
289 2 : walkid_(DBTableWalker::kInvalidWalkerId),
290 2 : route_delete_walker_(NULL),
291 18 : vrf_delete_walker_(NULL) { };
292 : virtual ~VrfTable();
293 :
294 : virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
295 23851 : virtual size_t Hash(const DBEntry *entry) const {return 0;};
296 23769 : virtual size_t Hash(const DBRequestKey *key) const {return 0;};
297 : virtual void Input(DBTablePartition *root, DBClient *client,
298 : DBRequest *req);
299 : void VrfReuse(std::string name);
300 : virtual DBEntry *OperDBAdd(const DBRequest *req);
301 : virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req);
302 : virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req);
303 : virtual void OnZeroRefcount(AgentDBEntry *e);
304 : virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
305 : const std::string &context);
306 : virtual void Clear();
307 :
308 : // Create a VRF entry with given name
309 : void CreateVrf(const string &name,
310 : const boost::uuids::uuid &vn_uuid, uint32_t flags);
311 : void CreateVrf(const string &name,
312 : const boost::uuids::uuid &vn_uuid, uint32_t flags,
313 : uint32_t isid, const std::string& bmac_vrf_name,
314 : uint32_t mac_aging_time, bool learning_enabled);
315 : void DeleteVrf(const string &name, uint32_t flags = VrfData::ConfigVrf);
316 : void CreateVrfReq(const string &name, uint32_t flags = VrfData::ConfigVrf);
317 : void CreateVrfReq(const string &name, const boost::uuids::uuid &vn_uuid,
318 : uint32_t flags = VrfData::ConfigVrf);
319 : void DeleteVrfReq(const string &name, uint32_t flags = VrfData::ConfigVrf);
320 : //Add and delete routine for VRF not deleted on VRF config delete
321 : void CreateStaticVrf(const string &name);
322 : void DeleteStaticVrf(const string &name);
323 : void CreateFabricPolicyVrf(const string &name);
324 :
325 : // Create VRF Table with given name
326 : static DBTableBase *CreateTable(DB *db, const std::string &name);
327 1 : static VrfTable *GetInstance() {return vrf_table_;};
328 :
329 : virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req,
330 : const boost::uuids::uuid &u);
331 : bool ProcessConfig(IFMapNode *node, DBRequest &req,
332 : const boost::uuids::uuid &u);
333 :
334 : VrfEntry *FindVrfFromName(const string &name);
335 : VrfEntry *FindVrfFromId(size_t index);
336 : VrfEntry *FindVrfFromIdIncludingDeletedVrf(size_t index);
337 : void FreeVrfId(size_t index);
338 :
339 : InetUnicastAgentRouteTable *GetInet4UnicastRouteTable
340 : (const std::string &vrf_name);
341 : InetUnicastAgentRouteTable *GetInet4MplsUnicastRouteTable
342 : (const std::string &vrf_name);
343 : AgentRouteTable *GetInet4MulticastRouteTable(const std::string &vrf_name);
344 : AgentRouteTable *GetEvpnRouteTable(const std::string &vrf_name);
345 : AgentRouteTable *GetBridgeRouteTable(const std::string &vrf_name);
346 : AgentRouteTable *GetRouteTable(const string &vrf_name, uint8_t table_type);
347 : InetUnicastAgentRouteTable *GetInet6UnicastRouteTable
348 : (const std::string &vrf_name);
349 136 : bool IsStaticVrf(const std::string &vrf_name) const {
350 136 : if (static_vrf_set_.find(vrf_name) != static_vrf_set_.end()) {
351 0 : return true;
352 : }
353 136 : return false;
354 : }
355 :
356 : void DeleteRoutes();
357 : void Shutdown();
358 : void DeleteFromDbTree(int table_type, const std::string &vrf_name);
359 2 : void reset_route_delete_walker() {route_delete_walker_.reset();}
360 0 : void reset_vrf_delete_walker() {vrf_delete_walker_.reset();}
361 :
362 : private:
363 : friend class VrfEntry;
364 :
365 : DB *db_;
366 : static VrfTable *vrf_table_;
367 : IndexVector<VrfEntry *> index_table_;
368 : VrfNameTree name_tree_;
369 : VrfDbTree dbtree_[Agent::ROUTE_TABLE_MAX];
370 : DBTableWalker::WalkId walkid_;
371 : std::set<std::string> static_vrf_set_;
372 : AgentRouteWalkerPtr route_delete_walker_;
373 : AgentRouteWalkerPtr vrf_delete_walker_;
374 : DISALLOW_COPY_AND_ASSIGN(VrfTable);
375 : };
376 :
377 : #endif // vnsw_agent_vrf_hpp
|