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_vn_hpp
7 : #define vnsw_agent_vn_hpp
8 :
9 : #include <cmn/agent_cmn.h>
10 : #include <cmn/agent.h>
11 : #include <oper/agent_types.h>
12 : #include <oper/oper_db.h>
13 : #include <oper/oper_dhcp_options.h>
14 : #include <oper/agent_route_walker.h>
15 :
16 : class AgentRouteResync;
17 :
18 : namespace autogen {
19 : class NetworkIpam;
20 : class VirtualDns;
21 : struct IpamType;
22 : struct VirtualDnsType;
23 : }
24 :
25 : bool IsVRFServiceChainingInstance(const std::string &vn_name,
26 : const std::string &vrf_name);
27 : class VmInterface;
28 :
29 : struct VnIpam {
30 : IpAddress ip_prefix;
31 : uint32_t plen;
32 : IpAddress default_gw;
33 : // In case of TSN, we could have different addresses for default_gw & dns
34 : IpAddress dns_server;
35 : bool installed; // is the route to send pkts to host installed
36 : bool dhcp_enable;
37 : bool dhcp_enable_v6;
38 : std::string ipam_name;
39 : OperDhcpOptions oper_dhcp_options;
40 : uint32_t alloc_unit;
41 :
42 : VnIpam(const std::string& ip, uint32_t len, const std::string& gw,
43 : const std::string& dns, bool dhcp, const std::string &name,
44 : const std::vector<autogen::DhcpOptionType> &dhcp_options,
45 : const std::vector<autogen::RouteType> &host_routes,
46 : uint32_t alloc);
47 :
48 182 : bool IsV4() const {
49 182 : return ip_prefix.is_v4();
50 : }
51 0 : bool IsV6() const {
52 0 : return ip_prefix.is_v6();
53 : }
54 904 : bool operator<(const VnIpam &rhs) const {
55 904 : if (ip_prefix != rhs.ip_prefix)
56 324 : return ip_prefix < rhs.ip_prefix;
57 :
58 580 : return (plen < rhs.plen);
59 : }
60 : IpAddress GetSubnetAddress() const;
61 :
62 : bool IsSubnetMember(const IpAddress &ip) const;
63 : };
64 :
65 : // Per IPAM data of the VN
66 : struct VnIpamLinkData {
67 : OperDhcpOptions oper_dhcp_options_;
68 :
69 227 : bool operator==(const VnIpamLinkData &rhs) const {
70 227 : if (oper_dhcp_options_.host_routes() ==
71 : rhs.oper_dhcp_options_.host_routes())
72 227 : return true;
73 0 : return false;
74 : }
75 : };
76 :
77 : struct VnKey : public AgentOperDBKey {
78 3705 : VnKey(const boost::uuids::uuid &id) : AgentOperDBKey(), uuid_(id) { }
79 4552 : virtual ~VnKey() { }
80 :
81 : boost::uuids::uuid uuid_;
82 : };
83 :
84 : struct VnData : public AgentOperDBData {
85 : typedef std::map<std::string, VnIpamLinkData> VnIpamDataMap;
86 : typedef std::pair<std::string, VnIpamLinkData> VnIpamDataPair;
87 :
88 651 : VnData(const Agent *agent, IFMapNode *node, const string &name,
89 : const boost::uuids::uuid &acl_id, const string &vrf_name,
90 : const boost::uuids::uuid &mirror_acl_id,
91 : const boost::uuids::uuid &mc_acl_id, const std::vector<VnIpam> &ipam,
92 : const VnIpamDataMap &vn_ipam_data, int vxlan_id, int vnid,
93 : bool admin_state, bool enable_rpf, bool flood_unknown_unicast,
94 : Agent::ForwardingMode forwarding_mode,
95 : const boost::uuids::uuid &qos_config_uuid, bool mirror_destination,
96 : bool pbb_etree_enable, bool pbb_evpn_enable,
97 : bool layer2_control_word, UuidList slo_list,
98 : bool underlay_forwarding,
99 : bool vxlan_routing_vn,
100 : const boost::uuids::uuid &logical_router_uuid,
101 : UuidList mp_list, bool cfg_igmp_enable, uint32_t vn_max_flows,
102 : bool mac_ip_learning_enable,
103 651 : const boost::uuids::uuid &health_check_uuid) :
104 651 : AgentOperDBData(agent, node), name_(name), vrf_name_(vrf_name),
105 651 : acl_id_(acl_id), mirror_acl_id_(mirror_acl_id),
106 651 : mirror_cfg_acl_id_(mc_acl_id), ipam_(ipam), vn_ipam_data_(vn_ipam_data),
107 651 : vxlan_id_(vxlan_id), vnid_(vnid), admin_state_(admin_state),
108 651 : enable_rpf_(enable_rpf), flood_unknown_unicast_(flood_unknown_unicast),
109 651 : forwarding_mode_(forwarding_mode), qos_config_uuid_(qos_config_uuid),
110 651 : mirror_destination_(mirror_destination),
111 651 : pbb_etree_enable_(pbb_etree_enable), pbb_evpn_enable_(pbb_evpn_enable),
112 651 : layer2_control_word_(layer2_control_word), slo_list_(slo_list),
113 651 : underlay_forwarding_(underlay_forwarding),
114 651 : vxlan_routing_vn_(vxlan_routing_vn),
115 651 : logical_router_uuid_(logical_router_uuid), mp_list_(mp_list),
116 651 : cfg_igmp_enable_(cfg_igmp_enable),
117 651 : vn_max_flows_(vn_max_flows),
118 651 : mac_ip_learning_enable_(mac_ip_learning_enable),
119 651 : health_check_uuid_(health_check_uuid) {
120 651 : };
121 1302 : virtual ~VnData() { }
122 :
123 : string name_;
124 : string vrf_name_;
125 : boost::uuids::uuid acl_id_;
126 : boost::uuids::uuid mirror_acl_id_;
127 : boost::uuids::uuid mirror_cfg_acl_id_;
128 : std::vector<VnIpam> ipam_;
129 : VnIpamDataMap vn_ipam_data_;
130 : int vxlan_id_;
131 : int vnid_;
132 : bool admin_state_;
133 : bool enable_rpf_;
134 : bool flood_unknown_unicast_;
135 : Agent::ForwardingMode forwarding_mode_;
136 : boost::uuids::uuid qos_config_uuid_;
137 : bool mirror_destination_;
138 : bool pbb_etree_enable_;
139 : bool pbb_evpn_enable_;
140 : bool layer2_control_word_;
141 : UuidList slo_list_;
142 : bool underlay_forwarding_;
143 : bool vxlan_routing_vn_;
144 : boost::uuids::uuid logical_router_uuid_;
145 : UuidList mp_list_;
146 : bool cfg_igmp_enable_;
147 : uint32_t vn_max_flows_;
148 : bool mac_ip_learning_enable_;
149 : boost::uuids::uuid health_check_uuid_;
150 : };
151 :
152 : class VnEntry : AgentRefCount<VnEntry>, public AgentOperDBEntry {
153 : public:
154 : VnEntry(Agent *agent, boost::uuids::uuid id);
155 : virtual ~VnEntry();
156 :
157 : virtual bool IsLess(const DBEntry &rhs) const;
158 : virtual KeyPtr GetDBRequestKey() const;
159 : virtual void SetKey(const DBRequestKey *key);
160 : virtual string ToString() const;
161 :
162 1119 : const boost::uuids::uuid &GetUuid() const {return uuid_;};
163 12652 : const string &GetName() const {return name_;};
164 : bool IsAclSet() const {
165 : return ((acl_.get() != NULL) || (mirror_acl_.get() != NULL) ||
166 : (mirror_cfg_acl_.get() != NULL));
167 : }
168 1389 : const AclDBEntry *GetAcl() const {return acl_.get();}
169 1267 : const AclDBEntry *GetMirrorAcl() const {return mirror_acl_.get();}
170 1267 : const AclDBEntry *GetMirrorCfgAcl() const {return mirror_cfg_acl_.get();}
171 3500 : VrfEntry *GetVrf() const {return vrf_.get();}
172 971 : const std::vector<VnIpam> &GetVnIpam() const { return ipam_; }
173 : const VnIpam *GetIpam(const IpAddress &ip) const;
174 : IpAddress GetGatewayFromIpam(const IpAddress &ip) const;
175 : IpAddress GetDnsFromIpam(const IpAddress &ip) const;
176 : uint32_t GetAllocUnitFromIpam(const IpAddress &ip) const;
177 : bool GetVnHostRoutes(const std::string &ipam,
178 : std::vector<OperDhcpOptions::HostRoute> *routes) const;
179 : bool GetIpamName(const IpAddress &vm_addr, std::string *ipam_name) const;
180 : bool GetIpamData(const IpAddress &vm_addr, std::string *ipam_name,
181 : autogen::IpamType *ipam_type) const;
182 : bool GetIpamVdnsData(const IpAddress &vm_addr,
183 : autogen::IpamType *ipam_type,
184 : autogen::VirtualDnsType *vdns_type) const;
185 : bool GetPrefix(const Ip6Address &ip, Ip6Address *prefix,
186 : uint8_t *plen) const;
187 : std::string GetProject() const;
188 : int GetVxLanId() const;
189 :
190 : /// Returns a value of the VxLAN ID stored in the Oper DB
191 : int GetOperVxlanId() const;
192 :
193 2 : const VxLanId *vxlan_id_ref() const {return vxlan_id_ref_.get();}
194 : void set_bridging(bool bridging) {bridging_ = bridging;}
195 7024 : bool bridging() const {return bridging_;};
196 4748 : bool layer3_forwarding() const {return layer3_forwarding_;};
197 : void set_layer3_forwarding(bool layer3_forwarding)
198 : {layer3_forwarding_ = layer3_forwarding;}
199 : Agent::ForwardingMode forwarding_mode() const {return forwarding_mode_;}
200 :
201 11475 : bool admin_state() const {return admin_state_;}
202 632 : bool enable_rpf() const {return enable_rpf_;}
203 1203 : bool flood_unknown_unicast() const {return flood_unknown_unicast_;}
204 :
205 1000 : const AgentQosConfig* qos_config() const {
206 1000 : return qos_config_.get();
207 : }
208 :
209 984 : const bool mirror_destination() const {
210 984 : return mirror_destination_;
211 : }
212 0 : int vnid() const {return vnid_;}
213 :
214 1000 : bool pbb_etree_enable() const {
215 1000 : return pbb_etree_enable_;
216 : }
217 :
218 : bool pbb_evpn_enable() const {
219 : return pbb_evpn_enable_;
220 : }
221 :
222 1491 : bool layer2_control_word() const {
223 1491 : return layer2_control_word_;
224 : }
225 :
226 70 : const UuidList &slo_list() const {
227 70 : return slo_list_;
228 : }
229 :
230 0 : bool underlay_forwarding() const {
231 0 : return underlay_forwarding_;
232 : }
233 :
234 0 : const UuidList &mp_list() const {
235 0 : return mp_list_;
236 : }
237 :
238 0 : bool cfg_igmp_enable() const {
239 0 : return cfg_igmp_enable_;
240 : }
241 :
242 200 : bool mac_ip_learning_enable() const {
243 200 : return mac_ip_learning_enable_;
244 : }
245 :
246 200 : const boost::uuids::uuid &health_check_uuid() const {
247 200 : return health_check_uuid_;
248 : }
249 :
250 69 : uint32_t GetRefCount() const {
251 69 : return AgentRefCount<VnEntry>::GetRefCount();
252 : }
253 : bool DBEntrySandesh(Sandesh *sresp, std::string &name) const;
254 : void SendObjectLog(SandeshTraceBufferPtr ptr,
255 : AgentLogEvent::type event) const;
256 : bool IdentifyBgpRoutersServiceIp(const IpAddress &ip_address, bool *is_dns,
257 : bool *is_gateway) const;
258 : void AllocWalker();
259 : void ReleaseWalker();
260 7671 : bool vxlan_routing_vn() const {return vxlan_routing_vn_;}
261 920 : const boost::uuids::uuid &logical_router_uuid() const {
262 920 : return logical_router_uuid_;
263 : }
264 0 : uint32_t vn_max_flows() const {return vn_max_flows_;}
265 :
266 0 : const VrfEntry* lr_vrf() const {
267 0 : return lr_vrf_.get();
268 : }
269 :
270 248 : void set_lr_vrf(const VrfEntry *vrf) {
271 248 : lr_vrf_.reset(vrf);
272 248 : }
273 :
274 : private:
275 : friend class VnTable;
276 : bool Resync(Agent *agent);
277 : bool ChangeHandler(Agent *agent, const DBRequest *req);
278 : bool UpdateVxlan(Agent *agent, bool op_del);
279 : void ResyncRoutes();
280 : bool UpdateForwardingMode(Agent *agent);
281 : bool ApplyAllIpam(Agent *agent, VrfEntry *old_vrf, bool del);
282 : bool ApplyIpam(Agent *agent, VnIpam *ipam, VrfEntry *old_vrf, bool del);
283 : bool CanInstallIpam(const VnIpam *ipam);
284 : bool UpdateIpam(Agent *agent, std::vector<VnIpam> &new_ipam);
285 : bool HandleIpamChange(Agent *agent, VnIpam *old_ipam, VnIpam *new_ipam);
286 : void UpdateHostRoute(Agent *agent, const IpAddress &old_address,
287 : const IpAddress &new_address, bool policy);
288 : bool AddIpamRoutes(Agent *agent, VnIpam *ipam);
289 : void DelIpamRoutes(Agent *agent, VnIpam *ipam, VrfEntry *vrf);
290 : void AddHostRoute(const IpAddress &address, bool policy);
291 : void DelHostRoute(const IpAddress &address);
292 : void AddSubnetRoute(VnIpam *ipam);
293 : void DelSubnetRoute(VnIpam *ipam);
294 :
295 : Agent *agent_;
296 : boost::uuids::uuid uuid_;
297 : string name_;
298 : AclDBEntryRef acl_;
299 : AclDBEntryRef mirror_acl_;
300 : AclDBEntryRef mirror_cfg_acl_;
301 : VrfEntryRef vrf_;
302 : std::vector<VnIpam> ipam_;
303 : VnData::VnIpamDataMap vn_ipam_data_;
304 : int vxlan_id_;
305 : int vnid_;
306 : // Based on vxlan-network-identifier mode, the active_vxlan_id_ is picked
307 : // from either vxlan_id_ or vnid_
308 : int active_vxlan_id_;
309 : bool bridging_;
310 : bool layer3_forwarding_;
311 : bool admin_state_;
312 : VxLanIdRef vxlan_id_ref_;
313 : uint32_t table_label_;
314 : bool enable_rpf_;
315 : bool flood_unknown_unicast_;
316 : Agent::ForwardingMode forwarding_mode_;
317 : AgentRouteWalkerPtr route_resync_walker_;
318 : AgentQosConfigConstRef qos_config_;
319 : bool mirror_destination_;
320 : bool pbb_etree_enable_;
321 : bool pbb_evpn_enable_;
322 : bool layer2_control_word_;
323 : UuidList slo_list_;
324 : bool underlay_forwarding_;
325 : bool vxlan_routing_vn_;
326 : boost::uuids::uuid logical_router_uuid_;
327 : UuidList mp_list_;
328 : bool cfg_igmp_enable_;
329 : uint32_t vn_max_flows_;
330 : bool mac_ip_learning_enable_;
331 : boost::uuids::uuid health_check_uuid_;
332 : VrfEntryConstRef lr_vrf_;
333 : DISALLOW_COPY_AND_ASSIGN(VnEntry);
334 : };
335 :
336 : class VnTable : public AgentOperDBTable {
337 : public:
338 : VnTable(DB *db, const std::string &name);
339 : virtual ~VnTable();
340 :
341 : virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
342 6497 : virtual size_t Hash(const DBEntry *entry) const {return 0;};
343 3705 : virtual size_t Hash(const DBRequestKey *key) const {return 0;};
344 : virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
345 : const std::string &context);
346 :
347 : virtual DBEntry *OperDBAdd(const DBRequest *req);
348 : virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req);
349 : virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req);
350 : virtual bool OperDBResync(DBEntry *entry, const DBRequest *req);
351 :
352 : virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req,
353 : const boost::uuids::uuid &u);
354 : virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u);
355 : virtual bool ProcessConfig(IFMapNode *node, DBRequest &req,
356 : const boost::uuids::uuid &u);
357 : virtual void Clear();
358 :
359 : void CfgForwardingFlags(IFMapNode *node, bool *rpf,
360 : bool *flood_unknown_unicast,
361 : Agent::ForwardingMode *forwarding_mode,
362 : bool *mirror_destination);
363 :
364 : static DBTableBase *CreateTable(DB *db, const std::string &name);
365 : static VnTable *GetInstance() {return vn_table_;};
366 :
367 : void AddVn(const boost::uuids::uuid &vn_uuid, const string &name,
368 : const boost::uuids::uuid &acl_id, const string &vrf_name,
369 : const std::vector<VnIpam> &ipam,
370 : const VnData::VnIpamDataMap &vn_ipam_data, int vn_id,
371 : int vxlan_id, bool admin_state, bool enable_rpf,
372 : bool flood_unknown_unicast, bool pbb_etree_enable,
373 : bool pbb_evpn_enable, bool layer2_control_word);
374 : void DelVn(const boost::uuids::uuid &vn_uuid);
375 : void ResyncReq(const boost::uuids::uuid &vn);
376 : VnEntry *Find(const boost::uuids::uuid &vn_uuid);
377 : void GlobalVrouterConfigChanged();
378 : bool VnEntryWalk(DBTablePartBase *partition, DBEntryBase *entry);
379 : void VnEntryWalkDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition);
380 : int GetCfgVnId(autogen::VirtualNetwork *cfg_vn);
381 :
382 : private:
383 : static VnTable *vn_table_;
384 : bool IsGwHostRouteRequired();
385 : bool IsGatewayL2(const string &gateway) const;
386 : void BuildVnIpamData(const std::vector<autogen::IpamSubnetType> &subnets,
387 : const std::string &ipam_name,
388 : std::vector<VnIpam> *vn_ipam);
389 : VnData *BuildData(IFMapNode *node);
390 : IFMapNode *FindTarget(IFMapAgentTable *table, IFMapNode *node,
391 : std::string node_type);
392 : DBTable::DBTableWalkRef walk_ref_;
393 :
394 : DISALLOW_COPY_AND_ASSIGN(VnTable);
395 : };
396 :
397 : class OperNetworkIpam : public OperIFMapTable {
398 : public:
399 :
400 : OperNetworkIpam(Agent *agent, DomainConfig *domain_config);
401 : virtual ~OperNetworkIpam();
402 :
403 : void ConfigDelete(IFMapNode *node);
404 : void ConfigAddChange(IFMapNode *node);
405 : void ConfigManagerEnqueue(IFMapNode *node);
406 : private:
407 : DomainConfig *domain_config_;
408 : DISALLOW_COPY_AND_ASSIGN(OperNetworkIpam);
409 : };
410 :
411 : class OperVirtualDns : public OperIFMapTable {
412 : public:
413 :
414 : OperVirtualDns(Agent *agent, DomainConfig *domain_config);
415 : virtual ~OperVirtualDns();
416 :
417 : void ConfigDelete(IFMapNode *node);
418 : void ConfigAddChange(IFMapNode *node);
419 : void ConfigManagerEnqueue(IFMapNode *node);
420 : private:
421 : DomainConfig *domain_config_;
422 : DISALLOW_COPY_AND_ASSIGN(OperVirtualDns);
423 : };
424 :
425 : class DomainConfig {
426 : public:
427 : typedef std::map<std::string, autogen::IpamType> IpamDomainConfigMap;
428 : typedef std::pair<std::string, autogen::IpamType> IpamDomainConfigPair;
429 : typedef std::map<std::string, autogen::VirtualDnsType> VdnsDomainConfigMap;
430 : typedef std::pair<std::string, autogen::VirtualDnsType> VdnsDomainConfigPair;
431 : typedef boost::function<void(IFMapNode *)> Callback;
432 :
433 : DomainConfig(Agent *);
434 : virtual ~DomainConfig();
435 : void Init();
436 : void Terminate();
437 : void RegisterIpamCb(Callback cb);
438 : void RegisterVdnsCb(Callback cb);
439 : void IpamDelete(IFMapNode *node);
440 : void IpamAddChange(IFMapNode *node);
441 : void VDnsDelete(IFMapNode *node);
442 : void VDnsAddChange(IFMapNode *node);
443 : bool GetIpam(const std::string &name, autogen::IpamType *ipam);
444 : bool GetVDns(const std::string &vdns, autogen::VirtualDnsType *vdns_type);
445 :
446 : private:
447 : void CallVdnsCb(IFMapNode *node);
448 : void CallIpamCb(IFMapNode *node);
449 : bool IpamChanged(const autogen::IpamType &old,
450 : const autogen::IpamType &cur) const;
451 :
452 : IpamDomainConfigMap ipam_config_;
453 : VdnsDomainConfigMap vdns_config_;
454 : std::vector<Callback> ipam_callback_;
455 : std::vector<Callback> vdns_callback_;
456 :
457 : DISALLOW_COPY_AND_ASSIGN(DomainConfig);
458 : };
459 :
460 : #endif // vnsw_agent_vn_hpp
|