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