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