Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consistent hashing for balancer #258

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "subprojects/json"]
path = subprojects/json
url = https://github.com/nlohmann/json.git
[submodule "subprojects/chash"]
path = subprojects/chash
url = https://github.com/yanet-platform/chash.git
Binary file modified autotest/units/001_one_port/055_balancer_wlc/001-expect.pcap
Binary file not shown.
Binary file modified autotest/units/001_one_port/055_balancer_wlc/001-send.pcap
Binary file not shown.
Binary file modified autotest/units/001_one_port/055_balancer_wlc/002-expect.pcap
Binary file not shown.
Binary file modified autotest/units/001_one_port/055_balancer_wlc/002-send.pcap
Binary file not shown.
Binary file modified autotest/units/001_one_port/055_balancer_wlc/003-expect.pcap
Binary file not shown.
24 changes: 13 additions & 11 deletions autotest/units/001_one_port/055_balancer_wlc/autotest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ steps:
YANET_FORMAT_COLUMNS=module,virtual_ip,proto,virtual_port,scheduler,real_ip,real_port,enabled,weight,connections,packets,bytes balancer real any
module virtual_ip proto virtual_port scheduler real_ip real_port enabled weight connections packets bytes
--------- ---------- ----- ------------ --------- ------- --------- ------- ------ ----------- ------- -----
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 16 16 1568
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 8 8 784
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 8 8 784
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 34 34 3332
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 19 19 1862
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 11 11 1078
balancer0 10.1.0.55 tcp 443 wlc 2443::4 443 false 4 0 0 0


- cli:
- balancer real enable balancer0 10.1.0.55 tcp 443 2443::4 443
- balancer real flush
Expand All @@ -30,10 +31,10 @@ steps:
YANET_FORMAT_COLUMNS=module,virtual_ip,proto,virtual_port,scheduler,real_ip,real_port,enabled,weight,connections,packets,bytes balancer real any
module virtual_ip proto virtual_port scheduler real_ip real_port enabled weight connections packets bytes
--------- ---------- ----- ------------ --------- ------- --------- ------- ------ ----------- ------- -----
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 17 17 1666
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 10 10 980
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 9 9 882
balancer0 10.1.0.55 tcp 443 wlc 2443::4 443 true 4 28 28 2744
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 35 35 3430
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 23 23 2254
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 11 11 1078
balancer0 10.1.0.55 tcp 443 wlc 2443::4 443 true 4 59 59 5782

- sleep: 2
- sendPackets:
Expand All @@ -44,7 +45,8 @@ steps:
YANET_FORMAT_COLUMNS=module,virtual_ip,proto,virtual_port,scheduler,real_ip,real_port,enabled,weight,connections,packets,bytes balancer real any
module virtual_ip proto virtual_port scheduler real_ip real_port enabled weight connections packets bytes
--------- ---------- ----- ------------ --------- ------- --------- ------- ------ ----------- ------- -----
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 24 24 2352
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 11 11 1078
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 12 12 1176
balancer0 10.1.0.55 tcp 443 wlc 2443::4 443 true 4 49 49 4802
balancer0 10.1.0.55 tcp 443 wlc 2443::1 443 true 2 40 40 3920
balancer0 10.1.0.55 tcp 443 wlc 2443::2 443 true 1 27 27 2646
balancer0 10.1.0.55 tcp 443 wlc 2443::3 443 true 1 20 20 1960
balancer0 10.1.0.55 tcp 443 wlc 2443::4 443 true 4 73 73 7154

35 changes: 35 additions & 0 deletions autotest/units/001_one_port/055_balancer_wlc/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
from scapy.all import *

def dist(packets):
d = {}
for packet in packets:
dst = packet.getlayer(IPv6).dst
if dst not in d:
d[dst] = 0
d[dst] += 1
return d

def dist_cmd():
if len(sys.argv) < 3:
print("Provide file name.")
exit(1)
packets = rdpcap(sys.argv[2])
print(dist(packets))
exit(0)

def main():
if len(sys.argv) < 2:
print("Provide command.")
exit(1)
if sys.argv[1] == "dist":
dist_cmd()
print("Command not found.")
exit(1)

if __name__ == "__main__":
main()

4 changes: 2 additions & 2 deletions autotest/units/001_one_port/055_balancer_wlc/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def write_pcap(filename, *packetsList):


packages1 = [Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02") / Dot1Q(vlan=200) / IP(dst="10.1.0.55", src=f"1.{a_h}.{a_m}.{a_l}", ttl=64) / TCP(dport=443, sport=sport)
for sport in (12443, 12444) for a_h in range(2) for a_m in range(2) for a_l in range(4)]
for sport in (12443, 12444) for a_h in range(4) for a_m in range(2) for a_l in range(4)]
packages2 = [Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02") / Dot1Q(vlan=200) / IP(dst="10.1.0.55", src=f"1.{a_h}.{a_m}.{a_l}", ttl=64) / TCP(dport=443, sport=sport)
for sport in (11443, 11444) for a_h in range(2) for a_m in range(0, 2) for a_l in range(4)]
for sport in (11443, 11444) for a_h in range(4) for a_m in range(0, 2) for a_l in range(4)]
packages3 = [Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02") / Dot1Q(vlan=200) / IP(dst="10.1.0.55", src=f"1.{a_h}.{a_m}.{a_l}", ttl=64) / TCP(dport=443, sport=sport)
for sport in (11443, 11444) for a_h in range(2) for a_m in range(2, 4) for a_l in range(4)]

Expand Down
2 changes: 1 addition & 1 deletion common/controlplaneconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ using service_t = std::tuple<balancer_service_id_t,
std::optional<uint16_t>, ///< vport
std::optional<std::string>, ///< version
::balancer::scheduler,
::balancer::scheduler_params,
uint32_t, ///< wlc power
::balancer::forwarding_method,
uint8_t, ///< flags: mss_fix|ops
std::optional<common::ipv4_prefix_t>, ///< ipv4_outer_source_network
Expand Down
23 changes: 23 additions & 0 deletions common/deferer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace utils
{

template<typename F>
class Deferer
{
F action_;

public:
Deferer(F&& action) :
action_{std::move(action)}
{}
Deferer(const Deferer& other) = delete;
Deferer(Deferer&& other) = delete;
Deferer& operator=(const Deferer& other) = delete;
Deferer& operator=(Deferer&& other) = delete;
~Deferer()
{
action_();
}
};

} // namespace utils
2 changes: 2 additions & 0 deletions common/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ extern LogPriority logPriority;
#define YANET_BALANCER_DEFAULT_MSS_SIZE 536
#define YANET_BALANCER_FIX_MSS_SIZE 1220
#define YANET_BALANCER_FIX_MSS_FLAG ((uint8_t)(1u << 0))
static constexpr size_t YANET_DEFAULT_BALANCER_REAL_MAPPINGS_LIMIT = 100;
static constexpr size_t YANET_DEFAULT_BALANCER_CELLS_PER_WEIGHT_UNIT = 20;

#define YANET_BALANCER_OPS_FLAG ((uint8_t)(1u << 1))
#define YANET_BALANCER_PURE_L3 ((uint8_t)(1u << 2))
Expand Down
1 change: 0 additions & 1 deletion common/idp.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ using service = std::tuple<balancer_service_id_t, /// service id
tCounterId, ///< size 4
balancer::scheduler,
balancer::forwarding_method, // tunneling method (default ipip)
uint32_t, /// default_wlc_power
uint32_t, ///< real_start
uint32_t, ///< real_size
std::optional<common::ipv4_prefix_t>, ///< ipv4_outer_source_network
Expand Down
20 changes: 5 additions & 15 deletions common/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,24 @@ enum class scheduler : uint8_t
rr,
wrr,
wlc,
};

class scheduler_params
{
public:
scheduler_params() = default;
uint32_t wlc_power;
chash
};

[[maybe_unused]] constexpr const char* to_string(const scheduler& scheduler)
{
switch (scheduler)
{
case scheduler::rr:
{
return "rr";
}
case scheduler::wrr:
{
return "wrr";
}
case scheduler::wlc:
{
return "wlc";
}
case scheduler::chash:
return "chash";
default:
return "unknown";
}

return "unknown";
}

}
10 changes: 5 additions & 5 deletions controlplane/balancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,14 +757,14 @@ void balancer_t::compile(common::idp::updateGlobalBase::request& globalbase,
virtual_port,
version,
scheduler,
scheduler_params,
wlc_power,
forwarding_method,
flags,
ipv4_outer_source_network,
ipv6_outer_source_network,
reals] : balancer.services)
{
GCC_BUG_UNUSED(scheduler_params);
GCC_BUG_UNUSED(wlc_power);
GCC_BUG_UNUSED(version);

if (service_id >= YANET_CONFIG_BALANCER_SERVICES_SIZE)
Expand Down Expand Up @@ -808,7 +808,6 @@ void balancer_t::compile(common::idp::updateGlobalBase::request& globalbase,
counter_id,
scheduler,
forwarding_method,
balancer.default_wlc_power, // todo use scheduler_params.wlc_power when other services will be able to set it
(uint32_t)real_start,
(uint32_t)(req_reals.size() - real_start),
ipv4_outer_source_network,
Expand Down Expand Up @@ -955,7 +954,7 @@ bool balancer_t::reconfigure_wlc()
virtual_port,
version,
scheduler,
scheduler_params,
requested_wlc_power,
forwarding_method,
flags,
ipv4_outer_source_network,
Expand All @@ -979,6 +978,7 @@ bool balancer_t::reconfigure_wlc()
}

std::vector<std::tuple<balancer::real_key_global_t, uint32_t, uint32_t>> service_reals_usage_info;
service_reals_usage_info.reserve(reals.size());
uint32_t connection_sum = 0;
uint32_t weight_sum = 0;

Expand Down Expand Up @@ -1026,7 +1026,7 @@ bool balancer_t::reconfigure_wlc()
effective_weight,
connections] : service_reals_usage_info)
{
uint32_t wlc_power = scheduler_params.wlc_power;
uint32_t wlc_power = requested_wlc_power;
if (wlc_power < 1 || wlc_power > 100)
{
wlc_power = YANET_CONFIG_BALANCER_WLC_DEFAULT_POWER;
Expand Down
10 changes: 7 additions & 3 deletions controlplane/configparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,8 +1660,8 @@ void config_parser_t::loadConfig_balancer_services(controlplane::base_t& baseNex
std::string scheduler_string = service_json["scheduler"];

balancer::scheduler scheduler{};
balancer::scheduler_params scheduler_params{};
uint8_t flags = 0;
std::uint32_t wlc_power{};
if (scheduler_string == "rr")
{
scheduler = balancer::scheduler::rr;
Expand All @@ -1675,9 +1675,13 @@ void config_parser_t::loadConfig_balancer_services(controlplane::base_t& baseNex
scheduler = balancer::scheduler::wlc;
if (exist(service_json, "scheduler_params") && exist(service_json["scheduler_params"], "wlc_power"))
{
scheduler_params.wlc_power = std::stoll(service_json["scheduler_params"]["wlc_power"].get<std::string>(), nullptr, 10);
wlc_power = std::stoll(service_json["scheduler_params"]["wlc_power"].get<std::string>(), nullptr, 10);
}
}
else if (scheduler_string == "chash")
{
scheduler = balancer::scheduler::chash;
}
else if (scheduler_string == "purr")
{
scheduler = balancer::scheduler::wrr;
Expand Down Expand Up @@ -1764,7 +1768,7 @@ void config_parser_t::loadConfig_balancer_services(controlplane::base_t& baseNex
exist(service_json, "vport") ? std::make_optional(std::stoll(service_json["vport"].get<std::string>(), nullptr, 0)) : std::nullopt,
service_version,
scheduler,
scheduler_params,
wlc_power,
forwarding_method,
flags,
ipv4_outer_source_network,
Expand Down
Loading