LCOV - code coverage report
Current view: top level - bgp/routing-policy - routing_policy_match.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 289 296 97.6 %
Date: 2026-11-09 02:10:49 Functions: 41 41 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "bgp/routing-policy/routing_policy_match.h"
       7             : 
       8             : #include <boost/foreach.hpp>
       9             : #include <boost/assign/list_of.hpp>
      10             : 
      11             : #include <algorithm>
      12             : #include <map>
      13             : #include <sstream>
      14             : #include <vector>
      15             : 
      16             : #include "bgp/ipeer.h"
      17             : #include "bgp/bgp_attr.h"
      18             : #include "bgp/bgp_path.h"
      19             : #include "bgp/extended-community/default_gateway.h"
      20             : #include "bgp/extended-community/es_import.h"
      21             : #include "bgp/extended-community/esi_label.h"
      22             : #include "bgp/extended-community/etree.h"
      23             : #include "bgp/extended-community/load_balance.h"
      24             : #include "bgp/extended-community/mac_mobility.h"
      25             : #include "bgp/extended-community/router_mac.h"
      26             : #include "bgp/extended-community/site_of_origin.h"
      27             : #include "bgp/extended-community/source_as.h"
      28             : #include "bgp/extended-community/tag.h"
      29             : #include "bgp/extended-community/vrf_route_import.h"
      30             : #include "bgp/origin-vn/origin_vn.h"
      31             : #include "bgp/routing-instance/routepath_replicator.h"
      32             : #include "bgp/routing-instance/routing_instance.h"
      33             : #include "bgp/rtarget/rtarget_address.h"
      34             : #include "bgp/security_group/security_group.h"
      35             : #include "bgp/tunnel_encap/tunnel_encap.h"
      36             : #include "net/community_type.h"
      37             : 
      38             : 
      39             : using contrail::regex;
      40             : using contrail::regex_match;
      41             : using contrail::regex_search;
      42             : using std::includes;
      43             : using std::map;
      44             : using std::ostringstream;
      45             : using std::sort;
      46             : using std::string;
      47             : using std::unique;
      48             : using std::vector;
      49             : using std::find;
      50             : 
      51         351 : MatchCommunity::MatchCommunity(const vector<string> &communities,
      52         351 :     bool match_all) : match_all_(match_all) {
      53             :     // Assume that the each community string that doesn't correspond to a
      54             :     // community name or value is a regex string.
      55        1327 :     BOOST_FOREACH(const string &community, communities) {
      56         488 :         uint32_t value = CommunityType::CommunityFromString(community);
      57         488 :         if (value) {
      58         370 :             to_match_.insert(value);
      59             :         } else {
      60         118 :             to_match_regex_strings_.push_back(community);
      61             :         }
      62             :     }
      63             : 
      64             :     // Sort and uniquify the vector of regex strings.
      65         351 :     sort(to_match_regex_strings_.begin(), to_match_regex_strings_.end());
      66             :     vector<string>::iterator it =
      67         351 :         unique(to_match_regex_strings_.begin(), to_match_regex_strings_.end());
      68         351 :     to_match_regex_strings_.erase(it, to_match_regex_strings_.end());
      69             : 
      70             :     // Build a vector of regexs corresponding to the regex strings.
      71         575 :     BOOST_FOREACH(string regex_str, regex_strings()) {
      72         112 :         to_match_regexs_.push_back(regex(regex_str));
      73         112 :     }
      74         351 : }
      75             : 
      76         839 : MatchCommunity::~MatchCommunity() {
      77         839 : }
      78             : 
      79             : //
      80             : // Return true if all community strings (normal or regex) are matched by the
      81             : // community values in the BgpAttr.
      82             : //
      83          72 : bool MatchCommunity::MatchAll(const BgpAttr *attr) const {
      84             :     // Bail if there's no community values in the BgpAttr.
      85          72 :     const Community *comm = attr->community();
      86          72 :     if (!comm)
      87           0 :         return false;
      88             : 
      89             :     // Make sure that all non-regex communities in this MatchCommunity are
      90             :     // present in the BgpAttr.
      91          72 :     vector<uint32_t> list = comm->communities();
      92          72 :     sort(list.begin(), list.end());
      93         144 :     if (!includes(list.begin(), list.end(),
      94         144 :         communities().begin(), communities().end())) {
      95          20 :         return false;
      96             :     }
      97             : 
      98             :     // Make sure that each regex in this MatchCommunity is matched by one
      99             :     // of the communities in the BgpAttr.
     100         172 :     BOOST_FOREACH(const regex &match_expr, regexs()) {
     101          77 :         bool matched = false;
     102         383 :         BOOST_FOREACH(uint32_t community, comm->communities()) {
     103         183 :             string community_str = CommunityType::CommunityToString(community);
     104         183 :             if (regex_match(community_str, match_expr)) {
     105          60 :                 matched = true;
     106          60 :                 break;
     107             :             }
     108         183 :         }
     109          77 :         if (!matched)
     110          17 :             return false;
     111             :     }
     112             : 
     113          35 :     return true;
     114          72 : }
     115             : 
     116             : //
     117             : // Return true if any community strings (normal or regex) is matched by the
     118             : // community values in the BgpAttr.
     119             : //
     120         383 : bool MatchCommunity::MatchAny(const BgpAttr *attr) const {
     121             :     // Bail if there's no community values in the BgpAttr.
     122         383 :     const Community *comm = attr->community();
     123         383 :     if (!comm)
     124         254 :         return false;
     125             : 
     126             :     // Check if any of the community values in the BgpAttr matches one of
     127             :     // the normal community strings.
     128         315 :     BOOST_FOREACH(uint32_t community, comm->communities()) {
     129         174 :         if (communities().find(community) != communities().end())
     130          81 :             return true;
     131             :     }
     132             : 
     133             :     // Check if any of the community values in the BgpAttr matches one of
     134             :     // the community regexs.
     135         150 :     BOOST_FOREACH(uint32_t community, comm->communities()) {
     136          64 :         string community_str = CommunityType::CommunityToString(community);
     137         168 :         BOOST_FOREACH(const regex &match_expr, regexs()) {
     138          65 :             if (regex_match(community_str, match_expr))
     139          13 :                 return true;
     140             :         }
     141          64 :     }
     142             : 
     143          35 :     return false;
     144             : }
     145             : 
     146             : //
     147             : // Return true if the BgpPath matches this MatchCommunity.
     148             : //
     149         455 : bool MatchCommunity::Match(const BgpRoute *route, const BgpPath *path,
     150             :                            const BgpAttr *attr) const {
     151         455 :     return (match_all_ ? MatchAll(attr) : MatchAny(attr));
     152             : }
     153             : 
     154             : //
     155             : // Return string representation of this MatchCommunity.
     156             : //
     157          19 : string MatchCommunity::ToString() const {
     158          19 :     ostringstream oss;
     159          19 :     if (match_all_) {
     160           4 :         oss << "community (all) [ ";
     161             :     } else {
     162          15 :         oss << "community (any) [ ";
     163             :     }
     164          53 :     BOOST_FOREACH(uint32_t community, communities()) {
     165          17 :         string name = CommunityType::CommunityToString(community);
     166          17 :         oss << name << ",";
     167          17 :     }
     168          43 :     BOOST_FOREACH(string regex_str, regex_strings()) {
     169          12 :         oss << regex_str << ",";
     170          12 :     }
     171          19 :     oss.seekp(-1, oss.cur);
     172          19 :     oss << " ]";
     173          38 :     return oss.str();
     174          19 : }
     175             : 
     176             : //
     177             : // Return true if this MatchCommunity is equal to the one supplied.
     178             : //
     179         204 : bool MatchCommunity::IsEqual(const RoutingPolicyMatch &community) const {
     180             :     const MatchCommunity in_community =
     181         204 :         static_cast<const MatchCommunity &>(community);
     182         204 :     if (match_all() != in_community.match_all())
     183           8 :         return false;
     184         196 :     if (communities() != in_community.communities())
     185          14 :         return false;
     186         182 :     if (regex_strings() != in_community.regex_strings())
     187          12 :         return false;
     188         170 :     return true;
     189         204 : }
     190             : 
     191          81 : MatchExtCommunity::MatchExtCommunity(const vector<string> &communities,
     192          81 :     bool match_all) : match_all_(match_all) {
     193             :     // Assume that the each community string that doesn't correspond to a
     194             :     // community name or value is a regex string.
     195         465 :     BOOST_FOREACH(const string &community, communities) {
     196             :         const ExtCommunity::ExtCommunityList list =
     197         192 :             ExtCommunity::ExtCommunityFromString(community);
     198         192 :         if (list.size()) {
     199          92 :             if(!Find(list[0]))
     200          88 :                 to_match_.push_back(list[0]);
     201             :         } else {
     202         100 :             to_match_regex_strings_.push_back(community);
     203             :         }
     204         192 :     }
     205             : 
     206             :     // Sort and uniquify the vector of regex strings.
     207          81 :     sort(to_match_.begin(), to_match_.end());
     208          81 :     sort(to_match_regex_strings_.begin(), to_match_regex_strings_.end());
     209             :     vector<string>::iterator it =
     210          81 :         unique(to_match_regex_strings_.begin(), to_match_regex_strings_.end());
     211          81 :     to_match_regex_strings_.erase(it, to_match_regex_strings_.end());
     212             : 
     213             :     // Build a vector of regexs corresponding to the regex strings.
     214         269 :     BOOST_FOREACH(string regex_str, regex_strings()) {
     215          94 :         to_match_regexs_.push_back(regex(regex_str));
     216          94 :     }
     217          81 : }
     218             : 
     219         139 : MatchExtCommunity::~MatchExtCommunity() {
     220         139 : }
     221             : 
     222             : //
     223             : // Return true if all community strings (normal or regex) are matched by the
     224             : // community values in the BgpAttr.
     225             : //
     226          51 : bool MatchExtCommunity::MatchAll(const BgpAttr *attr) const {
     227             :     // Bail if there's no community values in the BgpAttr.
     228          51 :     const ExtCommunity *comm = attr->ext_community();
     229          51 :     if (!comm)
     230           0 :         return false;
     231             : 
     232             :     // Make sure that all non-regex communities in this MatchExtCommunity are
     233             :     // present in the BgpAttr.
     234          51 :     ExtCommunity::ExtCommunityList list = comm->communities();
     235          51 :     sort(list.begin(), list.end());
     236         102 :     if (!includes(list.begin(), list.end(),
     237         102 :         communities().begin(), communities().end())) {
     238          15 :         return false;
     239             :     }
     240             : 
     241             :     // Make sure that each regex in this MatchExtCommunity is matched by one
     242             :     // of the communities in the BgpAttr.
     243         120 :     BOOST_FOREACH(const regex &match_expr, regexs()) {
     244          54 :         bool matched = false;
     245         260 :         BOOST_FOREACH(ExtCommunity::ExtCommunityValue community,
     246             :                       comm->communities()) {
     247         124 :             string community_str = ExtCommunity::ToString(community);
     248         124 :             if (regex_match(community_str, match_expr)) {
     249          42 :                 matched = true;
     250          42 :                 break;
     251             :             }
     252          82 :             community_str = ExtCommunity::ToHexString(community);
     253          82 :             if (regex_match(community_str, match_expr)) {
     254           0 :                 matched = true;
     255           0 :                 break;
     256             :             }
     257         124 :         }
     258          54 :         if (!matched)
     259          12 :             return false;
     260             :     }
     261             : 
     262          24 :     return true;
     263          51 : }
     264             : 
     265         151 : bool MatchExtCommunity::Find(const ExtCommunity::ExtCommunityValue &community)
     266             :                             const {
     267         151 :     return (std::find(communities().begin(), communities().end(), community) !=
     268         302 :             communities().end());
     269             : }
     270             : 
     271             : //
     272             : // Return true if any community strings (normal or regex) is matched by the
     273             : // community values in the BgpAttr.
     274             : //
     275          25 : bool MatchExtCommunity::MatchAny(const BgpAttr *attr) const {
     276             :     // Bail if there's no community values in the BgpAttr.
     277          25 :     const ExtCommunity *comm = attr->ext_community();
     278          25 :     if (!comm)
     279           0 :         return false;
     280             : 
     281             :     // Check if any of the community values in the BgpAttr matches one of
     282             :     // the normal community strings.
     283          97 :     BOOST_FOREACH(ExtCommunity::ExtCommunityValue community,
     284             :                   comm->communities()) {
     285          43 :         if (Find(community))
     286           7 :             return true;
     287             :     }
     288             : 
     289             :     // Check if any of the community values in the BgpAttr matches one of
     290             :     // the community regexs.
     291          58 :     BOOST_FOREACH(ExtCommunity::ExtCommunityValue community,
     292             :                   comm->communities()) {
     293          27 :         string community_str = ExtCommunity::ToString(community);
     294          91 :         BOOST_FOREACH(const regex &match_expr, regexs()) {
     295          38 :             if (regex_match(community_str, match_expr))
     296           6 :                 return true;
     297             :         }
     298          21 :         community_str = ExtCommunity::ToHexString(community);
     299          77 :         BOOST_FOREACH(const regex &match_expr, regexs()) {
     300          29 :             if (regex_match(community_str, match_expr))
     301           1 :                 return true;
     302             :         }
     303          27 :     }
     304             : 
     305          11 :     return false;
     306             : }
     307             : 
     308             : //
     309             : // Return true if the BgpPath matches this MatchExtCommunity.
     310             : //
     311          76 : bool MatchExtCommunity::Match(const BgpRoute *route, const BgpPath *path,
     312             :                               const BgpAttr *attr) const {
     313          76 :     return (match_all_ ? MatchAll(attr) : MatchAny(attr));
     314             : }
     315             : 
     316             : //
     317             : // Return string representation of this MatchExtCommunity.
     318             : //
     319           8 : string MatchExtCommunity::ToString() const {
     320           8 :     ostringstream oss;
     321           8 :     if (match_all_) {
     322           4 :         oss << "Extcommunity (all) [ ";
     323             :     } else {
     324           4 :         oss << "Extcommunity (any) [ ";
     325             :     }
     326          20 :     BOOST_FOREACH(ExtCommunity::ExtCommunityValue community, communities()) {
     327           6 :         string name = ExtCommunity::ToString(community);
     328           6 :         oss << name << ",";
     329           6 :     }
     330          32 :     BOOST_FOREACH(string regex_str, regex_strings()) {
     331          12 :         oss << regex_str << ",";
     332          12 :     }
     333           8 :     oss.seekp(-1, oss.cur);
     334           8 :     oss << " ]";
     335          16 :     return oss.str();
     336           8 : }
     337             : 
     338             : //
     339             : // Return true if this MatchExtCommunity is equal to the one supplied.
     340             : //
     341          46 : bool MatchExtCommunity::IsEqual(const RoutingPolicyMatch &community) const {
     342             :     const MatchExtCommunity in_community =
     343          46 :         static_cast<const MatchExtCommunity &>(community);
     344          46 :     if (match_all() != in_community.match_all())
     345           8 :         return false;
     346          38 :     if (communities() != in_community.communities())
     347          12 :         return false;
     348          26 :     if (regex_strings() != in_community.regex_strings())
     349          12 :         return false;
     350          14 :     return true;
     351          46 : }
     352             : 
     353             : template <typename T>
     354         298 : typename MatchPrefix<T>::MatchType MatchPrefix<T>::GetMatchType(
     355             :     const string &match_type_str) {
     356         298 :     MatchType match_type = EXACT;
     357         298 :     if (match_type_str == "exact") {
     358         180 :         match_type = EXACT;
     359         118 :     } else if (match_type_str == "longer") {
     360          36 :         match_type = LONGER;
     361          82 :     } else if (match_type_str == "orlonger") {
     362          62 :         match_type = ORLONGER;
     363             :     }
     364         298 :     return match_type;
     365             : }
     366             : 
     367             : template <typename T>
     368         200 : MatchPrefix<T>::MatchPrefix(const PrefixMatchConfigList &match_config_list) {
     369         760 :     BOOST_FOREACH(const PrefixMatchConfig &match_config, match_config_list) {
     370         280 :         boost::system::error_code ec;
     371         280 :         PrefixT prefix = PrefixT::FromString(match_config.prefix_to_match, &ec);
     372             :         MatchType match_type =
     373         280 :             MatchPrefix<T>::GetMatchType(match_config.prefix_match_type);
     374         280 :         match_list_.push_back(PrefixMatch(prefix, match_type));
     375             :     }
     376             : 
     377             :     // Sort and uniquify the vector of PrefixMatch elements.
     378         200 :     sort(match_list_.begin(), match_list_.end());
     379             :     typename PrefixMatchList::iterator it =
     380         200 :         unique(match_list_.begin(), match_list_.end());
     381         200 :     match_list_.erase(it, match_list_.end());
     382         200 : }
     383             : 
     384             : template <typename T>
     385         478 : MatchPrefix<T>::~MatchPrefix() {
     386         478 : }
     387             : 
     388             : template <typename T>
     389         596 : bool MatchPrefix<T>::Match(const BgpRoute *route, const BgpPath *path,
     390             :                            const BgpAttr *attr) const {
     391         596 :     const RouteT *in_route = dynamic_cast<const RouteT *>(route);
     392         596 :     if (in_route == NULL)
     393           3 :         return false;
     394         593 :     const PrefixT &prefix = in_route->GetPrefix();
     395        2198 :     BOOST_FOREACH(const PrefixMatch &prefix_match, match_list_) {
     396         870 :         if (prefix_match.match_type == EXACT) {
     397         564 :             if (prefix == prefix_match.prefix)
     398          67 :                 return true;
     399         306 :         } else if (prefix_match.match_type == LONGER) {
     400         272 :             if (prefix == prefix_match.prefix)
     401           3 :                 continue;
     402         269 :             if (prefix.IsMoreSpecific(prefix_match.prefix))
     403           7 :                 return true;
     404          34 :         } else if (prefix_match.match_type == ORLONGER) {
     405          34 :             if (prefix.IsMoreSpecific(prefix_match.prefix))
     406          26 :                 return true;
     407             :         }
     408             :     }
     409         523 :     return false;
     410             : }
     411             : 
     412             : template <typename T>
     413         106 : bool MatchPrefix<T>::IsEqual(const RoutingPolicyMatch &prefix) const {
     414         106 :     const MatchPrefix in_prefix = static_cast<const MatchPrefix&>(prefix);
     415         212 :     return (in_prefix.match_list_ == match_list_);
     416         106 : }
     417             : 
     418             : template <typename T>
     419          16 : string MatchPrefix<T>::ToString() const {
     420          16 :     ostringstream oss;
     421          16 :     oss << "prefix [";
     422          72 :     BOOST_FOREACH(const PrefixMatch &prefix_match, match_list_) {
     423          28 :         oss << " " << prefix_match.prefix.ToString();
     424          28 :         if  (prefix_match.match_type == LONGER) {
     425           6 :             oss << " longer";
     426          22 :         } else if  (prefix_match.match_type == ORLONGER) {
     427           6 :             oss << " orlonger";
     428             :         }
     429          28 :         oss << ",";
     430             :     }
     431          16 :     oss.seekp(-1, oss.cur);
     432          16 :     oss << " ]";
     433          32 :     return oss.str();
     434          16 : }
     435             : 
     436             : template class MatchPrefix<PrefixMatchInet>;
     437             : template class MatchPrefix<PrefixMatchInet6>;
     438             : 
     439             : static const map<string, MatchProtocol::MatchProtocolType> fromString
     440             :   = boost::assign::map_list_of
     441             :     ("bgp", MatchProtocol::BGP)
     442             :     ("xmpp", MatchProtocol::XMPP)
     443             :     ("static", MatchProtocol::StaticRoute)
     444             :     ("service-chain", MatchProtocol::ServiceChainRoute)
     445             :     ("aggregate", MatchProtocol::AggregateRoute)
     446             :     ("interface", MatchProtocol::Interface)
     447             :     ("interface-static", MatchProtocol::InterfaceStatic)
     448             :     ("service-interface", MatchProtocol::ServiceInterface)
     449             :     ("bgpaas", MatchProtocol::BGPaaS);
     450             : 
     451             : static const map<MatchProtocol::MatchProtocolType, string> toString
     452             :   = boost::assign::map_list_of
     453             :     (MatchProtocol::BGP, "bgp")
     454             :     (MatchProtocol::XMPP, "xmpp")
     455             :     (MatchProtocol::StaticRoute, "static")
     456             :     (MatchProtocol::ServiceChainRoute, "service-chain")
     457             :     (MatchProtocol::AggregateRoute, "aggregate")
     458             :     (MatchProtocol::Interface, "interface")
     459             :     (MatchProtocol::InterfaceStatic, "interface-static")
     460             :     (MatchProtocol::ServiceInterface, "service-interface")
     461             :     (MatchProtocol::BGPaaS, "bgpaas");
     462             : 
     463             : static const map<MatchProtocol::MatchProtocolType, BgpPath::PathSource>
     464             :     pathSourceMap = boost::assign::map_list_of
     465             :     (MatchProtocol::BGP, BgpPath::BGP_XMPP)
     466             :     (MatchProtocol::XMPP, BgpPath::BGP_XMPP)
     467             :     (MatchProtocol::StaticRoute, BgpPath::StaticRoute)
     468             :     (MatchProtocol::ServiceChainRoute, BgpPath::ServiceChain)
     469             :     (MatchProtocol::AggregateRoute, BgpPath::Aggregate)
     470             :     (MatchProtocol::Interface, BgpPath::BGP_XMPP)
     471             :     (MatchProtocol::InterfaceStatic, BgpPath::BGP_XMPP)
     472             :     (MatchProtocol::ServiceInterface, BgpPath::BGP_XMPP)
     473             :     (MatchProtocol::BGPaaS, BgpPath::BGP_XMPP);
     474             : 
     475             : static const vector<MatchProtocol::MatchProtocolType>
     476             :     isSubprotocol = boost::assign::list_of(MatchProtocol::Interface)
     477             :                                           (MatchProtocol::InterfaceStatic)
     478             :                                           (MatchProtocol::ServiceInterface)
     479             :                                           (MatchProtocol::StaticRoute);
     480             : 
     481          78 : static bool IsSubprotocol(MatchProtocol::MatchProtocolType protocol) {
     482          78 :     return (find(isSubprotocol.begin(), isSubprotocol.end(), protocol) !=
     483         156 :             isSubprotocol.end());
     484             : }
     485             : 
     486        2092 : const string MatchProtocolToString(MatchProtocol::MatchProtocolType protocol) {
     487             :     map<MatchProtocol::MatchProtocolType, string>::const_iterator it =
     488        2092 :         toString.find(protocol);
     489        2092 :     if (it != toString.end()) {
     490        2092 :         return it->second;
     491             :     }
     492           0 :     return "unspecified";
     493             : }
     494             : 
     495         107 : static MatchProtocol::MatchProtocolType MatchProtocolFromString(
     496             :     const string &protocol) {
     497             :     map<string, MatchProtocol::MatchProtocolType>::const_iterator it =
     498         107 :         fromString.find(protocol);
     499         107 :     if (it != fromString.end()) {
     500         106 :         return it->second;
     501             :     }
     502           1 :     return MatchProtocol::Unspecified;
     503             : }
     504             : 
     505          55 : static BgpPath::PathSource PathSourceFromMatchProtocol(
     506             :     MatchProtocol::MatchProtocolType src) {
     507             :     map<MatchProtocol::MatchProtocolType, BgpPath::PathSource>::const_iterator
     508          55 :         it = pathSourceMap.find(src);
     509          55 :     if (it != pathSourceMap.end()) {
     510          55 :         return it->second;
     511             :     }
     512           0 :     return BgpPath::None;
     513             : }
     514             : 
     515          41 : MatchProtocol::MatchProtocol(const vector<string> &protocols) {
     516         255 :     BOOST_FOREACH(const string &protocol, protocols) {
     517         107 :         MatchProtocolType value = MatchProtocolFromString(protocol);
     518             :         // Ignore invalid protocol values.
     519         107 :         if (value == Unspecified)
     520           1 :             continue;
     521         106 :         to_match_.push_back(value);
     522             :     }
     523             : 
     524             :     // Sort and uniquify the vector match protocols.
     525          41 :     sort(to_match_.begin(), to_match_.end());
     526             :     vector<MatchProtocolType>::iterator it =
     527          41 :         unique(to_match_.begin(), to_match_.end());
     528          41 :     to_match_.erase(it, to_match_.end());
     529          41 : }
     530             : 
     531          76 : MatchProtocol::~MatchProtocol() {
     532          76 : }
     533             : 
     534          43 : bool MatchProtocol::Match(const BgpRoute *route, const BgpPath *path,
     535             :                            const BgpAttr *attr) const {
     536          43 :     BgpPath::PathSource path_src = path->GetSource();
     537          43 :     bool is_xmpp = path->GetPeer() ? path->GetPeer()->IsXmppPeer() : false;
     538          43 :     bool bgpaas = path->GetPeer() ? path->GetPeer()->IsRouterTypeBGPaaS() : false;
     539         145 :     BOOST_FOREACH(MatchProtocolType protocol, protocols()) {
     540          78 :         if (IsSubprotocol(protocol)) {
     541             :             // Check only if matching protocol is subprotocol
     542          23 :             if (attr && !attr->sub_protocol().empty()) {
     543          14 :                 std::string matchps = MatchProtocolToString(protocol);
     544          14 :                 if (matchps.compare(attr->sub_protocol()) == 0)
     545          11 :                     return true;
     546          14 :             }
     547             :         } else {
     548             :             BgpPath::PathSource mapped_src =
     549          55 :                                 PathSourceFromMatchProtocol(protocol);
     550          55 :             if (mapped_src != BgpPath::None) {
     551          55 :                 if (mapped_src == path_src) {
     552          25 :                     if (protocol == XMPP && !is_xmpp)
     553           3 :                         continue;
     554          22 :                     if (protocol == BGP && (bgpaas || is_xmpp))
     555           4 :                         continue;
     556          18 :                     if (protocol == BGPaaS && (!bgpaas || is_xmpp))
     557           2 :                         continue;
     558          16 :                     return true;
     559             :                 }
     560             :             }
     561             :         }
     562             :     }
     563          16 :     return false;
     564             : }
     565             : 
     566           6 : string MatchProtocol::ToString() const {
     567           6 :     ostringstream oss;
     568           6 :     oss << "protocol [ ";
     569          40 :     BOOST_FOREACH(MatchProtocolType protocol, protocols()) {
     570          17 :         string name = MatchProtocolToString(protocol);
     571          17 :         oss << name << ",";
     572          17 :     }
     573           6 :     oss.seekp(-1, oss.cur);
     574           6 :     oss << " ]";
     575          12 :     return oss.str();
     576           6 : }
     577             : 
     578          19 : bool MatchProtocol::IsEqual(const RoutingPolicyMatch &protocol) const {
     579             :     const MatchProtocol in_protocol =
     580          19 :         static_cast<const MatchProtocol&>(protocol);
     581          38 :     return (protocols() == in_protocol.protocols());
     582          19 : }

Generated by: LCOV version 1.14