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