Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef vnsw_agent_route_ksync_h
6 : #define vnsw_agent_route_ksync_h
7 :
8 : #include <boost/asio.hpp>
9 : #include <boost/bind/bind.hpp>
10 :
11 : #include <db/db_entry.h>
12 : #include <db/db_table.h>
13 : #include <db/db_table_partition.h>
14 : #include <base/lifetime.h>
15 : #include <ksync/ksync_entry.h>
16 : #include <ksync/ksync_object.h>
17 : #include <ksync/ksync_netlink.h>
18 : #include "oper/nexthop.h"
19 : #include "oper/route_common.h"
20 : #include "oper/agent_route_walker.h"
21 : #include "vrouter/ksync/agent_ksync_types.h"
22 : #include "vrouter/ksync/nexthop_ksync.h"
23 :
24 : using namespace boost::placeholders;
25 :
26 : class RouteKSyncObject;
27 :
28 : class RouteKSyncEntry : public KSyncNetlinkDBEntry {
29 : public:
30 : RouteKSyncEntry(RouteKSyncObject* obj, const RouteKSyncEntry *entry,
31 : uint32_t index);
32 : RouteKSyncEntry(RouteKSyncObject* obj, const AgentRoute *route);
33 : virtual ~RouteKSyncEntry();
34 :
35 99 : uint32_t prefix_len() const { return prefix_len_; }
36 20 : uint32_t label() const { return label_; }
37 453 : bool proxy_arp() const { return proxy_arp_; }
38 453 : bool flood() const { return flood_; }
39 2 : bool flood_dhcp() const { return flood_dhcp_; }
40 20 : bool wait_for_traffic() const { return wait_for_traffic_; }
41 414 : MacAddress mac() const { return mac_; }
42 3464 : NHKSyncEntry* nh() const {
43 3464 : return static_cast<NHKSyncEntry *>(nh_.get());
44 : }
45 3936 : void set_prefix_len(uint32_t len) { prefix_len_ = len; }
46 3936 : void set_ip(IpAddress addr) { addr_ = addr; }
47 : KSyncDBObject *GetObject() const;
48 :
49 : void FillObjectLog(sandesh_op::type op, KSyncRouteInfo &info) const;
50 : virtual bool IsLess(const KSyncEntry &rhs) const;
51 : virtual std::string ToString() const;
52 : virtual KSyncEntry *UnresolvedReference();
53 : virtual bool Sync(DBEntry *e);
54 : virtual int AddMsg(char *buf, int buf_len);
55 : virtual int ChangeMsg(char *buf, int buf_len);
56 : virtual int DeleteMsg(char *buf, int buf_len);
57 :
58 : bool BuildArpFlags(const DBEntry *rt, const AgentPath *path,
59 : const MacAddress &mac);
60 : uint8_t CopyReplacementData(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt);
61 20 : bool IsLearntRoute() { return is_learnt_route_;}
62 : private:
63 : int Encode(sandesh_op::type op, uint8_t replace_plen,
64 : char *buf, int buf_len);
65 : int DeleteInternal(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt,
66 : char *buf, int buf_len);
67 : bool UcIsLess(const KSyncEntry &rhs) const;
68 : bool McIsLess(const KSyncEntry &rhs) const;
69 : bool EvpnIsLess(const KSyncEntry &rhs) const;
70 : bool L2IsLess(const KSyncEntry &rhs) const;
71 : const NextHop *GetActiveNextHop(const AgentRoute *route) const;
72 : const AgentPath *GetActivePath(const AgentRoute *route) const;
73 :
74 : RouteKSyncObject* ksync_obj_;
75 : Agent::RouteTableType rt_type_;
76 : uint32_t vrf_id_;
77 : IpAddress addr_;
78 : IpAddress src_addr_;
79 : MacAddress mac_;
80 : uint32_t prefix_len_;
81 : KSyncEntryPtr nh_;
82 : uint32_t label_;
83 : uint8_t type_;
84 : bool proxy_arp_;
85 : bool flood_dhcp_;
86 : string address_string_;
87 : TunnelType::Type tunnel_type_;
88 : bool wait_for_traffic_;
89 : bool local_vm_peer_route_;
90 : bool flood_;
91 : uint32_t ethernet_tag_;
92 : bool layer2_control_word_;
93 : bool is_learnt_route_; // this does not need to be copied for replacement
94 : // data
95 : //////////////////////////////////////////////////////////////////
96 : // NOTE: Please update CopyReplacmenetData when any new field is added
97 : // here
98 : //////////////////////////////////////////////////////////////////
99 : DISALLOW_COPY_AND_ASSIGN(RouteKSyncEntry);
100 : };
101 :
102 : class RouteKSyncObject : public KSyncDBObject {
103 : public:
104 : struct VrfState : DBState {
105 : VrfState() : DBState(), seen_(false),
106 : created_(UTCTimestampUsec()) {};
107 : bool seen_;
108 : uint64_t created_;
109 : };
110 :
111 : RouteKSyncObject(KSync *ksync, AgentRouteTable *rt_table);
112 : virtual ~RouteKSyncObject();
113 :
114 2925 : KSync *ksync() const { return ksync_; }
115 :
116 : virtual KSyncEntry *Alloc(const KSyncEntry *entry, uint32_t index);
117 : virtual KSyncEntry *DBToKSyncEntry(const DBEntry *e);
118 : void ManagedDelete();
119 : void Unregister();
120 : virtual void EmptyTable();
121 : DBFilterResp DBEntryFilter(const DBEntry *entry, const KSyncDBEntry *ksync);
122 :
123 : private:
124 : KSync *ksync_;
125 : bool marked_delete_;
126 : AgentRouteTable *rt_table_;
127 : LifetimeRef<RouteKSyncObject> table_delete_ref_;
128 : DISALLOW_COPY_AND_ASSIGN(RouteKSyncObject);
129 : };
130 :
131 : struct MacBinding {
132 : typedef std::map<const MacAddress,
133 : PathPreference> MacPreferenceMap;
134 : typedef std::pair<const MacAddress,
135 : PathPreference> MacPreferencePair;
136 :
137 40 : MacBinding(const MacBinding &mac_binding):
138 40 : mac_preference_map_(mac_binding.mac_preference_map_) {}
139 :
140 20 : MacBinding(const MacAddress &mac, const PathPreference &pref) {
141 20 : mac_preference_map_[mac] = pref;
142 20 : }
143 :
144 22 : const MacAddress& get_mac() const {
145 22 : const MacAddress *mac = &MacAddress::ZeroMac();
146 22 : uint32_t pref = PathPreference::INVALID;
147 22 : for (MacPreferenceMap::const_iterator it = mac_preference_map_.begin();
148 44 : it != mac_preference_map_.end(); it++) {
149 22 : if (*mac == MacAddress::ZeroMac() || pref < it->second.preference()) {
150 22 : mac = &(it->first);
151 22 : pref = it->second.preference();
152 : }
153 : }
154 22 : return *mac;
155 : }
156 :
157 31 : void reset_mac(const MacAddress &mac) {
158 31 : mac_preference_map_.erase(mac);
159 31 : }
160 :
161 31 : bool can_erase() {
162 31 : if (mac_preference_map_.size() == 0) {
163 20 : return true;
164 : }
165 11 : return false;
166 : }
167 :
168 56 : void set_mac(const PathPreference &pref,
169 : const MacAddress &mac) {
170 56 : mac_preference_map_[mac] = pref;
171 56 : }
172 :
173 22 : bool WaitForTraffic() const {
174 22 : for (MacPreferenceMap::const_iterator it = mac_preference_map_.begin();
175 22 : it != mac_preference_map_.end(); it++) {
176 22 : if (it->second.wait_for_traffic() == true) {
177 22 : return true;
178 : }
179 : }
180 0 : return false;
181 : }
182 :
183 : private:
184 : MacPreferenceMap mac_preference_map_;
185 : };
186 :
187 : class VrfKSyncObject;
188 :
189 : class VrfKSyncEntry : public KSyncNetlinkDBEntry {
190 : public:
191 : VrfKSyncEntry(VrfKSyncObject* obj, const VrfKSyncEntry *entry,
192 : uint32_t index);
193 : VrfKSyncEntry(VrfKSyncObject* obj, const VrfEntry *vrf);
194 : virtual ~VrfKSyncEntry();
195 :
196 483 : const uint32_t hbf_rintf() const { return hbf_rintf_; }
197 482 : const uint32_t hbf_lintf() const { return hbf_lintf_; }
198 174 : const uint32_t vrf_id() const { return vrf_id_; }
199 : void set_hbf_rintf(uint32_t hbf_rintf) { hbf_rintf_ = hbf_rintf_; }
200 : void set_hbf_lintf(uint32_t hbf_lintf) { hbf_lintf_ = hbf_lintf_; }
201 : KSyncDBObject *GetObject() const;
202 :
203 : void FillObjectLog(sandesh_op::type op, KSyncVrfInfo &info) const;
204 : virtual bool IsLess(const KSyncEntry &rhs) const;
205 : virtual std::string ToString() const;
206 : virtual KSyncEntry *UnresolvedReference();
207 : virtual bool Sync(DBEntry *e);
208 : virtual int AddMsg(char *buf, int buf_len);
209 : virtual int ChangeMsg(char *buf, int buf_len);
210 : virtual int DeleteMsg(char *buf, int buf_len);
211 : private:
212 : int Encode(sandesh_op::type op, uint8_t replace_plen,
213 : char *buf, int buf_len);
214 :
215 : VrfKSyncObject* ksync_obj_;
216 : uint32_t vrf_id_;
217 : uint32_t hbf_rintf_;
218 : uint32_t hbf_lintf_;
219 : DISALLOW_COPY_AND_ASSIGN(VrfKSyncEntry);
220 : };
221 :
222 :
223 : class KSyncRouteWalker;
224 : class VrfKSyncObject : public KSyncDBObject {
225 : public:
226 : // Table to maintain IP - MAC binding. Used to stitch MAC to inet routes
227 : typedef std::pair<IpAddress, uint32_t> IpToMacBindingKey;
228 : typedef std::map<IpToMacBindingKey, MacBinding> IpToMacBinding;
229 :
230 : struct VrfState : DBState {
231 : VrfState(Agent *agent);
232 : bool seen_;
233 : RouteKSyncObject *inet4_uc_route_table_;
234 : RouteKSyncObject *inet4_mc_route_table_;
235 : RouteKSyncObject *inet6_uc_route_table_;
236 : RouteKSyncObject *bridge_route_table_;
237 : IpToMacBinding ip_mac_binding_;
238 : DBTableBase::ListenerId evpn_rt_table_listener_id_;
239 : AgentRouteWalkerPtr ksync_route_walker_;
240 : VrfKSyncEntry* ksync_;
241 : };
242 :
243 : VrfKSyncObject(KSync *ksync);
244 : virtual ~VrfKSyncObject();
245 :
246 0 : KSync *ksync() const { return ksync_; }
247 :
248 : void RegisterDBClients();
249 : void Shutdown();
250 : void VrfNotify(DBTablePartBase *partition, DBEntryBase *e);
251 :
252 : void EvpnRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e);
253 : void UnRegisterEvpnRouteTableListener(const VrfEntry *entry,
254 : VrfState *state);
255 : void AddIpMacBinding(VrfEntry *vrf, const IpAddress &ip,
256 : const MacAddress &mac,
257 : uint32_t ethernet_tag,
258 : uint32_t pref,
259 : bool wait_for_traffic);
260 : void DelIpMacBinding(VrfEntry *vrf, const IpAddress &ip,
261 : const MacAddress &mac, uint32_t ethernet_tag);
262 : MacAddress GetIpMacBinding(VrfEntry *vrf, const IpAddress &ip,
263 : const InetUnicastRouteEntry *rt) const;
264 : bool GetIpMacWaitForTraffic(VrfEntry *vrf,
265 : const IpAddress &ip) const;
266 : void NotifyUcRoute(VrfEntry *vrf, VrfState *state, const IpAddress &ip);
267 : bool RouteNeedsMacBinding(const InetUnicastRouteEntry *rt);
268 318 : DBTableBase::ListenerId vrf_listener_id() const {return vrf_listener_id_;}
269 : virtual KSyncEntry *Alloc(const KSyncEntry *entry, uint32_t index);
270 : virtual KSyncEntry *DBToKSyncEntry(const DBEntry *entry);
271 :
272 : private:
273 : KSync *ksync_;
274 : DBTableBase::ListenerId vrf_listener_id_;
275 : bool marked_delete_;
276 : VrfTable *vrf_table_;
277 : DISALLOW_COPY_AND_ASSIGN(VrfKSyncObject);
278 : };
279 :
280 : class KSyncRouteWalker : public AgentRouteWalker {
281 : public:
282 : typedef DBTableWalker::WalkId RouteWalkerIdList[Agent::ROUTE_TABLE_MAX];
283 : KSyncRouteWalker(Agent *agent, VrfKSyncObject::VrfState *state);
284 : virtual ~KSyncRouteWalker();
285 :
286 : void NotifyRoutes(VrfEntry *vrf);
287 : void EnqueueDelete();
288 : virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e);
289 :
290 : private:
291 : VrfKSyncObject::VrfState *state_;
292 : bool marked_for_deletion_;
293 : DISALLOW_COPY_AND_ASSIGN(KSyncRouteWalker);
294 : };
295 :
296 : #endif // vnsw_agent_route_ksync_h
|