LCOV - code coverage report
Current view: top level - bgp/extended-community - load_balance.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 17 193 8.8 %
Date: 2026-09-21 02:11:39 Functions: 1 25 4.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/extended-community/load_balance.h"
       6             : 
       7             : #include <boost/foreach.hpp>
       8             : 
       9             : #include <algorithm>
      10             : #include <string>
      11             : #include <vector>
      12             : 
      13             : using std::copy;
      14             : using std::string;
      15             : 
      16             : // Initialize default attribute statically.
      17             : const LoadBalance::LoadBalanceAttribute
      18             :     LoadBalance::LoadBalanceAttribute::kDefaultLoadBalanceAttribute =
      19             :         LoadBalance::LoadBalanceAttribute();
      20             : 
      21           1 : LoadBalance::LoadBalanceAttribute::LoadBalanceAttribute() {
      22           1 :     value1 = 0;  // reset all fields
      23           1 :     value2 = 0;  // reset all fields
      24           1 :     type = BgpExtendedCommunityType::Opaque;
      25           1 :     sub_type = BgpExtendedCommunityOpaqueSubType::LoadBalance;
      26             : 
      27           1 :     l3_source_address = true;
      28           1 :     l3_destination_address = true;
      29           1 :     l4_protocol = true;
      30           1 :     l4_source_port = true;
      31           1 :     l4_destination_port = true;
      32           1 :     reserved1 = false;
      33             : 
      34           1 :     reserved2 = 0;
      35             : 
      36           1 :     source_bias = false;
      37             : 
      38           1 :     reserved3 = 0;
      39           1 :     reserved4 = 0;
      40           1 :     reserved5 = 0;
      41           1 : }
      42             : 
      43           0 : LoadBalance::LoadBalanceAttribute::LoadBalanceAttribute(
      44           0 :         uint32_t value1, uint32_t value2) : value1(value1), value2(value2) {
      45           0 : }
      46             : 
      47           0 : void LoadBalance::LoadBalanceAttribute::Encode(
      48             :         autogen::LoadBalanceType *lb_type) const {
      49           0 :     lb_type->load_balance_fields.load_balance_field_list.clear();
      50           0 :     if (l3_source_address)
      51           0 :         lb_type->load_balance_fields.load_balance_field_list.push_back(
      52           0 :                 string("l3-source-address"));
      53           0 :     if (l3_destination_address)
      54           0 :         lb_type->load_balance_fields.load_balance_field_list.push_back(
      55           0 :                 string("l3-destination-address"));
      56           0 :     if (l4_protocol)
      57           0 :         lb_type->load_balance_fields.load_balance_field_list.push_back(
      58           0 :                 string("l4-protocol"));
      59           0 :     if (l4_source_port)
      60           0 :         lb_type->load_balance_fields.load_balance_field_list.push_back(
      61           0 :                 string("l4-source-port"));
      62           0 :     if (l4_destination_port)
      63           0 :         lb_type->load_balance_fields.load_balance_field_list.push_back(
      64           0 :                 string("l4-destination-port"));
      65           0 :     lb_type->load_balance_decision = source_bias ? "source-bias" : "field-hash";
      66           0 : }
      67             : 
      68           0 : bool LoadBalance::LoadBalanceAttribute::operator==(
      69             :         const LoadBalance::LoadBalanceAttribute &other) const {
      70           0 :     return value1 == other.value1 && value2 == other.value2;
      71             : }
      72             : 
      73           0 : bool LoadBalance::LoadBalanceAttribute::operator!=(
      74             :         const LoadBalance::LoadBalanceAttribute &other) const {
      75           0 :     return value1 != other.value1 || value2 != other.value2;
      76             : }
      77             : 
      78           0 : const bool LoadBalance::LoadBalanceAttribute::IsDefault() const {
      79           0 :     return *this == kDefaultLoadBalanceAttribute;
      80             : }
      81             : 
      82           0 : LoadBalance::LoadBalance() {
      83           0 :     LoadBalanceAttribute attr;
      84           0 :     put_value(&data_[0], 4, attr.value1);
      85           0 :     put_value(&data_[4], 4, attr.value2);
      86           0 : }
      87             : 
      88           0 : LoadBalance::LoadBalance(const bytes_type &data) {
      89           0 :     copy(data.begin(), data.end(), data_.begin());
      90           0 : }
      91             : 
      92           0 : LoadBalance::LoadBalance(const BgpPath *path) {
      93           0 :     LoadBalance();
      94           0 :     if (!path)
      95           0 :         return;
      96           0 :     const BgpAttr *attr = path->GetAttr();
      97           0 :     if (!attr)
      98           0 :         return;
      99           0 :     const ExtCommunity *ext_community = attr->ext_community();
     100           0 :     if (!ext_community)
     101           0 :         return;
     102           0 :     for (const auto &comm : ext_community->communities()) {
     103           0 :         if (ExtCommunity::is_load_balance(comm)) {
     104           0 :             copy(comm.begin(), comm.end(), data_.begin());
     105           0 :             break;
     106             :         }
     107             :     }
     108             : }
     109             : 
     110           0 : LoadBalance::LoadBalance(const LoadBalanceAttribute &attr) {
     111           0 :     put_value(&data_[0], 4, attr.value1);
     112           0 :     put_value(&data_[4], 4, attr.value2);
     113           0 : }
     114             : 
     115           0 : LoadBalance::LoadBalance(const autogen::LoadBalanceType &lb_type) {
     116           0 :     LoadBalanceAttribute attr;
     117             : 
     118           0 :     attr.source_bias = lb_type.load_balance_decision == "source-bias";
     119             : 
     120             :     // autogen::LoadBalanceType fields list empty should imply as standard
     121             :     // 5-tuple fields set. xml schema does not let one specifify default values
     122             :     // for a complex type such as a list in this case.
     123             :     bool load_balance_default =
     124           0 :         !attr.source_bias && (lb_type.load_balance_fields.begin() ==
     125           0 :                               lb_type.load_balance_fields.end());
     126           0 :     attr.l3_source_address = load_balance_default || false;
     127           0 :     attr.l3_destination_address = load_balance_default || false;
     128           0 :     attr.l4_protocol = load_balance_default || false;
     129           0 :     attr.l4_source_port = load_balance_default || false;
     130           0 :     attr.l4_destination_port = load_balance_default || false;
     131             : 
     132           0 :     for (autogen::LoadBalanceFieldListType::const_iterator it =
     133           0 :             lb_type.load_balance_fields.begin();
     134           0 :             it != lb_type.load_balance_fields.end(); ++it) {
     135           0 :         const string s = *it;
     136           0 :         if (s == "l3-source-address") {
     137           0 :             attr.l3_source_address = true;
     138           0 :             continue;
     139             :         }
     140           0 :         if (s == "l3-destination-address") {
     141           0 :             attr.l3_destination_address = true;
     142           0 :             continue;
     143             :         }
     144           0 :         if (s == "l4-protocol") {
     145           0 :             attr.l4_protocol = true;
     146           0 :             continue;
     147             :         }
     148           0 :         if (s == "l4-source-port") {
     149           0 :             attr.l4_source_port = true;
     150           0 :             continue;
     151             :         }
     152           0 :         if (s == "l4-destination-port") {
     153           0 :             attr.l4_destination_port = true;
     154           0 :             continue;
     155             :         }
     156           0 :     }
     157             : 
     158           0 :     put_value(&data_[0], 4, attr.value1);
     159           0 :     put_value(&data_[4], 4, attr.value2);
     160           0 : }
     161             : 
     162           0 : void LoadBalance::FillAttribute(LoadBalanceAttribute *attr) {
     163           0 :     attr->value1 = get_value(&data_[0], 4);
     164           0 :     attr->value2 = get_value(&data_[4], 4);
     165           0 : }
     166             : 
     167           0 : const LoadBalance::LoadBalanceAttribute LoadBalance::ToAttribute() const {
     168           0 :     return LoadBalanceAttribute(
     169           0 :             get_value_unaligned(&data_[0], 4),
     170           0 :             get_value_unaligned(&data_[4], 4));
     171             : }
     172             : 
     173           0 : void LoadBalance::SetL3SourceAddress(bool flag) {
     174           0 :     LoadBalanceAttribute attr = ToAttribute();
     175           0 :     attr.l3_source_address = flag;
     176             : 
     177           0 :     put_value(&data_[0], 4, attr.value1);
     178           0 :     put_value(&data_[4], 4, attr.value2);
     179           0 : }
     180             : 
     181           0 : void LoadBalance::SetL3DestinationAddress(bool flag) {
     182           0 :     LoadBalanceAttribute attr = ToAttribute();
     183           0 :     attr.l3_destination_address = flag;
     184             : 
     185           0 :     put_value(&data_[0], 4, attr.value1);
     186           0 :     put_value(&data_[4], 4, attr.value2);
     187           0 : }
     188             : 
     189           0 : void LoadBalance::SetL4Protocol(bool flag) {
     190           0 :     LoadBalanceAttribute attr = ToAttribute();
     191           0 :     attr.l4_protocol = flag;
     192             : 
     193           0 :     put_value(&data_[0], 4, attr.value1);
     194           0 :     put_value(&data_[4], 4, attr.value2);
     195           0 : }
     196             : 
     197           0 : void LoadBalance::SetL4SourcePort(bool flag) {
     198           0 :     LoadBalanceAttribute attr = ToAttribute();
     199           0 :     attr.l4_source_port = flag;
     200             : 
     201           0 :     put_value(&data_[0], 4, attr.value1);
     202           0 :     put_value(&data_[4], 4, attr.value2);
     203           0 : }
     204             : 
     205           0 : void LoadBalance::SetL4DestinationPort(bool flag) {
     206           0 :     LoadBalanceAttribute attr = ToAttribute();
     207           0 :     attr.l4_destination_port = flag;
     208             : 
     209           0 :     put_value(&data_[0], 4, attr.value1);
     210           0 :     put_value(&data_[4], 4, attr.value2);
     211           0 : }
     212             : 
     213           0 : void LoadBalance::SetSourceBias(bool flag) {
     214           0 :     LoadBalanceAttribute attr = ToAttribute();
     215           0 :     attr.source_bias = flag;
     216             : 
     217           0 :     put_value(&data_[0], 4, attr.value1);
     218           0 :     put_value(&data_[4], 4, attr.value2);
     219           0 : }
     220             : 
     221           0 : bool LoadBalance::IsPresent(const BgpPath *path) {
     222           0 :     if (!path)
     223           0 :         return false;
     224           0 :     const BgpAttr *attr = path->GetAttr();
     225           0 :     if (!attr)
     226           0 :         return false;
     227           0 :     const ExtCommunity *ext_community = attr->ext_community();
     228           0 :     if (!ext_community)
     229           0 :         return false;
     230           0 :     BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
     231             :                   ext_community->communities()) {
     232           0 :         if (ExtCommunity::is_load_balance(comm)) {
     233           0 :             return true;
     234             :         }
     235             :     }
     236           0 :     return false;
     237             : }
     238             : 
     239           0 : const bool LoadBalance::IsDefault() const {
     240           0 :     return ToAttribute() == LoadBalanceAttribute::kDefaultLoadBalanceAttribute;
     241             : }
     242             : 
     243           0 : bool LoadBalance::operator==(const LoadBalance &other) const {
     244           0 :     return ToAttribute() == other.ToAttribute();
     245             : }
     246             : 
     247           0 : bool LoadBalance::operator!=(const LoadBalance &other) const {
     248           0 :     return ToAttribute() != other.ToAttribute();
     249             : }
     250             : 
     251           0 : void LoadBalance::ShowAttribute(ShowLoadBalance *show_load_balance) const {
     252           0 :     const LoadBalanceAttribute attr = ToAttribute();
     253           0 :     vector<string> fields = vector<string>();
     254           0 :     if (attr.source_bias) {
     255           0 :         show_load_balance->set_decision_type("source-bias");
     256           0 :         show_load_balance->set_fields(fields);
     257           0 :         return;
     258             :     }
     259             : 
     260           0 :     show_load_balance->set_decision_type("field-hash");
     261           0 :     if (attr.l3_source_address)
     262           0 :         fields.push_back("l3-source-address");
     263           0 :     if (attr.l3_destination_address)
     264           0 :         fields.push_back("l3-destination-address");
     265           0 :     if (attr.l4_protocol)
     266           0 :         fields.push_back("l4-protocol");
     267           0 :     if (attr.l4_source_port)
     268           0 :         fields.push_back("l4-source-port");
     269           0 :     if (attr.l4_destination_port)
     270           0 :         fields.push_back("l4-destination-port");
     271           0 :     show_load_balance->set_fields(fields);
     272           0 : }
     273             : 
     274           0 : string LoadBalance::ToString() const {
     275           0 :     const LoadBalanceAttribute attr = ToAttribute();
     276           0 :     string str("load-balance:");
     277           0 :     str += attr.source_bias ? "source-bias" : "field-hash";
     278           0 :     return str;
     279           0 : }

Generated by: LCOV version 1.14