Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef vnsw_agent_peer_h_
6 : #define vnsw_agent_peer_h_
7 :
8 : #include <atomic>
9 : #include <string>
10 : #include <map>
11 : #include <db/db_table_walker.h>
12 : #include <base/address.h>
13 : #include <boost/intrusive_ptr.hpp>
14 : #include <oper/agent_route_walker.h>
15 :
16 : #define LOCAL_PEER_NAME "Local"
17 : #define LOCAL_VM_PEER_NAME "Local_Vm"
18 : #define LOCAL_VM_PORT_PEER_NAME "LocalVmPort"
19 : #define NOVA_PEER_NAME "Nova"
20 : #define LINKLOCAL_PEER_NAME "LinkLocal"
21 : #define ECMP_PEER_NAME "Ecmp"
22 : #define VGW_PEER_NAME "Vgw"
23 : #define EVPN_ROUTING_PEER_NAME "EVPN Router"
24 : #define EVPN_PEER_NAME "EVPN"
25 : #define MULTICAST_PEER_NAME "Multicast"
26 : #define MULTICAST_TOR_PEER_NAME "Multicast TOR"
27 : #define MULTICAST_FABRIC_TREE_BUILDER_NAME "MulticastTreeBuilder"
28 : #define MAC_VM_BINDING_PEER_NAME "MacVmBindingPeer"
29 : #define MAC_LEARNING_PEER_NAME "DynamicMacLearningPeer"
30 : #define FABRIC_RT_EXPORT "FabricRouteExport"
31 : #define LOCAL_VM_EXPORT_PEER "LocalVmExportPeer"
32 :
33 : class AgentXmppChannel;
34 : class ControllerRouteWalker;
35 : class VrfTable;
36 : class AgentPath;
37 :
38 : class Peer;
39 : void intrusive_ptr_add_ref(const Peer* p);
40 : void intrusive_ptr_release(const Peer* p);
41 : typedef boost::intrusive_ptr<const Peer> PeerConstPtr;
42 : typedef boost::intrusive_ptr<Peer> PeerPtr;
43 :
44 : class Peer {
45 : public:
46 : typedef std::map<std::string, Peer *> PeerMap;
47 : typedef std::pair<std::string, Peer *> PeerPair;
48 : enum Type {
49 : MULTICAST_PEER,
50 : EVPN_PEER,
51 : BGP_PEER,
52 : EVPN_ROUTING_PEER,
53 : LINKLOCAL_PEER,
54 : ECMP_PEER,
55 : VXLAN_BGP_PEER,
56 : LOCAL_VM_PORT_PEER,
57 : LOCAL_VM_PEER,
58 : LOCAL_PEER,
59 : NOVA_PEER,
60 : VGW_PEER,
61 : MULTICAST_FABRIC_TREE_BUILDER,
62 : OVS_PEER,
63 : MULTICAST_TOR_PEER,
64 : MAC_VM_BINDING_PEER,
65 : INET_EVPN_PEER,
66 : MAC_LEARNING_PEER, /* The peer has the lowest priority
67 : to prevent interference with other paths */
68 : };
69 :
70 : Peer(Type type, const std::string &name, bool controller_export);
71 : virtual ~Peer();
72 :
73 404 : bool IsLess(const Peer *rhs) const {
74 404 : if (type_ != rhs->type_) {
75 396 : return type_ < rhs->type_;
76 : }
77 :
78 8 : return Compare(rhs);
79 : }
80 0 : virtual bool Compare(const Peer *rhs) const {return false;}
81 : // Should we export path from this peer to controller?
82 483 : virtual bool export_to_controller() const {return export_to_controller_;}
83 : virtual const Ip4Address *NexthopIp(Agent *agent,
84 : const AgentPath *path) const;
85 :
86 1020 : const std::string &GetName() const { return name_; }
87 5189 : const Type GetType() const { return type_; }
88 :
89 707 : virtual bool SkipAddChangeRequest() const { return false; }
90 :
91 1385 : virtual bool IsDeleted() const { return false; }
92 :
93 4 : uint32_t refcount() const { return refcount_; }
94 490 : uint64_t sequence_number() const {return sequence_number_;}
95 1 : void incr_sequence_number() {sequence_number_++;}
96 :
97 : private:
98 : friend void intrusive_ptr_add_ref(const Peer *p);
99 : friend void intrusive_ptr_release(const Peer *p);
100 :
101 : virtual bool DeleteOnZeroRefcount() const;
102 :
103 : Type type_;
104 : std::string name_;
105 : bool export_to_controller_;
106 : mutable std::atomic<uint32_t> refcount_;
107 : // Sequence number can be used for tracking event based changes like
108 : // add/update on peer flaps(as example).
109 : uint64_t sequence_number_;
110 : DISALLOW_COPY_AND_ASSIGN(Peer);
111 : };
112 :
113 : // DynamicPeer is one of the base class for Peer to be used for
114 : // all the Dynamic Peers.
115 : // This provide Peer pointer sanity using references ensuring
116 : // that the Peer pointer will be accessible till all the Async
117 : // DB Requests for this Peer has been processed and all the route
118 : // Paths are removed
119 : class DynamicPeer : public Peer {
120 : public:
121 : // Dynamic peer clean up is supposed to be relatively faster process
122 : // however trigger a timeoout after 5 mins to catch if any issue
123 : // happend
124 : static const uint32_t kDeleteTimeout = 300 * 1000;
125 :
126 : DynamicPeer(Agent *agent, Type type, const std::string &name,
127 : bool controller_export);
128 : virtual ~DynamicPeer();
129 :
130 : // Skip Add/Change request if set
131 65 : virtual bool SkipAddChangeRequest() const { return skip_add_change_; }
132 :
133 66 : virtual bool IsDeleted() const { return deleted_; }
134 :
135 : // only sets skip_add_change to true, should be set only just
136 : // before triggering a delete on Peer and a reset is not needed
137 4 : void StopRouteExports() { skip_add_change_ = true; }
138 :
139 : static void ProcessDelete(DynamicPeer *p);
140 :
141 : bool DeleteTimeout();
142 :
143 : private:
144 : friend void intrusive_ptr_add_ref(const Peer *p);
145 : friend void intrusive_ptr_release(const Peer *p);
146 :
147 : virtual bool DeleteOnZeroRefcount() const;
148 :
149 : Timer *delete_timeout_timer_;
150 : std::atomic<bool> deleted_;
151 : std::atomic<bool> skip_add_change_;
152 : DISALLOW_COPY_AND_ASSIGN(DynamicPeer);
153 : };
154 :
155 : // Peer used for BGP paths
156 : class BgpPeer : public DynamicPeer {
157 : public:
158 : typedef boost::function<void()> WalkDoneCb;
159 : BgpPeer(AgentXmppChannel *channel,
160 : const Ip4Address &server_ip, const std::string &name,
161 : DBTableBase::ListenerId id, Peer::Type bgp_peer_type);
162 : virtual ~BgpPeer();
163 :
164 0 : bool Compare(const Peer *rhs) const {
165 0 : const BgpPeer *bgp = static_cast<const BgpPeer *>(rhs);
166 0 : return server_ip_ < bgp->server_ip_;
167 : }
168 :
169 : // For testing
170 : void SetVrfListenerId(DBTableBase::ListenerId id) { id_ = id; }
171 841 : DBTableBase::ListenerId GetVrfExportListenerId() { return id_; }
172 :
173 : // Table Walkers
174 : //Notify walker
175 : void PeerNotifyRoutes(WalkDoneCb cb);
176 : void PeerNotifyMulticastRoutes(bool associate);
177 : void AllocPeerNotifyWalker();
178 : void ReleasePeerNotifyWalker();
179 : void StopPeerNotifyRoutes();
180 : //Del peer walker
181 : void DelPeerRoutes(WalkDoneCb walk_done_cb,
182 : uint64_t sequence_number);
183 : void DeleteStale();
184 : void AllocDeleteStaleWalker();
185 : void ReleaseDeleteStaleWalker();
186 : void AllocDeletePeerWalker();
187 : void ReleaseDeletePeerWalker();
188 : void StopDeleteStale();
189 :
190 : ControllerRouteWalker *route_walker() const;
191 : ControllerRouteWalker *delete_stale_walker() const;
192 : ControllerRouteWalker *delete_peer_walker() const;
193 :
194 : //Helper routines to get export state for vrf and route
195 : DBState *GetVrfExportState(DBTablePartBase *partition,
196 : DBEntryBase *e);
197 : DBState *GetRouteExportState(DBTablePartBase *partition,
198 : DBEntryBase *e);
199 : void DeleteVrfState(DBTablePartBase *partition, DBEntryBase *entry);
200 :
201 : uint32_t setup_time() const {return setup_time_;}
202 : Agent *agent() const;
203 : AgentXmppChannel *GetAgentXmppChannel() const;
204 : uint64_t ChannelSequenceNumber() const;
205 : void set_route_walker_cb(WalkDoneCb cb);
206 : void set_delete_stale_walker_cb(WalkDoneCb cb);
207 : void set_delete_peer_walker_cb(WalkDoneCb cb);
208 :
209 : private:
210 : AgentXmppChannel *channel_;
211 : Ip4Address server_ip_;
212 : DBTableBase::ListenerId id_;
213 : uint32_t setup_time_;
214 : AgentRouteWalkerPtr route_walker_;
215 : AgentRouteWalkerPtr delete_peer_walker_;
216 : AgentRouteWalkerPtr delete_stale_walker_;
217 : WalkDoneCb route_walker_cb_;
218 : WalkDoneCb delete_stale_walker_cb_;
219 : WalkDoneCb delete_peer_walker_cb_;
220 : DISALLOW_COPY_AND_ASSIGN(BgpPeer);
221 : };
222 :
223 : // Peer for local-vm-port paths. There can be multiple VMs with same IP.
224 : // They are all added as different path. ECMP path will consolidate all
225 : // local-vm-port paths
226 : class LocalVmPortPeer : public Peer {
227 : public:
228 15 : LocalVmPortPeer(const std::string &name, uint64_t handle) :
229 15 : Peer(Peer::LOCAL_VM_PORT_PEER, name, true), handle_(handle) {
230 15 : }
231 :
232 30 : virtual ~LocalVmPortPeer() { }
233 :
234 8 : bool Compare(const Peer *rhs) const {
235 8 : const LocalVmPortPeer *local =
236 : static_cast<const LocalVmPortPeer *>(rhs);
237 8 : return handle_ < local->handle_;
238 : }
239 :
240 : private:
241 : uint64_t handle_;
242 : DISALLOW_COPY_AND_ASSIGN(LocalVmPortPeer);
243 : };
244 :
245 : // ECMP peer
246 : class EcmpPeer : public Peer {
247 : public:
248 : EcmpPeer() : Peer(Peer::ECMP_PEER, "ECMP", true) { }
249 : virtual ~EcmpPeer() { }
250 :
251 : bool Compare(const Peer *rhs) const { return false; }
252 : private:
253 : DISALLOW_COPY_AND_ASSIGN(EcmpPeer);
254 : };
255 :
256 : // EVPN peer
257 : class EvpnPeer : public Peer {
258 : public:
259 : typedef boost::shared_ptr<EvpnPeer> EvpnPeerRef;
260 :
261 1 : EvpnPeer() : Peer(Peer::EVPN_PEER, "EVPN", false) { }
262 2 : virtual ~EvpnPeer() { }
263 :
264 0 : bool Compare(const Peer *rhs) const { return false; }
265 : private:
266 : DISALLOW_COPY_AND_ASSIGN(EvpnPeer);
267 : };
268 :
269 : // Inet EVPN peer
270 : class InetEvpnPeer : public Peer {
271 : public:
272 : typedef boost::shared_ptr<EvpnPeer> InetEvpnPeerRef;
273 :
274 1 : InetEvpnPeer() : Peer(Peer::INET_EVPN_PEER, "INET-EVPN", false) { }
275 2 : virtual ~InetEvpnPeer() { }
276 :
277 0 : bool Compare(const Peer *rhs) const { return false; }
278 : private:
279 : DISALLOW_COPY_AND_ASSIGN(InetEvpnPeer);
280 : };
281 :
282 : // EVPN routing peer
283 : class EvpnRoutingPeer : public Peer {
284 : public:
285 : typedef boost::shared_ptr<EvpnPeer> EvpnRoutingPeerRef;
286 :
287 1 : EvpnRoutingPeer() : Peer(Peer::EVPN_ROUTING_PEER, "EVPN-ROUTING", false) { }
288 2 : virtual ~EvpnRoutingPeer() { }
289 :
290 0 : bool Compare(const Peer *rhs) const { return false; }
291 : private:
292 : DISALLOW_COPY_AND_ASSIGN(EvpnRoutingPeer);
293 : };
294 :
295 : // EVPN routing peer
296 : class VxlanBgpPeer : public Peer {
297 : public:
298 : typedef boost::shared_ptr<VxlanBgpPeer> VxlanBgpPeerRef;
299 :
300 1 : VxlanBgpPeer() : Peer(Peer::VXLAN_BGP_PEER, "VxLAN BGP PEER", false) { }
301 2 : virtual ~VxlanBgpPeer() { }
302 :
303 0 : bool Compare(const Peer *rhs) const { return false; }
304 : private:
305 : DISALLOW_COPY_AND_ASSIGN(VxlanBgpPeer);
306 : };
307 :
308 : #endif // vnsw_agent_peer_h_
|