Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "bgp/bgp_attr.h"
6 :
7 : #include <algorithm>
8 : #include <string>
9 :
10 : #include "bgp/bgp_server.h"
11 : #include "bgp/extended-community/esi_label.h"
12 : #include "bgp/extended-community/etree.h"
13 : #include "bgp/extended-community/mac_mobility.h"
14 : #include "bgp/extended-community/router_mac.h"
15 : #include "net/bgp_af.h"
16 :
17 : using std::sort;
18 : using std::vector;
19 : using std::string;
20 :
21 9985 : int BgpAttrOrigin::CompareTo(const BgpAttribute &rhs_attr) const {
22 9985 : int ret = BgpAttribute::CompareTo(rhs_attr);
23 9985 : if (ret != 0) return ret;
24 9985 : KEY_COMPARE(origin, static_cast<const BgpAttrOrigin &>(rhs_attr).origin);
25 9985 : return 0;
26 : }
27 :
28 184306 : void BgpAttrOrigin::ToCanonical(BgpAttr *attr) {
29 184306 : attr->set_origin(static_cast<BgpAttrOrigin::OriginType>(origin));
30 184306 : }
31 :
32 111181 : string BgpAttrOrigin::ToString() const {
33 : char repr[80];
34 111181 : snprintf(repr, sizeof(repr), "ORIGIN <code: %d, flags: %02x> : %02x",
35 111181 : code, flags, origin);
36 111181 : return string(repr);
37 : }
38 :
39 9981 : int BgpAttrNextHop::CompareTo(const BgpAttribute &rhs_attr) const {
40 9981 : int ret = BgpAttribute::CompareTo(rhs_attr);
41 9981 : if (ret != 0) return ret;
42 9981 : KEY_COMPARE(nexthop,
43 : static_cast<const BgpAttrNextHop &>(rhs_attr).nexthop);
44 9981 : return 0;
45 : }
46 :
47 191200 : void BgpAttrNextHop::ToCanonical(BgpAttr *attr) {
48 191200 : if (v6_nexthop.is_unspecified()) {
49 188669 : attr->set_nexthop(Ip4Address(nexthop));
50 : } else {
51 2532 : attr->set_nexthop(v6_nexthop);
52 : }
53 191200 : }
54 :
55 3012 : string BgpAttrNextHop::ToString() const {
56 : char repr[80];
57 3012 : snprintf(repr, sizeof(repr), "NEXTHOP <code: %d, flags: %02x> : %04x",
58 3012 : code, flags, nexthop);
59 3012 : return string(repr);
60 : }
61 :
62 1988 : int BgpAttrMultiExitDisc::CompareTo(const BgpAttribute &rhs_attr) const {
63 1988 : int ret = BgpAttribute::CompareTo(rhs_attr);
64 1988 : if (ret != 0) return ret;
65 1988 : KEY_COMPARE(med, static_cast<const BgpAttrMultiExitDisc &>(rhs_attr).med);
66 1986 : return 0;
67 : }
68 76339 : void BgpAttrMultiExitDisc::ToCanonical(BgpAttr *attr) {
69 76339 : attr->set_med(med);
70 76339 : }
71 :
72 51518 : string BgpAttrMultiExitDisc::ToString() const {
73 : char repr[80];
74 51518 : snprintf(repr, sizeof(repr), "MED <code: %d, flags: %02x> : %d",
75 51518 : code, flags, med);
76 51518 : return string(repr);
77 : }
78 :
79 1994 : int BgpAttrLocalPref::CompareTo(const BgpAttribute &rhs_attr) const {
80 1994 : int ret = BgpAttribute::CompareTo(rhs_attr);
81 1994 : if (ret != 0) return ret;
82 1994 : KEY_COMPARE(local_pref,
83 : static_cast<const BgpAttrLocalPref &>(rhs_attr).local_pref);
84 1994 : return 0;
85 : }
86 92234 : void BgpAttrLocalPref::ToCanonical(BgpAttr *attr) {
87 92234 : attr->set_local_pref(local_pref);
88 92234 : }
89 :
90 24031 : string BgpAttrLocalPref::ToString() const {
91 : char repr[80];
92 24031 : snprintf(repr, sizeof(repr), "LOCAL_PREF <code: %d, flags: %02x> : %d",
93 24031 : code, flags, local_pref);
94 24031 : return string(repr);
95 : }
96 :
97 9 : void BgpAttrAtomicAggregate::ToCanonical(BgpAttr *attr) {
98 9 : attr->set_atomic_aggregate(true);
99 9 : }
100 :
101 1 : string BgpAttrAtomicAggregate::ToString() const {
102 : char repr[80];
103 1 : snprintf(repr, sizeof(repr), "ATOMIC_AGGR <code: %d, flags: %02x>",
104 1 : code, flags);
105 1 : return string(repr);
106 : }
107 :
108 3 : int BgpAttr4ByteAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
109 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
110 3 : if (ret != 0) return ret;
111 3 : KEY_COMPARE(as_num,
112 : static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).as_num);
113 3 : KEY_COMPARE(address,
114 : static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).address);
115 3 : return 0;
116 : }
117 1 : void BgpAttr4ByteAggregator::ToCanonical(BgpAttr *attr) {
118 1 : attr->set_aggregator(as_num, Ip4Address(address));
119 1 : }
120 :
121 0 : string BgpAttr4ByteAggregator::ToString() const {
122 : char repr[80];
123 0 : snprintf(repr, sizeof(repr),
124 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
125 0 : code, flags, as_num, address);
126 0 : return string(repr);
127 : }
128 :
129 1973 : int BgpAttrAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
130 1973 : int ret = BgpAttribute::CompareTo(rhs_attr);
131 1973 : if (ret != 0) return ret;
132 1973 : KEY_COMPARE(as_num,
133 : static_cast<const BgpAttrAggregator &>(rhs_attr).as_num);
134 1971 : KEY_COMPARE(address,
135 : static_cast<const BgpAttrAggregator &>(rhs_attr).address);
136 1969 : return 0;
137 : }
138 8 : void BgpAttrAggregator::ToCanonical(BgpAttr *attr) {
139 8 : attr->set_aggregator(as_num, Ip4Address(address));
140 8 : }
141 :
142 1 : string BgpAttrAggregator::ToString() const {
143 : char repr[80];
144 1 : snprintf(repr, sizeof(repr),
145 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
146 1 : code, flags, as_num, address);
147 1 : return string(repr);
148 : }
149 :
150 0 : int BgpAttrAs4Aggregator::CompareTo(const BgpAttribute &rhs_attr) const {
151 0 : int ret = BgpAttribute::CompareTo(rhs_attr);
152 0 : if (ret != 0) return ret;
153 0 : KEY_COMPARE(as_num,
154 : static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).as_num);
155 0 : KEY_COMPARE(address,
156 : static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).address);
157 0 : return 0;
158 : }
159 0 : void BgpAttrAs4Aggregator::ToCanonical(BgpAttr *attr) {
160 0 : attr->set_as4_aggregator(as_num, Ip4Address(address));
161 0 : }
162 :
163 0 : string BgpAttrAs4Aggregator::ToString() const {
164 : char repr[80];
165 0 : snprintf(repr, sizeof(repr),
166 : "Aggregator <code: %d, flags: %02x> : %d:%08x",
167 0 : code, flags, as_num, address);
168 0 : return string(repr);
169 : }
170 :
171 3 : int BgpAttrOriginatorId::CompareTo(const BgpAttribute &rhs_attr) const {
172 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
173 3 : if (ret != 0) return ret;
174 3 : KEY_COMPARE(originator_id,
175 : static_cast<const BgpAttrOriginatorId &>(rhs_attr).originator_id);
176 1 : return 0;
177 : }
178 :
179 18 : void BgpAttrOriginatorId::ToCanonical(BgpAttr *attr) {
180 18 : attr->set_originator_id(Ip4Address(originator_id));
181 18 : }
182 :
183 3 : string BgpAttrOriginatorId::ToString() const {
184 : char repr[80];
185 3 : snprintf(repr, sizeof(repr), "OriginatorId <code: %d, flags: 0x%02x> : %s",
186 6 : code, flags, Ip4Address(originator_id).to_string().c_str());
187 3 : return string(repr);
188 : }
189 :
190 9 : ClusterListSpec::ClusterListSpec(uint32_t cluster_id,
191 9 : const ClusterListSpec *rhs)
192 9 : : BgpAttribute(BgpAttribute::ClusterList, kFlags) {
193 9 : cluster_list.push_back(cluster_id);
194 9 : if (rhs) {
195 1 : cluster_list.insert(cluster_list.end(), rhs->cluster_list.begin(),
196 : rhs->cluster_list.end());
197 : }
198 9 : }
199 :
200 46 : int ClusterListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
201 46 : int ret = BgpAttribute::CompareTo(rhs_attr);
202 46 : if (ret != 0) return ret;
203 46 : KEY_COMPARE(cluster_list,
204 : static_cast<const ClusterListSpec &>(rhs_attr).cluster_list);
205 38 : return 0;
206 : }
207 :
208 8 : void ClusterListSpec::ToCanonical(BgpAttr *attr) {
209 8 : attr->set_cluster_list(this);
210 8 : }
211 :
212 3 : string ClusterListSpec::ToString() const {
213 3 : std::stringstream repr;
214 3 : repr << "CLUSTER_LIST <code: " << int(code);
215 3 : repr << ", flags: 0x" << std::hex << int(flags) << "> :";
216 3 : for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
217 9 : iter != cluster_list.end(); ++iter) {
218 6 : repr << " " << Ip4Address(*iter).to_string();
219 : }
220 6 : return repr.str();
221 3 : }
222 :
223 14 : bool ClusterListSpec::ClusterListLoop(uint32_t cluster_id) const {
224 14 : for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
225 56 : iter != cluster_list.end(); ++iter) {
226 47 : if (*iter == cluster_id)
227 5 : return true;
228 : }
229 9 : return false;
230 : }
231 :
232 22 : ClusterList::ClusterList(ClusterListDB *cluster_list_db,
233 22 : const ClusterListSpec &spec)
234 22 : : cluster_list_db_(cluster_list_db),
235 22 : spec_(spec) {
236 22 : refcount_ = 0;
237 22 : }
238 :
239 18 : void ClusterList::Remove() {
240 18 : cluster_list_db_->Delete(this);
241 18 : }
242 :
243 9743 : ClusterListDB::ClusterListDB(BgpServer *server) {
244 9743 : }
245 :
246 1990 : int BgpMpNlri::CompareTo(const BgpAttribute &rhs_attr) const {
247 1990 : int ret = BgpAttribute::CompareTo(rhs_attr);
248 1990 : if (ret != 0) return ret;
249 1990 : const BgpMpNlri &rhs = static_cast<const BgpMpNlri &>(rhs_attr);
250 1990 : KEY_COMPARE(afi, rhs.afi);
251 1990 : KEY_COMPARE(safi, rhs.safi);
252 1990 : KEY_COMPARE(nexthop, rhs.nexthop);
253 1990 : KEY_COMPARE(nlri.size(), rhs.nlri.size());
254 :
255 498340 : for (size_t i = 0; i < nlri.size(); i++) {
256 496350 : KEY_COMPARE(nlri[i]->type, rhs.nlri[i]->type);
257 496350 : KEY_COMPARE(nlri[i]->prefixlen, rhs.nlri[i]->prefixlen);
258 496350 : KEY_COMPARE(nlri[i]->prefix, rhs.nlri[i]->prefix);
259 : }
260 1990 : return 0;
261 : }
262 :
263 157947 : void BgpMpNlri::ToCanonical(BgpAttr *attr) {
264 157947 : }
265 :
266 507216 : size_t BgpMpNlri::EncodeLength() const {
267 507216 : size_t sz = 2 /* safi */ + 1 /* afi */ +
268 : 1 /* NlriNextHopLength */ +
269 : 1 /* Reserved */;
270 507216 : sz += nexthop.size();
271 507219 : for (vector<BgpProtoPrefix*>::const_iterator iter = nlri.begin();
272 2858420 : iter != nlri.end(); ++iter) {
273 2351214 : size_t bytes = 0;
274 2351214 : if (afi == BgpAf::L2Vpn &&
275 39794 : (safi == BgpAf::EVpn || safi == BgpAf::ErmVpn)) {
276 39794 : bytes = (*iter)->prefixlen;
277 : } else {
278 2311420 : bytes = ((*iter)->prefixlen + 7) / 8;
279 : }
280 2351218 : sz += 1 + bytes;
281 : }
282 507183 : return sz;
283 : }
284 :
285 25394 : PmsiTunnelSpec::PmsiTunnelSpec()
286 : : BgpAttribute(PmsiTunnel, kFlags),
287 25394 : tunnel_flags(0), tunnel_type(0), label(0) {
288 25393 : }
289 :
290 3008 : PmsiTunnelSpec::PmsiTunnelSpec(const BgpAttribute &rhs)
291 3008 : : BgpAttribute(rhs), tunnel_flags(0), tunnel_type(0), label(0) {
292 3008 : }
293 :
294 473569 : int PmsiTunnelSpec::CompareTo(const BgpAttribute &rhs_attr) const {
295 473569 : int ret = BgpAttribute::CompareTo(rhs_attr);
296 473569 : if (ret != 0) return ret;
297 473569 : const PmsiTunnelSpec &rhs = static_cast<const PmsiTunnelSpec &>(rhs_attr);
298 473569 : KEY_COMPARE(tunnel_flags, rhs.tunnel_flags);
299 461940 : KEY_COMPARE(tunnel_type, rhs.tunnel_type);
300 461933 : KEY_COMPARE(label, rhs.label);
301 438005 : KEY_COMPARE(identifier, rhs.identifier);
302 435287 : return 0;
303 : }
304 :
305 8134 : void PmsiTunnelSpec::ToCanonical(BgpAttr *attr) {
306 8134 : attr->set_pmsi_tunnel(this);
307 8134 : }
308 :
309 840 : string PmsiTunnelSpec::ToString() const {
310 840 : std::ostringstream oss;
311 840 : oss << "PmsiTunnel <code: " << int(code);
312 840 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
313 840 : oss << " Tunnel Flags: 0x" << std::hex << int(tunnel_flags) << std::dec;
314 840 : oss << " Tunnel Type: " << int(tunnel_type);
315 840 : oss << " Label: 0x" << std::hex << int(label) << std::dec;
316 840 : oss << " (" << int(label) << ")";
317 840 : oss << " Identifier: " << GetIdentifier().to_string();
318 :
319 1680 : return oss.str();
320 840 : }
321 :
322 2 : uint32_t PmsiTunnelSpec::GetLabel(const ExtCommunity *ext) const {
323 2 : assert(ext);
324 2 : bool is_vni = ext->ContainsTunnelEncapVxlan();
325 2 : return (is_vni ? label : (label >> 4));
326 : }
327 :
328 7749 : void PmsiTunnelSpec::SetLabel(uint32_t in_label, const ExtCommunity *ext) {
329 7749 : assert(ext);
330 7749 : bool is_vni = ext->ContainsTunnelEncapVxlan();
331 7749 : label = (is_vni ? in_label : (in_label << 4 | 0x01));
332 7749 : }
333 :
334 18768 : Ip4Address PmsiTunnelSpec::GetIdentifier() const {
335 18768 : if (identifier.size() < 4)
336 9826 : return Ip4Address();
337 8942 : return Ip4Address(get_value(&identifier[0], 4));
338 : }
339 :
340 11692 : void PmsiTunnelSpec::SetIdentifier(Ip4Address in_identifier) {
341 11692 : identifier.resize(4, 0);
342 11692 : const Ip4Address::bytes_type &bytes = in_identifier.to_bytes();
343 11692 : std::copy(bytes.begin(), bytes.begin() + 4, identifier.begin());
344 11692 : }
345 :
346 9 : string PmsiTunnelSpec::GetTunnelTypeString() const {
347 9 : switch (tunnel_type) {
348 1 : case RsvpP2mpLsp:
349 1 : return "RsvpP2mpLsp";
350 1 : case LdpP2mpLsp:
351 1 : return "LdpP2mpLsp";
352 1 : case PimSsmTree:
353 1 : return "PimSsmTree";
354 1 : case PimSmTree:
355 1 : return "PimSmTree";
356 1 : case BidirPimTree:
357 1 : return "BidirPimTree";
358 1 : case IngressReplication:
359 1 : return "IngressReplication";
360 1 : case MldpMp2mpLsp:
361 1 : return "MldpMp2mpLsp";
362 1 : case AssistedReplicationContrail:
363 1 : return "AssistedReplication";
364 1 : default:
365 1 : break;
366 : }
367 2 : std::ostringstream oss;
368 1 : oss << "Unknown(" << int(tunnel_type) << ")";
369 1 : return oss.str();
370 : }
371 :
372 4 : string PmsiTunnelSpec::GetTunnelArTypeString() const {
373 4 : switch (tunnel_flags & AssistedReplicationType) {
374 1 : case RegularNVE:
375 1 : return "RegularNVE";
376 1 : case ARReplicator:
377 1 : return "ARReplicator";
378 1 : case ARLeaf:
379 1 : return "ARLeaf";
380 1 : default:
381 1 : break;
382 : }
383 1 : return "Unknown";
384 : }
385 :
386 4 : vector<string> PmsiTunnelSpec::GetTunnelFlagsStrings() const {
387 4 : vector<string> flags;
388 4 : if (tunnel_flags & LeafInfoRequired) {
389 2 : flags.push_back("LeafInfoRequired");
390 : }
391 4 : if (tunnel_flags & EdgeReplicationSupported) {
392 2 : flags.push_back("EdgeReplicationSupported");
393 : }
394 4 : if (flags.empty()) {
395 1 : flags.push_back("None");
396 : }
397 4 : return flags;
398 0 : }
399 :
400 17926 : PmsiTunnel::PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db,
401 17926 : const PmsiTunnelSpec &pmsi_spec)
402 17926 : : pmsi_tunnel_db_(pmsi_tunnel_db),
403 17926 : pmsi_spec_(pmsi_spec) {
404 17924 : refcount_ = 0;
405 17926 : tunnel_flags_ = pmsi_spec_.tunnel_flags;
406 17926 : tunnel_type_ = pmsi_spec_.tunnel_type;
407 17926 : label_ = pmsi_spec_.label;
408 17926 : identifier_ = pmsi_spec_.GetIdentifier();
409 17925 : }
410 :
411 4981 : void PmsiTunnel::Remove() {
412 4981 : pmsi_tunnel_db_->Delete(this);
413 4981 : }
414 :
415 2597 : uint32_t PmsiTunnel::GetLabel(const ExtCommunity *ext) const {
416 2597 : bool is_vni = false;
417 2597 : if (ext)
418 2585 : is_vni = ext->ContainsTunnelEncapVxlan();
419 2597 : return (is_vni ? label_ : label_ >> 4);
420 : }
421 :
422 9743 : PmsiTunnelDB::PmsiTunnelDB(BgpServer *server) {
423 9743 : }
424 :
425 5911 : EdgeDiscoverySpec::EdgeDiscoverySpec()
426 5911 : : BgpAttribute(McastEdgeDiscovery, kFlags) {
427 5911 : }
428 :
429 3815 : EdgeDiscoverySpec::EdgeDiscoverySpec(const BgpAttribute &rhs)
430 3815 : : BgpAttribute(rhs) {
431 3815 : }
432 :
433 4161 : EdgeDiscoverySpec::EdgeDiscoverySpec(const EdgeDiscoverySpec &rhs)
434 4161 : : BgpAttribute(BgpAttribute::McastEdgeDiscovery, kFlags) {
435 13561 : for (size_t i = 0; i < rhs.edge_list.size(); i++) {
436 9401 : Edge *edge = new Edge;
437 9401 : *edge = *rhs.edge_list[i];
438 9401 : edge_list.push_back(edge);
439 : }
440 4160 : }
441 :
442 22736 : EdgeDiscoverySpec::~EdgeDiscoverySpec() {
443 13882 : STLDeleteValues(&edge_list);
444 22715 : }
445 :
446 9912 : Ip4Address EdgeDiscoverySpec::Edge::GetIp4Address() const {
447 9912 : return Ip4Address(get_value(&address[0], 4));
448 : }
449 :
450 130457 : void EdgeDiscoverySpec::Edge::SetIp4Address(Ip4Address addr) {
451 130457 : address.resize(4, 0);
452 130457 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
453 130457 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4, address.begin());
454 130457 : }
455 :
456 9912 : void EdgeDiscoverySpec::Edge::GetLabels(
457 : uint32_t *first_label, uint32_t *last_label) const {
458 9912 : *first_label = labels[0];
459 9912 : *last_label = labels[1];
460 9912 : }
461 :
462 130457 : void EdgeDiscoverySpec::Edge::SetLabels(
463 : uint32_t first_label, uint32_t last_label) {
464 130457 : labels.push_back(first_label);
465 130457 : labels.push_back(last_label);
466 130457 : }
467 :
468 : struct EdgeDiscoverySpecEdgeCompare {
469 63710 : int operator()(const EdgeDiscoverySpec::Edge *lhs,
470 : const EdgeDiscoverySpec::Edge *rhs) const {
471 63710 : KEY_COMPARE(lhs->address, rhs->address);
472 63710 : KEY_COMPARE(lhs->labels, rhs->labels);
473 63710 : return 0;
474 : }
475 : };
476 :
477 2003 : int EdgeDiscoverySpec::CompareTo(const BgpAttribute &rhs_attr) const {
478 2003 : int ret = BgpAttribute::CompareTo(rhs_attr);
479 2003 : if (ret != 0) return ret;
480 2003 : const EdgeDiscoverySpec &rhs =
481 : static_cast<const EdgeDiscoverySpec &>(rhs_attr);
482 2003 : ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
483 : rhs.edge_list.begin(), rhs.edge_list.end(),
484 : EdgeDiscoverySpecEdgeCompare());
485 2003 : return ret;
486 : }
487 :
488 2082 : void EdgeDiscoverySpec::ToCanonical(BgpAttr *attr) {
489 2082 : attr->set_edge_discovery(this);
490 2082 : }
491 :
492 1208 : string EdgeDiscoverySpec::ToString() const {
493 1208 : std::ostringstream oss;
494 1208 : oss << "EdgeDiscovery <code: " << int(code);
495 1208 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
496 1208 : int idx = 0;
497 1208 : for (EdgeList::const_iterator it = edge_list.begin();
498 4828 : it != edge_list.end(); ++it, ++idx) {
499 3620 : const Edge *edge = *it;
500 : uint32_t first_label, last_label;
501 3620 : edge->GetLabels(&first_label, &last_label);
502 3620 : oss << " Edge[" << idx << "] = (" << edge->GetIp4Address() << ", ";
503 3620 : oss << first_label << "-" << last_label << ")";
504 : }
505 :
506 2416 : return oss.str();
507 1208 : }
508 :
509 13923 : size_t EdgeDiscoverySpec::EncodeLength() const {
510 13923 : size_t sz = 0;
511 13923 : for (EdgeList::const_iterator iter = edge_list.begin();
512 276650 : iter != edge_list.end(); ++iter) {
513 262727 : sz += 2; /* AddressLen + LabelLen */
514 262727 : sz += (*iter)->address.size();
515 262727 : sz += (*iter)->labels.size() * sizeof(uint32_t);
516 : }
517 13923 : return sz;
518 : }
519 :
520 6264 : EdgeDiscovery::Edge::Edge(const EdgeDiscoverySpec::Edge *spec_edge) {
521 6264 : address = spec_edge->GetIp4Address();
522 : uint32_t first_label, last_label;
523 6264 : spec_edge->GetLabels(&first_label, &last_label);
524 6264 : label_block = new LabelBlock(first_label, last_label);
525 6264 : }
526 :
527 54256 : bool EdgeDiscovery::Edge::operator<(const Edge &rhs) const {
528 54256 : BOOL_KEY_COMPARE(address, rhs.address);
529 47288 : BOOL_KEY_COMPARE(label_block->first(), rhs.label_block->first());
530 41711 : BOOL_KEY_COMPARE(label_block->last(), rhs.label_block->last());
531 41711 : return false;
532 : }
533 :
534 3116 : EdgeDiscovery::EdgeDiscovery(EdgeDiscoveryDB *edge_discovery_db,
535 3116 : const EdgeDiscoverySpec &edspec)
536 3116 : : edge_discovery_db_(edge_discovery_db),
537 3116 : edspec_(edspec) {
538 3114 : refcount_ = 0;
539 3115 : for (EdgeDiscoverySpec::EdgeList::const_iterator it =
540 9378 : edspec_.edge_list.begin(); it != edspec_.edge_list.end(); ++it) {
541 6263 : Edge *edge = new Edge(*it);
542 6264 : edge_list.push_back(edge);
543 : }
544 3112 : sort(edge_list.begin(), edge_list.end(), EdgeDiscovery::EdgeCompare());
545 3113 : }
546 :
547 5210 : EdgeDiscovery::~EdgeDiscovery() {
548 3117 : STLDeleteValues(&edge_list);
549 5210 : }
550 :
551 : struct EdgeDiscoveryEdgeCompare {
552 21464 : int operator()(const EdgeDiscovery::Edge *lhs,
553 : const EdgeDiscovery::Edge *rhs) const {
554 21464 : KEY_COMPARE(*lhs, *rhs);
555 12544 : return 0;
556 : }
557 : };
558 :
559 363788 : int EdgeDiscovery::CompareTo(const EdgeDiscovery &rhs) const {
560 363788 : int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
561 : rhs.edge_list.begin(), rhs.edge_list.end(),
562 : EdgeDiscoveryEdgeCompare());
563 363789 : return result;
564 : }
565 :
566 1823 : void EdgeDiscovery::Remove() {
567 1823 : edge_discovery_db_->Delete(this);
568 1823 : }
569 :
570 9743 : EdgeDiscoveryDB::EdgeDiscoveryDB(BgpServer *server) {
571 9743 : }
572 :
573 6396 : EdgeForwardingSpec::EdgeForwardingSpec()
574 6396 : : BgpAttribute(McastEdgeForwarding, kFlags) {
575 6395 : }
576 :
577 4647 : EdgeForwardingSpec::EdgeForwardingSpec(const BgpAttribute &rhs)
578 4647 : : BgpAttribute(rhs) {
579 4647 : }
580 :
581 6292 : EdgeForwardingSpec::EdgeForwardingSpec(const EdgeForwardingSpec &rhs)
582 6292 : : BgpAttribute(BgpAttribute::McastEdgeForwarding, kFlags) {
583 11512 : for (size_t i = 0; i < rhs.edge_list.size(); i++) {
584 5222 : Edge *edge = new Edge;
585 5222 : *edge = *rhs.edge_list[i];
586 5222 : edge_list.push_back(edge);
587 : }
588 6290 : }
589 :
590 27745 : EdgeForwardingSpec:: ~EdgeForwardingSpec() {
591 17320 : STLDeleteValues(&edge_list);
592 27716 : }
593 :
594 5588 : Ip4Address EdgeForwardingSpec::Edge::GetInboundIp4Address() const {
595 5588 : return Ip4Address(get_value(&inbound_address[0], 4));
596 : }
597 :
598 5588 : Ip4Address EdgeForwardingSpec::Edge::GetOutboundIp4Address() const {
599 5588 : return Ip4Address(get_value(&outbound_address[0], 4));
600 : }
601 :
602 126191 : void EdgeForwardingSpec::Edge::SetInboundIp4Address(Ip4Address addr) {
603 126191 : inbound_address.resize(4, 0);
604 126191 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
605 126191 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
606 : inbound_address.begin());
607 126191 : }
608 :
609 126191 : void EdgeForwardingSpec::Edge::SetOutboundIp4Address(Ip4Address addr) {
610 126191 : outbound_address.resize(4, 0);
611 126191 : const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
612 126191 : std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
613 : outbound_address.begin());
614 126191 : }
615 :
616 : struct EdgeForwardingSpecEdgeCompare {
617 59919 : int operator()(const EdgeForwardingSpec::Edge *lhs,
618 : const EdgeForwardingSpec::Edge *rhs) const {
619 59919 : KEY_COMPARE(lhs->inbound_address, rhs->inbound_address);
620 59919 : KEY_COMPARE(lhs->outbound_address, rhs->outbound_address);
621 59919 : KEY_COMPARE(lhs->inbound_label, rhs->inbound_label);
622 59919 : KEY_COMPARE(lhs->outbound_label, rhs->outbound_label);
623 59919 : return 0;
624 : }
625 : };
626 :
627 1898 : int EdgeForwardingSpec::CompareTo(const BgpAttribute &rhs_attr) const {
628 1898 : int ret = BgpAttribute::CompareTo(rhs_attr);
629 1898 : if (ret != 0) return ret;
630 1898 : const EdgeForwardingSpec &rhs =
631 : static_cast<const EdgeForwardingSpec &>(rhs_attr);
632 1898 : ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
633 : rhs.edge_list.begin(), rhs.edge_list.end(),
634 : EdgeForwardingSpecEdgeCompare());
635 1898 : return ret;
636 : }
637 :
638 3464 : void EdgeForwardingSpec::ToCanonical(BgpAttr *attr) {
639 3464 : attr->set_edge_forwarding(this);
640 3464 : }
641 :
642 2096 : string EdgeForwardingSpec::ToString() const {
643 2096 : std::ostringstream oss;
644 2096 : oss << "EdgeForwarding <code: " << int(code);
645 2096 : oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
646 2096 : int idx = 0;
647 2096 : for (EdgeList::const_iterator it = edge_list.begin();
648 4375 : it != edge_list.end(); ++it, ++idx) {
649 2279 : const Edge *edge = *it;
650 2279 : oss << " Edge[" << idx << "] = (";
651 2279 : oss << "InAddress=" << edge->GetInboundIp4Address() << ", ";
652 2279 : oss << "InLabel=" << edge->inbound_label << ", ";
653 2279 : oss << "OutAddress=" << edge->GetOutboundIp4Address() << ", ";
654 2279 : oss << "OutLabel=" << edge->outbound_label << ")";
655 : }
656 :
657 4192 : return oss.str();
658 2096 : }
659 :
660 16231 : size_t EdgeForwardingSpec::EncodeLength() const {
661 16231 : size_t sz = 0;
662 16231 : for (EdgeList::const_iterator iter = edge_list.begin();
663 271384 : iter != edge_list.end(); ++iter) {
664 255153 : sz += 1 /* address len */ + 8 /* 2 labels */;
665 255153 : sz += (*iter)->inbound_address.size();
666 255153 : sz += (*iter)->outbound_address.size();
667 : }
668 :
669 16231 : return sz;
670 : }
671 :
672 3305 : EdgeForwarding::Edge::Edge(const EdgeForwardingSpec::Edge *spec_edge) {
673 3305 : inbound_address = spec_edge->GetInboundIp4Address();
674 3305 : outbound_address = spec_edge->GetOutboundIp4Address();
675 3305 : inbound_label = spec_edge->inbound_label;
676 3305 : outbound_label = spec_edge->outbound_label;
677 3305 : }
678 :
679 33500 : bool EdgeForwarding::Edge::operator<(const Edge &rhs) const {
680 33500 : BOOL_KEY_COMPARE(inbound_address, rhs.inbound_address);
681 23451 : BOOL_KEY_COMPARE(outbound_address, rhs.outbound_address);
682 18678 : BOOL_KEY_COMPARE(inbound_label, rhs.inbound_label);
683 16507 : BOOL_KEY_COMPARE(outbound_label, rhs.outbound_label);
684 14113 : return false;
685 : }
686 :
687 4499 : EdgeForwarding::EdgeForwarding(EdgeForwardingDB *edge_forwarding_db,
688 4499 : const EdgeForwardingSpec &efspec)
689 4498 : : edge_forwarding_db_(edge_forwarding_db),
690 4499 : efspec_(efspec) {
691 4495 : refcount_ = 0;
692 4499 : for (EdgeForwardingSpec::EdgeList::const_iterator it =
693 7804 : efspec_.edge_list.begin(); it != efspec_.edge_list.end(); ++it) {
694 3305 : Edge *edge = new Edge(*it);
695 3305 : edge_list.push_back(edge);
696 : }
697 4494 : sort(edge_list.begin(), edge_list.end(), EdgeForwarding::EdgeCompare());
698 4493 : }
699 :
700 7976 : EdgeForwarding::~EdgeForwarding() {
701 4500 : STLDeleteValues(&edge_list);
702 7976 : }
703 :
704 : struct EdgeForwardingEdgeCompare {
705 19047 : int operator()(const EdgeForwarding::Edge *lhs,
706 : const EdgeForwarding::Edge *rhs) const {
707 19047 : KEY_COMPARE(*lhs, *rhs);
708 7057 : return 0;
709 : }
710 : };
711 :
712 1319548 : int EdgeForwarding::CompareTo(const EdgeForwarding &rhs) const {
713 1319548 : int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
714 : rhs.edge_list.begin(), rhs.edge_list.end(),
715 : EdgeForwardingEdgeCompare());
716 1319547 : return result;
717 : }
718 :
719 2348 : void EdgeForwarding::Remove() {
720 2348 : edge_forwarding_db_->Delete(this);
721 2348 : }
722 :
723 9743 : EdgeForwardingDB::EdgeForwardingDB(BgpServer *server) {
724 9743 : }
725 :
726 196057 : bool BgpOListElem::operator<(const BgpOListElem &rhs) const {
727 196057 : BOOL_KEY_COMPARE(address, rhs.address);
728 128971 : BOOL_KEY_COMPARE(label, rhs.label);
729 124920 : BOOL_KEY_COMPARE(encap, rhs.encap);
730 124914 : return false;
731 : }
732 :
733 3 : int BgpOListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
734 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
735 3 : if (ret != 0) return ret;
736 3 : return 0;
737 : }
738 :
739 3604 : void BgpOListSpec::ToCanonical(BgpAttr *attr) {
740 3604 : if (subcode == BgpAttribute::OList) {
741 3604 : attr->set_olist(this);
742 0 : } else if (subcode == BgpAttribute::LeafOList) {
743 0 : attr->set_leaf_olist(this);
744 : } else {
745 0 : assert(false);
746 : }
747 3604 : }
748 :
749 1 : string BgpOListSpec::ToString() const {
750 1 : std::ostringstream oss;
751 1 : oss << "OList <subcode: " << int(subcode) << ">";
752 1 : int idx = 0;
753 1 : for (Elements::const_iterator it = elements.begin();
754 3 : it != elements.end(); ++it, ++idx) {
755 2 : BgpOListElem elem(*it);
756 2 : oss << "OList[" << idx << "] = (";
757 2 : oss << "address: " << elem.address << ", ";
758 2 : oss << "label: " << elem.label << ", ";
759 2 : oss << "encap-list:";
760 2 : int eid = 0;
761 2 : for (vector<string>::const_iterator e_it = elem.encap.begin();
762 6 : e_it != elem.encap.end(); ++e_it, ++eid) {
763 4 : oss << " " << *e_it;
764 : }
765 2 : oss << ")";
766 2 : }
767 2 : return (oss.str());
768 1 : }
769 :
770 13905 : BgpOList::BgpOList(BgpOListDB *olist_db, const BgpOListSpec &olist_spec)
771 13905 : : olist_db_(olist_db),
772 13905 : olist_spec_(olist_spec) {
773 13905 : refcount_ = 0;
774 13905 : for (BgpOListSpec::Elements::const_iterator it =
775 36711 : olist_spec_.elements.begin(); it != olist_spec_.elements.end(); ++it) {
776 22806 : BgpOListElem *elem = new BgpOListElem(*it);
777 22806 : sort(elem->encap.begin(), elem->encap.end());
778 22806 : elements_.push_back(elem);
779 : }
780 13905 : sort(elements_.begin(), elements_.end(), BgpOListElemCompare());
781 13904 : }
782 :
783 26786 : BgpOList::~BgpOList() {
784 13905 : STLDeleteValues(&elements_);
785 26786 : }
786 :
787 : struct BgpOListElementCompare {
788 76726 : int operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const {
789 76726 : KEY_COMPARE(*lhs, *rhs);
790 62457 : return 0;
791 : }
792 : };
793 :
794 1123216 : int BgpOList::CompareTo(const BgpOList &rhs) const {
795 1123216 : KEY_COMPARE(olist().subcode, rhs.olist().subcode);
796 2216864 : int result = STLSortedCompare(elements().begin(), elements().end(),
797 2216864 : rhs.elements().begin(), rhs.elements().end(),
798 : BgpOListElementCompare());
799 1108432 : return result;
800 : }
801 :
802 9642 : void BgpOList::Remove() {
803 9642 : olist_db_->Delete(this);
804 9642 : }
805 :
806 9743 : BgpOListDB::BgpOListDB(BgpServer *server) {
807 9743 : }
808 :
809 0 : int BgpAttrLabelBlock::CompareTo(const BgpAttribute &rhs_attr) const {
810 0 : int ret = BgpAttribute::CompareTo(rhs_attr);
811 0 : if (ret != 0) return ret;
812 0 : KEY_COMPARE(label_block.get(),
813 : static_cast<const BgpAttrLabelBlock &>(rhs_attr).label_block.get());
814 0 : return 0;
815 : }
816 :
817 1033 : void BgpAttrLabelBlock::ToCanonical(BgpAttr *attr) {
818 1033 : attr->set_label_block(label_block);
819 1033 : }
820 :
821 0 : string BgpAttrLabelBlock::ToString() const {
822 : char repr[80];
823 0 : snprintf(repr, sizeof(repr), "LabelBlock <subcode: %d> : %d-%d",
824 0 : subcode, label_block->first(), label_block->last());
825 0 : return string(repr);
826 : }
827 :
828 3 : int BgpAttrSourceRd::CompareTo(const BgpAttribute &rhs_attr) const {
829 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
830 3 : if (ret != 0) return ret;
831 3 : KEY_COMPARE(source_rd,
832 : static_cast<const BgpAttrSourceRd &>(rhs_attr).source_rd);
833 1 : return 0;
834 : }
835 :
836 28626 : void BgpAttrSourceRd::ToCanonical(BgpAttr *attr) {
837 28626 : attr->set_source_rd(source_rd);
838 28626 : }
839 :
840 1 : string BgpAttrSourceRd::ToString() const {
841 : char repr[80];
842 1 : snprintf(repr, sizeof(repr), "SourceRd <subcode: %d> : %s",
843 2 : subcode, source_rd.ToString().c_str());
844 1 : return string(repr);
845 : }
846 :
847 3 : int BgpAttrEsi::CompareTo(const BgpAttribute &rhs_attr) const {
848 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
849 3 : if (ret != 0) return ret;
850 3 : KEY_COMPARE(esi, static_cast<const BgpAttrEsi &>(rhs_attr).esi);
851 1 : return 0;
852 : }
853 :
854 59 : void BgpAttrEsi::ToCanonical(BgpAttr *attr) {
855 59 : attr->set_esi(esi);
856 59 : }
857 :
858 1 : string BgpAttrEsi::ToString() const {
859 : char repr[80];
860 1 : snprintf(repr, sizeof(repr), "Esi <subcode: %d> : %s",
861 2 : subcode, esi.ToString().c_str());
862 1 : return string(repr);
863 : }
864 :
865 3 : int BgpAttrParams::CompareTo(const BgpAttribute &rhs_attr) const {
866 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
867 3 : if (ret != 0) return ret;
868 3 : KEY_COMPARE(params, static_cast<const BgpAttrParams &>(rhs_attr).params);
869 1 : return 0;
870 : }
871 :
872 3 : void BgpAttrParams::ToCanonical(BgpAttr *attr) {
873 3 : attr->set_params(params);
874 3 : }
875 :
876 1 : string BgpAttrParams::ToString() const {
877 : char repr[80];
878 1 : snprintf(repr, sizeof(repr), "Params <subcode: %d> : 0x%016jx",
879 1 : subcode, params);
880 1 : return string(repr);
881 : }
882 :
883 3 : int BgpAttrSubProtocol::CompareTo(const BgpAttribute &rhs_attr) const {
884 3 : int ret = BgpAttribute::CompareTo(rhs_attr);
885 3 : if (ret != 0) return ret;
886 3 : KEY_COMPARE(sbp, static_cast<const BgpAttrSubProtocol &>(rhs_attr).sbp);
887 1 : return 0;
888 : }
889 :
890 21982 : void BgpAttrSubProtocol::ToCanonical(BgpAttr *attr) {
891 21982 : attr->set_sub_protocol(sbp);
892 21982 : }
893 :
894 1 : string BgpAttrSubProtocol::ToString() const {
895 : char repr[80];
896 1 : snprintf(repr, sizeof(repr), "SubProtocol <subcode: %d> : %s",
897 1 : subcode, sbp.c_str());
898 1 : return string(repr);
899 : }
900 :
901 38 : BgpAttr::BgpAttr()
902 38 : : attr_db_(NULL), origin_(BgpAttrOrigin::INCOMPLETE), nexthop_(),
903 38 : med_(0), local_pref_(0), atomic_aggregate_(false),
904 38 : aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
905 38 : refcount_ = 0;
906 38 : }
907 :
908 5953 : BgpAttr::BgpAttr(BgpAttrDB *attr_db)
909 5953 : : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
910 11906 : nexthop_(), med_(0), local_pref_(0), atomic_aggregate_(false),
911 5953 : aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
912 5953 : refcount_ = 0;
913 5953 : }
914 :
915 388747 : BgpAttr::BgpAttr(BgpAttrDB *attr_db, const BgpAttrSpec &spec)
916 388747 : : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
917 777493 : nexthop_(), med_(0),
918 388746 : local_pref_(BgpAttrLocalPref::kDefault),
919 388746 : atomic_aggregate_(false),
920 388746 : aggregator_as_num_(0), aggregator_as4_num_(0),
921 388747 : aggregator_address_(), params_(0) {
922 388741 : refcount_ = 0;
923 388750 : for (vector<BgpAttribute *>::const_iterator it = spec.begin();
924 1465579 : it < spec.end(); it++) {
925 1076846 : (*it)->ToCanonical(this);
926 : }
927 388742 : }
928 :
929 3025164 : BgpAttr::BgpAttr(const BgpAttr &rhs)
930 3025164 : : attr_db_(rhs.attr_db_), origin_(rhs.origin_), nexthop_(rhs.nexthop_),
931 3024804 : med_(rhs.med_), local_pref_(rhs.local_pref_),
932 3024804 : atomic_aggregate_(rhs.atomic_aggregate_),
933 3024804 : aggregator_as_num_(rhs.aggregator_as_num_),
934 3024804 : aggregator_as4_num_(rhs.aggregator_as4_num_),
935 3024804 : aggregator_address_(rhs.aggregator_address_),
936 3024624 : originator_id_(rhs.originator_id_),
937 3024544 : source_rd_(rhs.source_rd_), esi_(rhs.esi_), params_(rhs.params_),
938 3024454 : as_path_(rhs.as_path_),
939 3025161 : aspath_4byte_(rhs.aspath_4byte_),
940 3025055 : as4_path_(rhs.as4_path_),
941 3024869 : cluster_list_(rhs.cluster_list_),
942 3024775 : community_(rhs.community_),
943 3024704 : ext_community_(rhs.ext_community_),
944 3025691 : large_community_(rhs.large_community_),
945 3025257 : deferred_large_spec_(nullptr),
946 3024571 : origin_vn_path_(rhs.origin_vn_path_),
947 3024492 : pmsi_tunnel_(rhs.pmsi_tunnel_),
948 3024363 : edge_discovery_(rhs.edge_discovery_),
949 3024224 : edge_forwarding_(rhs.edge_forwarding_),
950 3024142 : label_block_(rhs.label_block_),
951 3024083 : olist_(rhs.olist_),
952 3023978 : leaf_olist_(rhs.leaf_olist_),
953 6049068 : sub_protocol_(rhs.sub_protocol_) {
954 3023663 : refcount_ = 0;
955 3025774 : }
956 :
957 19101 : void BgpAttr::set_as_path(AsPathPtr aspath) {
958 19101 : as_path_ = aspath;
959 19101 : }
960 :
961 362266 : void BgpAttr::set_as_path(const AsPathSpec *spec) {
962 362266 : if (spec) {
963 362134 : as_path_ = attr_db_->server()->aspath_db()->Locate(*spec);
964 : } else {
965 132 : as_path_ = NULL;
966 : }
967 362316 : }
968 :
969 0 : void BgpAttr::set_as4_path(As4PathPtr aspath) {
970 0 : as4_path_ = aspath;
971 0 : }
972 :
973 484 : void BgpAttr::set_as4_path(const As4PathSpec *spec) {
974 484 : if (spec) {
975 450 : as4_path_ = attr_db_->server()->as4path_db()->Locate(*spec);
976 : } else {
977 34 : as4_path_ = NULL;
978 : }
979 484 : }
980 :
981 0 : void BgpAttr::set_aspath_4byte(AsPath4BytePtr aspath) {
982 0 : aspath_4byte_ = aspath;
983 0 : }
984 :
985 536 : void BgpAttr::set_aspath_4byte(const AsPath4ByteSpec *spec) {
986 536 : if (spec) {
987 479 : aspath_4byte_ = attr_db_->server()->aspath_4byte_db()->Locate(*spec);
988 : } else {
989 57 : aspath_4byte_ = NULL;
990 : }
991 536 : }
992 :
993 203549 : void BgpAttr::set_cluster_list(const ClusterListSpec *spec) {
994 203549 : if (spec) {
995 18 : cluster_list_ = attr_db_->server()->cluster_list_db()->Locate(*spec);
996 : } else {
997 203531 : cluster_list_ = NULL;
998 : }
999 203545 : }
1000 :
1001 25228 : void BgpAttr::set_community(CommunityPtr comm) {
1002 25228 : community_ = comm;
1003 25228 : }
1004 :
1005 4363 : void BgpAttr::set_community(const CommunitySpec *comm) {
1006 4363 : if (comm) {
1007 4363 : community_ = attr_db_->server()->comm_db()->Locate(*comm);
1008 : } else {
1009 0 : community_ = NULL;
1010 : }
1011 4363 : }
1012 :
1013 1006880 : void BgpAttr::set_ext_community(ExtCommunityPtr extcomm) {
1014 1006880 : ext_community_ = extcomm;
1015 1006900 : }
1016 :
1017 183366 : void BgpAttr::set_ext_community(const ExtCommunitySpec *extcomm) {
1018 183366 : if (extcomm) {
1019 183366 : LargeCommunitySpec large_spec = LargeCommunitySpec::FromTag(*extcomm);
1020 183365 : set_large_community(&large_spec);
1021 :
1022 183366 : if (large_spec.communities.size()) {
1023 : ExtCommunitySpec new_comms =
1024 4 : LargeCommunitySpec::RemoveTags(*extcomm);
1025 : ext_community_ =
1026 4 : attr_db_->server()->extcomm_db()->Locate(new_comms);
1027 4 : return;
1028 4 : }
1029 183362 : ext_community_ = attr_db_->server()->extcomm_db()->Locate(*extcomm);
1030 183370 : } else {
1031 0 : ext_community_ = NULL;
1032 : }
1033 : }
1034 :
1035 18798 : void BgpAttr::set_large_community(LargeCommunityPtr largecomm) {
1036 18798 : large_community_ = largecomm;
1037 18798 : }
1038 :
1039 183407 : void BgpAttr::set_large_community(const LargeCommunitySpec *largecomm) {
1040 183407 : if (largecomm) {
1041 183409 : if (!bool(deferred_large_spec_)) {
1042 183364 : deferred_large_spec_.reset(new LargeCommunitySpec);
1043 183364 : deferred_large_spec_->communities = largecomm->communities;
1044 : } else {
1045 88 : deferred_large_spec_->communities.insert(
1046 88 : deferred_large_spec_->communities.end(),
1047 : largecomm->communities.begin(),
1048 : largecomm->communities.end());
1049 : }
1050 : large_community_ =
1051 183409 : attr_db_->server()->largecomm_db()->Locate(*deferred_large_spec_);
1052 : } else {
1053 0 : large_community_ = NULL;
1054 : }
1055 183410 : }
1056 :
1057 18799 : void BgpAttr::set_origin_vn_path(OriginVnPathPtr ovnpath) {
1058 18799 : origin_vn_path_ = ovnpath;
1059 18799 : }
1060 :
1061 760 : void BgpAttr::set_origin_vn_path(const OriginVnPathSpec *spec) {
1062 760 : if (spec) {
1063 760 : origin_vn_path_ = attr_db_->server()->ovnpath_db()->Locate(*spec);
1064 : } else {
1065 0 : origin_vn_path_ = NULL;
1066 : }
1067 760 : }
1068 :
1069 16892 : void BgpAttr::set_pmsi_tunnel(const PmsiTunnelSpec *pmsi_spec) {
1070 16892 : if (pmsi_spec) {
1071 16892 : pmsi_tunnel_ = attr_db_->server()->pmsi_tunnel_db()->Locate(*pmsi_spec);
1072 : } else {
1073 0 : pmsi_tunnel_ = NULL;
1074 : }
1075 16892 : }
1076 :
1077 2083 : void BgpAttr::set_edge_discovery(const EdgeDiscoverySpec *edspec) {
1078 2083 : if (edspec) {
1079 : edge_discovery_ =
1080 2083 : attr_db_->server()->edge_discovery_db()->Locate(*edspec);
1081 : } else {
1082 0 : edge_discovery_ = NULL;
1083 : }
1084 2083 : }
1085 :
1086 3466 : void BgpAttr::set_edge_forwarding(const EdgeForwardingSpec *efspec) {
1087 3466 : if (efspec) {
1088 : edge_forwarding_ =
1089 3466 : attr_db_->server()->edge_forwarding_db()->Locate(*efspec);
1090 : } else {
1091 0 : edge_forwarding_ = NULL;
1092 : }
1093 3466 : }
1094 :
1095 1034 : void BgpAttr::set_label_block(LabelBlockPtr label_block) {
1096 1034 : label_block_ = label_block;
1097 1033 : }
1098 :
1099 8310 : void BgpAttr::set_olist(const BgpOListSpec *olist_spec) {
1100 8310 : if (olist_spec) {
1101 8310 : olist_ = attr_db_->server()->olist_db()->Locate(*olist_spec);
1102 : } else {
1103 0 : olist_ = NULL;
1104 : }
1105 8310 : }
1106 :
1107 4551 : void BgpAttr::set_leaf_olist(const BgpOListSpec *leaf_olist_spec) {
1108 4551 : if (leaf_olist_spec) {
1109 4551 : leaf_olist_ = attr_db_->server()->olist_db()->Locate(*leaf_olist_spec);
1110 : } else {
1111 0 : leaf_olist_ = NULL;
1112 : }
1113 4551 : }
1114 :
1115 9330558 : int BgpAttr::max_as_path_count() const {
1116 9330558 : int as_count = as_path_count();
1117 9330561 : int as4_count = aspath_4byte_count();
1118 9330562 : return as_count > as4_count ? as_count : as4_count;
1119 : }
1120 :
1121 99418 : bool BgpAttr::IsAsPathEmpty() const {
1122 99418 : if (as_path_ && !as_path_->empty())
1123 332 : return false;
1124 99089 : if (aspath_4byte_ && !aspath_4byte_->empty())
1125 86 : return false;
1126 99003 : return true;
1127 : }
1128 :
1129 5613 : string BgpAttr::OriginToString(BgpAttrOrigin::OriginType origin) {
1130 5613 : switch (origin) {
1131 5253 : case BgpAttrOrigin::IGP:
1132 5253 : return "igp";
1133 : break;
1134 3 : case BgpAttrOrigin::EGP:
1135 3 : return "egp";
1136 : break;
1137 356 : case BgpAttrOrigin::INCOMPLETE:
1138 356 : return "incomplete";
1139 : break;
1140 : }
1141 1 : return "unknown";
1142 : }
1143 :
1144 20424 : BgpAttrOrigin::OriginType BgpAttr::OriginFromString(
1145 : const string &bgp_origin_type) {
1146 20424 : if(bgp_origin_type == "IGP"){
1147 20421 : return BgpAttrOrigin::IGP;
1148 3 : } else if( bgp_origin_type == "EGP") {
1149 2 : return BgpAttrOrigin::EGP;
1150 : }
1151 1 : return BgpAttrOrigin::INCOMPLETE;
1152 : }
1153 :
1154 5611 : string BgpAttr::origin_string() const {
1155 5611 : return OriginToString(origin());
1156 : }
1157 :
1158 2910 : Address::Family BgpAttr::nexthop_family() const {
1159 2910 : if (nexthop_.is_v6()) {
1160 325 : return Address::INET6;
1161 : } else {
1162 2585 : return Address::INET;
1163 : }
1164 : }
1165 :
1166 2654919 : as_t BgpAttr::neighbor_as() const {
1167 2654919 : if (as_path_.get())
1168 496044 : return as_path_->neighbor_as();
1169 2158865 : if (aspath_4byte_.get())
1170 219 : return aspath_4byte_->neighbor_as();
1171 2158651 : return 0;
1172 : }
1173 :
1174 9423523 : uint32_t BgpAttr::sequence_number() const {
1175 9423523 : if (!ext_community_)
1176 1136345 : return 0;
1177 8287186 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1178 8287186 : ext_community_->communities().begin();
1179 28924164 : it != ext_community_->communities().end(); ++it) {
1180 20641074 : if (ExtCommunity::is_mac_mobility(*it)) {
1181 4325 : MacMobility mm(*it);
1182 4325 : return mm.sequence_number();
1183 : }
1184 : }
1185 8282754 : return 0;
1186 : }
1187 :
1188 4711827 : bool BgpAttr::evpn_sticky_mac() const {
1189 4711827 : if (!ext_community_)
1190 568175 : return 0;
1191 4143650 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1192 4143668 : ext_community_->communities().begin();
1193 14462889 : it != ext_community_->communities().end(); ++it) {
1194 10321386 : if (ExtCommunity::is_mac_mobility(*it)) {
1195 2182 : MacMobility mm(*it);
1196 2182 : return mm.sticky();
1197 : }
1198 : }
1199 4141463 : return 0;
1200 : }
1201 :
1202 4711869 : bool BgpAttr::etree_leaf() const {
1203 4711869 : if (!ext_community_)
1204 568176 : return 0;
1205 4143695 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1206 4143696 : ext_community_->communities().begin();
1207 14317949 : it != ext_community_->communities().end(); ++it) {
1208 10247793 : if (ExtCommunity::is_etree(*it)) {
1209 73558 : ETree etree(*it);
1210 73559 : return etree.leaf();
1211 : }
1212 : }
1213 4070079 : return 0;
1214 : }
1215 :
1216 59 : bool BgpAttr::evpn_single_active() const {
1217 59 : if (!ext_community_)
1218 0 : return false;
1219 59 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1220 59 : ext_community_->communities().begin();
1221 118 : it != ext_community_->communities().end(); ++it) {
1222 118 : if (ExtCommunity::is_esi_label(*it)) {
1223 59 : EsiLabel esi_label(*it);
1224 59 : return esi_label.single_active();
1225 : }
1226 : }
1227 0 : return true;
1228 : }
1229 :
1230 463184 : MacAddress BgpAttr::mac_address() const {
1231 463184 : if (!ext_community_)
1232 13766 : return MacAddress::kZeroMac;
1233 449390 : for (ExtCommunity::ExtCommunityList::const_iterator it =
1234 449407 : ext_community_->communities().begin();
1235 3174479 : it != ext_community_->communities().end(); ++it) {
1236 2725032 : if (ExtCommunity::is_router_mac(*it)) {
1237 22 : RouterMac router_mac(*it);
1238 22 : return router_mac.mac_address();
1239 : }
1240 : }
1241 449283 : return MacAddress::kZeroMac;
1242 : }
1243 :
1244 438716 : void BgpAttr::Remove() {
1245 438716 : attr_db_->Delete(this);
1246 438721 : }
1247 :
1248 451905 : int BgpAttr::IsAsPathLoop(as_t asn, uint8_t max_loop_count) const {
1249 451905 : if (as_path() && as_path()->path().AsPathLoop(asn, max_loop_count)) {
1250 137337 : return true;
1251 : }
1252 314906 : if (aspath_4byte() &&
1253 192 : aspath_4byte()->path().AsPathLoop(asn, max_loop_count)) {
1254 51 : return true;
1255 : }
1256 314680 : if (asn > AS2_MAX && as4_path() &&
1257 20 : as4_path()->path().AsPathLoop(asn, max_loop_count)) {
1258 4 : return true;
1259 : }
1260 314656 : return false;
1261 : }
1262 :
1263 25731102 : int BgpAttr::CompareTo(const BgpAttr &rhs) const {
1264 25731102 : KEY_COMPARE(origin_, rhs.origin_);
1265 23968870 : KEY_COMPARE(nexthop_, rhs.nexthop_);
1266 16097645 : KEY_COMPARE(med_, rhs.med_);
1267 15334508 : KEY_COMPARE(local_pref_, rhs.local_pref_);
1268 14932109 : KEY_COMPARE(atomic_aggregate_, rhs.atomic_aggregate_);
1269 14932109 : KEY_COMPARE(aggregator_as_num_, rhs.aggregator_as_num_);
1270 14931917 : KEY_COMPARE(aggregator_as4_num_, rhs.aggregator_as4_num_);
1271 14931789 : KEY_COMPARE(aggregator_address_, rhs.aggregator_address_);
1272 14935219 : KEY_COMPARE(originator_id_, rhs.originator_id_);
1273 14933699 : KEY_COMPARE(pmsi_tunnel_.get(), rhs.pmsi_tunnel_.get());
1274 14578422 : KEY_COMPARE(edge_discovery_.get(), rhs.edge_discovery_.get());
1275 14516261 : KEY_COMPARE(edge_forwarding_.get(), rhs.edge_forwarding_.get());
1276 14452362 : KEY_COMPARE(esi_, rhs.esi_);
1277 14452226 : KEY_COMPARE(params_, rhs.params_);
1278 14452221 : KEY_COMPARE(source_rd_, rhs.source_rd_);
1279 10456335 : KEY_COMPARE(label_block_.get(), rhs.label_block_.get());
1280 10458353 : KEY_COMPARE(olist_.get(), rhs.olist_.get());
1281 10400676 : KEY_COMPARE(leaf_olist_.get(), rhs.leaf_olist_.get());
1282 10381263 : KEY_COMPARE(as_path_.get(), rhs.as_path_.get());
1283 10083507 : KEY_COMPARE(aspath_4byte_.get(), rhs.aspath_4byte_.get());
1284 10082550 : KEY_COMPARE(as4_path_.get(), rhs.as4_path_.get());
1285 10081575 : KEY_COMPARE(cluster_list_.get(), rhs.cluster_list_.get());
1286 10081547 : KEY_COMPARE(community_.get(), rhs.community_.get());
1287 9827615 : KEY_COMPARE(ext_community_.get(), rhs.ext_community_.get());
1288 7349783 : KEY_COMPARE(large_community_.get(), rhs.large_community_.get());
1289 7335080 : KEY_COMPARE(origin_vn_path_.get(), rhs.origin_vn_path_.get());
1290 7259126 : KEY_COMPARE(sub_protocol_, rhs.sub_protocol_);
1291 7243239 : return 0;
1292 : }
1293 :
1294 0 : std::size_t hash_value(BgpAttr const &attr) {
1295 0 : size_t hash = 0;
1296 :
1297 0 : boost::hash_combine(hash, attr.origin_);
1298 0 : boost::hash_combine(hash, attr.nexthop_.to_string());
1299 0 : boost::hash_combine(hash, attr.med_);
1300 0 : boost::hash_combine(hash, attr.local_pref_);
1301 0 : boost::hash_combine(hash, attr.atomic_aggregate_);
1302 0 : boost::hash_combine(hash, attr.aggregator_as_num_);
1303 0 : boost::hash_combine(hash, attr.aggregator_as4_num_);
1304 0 : boost::hash_combine(hash, attr.aggregator_address_.to_string());
1305 0 : boost::hash_combine(hash, attr.originator_id_.to_string());
1306 0 : boost::hash_combine(hash, attr.params_);
1307 0 : boost::hash_combine(hash, attr.source_rd_.ToString());
1308 0 : boost::hash_combine(hash, attr.esi_.ToString());
1309 :
1310 0 : if (attr.label_block_) {
1311 0 : boost::hash_combine(hash, attr.label_block_->first());
1312 0 : boost::hash_combine(hash, attr.label_block_->last());
1313 : }
1314 :
1315 0 : if (attr.olist_) {
1316 0 : boost::hash_range(hash, attr.olist_->elements().begin(),
1317 0 : attr.olist_->elements().end());
1318 : }
1319 0 : if (attr.leaf_olist_) {
1320 0 : boost::hash_range(hash, attr.leaf_olist_->elements().begin(),
1321 0 : attr.leaf_olist_->elements().end());
1322 : }
1323 :
1324 0 : if (attr.as_path_) boost::hash_combine(hash, *attr.as_path_);
1325 0 : if (attr.aspath_4byte_) boost::hash_combine(hash, *attr.aspath_4byte_);
1326 0 : if (attr.as4_path_) boost::hash_combine(hash, *attr.as4_path_);
1327 0 : if (attr.community_) boost::hash_combine(hash, *attr.community_);
1328 0 : if (attr.ext_community_) boost::hash_combine(hash, *attr.ext_community_);
1329 0 : if (attr.large_community_) boost::hash_combine(hash, *attr.large_community_);
1330 0 : if (attr.origin_vn_path_) boost::hash_combine(hash, *attr.origin_vn_path_);
1331 0 : if (!attr.sub_protocol_.empty()) {
1332 0 : boost::hash_combine(hash, attr.sub_protocol_);
1333 : }
1334 :
1335 0 : return hash;
1336 : }
1337 :
1338 9743 : BgpAttrDB::BgpAttrDB(BgpServer *server) : server_(server) {
1339 9743 : }
1340 :
1341 : // Return a clone of attribute with updated aspath.
1342 19101 : BgpAttrPtr BgpAttrDB::ReplaceAsPathAndLocate(const BgpAttr *attr,
1343 : AsPathPtr aspath) {
1344 19101 : BgpAttr *clone = new BgpAttr(*attr);
1345 19101 : clone->set_as_path(aspath);
1346 19101 : return Locate(clone);
1347 : }
1348 :
1349 : // Return a clone of attribute with updated community.
1350 19131 : BgpAttrPtr BgpAttrDB::ReplaceCommunityAndLocate(const BgpAttr *attr,
1351 : CommunityPtr community) {
1352 19131 : BgpAttr *clone = new BgpAttr(*attr);
1353 19131 : clone->set_community(community);
1354 19131 : return Locate(clone);
1355 : }
1356 :
1357 : //Return a clone of attribute with updated origin
1358 4 : BgpAttrPtr BgpAttrDB::ReplaceOriginAndLocate(const BgpAttr *attr,
1359 : BgpAttrOrigin::OriginType origin) {
1360 4 : BgpAttr *clone = new BgpAttr(*attr);
1361 4 : clone->set_origin(origin);
1362 4 : return Locate(clone);
1363 : }
1364 :
1365 : // Return a clone of attribute with updated extended community.
1366 1006861 : BgpAttrPtr BgpAttrDB::ReplaceExtCommunityAndLocate(const BgpAttr *attr,
1367 : ExtCommunityPtr extcomm) {
1368 1006861 : BgpAttr *clone = new BgpAttr(*attr);
1369 1006901 : clone->set_ext_community(extcomm);
1370 1006879 : return Locate(clone);
1371 : }
1372 :
1373 : // Return a clone of attribute with updated large community.
1374 18798 : BgpAttrPtr BgpAttrDB::ReplaceLargeCommunityAndLocate(
1375 : const BgpAttr *attr, LargeCommunityPtr largecomm) {
1376 18798 : BgpAttr *clone = new BgpAttr(*attr);
1377 18798 : clone->set_large_community(largecomm);
1378 18798 : return Locate(clone);
1379 : }
1380 :
1381 : // Return a clone of attribute with updated origin vn path.
1382 18799 : BgpAttrPtr BgpAttrDB::ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
1383 : OriginVnPathPtr ovnpath) {
1384 18799 : BgpAttr *clone = new BgpAttr(*attr);
1385 18799 : clone->set_origin_vn_path(ovnpath);
1386 18799 : return Locate(clone);
1387 : }
1388 :
1389 : // Return a clone of attribute with updated local preference.
1390 18 : BgpAttrPtr BgpAttrDB::ReplaceLocalPreferenceAndLocate(const BgpAttr *attr,
1391 : uint32_t local_pref) {
1392 18 : BgpAttr *clone = new BgpAttr(*attr);
1393 18 : clone->set_local_pref(local_pref);
1394 18 : return Locate(clone);
1395 : }
1396 :
1397 : // Return a clone of attribute with updated originator id.
1398 1 : BgpAttrPtr BgpAttrDB::ReplaceOriginatorIdAndLocate(const BgpAttr *attr,
1399 : Ip4Address originator_id) {
1400 1 : BgpAttr *clone = new BgpAttr(*attr);
1401 1 : clone->set_originator_id(originator_id);
1402 1 : return Locate(clone);
1403 : }
1404 :
1405 : // Return a clone of attribute with updated source rd.
1406 605950 : BgpAttrPtr BgpAttrDB::ReplaceSourceRdAndLocate(const BgpAttr *attr,
1407 : const RouteDistinguisher &source_rd) {
1408 605950 : BgpAttr *clone = new BgpAttr(*attr);
1409 605986 : clone->set_source_rd(source_rd);
1410 605971 : return Locate(clone);
1411 : }
1412 :
1413 : // Return a clone of attribute with updated esi.
1414 17817 : BgpAttrPtr BgpAttrDB::ReplaceEsiAndLocate(const BgpAttr *attr,
1415 : const EthernetSegmentId &esi) {
1416 17817 : BgpAttr *clone = new BgpAttr(*attr);
1417 17817 : clone->set_esi(esi);
1418 17817 : return Locate(clone);
1419 : }
1420 :
1421 : // Return a clone of attribute with updated olist.
1422 4706 : BgpAttrPtr BgpAttrDB::ReplaceOListAndLocate(const BgpAttr *attr,
1423 : const BgpOListSpec *olist_spec) {
1424 4706 : assert(olist_spec->subcode == BgpAttribute::OList);
1425 4706 : BgpAttr *clone = new BgpAttr(*attr);
1426 4706 : clone->set_olist(olist_spec);
1427 4706 : return Locate(clone);
1428 : }
1429 :
1430 : // Return a clone of attribute with updated leaf olist.
1431 4551 : BgpAttrPtr BgpAttrDB::ReplaceLeafOListAndLocate(const BgpAttr *attr,
1432 : const BgpOListSpec *leaf_olist_spec) {
1433 4551 : assert(leaf_olist_spec->subcode == BgpAttribute::LeafOList);
1434 4551 : BgpAttr *clone = new BgpAttr(*attr);
1435 4551 : clone->set_leaf_olist(leaf_olist_spec);
1436 4551 : return Locate(clone);
1437 : }
1438 :
1439 : // Return a clone of attribute with updated sub-protocol.
1440 2028 : BgpAttrPtr BgpAttrDB::ReplaceSubProtocolAndLocate(const BgpAttr *attr,
1441 : const string &sbp) {
1442 2028 : BgpAttr *clone = new BgpAttr(*attr);
1443 2028 : clone->set_sub_protocol(sbp);
1444 2028 : return Locate(clone);
1445 : }
1446 :
1447 :
1448 : // Return a clone of attribute with updated pmsi tunnel.
1449 8758 : BgpAttrPtr BgpAttrDB::ReplacePmsiTunnelAndLocate(const BgpAttr *attr,
1450 : const PmsiTunnelSpec *pmsi_spec) {
1451 8758 : BgpAttr *clone = new BgpAttr(*attr);
1452 8758 : clone->set_pmsi_tunnel(pmsi_spec);
1453 8758 : return Locate(clone);
1454 : }
1455 :
1456 : // Return a clone of attribute with updated nexthop.
1457 338909 : BgpAttrPtr BgpAttrDB::ReplaceNexthopAndLocate(const BgpAttr *attr,
1458 : const IpAddress &addr) {
1459 338909 : BgpAttr *clone = new BgpAttr(*attr);
1460 338919 : clone->set_nexthop(addr);
1461 338914 : return Locate(clone);
1462 : }
|