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-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "bgp/l3vpn/inetvpn_address.h"
       7             : 
       8             : #include <algorithm>
       9             : 
      10             : #include "bgp/inet/inet_route.h"
      11             : 
      12             : using std::copy;
      13             : using std::string;
      14             : 
      15       71776 : InetVpnPrefix::InetVpnPrefix() : prefixlen_(0) {
      16       71776 : }
      17             : 
      18       67194 : int InetVpnPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix,
      19             :                                InetVpnPrefix *prefix, const BgpAttr *attr,
      20             :                                uint32_t *label) {
      21       67194 :     size_t nlri_size = proto_prefix.prefix.size();
      22       67194 :     size_t expected_min_nlri_size =
      23       67194 :         BgpProtoPrefix::kLabelSize + RouteDistinguisher::kSize;
      24             : 
      25       67194 :     if (nlri_size < expected_min_nlri_size)
      26           1 :         return -1;
      27       67193 :     if (nlri_size > expected_min_nlri_size + Address::kMaxV4Bytes)
      28           1 :         return -1;
      29             : 
      30       67192 :     bool is_vni = false;
      31       67192 :     if (attr != NULL) {
      32       45664 :         const ExtCommunity *extcomm = attr->ext_community();
      33       45664 :         if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
      34          19 :             is_vni = true;
      35             :         }
      36             :     }
      37             : 
      38       67192 :     size_t label_offset = 0;
      39       67192 :     *label = proto_prefix.ReadLabel(label_offset, is_vni); //was ,false
      40       67192 :     size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
      41       67192 :     prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
      42             : 
      43       67192 :     size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
      44       67192 :     prefix->prefixlen_ = proto_prefix.prefixlen - prefix_offset * 8;
      45       67192 :     Ip4Address::bytes_type bt = { { 0 } };
      46       67192 :     copy(proto_prefix.prefix.begin() + prefix_offset,
      47             :         proto_prefix.prefix.end(), bt.begin());
      48       67192 :     prefix->addr_ = Ip4Address(bt);
      49             : 
      50       67192 :     return 0;
      51             : }
      52             : 
      53       67189 : int InetVpnPrefix::FromProtoPrefix(BgpServer *server,
      54             :                                    const BgpProtoPrefix &proto_prefix,
      55             :                                    const BgpAttr *attr,
      56             :                                    const Address::Family family,
      57             :                                    InetVpnPrefix *prefix,
      58             :                                    BgpAttrPtr *new_attr, uint32_t *label,
      59             :                                    uint32_t *l3_label) {
      60       67189 :     int rval = FromProtoPrefix(proto_prefix, prefix, attr, label);
      61       67189 :     return rval;
      62             : }
      63             : 
      64       74573 : void InetVpnPrefix::BuildProtoPrefix(uint32_t label,
      65             :     BgpProtoPrefix *proto_prefix, const BgpAttr *attr) const {
      66       74573 :     proto_prefix->prefix.clear();
      67       74575 :     size_t prefix_size = (prefixlen_ + 7) / 8;
      68       74575 :     size_t nlri_size =
      69       74575 :         BgpProtoPrefix::kLabelSize + RouteDistinguisher::kSize + prefix_size;
      70             : 
      71       74575 :     proto_prefix->prefix.resize(nlri_size, 0);
      72       74566 :     size_t label_offset = 0;
      73             : 
      74       74566 :     bool is_vni = false;
      75       74566 :     if (attr != NULL) {
      76       45768 :         const ExtCommunity *extcomm = attr->ext_community();
      77       45768 :         if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
      78          19 :             is_vni = true;
      79             :         }
      80             :     }
      81             : 
      82       74561 :     proto_prefix->WriteLabel(label_offset, label, is_vni); // was false
      83       74562 :     size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
      84       74559 :     copy(rd_.GetData(), rd_.GetData() + RouteDistinguisher::kSize,
      85       74562 :         proto_prefix->prefix.begin() + rd_offset);
      86             : 
      87       74568 :     size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
      88       74568 :     proto_prefix->prefixlen = prefix_offset * 8 + prefixlen_;
      89       74568 :     const Ip4Address::bytes_type &addr_bytes = addr_.to_bytes();
      90       74566 :     copy(addr_bytes.begin(), addr_bytes.begin() + prefix_size,
      91       74566 :         proto_prefix->prefix.begin() + prefix_offset);
      92       74565 : }
      93             : 
      94             : // RD:inet4-prefix
      95        4580 : InetVpnPrefix InetVpnPrefix::FromString(const string &str,
      96             :                                         boost::system::error_code *errorp) {
      97        4580 :     InetVpnPrefix prefix;
      98             : 
      99        4580 :     size_t pos = str.rfind(':');
     100        4580 :     if (pos == string::npos) {
     101           3 :         if (errorp != NULL) {
     102           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     103             :         }
     104           3 :         return prefix;
     105             :     }
     106        4577 :     string rdstr = str.substr(0, pos);
     107        4577 :     boost::system::error_code rderr;
     108        4577 :     prefix.rd_ = RouteDistinguisher::FromString(rdstr, &rderr);
     109        4577 :     if (rderr.failed()) {
     110           0 :         if (errorp != NULL) {
     111           0 :             *errorp = rderr;
     112             :         }
     113           0 :         return prefix;
     114             :     }
     115             : 
     116        4577 :     string ip4pstr(str, pos + 1);
     117        4577 :     boost::system::error_code pfxerr = Ip4SubnetParse(ip4pstr, &prefix.addr_,
     118             :                                        &prefix.prefixlen_);
     119        4577 :     if (errorp != NULL) {
     120        1788 :         *errorp = pfxerr;
     121             :     }
     122        4577 :     return prefix;
     123        4577 : }
     124             : 
     125          69 : string InetVpnPrefix::ToString() const {
     126          69 :     Ip4Prefix prefix(addr_, prefixlen_);
     127         138 :     return (rd_.ToString() + ":" + prefix.ToString());
     128             : }
     129             : 
     130             : // Check whether 'this' is more specific than rhs.
     131          40 : bool InetVpnPrefix::IsMoreSpecific(const InetVpnPrefix &rhs) const {
     132          40 :     Ip4Prefix this_prefix(addr_, prefixlen_);
     133          40 :     Ip4Prefix match_prefix(rhs.addr(), rhs.prefixlen());
     134             : 
     135          80 :     return this_prefix.IsMoreSpecific(match_prefix);
     136             : }
     137             : 
     138           9 : bool InetVpnPrefix::operator==(const InetVpnPrefix &rhs) const {
     139          18 :     return (rd_ == rhs.rd_ &&
     140          18 :         addr_ == rhs.addr_ &&
     141          18 :         prefixlen_ == rhs.prefixlen_);
     142             : }

Generated by: LCOV version 1.14