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