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