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