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