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 44056 : RTargetPrefix::RTargetPrefix() : as_(0), rtarget_(RouteTarget::null_rtarget) { 17 44056 : } 18 : 19 38522 : int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, 20 : RTargetPrefix *prefix) { 21 38522 : size_t nlri_size = proto_prefix.prefix.size(); 22 38521 : if (nlri_size == 0) { 23 17 : prefix->as_ = 0; 24 17 : prefix->rtarget_ = RouteTarget::null_rtarget; 25 17 : return 0; 26 : } 27 : 28 38504 : size_t expected_nlri_size = sizeof(as_t) + RouteTarget::kSize; 29 38504 : if (nlri_size != expected_nlri_size) 30 4 : return -1; 31 : 32 38500 : size_t as_offset = 0; 33 38500 : prefix->as_ = get_value(&proto_prefix.prefix[as_offset], sizeof(as_t)); 34 38492 : size_t rtarget_offset = as_offset + sizeof(as_t); 35 38492 : RouteTarget::bytes_type bt = { { 0 } }; 36 38492 : copy(proto_prefix.prefix.begin() + rtarget_offset, 37 : proto_prefix.prefix.end(), bt.begin()); 38 38486 : prefix->rtarget_ = RouteTarget(bt); 39 : 40 38488 : return 0; 41 : } 42 : 43 38516 : 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 38516 : return FromProtoPrefix(proto_prefix, prefix); 51 : } 52 : 53 38249 : void RTargetPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix) const { 54 38249 : proto_prefix->prefix.clear(); 55 38249 : if (as_ == 0 && rtarget_ == RouteTarget::null_rtarget) { 56 9 : proto_prefix->prefixlen = 0; 57 9 : return; 58 : } 59 : 60 38240 : size_t nlri_size = sizeof(as_t) + RouteTarget::kSize; 61 38240 : proto_prefix->prefix.resize(nlri_size); 62 38240 : proto_prefix->prefixlen = nlri_size * 8; 63 38240 : size_t as_offset = 0; 64 38240 : put_value(&proto_prefix->prefix[as_offset], sizeof(as_t), as_); 65 38240 : size_t rtarget_offset = as_offset + sizeof(as_t); 66 38240 : put_value(&proto_prefix->prefix[rtarget_offset], RouteTarget::kSize, 67 : rtarget_.GetExtCommunityValue()); 68 : } 69 : 70 : // as:rtarget 71 5479 : RTargetPrefix RTargetPrefix::FromString(const string &str, error_code *errorp) { 72 5479 : RTargetPrefix prefix; 73 : 74 5479 : if (str == kDefaultPrefixString) 75 60 : return RTargetPrefix(); 76 : 77 5419 : size_t pos = str.find(':'); 78 5419 : 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 5418 : string asstr = str.substr(0, pos); 86 5418 : stringToInteger(asstr, as); 87 : 88 5418 : string rtargetstr(str, pos + 1); 89 5418 : error_code rtarget_err; 90 5418 : RouteTarget rtarget; 91 5418 : rtarget = RouteTarget::FromString(rtargetstr, &rtarget_err); 92 5418 : if (rtarget_err.failed()) { 93 3 : if (errorp != NULL) 94 1 : *errorp = rtarget_err; 95 3 : return prefix; 96 : } 97 : 98 5415 : prefix.rtarget_ = rtarget; 99 5415 : prefix.as_ = as; 100 5415 : return prefix; 101 5418 : } 102 : 103 26527 : string RTargetPrefix::ToString() const { 104 53054 : return (integerToString(as_) + ":" + rtarget_.ToString()); 105 : } 106 : 107 1632309 : int RTargetPrefix::CompareTo(const RTargetPrefix &rhs) const { 108 1632309 : if (as_ < rhs.as_) { 109 170911 : return -1; 110 : } 111 1461398 : if (as_ > rhs.as_) { 112 137293 : return 1; 113 : } 114 1324105 : if (rtarget_ < rhs.rtarget_) { 115 596469 : return -1; 116 : } 117 727636 : if (rtarget_ > rhs.rtarget_) { 118 408973 : return 1; 119 : } 120 318663 : return 0; 121 : } 122 :