Skip to content
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
1,442 changes: 1,442 additions & 0 deletions modules/balancer2/api/controlplane.c

Large diffs are not rendered by default.

41 changes: 27 additions & 14 deletions modules/balancer2/api/controlplane.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ struct balancer_session_table_chain;
/*
* Creates a balancer handle from its full configuration.
*
* The session table chain and session timeouts must be non-NULL. The
* session table chain must outlive the returned balancer handle; it
* is referenced, not owned. The session timeouts are copied into the
* handle.
* The agent, session table chain, and session timeouts must be
* non-NULL, and the name must be non-empty. The session table chain
* must outlive the returned balancer handle; it is referenced, not
* owned. The session timeouts are copied into the handle.
*
* Returns NULL on error.
*/
struct balancer_handle *
balancer_create(
Expand All @@ -115,6 +117,8 @@ balancer_create(
/*
* Installs a balancer handle in the dataplane.
*
* The agent and handle must be non-NULL.
*
* If a balancer with the same name is already installed, it is
* replaced; the previous handle becomes unused and the caller is
* responsible for freeing it.
Expand All @@ -134,9 +138,11 @@ void
balancer_free(struct agent *agent, struct balancer_handle *handle);

/*
* Updates per-real weights for a VS. The weights array must have
* length equal to the number of reals configured for the VS and be
* indexed in the same order as they were passed at VS creation.
* Updates per-real weights for a VS. The balancer handle must be
* non-NULL. The weights array must have length equal to the number
* of reals configured for the VS and be indexed in the same order
* as they were passed at VS creation.
*
* Returns 0 on success, -1 on error.
*/
int
Expand All @@ -148,9 +154,10 @@ balancer_vs_update_real_weights(
);

/*
* Updates per-real enabled flags for a VS. The states array must have
* length equal to the number of reals configured for the VS and be
* indexed in the same order as they were passed at VS creation.
* Updates per-real enabled flags for a VS. The balancer handle must
* be non-NULL. The states array must have length equal to the number
* of reals configured for the VS and be indexed in the same order
* as they were passed at VS creation.
*
* Reals start disabled after balancer_create. Until this function is
* called with a state of true for a given real, that real does not
Expand Down Expand Up @@ -204,7 +211,10 @@ struct balancer_session_table;

/*
* Creates a session table with the given capacity (number of session
* entries).
* entries). The agent must be non-NULL and the capacity must be
* non-zero.
*
* Returns NULL on error.
*/
struct balancer_session_table *
balancer_create_session_table(
Expand All @@ -213,6 +223,7 @@ balancer_create_session_table(

/*
* Pushes the given table as the new front (primary) session table.
* The chain and front table must be non-NULL.
*
* Workers look up sessions in the front table first and fall back to
* the previous (back) table; a session found in the back table is
Expand All @@ -228,7 +239,7 @@ balancer_session_table_chain_push_front(
);

/*
* Detaches the back session table.
* Detaches the back session table. The chain must be non-NULL.
*
* After this call, new workers ignore the detached table for lookups.
*
Expand All @@ -250,8 +261,10 @@ balancer_free_session_table(

/*
* Creates a session table chain seeded with the given front table.
* The table is not owned by the chain and must outlive it.
* Returns NULL on allocation failure.
* The agent and front table must be non-NULL. The table is not owned
* by the chain and must outlive it.
*
* Returns NULL on error.
*/
struct balancer_session_table_chain *
balancer_create_session_table_chain(
Expand Down
26 changes: 26 additions & 0 deletions modules/balancer2/api/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
dependencies = [
lib_common_dep,
lib_agent_cp_dep,
lib_filter_compiler_dep,
]

includes = include_directories('.', '../')

sources = files(
'controlplane.c',
)

lib_balancer2_cp = static_library(
'balancer2_cp',
sources,
c_args: yanet_c_args,
link_args: yanet_link_args,
dependencies: dependencies,
include_directories: includes,
install: false,
)

lib_balancer2_cp_dep = declare_dependency(
link_with: [lib_balancer2_cp],
)

35 changes: 35 additions & 0 deletions modules/balancer2/dataplane/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "filter/filter.h"

#include "lib/controlplane/config/cp_module.h"

#include "types/session.h"

#include "common/rcu.h"

struct balancer_session_table_chain;
struct virtual_service;

struct balancer_module_config {
struct cp_module cp_module;

uint64_t common_counter_id;
uint64_t l4_counter_id;

struct filter vs_matcher_ip4;
struct filter vs_matcher_ip6;

struct virtual_service *vs;
uint32_t vs_count;

struct balancer_session_timeouts session_timeouts;

struct balancer_session_table_chain *st_chain;

/*
* RCU guard for the inner atomic changes on the config,
* including changes on reals ring of virtual services.
*/
rcu_t rcu;
};
47 changes: 47 additions & 0 deletions modules/balancer2/dataplane/dataplane.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <netinet/in.h>
#include <rte_ether.h>
#include <stdio.h>
#include <stdlib.h>

#include "lib/dataplane/config/zone.h"
#include "lib/dataplane/module/packet_front.h"
#include "lib/dataplane/pipeline/econtext.h"

#include "dataplane.h"

void
balancer2_handle_packets(
struct dp_worker *dp_worker,
struct module_ectx *module_ectx,
struct packet_front *packet_front
) {
(void)dp_worker;
(void)module_ectx;
(void)packet_front;
// TODO
}

struct balancer_module {
struct module module;
};

struct module *
new_module_balancer2() {
struct balancer_module *module =
(struct balancer_module *)malloc(sizeof(struct balancer_module)
);

if (module == NULL) {
return NULL;
}

snprintf(
module->module.name,
sizeof(module->module.name),
"%s",
"balancer"
);
module->module.handler = balancer2_handle_packets;

return &module->module;
}
4 changes: 4 additions & 0 deletions modules/balancer2/dataplane/dataplane.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

struct module *
new_module_balancer2();
32 changes: 32 additions & 0 deletions modules/balancer2/dataplane/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
dp_dependencies = [
lib_common_dep,
lib_packet_dp_dep,
lib_module_dp_dep,
lib_worker_dp_dep,
lib_filter_query_dep,
]

includes = include_directories('.', '../../../')

dp_sources = files(
'dataplane.c',
)

lib_balancer2_dp = static_library(
'balancer2_dp',
dp_sources,
c_args: yanet_c_args,
link_args: yanet_link_args,
dependencies: dp_dependencies,
include_directories: includes,
install: false,
)

lib_balancer2_dp_dep = declare_dependency(
link_with: lib_balancer2_dp,
link_args: [
'-Wl,--defsym',
'-Wl,new_module_balancer2=new_module_balancer2',
'-Wl,--export-dynamic-symbol=new_module_balancer2',
],
)
42 changes: 42 additions & 0 deletions modules/balancer2/dataplane/real.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include <stdbool.h>

#include "common/network.h"

enum real_flags {
real_enabled = 1u << 0,
real_ip6 = 1u << 1,
};

/*
* A real (backend) server within a virtual service.
*
* Stored in a per-VS contiguous array indexed by config index.
* See struct balancer_vs for the array layout and indexing scheme.
*/
struct real {
/* Destination IP address of the real server (IPv4 or IPv6). */
struct net_addr addr;

/*
* Source network for the outer tunnel header.
*
* Contains both the base address (src.v4.addr / src.v6.addr)
* and the mask (src.v4.mask / src.v6.mask).
*
* INVARIANT: the address bytes must be pre-masked by the
* controlplane, i.e. (addr[i] & mask[i]) == addr[i] for every
* byte i. The tunnel code relies on this to embed client source
* IP bits into the unmasked positions without an extra AND:
*
* outer_src[i] = addr[i] | (client_src[i] & ~mask[i])
*
* Use v4 when balancer_real_ipv6 is clear, v6 when set.
*/
struct net src;

uint64_t counter_id;

_Atomic uint8_t flags;
};
52 changes: 52 additions & 0 deletions modules/balancer2/dataplane/selector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include <stddef.h>
#include <stdint.h>

#include "common/big_array.h"

/**
* Ring containing real indices.
*
* Each backend appears multiple times according to its weight.
* The ring is shuffled to distribute selections evenly.
*/
struct ring {
/*
* Indices of backend servers.
*
* Stored in a big array because the weighted list can exceed
* the allocator's maximum block size.
*/
struct big_array real_ids;
};

/**
* Round-robin counter.
*
* Used to track the position of the current real in the ring.
*/
struct rr_counter {
uint64_t value;
} __attribute__((aligned(64)));

/**
* Real backend selector.
*
* Maintains two rings for RCU-swapped updates and per-worker RR counters.
* Uses either round-robin or hash-based selection,
* depending on the virtual server scheduler.
*/
struct real_selector {
/* Double-buffered rings. */
struct ring rings[2];

/* Active ring index. */
_Atomic uint64_t ring_id;

/* TODO: docs */
uint64_t packet_hash_mask;

/* Array of per-worker round-robin counters. */
struct rr_counter workers_rr_counter[];
};
45 changes: 45 additions & 0 deletions modules/balancer2/dataplane/session.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <stddef.h>

#include "common/rcu.h"
#include "common/ttlmap/detail/ttlmap.h"

struct balancer_session_table {
struct ttlmap map;
};

/*
* All access to session table chain must happen within a critical
* section (st_begin_cs / st_end_cs). The critical section pins the
* current generation, ensuring the controlplane does not
* free a map while workers are still reading it.
*/
struct balancer_session_table_chain {
_Atomic uint64_t gen;
struct balancer_session_table *tables[2];
rcu_t rcu;
};

/*
* Enter a session table chain critical section.
* Returns the current generation, which must be passed to
* all subsequent st_* calls within this critical section.
*/
static inline uint64_t
st_chain_begin_cs(
struct balancer_session_table_chain *st_chain, uint32_t worker
) {
return RCU_READ_BEGIN(&st_chain->rcu, worker, &st_chain->gen);
}

/*
* Leave a session table chain critical section.
* After this call, the controlplane may update the chain.
*/
static inline void
st_chain_end_cs(
struct balancer_session_table_chain *st_chain, uint32_t worker
) {
RCU_READ_END(&st_chain->rcu, worker);
}
Loading
Loading