|
xorp
|
00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- 00002 // vim:set sts=4 ts=8: 00003 00004 // Copyright (c) 2001-2011 XORP, Inc and Others 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License, Version 2, June 00008 // 1991 as published by the Free Software Foundation. Redistribution 00009 // and/or modification of this program under the terms of any other 00010 // version of the GNU General Public License is not permitted. 00011 // 00012 // This program is distributed in the hope that it will be useful, but 00013 // WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details, 00015 // see the GNU General Public License, Version 2, a copy of which can be 00016 // found in the XORP LICENSE.gpl file. 00017 // 00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; 00019 // http://xorp.net 00020 00021 // $XORP: xorp/bgp/aspath.hh,v 1.34 2008/10/02 21:56:14 bms Exp $ 00022 00023 #ifndef __BGP_ASPATH_HH__ 00024 #define __BGP_ASPATH_HH__ 00025 00026 #include <sys/types.h> 00027 #include <inttypes.h> 00028 00029 00030 00031 00032 #include "libxorp/xorp.h" 00033 #include "libxorp/debug.h" 00034 #include "libxorp/xlog.h" 00035 #include "libxorp/asnum.hh" 00036 #include "libxorp/exceptions.hh" 00037 #include "exceptions.hh" 00038 00039 class AS4Path; 00040 00110 // AS Path Values 00111 enum ASPathSegType { 00112 AS_NONE = 0, // not initialized 00113 AS_SET = 1, 00114 AS_SEQUENCE = 2, 00115 AS_CONFED_SEQUENCE = 3, 00116 AS_CONFED_SET = 4 00117 }; 00118 00122 class ASSegment { 00123 public: 00124 typedef list<AsNum> ASLIST; 00125 typedef ASLIST::iterator iterator; 00126 typedef ASLIST::const_iterator const_iterator; 00127 typedef ASLIST::const_reverse_iterator const_reverse_iterator; 00128 00132 ASSegment(ASPathSegType t = AS_NONE) : _type(t) { 00133 } 00134 00142 ASSegment(const uint8_t* d) throw(CorruptMessage) { 00143 decode(d); 00144 } 00145 00149 ASSegment(const ASSegment& a) : 00150 _type(a._type), _aslist(a._aslist) {} 00151 00156 ~ASSegment() {} 00157 00161 void clear() { 00162 _type = AS_NONE; 00163 _aslist.clear(); 00164 } 00165 00170 size_t path_length() const { 00171 if (_type == AS_SET || _type == AS_CONFED_SET) 00172 return 1; 00173 else if (_type == AS_SEQUENCE || _type == AS_CONFED_SEQUENCE) 00174 return _aslist.size(); 00175 else 00176 return 0; // XXX should not be called! 00177 } 00178 00179 size_t as_size() const { 00180 return _aslist.size(); 00181 } 00182 00188 void add_as(const AsNum& n) { 00189 debug_msg("Number of As entries %u\n", XORP_UINT_CAST(_aslist.size())); 00190 _aslist.push_back(n); 00191 } 00192 00198 void prepend_as(const AsNum& n) { 00199 debug_msg("Number of As entries %u\n", XORP_UINT_CAST(_aslist.size())); 00200 _aslist.push_front(n); 00201 } 00202 00206 bool contains(const AsNum& as_num) const { 00207 const_iterator iter; 00208 00209 for (iter = _aslist.begin(); iter != _aslist.end(); ++iter) 00210 if (*iter == as_num) 00211 return true; 00212 return false; 00213 } 00214 00215 const AsNum& first_asnum() const; 00216 00220 const AsNum& as_num(int n) const { 00221 const_iterator i = _aslist.begin(); 00222 00223 while (n--) 00224 i++; 00225 00226 return *i; 00227 } 00228 00233 void decode(const uint8_t *d) throw(CorruptMessage); 00234 00242 const uint8_t *encode(size_t &len, uint8_t *buf) const; 00243 00247 size_t wire_size() const { 00248 return 2 + 2 * _aslist.size(); 00249 } 00250 00254 string str() const; 00255 00259 string short_str() const; 00260 00264 bool operator==(const ASSegment& him) const; 00265 00269 bool operator<(const ASSegment& him) const; 00270 00271 ASPathSegType type() const { return _type; } 00272 void set_type(ASPathSegType t) { _type = t; } 00273 00274 size_t encode_for_mib(uint8_t* buf, size_t buf_size) const; 00275 00280 bool two_byte_compatible() const; 00281 00282 protected: 00283 ASPathSegType _type; 00284 ASLIST _aslist; 00285 }; 00286 00287 00288 /* subsclass of ASSegment to handle encoding and decoding of 4-byte AS 00289 numbers from a AS4_PATH attribute */ 00290 class AS4Segment : public ASSegment { 00291 public: 00292 AS4Segment(const uint8_t* d) throw(CorruptMessage) { decode(d); } 00297 void decode(const uint8_t *d) throw(CorruptMessage); 00298 00306 const uint8_t *encode(size_t &len, uint8_t *buf) const; 00307 00311 size_t wire_size() const { 00312 return 2 + 4 * _aslist.size(); 00313 } 00314 private: 00315 /* no storage, as this is handled by the underlying ASSegment */ 00316 }; 00317 00322 class ASPath { 00323 public: 00324 typedef list <ASSegment>::const_iterator const_iterator; 00325 typedef list <ASSegment>::iterator iterator; 00326 00327 ASPath() : _num_segments(0), _path_len(0) {} 00328 00333 ASPath(const char *as_path) throw(InvalidString); 00334 00338 ASPath(const uint8_t* d, size_t len) throw(CorruptMessage) { 00339 decode(d, len); 00340 } 00341 00345 ASPath(const ASPath &asp1, const ASPath &asp2); 00346 00350 ASPath(const ASPath &a) : _segments(a._segments), 00351 _num_segments(a._num_segments), _path_len(a._path_len) {} 00352 00353 ~ASPath() {} 00354 00355 void add_segment(const ASSegment& s); 00356 void prepend_segment(const ASSegment& s); 00357 00358 size_t path_length() const { return _path_len; } 00359 00360 bool contains(const AsNum& as_num) const { 00361 const_iterator i = _segments.begin(); 00362 for (; i != _segments.end(); ++i) 00363 if ((*i).contains(as_num)) 00364 return true; 00365 return false; 00366 } 00367 00368 const AsNum& first_asnum() const { 00369 XLOG_ASSERT(!_segments.empty()); 00370 return _segments.front().first_asnum(); 00371 } 00372 00373 string str() const; 00374 string short_str() const; 00375 00376 const ASSegment& segment(size_t n) const { 00377 if (n < _num_segments) { 00378 const_iterator iter = _segments.begin(); 00379 for (u_int i = 0; i<n; i++) 00380 ++iter; 00381 return (*iter); 00382 } 00383 XLOG_FATAL("Segment %u doesn't exist.", (uint32_t)n); 00384 xorp_throw(InvalidString, "segment invalid n\n"); 00385 } 00386 00387 size_t num_segments() const { return _num_segments; } 00388 00400 const uint8_t *encode(size_t &len, uint8_t *buf) const; 00401 00406 size_t wire_size() const; 00407 00413 void prepend_as(const AsNum &asn); 00414 00421 void prepend_confed_as(const AsNum &asn); 00422 00426 void remove_confed_segments(); 00427 00431 bool contains_confed_segments() const; 00432 00433 ASPath& operator=(const ASPath& him); 00434 00435 bool operator==(const ASPath& him) const; 00436 00437 bool operator<(const ASPath& him) const; 00438 00439 void encode_for_mib(vector<uint8_t>& aspath) const; 00440 00444 bool two_byte_compatible() const; 00445 00452 void merge_as4_path(AS4Path& as4_path); 00453 00454 protected: 00458 list <ASSegment> _segments; 00459 size_t _num_segments; 00460 size_t _path_len; 00461 00462 private: 00466 void decode(const uint8_t *d, size_t len) throw(CorruptMessage); 00467 }; 00468 00469 /* subclass to handle 4-byte AS encoding and decoding */ 00470 class AS4Path : public ASPath { 00471 public: 00475 AS4Path(const uint8_t* d, size_t len) throw(CorruptMessage); 00476 00481 AS4Path(const char *as_path) throw(InvalidString) 00482 : ASPath(as_path) 00483 {}; 00484 00485 #if 0 00486 00491 AS4Path(const uint8_t* d, size_t len, const ASPath& as_path) 00492 throw(CorruptMessage); 00493 00494 #endif 00495 00505 const uint8_t *encode(size_t &len, uint8_t *buf) const; 00506 00507 size_t wire_size() const; 00508 00509 void cross_validate(const ASPath& as_path); 00510 00511 private: 00515 void decode(const uint8_t *d, size_t len) throw(CorruptMessage); 00516 void pad_segment(const ASSegment& old_seg, ASSegment& new_seg); 00517 void do_patchup(const ASPath& as_path); 00518 }; 00519 00520 #endif // __BGP_ASPATH_HH__