Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include "bgp/bgp_attr.h"
7 :
8 : #include <algorithm>
9 : #include <string>
10 :
11 : #include "bgp/bgp_server.h"
12 : #include "bgp/extended-community/esi_label.h"
13 : #include "bgp/extended-community/etree.h"
14 : #include "bgp/extended-community/mac_mobility.h"
15 : #include "bgp/extended-community/router_mac.h"
16 : #include "net/bgp_af.h"
17 :
18 : using std::sort;
19 : using std::vector;
20 : using std::string;
21 :
22 9985 : int BgpAttrOrigin::CompareTo(const BgpAttribute &rhs_attr) const {
23 9985 : int ret = BgpAttribute::CompareTo(rhs_attr);
24 9985 : if (ret != 0) return ret;
25 9985 : KEY_COMPARE(origin, static_cast<const BgpAttrOrigin &>(rhs_attr).origin);
26 9985 : return 0;
27 : }
28 :
29 184580 : void BgpAttrOrigin::ToCanonical(BgpAttr *attr) {
30 184580 : attr->set_origin(static_cast<BgpAttrOrigin::OriginType>(origin));
31 184580 : }
32 :
33 111443 : string BgpAttrOrigin::ToString() const {
34 : char repr[80];
35 111443 : snprintf(repr, sizeof(repr), "ORIGIN <code: %d, flags: %02x> : %02x",
36 111443 : code, flags, origin);
37 111443 : return string(repr);
38 : }
39 :
40 9981 : int BgpAttrNextHop::CompareTo(const BgpAttribute &rhs_attr) const {
41 9981 : int ret = BgpAttribute::CompareTo(rhs_attr);
42 9981 : if (ret != 0) return ret;
43 9981 : KEY_COMPARE(nexthop,
44 : static_cast<const BgpAttrNextHop &>(rhs_attr).nexthop);
45 9981 : return 0;
46 : }
47 :
48 191097 : void BgpAttrNextHop::ToCanonical(BgpAttr *attr) {
49 191097 : if (v6_nexthop.is_unspecified()) {
50 188566 : attr->set_nexthop(Ip4Address(nexthop));
51 : } else {
52 2532 : attr->set_nexthop(v6_nexthop);
53 : }
54 191099 : }
55 :
56 3045 : string BgpAttrNextHop::ToString() const {
57 : char repr[80];
58 3045 : snprintf(repr, sizeof(repr), "NEXTHOP <code: %d, flags: %02x> : %04x",
59 3045 : code, flags, nexthop);
60 3045 : return string(repr);
61 : }
62 :
63 1988 : int BgpAttrMultiExitDisc::CompareTo(const BgpAttribute &rhs_attr) const {
64 1988 : int ret = BgpAttribute::CompareTo(rhs_attr);
65 1988 : if (ret != 0) return ret;
66 1988 : KEY_COMPARE(med, static_cast<const BgpAttrMultiExitDisc &>(rhs_attr).med);
67 1986 : return 0;
68 : }
69 76743 : void BgpAttrMultiExitDisc::ToCanonical(BgpAttr *attr) {
70 76743 : attr->set_med(med);
71 76743 : }
72 :
73 51917 : string BgpAttrMultiExitDisc::ToString() const {
74 : char repr[80];
75 51917 : snprintf(repr, sizeof(repr), "MED <code: %d, flags: %02x> : %d",
76 51917 : code, flags, med);
77 51917 : return string(repr);
78 : }
79 :
80 1994 : int BgpAttrLocalPref::CompareTo(const BgpAttribute &rhs_attr) const {
81 1994 : int ret = BgpAttribute::CompareTo(rhs_attr);
82 1994 : if (ret != 0) return ret;
83 1994 : KEY_COMPARE(local_pref,
84 : static_cast<const BgpAttrLocalPref &>(rhs_attr).local_pref);
85 1994 : return 0;
86 : }
87 92086 : void BgpAttrLocalPref::ToCanonical(BgpAttr *attr) {
88 92086 : attr->set_local_pref(local_pref);
89 92085 : }
90 :
91 23853 : string BgpAttrLocalPref::ToString() const {
92 : char repr[80];
93 23853 : snprintf(repr, sizeof(repr), "LOCAL_PREF <code: %d, flags: %02x> : %d",
94 23853 : code, flags, local_pref);
95 23853 : return string(repr);
96 : }
97 :
98 9 : void BgpAttrAtomicAggregate::ToCanonical(BgpAttr *attr) {
99 9 : attr->set_atomic_aggregate(true);
100 9 : }
101 :
102 1 : string BgpAttrAtomicAggregate::ToString() const {
103 : char repr[80];
104 1 : snprintf(repr, sizeof(repr), "ATOMIC_AGGR <code: %d, flags: %02x>",
105 1 : code, flags);
106 1 : return string(repr);
107 : }
108 :
109 3 : int BgpAttr4ByteAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
110 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
111 3 : if (ret != 0) return ret;
112 3 : KEY_COMPARE(as_num,
113 : static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).as_num);
114 3 : KEY_COMPARE(address,
115 : static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).address);
116 3 : return 0;
117 : }
118 1 : void BgpAttr4ByteAggregator::ToCanonical(BgpAttr *attr) {
119 1 : attr->set_aggregator(as_num, Ip4Address(address));
120 1 : }
121 :
122 0 : string BgpAttr4ByteAggregator::ToString() const {
123 : char repr[80];
124 0 : snprintf(repr, sizeof(repr),
125 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
126 0 : code, flags, as_num, address);
127 0 : return string(repr);
128 : }
129 :
130 1973 : int BgpAttrAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
131 1973 : int ret = BgpAttribute::CompareTo(rhs_attr);
132 1973 : if (ret != 0) return ret;
133 1973 : KEY_COMPARE(as_num,
134 : static_cast<const BgpAttrAggregator &>(rhs_attr).as_num);
135 1971 : KEY_COMPARE(address,
136 : static_cast<const BgpAttrAggregator &>(rhs_attr).address);
137 1969 : return 0;
138 : }
139 8 : void BgpAttrAggregator::ToCanonical(BgpAttr *attr) {
140 8 : attr->set_aggregator(as_num, Ip4Address(address));
141 8 : }
142 :
143 1 : string BgpAttrAggregator::ToString() const {
144 : char repr[80];
145 1 : snprintf(repr, sizeof(repr),
146 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
147 1 : code, flags, as_num, address);
148 1 : return string(repr);
149 : }
150 :
151 0 : int BgpAttrAs4Aggregator::CompareTo(const BgpAttribute &rhs_attr) const {
152 0 : int ret = BgpAttribute::CompareTo(rhs_attr);
153 0 : if (ret != 0) return ret;
154 0 : KEY_COMPARE(as_num,
155 : static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).as_num);
156 0 : KEY_COMPARE(address,
157 : static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).address);
158 0 : return 0;
159 : }
160 0 : void BgpAttrAs4Aggregator::ToCanonical(BgpAttr *attr) {
161 0 : attr->set_as4_aggregator(as_num, Ip4Address(address));
162 0 : }
163 :
164 0 : string BgpAttrAs4Aggregator::ToString() const {
165 : char repr[80];
166 0 : snprintf(repr, sizeof(repr),
167 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
168 0 : code, flags, as_num, address);
169 0 : return string(repr);
170 : }
171 :
172 3 : int BgpAttrOriginatorId::CompareTo(const BgpAttribute &rhs_attr) const {
173 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
174 3 : if (ret != 0) return ret;
175 3 : KEY_COMPARE(originator_id,
176 : static_cast<const BgpAttrOriginatorId &>(rhs_attr).originator_id);
177 1 : return 0;
178 : }
179 :
180 18 : void BgpAttrOriginatorId::ToCanonical(BgpAttr *attr) {
181 18 : attr->set_originator_id(Ip4Address(originator_id));
182 18 : }
183 :
184 3 : string BgpAttrOriginatorId::ToString() const {
185 : char repr[80];
186 3 : snprintf(repr, sizeof(repr), "OriginatorId <code: %d, flags: 0x%02x> : %s",
187 6 : code, flags, Ip4Address(originator_id).to_string().c_str());
188 3 : return string(repr);
189 : }
190 :
191 9 : ClusterListSpec::ClusterListSpec(uint32_t cluster_id,
192 9 : const ClusterListSpec *rhs)
193 9 : : BgpAttribute(BgpAttribute::ClusterList, kFlags) {
194 9 : cluster_list.push_back(cluster_id);
195 9 : if (rhs) {
196 1 : cluster_list.insert(cluster_list.end(), rhs->cluster_list.begin(),
197 : rhs->cluster_list.end());
198 : }
199 9 : }
200 :
201 46 : int ClusterListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
202 46 : int ret = BgpAttribute::CompareTo(rhs_attr);
203 46 : if (ret != 0) return ret;
204 46 : KEY_COMPARE(cluster_list,
205 : static_cast<const ClusterListSpec &>(rhs_attr).cluster_list);
206 38 : return 0;
207 : }
208 :
209 8 : void ClusterListSpec::ToCanonical(BgpAttr *attr) {
210 8 : attr->set_cluster_list(this);
211 8 : }
212 :
213 3 : string ClusterListSpec::ToString() const {
214 3 : std::stringstream repr;
215 3 : repr << "CLUSTER_LIST <code: " << int(code);
216 3 : repr << ", flags: 0x" << std::hex << int(flags) << "> :";
217 3 : for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
218 9 : iter != cluster_list.end(); ++iter) {
219 6 : repr << " " << Ip4Address(*iter).to_string();
220 : }
221 6 : return repr.str();
222 3 : }
223 :
224 14 : bool ClusterListSpec::ClusterListLoop(uint32_t cluster_id) const {
225 14 : for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
226 56 : iter != cluster_list.end(); ++iter) {
227 47 : if (*iter == cluster_id)
228 5 : return true;
229 : }
230 9 : return false;
231 : }
232 :
233 22 : ClusterList::ClusterList(ClusterListDB *cluster_list_db,
234 22 : const ClusterListSpec &spec)
235 22 : : cluster_list_db_(cluster_list_db),
236 22 : spec_(spec) {
237 22 : refcount_ = 0;
238 22 : }
239 :
240 18 : void ClusterList::Remove() {
241 18 : cluster_list_db_->Delete(this);
242 18 : }
243 :
244 9743 : ClusterListDB::ClusterListDB(BgpServer *server) {
245 9743 : }
246 :
247 1990 : int BgpMpNlri::CompareTo(const BgpAttribute &rhs_attr) const {
248 1990 : int ret = BgpAttribute::CompareTo(rhs_attr);
249 1990 : if (ret != 0) return ret;
250 1990 : const BgpMpNlri &rhs = static_cast<const BgpMpNlri &>(rhs_attr);
251 1990 : KEY_COMPARE(afi, rhs.afi);
252 1990 : KEY_COMPARE(safi, rhs.safi);
253 1990 : KEY_COMPARE(nexthop, rhs.nexthop);
254 1990 : KEY_COMPARE(nlri.size(), rhs.nlri.size());
255 :
256 498340 : for (size_t i = 0; i < nlri.size(); i++) {
257 496350 : KEY_COMPARE(nlri[i]->type, rhs.nlri[i]->type);
258 496350 : KEY_COMPARE(nlri[i]->prefixlen, rhs.nlri[i]->prefixlen);
259 496350 : KEY_COMPARE(nlri[i]->prefix, rhs.nlri[i]->prefix);
260 : }
261 1990 : return 0;
262 : }
263 :
264 158286 : void BgpMpNlri::ToCanonical(BgpAttr *attr) {
265 158286 : }
266 :
267 505519 : size_t BgpMpNlri::EncodeLength() const {
268 505519 : size_t sz = 2 /* safi */ + 1 /* afi */ +
269 : 1 /* NlriNextHopLength */ +
270 : 1 /* Reserved */;
271 505519 : sz += nexthop.size();
272 505540 : for (vector<BgpProtoPrefix*>::const_iterator iter = nlri.begin();
273 2854682 : iter != nlri.end(); ++iter) {
274 2349152 : size_t bytes = 0;
275 2349152 : if (afi == BgpAf::L2Vpn &&
276 39764 : (safi == BgpAf::EVpn || safi == BgpAf::ErmVpn)) {
277 39764 : bytes = (*iter)->prefixlen;
278 : } else {
279 2309388 : bytes = ((*iter)->prefixlen + 7) / 8;
280 : }
281 2349157 : sz += 1 + bytes;
282 : }
283 505513 : return sz;
284 : }
285 :
286 25397 : PmsiTunnelSpec::PmsiTunnelSpec()
287 : : BgpAttribute(PmsiTunnel, kFlags),
288 25397 : tunnel_flags(0), tunnel_type(0), label(0) {
289 25396 : }
290 :
291 3006 : PmsiTunnelSpec::PmsiTunnelSpec(const BgpAttribute &rhs)
292 3006 : : BgpAttribute(rhs), tunnel_flags(0), tunnel_type(0), label(0) {
293 3006 : }
294 :
295 659713 : int PmsiTunnelSpec::CompareTo(const BgpAttribute &rhs_attr) const {
296 659713 : int ret = BgpAttribute::CompareTo(rhs_attr);
297 659713 : if (ret != 0) return ret;
298 659713 : const PmsiTunnelSpec &rhs = static_cast<const PmsiTunnelSpec &>(rhs_attr);
299 659713 : KEY_COMPARE(tunnel_flags, rhs.tunnel_flags);
300 648059 : KEY_COMPARE(tunnel_type, rhs.tunnel_type);
301 648052 : KEY_COMPARE(label, rhs.label);
302 624122 : KEY_COMPARE(identifier, rhs.identifier);
303 621449 : return 0;
304 : }
305 :
306 8132 : void PmsiTunnelSpec::ToCanonical(BgpAttr *attr) {
307 8132 : attr->set_pmsi_tunnel(this);
308 8132 : }
309 :
310 840 : string PmsiTunnelSpec::ToString() const {
311 840 : std::ostringstream oss;
312 840 : oss << "PmsiTunnel <code: " << int(code);
313 840 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
314 840 : oss << " Tunnel Flags: 0x" << std::hex << int(tunnel_flags) << std::dec;
315 840 : oss << " Tunnel Type: " << int(tunnel_type);
316 840 : oss << " Label: 0x" << std::hex << int(label) << std::dec;
317 840 : oss << " (" << int(label) << ")";
318 840 : oss << " Identifier: " << GetIdentifier().to_string();
319 :
320 1680 : return oss.str();
321 840 : }
322 :
323 2 : uint32_t PmsiTunnelSpec::GetLabel(const ExtCommunity *ext) const {
324 2 : assert(ext);
325 2 : bool is_vni = ext->ContainsTunnelEncapVxlan();
326 2 : return (is_vni ? label : (label >> 4));
327 : }
328 :
329 7747 : void PmsiTunnelSpec::SetLabel(uint32_t in_label, const ExtCommunity *ext) {
330 7747 : assert(ext);
331 7747 : bool is_vni = ext->ContainsTunnelEncapVxlan();
332 7747 : label = (is_vni ? in_label : (in_label << 4 | 0x01));
333 7747 : }
334 :
335 18762 : Ip4Address PmsiTunnelSpec::GetIdentifier() const {
336 18762 : if (identifier.size() < 4)
337 9824 : return Ip4Address();
338 8938 : return Ip4Address(get_value(&identifier[0], 4));
339 : }
340 :
341 11690 : void PmsiTunnelSpec::SetIdentifier(Ip4Address in_identifier) {
342 11690 : identifier.resize(4, 0);
343 11689 : const Ip4Address::bytes_type &bytes = in_identifier.to_bytes();
344 11689 : std::copy(bytes.begin(), bytes.begin() + 4, identifier.begin());
345 11689 : }
346 :
347 9 : string PmsiTunnelSpec::GetTunnelTypeString() const {
348 9 : switch (tunnel_type) {
349 1 : case RsvpP2mpLsp:
350 1 : return "RsvpP2mpLsp";
351 1 : case LdpP2mpLsp:
352 1 : return "LdpP2mpLsp";
353 1 : case PimSsmTree:
354 1 : return "PimSsmTree";
355 1 : case PimSmTree:
356 1 : return "PimSmTree";
357 1 : case BidirPimTree:
358 1 : return "BidirPimTree";
359 1 : case IngressReplication:
360 1 : return "IngressReplication";
361 1 : case MldpMp2mpLsp:
362 1 : return "MldpMp2mpLsp";
363 1 : case AssistedReplicationContrail:
364 1 : return "AssistedReplication";
365 1 : default:
366 1 : break;
367 : }
368 2 : std::ostringstream oss;
369 1 : oss << "Unknown(" << int(tunnel_type) << ")";
370 1 : return oss.str();
371 : }
372 :
373 4 : string PmsiTunnelSpec::GetTunnelArTypeString() const {
374 4 : switch (tunnel_flags & AssistedReplicationType) {
375 1 : case RegularNVE:
376 1 : return "RegularNVE";
377 1 : case ARReplicator:
378 1 : return "ARReplicator";
379 1 : case ARLeaf:
380 1 : return "ARLeaf";
381 1 : default:
382 1 : break;
383 : }
384 1 : return "Unknown";
385 : }
386 :
387 4 : vector<string> PmsiTunnelSpec::GetTunnelFlagsStrings() const {
388 4 : vector<string> flags;
389 4 : if (tunnel_flags & LeafInfoRequired) {
390 2 : flags.push_back("LeafInfoRequired");
391 : }
392 4 : if (tunnel_flags & EdgeReplicationSupported) {
393 2 : flags.push_back("EdgeReplicationSupported");
394 : }
395 4 : if (flags.empty()) {
396 1 : flags.push_back("None");
397 : }
398 4 : return flags;
399 0 : }
400 :
401 17923 : PmsiTunnel::PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db,
402 17923 : const PmsiTunnelSpec &pmsi_spec)
403 17923 : : pmsi_tunnel_db_(pmsi_tunnel_db),
404 17923 : pmsi_spec_(pmsi_spec) {
405 17917 : refcount_ = 0;
406 17922 : tunnel_flags_ = pmsi_spec_.tunnel_flags;
407 17922 : tunnel_type_ = pmsi_spec_.tunnel_type;
408 17922 : label_ = pmsi_spec_.label;
409 17922 : identifier_ = pmsi_spec_.GetIdentifier();
410 17920 : }
411 :
412 4973 : void PmsiTunnel::Remove() {
413 4973 : pmsi_tunnel_db_->Delete(this);
414 4973 : }
415 :
416 2598 : uint32_t PmsiTunnel::GetLabel(const ExtCommunity *ext) const {
417 2598 : bool is_vni = false;
418 2598 : if (ext)
419 2586 : is_vni = ext->ContainsTunnelEncapVxlan();
420 2598 : return (is_vni ? label_ : label_ >> 4);
421 : }
422 :
423 9743 : PmsiTunnelDB::PmsiTunnelDB(BgpServer *server) {
424 9743 : }
425 :
426 5859 : EdgeDiscoverySpec::EdgeDiscoverySpec()
427 5859 : : BgpAttribute(McastEdgeDiscovery, kFlags) {
428 5858 : }
429 :
430 3814 : EdgeDiscoverySpec::EdgeDiscoverySpec(const BgpAttribute &rhs)
431 3814 : : BgpAttribute(rhs) {
432 3814 : }
433 :
434 4118 : EdgeDiscoverySpec::EdgeDiscoverySpec(const EdgeDiscoverySpec &rhs)
435 4118 : : BgpAttribute(BgpAttribute::McastEdgeDiscovery, kFlags) {
436 13385 : for (size_t i = 0; i < rhs.edge_list.size(); i++) {
437 9268 : Edge *edge = new Edge;
438 9269 : *edge = *rhs.edge_list[i];
439 9268 : edge_list.push_back(edge);
440 : }
441 4117 : }
442 :
443 22640 : EdgeDiscoverySpec::~EdgeDiscoverySpec() {
444 13780 : STLDeleteValues(&edge_list);
445 22615 : }
446 :
447 9754 : Ip4Address EdgeDiscoverySpec::Edge::GetIp4Address() const {
448 9754 : return Ip4Address(get_value(&address[0], 4));
449 : }
450 :
451 130307 : void EdgeDiscoverySpec::Edge::SetIp4Address(Ip4Address addr) {
452 130307 : address.resize(4, 0);
453 130307 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
454 130307 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4, address.begin());
455 130307 : }
456 :
457 9753 : void EdgeDiscoverySpec::Edge::GetLabels(
458 : uint32_t *first_label, uint32_t *last_label) const {
459 9753 : *first_label = labels[0];
460 9753 : *last_label = labels[1];
461 9753 : }
462 :
463 130307 : void EdgeDiscoverySpec::Edge::SetLabels(
464 : uint32_t first_label, uint32_t last_label) {
465 130307 : labels.push_back(first_label);
466 130307 : labels.push_back(last_label);
467 130307 : }
468 :
469 : struct EdgeDiscoverySpecEdgeCompare {
470 63710 : int operator()(const EdgeDiscoverySpec::Edge *lhs,
471 : const EdgeDiscoverySpec::Edge *rhs) const {
472 63710 : KEY_COMPARE(lhs->address, rhs->address);
473 63710 : KEY_COMPARE(lhs->labels, rhs->labels);
474 63710 : return 0;
475 : }
476 : };
477 :
478 2003 : int EdgeDiscoverySpec::CompareTo(const BgpAttribute &rhs_attr) const {
479 2003 : int ret = BgpAttribute::CompareTo(rhs_attr);
480 2003 : if (ret != 0) return ret;
481 2003 : const EdgeDiscoverySpec &rhs =
482 : static_cast<const EdgeDiscoverySpec &>(rhs_attr);
483 2003 : ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
484 : rhs.edge_list.begin(), rhs.edge_list.end(),
485 : EdgeDiscoverySpecEdgeCompare());
486 2003 : return ret;
487 : }
488 :
489 2031 : void EdgeDiscoverySpec::ToCanonical(BgpAttr *attr) {
490 2031 : attr->set_edge_discovery(this);
491 2031 : }
492 :
493 1207 : string EdgeDiscoverySpec::ToString() const {
494 1207 : std::ostringstream oss;
495 1207 : oss << "EdgeDiscovery <code: " << int(code);
496 1207 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
497 1207 : int idx = 0;
498 1207 : for (EdgeList::const_iterator it = edge_list.begin();
499 4822 : it != edge_list.end(); ++it, ++idx) {
500 3616 : const Edge *edge = *it;
501 : uint32_t first_label, last_label;
502 3616 : edge->GetLabels(&first_label, &last_label);
503 3616 : oss << " Edge[" << idx << "] = (" << edge->GetIp4Address() << ", ";
504 3616 : oss << first_label << "-" << last_label << ")";
505 : }
506 :
507 2414 : return oss.str();
508 1207 : }
509 :
510 13936 : size_t EdgeDiscoverySpec::EncodeLength() const {
511 13936 : size_t sz = 0;
512 13936 : for (EdgeList::const_iterator iter = edge_list.begin();
513 276705 : iter != edge_list.end(); ++iter) {
514 262769 : sz += 2; /* AddressLen + LabelLen */
515 262769 : sz += (*iter)->address.size();
516 262769 : sz += (*iter)->labels.size() * sizeof(uint32_t);
517 : }
518 13936 : return sz;
519 : }
520 :
521 6110 : EdgeDiscovery::Edge::Edge(const EdgeDiscoverySpec::Edge *spec_edge) {
522 6110 : address = spec_edge->GetIp4Address();
523 : uint32_t first_label, last_label;
524 6110 : spec_edge->GetLabels(&first_label, &last_label);
525 6110 : label_block = new LabelBlock(first_label, last_label);
526 6111 : }
527 :
528 53095 : bool EdgeDiscovery::Edge::operator<(const Edge &rhs) const {
529 53095 : BOOL_KEY_COMPARE(address, rhs.address);
530 46049 : BOOL_KEY_COMPARE(label_block->first(), rhs.label_block->first());
531 40688 : BOOL_KEY_COMPARE(label_block->last(), rhs.label_block->last());
532 40688 : return false;
533 : }
534 :
535 3066 : EdgeDiscovery::EdgeDiscovery(EdgeDiscoveryDB *edge_discovery_db,
536 3066 : const EdgeDiscoverySpec &edspec)
537 3065 : : edge_discovery_db_(edge_discovery_db),
538 3066 : edspec_(edspec) {
539 3064 : refcount_ = 0;
540 3061 : for (EdgeDiscoverySpec::EdgeList::const_iterator it =
541 9176 : edspec_.edge_list.begin(); it != edspec_.edge_list.end(); ++it) {
542 6110 : Edge *edge = new Edge(*it);
543 6111 : edge_list.push_back(edge);
544 : }
545 3061 : sort(edge_list.begin(), edge_list.end(), EdgeDiscovery::EdgeCompare());
546 3062 : }
547 :
548 5108 : EdgeDiscovery::~EdgeDiscovery() {
549 3066 : STLDeleteValues(&edge_list);
550 5108 : }
551 :
552 : struct EdgeDiscoveryEdgeCompare {
553 21044 : int operator()(const EdgeDiscovery::Edge *lhs,
554 : const EdgeDiscovery::Edge *rhs) const {
555 21044 : KEY_COMPARE(*lhs, *rhs);
556 12236 : return 0;
557 : }
558 : };
559 :
560 638655 : int EdgeDiscovery::CompareTo(const EdgeDiscovery &rhs) const {
561 638655 : int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
562 : rhs.edge_list.begin(), rhs.edge_list.end(),
563 : EdgeDiscoveryEdgeCompare());
564 638655 : return result;
565 : }
566 :
567 1763 : void EdgeDiscovery::Remove() {
568 1763 : edge_discovery_db_->Delete(this);
569 1763 : }
570 :
571 9743 : EdgeDiscoveryDB::EdgeDiscoveryDB(BgpServer *server) {
572 9743 : }
573 :
574 6287 : EdgeForwardingSpec::EdgeForwardingSpec()
575 6287 : : BgpAttribute(McastEdgeForwarding, kFlags) {
576 6286 : }
577 :
578 4537 : EdgeForwardingSpec::EdgeForwardingSpec(const BgpAttribute &rhs)
579 4537 : : BgpAttribute(rhs) {
580 4537 : }
581 :
582 5983 : EdgeForwardingSpec::EdgeForwardingSpec(const EdgeForwardingSpec &rhs)
583 5983 : : BgpAttribute(BgpAttribute::McastEdgeForwarding, kFlags) {
584 11013 : for (size_t i = 0; i < rhs.edge_list.size(); i++) {
585 5031 : Edge *edge = new Edge;
586 5031 : *edge = *rhs.edge_list[i];
587 5031 : edge_list.push_back(edge);
588 : }
589 5982 : }
590 :
591 27020 : EdgeForwardingSpec:: ~EdgeForwardingSpec() {
592 16795 : STLDeleteValues(&edge_list);
593 26994 : }
594 :
595 5375 : Ip4Address EdgeForwardingSpec::Edge::GetInboundIp4Address() const {
596 5375 : return Ip4Address(get_value(&inbound_address[0], 4));
597 : }
598 :
599 5376 : Ip4Address EdgeForwardingSpec::Edge::GetOutboundIp4Address() const {
600 5376 : return Ip4Address(get_value(&outbound_address[0], 4));
601 : }
602 :
603 126137 : void EdgeForwardingSpec::Edge::SetInboundIp4Address(Ip4Address addr) {
604 126137 : inbound_address.resize(4, 0);
605 126137 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
606 126137 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
607 : inbound_address.begin());
608 126137 : }
609 :
610 126137 : void EdgeForwardingSpec::Edge::SetOutboundIp4Address(Ip4Address addr) {
611 126137 : outbound_address.resize(4, 0);
612 126137 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
613 126137 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
614 : outbound_address.begin());
615 126137 : }
616 :
617 : struct EdgeForwardingSpecEdgeCompare {
618 59919 : int operator()(const EdgeForwardingSpec::Edge *lhs,
619 : const EdgeForwardingSpec::Edge *rhs) const {
620 59919 : KEY_COMPARE(lhs->inbound_address, rhs->inbound_address);
621 59919 : KEY_COMPARE(lhs->outbound_address, rhs->outbound_address);
622 59919 : KEY_COMPARE(lhs->inbound_label, rhs->inbound_label);
623 59919 : KEY_COMPARE(lhs->outbound_label, rhs->outbound_label);
624 59919 : return 0;
625 : }
626 : };
627 :
628 1898 : int EdgeForwardingSpec::CompareTo(const BgpAttribute &rhs_attr) const {
629 1898 : int ret = BgpAttribute::CompareTo(rhs_attr);
630 1898 : if (ret != 0) return ret;
631 1898 : const EdgeForwardingSpec &rhs =
632 : static_cast<const EdgeForwardingSpec &>(rhs_attr);
633 1898 : ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
634 : rhs.edge_list.begin(), rhs.edge_list.end(),
635 : EdgeForwardingSpecEdgeCompare());
636 1898 : return ret;
637 : }
638 :
639 3245 : void EdgeForwardingSpec::ToCanonical(BgpAttr *attr) {
640 3245 : attr->set_edge_forwarding(this);
641 3245 : }
642 :
643 1986 : string EdgeForwardingSpec::ToString() const {
644 1986 : std::ostringstream oss;
645 1986 : oss << "EdgeForwarding <code: " << int(code);
646 1986 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
647 1986 : int idx = 0;
648 1986 : for (EdgeList::const_iterator it = edge_list.begin();
649 4185 : it != edge_list.end(); ++it, ++idx) {
650 2200 : const Edge *edge = *it;
651 2200 : oss << " Edge[" << idx << "] = (";
652 2200 : oss << "InAddress=" << edge->GetInboundIp4Address() << ", ";
653 2200 : oss << "InLabel=" << edge->inbound_label << ", ";
654 2200 : oss << "OutAddress=" << edge->GetOutboundIp4Address() << ", ";
655 2200 : oss << "OutLabel=" << edge->outbound_label << ")";
656 : }
657 :
658 3972 : return oss.str();
659 1986 : }
660 :
661 15940 : size_t EdgeForwardingSpec::EncodeLength() const {
662 15940 : size_t sz = 0;
663 15940 : for (EdgeList::const_iterator iter = edge_list.begin();
664 270978 : iter != edge_list.end(); ++iter) {
665 255037 : sz += 1 /* address len */ + 8 /* 2 labels */;
666 255037 : sz += (*iter)->inbound_address.size();
667 255037 : sz += (*iter)->outbound_address.size();
668 : }
669 :
670 15941 : return sz;
671 : }
672 :
673 3172 : EdgeForwarding::Edge::Edge(const EdgeForwardingSpec::Edge *spec_edge) {
674 3172 : inbound_address = spec_edge->GetInboundIp4Address();
675 3172 : outbound_address = spec_edge->GetOutboundIp4Address();
676 3172 : inbound_label = spec_edge->inbound_label;
677 3172 : outbound_label = spec_edge->outbound_label;
678 3172 : }
679 :
680 31731 : bool EdgeForwarding::Edge::operator<(const Edge &rhs) const {
681 31731 : BOOL_KEY_COMPARE(inbound_address, rhs.inbound_address);
682 22123 : BOOL_KEY_COMPARE(outbound_address, rhs.outbound_address);
683 17564 : BOOL_KEY_COMPARE(inbound_label, rhs.inbound_label);
684 15672 : BOOL_KEY_COMPARE(outbound_label, rhs.outbound_label);
685 13431 : return false;
686 : }
687 :
688 4279 : EdgeForwarding::EdgeForwarding(EdgeForwardingDB *edge_forwarding_db,
689 4279 : const EdgeForwardingSpec &efspec)
690 4278 : : edge_forwarding_db_(edge_forwarding_db),
691 4279 : efspec_(efspec) {
692 4277 : refcount_ = 0;
693 4275 : for (EdgeForwardingSpec::EdgeList::const_iterator it =
694 7453 : efspec_.edge_list.begin(); it != efspec_.edge_list.end(); ++it) {
695 3172 : Edge *edge = new Edge(*it);
696 3172 : edge_list.push_back(edge);
697 : }
698 4269 : sort(edge_list.begin(), edge_list.end(), EdgeForwarding::EdgeCompare());
699 4268 : }
700 :
701 7538 : EdgeForwarding::~EdgeForwarding() {
702 4281 : STLDeleteValues(&edge_list);
703 7538 : }
704 :
705 : struct EdgeForwardingEdgeCompare {
706 17998 : int operator()(const EdgeForwarding::Edge *lhs,
707 : const EdgeForwarding::Edge *rhs) const {
708 17998 : KEY_COMPARE(*lhs, *rhs);
709 6718 : return 0;
710 : }
711 : };
712 :
713 871202 : int EdgeForwarding::CompareTo(const EdgeForwarding &rhs) const {
714 871202 : int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
715 : rhs.edge_list.begin(), rhs.edge_list.end(),
716 : EdgeForwardingEdgeCompare());
717 871201 : return result;
718 : }
719 :
720 2219 : void EdgeForwarding::Remove() {
721 2219 : edge_forwarding_db_->Delete(this);
722 2219 : }
723 :
724 9743 : EdgeForwardingDB::EdgeForwardingDB(BgpServer *server) {
725 9743 : }
726 :
727 199371 : bool BgpOListElem::operator<(const BgpOListElem &rhs) const {
728 199371 : BOOL_KEY_COMPARE(address, rhs.address);
729 131099 : BOOL_KEY_COMPARE(label, rhs.label);
730 127025 : BOOL_KEY_COMPARE(encap, rhs.encap);
731 127014 : return false;
732 : }
733 :
734 3 : int BgpOListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
735 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
736 3 : if (ret != 0) return ret;
737 3 : return 0;
738 : }
739 :
740 3475 : void BgpOListSpec::ToCanonical(BgpAttr *attr) {
741 3475 : if (subcode == BgpAttribute::OList) {
742 3475 : attr->set_olist(this);
743 0 : } else if (subcode == BgpAttribute::LeafOList) {
744 0 : attr->set_leaf_olist(this);
745 : } else {
746 0 : assert(false);
747 : }
748 3475 : }
749 :
750 1 : string BgpOListSpec::ToString() const {
751 1 : std::ostringstream oss;
752 1 : oss << "OList <subcode: " << int(subcode) << ">";
753 1 : int idx = 0;
754 1 : for (Elements::const_iterator it = elements.begin();
755 3 : it != elements.end(); ++it, ++idx) {
756 2 : BgpOListElem elem(*it);
757 2 : oss << "OList[" << idx << "] = (";
758 2 : oss << "address: " << elem.address << ", ";
759 2 : oss << "label: " << elem.label << ", ";
760 2 : oss << "encap-list:";
761 2 : int eid = 0;
762 2 : for (vector<string>::const_iterator e_it = elem.encap.begin();
763 6 : e_it != elem.encap.end(); ++e_it, ++eid) {
764 4 : oss << " " << *e_it;
765 : }
766 2 : oss << ")";
767 2 : }
768 2 : return (oss.str());
769 1 : }
770 :
771 13874 : BgpOList::BgpOList(BgpOListDB *olist_db, const BgpOListSpec &olist_spec)
772 13874 : : olist_db_(olist_db),
773 13874 : olist_spec_(olist_spec) {
774 13870 : refcount_ = 0;
775 13874 : for (BgpOListSpec::Elements::const_iterator it =
776 36816 : olist_spec_.elements.begin(); it != olist_spec_.elements.end(); ++it) {
777 22941 : BgpOListElem *elem = new BgpOListElem(*it);
778 22941 : sort(elem->encap.begin(), elem->encap.end());
779 22941 : elements_.push_back(elem);
780 : }
781 13873 : sort(elements_.begin(), elements_.end(), BgpOListElemCompare());
782 13872 : }
783 :
784 26724 : BgpOList::~BgpOList() {
785 13873 : STLDeleteValues(&elements_);
786 26723 : }
787 :
788 : struct BgpOListElementCompare {
789 77729 : int operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const {
790 77729 : KEY_COMPARE(*lhs, *rhs);
791 63507 : return 0;
792 : }
793 : };
794 :
795 425926 : int BgpOList::CompareTo(const BgpOList &rhs) const {
796 425926 : KEY_COMPARE(olist().subcode, rhs.olist().subcode);
797 822166 : int result = STLSortedCompare(elements().begin(), elements().end(),
798 822166 : rhs.elements().begin(), rhs.elements().end(),
799 : BgpOListElementCompare());
800 411083 : return result;
801 : }
802 :
803 9638 : void BgpOList::Remove() {
804 9638 : olist_db_->Delete(this);
805 9638 : }
806 :
807 9743 : BgpOListDB::BgpOListDB(BgpServer *server) {
808 9743 : }
809 :
810 0 : int BgpAttrLabelBlock::CompareTo(const BgpAttribute &rhs_attr) const {
811 0 : int ret = BgpAttribute::CompareTo(rhs_attr);
812 0 : if (ret != 0) return ret;
813 0 : KEY_COMPARE(label_block.get(),
814 : static_cast<const BgpAttrLabelBlock &>(rhs_attr).label_block.get());
815 0 : return 0;
816 : }
817 :
818 1033 : void BgpAttrLabelBlock::ToCanonical(BgpAttr *attr) {
819 1033 : attr->set_label_block(label_block);
820 1033 : }
821 :
822 0 : string BgpAttrLabelBlock::ToString() const {
823 : char repr[80];
824 0 : snprintf(repr, sizeof(repr), "LabelBlock <subcode: %d> : %d-%d",
825 0 : subcode, label_block->first(), label_block->last());
826 0 : return string(repr);
827 : }
828 :
829 3 : int BgpAttrSourceRd::CompareTo(const BgpAttribute &rhs_attr) const {
830 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
831 3 : if (ret != 0) return ret;
832 3 : KEY_COMPARE(source_rd,
833 : static_cast<const BgpAttrSourceRd &>(rhs_attr).source_rd);
834 1 : return 0;
835 : }
836 :
837 28475 : void BgpAttrSourceRd::ToCanonical(BgpAttr *attr) {
838 28475 : attr->set_source_rd(source_rd);
839 28475 : }
840 :
841 1 : string BgpAttrSourceRd::ToString() const {
842 : char repr[80];
843 1 : snprintf(repr, sizeof(repr), "SourceRd <subcode: %d> : %s",
844 2 : subcode, source_rd.ToString().c_str());
845 1 : return string(repr);
846 : }
847 :
848 3 : int BgpAttrEsi::CompareTo(const BgpAttribute &rhs_attr) const {
849 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
850 3 : if (ret != 0) return ret;
851 3 : KEY_COMPARE(esi, static_cast<const BgpAttrEsi &>(rhs_attr).esi);
852 1 : return 0;
853 : }
854 :
855 59 : void BgpAttrEsi::ToCanonical(BgpAttr *attr) {
856 59 : attr->set_esi(esi);
857 59 : }
858 :
859 1 : string BgpAttrEsi::ToString() const {
860 : char repr[80];
861 1 : snprintf(repr, sizeof(repr), "Esi <subcode: %d> : %s",
862 2 : subcode, esi.ToString().c_str());
863 1 : return string(repr);
864 : }
865 :
866 3 : int BgpAttrParams::CompareTo(const BgpAttribute &rhs_attr) const {
867 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
868 3 : if (ret != 0) return ret;
869 3 : KEY_COMPARE(params, static_cast<const BgpAttrParams &>(rhs_attr).params);
870 1 : return 0;
871 : }
872 :
873 3 : void BgpAttrParams::ToCanonical(BgpAttr *attr) {
874 3 : attr->set_params(params);
875 3 : }
876 :
877 1 : string BgpAttrParams::ToString() const {
878 : char repr[80];
879 1 : snprintf(repr, sizeof(repr), "Params <subcode: %d> : 0x%016jx",
880 1 : subcode, params);
881 1 : return string(repr);
882 : }
883 :
884 3 : int BgpAttrSubProtocol::CompareTo(const BgpAttribute &rhs_attr) const {
885 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
886 3 : if (ret != 0) return ret;
887 3 : KEY_COMPARE(sbp, static_cast<const BgpAttrSubProtocol &>(rhs_attr).sbp);
888 1 : return 0;
889 : }
890 :
891 21985 : void BgpAttrSubProtocol::ToCanonical(BgpAttr *attr) {
892 21985 : attr->set_sub_protocol(sbp);
893 21985 : }
894 :
895 1 : string BgpAttrSubProtocol::ToString() const {
896 : char repr[80];
897 1 : snprintf(repr, sizeof(repr), "SubProtocol <subcode: %d> : %s",
898 1 : subcode, sbp.c_str());
899 1 : return string(repr);
900 : }
901 :
902 38 : BgpAttr::BgpAttr()
903 38 : : attr_db_(NULL), origin_(BgpAttrOrigin::INCOMPLETE), nexthop_(),
904 38 : med_(0), local_pref_(0), atomic_aggregate_(false),
905 38 : aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
906 38 : refcount_ = 0;
907 38 : }
908 :
909 5953 : BgpAttr::BgpAttr(BgpAttrDB *attr_db)
910 5953 : : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
911 11906 : nexthop_(), med_(0), local_pref_(0), atomic_aggregate_(false),
912 5953 : aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
913 5953 : refcount_ = 0;
914 5953 : }
915 :
916 388825 : BgpAttr::BgpAttr(BgpAttrDB *attr_db, const BgpAttrSpec &spec)
917 388825 : : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
918 777649 : nexthop_(), med_(0),
919 388824 : local_pref_(BgpAttrLocalPref::kDefault),
920 388824 : atomic_aggregate_(false),
921 388824 : aggregator_as_num_(0), aggregator_as4_num_(0),
922 388825 : aggregator_address_(), params_(0) {
923 388807 : refcount_ = 0;
924 388831 : for (vector<BgpAttribute *>::const_iterator it = spec.begin();
925 1466648 : it < spec.end(); it++) {
926 1077794 : (*it)->ToCanonical(this);
927 : }
928 388814 : }
929 :
930 3040989 : BgpAttr::BgpAttr(const BgpAttr &rhs)
931 3040989 : : attr_db_(rhs.attr_db_), origin_(rhs.origin_), nexthop_(rhs.nexthop_),
932 3040549 : med_(rhs.med_), local_pref_(rhs.local_pref_),
933 3040549 : atomic_aggregate_(rhs.atomic_aggregate_),
934 3040549 : aggregator_as_num_(rhs.aggregator_as_num_),
935 3040549 : aggregator_as4_num_(rhs.aggregator_as4_num_),
936 3040549 : aggregator_address_(rhs.aggregator_address_),
937 3040345 : originator_id_(rhs.originator_id_),
938 3040223 : source_rd_(rhs.source_rd_), esi_(rhs.esi_), params_(rhs.params_),
939 3040147 : as_path_(rhs.as_path_),
940 3040945 : aspath_4byte_(rhs.aspath_4byte_),
941 3040814 : as4_path_(rhs.as4_path_),
942 3040644 : cluster_list_(rhs.cluster_list_),
943 3040509 : community_(rhs.community_),
944 3040412 : ext_community_(rhs.ext_community_),
945 3041555 : large_community_(rhs.large_community_),
946 3041124 : deferred_large_spec_(nullptr),
947 3040296 : origin_vn_path_(rhs.origin_vn_path_),
948 3040200 : pmsi_tunnel_(rhs.pmsi_tunnel_),
949 3040073 : edge_discovery_(rhs.edge_discovery_),
950 3039940 : edge_forwarding_(rhs.edge_forwarding_),
951 3039868 : label_block_(rhs.label_block_),
952 3039794 : olist_(rhs.olist_),
953 3039707 : leaf_olist_(rhs.leaf_olist_),
954 6080589 : sub_protocol_(rhs.sub_protocol_) {
955 3039366 : refcount_ = 0;
956 3041692 : }
957 :
958 19267 : void BgpAttr::set_as_path(AsPathPtr aspath) {
959 19267 : as_path_ = aspath;
960 19267 : }
961 :
962 363132 : void BgpAttr::set_as_path(const AsPathSpec *spec) {
963 363132 : if (spec) {
964 363000 : as_path_ = attr_db_->server()->aspath_db()->Locate(*spec);
965 : } else {
966 132 : as_path_ = NULL;
967 : }
968 363221 : }
969 :
970 0 : void BgpAttr::set_as4_path(As4PathPtr aspath) {
971 0 : as4_path_ = aspath;
972 0 : }
973 :
974 495 : void BgpAttr::set_as4_path(const As4PathSpec *spec) {
975 495 : if (spec) {
976 461 : as4_path_ = attr_db_->server()->as4path_db()->Locate(*spec);
977 : } else {
978 34 : as4_path_ = NULL;
979 : }
980 495 : }
981 :
982 0 : void BgpAttr::set_aspath_4byte(AsPath4BytePtr aspath) {
983 0 : aspath_4byte_ = aspath;
984 0 : }
985 :
986 556 : void BgpAttr::set_aspath_4byte(const AsPath4ByteSpec *spec) {
987 556 : if (spec) {
988 495 : aspath_4byte_ = attr_db_->server()->aspath_4byte_db()->Locate(*spec);
989 : } else {
990 61 : aspath_4byte_ = NULL;
991 : }
992 556 : }
993 :
994 204576 : void BgpAttr::set_cluster_list(const ClusterListSpec *spec) {
995 204576 : if (spec) {
996 18 : cluster_list_ = attr_db_->server()->cluster_list_db()->Locate(*spec);
997 : } else {
998 204558 : cluster_list_ = NULL;
999 : }
1000 204575 : }
1001 :
1002 25014 : void BgpAttr::set_community(CommunityPtr comm) {
1003 25014 : community_ = comm;
1004 25014 : }
1005 :
1006 4371 : void BgpAttr::set_community(const CommunitySpec *comm) {
1007 4371 : if (comm) {
1008 4371 : community_ = attr_db_->server()->comm_db()->Locate(*comm);
1009 : } else {
1010 0 : community_ = NULL;
1011 : }
1012 4371 : }
1013 :
1014 1013638 : void BgpAttr::set_ext_community(ExtCommunityPtr extcomm) {
1015 1013638 : ext_community_ = extcomm;
1016 1013708 : }
1017 :
1018 183845 : void BgpAttr::set_ext_community(const ExtCommunitySpec *extcomm) {
1019 183845 : if (extcomm) {
1020 183845 : LargeCommunitySpec large_spec = LargeCommunitySpec::FromTag(*extcomm);
1021 183842 : set_large_community(&large_spec);
1022 :
1023 183843 : if (large_spec.communities.size()) {
1024 : ExtCommunitySpec new_comms =
1025 4 : LargeCommunitySpec::RemoveTags(*extcomm);
1026 : ext_community_ =
1027 4 : attr_db_->server()->extcomm_db()->Locate(new_comms);
1028 4 : return;
1029 4 : }
1030 183839 : ext_community_ = attr_db_->server()->extcomm_db()->Locate(*extcomm);
1031 183847 : } else {
1032 0 : ext_community_ = NULL;
1033 : }
1034 : }
1035 :
1036 18971 : void BgpAttr::set_large_community(LargeCommunityPtr largecomm) {
1037 18971 : large_community_ = largecomm;
1038 18971 : }
1039 :
1040 183886 : void BgpAttr::set_large_community(const LargeCommunitySpec *largecomm) {
1041 183886 : if (largecomm) {
1042 183886 : if (!bool(deferred_large_spec_)) {
1043 183843 : deferred_large_spec_.reset(new LargeCommunitySpec);
1044 183840 : deferred_large_spec_->communities = largecomm->communities;
1045 : } else {
1046 88 : deferred_large_spec_->communities.insert(
1047 88 : deferred_large_spec_->communities.end(),
1048 : largecomm->communities.begin(),
1049 : largecomm->communities.end());
1050 : }
1051 : large_community_ =
1052 183883 : attr_db_->server()->largecomm_db()->Locate(*deferred_large_spec_);
1053 : } else {
1054 0 : large_community_ = NULL;
1055 : }
1056 183887 : }
1057 :
1058 18972 : void BgpAttr::set_origin_vn_path(OriginVnPathPtr ovnpath) {
1059 18972 : origin_vn_path_ = ovnpath;
1060 18972 : }
1061 :
1062 721 : void BgpAttr::set_origin_vn_path(const OriginVnPathSpec *spec) {
1063 721 : if (spec) {
1064 721 : origin_vn_path_ = attr_db_->server()->ovnpath_db()->Locate(*spec);
1065 : } else {
1066 0 : origin_vn_path_ = NULL;
1067 : }
1068 721 : }
1069 :
1070 16889 : void BgpAttr::set_pmsi_tunnel(const PmsiTunnelSpec *pmsi_spec) {
1071 16889 : if (pmsi_spec) {
1072 16889 : pmsi_tunnel_ = attr_db_->server()->pmsi_tunnel_db()->Locate(*pmsi_spec);
1073 : } else {
1074 0 : pmsi_tunnel_ = NULL;
1075 : }
1076 16889 : }
1077 :
1078 2032 : void BgpAttr::set_edge_discovery(const EdgeDiscoverySpec *edspec) {
1079 2032 : if (edspec) {
1080 : edge_discovery_ =
1081 2032 : attr_db_->server()->edge_discovery_db()->Locate(*edspec);
1082 : } else {
1083 0 : edge_discovery_ = NULL;
1084 : }
1085 2032 : }
1086 :
1087 3247 : void BgpAttr::set_edge_forwarding(const EdgeForwardingSpec *efspec) {
1088 3247 : if (efspec) {
1089 : edge_forwarding_ =
1090 3247 : attr_db_->server()->edge_forwarding_db()->Locate(*efspec);
1091 : } else {
1092 0 : edge_forwarding_ = NULL;
1093 : }
1094 3247 : }
1095 :
1096 1034 : void BgpAttr::set_label_block(LabelBlockPtr label_block) {
1097 1034 : label_block_ = label_block;
1098 1034 : }
1099 :
1100 8231 : void BgpAttr::set_olist(const BgpOListSpec *olist_spec) {
1101 8231 : if (olist_spec) {
1102 8231 : olist_ = attr_db_->server()->olist_db()->Locate(*olist_spec);
1103 : } else {
1104 0 : olist_ = NULL;
1105 : }
1106 8231 : }
1107 :
1108 4600 : void BgpAttr::set_leaf_olist(const BgpOListSpec *leaf_olist_spec) {
1109 4600 : if (leaf_olist_spec) {
1110 4600 : leaf_olist_ = attr_db_->server()->olist_db()->Locate(*leaf_olist_spec);
1111 : } else {
1112 0 : leaf_olist_ = NULL;
1113 : }
1114 4600 : }
1115 :
1116 9337321 : int BgpAttr::max_as_path_count() const {
1117 9337321 : int as_count = as_path_count();
1118 9337296 : int as4_count = aspath_4byte_count();
1119 9337292 : return as_count > as4_count ? as_count : as4_count;
1120 : }
1121 :
1122 100681 : bool BgpAttr::IsAsPathEmpty() const {
1123 100681 : if (as_path_ && !as_path_->empty())
1124 332 : return false;
1125 100350 : if (aspath_4byte_ && !aspath_4byte_->empty())
1126 86 : return false;
1127 100196 : return true;
1128 : }
1129 :
1130 5608 : string BgpAttr::OriginToString(BgpAttrOrigin::OriginType origin) {
1131 5608 : switch (origin) {
1132 5246 : case BgpAttrOrigin::IGP:
1133 5246 : return "igp";
1134 : break;
1135 3 : case BgpAttrOrigin::EGP:
1136 3 : return "egp";
1137 : break;
1138 358 : case BgpAttrOrigin::INCOMPLETE:
1139 358 : return "incomplete";
1140 : break;
1141 : }
1142 1 : return "unknown";
1143 : }
1144 :
1145 20418 : BgpAttrOrigin::OriginType BgpAttr::OriginFromString(
1146 : const string &bgp_origin_type) {
1147 20418 : if(bgp_origin_type == "IGP"){
1148 20415 : return BgpAttrOrigin::IGP;
1149 3 : } else if( bgp_origin_type == "EGP") {
1150 2 : return BgpAttrOrigin::EGP;
1151 : }
1152 1 : return BgpAttrOrigin::INCOMPLETE;
1153 : }
1154 :
1155 5605 : string BgpAttr::origin_string() const {
1156 5605 : return OriginToString(origin());
1157 : }
1158 :
1159 2860 : Address::Family BgpAttr::nexthop_family() const {
1160 2860 : if (nexthop_.is_v6()) {
1161 325 : return Address::INET6;
1162 : } else {
1163 2535 : return Address::INET;
1164 : }
1165 : }
1166 :
1167 2652109 : as_t BgpAttr::neighbor_as() const {
1168 2652109 : if (as_path_.get())
1169 489680 : return as_path_->neighbor_as();
1170 2162419 : if (aspath_4byte_.get())
1171 233 : return aspath_4byte_->neighbor_as();
1172 2162198 : return 0;
1173 : }
1174 :
1175 9429457 : uint32_t BgpAttr::sequence_number() const {
1176 9429457 : if (!ext_community_)
1177 1135713 : return 0;
1178 8293785 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1179 8293770 : ext_community_->communities().begin();
1180 29166178 : it != ext_community_->communities().end(); ++it) {
1181 20876614 : if (ExtCommunity::is_mac_mobility(*it)) {
1182 4321 : MacMobility mm(*it);
1183 4321 : return mm.sequence_number();
1184 : }
1185 : }
1186 8289398 : return 0;
1187 : }
1188 :
1189 4714807 : bool BgpAttr::evpn_sticky_mac() const {
1190 4714807 : if (!ext_community_)
1191 567864 : return 0;
1192 4146945 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1193 4146960 : ext_community_->communities().begin();
1194 14583829 : it != ext_community_->communities().end(); ++it) {
1195 10439125 : if (ExtCommunity::is_mac_mobility(*it)) {
1196 2180 : MacMobility mm(*it);
1197 2180 : return mm.sticky();
1198 : }
1199 : }
1200 4144754 : return 0;
1201 : }
1202 :
1203 4714880 : bool BgpAttr::etree_leaf() const {
1204 4714880 : if (!ext_community_)
1205 567866 : return 0;
1206 4146995 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1207 4147000 : ext_community_->communities().begin();
1208 14438522 : it != ext_community_->communities().end(); ++it) {
1209 10365284 : if (ExtCommunity::is_etree(*it)) {
1210 73791 : ETree etree(*it);
1211 73797 : return etree.leaf();
1212 : }
1213 : }
1214 4073147 : return 0;
1215 : }
1216 :
1217 52 : bool BgpAttr::evpn_single_active() const {
1218 52 : if (!ext_community_)
1219 0 : return false;
1220 52 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1221 52 : ext_community_->communities().begin();
1222 104 : it != ext_community_->communities().end(); ++it) {
1223 104 : if (ExtCommunity::is_esi_label(*it)) {
1224 52 : EsiLabel esi_label(*it);
1225 52 : return esi_label.single_active();
1226 : }
1227 : }
1228 0 : return true;
1229 : }
1230 :
1231 463036 : MacAddress BgpAttr::mac_address() const {
1232 463036 : if (!ext_community_)
1233 13548 : return MacAddress::kZeroMac;
1234 449464 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1235 449482 : ext_community_->communities().begin();
1236 3183031 : it != ext_community_->communities().end(); ++it) {
1237 2733597 : if (ExtCommunity::is_router_mac(*it)) {
1238 22 : RouterMac router_mac(*it);
1239 22 : return router_mac.mac_address();
1240 : }
1241 : }
1242 449365 : return MacAddress::kZeroMac;
1243 : }
1244 :
1245 439464 : void BgpAttr::Remove() {
1246 439464 : attr_db_->Delete(this);
1247 439465 : }
1248 :
1249 452375 : int BgpAttr::IsAsPathLoop(as_t asn, uint8_t max_loop_count) const {
1250 452375 : if (as_path() && as_path()->path().AsPathLoop(asn, max_loop_count)) {
1251 136352 : return true;
1252 : }
1253 316234 : if (aspath_4byte() &&
1254 199 : aspath_4byte()->path().AsPathLoop(asn, max_loop_count)) {
1255 54 : return true;
1256 : }
1257 315999 : if (asn > AS2_MAX && as4_path() &&
1258 20 : as4_path()->path().AsPathLoop(asn, max_loop_count)) {
1259 4 : return true;
1260 : }
1261 315975 : return false;
1262 : }
1263 :
1264 25753360 : int BgpAttr::CompareTo(const BgpAttr &rhs) const {
1265 25753360 : KEY_COMPARE(origin_, rhs.origin_);
1266 24029562 : KEY_COMPARE(nexthop_, rhs.nexthop_);
1267 16149515 : KEY_COMPARE(med_, rhs.med_);
1268 15368418 : KEY_COMPARE(local_pref_, rhs.local_pref_);
1269 14971238 : KEY_COMPARE(atomic_aggregate_, rhs.atomic_aggregate_);
1270 14971238 : KEY_COMPARE(aggregator_as_num_, rhs.aggregator_as_num_);
1271 14971046 : KEY_COMPARE(aggregator_as4_num_, rhs.aggregator_as4_num_);
1272 14970918 : KEY_COMPARE(aggregator_address_, rhs.aggregator_address_);
1273 14973951 : KEY_COMPARE(originator_id_, rhs.originator_id_);
1274 14973607 : KEY_COMPARE(pmsi_tunnel_.get(), rhs.pmsi_tunnel_.get());
1275 14619790 : KEY_COMPARE(edge_discovery_.get(), rhs.edge_discovery_.get());
1276 14559572 : KEY_COMPARE(edge_forwarding_.get(), rhs.edge_forwarding_.get());
1277 14498303 : KEY_COMPARE(esi_, rhs.esi_);
1278 14497980 : KEY_COMPARE(params_, rhs.params_);
1279 14497975 : KEY_COMPARE(source_rd_, rhs.source_rd_);
1280 10439883 : KEY_COMPARE(label_block_.get(), rhs.label_block_.get());
1281 10441659 : KEY_COMPARE(olist_.get(), rhs.olist_.get());
1282 10383452 : KEY_COMPARE(leaf_olist_.get(), rhs.leaf_olist_.get());
1283 10363721 : KEY_COMPARE(as_path_.get(), rhs.as_path_.get());
1284 10073277 : KEY_COMPARE(aspath_4byte_.get(), rhs.aspath_4byte_.get());
1285 10072154 : KEY_COMPARE(as4_path_.get(), rhs.as4_path_.get());
1286 10071186 : KEY_COMPARE(cluster_list_.get(), rhs.cluster_list_.get());
1287 10071136 : KEY_COMPARE(community_.get(), rhs.community_.get());
1288 9817148 : KEY_COMPARE(ext_community_.get(), rhs.ext_community_.get());
1289 7315243 : KEY_COMPARE(large_community_.get(), rhs.large_community_.get());
1290 7300464 : KEY_COMPARE(origin_vn_path_.get(), rhs.origin_vn_path_.get());
1291 7223613 : KEY_COMPARE(sub_protocol_, rhs.sub_protocol_);
1292 7207702 : return 0;
1293 : }
1294 :
1295 0 : std::size_t hash_value(BgpAttr const &attr) {
1296 0 : size_t hash = 0;
1297 :
1298 0 : boost::hash_combine(hash, attr.origin_);
1299 0 : boost::hash_combine(hash, attr.nexthop_.to_string());
1300 0 : boost::hash_combine(hash, attr.med_);
1301 0 : boost::hash_combine(hash, attr.local_pref_);
1302 0 : boost::hash_combine(hash, attr.atomic_aggregate_);
1303 0 : boost::hash_combine(hash, attr.aggregator_as_num_);
1304 0 : boost::hash_combine(hash, attr.aggregator_as4_num_);
1305 0 : boost::hash_combine(hash, attr.aggregator_address_.to_string());
1306 0 : boost::hash_combine(hash, attr.originator_id_.to_string());
1307 0 : boost::hash_combine(hash, attr.params_);
1308 0 : boost::hash_combine(hash, attr.source_rd_.ToString());
1309 0 : boost::hash_combine(hash, attr.esi_.ToString());
1310 :
1311 0 : if (attr.label_block_) {
1312 0 : boost::hash_combine(hash, attr.label_block_->first());
1313 0 : boost::hash_combine(hash, attr.label_block_->last());
1314 : }
1315 :
1316 0 : if (attr.olist_) {
1317 0 : boost::hash_range(hash, attr.olist_->elements().begin(),
1318 0 : attr.olist_->elements().end());
1319 : }
1320 0 : if (attr.leaf_olist_) {
1321 0 : boost::hash_range(hash, attr.leaf_olist_->elements().begin(),
1322 0 : attr.leaf_olist_->elements().end());
1323 : }
1324 :
1325 0 : if (attr.as_path_) boost::hash_combine(hash, *attr.as_path_);
1326 0 : if (attr.aspath_4byte_) boost::hash_combine(hash, *attr.aspath_4byte_);
1327 0 : if (attr.as4_path_) boost::hash_combine(hash, *attr.as4_path_);
1328 0 : if (attr.community_) boost::hash_combine(hash, *attr.community_);
1329 0 : if (attr.ext_community_) boost::hash_combine(hash, *attr.ext_community_);
1330 0 : if (attr.large_community_) boost::hash_combine(hash, *attr.large_community_);
1331 0 : if (attr.origin_vn_path_) boost::hash_combine(hash, *attr.origin_vn_path_);
1332 0 : if (!attr.sub_protocol_.empty()) {
1333 0 : boost::hash_combine(hash, attr.sub_protocol_);
1334 : }
1335 :
1336 0 : return hash;
1337 : }
1338 :
1339 9743 : BgpAttrDB::BgpAttrDB(BgpServer *server) : server_(server) {
1340 9743 : }
1341 :
1342 : // Return a clone of attribute with updated aspath.
1343 19267 : BgpAttrPtr BgpAttrDB::ReplaceAsPathAndLocate(const BgpAttr *attr,
1344 : AsPathPtr aspath) {
1345 19267 : BgpAttr *clone = new BgpAttr(*attr);
1346 19267 : clone->set_as_path(aspath);
1347 19267 : return Locate(clone);
1348 : }
1349 :
1350 : // Return a clone of attribute with updated community.
1351 19297 : BgpAttrPtr BgpAttrDB::ReplaceCommunityAndLocate(const BgpAttr *attr,
1352 : CommunityPtr community) {
1353 19297 : BgpAttr *clone = new BgpAttr(*attr);
1354 19297 : clone->set_community(community);
1355 19297 : return Locate(clone);
1356 : }
1357 :
1358 : //Return a clone of attribute with updated origin
1359 4 : BgpAttrPtr BgpAttrDB::ReplaceOriginAndLocate(const BgpAttr *attr,
1360 : BgpAttrOrigin::OriginType origin) {
1361 4 : BgpAttr *clone = new BgpAttr(*attr);
1362 4 : clone->set_origin(origin);
1363 4 : return Locate(clone);
1364 : }
1365 :
1366 : // Return a clone of attribute with updated extended community.
1367 1013641 : BgpAttrPtr BgpAttrDB::ReplaceExtCommunityAndLocate(const BgpAttr *attr,
1368 : ExtCommunityPtr extcomm) {
1369 1013641 : BgpAttr *clone = new BgpAttr(*attr);
1370 1013696 : clone->set_ext_community(extcomm);
1371 1013693 : return Locate(clone);
1372 : }
1373 :
1374 : // Return a clone of attribute with updated large community.
1375 18971 : BgpAttrPtr BgpAttrDB::ReplaceLargeCommunityAndLocate(
1376 : const BgpAttr *attr, LargeCommunityPtr largecomm) {
1377 18971 : BgpAttr *clone = new BgpAttr(*attr);
1378 18971 : clone->set_large_community(largecomm);
1379 18971 : return Locate(clone);
1380 : }
1381 :
1382 : // Return a clone of attribute with updated origin vn path.
1383 18972 : BgpAttrPtr BgpAttrDB::ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
1384 : OriginVnPathPtr ovnpath) {
1385 18972 : BgpAttr *clone = new BgpAttr(*attr);
1386 18972 : clone->set_origin_vn_path(ovnpath);
1387 18972 : return Locate(clone);
1388 : }
1389 :
1390 : // Return a clone of attribute with updated local preference.
1391 18 : BgpAttrPtr BgpAttrDB::ReplaceLocalPreferenceAndLocate(const BgpAttr *attr,
1392 : uint32_t local_pref) {
1393 18 : BgpAttr *clone = new BgpAttr(*attr);
1394 18 : clone->set_local_pref(local_pref);
1395 18 : return Locate(clone);
1396 : }
1397 :
1398 : // Return a clone of attribute with updated originator id.
1399 1 : BgpAttrPtr BgpAttrDB::ReplaceOriginatorIdAndLocate(const BgpAttr *attr,
1400 : Ip4Address originator_id) {
1401 1 : BgpAttr *clone = new BgpAttr(*attr);
1402 1 : clone->set_originator_id(originator_id);
1403 1 : return Locate(clone);
1404 : }
1405 :
1406 : // Return a clone of attribute with updated source rd.
1407 612744 : BgpAttrPtr BgpAttrDB::ReplaceSourceRdAndLocate(const BgpAttr *attr,
1408 : const RouteDistinguisher &source_rd) {
1409 612744 : BgpAttr *clone = new BgpAttr(*attr);
1410 612775 : clone->set_source_rd(source_rd);
1411 612761 : return Locate(clone);
1412 : }
1413 :
1414 : // Return a clone of attribute with updated esi.
1415 17817 : BgpAttrPtr BgpAttrDB::ReplaceEsiAndLocate(const BgpAttr *attr,
1416 : const EthernetSegmentId &esi) {
1417 17817 : BgpAttr *clone = new BgpAttr(*attr);
1418 17817 : clone->set_esi(esi);
1419 17817 : return Locate(clone);
1420 : }
1421 :
1422 : // Return a clone of attribute with updated olist.
1423 4756 : BgpAttrPtr BgpAttrDB::ReplaceOListAndLocate(const BgpAttr *attr,
1424 : const BgpOListSpec *olist_spec) {
1425 4756 : assert(olist_spec->subcode == BgpAttribute::OList);
1426 4756 : BgpAttr *clone = new BgpAttr(*attr);
1427 4756 : clone->set_olist(olist_spec);
1428 4756 : return Locate(clone);
1429 : }
1430 :
1431 : // Return a clone of attribute with updated leaf olist.
1432 4600 : BgpAttrPtr BgpAttrDB::ReplaceLeafOListAndLocate(const BgpAttr *attr,
1433 : const BgpOListSpec *leaf_olist_spec) {
1434 4600 : assert(leaf_olist_spec->subcode == BgpAttribute::LeafOList);
1435 4600 : BgpAttr *clone = new BgpAttr(*attr);
1436 4600 : clone->set_leaf_olist(leaf_olist_spec);
1437 4600 : return Locate(clone);
1438 : }
1439 :
1440 : // Return a clone of attribute with updated sub-protocol.
1441 2054 : BgpAttrPtr BgpAttrDB::ReplaceSubProtocolAndLocate(const BgpAttr *attr,
1442 : const string &sbp) {
1443 2054 : BgpAttr *clone = new BgpAttr(*attr);
1444 2054 : clone->set_sub_protocol(sbp);
1445 2054 : return Locate(clone);
1446 : }
1447 :
1448 :
1449 : // Return a clone of attribute with updated pmsi tunnel.
1450 8757 : BgpAttrPtr BgpAttrDB::ReplacePmsiTunnelAndLocate(const BgpAttr *attr,
1451 : const PmsiTunnelSpec *pmsi_spec) {
1452 8757 : BgpAttr *clone = new BgpAttr(*attr);
1453 8757 : clone->set_pmsi_tunnel(pmsi_spec);
1454 8757 : return Locate(clone);
1455 : }
1456 :
1457 : // Return a clone of attribute with updated nexthop.
1458 339467 : BgpAttrPtr BgpAttrDB::ReplaceNexthopAndLocate(const BgpAttr *attr,
1459 : const IpAddress &addr) {
1460 339467 : BgpAttr *clone = new BgpAttr(*attr);
1461 339476 : clone->set_nexthop(addr);
1462 339470 : return Locate(clone);
1463 : }
|