LCOV - code coverage report
Current view: top level - bgp/l3vpn - inetvpn_address.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 78 81 96.3 %
Date: 2026-06-22 02:21:21 Functions: 8 8 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 "bgp/l3vpn/inetvpn_address.h"
       6             : 
       7             : #include <algorithm>
       8             : 
       9             : #include "bgp/inet/inet_route.h"
      10             : 
      11             : using std::copy;
      12             : using std::string;
      13             : 
      14       71834 : InetVpnPrefix::InetVpnPrefix() : prefixlen_(0) {
      15       71834 : }
      16             : 
      17       67247 : int InetVpnPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix,
      18             :                                InetVpnPrefix *prefix, const BgpAttr *attr,
      19             :                                uint32_t *label) {
      20       67247 :     size_t nlri_size = proto_prefix.prefix.size();
      21       67247 :     size_t expected_min_nlri_size =
      22       67247 :         BgpProtoPrefix::kLabelSize + RouteDistinguisher::kSize;
      23             : 
      24       67247 :     if (nlri_size < expected_min_nlri_size)
      25           1 :         return -1;
      26       67246 :     if (nlri_size > expected_min_nlri_size + Address::kMaxV4Bytes)
      27           1 :         return -1;
      28             : 
      29       67245 :     bool is_vni = false;
      30       67245 :     if (attr != NULL) {
      31       45708 :         const ExtCommunity *extcomm = attr->ext_community();
      32       45708 :         if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
      33          19 :             is_vni = true;
      34             :         }
      35             :     }
      36             : 
      37       67245 :     size_t label_offset = 0;
      38       67245 :     *label = proto_prefix.ReadLabel(label_offset, is_vni); //was ,false
      39       67245 :     size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
      40       67245 :     prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
      41             : 
      42       67245 :     size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
      43       67245 :     prefix->prefixlen_ = proto_prefix.prefixlen - prefix_offset * 8;
      44       67245 :     Ip4Address::bytes_type bt = { { 0 } };
      45       67245 :     copy(proto_prefix.prefix.begin() + prefix_offset,
      46             :         proto_prefix.prefix.end(), bt.begin());
      47       67244 :     prefix->addr_ = Ip4Address(bt);
      48             : 
      49       67244 :     return 0;
      50             : }
      51             : 
      52       67242 : int InetVpnPrefix::FromProtoPrefix(BgpServer *server,
      53             :                                    const BgpProtoPrefix &proto_prefix,
      54             :                                    const BgpAttr *attr,
      55             :                                    const Address::Family family,
      56             :                                    InetVpnPrefix *prefix,
      57             :                                    BgpAttrPtr *new_attr, uint32_t *label,
      58             :                                    uint32_t *l3_label) {
      59       67242 :     int rval = FromProtoPrefix(proto_prefix, prefix, attr, label);
      60       67241 :     return rval;
      61             : }
      62             : 
      63       73908 : void InetVpnPrefix::BuildProtoPrefix(uint32_t label,
      64             :     BgpProtoPrefix *proto_prefix, const BgpAttr *attr) const {
      65       73908 :     proto_prefix->prefix.clear();
      66       73906 :     size_t prefix_size = (prefixlen_ + 7) / 8;
      67       73906 :     size_t nlri_size =
      68       73906 :         BgpProtoPrefix::kLabelSize + RouteDistinguisher::kSize + prefix_size;
      69             : 
      70       73906 :     proto_prefix->prefix.resize(nlri_size, 0);
      71       73899 :     size_t label_offset = 0;
      72             : 
      73       73899 :     bool is_vni = false;
      74       73899 :     if (attr != NULL) {
      75       45692 :         const ExtCommunity *extcomm = attr->ext_community();
      76       45692 :         if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
      77          19 :             is_vni = true;
      78             :         }
      79             :     }
      80             : 
      81       73899 :     proto_prefix->WriteLabel(label_offset, label, is_vni); // was false
      82       73899 :     size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
      83       73898 :     copy(rd_.GetData(), rd_.GetData() + RouteDistinguisher::kSize,
      84       73899 :         proto_prefix->prefix.begin() + rd_offset);
      85             : 
      86       73898 :     size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
      87       73898 :     proto_prefix->prefixlen = prefix_offset * 8 + prefixlen_;
      88       73898 :     const Ip4Address::bytes_type &addr_bytes = addr_.to_bytes();
      89       73897 :     copy(addr_bytes.begin(), addr_bytes.begin() + prefix_size,
      90       73897 :         proto_prefix->prefix.begin() + prefix_offset);
      91       73899 : }
      92             : 
      93             : // RD:inet4-prefix
      94        4586 : InetVpnPrefix InetVpnPrefix::FromString(const string &str,
      95             :                                         boost::system::error_code *errorp) {
      96        4586 :     InetVpnPrefix prefix;
      97             : 
      98        4586 :     size_t pos = str.rfind(':');
      99        4586 :     if (pos == string::npos) {
     100           3 :         if (errorp != NULL) {
     101           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     102             :         }
     103           3 :         return prefix;
     104             :     }
     105        4583 :     string rdstr = str.substr(0, pos);
     106        4583 :     boost::system::error_code rderr;
     107        4583 :     prefix.rd_ = RouteDistinguisher::FromString(rdstr, &rderr);
     108        4583 :     if (rderr.failed()) {
     109           0 :         if (errorp != NULL) {
     110           0 :             *errorp = rderr;
     111             :         }
     112           0 :         return prefix;
     113             :     }
     114             : 
     115        4583 :     string ip4pstr(str, pos + 1);
     116        4583 :     boost::system::error_code pfxerr = Ip4SubnetParse(ip4pstr, &prefix.addr_,
     117             :                                        &prefix.prefixlen_);
     118        4583 :     if (errorp != NULL) {
     119        1800 :         *errorp = pfxerr;
     120             :     }
     121        4583 :     return prefix;
     122        4583 : }
     123             : 
     124          69 : string InetVpnPrefix::ToString() const {
     125          69 :     Ip4Prefix prefix(addr_, prefixlen_);
     126         138 :     return (rd_.ToString() + ":" + prefix.ToString());
     127             : }
     128             : 
     129             : // Check whether 'this' is more specific than rhs.
     130          40 : bool InetVpnPrefix::IsMoreSpecific(const InetVpnPrefix &rhs) const {
     131          40 :     Ip4Prefix this_prefix(addr_, prefixlen_);
     132          40 :     Ip4Prefix match_prefix(rhs.addr(), rhs.prefixlen());
     133             : 
     134          80 :     return this_prefix.IsMoreSpecific(match_prefix);
     135             : }
     136             : 
     137           9 : bool InetVpnPrefix::operator==(const InetVpnPrefix &rhs) const {
     138          18 :     return (rd_ == rhs.rd_ &&
     139          18 :         addr_ == rhs.addr_ &&
     140          18 :         prefixlen_ == rhs.prefixlen_);
     141             : }

Generated by: LCOV version 1.14