Line data Source code
1 : /*
2 : * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3 : * Copyright (c) 2022 - 2026 Matvey Kraposhin.
4 : * Copyright (c) 2024 - 2026 Elena Zizganova.
5 : */
6 :
7 : #include <oper/route_common.h>
8 : #include <controller/controller_init.h>
9 : #include <controller/controller_route_path.h>
10 : #include <xmpp_enet_types.h>
11 : #include <xmpp_unicast_types.h>
12 : #include <oper/tunnel_nh.h>
13 : #include <oper/vxlan_routing_manager.h>
14 : #include <oper/bgp_as_service.h>
15 :
16 :
17 : static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
18 : const uint32_t plen,
19 : DBRequest &nh_req,
20 : const Peer *peer,
21 : const RouteParameters& params,
22 : EvpnAgentRouteTable *evpn_table);
23 :
24 0 : static bool IsGivenTypeCompositeNextHop(const NextHop *nh,
25 : NextHop::Type nh_type, bool strict_match = true) {
26 0 : if (nh->GetType() != NextHop::COMPOSITE) {
27 0 : return false;
28 : }
29 : const CompositeNH *composite_nh =
30 0 : dynamic_cast<const CompositeNH*>(nh);
31 0 : uint32_t comp_nh_count = composite_nh->ComponentNHCount();
32 0 : for (uint32_t i=0; i < comp_nh_count; i++) {
33 0 : const NextHop * c_nh = composite_nh->GetNH(i);
34 0 : if (c_nh != NULL) {
35 : // return true if at least one componet is interface
36 0 : if (c_nh->GetType() == nh_type &&
37 0 : !strict_match) {
38 0 : return true;
39 : }
40 : // return true only if all components are interfaces
41 0 : if (c_nh->GetType() != nh_type &&
42 : strict_match) {
43 0 : return false;
44 : }
45 : }
46 : }
47 0 : return strict_match;
48 : }
49 :
50 : //
51 : // VxlanRoutingManager members
52 : //
53 :
54 0 : uint32_t VxlanRoutingManager::GetNewLocalSequence(const AgentPath* path) {
55 0 : const NextHop *path_nh = path->nexthop();
56 0 : if (path_nh->GetType() != NextHop::COMPOSITE) {
57 0 : return 0;
58 : }
59 0 : loc_sequence_++;
60 0 : return loc_sequence_;
61 : }
62 :
63 0 : bool VxlanRoutingManager::is_ipv4_string(const std::string& prefix_str) {
64 0 : return (prefix_str.find(".") != std::string::npos);
65 : }
66 :
67 0 : bool VxlanRoutingManager::is_ipv6_string(const std::string& prefix_str) {
68 0 : return (prefix_str.find(":") != std::string::npos) &&
69 0 : !is_ipv4_string(prefix_str);
70 : }
71 :
72 0 : uint32_t VxlanRoutingManager::ipv4_prefix_len(const std::string& prefix_str) {
73 0 : const std::string::size_type slash_pos = prefix_str.rfind("/");
74 0 : if (slash_pos == std::string::npos) {
75 0 : return 32;
76 : }
77 0 : const std::string len_str = prefix_str.substr(slash_pos + 1);
78 0 : uint32_t prefix_len = 0;
79 0 : std::istringstream(len_str) >> prefix_len;
80 0 : return std::min(uint32_t(32), prefix_len);
81 0 : }
82 :
83 0 : std::string VxlanRoutingManager::ipv4_prefix(const std::string& prefix_str) {
84 0 : std::string::size_type first_dot_pos = 0;
85 : std::string::size_type last_colon_pos =
86 0 : prefix_str.rfind(":");
87 0 : std::string::size_type slash_pos = prefix_str.rfind("/");
88 0 : std::string ip_str = "0.0.0.0";
89 0 : if ((first_dot_pos = prefix_str.find(".")) != std::string::npos) {
90 0 : if (first_dot_pos - last_colon_pos >= 2 &&
91 0 : first_dot_pos - last_colon_pos <= 4) {
92 0 : ip_str = prefix_str.substr(last_colon_pos + 1);
93 : }
94 0 : if (last_colon_pos == string::npos) {
95 0 : ip_str = prefix_str;
96 : }
97 0 : if (slash_pos != string::npos) {
98 0 : ip_str = ip_str.substr(0, slash_pos);
99 : }
100 : }
101 0 : return ip_str;
102 0 : }
103 :
104 0 : uint32_t VxlanRoutingManager::ipv6_prefix_len(const std::string& prefix_str) {
105 0 : const std::string::size_type slash_pos = prefix_str.rfind("/");
106 0 : if (slash_pos == std::string::npos) {
107 0 : return 128;
108 : }
109 0 : const std::string len_str = prefix_str.substr(slash_pos + 1);
110 0 : uint32_t prefix_len = 0;
111 0 : std::istringstream(len_str) >> prefix_len;
112 0 : return std::min(uint32_t(128), prefix_len);
113 0 : }
114 :
115 0 : std::string VxlanRoutingManager::ipv6_prefix(const std::string& prefix_str) {
116 0 : const std::string zero_mac_str = "00:00:00:00:00:00";
117 0 : const std::string::size_type mac_pos = prefix_str.find(zero_mac_str);
118 0 : std::string ip_str = prefix_str;
119 :
120 0 : if (mac_pos != std::string::npos) {
121 0 : ip_str = prefix_str.substr(mac_pos + zero_mac_str.size() + 1);
122 : }
123 :
124 0 : const std::string::size_type slash_pos = ip_str.rfind("/");
125 0 : if (slash_pos != std::string::npos) {
126 0 : ip_str = ip_str.substr(0, slash_pos);
127 : }
128 0 : if (ip_str.find(":") == std::string::npos) {
129 0 : ip_str = "::";
130 : }
131 0 : return ip_str;
132 0 : }
133 :
134 0 : bool VxlanRoutingManager::IsVxlanAvailable(const Agent* agent) {
135 0 : VxlanRoutingManager *vxlan_rt_mgr = NULL;
136 0 : if (agent->oper_db()) {
137 0 : vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
138 : }
139 0 : if (vxlan_rt_mgr == NULL) {
140 0 : return false;
141 : }
142 0 : return true;
143 : }
144 :
145 0 : std::string VxlanRoutingManager::GetOriginVn(const VrfEntry *routing_vrf,
146 : const IpAddress& ip_addr,
147 : const uint8_t& plen) {
148 :
149 0 : std::string origin_vn = "";
150 0 : if (routing_vrf->vn()) {
151 : VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
152 : vrf_mapper_.lr_vrf_info_map_
153 0 : [routing_vrf->vn()->logical_router_uuid()];
154 0 : for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
155 0 : VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
156 0 : if (it_vrf == nullptr) {
157 0 : continue;
158 : }
159 0 : InetUnicastRouteEntry *rt = it_vrf->GetUcRoute(ip_addr);
160 0 : if (rt && RoutePrefixIsEqualTo(rt, ip_addr, plen)) {
161 0 : origin_vn = bridge_vn_entry->GetName();
162 0 : break;
163 : }
164 : }
165 : }
166 :
167 0 : return origin_vn;
168 0 : }
169 :
170 0 : bool VxlanRoutingManager::RoutePrefixIsEqualTo(const EvpnRouteEntry* route,
171 : const IpAddress& prefix_ip,
172 : const uint32_t prefix_len) {
173 0 : if (route == NULL ||
174 0 : route->prefix_address() != prefix_ip ||
175 0 : route->prefix_length() != prefix_len) {
176 0 : return false;
177 : }
178 0 : return true;
179 : }
180 :
181 0 : bool VxlanRoutingManager::RoutePrefixIsEqualTo(const InetUnicastRouteEntry* route,
182 : const IpAddress& prefix_ip,
183 : const uint32_t prefix_len) {
184 0 : if (route == NULL ||
185 0 : route->prefix_address() != prefix_ip ||
186 0 : route->prefix_length() != prefix_len) {
187 0 : return false;
188 : }
189 0 : return true;
190 : }
191 :
192 0 : bool VxlanRoutingManager::IsHostRoute(const IpAddress& prefix_ip, uint32_t prefix_len) {
193 0 : if (prefix_ip.is_v4() && prefix_len == 32)
194 0 : return true;
195 0 : if (prefix_ip.is_v6() && prefix_len == 128)
196 0 : return true;
197 0 : return false;
198 : }
199 :
200 0 : bool VxlanRoutingManager::IsHostRoute(const EvpnRouteEntry *evpn_rt) {
201 0 : if (evpn_rt != NULL) {
202 0 : return IsHostRoute(evpn_rt->prefix_address(), evpn_rt->prefix_length());
203 : }
204 0 : return false;
205 : }
206 :
207 0 : bool VxlanRoutingManager::IsHostRouteFromLocalSubnet(const EvpnRouteEntry *rt) {
208 0 : if(rt->vrf() == NULL || rt->vrf()->vn() == NULL){
209 0 : LOG(ERROR, "Error in VxlanRoutingManager::IsHostRouteFromLocalSubnet"
210 : << ", vrf == NULL || vrf()->vn() == NULL");
211 0 : assert(rt->vrf() && rt->vrf()->vn());
212 : }
213 :
214 0 : if (IsHostRoute(rt) == false) {
215 0 : return false;
216 : }
217 :
218 : const boost::uuids::uuid lr_uuid =
219 0 : vrf_mapper_.GetLogicalRouterUuidUsingRoute(rt);
220 0 : if (lr_uuid == boost::uuids::nil_uuid()) {
221 0 : return false;
222 : }
223 :
224 : const VxlanRoutingVrfMapper::RoutedVrfInfo& vr_info =
225 0 : vrf_mapper_.lr_vrf_info_map_[lr_uuid];
226 0 : const VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList& bridge_vns =
227 : vr_info.bridge_vn_list_;
228 :
229 0 : const VnEntry *bridge_vn = NULL;
230 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it_br =
231 0 : bridge_vns.begin();
232 0 : while (it_br != bridge_vns.end()) {
233 0 : bridge_vn = *it_br;
234 0 : const std::vector<VnIpam> &VnIpams = bridge_vn->GetVnIpam();
235 0 : for (uint32_t j=0; j < VnIpams.size(); j++) {
236 0 : if (VnIpams[j].IsSubnetMember(rt->prefix_address())) {
237 0 : return true;
238 : }
239 : }
240 0 : it_br++;
241 : }
242 0 : return false;
243 : }
244 :
245 0 : bool VxlanRoutingManager::IsVrfLocalRoute(EvpnRouteEntry *routing_evpn_rt,
246 : VrfEntry *bridge_vrf) {
247 : // check that the Inet table holds the corresponding route
248 : InetUnicastRouteEntry local_vm_route_key(
249 : bridge_vrf,
250 0 : routing_evpn_rt->prefix_address(),
251 0 : routing_evpn_rt->prefix_length(), false);
252 :
253 : InetUnicastAgentRouteTable *inet_table =
254 0 : bridge_vrf->GetInetUnicastRouteTable(routing_evpn_rt->prefix_address());
255 : InetUnicastRouteEntry *inet_rt =
256 : dynamic_cast<InetUnicastRouteEntry *>
257 0 : (inet_table->FindLPM(local_vm_route_key));
258 0 : if (inet_rt && RoutePrefixIsEqualTo(inet_rt, routing_evpn_rt->prefix_address(),
259 0 : routing_evpn_rt->prefix_length())) {
260 0 : return inet_rt->FindPath(agent_->evpn_routing_peer()) ? false : true;
261 : }
262 0 : return false;
263 0 : }
264 :
265 0 : bool VxlanRoutingManager::HasVrfNexthop(const AgentRoute* rt) {
266 0 : const Route::PathList & path_list = rt->GetPathList();
267 0 : for (Route::PathList::const_iterator it = path_list.begin();
268 0 : it != path_list.end(); ++it) {
269 : const AgentPath* path =
270 0 : dynamic_cast<const AgentPath*>(it.operator->());
271 :
272 0 : if (path != NULL &&
273 0 : path->nexthop() != NULL &&
274 0 : path->nexthop()->GetType() == NextHop::VRF) {
275 0 : return true;
276 : }
277 : }
278 0 : return false;
279 : }
280 :
281 0 : bool VxlanRoutingManager::HasBgpPeerPath(EvpnRouteEntry *evpn_rt) {
282 0 : const Route::PathList & path_list = evpn_rt->GetPathList();
283 0 : for (Route::PathList::const_iterator it = path_list.begin();
284 0 : it != path_list.end(); ++it) {
285 : const AgentPath* path =
286 0 : dynamic_cast<const AgentPath*>(it.operator->());
287 0 : if (path != NULL &&
288 0 : path->peer() != NULL &&
289 0 : path->peer()->GetType() == Peer::BGP_PEER) {
290 0 : return true;
291 : }
292 : }
293 0 : return false;
294 : }
295 :
296 0 : bool VxlanRoutingManager::IsRoutingVrf(const VrfEntry* vrf) {
297 0 : return vrf && vrf->vn() &&
298 0 : vrf->vn()->vxlan_routing_vn();
299 : // An alternative method
300 : // if (vrf == NULL) {
301 : // return false;
302 : // }
303 : // if (vrf->vn() == NULL) {
304 : // return false;
305 : // }
306 : // if (vrf_mapper_.lr_vrf_info_map_.count(
307 : // vrf->vn()->logical_router_uuid())) {
308 : // const VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
309 : // vrf_mapper_.lr_vrf_info_map_.at(vrf->vn()->logical_router_uuid());
310 : // if (lr_vrf_info.routing_vrf_ == vrf) {
311 : // return true;
312 : // }
313 : // }
314 : // return false;
315 : }
316 :
317 0 : bool VxlanRoutingManager::IsBridgeVrf(const VrfEntry* vrf) {
318 0 : return vrf && vrf->vn() &&
319 0 : !vrf->vn()->vxlan_routing_vn();
320 : }
321 :
322 :
323 0 : bool VxlanRoutingManager::IsRoutingVrf(const std::string vrf_name,
324 : const Agent* agent) {
325 0 : VxlanRoutingManager *vxlan_rt_mgr = NULL;
326 0 : const VrfEntry *vrf_cand = NULL;
327 0 : if (agent->oper_db()) {
328 0 : vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
329 : }
330 0 : if (vxlan_rt_mgr == NULL) {
331 0 : return false;
332 : }
333 0 : if (agent->vrf_table())
334 0 : vrf_cand = agent->vrf_table()->FindVrfFromName(vrf_name);
335 0 : if (vrf_cand == NULL) {
336 0 : return false;
337 : }
338 0 : return vxlan_rt_mgr->IsRoutingVrf(vrf_cand);
339 : }
340 :
341 0 : const AgentPath* VxlanRoutingManager::FindPathWithGivenPeer(
342 : const AgentRoute *inet_rt,
343 : const Peer::Type peer_type) {
344 0 : if (inet_rt == NULL)
345 0 : return NULL;
346 :
347 0 : const Route::PathList & path_list = inet_rt->GetPathList();
348 0 : for (Route::PathList::const_iterator it = path_list.begin();
349 0 : it != path_list.end(); ++it) {
350 : const AgentPath* path =
351 0 : dynamic_cast<const AgentPath*>(it.operator->());
352 :
353 0 : if (path != NULL &&
354 0 : path->peer()->GetType() == peer_type) {
355 0 : return path;
356 : }
357 : }
358 0 : return NULL;
359 : }
360 :
361 0 : const AgentPath* VxlanRoutingManager::FindPathWithGivenPeerAndNexthop(
362 : const AgentRoute *route,
363 : const Peer::Type peer_type,
364 : const NextHop::Type nh_type,
365 : bool strict_match) {
366 0 : if (route == NULL)
367 0 : return NULL;
368 :
369 0 : const Route::PathList & path_list = route->GetPathList();
370 0 : for (Route::PathList::const_iterator it = path_list.begin();
371 0 : it != path_list.end(); ++it) {
372 : const AgentPath* path =
373 0 : dynamic_cast<const AgentPath*>(it.operator->());
374 :
375 0 : if (path != NULL &&
376 0 : path->nexthop() != NULL &&
377 0 : path->peer() != NULL &&
378 0 : path->peer()->GetType() == peer_type) {
379 0 : if (path->nexthop()->GetType() == nh_type) {
380 0 : return path;
381 : }
382 0 : if (IsGivenTypeCompositeNextHop(path->nexthop(), nh_type,
383 : strict_match)) {
384 0 : return path;
385 : }
386 : }
387 : }
388 0 : return NULL;
389 : }
390 :
391 0 : const AgentPath* VxlanRoutingManager::FindInterfacePathWithGivenPeer(
392 : const AgentRoute *inet_rt,
393 : const Peer::Type peer_type,
394 : bool strict_match) {
395 0 : return FindPathWithGivenPeerAndNexthop(inet_rt,
396 0 : peer_type, NextHop::INTERFACE, strict_match);
397 : }
398 :
399 0 : const AgentPath *VxlanRoutingManager::FindInterfacePathWithBgpPeer(
400 : const AgentRoute *inet_rt,
401 : bool strict_match) {
402 0 : return FindInterfacePathWithGivenPeer(inet_rt, Peer::BGP_PEER,
403 0 : strict_match);
404 : }
405 :
406 0 : const AgentPath* VxlanRoutingManager::FindInterfacePathWithLocalVmPeer(
407 : const AgentRoute *inet_rt,
408 : bool strict_match) {
409 0 : return FindInterfacePathWithGivenPeer(inet_rt, Peer::LOCAL_VM_PORT_PEER,
410 0 : strict_match);
411 : }
412 :
413 0 : MacAddress VxlanRoutingManager::NbComputeMac(const Ip4Address& compute_ip,
414 : const Agent *agent) {
415 0 : MacAddress compute_mac;
416 0 : VrfEntry *underlay_vrf = agent->fabric_policy_vrf();
417 0 : InetUnicastRouteEntry *router_rt = NULL;
418 0 : router_rt = underlay_vrf->GetUcRoute(compute_ip);
419 0 : if (router_rt != NULL &&
420 0 : router_rt->prefix_address() == compute_ip) {
421 0 : const AgentPath *apath = FindPathWithGivenPeerAndNexthop(router_rt,
422 : Peer::BGP_PEER, NextHop::TUNNEL);
423 0 : if (apath) {
424 : const TunnelNH * tunl_nh =
425 0 : dynamic_cast<const TunnelNH*>(apath->nexthop());
426 0 : if (tunl_nh->GetDmac()) {
427 0 : compute_mac = *(tunl_nh->GetDmac());
428 : }
429 : }
430 : }
431 0 : return compute_mac;
432 : }
433 :
434 : //Finds route in a EVPN table
435 0 : AgentRoute *VxlanRoutingManager::FindEvpnOrInetRoute(const Agent *agent,
436 : const std::string &vrf_name,
437 : const IpAddress &ip_addr,
438 : unsigned int prefix_len,
439 : const autogen::EnetNextHopType &nh_item) {
440 :
441 0 : const unsigned int ethernet_tag = 0;
442 :
443 : EvpnRouteEntry *evpn_rt =
444 0 : EvpnAgentRouteTable::FindRoute(agent,
445 : vrf_name,
446 0 : MacAddress(),
447 : ip_addr,
448 : prefix_len,
449 : ethernet_tag);
450 0 : if (RoutePrefixIsEqualTo(evpn_rt, ip_addr, prefix_len)) {
451 0 : return evpn_rt;
452 : }
453 0 : return NULL;
454 : }
455 :
456 : //Finds route in an Inet table
457 0 : AgentRoute *VxlanRoutingManager::FindEvpnOrInetRoute(const Agent *agent,
458 : const std::string &vrf_name,
459 : const IpAddress &ip_addr,
460 : unsigned int prefix_len,
461 : const autogen::NextHopType &nh_item) {
462 :
463 : VrfEntry *vrf_entry =
464 0 : agent->vrf_table()->FindVrfFromName(vrf_name);
465 0 : if (vrf_entry == NULL)
466 0 : return NULL;
467 :
468 : InetUnicastAgentRouteTable *inet_tbl =
469 0 : vrf_entry->GetInetUnicastRouteTable(ip_addr);
470 0 : if (inet_tbl == NULL)
471 0 : return NULL;
472 :
473 : InetUnicastRouteEntry local_vm_route_key(inet_tbl->vrf_entry(),
474 : ip_addr,
475 0 : prefix_len, false);
476 : InetUnicastRouteEntry *inet_rt =
477 : dynamic_cast<InetUnicastRouteEntry *>
478 0 : (inet_tbl->FindLPM(local_vm_route_key));
479 0 : if (RoutePrefixIsEqualTo(inet_rt, ip_addr, prefix_len)) {
480 0 : return inet_rt;
481 : }
482 0 : return NULL;
483 0 : }
484 :
485 0 : static bool InitializeNhRequest(const NextHop *path_nh,
486 : DBRequest &nh_req,
487 : const std::string& vrf_name) {
488 0 : NextHopKey * orig_key = dynamic_cast<NextHopKey*>(
489 0 : path_nh->GetDBRequestKey().get())->Clone();
490 :
491 0 : if(orig_key == NULL) {
492 0 : LOG(ERROR, "Error in InitializeNhRequest"
493 : << ", orig_key == NULL");
494 0 : assert(orig_key != NULL);
495 : }
496 :
497 0 : nh_req.key.reset(orig_key);
498 0 : if (path_nh->GetType() == NextHop::INTERFACE) {
499 : InterfaceNHKey *intf_orig_key =
500 0 : dynamic_cast<InterfaceNHKey*>(orig_key);
501 0 : if(intf_orig_key == NULL) {
502 0 : LOG(ERROR, "Error in InitializeNhRequest"
503 : << ", intf_orig_key == NULL");
504 0 : assert(intf_orig_key != NULL);
505 : }
506 : // if NH is an interface, then update flags
507 0 : intf_orig_key->set_flags(intf_orig_key->flags() |
508 : InterfaceNHFlags::VXLAN_ROUTING);
509 0 : nh_req.data.reset(new InterfaceNHData(vrf_name));
510 0 : } else if (path_nh->GetType() == NextHop::COMPOSITE) {
511 0 : nh_req.data.reset(new CompositeNHData);
512 : } else { // other types of NH are not expected here
513 0 : LOG(ERROR, "Error in InitializeNhRequest"
514 : << ", Wrong NH type:" << path_nh->GetType());
515 0 : assert(
516 : path_nh->GetType() == NextHop::INTERFACE ||
517 : path_nh->GetType() == NextHop::COMPOSITE);
518 0 : return false;
519 : }
520 0 : return true;
521 : }
522 :
523 : //
524 : // EVPN routes advertising
525 : //
526 :
527 0 : static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
528 : const uint32_t plen,
529 : DBRequest &nh_req,
530 : const Peer *peer,
531 : const RouteParameters& params,
532 : EvpnAgentRouteTable *evpn_table
533 : ) {
534 : EvpnRoutingData *rt_data = new EvpnRoutingData(nh_req,
535 : params.sg_list_,
536 : params.communities_,
537 : params.path_preference_,
538 : params.ecmp_load_balance_,
539 : params.tag_list_,
540 0 : evpn_table->vrf_entry(),
541 0 : evpn_table->vrf_entry()->vxlan_id(),
542 0 : params.vn_list_);
543 0 : evpn_table->AddType5Route(peer,
544 : evpn_table->vrf_entry()->GetName(),
545 : prefix_ip,
546 : 0, // ethernet_tag = 0 for Type5
547 : rt_data,
548 : plen);
549 0 : }
550 :
551 0 : static void AdvertiseInterfaceBgpRoute(const IpAddress &prefix_ip,
552 : const uint32_t plen,
553 : DBRequest &nh_req,
554 : const Peer *peer,
555 : const AgentPath* path,
556 : EvpnAgentRouteTable *evpn_table
557 : ) {
558 0 : const NextHop *path_nh = path->nexthop();
559 :
560 0 : const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
561 0 : (path_nh);
562 0 : const Interface *intf = intf_nh->GetInterface();
563 0 : if (intf->type() != Interface::VM_INTERFACE) {
564 0 : return;
565 : }
566 0 : const VmInterface *vm_intf = dynamic_cast<const VmInterface*>
567 0 : (intf);
568 0 : DBEntryBase::KeyPtr tintf_key_ptr = vm_intf->GetDBRequestKey();
569 : const VmInterfaceKey* intf_key_ptr =
570 0 : dynamic_cast<const VmInterfaceKey *>(tintf_key_ptr.get());
571 :
572 : LocalVmRoute *loc_rt_ptr = new LocalVmRoute(
573 : *intf_key_ptr,
574 : MplsTable::kInvalidLabel, // mpls_label
575 0 : path->vxlan_id(),
576 0 : path->force_policy(),
577 0 : path->dest_vn_list(),
578 0 : intf_nh->GetFlags(), // flags
579 0 : path->sg_list(),
580 0 : path->tag_list(),
581 0 : path->communities(),
582 0 : path->path_preference(),
583 0 : path->subnet_service_ip(),
584 0 : path->ecmp_load_balance(),
585 0 : path->is_local(),
586 0 : path->is_health_check_service(),
587 0 : path->sequence(),
588 0 : path->etree_leaf(),
589 0 : false); // native_encap
590 0 : loc_rt_ptr->set_tunnel_bmap(TunnelType::VxlanType());
591 :
592 : {
593 0 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
594 :
595 0 : req.key.reset(new EvpnRouteKey(peer,
596 0 : evpn_table->vrf_entry()->GetName(),
597 0 : MacAddress(),
598 : prefix_ip,
599 : plen,
600 0 : 0));
601 0 : req.data.reset(loc_rt_ptr);
602 0 : evpn_table->Enqueue(&req);
603 0 : }
604 0 : }
605 :
606 0 : static void AdvertiseCompositeInterfaceBgpRoute(const IpAddress &prefix_ip,
607 : const uint32_t plen,
608 : DBRequest &nh_req,
609 : const Peer *peer,
610 : const AgentPath* path,
611 : EvpnAgentRouteTable *evpn_table
612 : ) {
613 0 : const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer*>(peer);
614 0 : std::stringstream prefix_str;
615 0 : prefix_str << prefix_ip.to_string();
616 0 : prefix_str << "/";
617 0 : prefix_str << plen;
618 0 : std::string vrf_name = evpn_table->vrf_name();
619 :
620 : ControllerEcmpRoute *rt_data = new ControllerEcmpRoute(
621 : bgp_peer,
622 0 : path->dest_vn_list(),
623 0 : path->ecmp_load_balance(),
624 0 : path->tag_list(),
625 0 : path->sg_list(),
626 0 : path->path_preference(),
627 0 : TunnelType::VxlanType(),
628 : nh_req,
629 0 : prefix_str.str(),
630 0 : evpn_table->vrf_name());
631 :
632 : ControllerEcmpRoute::ClonedLocalPathListIter iter =
633 0 : rt_data->cloned_local_path_list().begin();
634 0 : while (iter != rt_data->cloned_local_path_list().end()) {
635 0 : evpn_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
636 0 : MacAddress(), prefix_ip, 0, (*iter));
637 0 : iter++;
638 : }
639 :
640 0 : evpn_table->AddRemoteVmRouteReq(bgp_peer,
641 0 : vrf_name, MacAddress(),
642 : prefix_ip,
643 : plen,
644 : 0, // ethernet tag is 0 for VxLAN
645 : rt_data);
646 0 : }
647 :
648 : //
649 : // Inet routes advertising
650 : //
651 0 : static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
652 : const uint32_t plen,
653 : DBRequest &nh_req,
654 : const Peer *peer,
655 : const RouteParameters& params,
656 : InetUnicastAgentRouteTable *inet_table,
657 : const std::string& origin_vn
658 : ) {
659 0 : inet_table->AddEvpnRoutingRoute(prefix_ip,
660 : plen,
661 0 : inet_table->vrf_entry(),
662 : peer,
663 : params.sg_list_,
664 : params.communities_,
665 : params.path_preference_,
666 : params.ecmp_load_balance_,
667 : params.tag_list_,
668 : nh_req,
669 : inet_table->vrf_entry()->vxlan_id(),
670 : params.vn_list_,
671 : origin_vn);
672 0 : }
673 :
674 0 : void VxlanRoutingManager::DeleteOldInterfacePath(const IpAddress &prefix_ip,
675 : const uint32_t plen,
676 : const Peer *peer,
677 : EvpnAgentRouteTable *evpn_table) {
678 :
679 0 : if (peer != routing_vrf_interface_peer_) {
680 0 : return;
681 : }
682 :
683 0 : EvpnRouteEntry *rt_entry = evpn_table->FindRoute(MacAddress(),
684 : prefix_ip, plen, 0);
685 0 : if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
686 : // Delete the old non-BGP path if it exists
687 0 : AgentPath *old_path = rt_entry->FindPath(peer);
688 0 : if (old_path) {
689 0 : rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
690 : evpn_table, old_path);
691 : }
692 : }
693 : }
694 :
695 0 : void VxlanRoutingManager::CopyInterfacePathToEvpnTable(const AgentPath* path,
696 : const IpAddress &prefix_ip,
697 : const uint32_t plen,
698 : const Peer *peer,
699 : const RouteParameters ¶ms,
700 : EvpnAgentRouteTable *evpn_table) {
701 0 : const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
702 :
703 0 : if (path_nh == NULL) {
704 0 : return;
705 : }
706 :
707 0 : DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
708 0 : if (InitializeNhRequest(path_nh,
709 0 : nh_req, evpn_table->vrf_entry()->GetName()) == false) {
710 0 : return;
711 : }
712 :
713 0 : if (peer->GetType() == Peer::BGP_PEER) {
714 0 : if (path_nh->GetType() == NextHop::INTERFACE) {
715 0 : AdvertiseInterfaceBgpRoute(
716 : prefix_ip, plen, nh_req, peer, path, evpn_table);
717 0 : } else if (path_nh->GetType() == NextHop::COMPOSITE) {
718 0 : AdvertiseCompositeInterfaceBgpRoute(
719 : prefix_ip, plen, nh_req, peer, path, evpn_table);
720 : }
721 : } else {
722 0 : AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
723 : evpn_table);
724 : }
725 0 : }
726 :
727 0 : void VxlanRoutingManager::DeleteOldInterfacePath(const IpAddress &prefix_ip,
728 : const uint32_t plen,
729 : const Peer *peer,
730 : InetUnicastAgentRouteTable *inet_table) {
731 0 : if (peer != routing_vrf_interface_peer_) {
732 0 : return;
733 : }
734 :
735 : InetUnicastRouteEntry old_rt_key(inet_table->vrf_entry(),
736 0 : prefix_ip, plen, false);
737 0 : InetUnicastRouteEntry *rt_entry = inet_table->FindRouteUsingKey(old_rt_key);
738 0 : if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
739 : // Delete the old non-BGP path if it exists
740 0 : AgentPath *old_path = rt_entry->FindPath(peer);
741 0 : if (old_path) {
742 0 : rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
743 : inet_table, old_path);
744 : }
745 : }
746 0 : }
747 :
748 0 : void VxlanRoutingManager::CopyPathToInetTable(const AgentPath* path,
749 : const IpAddress &prefix_ip,
750 : const uint32_t plen,
751 : const Peer *peer,
752 : const RouteParameters ¶ms,
753 : InetUnicastAgentRouteTable *inet_table) {
754 0 : const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
755 0 : if (path_nh == NULL || inet_table == NULL || peer == NULL) {
756 0 : return;
757 : }
758 :
759 :
760 0 : DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
761 0 : if (InitializeNhRequest(path_nh,
762 0 : nh_req, inet_table->vrf_entry()->GetName()) == false) {
763 0 : return;
764 : }
765 :
766 0 : std::string origin_vn = "";
767 0 : if (peer->GetType() == Peer::VXLAN_BGP_PEER) {
768 : } else {
769 0 : origin_vn = GetOriginVn(inet_table->vrf_entry(), prefix_ip, plen);
770 : }
771 0 : AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
772 : inet_table, origin_vn);
773 0 : }
774 :
775 :
776 0 : void VxlanRoutingManager::PrintEvpnTable(const VrfEntry* const_vrf) {
777 0 : if (const_vrf == NULL) {
778 : std::cout<< "VxlanRoutingManager::PrintEvpnTable"
779 0 : << ", NULL vrf ptr"
780 0 : << std::endl;
781 0 : return;
782 : }
783 0 : VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
784 0 : EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
785 0 : (routing_vrf->GetEvpnRouteTable());
786 0 : if (evpn_table == NULL) {
787 : std::cout<< "VxlanRoutingManager::PrintEvpnTable"
788 0 : << ", NULL EVPN tbl ptr"
789 0 : << std::endl;
790 0 : return;
791 : }
792 0 : EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
793 0 : (evpn_table->GetTablePartition(0)->GetFirst());
794 0 : if (c_entry) {
795 0 : if (c_entry->IsType5())
796 0 : std::cout << "Evpn Type 5 table:" << std::endl;
797 : else
798 0 : std::cout << "Evpn Type 2 table:" << std::endl;
799 : }
800 0 : while (c_entry) {
801 0 : const Route::PathList & path_list = c_entry->GetPathList();
802 0 : std::cout<< " IP:" << c_entry->prefix_address()
803 0 : << ", path count = " << path_list.size()
804 0 : << ", ethernet_tag = " << c_entry->ethernet_tag()
805 0 : << std::endl;
806 0 : for (Route::PathList::const_iterator it = path_list.begin();
807 0 : it != path_list.end(); ++it) {
808 : const AgentPath* path =
809 0 : dynamic_cast<const AgentPath*>(it.operator->());
810 0 : if (!path)
811 0 : continue;
812 : std::cout<< " NH: "
813 0 : << (path->nexthop() ? path->nexthop()->ToString() :
814 : "NULL")
815 : << ", " << "Peer:"
816 0 : << (path->peer() ? path->peer()->GetName() : "NULL")
817 0 : << std::endl;
818 0 : if (path->nexthop()->GetType() == NextHop::COMPOSITE) {
819 0 : CompositeNH *comp_nh = dynamic_cast<CompositeNH *>
820 0 : (path->nexthop());
821 0 : std::cout<< " n components="
822 0 : << comp_nh->ComponentNHCount()
823 0 : << std::endl;
824 : }
825 : }
826 0 : if (evpn_table && evpn_table->GetTablePartition(0))
827 0 : c_entry = dynamic_cast<EvpnRouteEntry *>
828 0 : (evpn_table->GetTablePartition(0)->GetNext(c_entry));
829 : else
830 0 : break;
831 : }
832 : }
833 :
834 0 : void VxlanRoutingManager::PrintInetTable(const VrfEntry* const_vrf) {
835 0 : if (const_vrf == NULL) {
836 : std::cout<< "VxlanRoutingManager::PrintInetTable"
837 0 : << ", NULL vrf ptr"
838 0 : << std::endl;
839 0 : return;
840 : }
841 0 : VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
842 : InetUnicastAgentRouteTable *inet_table =
843 0 : routing_vrf->GetInet4UnicastRouteTable();
844 0 : if (inet_table == NULL) {
845 : std::cout<< "VxlanRoutingManager::PrintInetTable"
846 0 : << ", NULL Inet tbl ptr"
847 0 : << std::endl;
848 0 : return;
849 : }
850 0 : InetUnicastRouteEntry *c_entry = dynamic_cast<InetUnicastRouteEntry *>
851 0 : (inet_table->GetTablePartition(0)->GetFirst());
852 0 : if (c_entry) {
853 0 : std::cout << "Inet table:" << std::endl;
854 : }
855 0 : while (c_entry) {
856 0 : const Route::PathList & path_list = c_entry->GetPathList();
857 0 : std::cout<< " IP:" << c_entry->prefix_address()
858 0 : << ", path count = " << path_list.size() << std::endl;
859 0 : for (Route::PathList::const_iterator it = path_list.begin();
860 0 : it != path_list.end(); ++it) {
861 : const AgentPath* path =
862 0 : dynamic_cast<const AgentPath*>(it.operator->());
863 0 : if (!path)
864 0 : continue;
865 : std::cout<< " NH: "
866 0 : << (path->nexthop() ? path->nexthop()->ToString() :
867 : "NULL")
868 : << ", " << "Peer:"
869 0 : << (path->peer() ? path->peer()->GetName() : "NULL")
870 0 : << ", nh ptr = " << path->nexthop()
871 0 : << ", pt ptr = " << path
872 0 : << std::endl;
873 : // if (path->nexthop()->GetType() == NextHop::COMPOSITE) {
874 : // CompositeNH *comp_nh = dynamic_cast<CompositeNH *>
875 : // (path->nexthop());
876 : // std::cout<< " n components="
877 : // << comp_nh->ComponentNHCount()
878 : // << std::endl;
879 : // }
880 : }
881 0 : if (inet_table && inet_table->GetTablePartition(0))
882 0 : c_entry = dynamic_cast<InetUnicastRouteEntry *>
883 0 : (inet_table->GetTablePartition(0)->GetNext(c_entry));
884 : else
885 0 : break;
886 : }
887 : }
888 :
889 0 : void VxlanRoutingManager::ListAttachedVns() {
890 0 : Agent *agent = Agent::GetInstance();
891 0 : if (agent == NULL) {
892 0 : std::cout<<"VxlanRoutingManager::ListAttachedVns agent == NULL"<<std::endl;
893 0 : return;
894 : }
895 0 : VxlanRoutingManager *vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
896 0 : if (vxlan_rt_mgr == NULL) {
897 0 : std::cout<<"VxlanRoutingManager::ListAttachedVns rt mgr = NULL"<<std::endl;
898 0 : return;
899 : }
900 0 : VxlanRoutingVrfMapper& vrf_mapper = vxlan_rt_mgr->vrf_mapper_;
901 0 : VxlanRoutingVrfMapper::LrVrfInfoMap& lr_vrf_info_map = vrf_mapper.lr_vrf_info_map_;
902 0 : for(VxlanRoutingVrfMapper::LrVrfInfoMap::iterator it = lr_vrf_info_map.begin();
903 0 : it != lr_vrf_info_map.end(); it++) {
904 : std::cout << "VxlanRoutingManager::ListAttachedVns, "
905 : << "rt VRF = "
906 0 : << (*it).second.routing_vrf_->GetName()
907 0 : << std::endl;
908 : std::cout << "VxlanRoutingManager::ListAttachedVns, "
909 0 : << "size = "
910 0 : << (*it).second.bridge_vn_list_.size()
911 0 : << std::endl;
912 : VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList ®_br =
913 0 : (*it).second.bridge_vn_list_;
914 0 : for(VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList::iterator it_br = reg_br.begin();
915 0 : it_br != reg_br.end(); it_br++) {
916 0 : if ((*it_br))
917 : std::cout<< "VxlanRoutingManager::ListAttachedVns, "
918 0 : << "br VN = " << (*it_br)->GetName()
919 0 : << std::endl;
920 : }
921 : }
922 : }
923 :
924 : //
925 : //END-OF-FILE
926 : //
|