Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/rtarget/rtarget_prefix.h" 6 : 7 : #include <algorithm> 8 : #include "base/string_util.h" 9 : 10 : using boost::system::error_code; 11 : using std::copy; 12 : using std::string; 13 : 14 : const string RTargetPrefix::kDefaultPrefixString = "0:target:0:0"; 15 : 16 43937 : RTargetPrefix::RTargetPrefix() : as_(0), rtarget_(RouteTarget::null_rtarget) { 17 43937 : } 18 : 19 38292 : int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, 20 : RTargetPrefix *prefix) { 21 38292 : size_t nlri_size = proto_prefix.prefix.size(); 22 38290 : if (nlri_size == 0) { 23 17 : prefix->as_ = 0; 24 17 : prefix->rtarget_ = RouteTarget::null_rtarget; 25 17 : return 0; 26 : } 27 : 28 38273 : size_t expected_nlri_size = sizeof(as_t) + RouteTarget::kSize; 29 38273 : if (nlri_size != expected_nlri_size) 30 4 : return -1; 31 : 32 38269 : size_t as_offset = 0; 33 38269 : prefix->as_ = get_value(&proto_prefix.prefix[as_offset], sizeof(as_t)); 34 38265 : size_t rtarget_offset = as_offset + sizeof(as_t); 35 38265 : RouteTarget::bytes_type bt = { { 0 } }; 36 38265 : copy(proto_prefix.prefix.begin() + rtarget_offset, 37 : proto_prefix.prefix.end(), bt.begin()); 38 38254 : prefix->rtarget_ = RouteTarget(bt); 39 : 40 38252 : return 0; 41 : } 42 : 43 38285 : int RTargetPrefix::FromProtoPrefix(BgpServer *server, 44 : const BgpProtoPrefix &proto_prefix, 45 : const BgpAttr *attr, 46 : const Address::Family family, 47 : RTargetPrefix *prefix, 48 : BgpAttrPtr *new_attr, uint32_t *label, 49 : uint32_t *l3_label) { 50 38285 : return FromProtoPrefix(proto_prefix, prefix); 51 : } 52 : 53 37696 : void RTargetPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix) const { 54 37696 : proto_prefix->prefix.clear(); 55 37696 : if (as_ == 0 && rtarget_ == RouteTarget::null_rtarget) { 56 9 : proto_prefix->prefixlen = 0; 57 9 : return; 58 : } 59 : 60 37687 : size_t nlri_size = sizeof(as_t) + RouteTarget::kSize; 61 37687 : proto_prefix->prefix.resize(nlri_size); 62 37687 : proto_prefix->prefixlen = nlri_size * 8; 63 37687 : size_t as_offset = 0; 64 37687 : put_value(&proto_prefix->prefix[as_offset], sizeof(as_t), as_); 65 37687 : size_t rtarget_offset = as_offset + sizeof(as_t); 66 37687 : put_value(&proto_prefix->prefix[rtarget_offset], RouteTarget::kSize, 67 : rtarget_.GetExtCommunityValue()); 68 : } 69 : 70 : // as:rtarget 71 5596 : RTargetPrefix RTargetPrefix::FromString(const string &str, error_code *errorp) { 72 5596 : RTargetPrefix prefix; 73 : 74 5596 : if (str == kDefaultPrefixString) 75 64 : return RTargetPrefix(); 76 : 77 5532 : size_t pos = str.find(':'); 78 5532 : if (pos == string::npos) { 79 1 : if (errorp != NULL) 80 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 81 1 : return prefix; 82 : } 83 : 84 : as_t as; 85 5531 : string asstr = str.substr(0, pos); 86 5531 : stringToInteger(asstr, as); 87 : 88 5531 : string rtargetstr(str, pos + 1); 89 5531 : error_code rtarget_err; 90 5531 : RouteTarget rtarget; 91 5531 : rtarget = RouteTarget::FromString(rtargetstr, &rtarget_err); 92 5531 : if (rtarget_err.failed()) { 93 3 : if (errorp != NULL) 94 1 : *errorp = rtarget_err; 95 3 : return prefix; 96 : } 97 : 98 5528 : prefix.rtarget_ = rtarget; 99 5528 : prefix.as_ = as; 100 5528 : return prefix; 101 5531 : } 102 : 103 26502 : string RTargetPrefix::ToString() const { 104 53004 : return (integerToString(as_) + ":" + rtarget_.ToString()); 105 : } 106 : 107 1629979 : int RTargetPrefix::CompareTo(const RTargetPrefix &rhs) const { 108 1629979 : if (as_ < rhs.as_) { 109 171830 : return -1; 110 : } 111 1458149 : if (as_ > rhs.as_) { 112 135483 : return 1; 113 : } 114 1322666 : if (rtarget_ < rhs.rtarget_) { 115 595947 : return -1; 116 : } 117 726719 : if (rtarget_ > rhs.rtarget_) { 118 409338 : return 1; 119 : } 120 317381 : return 0; 121 : } 122 :