Line data Source code
1 : /* 2 : * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/extended-community/vrf_route_import.h" 6 : 7 : #include <algorithm> 8 : 9 : #include "base/address.h" 10 : 11 : using std::copy; 12 : using std::string; 13 : 14 : VrfRouteImport VrfRouteImport::null_rt_import; 15 : 16 171 : VrfRouteImport::VrfRouteImport() { 17 171 : data_.fill(0); 18 171 : } 19 : 20 119 : VrfRouteImport::VrfRouteImport(const bytes_type &data) { 21 119 : copy(data.begin(), data.end(), data_.begin()); 22 119 : } 23 : 24 115 : Ip4Address VrfRouteImport::GetIPv4Address() const { 25 115 : return Ip4Address(get_value(&data_[2], 4)); 26 : } 27 : 28 115 : uint16_t VrfRouteImport::GetNumber() const { 29 115 : return get_value(&data_[6], 2); 30 : } 31 : 32 194 : VrfRouteImport::VrfRouteImport(const uint32_t bgp_id, const uint32_t ri_index) { 33 194 : data_[0] = BgpExtendedCommunityType::IPv4Address; 34 194 : data_[1] = BgpExtendedCommunitySubType::VrfRouteImport; 35 194 : put_value(&data_[2], 4, bgp_id); 36 194 : put_value(&data_[6], VrfRouteImport::kSize - 6, ri_index); 37 194 : } 38 : 39 8 : string VrfRouteImport::ToString() const { 40 : uint8_t data[VrfRouteImport::kSize]; 41 8 : copy(data_.begin(), data_.end(), &data[0]); 42 8 : if (data[0] == BgpExtendedCommunityType::IPv4Address) { 43 8 : Ip4Address addr(get_value(data + 2, 4)); 44 8 : uint16_t num = get_value(data + 6, 2); 45 : char temp[50]; 46 8 : snprintf(temp, sizeof(temp), "rt-import:%s:%u", 47 16 : addr.to_string().c_str(), num); 48 8 : return string(temp); 49 : } 50 0 : return ""; 51 : } 52 : 53 11 : VrfRouteImport VrfRouteImport::FromString(const string &str, 54 : boost::system::error_code *errorp) { 55 11 : VrfRouteImport rt_import; 56 : uint8_t data[VrfRouteImport::kSize]; 57 : 58 : // rt-import:1.2.3.4:3 59 11 : size_t pos = str.find(':'); 60 11 : if (pos == string::npos) { 61 1 : if (errorp != NULL) { 62 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 63 : } 64 1 : return VrfRouteImport::null_rt_import; 65 : } 66 : 67 10 : string first(str.substr(0, pos)); 68 10 : if (first != "rt-import") { 69 1 : if (errorp != NULL) { 70 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 71 : } 72 1 : return VrfRouteImport::null_rt_import; 73 : } 74 : 75 9 : string rest(str.substr(pos+1)); 76 : 77 9 : pos = rest.find(':'); 78 9 : if (pos == string::npos) { 79 1 : if (errorp != NULL) { 80 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 81 : } 82 1 : return VrfRouteImport::null_rt_import; 83 : } 84 : 85 8 : boost::system::error_code ec; 86 8 : string second(rest.substr(0, pos)); 87 8 : Ip4Address addr = Ip4Address::from_string(second, ec); 88 : char *endptr; 89 8 : if (ec.failed()) { 90 : // Not an IP address. 91 1 : if (errorp != NULL) { 92 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 93 : } 94 1 : return VrfRouteImport::null_rt_import; 95 : } 96 7 : data[0] = BgpExtendedCommunityType::IPv4Address; 97 7 : data[1] = BgpExtendedCommunitySubType::VrfRouteImport; 98 7 : uint32_t l_addr = addr.to_ulong(); 99 7 : put_value(&data[2], 4, l_addr); 100 7 : int offset = 6; 101 : 102 7 : string third(rest.substr(pos+1)); 103 7 : uint64_t value = strtol(third.c_str(), &endptr, 10); 104 7 : if (*endptr != '\0') { 105 2 : if (errorp != NULL) { 106 2 : *errorp = make_error_code(boost::system::errc::invalid_argument); 107 : } 108 2 : return VrfRouteImport::null_rt_import; 109 : } 110 : 111 : // Check assigned number. 112 5 : if (value > 0xFFFF) { 113 1 : if (errorp != NULL) { 114 1 : *errorp = make_error_code(boost::system::errc::invalid_argument); 115 : } 116 1 : return VrfRouteImport::null_rt_import; 117 : } 118 : 119 4 : put_value(&data[offset], VrfRouteImport::kSize - offset, value); 120 4 : copy(&data[0], &data[VrfRouteImport::kSize], rt_import.data_.begin()); 121 4 : return rt_import; 122 10 : }