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 43568 : RTargetPrefix::RTargetPrefix() : as_(0), rtarget_(RouteTarget::null_rtarget) { 17 43568 : } 18 : 19 37886 : int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, 20 : RTargetPrefix *prefix) { 21 37886 : size_t nlri_size = proto_prefix.prefix.size(); 22 37886 : if (nlri_size == 0) { 23 17 : prefix->as_ = 0; 24 17 : prefix->rtarget_ = RouteTarget::null_rtarget; 25 17 : return 0; 26 : } 27 : 28 37869 : size_t expected_nlri_size = sizeof(as_t) + RouteTarget::kSize; 29 37869 : if (nlri_size != expected_nlri_size) 30 4 : return -1; 31 : 32 37865 : size_t as_offset = 0; 33 37865 : prefix->as_ = get_value(&proto_prefix.prefix[as_offset], sizeof(as_t)); 34 37862 : size_t rtarget_offset = as_offset + sizeof(as_t); 35 37862 : RouteTarget::bytes_type bt = { { 0 } }; 36 37862 : copy(proto_prefix.prefix.begin() + rtarget_offset, 37 : proto_prefix.prefix.end(), bt.begin()); 38 37858 : prefix->rtarget_ = RouteTarget(bt); 39 : 40 37855 : return 0; 41 : } 42 : 43 37880 : 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 37880 : return FromProtoPrefix(proto_prefix, prefix); 51 : } 52 : 53 37965 : void RTargetPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix) const { 54 37965 : proto_prefix->prefix.clear(); 55 37965 : if (as_ == 0 && rtarget_ == RouteTarget::null_rtarget) { 56 9 : proto_prefix->prefixlen = 0; 57 9 : return; 58 : } 59 : 60 37956 : size_t nlri_size = sizeof(as_t) + RouteTarget::kSize; 61 37956 : proto_prefix->prefix.resize(nlri_size); 62 37956 : proto_prefix->prefixlen = nlri_size * 8; 63 37956 : size_t as_offset = 0; 64 37956 : put_value(&proto_prefix->prefix[as_offset], sizeof(as_t), as_); 65 37956 : size_t rtarget_offset = as_offset + sizeof(as_t); 66 37956 : put_value(&proto_prefix->prefix[rtarget_offset], RouteTarget::kSize, 67 : rtarget_.GetExtCommunityValue()); 68 : } 69 : 70 : // as:rtarget 71 5586 : RTargetPrefix RTargetPrefix::FromString(const string &str, error_code *errorp) { 72 5586 : RTargetPrefix prefix; 73 : 74 5586 : if (str == kDefaultPrefixString) 75 102 : return RTargetPrefix(); 76 : 77 5484 : size_t pos = str.find(':'); 78 5484 : 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 5483 : string asstr = str.substr(0, pos); 86 5483 : stringToInteger(asstr, as); 87 : 88 5483 : string rtargetstr(str, pos + 1); 89 5483 : error_code rtarget_err; 90 5483 : RouteTarget rtarget; 91 5483 : rtarget = RouteTarget::FromString(rtargetstr, &rtarget_err); 92 5483 : if (rtarget_err.failed()) { 93 3 : if (errorp != NULL) 94 1 : *errorp = rtarget_err; 95 3 : return prefix; 96 : } 97 : 98 5480 : prefix.rtarget_ = rtarget; 99 5480 : prefix.as_ = as; 100 5480 : return prefix; 101 5483 : } 102 : 103 26464 : string RTargetPrefix::ToString() const { 104 52928 : return (integerToString(as_) + ":" + rtarget_.ToString()); 105 : } 106 : 107 1632028 : int RTargetPrefix::CompareTo(const RTargetPrefix &rhs) const { 108 1632028 : if (as_ < rhs.as_) { 109 170857 : return -1; 110 : } 111 1461171 : if (as_ > rhs.as_) { 112 134761 : return 1; 113 : } 114 1326410 : if (rtarget_ < rhs.rtarget_) { 115 597420 : return -1; 116 : } 117 728990 : if (rtarget_ > rhs.rtarget_) { 118 410429 : return 1; 119 : } 120 318561 : return 0; 121 : } 122 :