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 43723 : RTargetPrefix::RTargetPrefix() : as_(0), rtarget_(RouteTarget::null_rtarget) { 17 43723 : } 18 : 19 38160 : int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, 20 : RTargetPrefix *prefix) { 21 38160 : size_t nlri_size = proto_prefix.prefix.size(); 22 38157 : if (nlri_size == 0) { 23 17 : prefix->as_ = 0; 24 17 : prefix->rtarget_ = RouteTarget::null_rtarget; 25 17 : return 0; 26 : } 27 : 28 38140 : size_t expected_nlri_size = sizeof(as_t) + RouteTarget::kSize; 29 38140 : if (nlri_size != expected_nlri_size) 30 4 : return -1; 31 : 32 38136 : size_t as_offset = 0; 33 38136 : prefix->as_ = get_value(&proto_prefix.prefix[as_offset], sizeof(as_t)); 34 38130 : size_t rtarget_offset = as_offset + sizeof(as_t); 35 38130 : RouteTarget::bytes_type bt = { { 0 } }; 36 38130 : copy(proto_prefix.prefix.begin() + rtarget_offset, 37 : proto_prefix.prefix.end(), bt.begin()); 38 38120 : prefix->rtarget_ = RouteTarget(bt); 39 : 40 38123 : return 0; 41 : } 42 : 43 38153 : 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 38153 : return FromProtoPrefix(proto_prefix, prefix); 51 : } 52 : 53 38095 : void RTargetPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix) const { 54 38095 : proto_prefix->prefix.clear(); 55 38095 : if (as_ == 0 && rtarget_ == RouteTarget::null_rtarget) { 56 9 : proto_prefix->prefixlen = 0; 57 9 : return; 58 : } 59 : 60 38086 : size_t nlri_size = sizeof(as_t) + RouteTarget::kSize; 61 38086 : proto_prefix->prefix.resize(nlri_size); 62 38086 : proto_prefix->prefixlen = nlri_size * 8; 63 38086 : size_t as_offset = 0; 64 38086 : put_value(&proto_prefix->prefix[as_offset], sizeof(as_t), as_); 65 38086 : size_t rtarget_offset = as_offset + sizeof(as_t); 66 38086 : put_value(&proto_prefix->prefix[rtarget_offset], RouteTarget::kSize, 67 : rtarget_.GetExtCommunityValue()); 68 : } 69 : 70 : // as:rtarget 71 5510 : RTargetPrefix RTargetPrefix::FromString(const string &str, error_code *errorp) { 72 5510 : RTargetPrefix prefix; 73 : 74 5510 : if (str == kDefaultPrefixString) 75 61 : return RTargetPrefix(); 76 : 77 5449 : size_t pos = str.find(':'); 78 5449 : 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 5448 : string asstr = str.substr(0, pos); 86 5448 : stringToInteger(asstr, as); 87 : 88 5448 : string rtargetstr(str, pos + 1); 89 5448 : error_code rtarget_err; 90 5448 : RouteTarget rtarget; 91 5448 : rtarget = RouteTarget::FromString(rtargetstr, &rtarget_err); 92 5448 : if (rtarget_err.failed()) { 93 3 : if (errorp != NULL) 94 1 : *errorp = rtarget_err; 95 3 : return prefix; 96 : } 97 : 98 5445 : prefix.rtarget_ = rtarget; 99 5445 : prefix.as_ = as; 100 5445 : return prefix; 101 5448 : } 102 : 103 26500 : string RTargetPrefix::ToString() const { 104 53000 : return (integerToString(as_) + ":" + rtarget_.ToString()); 105 : } 106 : 107 1637913 : int RTargetPrefix::CompareTo(const RTargetPrefix &rhs) const { 108 1637913 : if (as_ < rhs.as_) { 109 173690 : return -1; 110 : } 111 1464223 : if (as_ > rhs.as_) { 112 140539 : return 1; 113 : } 114 1323684 : if (rtarget_ < rhs.rtarget_) { 115 595629 : return -1; 116 : } 117 728055 : if (rtarget_ > rhs.rtarget_) { 118 410330 : return 1; 119 : } 120 317725 : return 0; 121 : } 122 :