LCOV - code coverage report
Current view: top level - net - rd.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 96 96 100.0 %
Date: 2026-05-18 11:54:02 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "net/rd.h"
       6             : 
       7             : #include <string>
       8             : 
       9             : #include "base/parse_object.h"
      10             : #include "base/address.h"
      11             : 
      12             : using std::string;
      13             : 
      14             : RouteDistinguisher RouteDistinguisher::kZeroRd;
      15             : 
      16     1892725 : RouteDistinguisher::RouteDistinguisher() {
      17     1892725 :     memset(data_, 0, kSize);
      18     1892725 : }
      19             : 
      20      189257 : RouteDistinguisher::RouteDistinguisher(const uint8_t *data) {
      21      189257 :     memcpy(data_, data, kSize);
      22      189257 : }
      23             : 
      24      233464 : RouteDistinguisher::RouteDistinguisher(uint32_t address, uint16_t vrf_id) {
      25      233464 :     put_value(data_, 2, TypeIpAddressBased);
      26      233470 :     put_value(data_ + 2, 4, address);
      27      233470 :     put_value(data_ + 6, 2, vrf_id);
      28      233471 : }
      29             : 
      30        1240 : RouteDistinguisher::RouteDistinguisher(bool is_bgpaas, uint32_t asn, uint16_t vmi_index) {
      31        1240 :     put_value(data_, 2, Type4ByteASBased);
      32        1240 :     put_value(data_ + 2, 4, asn);
      33        1240 :     put_value(data_ + 6, 2, vmi_index);
      34        1240 : }
      35             : 
      36           8 : RouteDistinguisher::RouteDistinguisher(uint16_t cluster_seed, uint32_t address,
      37           8 :                                        uint16_t vrf_id) {
      38           8 :     put_value(data_, 2, TypeIpAddressBased);
      39           8 :     put_value(data_ + 2, 2, cluster_seed);
      40           8 :     put_value(data_ + 4, 2, (address & 0xFFFF));
      41           8 :     put_value(data_ + 6, 2, vrf_id);
      42           8 : }
      43             : 
      44       63115 : uint16_t RouteDistinguisher::Type() const {
      45       63115 :     return get_value(data_, 2);
      46             : }
      47             : 
      48       41583 : uint32_t RouteDistinguisher::GetAddress() const {
      49       41583 :     return (Type() == TypeIpAddressBased ? get_value(data_ + 2, 4) : 0);
      50             : }
      51             : 
      52       20069 : uint16_t RouteDistinguisher::GetVrfId() const {
      53       20069 :     return (Type() == TypeIpAddressBased ? get_value(data_ + 6, 2) : 0);
      54             : }
      55             : 
      56     2364610 : string RouteDistinguisher::ToString() const {
      57             :     char temp[32];
      58             : 
      59     2364610 :     uint16_t rd_type = get_value(data_, 2);
      60     2364607 :     if (rd_type == Type2ByteASBased) {
      61      674743 :         uint16_t asn = get_value(data_ + 2, 2);
      62      674756 :         uint32_t value = get_value(data_ + 4, 4);
      63      674756 :         snprintf(temp, sizeof(temp), "%u:%u", asn, value);
      64      674756 :         return string(temp);
      65     1689864 :     } else if (rd_type == TypeIpAddressBased) {
      66     1688276 :         Ip4Address ip(get_value(data_ + 2, 4));
      67     1688273 :         uint16_t value = get_value(data_ + 6, 2);
      68     1688272 :         snprintf(temp, sizeof(temp), ":%u", value);
      69     3376551 :         return ip.to_string() + temp;
      70        1588 :     } else if (rd_type == Type4ByteASBased) {
      71        1586 :         uint32_t asn = get_value(data_ + 2, 4);
      72        1586 :         uint16_t value = get_value(data_ + 6, 2);
      73        1586 :         snprintf(temp, sizeof(temp), "%u:%u", asn, value);
      74        1586 :         return string(temp);
      75             :     } else {
      76           2 :         snprintf(temp, sizeof(temp), "%u:%02x:%02x:%02x:%02x:%02x:%02x",
      77           2 :             rd_type, data_[2], data_[3], data_[4], data_[5], data_[6],
      78           2 :             data_[7]);
      79           2 :         return string(temp);
      80             :     }
      81             : }
      82             : 
      83      176164 : RouteDistinguisher RouteDistinguisher::FromString(
      84             :     const string &str, boost::system::error_code *errorp) {
      85      176164 :     RouteDistinguisher rd;
      86      176164 :     size_t pos = str.rfind(':');
      87      176164 :     if (pos == string::npos) {
      88          33 :         if (errorp != NULL) {
      89           1 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      90             :         }
      91          33 :         return RouteDistinguisher::kZeroRd;
      92             :     }
      93             : 
      94      176131 :     boost::system::error_code ec;
      95      176131 :     string first(str.substr(0, pos));
      96      176131 :     Ip4Address addr = Ip4Address::from_string(first, ec);
      97             :     int offset;
      98             :     char *endptr;
      99      176131 :     int32_t asn = -1;
     100      176131 :     if (ec.value() != 0) {
     101             :         // Not an IP address, try ASN.
     102       69718 :         asn = strtol(first.c_str(), &endptr, 10);
     103       69718 :         if (asn >= 65535 || *endptr != '\0') {
     104           8 :             if (errorp != NULL) {
     105             :                 *errorp =
     106           8 :                     make_error_code(boost::system::errc::invalid_argument);
     107             :             }
     108           8 :             return RouteDistinguisher::kZeroRd;
     109             :         }
     110             : 
     111       69710 :         put_value(rd.data_, 2, 0);
     112       69710 :         put_value(rd.data_ + 2, 2, asn);
     113       69710 :         offset = 4;
     114             :     } else {
     115      106413 :         put_value(rd.data_, 2, 1);
     116      106413 :         put_value(rd.data_ + 2, 4, addr.to_ulong());
     117      106413 :         offset = 6;
     118             :     }
     119             : 
     120      176123 :     string second(str, pos + 1);
     121      176123 :     uint64_t value = strtol(second.c_str(), &endptr, 10);
     122      176123 :     if (*endptr != '\0') {
     123           4 :         if (errorp != NULL) {
     124           4 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     125             :         }
     126           4 :         return RouteDistinguisher::kZeroRd;
     127             :     }
     128             : 
     129             :     // ASN 0 is not allowed if the assigned number is not 0.
     130      176119 :     if (asn == 0 && value != 0) {
     131           2 :         if (errorp != NULL) {
     132           2 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     133             :         }
     134           2 :         return RouteDistinguisher::kZeroRd;
     135             :     }
     136             : 
     137             :     // Check assigned number for type 0.
     138      176117 :     if (offset == 4 && value > 0xFFFFFFFF) {
     139           2 :         if (errorp != NULL) {
     140           2 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     141             :         }
     142           2 :         return RouteDistinguisher::kZeroRd;
     143             :     }
     144             : 
     145             :     // Check assigned number for type 1.
     146      176115 :     if (offset == 6 && value > 0xFFFF) {
     147          11 :         if (errorp != NULL) {
     148          11 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     149             :         }
     150          11 :         return RouteDistinguisher::kZeroRd;
     151             :     }
     152             : 
     153      176104 :     put_value(rd.data_ + offset, 8 - offset, value);
     154      176104 :     return rd;
     155      176131 : }
     156             : 
     157    39294499 : int RouteDistinguisher::CompareTo(const RouteDistinguisher &rhs) const {
     158    39294499 :     return memcmp(data_, rhs.data_, kSize);
     159             : }

Generated by: LCOV version 1.14