Skip to content

Commit

Permalink
fix balancer: add pure round robin
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergei Tolmachev committed Jan 30, 2025
1 parent 9fccdf6 commit 61569ef
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 1 deletion.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
steps:
- ipv4Update: "0.0.0.0/0 -> 200.0.0.1"
- ipv6Update: "::/0 -> fe80::1"
- cli:
- balancer real enable balancer0 10.0.0.3 udp 80 2000::1 80
- balancer real enable balancer0 10.0.0.3 udp 80 2000::2 80
- balancer real enable balancer0 10.0.0.3 udp 80 2000::3 80
- balancer real enable balancer0 10.0.0.3 udp 81 2000::1 81
- balancer real enable balancer0 10.0.0.3 udp 81 2000::2 81
- balancer real flush
- sendPackets:
- port: kni0
send: 001-send.pcap
expect: 001-expect.pcap
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"modules": {
"lp0.100": {
"type": "logicalPort",
"physicalPort": "kni0",
"vlanId": "100",
"macAddress": "00:11:22:33:44:55",
"nextModule": "acl0"
},
"lp0.200": {
"type": "logicalPort",
"physicalPort": "kni0",
"vlanId": "200",
"macAddress": "00:11:22:33:44:55",
"nextModule": "acl0"
},
"acl0": {
"type": "acl",
"nextModules": [
"balancer0",
"route0"
]
},
"balancer0": {
"type": "balancer",
"source": "2000:51b::1",
"services": "services.conf",
"nextModule": "route0"
},
"route0": {
"type": "route",
"interfaces": {
"kni0.100": {
"neighborIPv6Address": "fe80::1",
"neighborMacAddress": "00:00:00:00:00:01",
"nextModule": "lp0.100"
},
"kni0.200": {
"neighborIPv4Address": "200.0.0.1",
"neighborMacAddress": "00:00:00:00:00:02",
"nextModule": "lp0.200"
}
}
}
}
}
50 changes: 50 additions & 0 deletions autotest/units/001_one_port/080_balancer_pure_round_robin/gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from scapy.all import *


def write_pcap(filename, *packetsList):
if len(packetsList) == 0:
PcapWriter(filename)._write_header(Ether())
return

PcapWriter(filename)

for packets in packetsList:
if type(packets) == list:
for packet in packets:
packet.time = 0
wrpcap(filename, [p for p in packet], append=True)
else:
packets.time = 0
wrpcap(filename, [p for p in packets], append=True)


write_pcap("001-send.pcap",
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380))

write_pcap("001-expect.pcap",
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::2", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::3", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::2", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::3", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::2", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::3", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=80, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380),
Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IPv6(dst="2000::1", src="2000:51b::0101:0001:0:1", hlim=63, fl=0)/IP(dst="10.0.0.3", src="1.1.0.1", ttl=64)/UDP(dport=81, sport=12380))
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"vip": "10.0.0.3",
"proto": "udp",
"vport": "80",
"scheduler": "rr",
"pure_round_robin": true,
"ops": true,
"reals": [
{
"ip": "2000::1",
"port": "80"
},
{
"ip": "2000::2",
"port": "80"
},
{
"ip": "2000::3",
"port": "80"
}
]
},
{
"vip": "10.0.0.3",
"proto": "udp",
"vport": "81",
"scheduler": "rr",
"reals": [
{
"ip": "2000::1",
"port": "81"
},
{
"ip": "2000::2",
"port": "81"
}
]
}
]
1 change: 1 addition & 0 deletions common/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ extern LogPriority logPriority;

#define YANET_BALANCER_OPS_FLAG ((uint8_t)(1u << 1))
#define YANET_BALANCER_PURE_L3 ((uint8_t)(1u << 2))
#define YANET_BALANCER_PURE_ROUND_ROBIN ((uint8_t)(1u << 3))

#define CALCULATE_LOGICALPORT_ID(portId, vlanId) ((portId << 13) | ((vlanId & 0xFFF) << 1) | 1)

Expand Down
5 changes: 5 additions & 0 deletions controlplane/configparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1743,6 +1743,11 @@ void config_parser_t::loadConfig_balancer_services(controlplane::base_t& baseNex
flags |= YANET_BALANCER_OPS_FLAG;
}

if (service_json.value("pure_round_robin", false))
{
flags |= YANET_BALANCER_PURE_ROUND_ROBIN;
}

balancer.services.emplace_back(baseNext.services_count + 1, ///< 0 is invalid id
service_json["vip"].get<std::string>(),
proto,
Expand Down
5 changes: 4 additions & 1 deletion dataplane/worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ cWorker::cWorker(cDataPlane* dataPlane) :
ring_lowPriority(nullptr),
ring_toFreePackets(nullptr),
ring_log(nullptr),
roundRobinCounter(0),
packetsToSWNPRemainder(dataPlane->config.SWNormalPriorityRateLimitPerWorker)
{
}
Expand Down Expand Up @@ -4117,7 +4118,9 @@ inline void cWorker::balancer_handle()
continue;
}

const auto& real_id = ring->reals[range->start + (metadata->hash % range->size)];

const auto& reals_shift = service.flags & YANET_BALANCER_PURE_ROUND_ROBIN ? ++roundRobinCounter : metadata->hash;
const auto& real_id = ring->reals[range->start + (reals_shift % range->size)];
const auto& real_unordered = base.globalBase->balancer_reals[real_id];
if (!value)
{
Expand Down
1 change: 1 addition & 0 deletions dataplane/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ class cWorker
uint64_t* bursts; // CONFIG_YADECAP_MBUFS_BURST_SIZE + 1
uint64_t* counters; // YANET_CONFIG_COUNTERS_SIZE
uint64_t* aclCounters; // YANET_CONFIG_ACL_COUNTERS_SIZE
uint64_t roundRobinCounter;

// will decrease with each new packet sent to slow worker, replenishes each N mseconds
int32_t packetsToSWNPRemainder;
Expand Down

0 comments on commit 61569ef

Please sign in to comment.