Line data Source code
1 : /*
2 : * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include <boost/uuid/uuid_io.hpp>
7 : #include <cmn/agent_cmn.h>
8 :
9 : #include <base/logging.h>
10 : #include <oper/operdb_init.h>
11 : #include <oper/route_common.h>
12 : #include <oper/vrf.h>
13 : #include <oper/bridge_route.h>
14 : #include <oper/inet_unicast_route.h>
15 : #include <oper/evpn_route.h>
16 : #include <oper/agent_route.h>
17 : #include <oper/agent_route_walker.h>
18 : #include <oper/vn.h>
19 : #include <oper/vrf.h>
20 : #include <oper/vxlan_routing_manager.h>
21 : #include <oper/tunnel_nh.h> //for tunnel interception
22 :
23 : using namespace std;
24 :
25 70 : VxlanRoutingState::VxlanRoutingState(VxlanRoutingManager *mgr,
26 70 : VrfEntry *vrf) {
27 70 : inet4_table_ = vrf->GetInet4UnicastRouteTable();
28 70 : inet6_table_ = vrf->GetInet6UnicastRouteTable();
29 70 : evpn_table_ = vrf->GetEvpnRouteTable();
30 140 : std::string nm4 = std::string("vxlan_lstnr.") + inet4_table_->name();
31 140 : std::string nm6 = std::string("vxlan_lstnr.") + inet6_table_->name();
32 140 : std::string nme = std::string("vxlan_lstnr.") + evpn_table_->name();
33 :
34 140 : inet4_id_ = inet4_table_->
35 70 : Register(boost::bind(&VxlanRoutingManager::RouteNotify,
36 : mgr, _1, _2), nm4);
37 140 : inet6_id_ = inet6_table_->
38 70 : Register(boost::bind(&VxlanRoutingManager::RouteNotify,
39 : mgr, _1, _2), nm6);
40 140 : evpn_id_ = evpn_table_->
41 70 : Register(boost::bind(&VxlanRoutingManager::RouteNotify,
42 : mgr, _1, _2), nme);
43 70 : }
44 :
45 140 : VxlanRoutingState::~VxlanRoutingState() {
46 70 : evpn_table_->Unregister(evpn_id_);
47 70 : inet4_table_->Unregister(inet4_id_);
48 70 : inet6_table_->Unregister(inet6_id_);
49 140 : }
50 :
51 69 : VxlanRoutingVnState::VxlanRoutingVnState(VxlanRoutingManager *mgr) :
52 138 : vmi_list_(), is_routing_vn_(false),
53 69 : logical_router_uuid_(boost::uuids::nil_uuid()), mgr_(mgr) {
54 69 : }
55 :
56 138 : VxlanRoutingVnState::~VxlanRoutingVnState() {
57 138 : }
58 :
59 0 : void VxlanRoutingVnState::AddVmi(const VnEntry *vn, const VmInterface *vmi) {
60 0 : if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
61 0 : LOG(ERROR, "Error in VxlanRoutingManager::AddVmi"
62 : << ", vmi->logical_router_uuid() == boost::uuids::nil_uuid()");
63 0 : assert(vmi->logical_router_uuid() != boost::uuids::nil_uuid());
64 : }
65 0 : VmiListIter it = vmi_list_.find(vmi);
66 0 : if (it != vmi_list_.end()) {
67 0 : return;
68 : }
69 :
70 0 : vmi_list_.insert(vmi);
71 0 : if ((logical_router_uuid_ != vmi->logical_router_uuid()) &&
72 0 : (*(vmi_list_.begin()) == vmi)) {
73 0 : mgr_->BridgeVnNotify(vn, this);
74 : }
75 : }
76 :
77 0 : void VxlanRoutingVnState::DeleteVmi(const VnEntry *vn, const VmInterface *vmi) {
78 0 : VmiListIter it = vmi_list_.find(vmi);
79 0 : if (it == vmi_list_.end()) {
80 0 : return;
81 : }
82 0 : vmi_list_.erase(vmi);
83 0 : mgr_->BridgeVnNotify(vn, this);
84 : }
85 :
86 0 : VxlanRoutingVmiState::VxlanRoutingVmiState() :
87 0 : vn_entry_(NULL), logical_router_uuid_(boost::uuids::nil_uuid()) {
88 0 : }
89 :
90 0 : VxlanRoutingVmiState::~VxlanRoutingVmiState() {
91 0 : }
92 :
93 0 : boost::uuids::uuid VxlanRoutingVnState::logical_router_uuid() const {
94 0 : if (vmi_list_.size() == 0)
95 0 : return boost::uuids::nil_uuid();
96 :
97 0 : return (*(vmi_list_.begin()))->logical_router_uuid();
98 : }
99 :
100 2 : VxlanRoutingRouteWalker::VxlanRoutingRouteWalker(const std::string &name,
101 2 : VxlanRoutingManager *mgr, Agent *agent) :
102 2 : AgentRouteWalker(name, agent), mgr_(mgr) {
103 2 : }
104 :
105 4 : VxlanRoutingRouteWalker::~VxlanRoutingRouteWalker() {
106 4 : }
107 :
108 : // Only take notification of bridge inet routes.
109 : // Change in them will trigger change in rest.
110 0 : bool VxlanRoutingRouteWalker::RouteWalkNotify(DBTablePartBase *partition,
111 : DBEntryBase *e) {
112 : // Now route leaking is triggered by changes in the Inet table of
113 : // a bridge VRF instance
114 : const InetUnicastRouteEntry *inet_rt =
115 0 : dynamic_cast<const InetUnicastRouteEntry*>(e);
116 0 : if (inet_rt) {
117 0 : const VrfEntry *vrf = inet_rt->vrf();
118 0 : if (vrf && vrf->vn() && !mgr_->IsRoutingVrf(vrf)) {
119 0 : mgr_->InetRouteNotify(partition, e);
120 : }
121 : }
122 0 : return true;
123 : }
124 :
125 2 : VxlanRoutingVrfMapper::VxlanRoutingVrfMapper(VxlanRoutingManager *mgr) :
126 2 : mgr_(mgr), lr_vrf_info_map_(), vn_lr_set_(),
127 4 : inet4_table_walker_(), inet6_table_walker_() {
128 2 : }
129 :
130 2 : VxlanRoutingVrfMapper::~VxlanRoutingVrfMapper() {
131 2 : }
132 :
133 183 : void VxlanRoutingVrfMapper::WalkBridgeInetTables(
134 : InetUnicastAgentRouteTable *inet4_table,
135 : InetUnicastAgentRouteTable *inet6_table) {
136 : // Inet 4
137 : {
138 183 : DBTable::DBTableWalkRef walk_ref;
139 183 : InetTableWalker::iterator it = inet4_table_walker_.find(inet4_table);
140 183 : if (it == inet4_table_walker_.end()) {
141 : walk_ref = inet4_table->
142 366 : AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
143 : mgr_, _1, _2),
144 : boost::bind(&VxlanRoutingVrfMapper::BridgeInet4RouteWalkDone,
145 183 : this, _1, _2));
146 183 : inet4_table_walker_[inet4_table] = walk_ref;
147 : } else {
148 0 : walk_ref = it->second;
149 : }
150 183 : inet4_table->WalkAgain(walk_ref);
151 : //Every time walk is issued for bridge table revisit subnet routes
152 183 : mgr_->HandleSubnetRoute(inet4_table->vrf_entry());
153 183 : }
154 : // Inet 6
155 : {
156 183 : DBTable::DBTableWalkRef walk_ref;
157 183 : InetTableWalker::iterator it = inet6_table_walker_.find(inet6_table);
158 183 : if (it == inet6_table_walker_.end()) {
159 : walk_ref = inet6_table->
160 366 : AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
161 : mgr_, _1, _2),
162 : boost::bind(&VxlanRoutingVrfMapper::BridgeInet6RouteWalkDone,
163 183 : this, _1, _2));
164 183 : inet6_table_walker_[inet6_table] = walk_ref;
165 : } else {
166 0 : walk_ref = it->second;
167 : }
168 183 : inet6_table->WalkAgain(walk_ref);
169 : //Every time walk is issued for bridge table revisit subnet routes
170 183 : mgr_->HandleSubnetRoute(inet6_table->vrf_entry());
171 183 : }
172 183 : }
173 :
174 0 : void VxlanRoutingVrfMapper::WalkRoutingVrf(const boost::uuids::uuid &lr_uuid,
175 : const VnEntry *vn, bool update, bool withdraw) {
176 0 : if (lr_uuid == boost::uuids::nil_uuid())
177 0 : return;
178 : VxlanRoutingVrfMapper::RoutedVrfInfo &routing_vrf_info =
179 0 : lr_vrf_info_map_[lr_uuid];
180 0 : const VrfEntry *routing_vrf = routing_vrf_info.routing_vrf_;
181 0 : DBTable::DBTableWalkRef walk_ref;
182 :
183 0 : if (withdraw) {
184 0 : InetUnicastAgentRouteTable *inet4_table = nullptr;
185 0 : InetUnicastAgentRouteTable *inet6_table = nullptr;
186 0 : const VrfEntry *bridge_vrf = VxlanRoutingManager::VnVrf(vn,
187 0 : routing_vrf_info.bridge_vrf_names_list_[vn]);
188 0 : if (bridge_vrf && routing_vrf) {
189 0 : inet4_table = bridge_vrf->GetInet4UnicastRouteTable();
190 0 : inet6_table = bridge_vrf->GetInet6UnicastRouteTable();
191 : }
192 0 : if (inet4_table) {
193 : walk_ref = inet4_table->
194 0 : AllocWalker(boost::bind(
195 : &VxlanRoutingManager::WithdrawEvpnRouteFromRoutingVrf,
196 : mgr_, routing_vrf, _1, _2),
197 : boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
198 0 : this, _1, _2));
199 0 : inet4_table->WalkAgain(walk_ref);
200 : }
201 0 : if (inet6_table) {
202 : walk_ref = inet6_table->
203 0 : AllocWalker(boost::bind(
204 : &VxlanRoutingManager::WithdrawEvpnRouteFromRoutingVrf,
205 : mgr_, routing_vrf, _1, _2),
206 : boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
207 0 : this, _1, _2));
208 0 : inet6_table->WalkAgain(walk_ref);
209 : }
210 : } else {
211 0 : EvpnAgentRouteTable *evpn_table = NULL;
212 0 : if (routing_vrf) {
213 : evpn_table =
214 : static_cast<EvpnAgentRouteTable *>(
215 0 : routing_vrf->GetEvpnRouteTable());
216 : }
217 0 : if (!evpn_table) {
218 0 : return;
219 : }
220 :
221 : walk_ref = evpn_table->
222 0 : AllocWalker(boost::bind(&VxlanRoutingManager::LeakRoutesIntoBridgeTables,
223 : mgr_, _1, _2, lr_uuid, vn, update),
224 : boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
225 0 : this, _1, _2));
226 0 : evpn_table->WalkAgain(walk_ref);
227 : }
228 0 : }
229 :
230 0 : void VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone(DBTable::DBTableWalkRef walk_ref,
231 : DBTableBase *partition) {
232 0 : if (walk_ref.get() != NULL)
233 0 : (static_cast<DBTable *>(partition))->ReleaseWalker(walk_ref);
234 0 : }
235 :
236 183 : void VxlanRoutingVrfMapper::BridgeInet4RouteWalkDone(DBTable::DBTableWalkRef walk_ref,
237 : DBTableBase *partition) {
238 : const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
239 183 : (walk_ref->table());
240 183 : InetTableWalker::iterator it = inet4_table_walker_.find(table);
241 183 : if(it == inet4_table_walker_.end()) {
242 0 : LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet4RouteWalkDone"
243 : << ", it == inet4_table_walker_.end()");
244 0 : assert(it != inet4_table_walker_.end());
245 : }
246 183 : inet4_table_walker_.erase(it);
247 183 : }
248 :
249 183 : void VxlanRoutingVrfMapper::BridgeInet6RouteWalkDone(DBTable::DBTableWalkRef walk_ref,
250 : DBTableBase *partition) {
251 : const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
252 183 : (walk_ref->table());
253 183 : InetTableWalker::iterator it = inet6_table_walker_.find(table);
254 183 : if(it == inet6_table_walker_.end()){
255 0 : LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet6RouteWalkDone"
256 : << ", it == inet6_table_walker_.end()");
257 0 : assert(it != inet6_table_walker_.end());
258 : }
259 :
260 183 : inet6_table_walker_.erase(it);
261 183 : }
262 :
263 0 : void VxlanRoutingVrfMapper::WalkRoutingVrfRemoveExternalRoutes(
264 : const boost::uuids::uuid &lr_uuid, const VnEntry *vn,
265 : std::string bridge_vrf_name) {
266 0 : if (lr_uuid == boost::uuids::nil_uuid())
267 0 : return;
268 : VxlanRoutingVrfMapper::RoutedVrfInfo &routing_vrf_info =
269 0 : lr_vrf_info_map_[lr_uuid];
270 0 : const VrfEntry *routing_vrf = routing_vrf_info.routing_vrf_;
271 0 : DBTable::DBTableWalkRef walk_ref;
272 :
273 0 : EvpnAgentRouteTable *evpn_table = nullptr;
274 0 : if (routing_vrf != nullptr) {
275 : evpn_table =
276 : static_cast<EvpnAgentRouteTable *>(
277 0 : routing_vrf->GetEvpnRouteTable());
278 : }
279 0 : if (evpn_table == nullptr) {
280 0 : return;
281 : }
282 :
283 : walk_ref = evpn_table->
284 0 : AllocWalker(boost::bind(
285 : &VxlanRoutingManager::RemoveRoutesFromRoutingToBridgeVrf,
286 : mgr_, _1, _2, vn, bridge_vrf_name),
287 : boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
288 0 : this, _1, _2));
289 0 : evpn_table->WalkAgain(walk_ref);
290 0 : }
291 :
292 0 : void VxlanRoutingVrfMapper::WalkBridgeVrfs
293 : (const VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info)
294 : {
295 : // Start walk on all l3 tables
296 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it =
297 0 : routed_vrf_info.bridge_vn_list_.begin();
298 0 : while (it != routed_vrf_info.bridge_vn_list_.end()) {
299 0 : const VnEntry *vn = static_cast<const VnEntry *>(*it);
300 0 : const VrfEntry *vrf = VxlanRoutingManager::VnVrf(vn,
301 0 : routed_vrf_info.bridge_vrf_names_list_.at(vn));
302 0 : if (vrf) {
303 : InetUnicastAgentRouteTable *inet4_table =
304 : static_cast<InetUnicastAgentRouteTable *>
305 0 : (vrf->GetInet4UnicastRouteTable());
306 : InetUnicastAgentRouteTable *inet6_table =
307 : static_cast<InetUnicastAgentRouteTable *>
308 0 : (vrf->GetInet6UnicastRouteTable());
309 0 : if (!inet4_table || !inet6_table)
310 0 : continue;
311 0 : WalkBridgeInetTables(inet4_table, inet6_table);
312 : }
313 0 : it++;
314 : }
315 0 : }
316 :
317 248 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingVn
318 : (const VnEntry *vn) {
319 248 : VnLrSetIter it = vn_lr_set_.find(vn);
320 248 : if (it != vn_lr_set_.end()) {
321 0 : return GetRoutingVrfUsingUuid(it->second);
322 : }
323 248 : return NULL;
324 : }
325 :
326 2225 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingAgentRoute
327 : (const AgentRoute *rt) {
328 2225 : return GetRoutingVrfUsingUuid(GetLogicalRouterUuidUsingRoute(rt));
329 : }
330 :
331 2225 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingUuid
332 : (const boost::uuids::uuid &lr_uuid) {
333 2225 : LrVrfInfoMapIter it = lr_vrf_info_map_.find(lr_uuid);
334 2225 : if (it != lr_vrf_info_map_.end()) {
335 0 : return it->second.routing_vrf_;
336 : }
337 2225 : return NULL;
338 : }
339 :
340 2225 : const boost::uuids::uuid VxlanRoutingVrfMapper::GetLogicalRouterUuidUsingRoute
341 : (const AgentRoute *rt) {
342 : using boost::uuids::nil_uuid;
343 :
344 2225 : if (VxlanRoutingManager::IsRoutingVrf(rt->vrf())) {
345 0 : return rt->vrf()->vn()->logical_router_uuid();
346 : }
347 :
348 2225 : const VnEntry* rt_vn = rt->vrf()->vn();
349 2225 : if (!rt_vn) {
350 0 : return nil_uuid();
351 : }
352 :
353 : const VxlanRoutingVnState *vn_state =
354 2225 : dynamic_cast<const VxlanRoutingVnState *>(rt_vn->
355 2225 : GetAgentDBEntryState(mgr_->vn_listener_id()));
356 2225 : if ((vn_state == NULL) || (vn_state->vmi_list_.size() == 0)) {
357 2225 : return nil_uuid();
358 : }
359 :
360 0 : return vn_state->logical_router_uuid_;
361 : }
362 :
363 : // Invoked everytime when a vrf is pulled out of use.
364 : // Holds on object till all bridge and routing vrf are gone.
365 0 : void VxlanRoutingVrfMapper::TryDeleteLogicalRouter(LrVrfInfoMapIter &it) {
366 0 : if ((it->second.routing_vrf_ == NULL) &&
367 0 : (it->second.bridge_vn_list_.size() == 0)) {
368 0 : lr_vrf_info_map_.erase(it);
369 : }
370 0 : }
371 :
372 : const Peer *VxlanRoutingManager::routing_vrf_interface_peer_ = NULL;
373 : const Peer *VxlanRoutingManager::routing_vrf_vxlan_bgp_peer_ = NULL;
374 :
375 : /**
376 : * VxlanRoutingManager
377 : */
378 2 : VxlanRoutingManager::VxlanRoutingManager(Agent *agent) :
379 4 : agent_(agent), walker_(), vn_listener_id_(),
380 2 : vrf_listener_id_(), vmi_listener_id_(), vrf_mapper_(this) {
381 : //routing_vrf_interface_peer_ = agent_->evpn_routing_peer();
382 2 : routing_vrf_interface_peer_ = agent_->local_vm_export_peer();
383 2 : routing_vrf_vxlan_bgp_peer_ = agent_->vxlan_bgp_peer();
384 2 : }
385 :
386 4 : VxlanRoutingManager::~VxlanRoutingManager() {
387 4 : }
388 :
389 2 : void VxlanRoutingManager::Register() {
390 : // Walker to go through routes in bridge evpn tables.
391 4 : walker_.reset(new VxlanRoutingRouteWalker("VxlanRoutingManager", this,
392 2 : agent_));
393 2 : agent_->oper_db()->agent_route_walk_manager()->
394 2 : RegisterWalker(static_cast<AgentRouteWalker *>(walker_.get()));
395 :
396 : // Register all listener ids.
397 2 : vn_listener_id_ = agent_->vn_table()->
398 2 : Register(boost::bind(&VxlanRoutingManager::VnNotify,
399 : this, _1, _2));
400 2 : vrf_listener_id_ = agent_->vrf_table()->Register(
401 : boost::bind(&VxlanRoutingManager::VrfNotify, this, _1, _2));
402 2 : vmi_listener_id_ = agent_->interface_table()->Register(
403 : boost::bind(&VxlanRoutingManager::VmiNotify, this, _1, _2));
404 2 : }
405 :
406 2 : void VxlanRoutingManager::Shutdown() {
407 2 : agent_->vn_table()->Unregister(vn_listener_id_);
408 2 : agent_->vrf_table()->Unregister(vrf_listener_id_);
409 2 : agent_->interface_table()->Unregister(vmi_listener_id_);
410 2 : agent_->oper_db()->agent_route_walk_manager()->
411 2 : ReleaseWalker(walker_.get());
412 2 : walker_.reset(NULL);
413 2 : }
414 :
415 : /**
416 : * VNNotify
417 : * Handles routing vrf i.e. VRF meant for doing evpn routing.
418 : * Addition or deletion of same add/withdraws route imported from bridge vrf in
419 : * routing vrf.
420 : * Walk is issued for the routes of bridge vrf's evpn table.
421 : *
422 : * For bridge VRF, only delete of VN is handled here. Add has no operation as
423 : * add of VN does not give any info on LR/Routing VRF to use.
424 : * When delete is seen withdraw from the list of bridge list.
425 : */
426 269 : void VxlanRoutingManager::VnNotify(DBTablePartBase *partition, DBEntryBase *e) {
427 269 : VnEntry *vn = dynamic_cast<VnEntry *>(e);
428 269 : VxlanRoutingVnState *vn_state = dynamic_cast<VxlanRoutingVnState *>
429 269 : (vn->GetAgentDBEntryState(vn_listener_id_));
430 :
431 269 : if (vn->IsDeleted() && vn_state != NULL) {
432 69 : if (vn_state->is_routing_vn_) {
433 0 : RoutingVnNotify(vn, vn_state);
434 : } else {
435 69 : BridgeVnNotify(vn, vn_state);
436 : }
437 :
438 : //Delete State
439 69 : vn->ClearState(partition->parent(), vn_listener_id_);
440 69 : delete vn_state;
441 69 : return;
442 : }
443 :
444 : // if the VN had been deleted previously
445 200 : if (!vn_state && vn->IsDeleted()) {
446 0 : return;
447 : }
448 :
449 200 : if (!vn_state) {
450 69 : vn_state = new VxlanRoutingVnState(this);
451 69 : vn->SetState(partition->parent(), vn_listener_id_, vn_state);
452 : }
453 :
454 200 : if (vn->vxlan_routing_vn()) {
455 0 : vn_state->is_routing_vn_ = vn->vxlan_routing_vn();
456 : }
457 :
458 200 : vn_state->vrf_ref_ = vn->GetVrf();
459 200 : if (vn_state->is_routing_vn_) {
460 0 : vn_state->logical_router_uuid_ = vn->logical_router_uuid();
461 0 : RoutingVnNotify(vn, vn_state);
462 : } else {
463 200 : BridgeVnNotify(vn, vn_state);
464 : }
465 :
466 200 : return;
467 : }
468 :
469 269 : void UpdateLogicalRouterUuid(const VnEntry *vn,
470 : VxlanRoutingVnState *vn_state) {
471 : using boost::uuids::nil_uuid;
472 :
473 269 : if (vn_state->vmi_list_.size() == 0) {
474 269 : vn_state->logical_router_uuid_ = nil_uuid();
475 : }
476 :
477 269 : VxlanRoutingVnState::VmiListIter it = vn_state->vmi_list_.begin();
478 269 : while (it != vn_state->vmi_list_.end()) {
479 0 : vn_state->logical_router_uuid_ = (*it)->logical_router_uuid();
480 0 : if ((*it)->logical_router_uuid() != nil_uuid()) {
481 0 : return;
482 : }
483 : //Delete VMI with no lr uuid, vmi update will handle rest.
484 0 : vn_state->vmi_list_.erase(it);
485 0 : if (vn_state->vmi_list_.size() == 0) {
486 0 : vn_state->logical_router_uuid_ = nil_uuid();
487 0 : return;
488 : }
489 0 : it = vn_state->vmi_list_.begin();
490 : }
491 269 : return;
492 : }
493 :
494 269 : void VxlanRoutingManager::BridgeVnNotify(const VnEntry *vn,
495 : VxlanRoutingVnState *vn_state) {
496 : using boost::uuids::nil_uuid;
497 :
498 269 : if (vn->logical_router_uuid() != nil_uuid()) {
499 0 : return;
500 : }
501 :
502 269 : VxlanRoutingVrfMapper::VnLrSetIter it = vrf_mapper_.vn_lr_set_.find(vn);
503 : VxlanRoutingVrfMapper::LrVrfInfoMapIter routing_info_it =
504 269 : vrf_mapper_.lr_vrf_info_map_.end();
505 269 : VrfEntry *vn_vrf = vn->GetVrf();
506 269 : bool withdraw = false;
507 269 : bool update = true;
508 :
509 : // Update lr uuid in case some vmi is deleted or added.
510 269 : UpdateLogicalRouterUuid(vn, vn_state);
511 269 : if (vn->IsDeleted() || (vn_vrf == nullptr)) {
512 145 : withdraw = true;
513 145 : update = false;
514 : }
515 :
516 269 : if (it != vrf_mapper_.vn_lr_set_.end() &&
517 269 : (it->second != vn_state->logical_router_uuid_) &&
518 269 : (vn_state->logical_router_uuid_ != nil_uuid())) {
519 0 : withdraw = true;
520 : }
521 :
522 269 : if (vn_state->logical_router_uuid_ == nil_uuid()) {
523 269 : withdraw = true;
524 269 : update = false;
525 : }
526 :
527 269 : if (it != vrf_mapper_.vn_lr_set_.end()) {
528 0 : routing_info_it = vrf_mapper_.lr_vrf_info_map_.find(it->second);
529 : }
530 :
531 : // Handles deletion case
532 269 : if (withdraw) {
533 269 : if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
534 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter br_it =
535 0 : routing_info_it->second.bridge_vn_list_.find(vn);
536 0 : std::string vrf_name = "";
537 0 : if (routing_info_it->second.bridge_vrf_names_list_.count(vn) == 1) {
538 0 : vrf_name = routing_info_it->second.bridge_vrf_names_list_.at(vn);
539 0 : DeleteSubnetRoute(vn, vrf_name);
540 : }
541 0 : if (br_it != routing_info_it->second.bridge_vn_list_.end()) {
542 0 : vrf_mapper_.WalkRoutingVrf(it->second, vn, false, true);
543 0 : routing_info_it->second.bridge_vn_list_.erase(br_it);
544 0 : routing_info_it->second.bridge_vrf_names_list_.erase(vn);
545 0 : vrf_mapper_.WalkRoutingVrfRemoveExternalRoutes(it->second, vn,
546 : vrf_name);
547 : }
548 : // Trigger delete of logical router
549 0 : vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
550 0 : }
551 269 : vrf_mapper_.vn_lr_set_.erase(vn);
552 : }
553 :
554 269 : if (update) {
555 0 : vrf_mapper_.vn_lr_set_[vn] = vn_state->logical_router_uuid_;
556 0 : if (vrf_mapper_.vn_lr_set_[vn] == nil_uuid()) {
557 0 : return;
558 : }
559 :
560 : VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
561 0 : vrf_mapper_.lr_vrf_info_map_[vn_state->logical_router_uuid_];
562 0 : lr_vrf_info.bridge_vn_list_.insert(vn);
563 0 : if (vn->GetVrf())
564 0 : lr_vrf_info.bridge_vrf_names_list_[vn] = vn->GetVrf()->GetName();
565 : else {
566 0 : lr_vrf_info.bridge_vrf_names_list_[vn] = std::string{""};
567 : }
568 0 : vrf_mapper_.WalkRoutingVrf(vrf_mapper_.vn_lr_set_[vn], vn, true, false);
569 : }
570 :
571 : // Without vrf walks cant be scheduled
572 269 : if (!vn_state->vrf_ref_.get()) {
573 86 : return;
574 : }
575 :
576 : // Walk Evpn table if withdraw or update was done
577 183 : if (update || withdraw) {
578 : InetUnicastAgentRouteTable *inet4_table =
579 : static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
580 183 : GetInet4UnicastRouteTable());
581 : InetUnicastAgentRouteTable *inet6_table =
582 : static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
583 183 : GetInet6UnicastRouteTable());
584 183 : if (inet4_table && inet6_table) {
585 183 : vrf_mapper_.WalkBridgeInetTables(inet4_table, inet6_table);
586 : }
587 : }
588 183 : return;
589 : }
590 :
591 0 : void VxlanRoutingManager::RoutingVrfDeleteAllRoutes(VrfEntry* rt_vrf) {
592 0 : if (rt_vrf == nullptr) {
593 0 : return;
594 : }
595 : // Loop over all EVPN routes and delete them
596 :
597 0 : EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
598 0 : (rt_vrf->GetEvpnRouteTable());
599 0 : if (evpn_table == nullptr) {
600 0 : return;
601 : }
602 0 : EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
603 0 : (evpn_table->GetTablePartition(0)->GetFirst());
604 :
605 0 : const std::string vrf_name = rt_vrf->GetName();
606 0 : const uint32_t ethernet_tag = 0;
607 0 : const MacAddress mac_addr;
608 0 : while (c_entry != nullptr) {
609 0 : const IpAddress &prefix_ip = c_entry->prefix_address();
610 0 : const uint8_t plen = c_entry->prefix_length();
611 0 : const AgentPath *rt_active_path = c_entry->GetActivePath();
612 0 : const Peer *rt_active_peer = nullptr;
613 0 : const auto &path_list = c_entry->GetPathList();
614 0 : if (rt_active_path != nullptr)
615 0 : rt_active_peer = rt_active_path->peer();
616 :
617 : // Compute next entry in advance
618 0 : if (c_entry != nullptr && c_entry->get_table_partition()) {
619 0 : c_entry = dynamic_cast<EvpnRouteEntry *>
620 0 : (c_entry->get_table_partition()->GetNext(c_entry));
621 : } else {
622 0 : break;
623 : }
624 :
625 0 : InetUnicastAgentRouteTable::DeleteReq(routing_vrf_interface_peer_,
626 : vrf_name, prefix_ip, plen,
627 : nullptr);
628 0 : InetUnicastAgentRouteTable::DeleteReq(routing_vrf_vxlan_bgp_peer_,
629 : vrf_name, prefix_ip, plen,
630 : nullptr);
631 :
632 0 : if ((rt_active_peer != nullptr) &&
633 0 : (rt_active_peer->GetType() != Peer::BGP_PEER)) {
634 : // Delete routes originated from bridge networks
635 0 : EvpnAgentRouteTable::DeleteReq(rt_active_peer,
636 : vrf_name,
637 : mac_addr,
638 : prefix_ip,
639 : plen,
640 : ethernet_tag, // ethernet_tag = 0 for Type5
641 : nullptr);
642 : } else {
643 0 : for (auto &path_ref : path_list) {
644 0 : EvpnAgentRouteTable::DeleteReq(
645 : static_cast<const AgentPath*>
646 : (&path_ref)->peer(),
647 : vrf_name,
648 : mac_addr,
649 : prefix_ip,
650 : plen,
651 : ethernet_tag, // ethernet_tag = 0 for Type5
652 : nullptr);
653 : }
654 : }
655 : }
656 0 : }
657 :
658 0 : void VxlanRoutingManager::RoutingVnNotify(const VnEntry *vn,
659 : VxlanRoutingVnState *vn_state) {
660 :
661 0 : bool withdraw = false;
662 0 : bool update = false;
663 0 : VxlanRoutingVrfMapper::VnLrSetIter it = vrf_mapper_.vn_lr_set_.find(vn);
664 :
665 0 : if (vn->IsDeleted() ||
666 0 : (vn->GetVrf() == NULL) ||
667 0 : (vn_state->is_routing_vn_ == false)) {
668 0 : update = false;
669 0 : withdraw = true;
670 : } else {
671 0 : update = true;
672 0 : if (it != vrf_mapper_.vn_lr_set_.end()) {
673 : // LR uuid changed, so withdraw from old and add new.
674 0 : if (it->second != vn_state->logical_router_uuid_) {
675 0 : withdraw = true;
676 : }
677 : }
678 : }
679 :
680 0 : if (withdraw && (it != vrf_mapper_.vn_lr_set_.end())) {
681 : VxlanRoutingVrfMapper::LrVrfInfoMapIter routing_info_it =
682 0 : vrf_mapper_.lr_vrf_info_map_.find(it->second);
683 : // Delete only if parent VN is same as notified VN coz it may so happen
684 : // that some other VN has taken the ownership of this LR and
685 : // notification of same came before this VN.
686 0 : if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
687 0 : if (routing_info_it->second.routing_vn_ == vn) {
688 0 : RoutingVrfDeleteAllRoutes(
689 0 : routing_info_it->second.routing_vrf_);
690 : // Routing VN/VRF
691 : // Reset parent vn and routing vrf
692 0 : routing_info_it->second.routing_vn_ = nullptr;
693 0 : routing_info_it->second.routing_vrf_ = nullptr;
694 : }
695 : // Trigger delete of logical router
696 0 : vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
697 : }
698 0 : vrf_mapper_.vn_lr_set_.erase(it);
699 : }
700 :
701 0 : if (update) {
702 0 : if (vn_state->logical_router_uuid_ == boost::uuids::nil_uuid()) {
703 0 : return;
704 : }
705 :
706 0 : if (it == vrf_mapper_.vn_lr_set_.end()) {
707 0 : vrf_mapper_.vn_lr_set_[vn] = vn_state->logical_router_uuid_;
708 : }
709 :
710 : VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info =
711 0 : vrf_mapper_.lr_vrf_info_map_[vn_state->logical_router_uuid_];
712 : // Take the ownership of LR
713 0 : routed_vrf_info.routing_vn_ = vn;
714 0 : if (routed_vrf_info.routing_vrf_ != vn->GetVrf()) {
715 0 : routed_vrf_info.routing_vrf_ = vn->GetVrf();
716 0 : vrf_mapper_.WalkBridgeVrfs(routed_vrf_info);
717 : }
718 : }
719 : }
720 :
721 : /**
722 : * Updates (sets or deletes) VxlanRoutingState for the given
723 : * modified VrfEntry
724 : */
725 683 : void VxlanRoutingManager::VrfNotify(DBTablePartBase *partition,
726 : DBEntryBase *e) {
727 683 : VrfEntry *vrf = static_cast<VrfEntry *>(e);
728 683 : if (vrf->GetName().compare(agent_->fabric_vrf_name()) == 0)
729 18 : return;
730 665 : if (vrf->GetName().compare(agent_->fabric_policy_vrf_name()) == 0)
731 18 : return;
732 :
733 647 : VxlanRoutingState *state = dynamic_cast<VxlanRoutingState *>(vrf->
734 647 : GetState(partition->parent(), vrf_listener_id_));
735 647 : if (vrf->IsDeleted()) {
736 509 : if (state) {
737 70 : vrf->ClearState(partition->parent(), vrf_listener_id_);
738 70 : delete state;
739 : }
740 : } else {
741 : // Vrf was added/changed.
742 138 : if (!state) {
743 70 : state = new VxlanRoutingState(this, vrf);
744 70 : vrf->SetState(partition->parent(), vrf_listener_id_, state);
745 : }
746 138 : if (vrf->vn() && vrf->vn()->vxlan_routing_vn()) {
747 0 : vrf->set_routing_vrf(true);
748 : }
749 : }
750 : }
751 :
752 1421 : void VxlanRoutingManager::VmiNotify(DBTablePartBase *partition,
753 : DBEntryBase *e) {
754 1421 : VmInterface *vmi = dynamic_cast<VmInterface *>(e);
755 1421 : if (!vmi) {
756 21 : return;
757 : }
758 :
759 1400 : VnEntry *vn = vmi->GetNonConstVn();
760 1400 : VxlanRoutingVnState *vn_state = NULL;
761 1400 : VxlanRoutingVmiState *vmi_state = dynamic_cast<VxlanRoutingVmiState *>(vmi->
762 1400 : GetAgentDBEntryState(vmi_listener_id_));
763 2384 : if (vmi->IsDeleted() || (vn == NULL) ||
764 2384 : (vmi->logical_router_uuid() == boost::uuids::nil_uuid())) {
765 1400 : if (!vmi_state) {
766 1400 : return;
767 : }
768 0 : vn = vmi_state->vn_entry_.get();
769 0 : vn_state = dynamic_cast<VxlanRoutingVnState *>
770 0 : (vn->GetAgentDBEntryState(vn_listener_id_));
771 0 : if (vn_state)
772 0 : vn_state->DeleteVmi(vn, vmi);
773 0 : vmi->ClearState(partition->parent(), vmi_listener_id_);
774 0 : delete vmi_state;
775 0 : return;
776 : }
777 :
778 0 : if ((vmi->device_type() != VmInterface::VMI_ON_LR) ||
779 0 : (vmi->vmi_type() != VmInterface::ROUTER)) {
780 0 : return;
781 : }
782 :
783 0 : if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
784 0 : return;
785 : }
786 :
787 : // Without VN no point of update
788 0 : if (!vn) {
789 0 : return;
790 : }
791 :
792 0 : if (!vmi_state) {
793 0 : vmi_state = new VxlanRoutingVmiState();
794 0 : vmi->SetState(partition->parent(), vmi_listener_id_, vmi_state);
795 0 : vmi_state->vn_entry_ = vn;
796 : }
797 : // Update logical_router_uuid
798 0 : vmi_state->logical_router_uuid_ = vmi->logical_router_uuid();
799 :
800 : // Its necessary to add state on VN so as to push VMI. VN notify can come
801 : // after VMI notify.
802 0 : VnNotify(vn->get_table_partition(), vn);
803 : // Now get VN state and add/delete VMI there
804 0 : vn_state = dynamic_cast<VxlanRoutingVnState *>
805 0 : (vn->GetAgentDBEntryState(vn_listener_id_));
806 0 : if (vn_state) {
807 0 : vn_state->AddVmi(vn, vmi);
808 : }
809 : }
810 :
811 366 : void VxlanRoutingManager::HandleSubnetRoute(const VrfEntry *vrf, bool bridge_vrf) {
812 : //
813 : // New version
814 : //
815 366 : if (vrf->vn() && vrf->vn()->vxlan_routing_vn() == false) {
816 : const VrfEntry *routing_vrf =
817 248 : vrf_mapper_.GetRoutingVrfUsingVn(vrf->vn());
818 248 : if (!routing_vrf || vrf->IsDeleted()) {
819 248 : DeleteSubnetRoute(vrf);
820 248 : vrf->vn()->set_lr_vrf(NULL);
821 : } else {
822 0 : UpdateSubnetRoute(vrf, routing_vrf);
823 0 : vrf->vn()->set_lr_vrf(routing_vrf);
824 : }
825 : }
826 366 : }
827 :
828 0 : void VxlanRoutingManager::DeleteIpamRoutes(const VnEntry *vn,
829 : const std::string& vrf_name,
830 : const IpAddress& ipam_prefix,
831 : const uint32_t plen) {
832 0 : if (vn == NULL || vrf_name == std::string(""))
833 0 : return;
834 :
835 0 : VxlanRoutingVrfMapper::VnLrSetIter lr_it = vrf_mapper_.vn_lr_set_.find(vn);
836 :
837 0 : if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
838 0 : lr_it->second == boost::uuids::nil_uuid())
839 0 : return;
840 :
841 : VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
842 0 : vrf_mapper_.lr_vrf_info_map_[lr_it->second];
843 :
844 0 : if (lr_vrf_info.bridge_vn_list_.size() == 0)
845 0 : return;
846 :
847 0 : for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
848 0 : if (vn == bridge_vn_entry) {
849 0 : continue;
850 : }
851 :
852 0 : VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
853 0 : if (it_vrf == nullptr) {
854 0 : continue;
855 : }
856 :
857 : it_vrf->GetInetUnicastRouteTable(ipam_prefix)->
858 0 : Delete(agent_->evpn_routing_peer(), it_vrf->GetName(),
859 : ipam_prefix, plen, NULL);
860 : }
861 : }
862 :
863 248 : void VxlanRoutingManager::DeleteSubnetRoute(const VnEntry *vn, const std::string& vrf_name) {
864 248 : if (vn == NULL || vrf_name == std::string(""))
865 248 : return;
866 248 : std::vector<VnIpam> bridge_vn_ipam = vn->GetVnIpam();
867 :
868 248 : if (bridge_vn_ipam.size() == 0)
869 118 : return;
870 :
871 130 : VxlanRoutingVrfMapper::VnLrSetIter lr_it = vrf_mapper_.vn_lr_set_.find(vn);
872 :
873 130 : if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
874 130 : lr_it->second == boost::uuids::nil_uuid())
875 130 : return;
876 :
877 : VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
878 0 : vrf_mapper_.lr_vrf_info_map_[lr_it->second];
879 :
880 0 : if (lr_vrf_info.bridge_vn_list_.size() == 0)
881 0 : return;
882 :
883 0 : for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
884 0 : if (vn == bridge_vn_entry) {
885 0 : continue;
886 : }
887 :
888 0 : for (auto br_ipam : bridge_vn_ipam) {
889 0 : VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
890 0 : if (it_vrf == nullptr) {
891 0 : continue;
892 : }
893 :
894 0 : it_vrf->GetInetUnicastRouteTable(br_ipam.ip_prefix)->
895 0 : DeleteReq(agent_->evpn_routing_peer(), it_vrf->GetName(),
896 0 : br_ipam.GetSubnetAddress(), br_ipam.plen, NULL);
897 0 : }
898 :
899 0 : std::vector<VnIpam> vn_ipam = bridge_vn_entry->GetVnIpam();
900 :
901 0 : if (vn_ipam.size() == 0) {
902 0 : continue;
903 : }
904 0 : for (auto br_vn_ipam : vn_ipam) {
905 0 : InetUnicastAgentRouteTable::DeleteReq(agent_->evpn_routing_peer(),
906 0 : vrf_name, br_vn_ipam.GetSubnetAddress(),
907 0 : br_vn_ipam.plen, NULL);
908 0 : }
909 0 : }
910 248 : }
911 :
912 : //void VxlanRoutingManager::DeleteSubnetRoute(const VrfEntry *vrf, VnIpam *ipam) {
913 248 : void VxlanRoutingManager::DeleteSubnetRoute(const VrfEntry *vrf) {
914 248 : if (vrf == NULL)
915 0 : return;
916 248 : DeleteSubnetRoute(vrf->vn(), vrf->GetName());
917 : }
918 :
919 0 : void VxlanRoutingManager::UpdateSubnetRoute(const VrfEntry *bridge_vrf,
920 : const VrfEntry *routing_vrf) {
921 0 : if (!bridge_vrf->vn())
922 0 : return;
923 :
924 0 : std::vector<VnIpam> bridge_vn_ipam = bridge_vrf->vn()->GetVnIpam();
925 :
926 0 : if (bridge_vn_ipam.size() == 0)
927 0 : return;
928 :
929 : VxlanRoutingVrfMapper::VnLrSetIter lr_it =
930 0 : vrf_mapper_.vn_lr_set_.find(bridge_vrf->vn());
931 :
932 0 : if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
933 0 : lr_it->second == boost::uuids::nil_uuid())
934 0 : return;
935 :
936 : VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
937 0 : vrf_mapper_.lr_vrf_info_map_[lr_it->second];
938 :
939 0 : if (lr_vrf_info.bridge_vn_list_.size() == 0)
940 0 : return;
941 :
942 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it =
943 0 : lr_vrf_info.bridge_vn_list_.begin();
944 0 : while (it != lr_vrf_info.bridge_vn_list_.end()) {
945 0 : if (bridge_vrf->vn() == *it) {
946 0 : it++;
947 0 : continue;
948 : }
949 :
950 0 : for (std::vector<VnIpam>::iterator ipam_itr = bridge_vn_ipam.begin();
951 0 : ipam_itr < bridge_vn_ipam.end(); ipam_itr++) {
952 0 : DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
953 0 : nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
954 0 : nh_req.data.reset(new VrfNHData(false, false, false));
955 0 : VrfEntry* it_vrf = VnVrf((*it), lr_vrf_info.bridge_vrf_names_list_[(*it)]);
956 0 : if (it_vrf == nullptr) {
957 0 : continue;
958 : }
959 0 : it_vrf->GetInetUnicastRouteTable(ipam_itr->ip_prefix)->
960 0 : AddEvpnRoutingRouteReq(ipam_itr->ip_prefix, ipam_itr->plen, routing_vrf,
961 0 : agent_->evpn_routing_peer(),
962 0 : SecurityGroupList(),
963 0 : CommunityList(),
964 0 : PathPreference(),
965 0 : EcmpLoadBalance(),
966 0 : TagList(),
967 : nh_req,
968 : routing_vrf->vxlan_id(),
969 0 : VnListType());
970 0 : }
971 :
972 0 : std::vector<VnIpam> vn_ipam = (*it)->GetVnIpam();
973 0 : for (std::vector<VnIpam>::iterator vn_ipam_itr = vn_ipam.begin();
974 0 : vn_ipam_itr != vn_ipam.end(); vn_ipam_itr++) {
975 :
976 0 : DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
977 0 : nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
978 0 : nh_req.data.reset(new VrfNHData(false, false, false));
979 0 : bridge_vrf->GetInetUnicastRouteTable(vn_ipam_itr->ip_prefix)->
980 0 : AddEvpnRoutingRouteReq(vn_ipam_itr->ip_prefix, vn_ipam_itr->plen, routing_vrf,
981 0 : agent_->evpn_routing_peer(),
982 0 : SecurityGroupList(),
983 0 : CommunityList(),
984 0 : PathPreference(),
985 0 : EcmpLoadBalance(),
986 0 : TagList(),
987 : nh_req,
988 : routing_vrf->vxlan_id(),
989 0 : VnListType());
990 0 : }
991 0 : it++;
992 0 : }
993 0 : }
994 :
995 : /**
996 : * sandesh request
997 : */
998 0 : void VxlanRoutingManager::FillSandeshInfo(VxlanRoutingResp *resp) {
999 : VxlanRoutingVrfMapper::LrVrfInfoMapIter it1 =
1000 0 : vrf_mapper_.lr_vrf_info_map_.begin();
1001 0 : std::vector<VxlanRoutingMap> vr_map;
1002 0 : while (it1 != vrf_mapper_.lr_vrf_info_map_.end()) {
1003 0 : VxlanRoutingMap vxlan_routing_map;
1004 0 : vxlan_routing_map.set_logical_router_uuid(UuidToString(it1->first));
1005 0 : vxlan_routing_map.set_routing_vrf(it1->second.routing_vrf_->
1006 : GetName());
1007 0 : vxlan_routing_map.set_parent_routing_vn(it1->second.routing_vn_->
1008 : GetName());
1009 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it2 =
1010 0 : it1->second.bridge_vn_list_.begin();
1011 0 : while (it2 != it1->second.bridge_vn_list_.end()) {
1012 0 : VxlanRoutingBridgeVrf bridge_vrf;
1013 0 : if ((*it2)->GetVrf()) {
1014 0 : bridge_vrf.set_bridge_vrf((*it2)->GetVrf()->GetName());
1015 : }
1016 0 : bridge_vrf.set_bridge_vn((*it2)->GetName());
1017 0 : vxlan_routing_map.bridge_vrfs.push_back(bridge_vrf);
1018 0 : it2++;
1019 0 : }
1020 0 : vr_map.push_back(vxlan_routing_map);
1021 0 : it1++;
1022 0 : }
1023 0 : resp->set_vr_map(vr_map);
1024 0 : }
1025 :
1026 0 : void VxlanRoutingReq::HandleRequest() const {
1027 0 : VxlanRoutingResp *resp = new VxlanRoutingResp();
1028 0 : Agent *agent = Agent::GetInstance();
1029 : VxlanRoutingManager *vxlan_routing_mgr =
1030 0 : agent->oper_db()->vxlan_routing_manager();
1031 0 : if (vxlan_routing_mgr) {
1032 0 : resp->set_context(context());
1033 0 : vxlan_routing_mgr->FillSandeshInfo(resp);
1034 : }
1035 0 : resp->set_more(false);
1036 0 : resp->Response();
1037 0 : return;
1038 : }
|