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