Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef SRC_BGP_BGP_ATTR_H_
6 : #define SRC_BGP_BGP_ATTR_H_
7 :
8 : #include <boost/intrusive_ptr.hpp>
9 :
10 : #include <set>
11 : #include <string>
12 : #include <vector>
13 : #include <atomic>
14 :
15 : #include "base/label_block.h"
16 : #include "base/parse_object.h"
17 : #include "base/util.h"
18 : #include "base/address.h"
19 : #include "bgp/bgp_aspath.h"
20 : #include "bgp/bgp_attr_base.h"
21 : #include "bgp/bgp_origin_vn_path.h"
22 : #include "bgp/community.h"
23 : #include "net/esi.h"
24 : #include "net/mac_address.h"
25 : #include "net/rd.h"
26 :
27 : class BgpAttr;
28 : class BgpAttrDB;
29 : class BgpOListDB;
30 : class BgpServer;
31 : class ClusterListDB;
32 : class EdgeDiscoveryDB;
33 : class EdgeForwardingDB;
34 : class PmsiTunnelDB;
35 :
36 : // BGP UPDATE attributes: as-path, community, ext-community, next-hop,
37 : // cluster-list, ...
38 : // all information in the UPDATE except: NLRI (prefix) and label.
39 :
40 : struct BgpAttrOrigin : public BgpAttribute {
41 : static const int kSize = 1;
42 : static const uint8_t kFlags = Transitive;
43 : BgpAttrOrigin() : BgpAttribute(Origin, kFlags), origin(IGP) { }
44 124259 : explicit BgpAttrOrigin(const BgpAttribute &rhs)
45 124259 : : BgpAttribute(rhs), origin(IGP) {
46 124259 : }
47 204336 : explicit BgpAttrOrigin(int origin) :
48 204336 : BgpAttribute(Origin, kFlags), origin(origin) { }
49 : enum OriginType {
50 : IGP = 0,
51 : EGP = 1,
52 : INCOMPLETE = 2
53 : };
54 :
55 : int origin;
56 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
57 : virtual void ToCanonical(BgpAttr *attr);
58 : virtual std::string ToString() const;
59 : };
60 :
61 : struct BgpAttrNextHop : public BgpAttribute {
62 : static const int kSize = 4;
63 : static const uint8_t kFlags = Transitive;
64 : BgpAttrNextHop() : BgpAttribute(NextHop, kFlags), nexthop(0) {}
65 15964 : explicit BgpAttrNextHop(const BgpAttribute &rhs)
66 15964 : : BgpAttribute(rhs), nexthop(0) {
67 15964 : }
68 203152 : explicit BgpAttrNextHop(uint32_t nexthop)
69 203152 : : BgpAttribute(NextHop, kFlags), nexthop(nexthop) {}
70 1236 : explicit BgpAttrNextHop(Ip4Address v4_nexthop)
71 1236 : : BgpAttribute(NextHop, kFlags), nexthop(v4_nexthop.to_ulong()) {}
72 325 : explicit BgpAttrNextHop(Ip6Address v6_nexthop)
73 325 : : BgpAttribute(NextHop, kFlags), nexthop(0), v6_nexthop(v6_nexthop) {}
74 7948 : explicit BgpAttrNextHop(IpAddress ip_nexthop)
75 7948 : : BgpAttribute(NextHop, kFlags), nexthop(0) {
76 7948 : if (ip_nexthop.is_v4()) {
77 5741 : nexthop = ip_nexthop.to_v4().to_ulong();
78 2207 : } else if (ip_nexthop.is_v6()) {
79 2207 : v6_nexthop = ip_nexthop.to_v6();
80 : }
81 7948 : }
82 : uint32_t nexthop;
83 : Ip6Address v6_nexthop;
84 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
85 : virtual void ToCanonical(BgpAttr *attr);
86 : virtual std::string ToString() const;
87 : };
88 :
89 : struct BgpAttrMultiExitDisc : public BgpAttribute {
90 : static const int kSize = 4;
91 : static const uint8_t kFlags = Optional;
92 : BgpAttrMultiExitDisc() : BgpAttribute(MultiExitDisc, kFlags), med(0) {}
93 54148 : explicit BgpAttrMultiExitDisc(const BgpAttribute &rhs)
94 54148 : : BgpAttribute(rhs), med(0) {
95 54148 : }
96 84963 : explicit BgpAttrMultiExitDisc(uint32_t med) :
97 84963 : BgpAttribute(MultiExitDisc, kFlags), med(med) {}
98 : uint32_t med;
99 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
100 : virtual void ToCanonical(BgpAttr *attr);
101 : virtual std::string ToString() const;
102 : };
103 :
104 : struct BgpAttrLocalPref : public BgpAttribute {
105 : static const int kDefault = 100;
106 : static const int kSize = 4;
107 : static const uint8_t kFlags = Transitive;
108 : BgpAttrLocalPref() : BgpAttribute(LocalPref, kFlags), local_pref(0) {}
109 26697 : explicit BgpAttrLocalPref(const BgpAttribute &rhs)
110 26697 : : BgpAttribute(rhs), local_pref(0) {
111 26696 : }
112 98200 : explicit BgpAttrLocalPref(uint32_t local_pref)
113 98200 : : BgpAttribute(LocalPref, kFlags), local_pref(local_pref) {
114 98200 : }
115 : uint32_t local_pref;
116 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
117 : virtual void ToCanonical(BgpAttr *attr);
118 : virtual std::string ToString() const;
119 : };
120 :
121 : struct BgpAttrAtomicAggregate : public BgpAttribute {
122 : static const int kSize = 0;
123 : static const uint8_t kFlags = Transitive;
124 4015 : BgpAttrAtomicAggregate() : BgpAttribute(AtomicAggregate, kFlags) {}
125 2674 : explicit BgpAttrAtomicAggregate(const BgpAttribute &rhs)
126 2674 : : BgpAttribute(rhs) {
127 2674 : }
128 : virtual void ToCanonical(BgpAttr *attr);
129 : virtual std::string ToString() const;
130 : };
131 :
132 : struct BgpAttrAs4Aggregator : public BgpAttribute {
133 : static const int kSize = 8;
134 : static const uint8_t kFlags = Optional|Transitive;
135 : BgpAttrAs4Aggregator()
136 : : BgpAttribute(As4Aggregator, kFlags), as_num(0), address(0) {
137 : }
138 2 : explicit BgpAttrAs4Aggregator(const BgpAttribute &rhs)
139 2 : : BgpAttribute(rhs), as_num(0), address(0) {
140 2 : }
141 0 : explicit BgpAttrAs4Aggregator(uint32_t as_num, uint32_t address) :
142 0 : BgpAttribute(As4Aggregator, kFlags), as_num(as_num), address(address) {}
143 : as_t as_num;
144 : uint32_t address;
145 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
146 : virtual void ToCanonical(BgpAttr *attr);
147 : virtual std::string ToString() const;
148 : };
149 :
150 : struct BgpAttrAggregator : public BgpAttribute {
151 : static const int kSize = 6;
152 : static const uint8_t kFlags = Optional|Transitive;
153 : BgpAttrAggregator()
154 : : BgpAttribute(Aggregator, kFlags), as_num(0), address(0) {
155 : }
156 2621 : explicit BgpAttrAggregator(const BgpAttribute &rhs)
157 2621 : : BgpAttribute(rhs), as_num(0), address(0) {
158 2621 : }
159 4047 : explicit BgpAttrAggregator(uint32_t as_num, uint32_t address) :
160 4047 : BgpAttribute(Aggregator, kFlags), as_num(as_num), address(address) {}
161 : as2_t as_num;
162 : uint32_t address;
163 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
164 : virtual void ToCanonical(BgpAttr *attr);
165 : virtual std::string ToString() const;
166 : };
167 :
168 : struct BgpAttr4ByteAggregator : public BgpAttribute {
169 : static const int kSize = 8;
170 : static const uint8_t kFlags = Optional|Transitive;
171 : BgpAttr4ByteAggregator()
172 : : BgpAttribute(Aggregator, kFlags), as_num(0), address(0) {
173 : }
174 3 : explicit BgpAttr4ByteAggregator(const BgpAttribute &rhs)
175 3 : : BgpAttribute(rhs), as_num(0), address(0) {
176 3 : }
177 3 : explicit BgpAttr4ByteAggregator(uint32_t as_num, uint32_t address) :
178 3 : BgpAttribute(Aggregator, kFlags), as_num(as_num), address(address) {}
179 : as_t as_num;
180 : uint32_t address;
181 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
182 : virtual void ToCanonical(BgpAttr *attr);
183 : virtual std::string ToString() const;
184 : };
185 :
186 : struct BgpAttrOriginatorId : public BgpAttribute {
187 : static const int kSize = 4;
188 : static const uint8_t kFlags = Optional;
189 : BgpAttrOriginatorId()
190 : : BgpAttribute(OriginatorId, kFlags), originator_id(0) {
191 : }
192 3 : explicit BgpAttrOriginatorId(const BgpAttribute &rhs)
193 3 : : BgpAttribute(rhs), originator_id(0) {
194 3 : }
195 21 : explicit BgpAttrOriginatorId(uint32_t originator_id)
196 21 : : BgpAttribute(OriginatorId, kFlags), originator_id(originator_id) {}
197 : uint32_t originator_id;
198 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
199 : virtual void ToCanonical(BgpAttr *attr);
200 : virtual std::string ToString() const;
201 : };
202 :
203 : struct ClusterListSpec : public BgpAttribute {
204 : static const int kSize = -1;
205 : static const uint8_t kFlags = Optional;
206 16 : ClusterListSpec() : BgpAttribute(ClusterList, kFlags) { }
207 3 : explicit ClusterListSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) { }
208 24 : explicit ClusterListSpec(const ClusterListSpec &rhs)
209 24 : : BgpAttribute(BgpAttribute::ClusterList, kFlags) {
210 24 : cluster_list = rhs.cluster_list;
211 24 : }
212 : ClusterListSpec(uint32_t cluster_id, const ClusterListSpec *rhs);
213 : virtual int CompareTo(const BgpAttribute &rhs) const;
214 : virtual void ToCanonical(BgpAttr *attr);
215 : virtual std::string ToString() const;
216 : bool ClusterListLoop(uint32_t cluster_id) const;
217 : std::vector<uint32_t> cluster_list;
218 : };
219 :
220 : class ClusterList {
221 : public:
222 : ClusterList(ClusterListDB *cluster_list_db, const ClusterListSpec &spec);
223 22 : ~ClusterList() { }
224 : void Remove();
225 44 : int CompareTo(const ClusterList &rhs) const {
226 44 : return spec_.CompareTo(rhs.cluster_list());
227 : }
228 :
229 48 : const ClusterListSpec &cluster_list() const { return spec_; }
230 16 : size_t size() const { return spec_.cluster_list.size(); }
231 :
232 0 : friend std::size_t hash_value(const ClusterList &cluster_list) {
233 0 : size_t hash = 0;
234 0 : return hash;
235 : }
236 :
237 : private:
238 : friend int intrusive_ptr_add_ref(const ClusterList *ccluster_list);
239 : friend int intrusive_ptr_del_ref(const ClusterList *ccluster_list);
240 : friend void intrusive_ptr_release(const ClusterList *ccluster_list);
241 : friend class ClusterListDB;
242 :
243 : mutable std::atomic<int> refcount_;
244 : ClusterListDB *cluster_list_db_;
245 : ClusterListSpec spec_;
246 : };
247 :
248 47 : inline int intrusive_ptr_add_ref(const ClusterList *ccluster_list) {
249 94 : return ccluster_list->refcount_.fetch_add(1);
250 : }
251 :
252 18 : inline int intrusive_ptr_del_ref(const ClusterList *ccluster_list) {
253 36 : return ccluster_list->refcount_.fetch_sub(1);
254 : }
255 :
256 29 : inline void intrusive_ptr_release(const ClusterList *ccluster_list) {
257 29 : int prev = ccluster_list->refcount_.fetch_sub(1);
258 29 : if (prev == 1) {
259 18 : ClusterList *cluster_list = const_cast<ClusterList *>(ccluster_list);
260 18 : cluster_list->Remove();
261 18 : assert(cluster_list->refcount_ == 0);
262 18 : delete cluster_list;
263 : }
264 29 : }
265 :
266 : typedef boost::intrusive_ptr<ClusterList> ClusterListPtr;
267 :
268 : struct ClusterListCompare {
269 40 : bool operator()(const ClusterList *lhs, const ClusterList *rhs) const {
270 40 : return lhs->CompareTo(*rhs) < 0;
271 : }
272 : };
273 :
274 : class ClusterListDB : public BgpPathAttributeDB<ClusterList, ClusterListPtr,
275 : ClusterListSpec,
276 : ClusterListCompare,
277 : ClusterListDB> {
278 : public:
279 : explicit ClusterListDB(BgpServer *server);
280 : };
281 :
282 : struct BgpMpNlri : public BgpAttribute {
283 : static const int kSize = -1;
284 : static const uint8_t kFlags = Optional;
285 : // Always using extended length for MP NLRI
286 65360 : BgpMpNlri() : BgpAttribute(0, ExtendedLength|kFlags), afi(0), safi(0) {}
287 14 : explicit BgpMpNlri(BgpAttribute::Code code) :
288 14 : BgpAttribute(code, ExtendedLength|kFlags), afi(0), safi(0) {}
289 111214 : explicit BgpMpNlri(BgpAttribute::Code code, uint16_t afi, uint8_t safi,
290 111214 : std::vector<uint8_t> nh) :
291 111213 : BgpAttribute(code, ExtendedLength|kFlags), afi(afi), safi(safi),
292 111214 : nexthop(nh) {}
293 58046 : explicit BgpMpNlri(BgpAttribute::Code code, uint16_t afi, uint8_t safi) :
294 58046 : BgpAttribute(code, ExtendedLength|kFlags), afi(afi), safi(safi) {
295 58046 : nexthop.clear();
296 58046 : }
297 160696 : explicit BgpMpNlri(const BgpAttribute &rhs)
298 160696 : : BgpAttribute(rhs), afi(0), safi(0) {
299 160694 : }
300 729443 : ~BgpMpNlri() {
301 395346 : STLDeleteValues(&nlri);
302 729426 : }
303 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
304 : virtual void ToCanonical(BgpAttr *attr);
305 : virtual size_t EncodeLength() const;
306 :
307 : uint16_t afi;
308 : uint8_t safi;
309 : std::vector<uint8_t> nexthop;
310 :
311 : std::vector<BgpProtoPrefix *> nlri;
312 : };
313 :
314 : struct PmsiTunnelSpec : public BgpAttribute {
315 : enum Flags {
316 : LeafInfoRequired = 1 << 0,
317 : AssistedReplicationType = 3 << 3,
318 : EdgeReplicationSupported = 1 << 7
319 : };
320 :
321 : enum ARType {
322 : RegularNVE = 0 << 3,
323 : ARReplicator = 1 << 3,
324 : ARLeaf = 2 << 3
325 : };
326 :
327 : enum Type {
328 : NoTunnelInfo = 0,
329 : RsvpP2mpLsp = 1,
330 : LdpP2mpLsp = 2,
331 : PimSsmTree = 3,
332 : PimSmTree = 4,
333 : BidirPimTree = 5,
334 : IngressReplication = 6,
335 : MldpMp2mpLsp = 7,
336 : AssistedReplicationContrail = 252
337 : };
338 :
339 : static const int kSize = -1;
340 : static const uint8_t kFlags = Optional | Transitive;
341 :
342 : PmsiTunnelSpec();
343 : explicit PmsiTunnelSpec(const BgpAttribute &rhs);
344 :
345 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
346 : virtual void ToCanonical(BgpAttr *attr);
347 : virtual std::string ToString() const;
348 :
349 : uint32_t GetLabel(const ExtCommunity *ext) const;
350 : void SetLabel(uint32_t label, const ExtCommunity *ext);
351 : Ip4Address GetIdentifier() const;
352 : void SetIdentifier(Ip4Address identifier);
353 :
354 : std::string GetTunnelTypeString() const;
355 : std::string GetTunnelArTypeString() const;
356 : std::vector<std::string> GetTunnelFlagsStrings() const;
357 :
358 : uint8_t tunnel_flags;
359 : uint8_t tunnel_type;
360 : uint32_t label;
361 : std::vector<uint8_t> identifier;
362 : };
363 :
364 : class PmsiTunnel {
365 : public:
366 : PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db, const PmsiTunnelSpec &pmsi_spec);
367 34828 : virtual ~PmsiTunnel() { }
368 : virtual void Remove();
369 471623 : int CompareTo(const PmsiTunnel &rhs) const {
370 471623 : return pmsi_spec_.CompareTo(rhs.pmsi_tunnel());
371 : }
372 :
373 472461 : const PmsiTunnelSpec &pmsi_tunnel() const { return pmsi_spec_; }
374 : uint32_t GetLabel(const ExtCommunity *ext) const;
375 :
376 0 : friend std::size_t hash_value(const PmsiTunnel &pmsi_tunnel) {
377 0 : size_t hash = 0;
378 0 : boost::hash_combine(hash, pmsi_tunnel.pmsi_tunnel().ToString());
379 0 : return hash;
380 : }
381 :
382 116865 : const uint8_t tunnel_flags() const { return tunnel_flags_; }
383 27655 : const uint8_t tunnel_type() const { return tunnel_type_; }
384 52255 : const Ip4Address identifier() const { return identifier_; }
385 4116 : const uint32_t label() const { return label_; }
386 :
387 : private:
388 : friend int intrusive_ptr_add_ref(const PmsiTunnel *cpmsi_tunnel);
389 : friend int intrusive_ptr_del_ref(const PmsiTunnel *cpmsi_tunnel);
390 : friend void intrusive_ptr_release(const PmsiTunnel *cpmsi_tunnel);
391 : friend class PmsiTunnelDB;
392 :
393 : uint8_t tunnel_flags_;
394 : uint8_t tunnel_type_;
395 : Ip4Address identifier_;
396 : uint32_t label_;
397 : mutable std::atomic<int> refcount_;
398 : PmsiTunnelDB *pmsi_tunnel_db_;
399 : PmsiTunnelSpec pmsi_spec_;
400 : };
401 :
402 363346 : inline int intrusive_ptr_add_ref(const PmsiTunnel *cpmsi_tunnel) {
403 726692 : return cpmsi_tunnel->refcount_.fetch_add(1);
404 : }
405 :
406 216674 : inline int intrusive_ptr_del_ref(const PmsiTunnel *cpmsi_tunnel) {
407 433348 : return cpmsi_tunnel->refcount_.fetch_sub(1);
408 : }
409 :
410 146665 : inline void intrusive_ptr_release(const PmsiTunnel *cpmsi_tunnel) {
411 146665 : int prev = cpmsi_tunnel->refcount_.fetch_sub(1);
412 146665 : if (prev == 1) {
413 4981 : PmsiTunnel *pmsi_tunnel = const_cast<PmsiTunnel *>(cpmsi_tunnel);
414 4981 : pmsi_tunnel->Remove();
415 4981 : assert(pmsi_tunnel->refcount_ == 0);
416 4981 : delete pmsi_tunnel;
417 : }
418 146665 : }
419 :
420 : typedef boost::intrusive_ptr<PmsiTunnel> PmsiTunnelPtr;
421 :
422 : struct PmsiTunnelCompare {
423 471618 : bool operator()(const PmsiTunnel *lhs, const PmsiTunnel *rhs) const {
424 471618 : return lhs->CompareTo(*rhs) < 0;
425 : }
426 : };
427 :
428 : class PmsiTunnelDB : public BgpPathAttributeDB<PmsiTunnel, PmsiTunnelPtr,
429 : PmsiTunnelSpec,
430 : PmsiTunnelCompare,
431 : PmsiTunnelDB> {
432 : public:
433 : explicit PmsiTunnelDB(BgpServer *server);
434 : };
435 :
436 : struct EdgeDiscoverySpec : public BgpAttribute {
437 : static const int kSize = -1;
438 : static const uint8_t kFlags = Optional | Transitive;
439 : EdgeDiscoverySpec();
440 : explicit EdgeDiscoverySpec(const BgpAttribute &rhs);
441 : explicit EdgeDiscoverySpec(const EdgeDiscoverySpec &rhs);
442 : ~EdgeDiscoverySpec();
443 :
444 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
445 : virtual void ToCanonical(BgpAttr *attr);
446 : virtual std::string ToString() const;
447 : virtual size_t EncodeLength() const;
448 :
449 : struct Edge : public ParseObject {
450 : Ip4Address GetIp4Address() const;
451 : void SetIp4Address(Ip4Address addr);
452 : void GetLabels(uint32_t *first_label, uint32_t *last_label) const;
453 : void SetLabels(uint32_t first_label, uint32_t last_label);
454 :
455 : std::vector<uint8_t> address;
456 : std::vector<uint32_t> labels;
457 : };
458 : typedef std::vector<Edge *> EdgeList;
459 : EdgeList edge_list;
460 : };
461 :
462 : class EdgeDiscovery {
463 : public:
464 : EdgeDiscovery(EdgeDiscoveryDB *edge_discovery_db,
465 : const EdgeDiscoverySpec &edspec);
466 : virtual ~EdgeDiscovery();
467 : virtual void Remove();
468 : int CompareTo(const EdgeDiscovery &rhs) const;
469 :
470 1053 : const EdgeDiscoverySpec &edge_discovery() const { return edspec_; }
471 :
472 0 : friend std::size_t hash_value(const EdgeDiscovery &edge_discovery) {
473 0 : size_t hash = 0;
474 0 : boost::hash_combine(hash, edge_discovery.edge_discovery().ToString());
475 0 : return hash;
476 : }
477 :
478 : struct Edge {
479 : explicit Edge(const EdgeDiscoverySpec::Edge *edge_spec);
480 : Ip4Address address;
481 : LabelBlockPtr label_block;
482 : bool operator<(const Edge &rhs) const;
483 : };
484 : typedef std::vector<Edge *> EdgeList;
485 :
486 : struct EdgeCompare {
487 8343 : bool operator()(const Edge *lhs, const Edge *rhs) const {
488 8343 : BOOL_KEY_COMPARE(*lhs, *rhs);
489 8312 : return false;
490 : }
491 : };
492 :
493 : EdgeList edge_list;
494 :
495 : private:
496 : friend int intrusive_ptr_add_ref(const EdgeDiscovery *ediscovery);
497 : friend int intrusive_ptr_del_ref(const EdgeDiscovery *ediscovery);
498 : friend void intrusive_ptr_release(const EdgeDiscovery *ediscovery);
499 : friend class EdgeDiscoveryDB;
500 :
501 : mutable std::atomic<int> refcount_;
502 : EdgeDiscoveryDB *edge_discovery_db_;
503 : EdgeDiscoverySpec edspec_;
504 : };
505 :
506 187264 : inline int intrusive_ptr_add_ref(const EdgeDiscovery *cediscovery) {
507 374528 : return cediscovery->refcount_.fetch_add(1);
508 : }
509 :
510 177430 : inline int intrusive_ptr_del_ref(const EdgeDiscovery *cediscovery) {
511 354860 : return cediscovery->refcount_.fetch_sub(1);
512 : }
513 :
514 9826 : inline void intrusive_ptr_release(const EdgeDiscovery *cediscovery) {
515 9826 : int prev = cediscovery->refcount_.fetch_sub(1);
516 9826 : if (prev == 1) {
517 1823 : EdgeDiscovery *ediscovery = const_cast<EdgeDiscovery *>(cediscovery);
518 1823 : ediscovery->Remove();
519 1823 : assert(ediscovery->refcount_ == 0);
520 1823 : delete ediscovery;
521 : }
522 9826 : }
523 :
524 : typedef boost::intrusive_ptr<EdgeDiscovery> EdgeDiscoveryPtr;
525 :
526 : struct EdgeDiscoveryCompare {
527 363788 : bool operator()(const EdgeDiscovery *lhs, const EdgeDiscovery *rhs) const {
528 363788 : return lhs->CompareTo(*rhs) < 0;
529 : }
530 : };
531 :
532 : class EdgeDiscoveryDB : public BgpPathAttributeDB<EdgeDiscovery,
533 : EdgeDiscoveryPtr,
534 : EdgeDiscoverySpec,
535 : EdgeDiscoveryCompare,
536 : EdgeDiscoveryDB> {
537 : public:
538 : explicit EdgeDiscoveryDB(BgpServer *server);
539 : };
540 :
541 : struct EdgeForwardingSpec : public BgpAttribute {
542 : static const int kSize = -1;
543 : static const uint8_t kFlags = Optional | Transitive;
544 : EdgeForwardingSpec();
545 : explicit EdgeForwardingSpec(const BgpAttribute &rhs);
546 : explicit EdgeForwardingSpec(const EdgeForwardingSpec &rhs);
547 : ~EdgeForwardingSpec();
548 :
549 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
550 : virtual void ToCanonical(BgpAttr *attr);
551 : virtual std::string ToString() const;
552 : virtual size_t EncodeLength() const;
553 :
554 : struct Edge : public ParseObject {
555 : Ip4Address GetInboundIp4Address() const;
556 : Ip4Address GetOutboundIp4Address() const;
557 : void SetInboundIp4Address(Ip4Address addr);
558 : void SetOutboundIp4Address(Ip4Address addr);
559 :
560 : int address_len;
561 : std::vector<uint8_t> inbound_address, outbound_address;
562 : uint32_t inbound_label, outbound_label;
563 : };
564 : typedef std::vector<Edge *> EdgeList;
565 :
566 : EdgeList edge_list;
567 : };
568 :
569 : class EdgeForwarding {
570 : public:
571 : EdgeForwarding(EdgeForwardingDB *edge_forwarding_db,
572 : const EdgeForwardingSpec &efspec);
573 : virtual ~EdgeForwarding();
574 : virtual void Remove();
575 : int CompareTo(const EdgeForwarding &rhs) const;
576 :
577 1802 : const EdgeForwardingSpec &edge_forwarding() const { return efspec_; }
578 :
579 0 : friend std::size_t hash_value(const EdgeForwarding &edge_forwarding) {
580 0 : size_t hash = 0;
581 0 : boost::hash_combine(hash, edge_forwarding.edge_forwarding().ToString());
582 0 : return hash;
583 : }
584 :
585 : struct Edge {
586 : explicit Edge(const EdgeForwardingSpec::Edge *edge_spec);
587 : bool operator<(const Edge &rhs) const;
588 : Ip4Address inbound_address, outbound_address;
589 : uint32_t inbound_label, outbound_label;
590 : };
591 : typedef std::vector<Edge *> EdgeList;
592 :
593 : struct EdgeCompare {
594 1487 : bool operator()(const Edge *lhs, const Edge *rhs) const {
595 1487 : BOOL_KEY_COMPARE(*lhs, *rhs);
596 0 : return false;
597 : }
598 : };
599 :
600 : EdgeList edge_list;
601 :
602 : private:
603 : friend int intrusive_ptr_add_ref(const EdgeForwarding *ceforwarding);
604 : friend int intrusive_ptr_del_ref(const EdgeForwarding *ceforwarding);
605 : friend void intrusive_ptr_release(const EdgeForwarding *ceforwarding);
606 : friend class EdgeForwardingDB;
607 :
608 : mutable std::atomic<int> refcount_;
609 : EdgeForwardingDB *edge_forwarding_db_;
610 : EdgeForwardingSpec efspec_;
611 : };
612 :
613 667015 : inline int intrusive_ptr_add_ref(const EdgeForwarding *ceforwarding) {
614 1334030 : return ceforwarding->refcount_.fetch_add(1);
615 : }
616 :
617 652934 : inline int intrusive_ptr_del_ref(const EdgeForwarding *ceforwarding) {
618 1305868 : return ceforwarding->refcount_.fetch_sub(1);
619 : }
620 :
621 14069 : inline void intrusive_ptr_release(const EdgeForwarding *ceforwarding) {
622 14069 : int prev = ceforwarding->refcount_.fetch_sub(1);
623 14069 : if (prev == 1) {
624 2348 : EdgeForwarding *eforwarding =
625 : const_cast<EdgeForwarding *>(ceforwarding);
626 2348 : eforwarding->Remove();
627 2348 : assert(eforwarding->refcount_ == 0);
628 2348 : delete eforwarding;
629 : }
630 14069 : }
631 :
632 : typedef boost::intrusive_ptr<EdgeForwarding> EdgeForwardingPtr;
633 :
634 : struct EdgeForwardingCompare {
635 1319548 : bool operator()(const EdgeForwarding *lhs, const EdgeForwarding *rhs) const {
636 1319548 : return lhs->CompareTo(*rhs) < 0;
637 : }
638 : };
639 :
640 : class EdgeForwardingDB : public BgpPathAttributeDB<EdgeForwarding,
641 : EdgeForwardingPtr,
642 : EdgeForwardingSpec,
643 : EdgeForwardingCompare,
644 : EdgeForwardingDB> {
645 : public:
646 : explicit EdgeForwardingDB(BgpServer *server);
647 : };
648 :
649 : struct BgpAttrLabelBlock : public BgpAttribute {
650 : static const int kSize = 0;
651 : BgpAttrLabelBlock() : BgpAttribute(0, BgpAttribute::LabelBlock, 0) {}
652 : explicit BgpAttrLabelBlock(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
653 1036 : explicit BgpAttrLabelBlock(LabelBlockPtr label_block)
654 1036 : : BgpAttribute(0, BgpAttribute::LabelBlock, 0),
655 1036 : label_block(label_block) {
656 1036 : }
657 : LabelBlockPtr label_block;
658 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
659 : virtual void ToCanonical(BgpAttr *attr);
660 : virtual std::string ToString() const;
661 : };
662 :
663 : class BgpOListElem {
664 : public:
665 22887 : BgpOListElem(Ip4Address address, uint32_t label,
666 : std::vector<std::string> encap = std::vector<std::string>())
667 22887 : : address(address), label(label), encap(encap) {
668 22887 : }
669 :
670 : bool operator<(const BgpOListElem &rhs) const;
671 :
672 : Ip4Address address;
673 : uint32_t label;
674 : std::vector<std::string> encap;
675 : };
676 :
677 : struct BgpOListElemCompare {
678 31824 : bool operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const {
679 31824 : BOOL_KEY_COMPARE(*lhs, *rhs);
680 0 : return false;
681 : }
682 : };
683 :
684 : struct BgpOListSpec : public BgpAttribute {
685 : static const int kSize = 0;
686 1026 : BgpOListSpec() : BgpAttribute(0, BgpAttribute::OList, 0) {}
687 18518 : explicit BgpOListSpec(uint8_t subcode) : BgpAttribute(0, subcode, 0) {}
688 :
689 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
690 : virtual void ToCanonical(BgpAttr *attr);
691 : virtual std::string ToString() const;
692 :
693 : typedef std::vector<BgpOListElem> Elements;
694 : Elements elements;
695 : };
696 :
697 : class BgpOList {
698 : public:
699 : BgpOList(BgpOListDB *olist_db, const BgpOListSpec &olist_spec);
700 : virtual ~BgpOList();
701 : virtual void Remove();
702 : int CompareTo(const BgpOList &rhs) const;
703 :
704 4681351 : const BgpOListSpec &olist() const { return olist_spec_; }
705 :
706 0 : friend std::size_t hash_value(const BgpOList &olist) {
707 0 : size_t hash = 0;
708 0 : boost::hash_combine(hash, olist.olist().ToString());
709 0 : return hash;
710 : }
711 :
712 : typedef std::vector<BgpOListElem *> Elements;
713 :
714 4655921 : const Elements &elements() const { return elements_; }
715 :
716 : private:
717 : friend int intrusive_ptr_add_ref(const BgpOList *colist);
718 : friend int intrusive_ptr_del_ref(const BgpOList *colist);
719 : friend void intrusive_ptr_release(const BgpOList *colist);
720 : friend class BgpOListDB;
721 :
722 : Elements elements_;
723 : mutable std::atomic<int> refcount_;
724 : BgpOListDB *olist_db_;
725 : BgpOListSpec olist_spec_;
726 : };
727 :
728 785148 : inline int intrusive_ptr_add_ref(const BgpOList *colist) {
729 1570296 : return colist->refcount_.fetch_add(1);
730 : }
731 :
732 545467 : inline int intrusive_ptr_del_ref(const BgpOList *colist) {
733 1090934 : return colist->refcount_.fetch_sub(1);
734 : }
735 :
736 239669 : inline void intrusive_ptr_release(const BgpOList *colist) {
737 239669 : int prev = colist->refcount_.fetch_sub(1);
738 239669 : if (prev == 1) {
739 9642 : BgpOList *olist = const_cast<BgpOList *>(colist);
740 9642 : olist->Remove();
741 9642 : assert(olist->refcount_ == 0);
742 9642 : delete olist;
743 : }
744 239669 : }
745 :
746 : typedef boost::intrusive_ptr<BgpOList> BgpOListPtr;
747 :
748 : struct BgpOListCompare {
749 1123216 : bool operator()(const BgpOList *lhs, const BgpOList *rhs) const {
750 1123216 : return lhs->CompareTo(*rhs) < 0;
751 : }
752 : };
753 :
754 : class BgpOListDB : public BgpPathAttributeDB<BgpOList,
755 : BgpOListPtr,
756 : BgpOListSpec,
757 : BgpOListCompare,
758 : BgpOListDB> {
759 : public:
760 : explicit BgpOListDB(BgpServer *server);
761 : };
762 :
763 : struct BgpAttrUnknown : public BgpAttribute {
764 3972 : BgpAttrUnknown() : BgpAttribute() {}
765 2566 : explicit BgpAttrUnknown(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
766 : std::vector<uint8_t> value;
767 : };
768 :
769 : struct BgpAttrSourceRd : public BgpAttribute {
770 35970 : BgpAttrSourceRd() : BgpAttribute(0, SourceRd, 0) {}
771 : explicit BgpAttrSourceRd(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
772 42586 : explicit BgpAttrSourceRd(const RouteDistinguisher &source_rd)
773 42586 : : BgpAttribute(0, SourceRd, 0), source_rd(source_rd) {
774 42586 : }
775 : RouteDistinguisher source_rd;
776 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
777 : virtual void ToCanonical(BgpAttr *attr);
778 : virtual std::string ToString() const;
779 : };
780 :
781 : struct BgpAttrEsi : public BgpAttribute {
782 : BgpAttrEsi() : BgpAttribute(0, Esi, 0) {}
783 : explicit BgpAttrEsi(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
784 75 : explicit BgpAttrEsi(const EthernetSegmentId &esi)
785 75 : : BgpAttribute(0, Esi, 0), esi(esi) {
786 75 : }
787 : EthernetSegmentId esi;
788 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
789 : virtual void ToCanonical(BgpAttr *attr);
790 : virtual std::string ToString() const;
791 : };
792 :
793 : struct BgpAttrSubProtocol : public BgpAttribute {
794 : BgpAttrSubProtocol() : BgpAttribute(0, SubProtocol, 0) {}
795 : explicit BgpAttrSubProtocol(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
796 22432 : explicit BgpAttrSubProtocol(const std::string &sbp)
797 22432 : : BgpAttribute(0, SubProtocol, 0), sbp(sbp) {
798 22432 : }
799 : std::string sbp;
800 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
801 : virtual void ToCanonical(BgpAttr *attr);
802 : virtual std::string ToString() const;
803 : };
804 :
805 : struct BgpAttrParams : public BgpAttribute {
806 : enum Flags {
807 : TestFlag = 1 << 0
808 : };
809 :
810 : BgpAttrParams() : BgpAttribute(0, Params, 0), params(0) {}
811 : explicit BgpAttrParams(const BgpAttribute &rhs)
812 : : BgpAttribute(rhs), params(0) {
813 : }
814 6 : explicit BgpAttrParams(uint64_t params) :
815 6 : BgpAttribute(0, Params, 0), params(params) {}
816 : uint64_t params;
817 : virtual int CompareTo(const BgpAttribute &rhs_attr) const;
818 : virtual void ToCanonical(BgpAttr *attr);
819 : virtual std::string ToString() const;
820 : };
821 :
822 : typedef std::vector<BgpAttribute *> BgpAttrSpec;
823 :
824 : // Canonicalized BGP attribute
825 : class BgpAttr {
826 : public:
827 : BgpAttr();
828 : explicit BgpAttr(BgpAttrDB *attr_db);
829 : explicit BgpAttr(const BgpAttr &rhs);
830 : BgpAttr(BgpAttrDB *attr_db, const BgpAttrSpec &spec);
831 6839088 : virtual ~BgpAttr() { }
832 : virtual void Remove();
833 :
834 : int CompareTo(const BgpAttr &rhs) const;
835 :
836 184313 : void set_origin(BgpAttrOrigin::OriginType org) { origin_ = org; }
837 531730 : void set_nexthop(IpAddress nexthop) { nexthop_ = nexthop; }
838 80716 : void set_med(uint32_t med) { med_ = med; }
839 295920 : void set_local_pref(uint32_t local_pref) { local_pref_ = local_pref; }
840 9 : void set_atomic_aggregate(bool ae) { atomic_aggregate_ = ae; }
841 73 : void set_aggregator(as_t as_num, IpAddress address) {
842 73 : aggregator_as_num_ = as_num;
843 73 : aggregator_address_ = address;
844 73 : }
845 64 : void set_as4_aggregator(as_t as_num, IpAddress address) {
846 64 : aggregator_as4_num_ = as_num;
847 64 : aggregator_address_ = address;
848 64 : }
849 203560 : void set_originator_id(Ip4Address originator_id) {
850 203560 : originator_id_ = originator_id;
851 203560 : }
852 634596 : void set_source_rd(const RouteDistinguisher &source_rd) {
853 634596 : source_rd_ = source_rd;
854 634597 : }
855 17906 : void set_esi(const EthernetSegmentId &esi) { esi_ = esi; }
856 3 : void set_params(uint64_t params) { params_ = params; }
857 : void set_as_path(AsPathPtr aspath);
858 : void set_as_path(const AsPathSpec *spec);
859 : void set_as4_path(As4PathPtr aspath);
860 : void set_as4_path(const As4PathSpec *spec);
861 : void set_aspath_4byte(AsPath4BytePtr aspath);
862 : void set_aspath_4byte(const AsPath4ByteSpec *spec);
863 : void set_cluster_list(const ClusterListSpec *spec);
864 : void set_community(CommunityPtr comm);
865 : void set_community(const CommunitySpec *comm);
866 : void set_ext_community(ExtCommunityPtr extcomm);
867 : void set_ext_community(const ExtCommunitySpec *extcomm);
868 : void set_large_community(LargeCommunityPtr largecomm);
869 : void set_large_community(const LargeCommunitySpec *largecomm);
870 : void set_origin_vn_path(OriginVnPathPtr ovnpath);
871 : void set_origin_vn_path(const OriginVnPathSpec *spec);
872 : void set_pmsi_tunnel(const PmsiTunnelSpec *pmsi_spec);
873 : void set_edge_discovery(const EdgeDiscoverySpec *edspec);
874 : void set_edge_forwarding(const EdgeForwardingSpec *efspec);
875 : void set_label_block(LabelBlockPtr label_block);
876 : void set_olist(const BgpOListSpec *olist_spec);
877 : void set_leaf_olist(const BgpOListSpec *leaf_olist_spec);
878 24010 : void set_sub_protocol(const std::string &sub_protocol) {
879 24010 : sub_protocol_ = sub_protocol;
880 24010 : }
881 : friend std::size_t hash_value(BgpAttr const &attr);
882 :
883 9525288 : BgpAttrOrigin::OriginType origin() const { return origin_; }
884 : static std::string OriginToString(BgpAttrOrigin::OriginType origin);
885 : static BgpAttrOrigin::OriginType OriginFromString(const std::string &bgp_origin_type);
886 : std::string origin_string() const;
887 :
888 1010536 : const IpAddress &nexthop() const { return nexthop_; }
889 : Address::Family nexthop_family() const;
890 1670767 : uint32_t med() const { return med_; }
891 10246181 : uint32_t local_pref() const { return local_pref_; }
892 111220 : bool atomic_aggregate() const { return atomic_aggregate_; }
893 359362 : as_t aggregator_as_num() const { return aggregator_as_num_; }
894 64 : as_t aggregator_as4_num() const { return aggregator_as4_num_; }
895 : as_t neighbor_as() const;
896 50 : const IpAddress &aggregator_adderess() const { return aggregator_address_; }
897 524964 : const Ip4Address &originator_id() const { return originator_id_; }
898 165842 : const RouteDistinguisher &source_rd() const { return source_rd_; }
899 43170 : const EthernetSegmentId &esi() const { return esi_; }
900 3 : uint64_t params() const { return params_; }
901 1627969 : const AsPath *as_path() const { return as_path_.get(); }
902 9335441 : int as_path_count() const { return as_path_ ? as_path_->AsCount() : 0; }
903 : int max_as_path_count() const;
904 444655 : const AsPath4Byte *aspath_4byte() const { return aspath_4byte_.get(); }
905 9330632 : int aspath_4byte_count() const {
906 9330632 : return aspath_4byte_ ? aspath_4byte_->AsCount() : 0;
907 : }
908 : int IsAsPathLoop(as_t asn, uint8_t max_loop_count = 0) const;
909 116843 : const ClusterList *cluster_list() const { return cluster_list_.get(); }
910 320309 : size_t cluster_list_length() const {
911 320309 : return cluster_list_ ? cluster_list_->size() : 0;
912 : }
913 118096 : const As4Path *as4_path() const { return as4_path_.get(); }
914 125 : int as4_path_count() const { return as4_path_ ? as4_path_->AsCount() : 0; }
915 : bool IsAsPathEmpty() const;
916 6698017 : const Community *community() const { return community_.get(); }
917 3917649 : const ExtCommunity *ext_community() const { return ext_community_.get(); }
918 680651 : const LargeCommunity *large_community() const {
919 680651 : return large_community_.get();
920 : }
921 4353660 : const OriginVnPath *origin_vn_path() const { return origin_vn_path_.get(); }
922 225462 : const PmsiTunnel *pmsi_tunnel() const { return pmsi_tunnel_.get(); }
923 128149 : const EdgeDiscovery *edge_discovery() const {
924 128149 : return edge_discovery_.get();
925 : }
926 126768 : const EdgeForwarding *edge_forwarding() const {
927 126768 : return edge_forwarding_.get();
928 : }
929 10530 : LabelBlockPtr label_block() const { return label_block_; }
930 224950 : BgpOListPtr olist() const { return olist_; }
931 14123 : BgpOListPtr leaf_olist() const { return leaf_olist_; }
932 30552 : const std::string &sub_protocol() const { return sub_protocol_; }
933 248660 : BgpAttrDB *attr_db() { return attr_db_; }
934 2355365 : const BgpAttrDB *attr_db() const { return attr_db_; }
935 : uint32_t sequence_number() const;
936 : bool evpn_sticky_mac() const;
937 : bool etree_leaf() const;
938 : bool evpn_single_active() const;
939 : MacAddress mac_address() const;
940 :
941 : private:
942 : friend class BgpAttrDB;
943 : friend class BgpAttrTest;
944 : friend int intrusive_ptr_add_ref(const BgpAttr *cattrp);
945 : friend int intrusive_ptr_del_ref(const BgpAttr *cattrp);
946 : friend void intrusive_ptr_release(const BgpAttr *cattrp);
947 :
948 : mutable std::atomic<int> refcount_;
949 : BgpAttrDB *attr_db_;
950 : BgpAttrOrigin::OriginType origin_;
951 : IpAddress nexthop_;
952 : uint32_t med_;
953 : uint32_t local_pref_;
954 : bool atomic_aggregate_;
955 : as_t aggregator_as_num_;
956 : as_t aggregator_as4_num_;
957 : IpAddress aggregator_address_;
958 : Ip4Address originator_id_;
959 : RouteDistinguisher source_rd_;
960 : EthernetSegmentId esi_;
961 : uint64_t params_;
962 : AsPathPtr as_path_;
963 : AsPath4BytePtr aspath_4byte_;
964 : As4PathPtr as4_path_;
965 : ClusterListPtr cluster_list_;
966 : CommunityPtr community_;
967 : ExtCommunityPtr ext_community_;
968 : LargeCommunityPtr large_community_;
969 : std::unique_ptr<LargeCommunitySpec> deferred_large_spec_;
970 : OriginVnPathPtr origin_vn_path_;
971 : PmsiTunnelPtr pmsi_tunnel_;
972 : EdgeDiscoveryPtr edge_discovery_;
973 : EdgeForwardingPtr edge_forwarding_;
974 : LabelBlockPtr label_block_;
975 : BgpOListPtr olist_;
976 : BgpOListPtr leaf_olist_;
977 : std::string sub_protocol_;
978 : };
979 :
980 18016314 : inline int intrusive_ptr_add_ref(const BgpAttr *cattrp) {
981 36032628 : return cattrp->refcount_.fetch_add(1);
982 : }
983 :
984 3623465 : inline int intrusive_ptr_del_ref(const BgpAttr *cattrp) {
985 7246930 : return cattrp->refcount_.fetch_sub(1);
986 : }
987 :
988 14396325 : inline void intrusive_ptr_release(const BgpAttr *cattrp) {
989 14396325 : int prev = cattrp->refcount_.fetch_sub(1);
990 14396325 : if (prev == 1) {
991 438719 : BgpAttr *attrp = const_cast<BgpAttr *>(cattrp);
992 438719 : attrp->Remove();
993 438720 : assert(attrp->refcount_ == 0);
994 438717 : delete attrp;
995 : }
996 14396313 : }
997 :
998 : typedef boost::intrusive_ptr<const BgpAttr> BgpAttrPtr;
999 :
1000 : struct BgpAttrCompare {
1001 25731206 : bool operator()(const BgpAttr *lhs, const BgpAttr *rhs) const {
1002 25731206 : return lhs->CompareTo(*rhs) < 0;
1003 : }
1004 : };
1005 :
1006 : class BgpAttrDB : public BgpPathAttributeDB<BgpAttr, BgpAttrPtr, BgpAttrSpec,
1007 : BgpAttrCompare, BgpAttrDB> {
1008 : public:
1009 : explicit BgpAttrDB(BgpServer *server);
1010 : BgpAttrPtr ReplaceAsPathAndLocate(const BgpAttr *attr,
1011 : AsPathPtr aspath);
1012 : BgpAttrPtr ReplaceCommunityAndLocate(const BgpAttr *attr,
1013 : CommunityPtr community);
1014 : BgpAttrPtr ReplaceOriginAndLocate(const BgpAttr *attr,
1015 : BgpAttrOrigin::OriginType origin);
1016 : BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr,
1017 : ExtCommunityPtr extcomm);
1018 : BgpAttrPtr ReplaceLargeCommunityAndLocate(const BgpAttr *attr,
1019 : LargeCommunityPtr largecomm);
1020 : BgpAttrPtr ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
1021 : OriginVnPathPtr ovnpath);
1022 : BgpAttrPtr ReplaceLocalPreferenceAndLocate(const BgpAttr *attr,
1023 : uint32_t local_pref);
1024 : BgpAttrPtr ReplaceOriginatorIdAndLocate(const BgpAttr *attr,
1025 : Ip4Address originator_id);
1026 : BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr,
1027 : const RouteDistinguisher &source_rd);
1028 : BgpAttrPtr ReplaceEsiAndLocate(const BgpAttr *attr,
1029 : const EthernetSegmentId &esi);
1030 : BgpAttrPtr ReplaceOListAndLocate(const BgpAttr *attr,
1031 : const BgpOListSpec *olist_spec);
1032 : BgpAttrPtr ReplaceLeafOListAndLocate(const BgpAttr *attr,
1033 : const BgpOListSpec *leaf_olist_spec);
1034 : BgpAttrPtr ReplacePmsiTunnelAndLocate(const BgpAttr *attr,
1035 : const PmsiTunnelSpec *pmsi_spec);
1036 : BgpAttrPtr ReplaceNexthopAndLocate(const BgpAttr *attr,
1037 : const IpAddress &addr);
1038 : BgpAttrPtr ReplaceSubProtocolAndLocate(const BgpAttr *attr,
1039 : const std::string &sbp);
1040 770872 : BgpServer *server() { return server_; }
1041 2355368 : const BgpServer *server() const { return server_; }
1042 :
1043 : private:
1044 : BgpServer *server_;
1045 : };
1046 :
1047 : #endif // SRC_BGP_BGP_ATTR_H_
|