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 46123 : RTargetPrefix::RTargetPrefix() : as_(0), rtarget_(RouteTarget::null_rtarget) { 17 46123 : } 18 : 19 40585 : int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, 20 : RTargetPrefix *prefix) { 21 40585 : size_t nlri_size = proto_prefix.prefix.size(); 22 40583 : if (nlri_size == 0) { 23 17 : prefix->as_ = 0; 24 17 : prefix->rtarget_ = RouteTarget::null_rtarget; 25 17 : return 0; 26 : } 27 : 28 40566 : size_t expected_nlri_size = sizeof(as_t) + RouteTarget::kSize; 29 40566 : if (nlri_size != expected_nlri_size) 30 4 : return -1; 31 : 32 40562 : size_t as_offset = 0; 33 40562 : prefix->as_ = get_value(&proto_prefix.prefix[as_offset], sizeof(as_t)); 34 40557 : size_t rtarget_offset = as_offset + sizeof(as_t); 35 40557 : RouteTarget::bytes_type bt = { { 0 } }; 36 40557 : copy(proto_prefix.prefix.begin() + rtarget_offset, 37 : proto_prefix.prefix.end(), bt.begin()); 38 40541 : prefix->rtarget_ = RouteTarget(bt); 39 : 40 40540 : return 0; 41 : } 42 : 43 40578 : 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 40578 : return FromProtoPrefix(proto_prefix, prefix); 51 : } 52 : 53 40555 : void RTargetPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix) const { 54 40555 : proto_prefix->prefix.clear(); 55 40555 : if (as_ == 0 && rtarget_ == RouteTarget::null_rtarget) { 56 9 : proto_prefix->prefixlen = 0; 57 9 : return; 58 : } 59 : 60 40546 : size_t nlri_size = sizeof(as_t) + RouteTarget::kSize; 61 40546 : proto_prefix->prefix.resize(nlri_size); 62 40546 : proto_prefix->prefixlen = nlri_size * 8; 63 40546 : size_t as_offset = 0; 64 40546 : put_value(&proto_prefix->prefix[as_offset], sizeof(as_t), as_); 65 40546 : size_t rtarget_offset = as_offset + sizeof(as_t); 66 40546 : put_value(&proto_prefix->prefix[rtarget_offset], RouteTarget::kSize, 67 : rtarget_.GetExtCommunityValue()); 68 : } 69 : 70 : // as:rtarget 71 5499 : RTargetPrefix RTargetPrefix::FromString(const string &str, error_code *errorp) { 72 5499 : RTargetPrefix prefix; 73 : 74 5499 : if (str == kDefaultPrefixString) 75 63 : return RTargetPrefix(); 76 : 77 5436 : size_t pos = str.find(':'); 78 5436 : 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 5435 : string asstr = str.substr(0, pos); 86 5435 : stringToInteger(asstr, as); 87 : 88 5435 : string rtargetstr(str, pos + 1); 89 5435 : error_code rtarget_err; 90 5435 : RouteTarget rtarget; 91 5435 : rtarget = RouteTarget::FromString(rtargetstr, &rtarget_err); 92 5435 : if (rtarget_err.failed()) { 93 3 : if (errorp != NULL) 94 1 : *errorp = rtarget_err; 95 3 : return prefix; 96 : } 97 : 98 5432 : prefix.rtarget_ = rtarget; 99 5432 : prefix.as_ = as; 100 5432 : return prefix; 101 5435 : } 102 : 103 27074 : string RTargetPrefix::ToString() const { 104 54148 : return (integerToString(as_) + ":" + rtarget_.ToString()); 105 : } 106 : 107 1706960 : int RTargetPrefix::CompareTo(const RTargetPrefix &rhs) const { 108 1706960 : if (as_ < rhs.as_) { 109 186469 : return -1; 110 : } 111 1520491 : if (as_ > rhs.as_) { 112 147004 : return 1; 113 : } 114 1373487 : if (rtarget_ < rhs.rtarget_) { 115 617430 : return -1; 116 : } 117 756057 : if (rtarget_ > rhs.rtarget_) { 118 423579 : return 1; 119 : } 120 332478 : return 0; 121 : } 122 :