Skip to content

Commit

Permalink
api: add enable_reuse_port
Browse files Browse the repository at this point in the history
Currently, the socket option `SO_REUSEPORT` is always set on the
Listener sockets and is no longer configurable. Previously
(before #315), this was configurable  via Envoy Listeners option
`enable_reuse_port`.

Therefore, this commit introduces the config property `enable_reuse_port`
on the `BPFMetadata` to reintroduce the possibility to configure this
behaviour.

Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
  • Loading branch information
mhofstetter committed Jan 22, 2024
1 parent f63f6f8 commit 5da9cc8
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 20 deletions.
7 changes: 7 additions & 0 deletions cilium/api/bpf_metadata.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,11 @@ message BpfMetadata {
// proxy_id is passed to access log messages and allows relating access log messages to
// listeners.
uint32 proxy_id = 8;

// When this flag is set to true, listeners set the “SO_REUSEPORT“ socket option and
// create one socket for each worker thread. This makes inbound connections
// distribute among worker threads roughly evenly in cases where there are a high number
// of connections. When this flag is set to false, all worker threads share one socket. This field
// defaults to true.
bool enable_reuse_port = 9;
}
5 changes: 3 additions & 2 deletions cilium/bpf_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ Config::Config(const ::cilium::BpfMetadata& config,
Network::Utility::parseInternetAddressNoThrow(config.ipv4_source_address())),
ipv6_source_address_(
Network::Utility::parseInternetAddressNoThrow(config.ipv6_source_address())),
enforce_policy_on_l7lb_(config.enforce_policy_on_l7lb()) {
enforce_policy_on_l7lb_(config.enforce_policy_on_l7lb()),
enable_reuse_port_(config.enable_reuse_port()) {
if (is_l7lb_ && is_ingress_) {
throw EnvoyException("cilium.bpf_metadata: is_l7lb may not be set with is_ingress");
}
Expand Down Expand Up @@ -422,7 +423,7 @@ bool Config::getMetadata(Network::ConnectionSocket& socket) {
socket.addOption(std::make_shared<Cilium::SocketOption>(
policy, mark, ingress_source_identity, source_identity, is_ingress_, is_l7lb_, dip->port(),
std::move(pod_ip), std::move(src_address), std::move(ipv4_source_address),
std::move(ipv6_source_address), shared_from_this(), proxy_id_));
std::move(ipv6_source_address), shared_from_this(), proxy_id_, enable_reuse_port_));
return true;
}

Expand Down
1 change: 1 addition & 0 deletions cilium/bpf_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Config : public Cilium::PolicyResolver,
Network::Address::InstanceConstSharedPtr ipv4_source_address_;
Network::Address::InstanceConstSharedPtr ipv6_source_address_;
bool enforce_policy_on_l7lb_;
bool enable_reuse_port_;

std::shared_ptr<const Cilium::NetworkPolicyMap> npmap_{};
Cilium::CtMapSharedPtr ct_maps_{};
Expand Down
30 changes: 19 additions & 11 deletions cilium/socket_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ class SocketMarkOption : public Network::Socket::Option,
SocketMarkOption(uint32_t mark, uint32_t identity,
Network::Address::InstanceConstSharedPtr original_source_address = nullptr,
Network::Address::InstanceConstSharedPtr ipv4_source_address = nullptr,
Network::Address::InstanceConstSharedPtr ipv6_source_address = nullptr)
Network::Address::InstanceConstSharedPtr ipv6_source_address = nullptr,
bool enable_reuse_port = true)
: identity_(identity), mark_(mark),
original_source_address_(std::move(original_source_address)),
ipv4_source_address_(std::move(ipv4_source_address)),
ipv6_source_address_(std::move(ipv6_source_address)) {}
ipv6_source_address_(std::move(ipv6_source_address)),
enable_reuse_port_(enable_reuse_port) {}

absl::optional<Network::Socket::Option::Details>
getOptionDetails(const Network::Socket&,
Expand Down Expand Up @@ -135,11 +137,14 @@ class SocketMarkOption : public Network::Socket::Option,
Envoy::errorDetails(status.errno_));
return false;
}
status = socket.setSocketOption(SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
if (status.return_value_ < 0) {
ENVOY_LOG(critical, "Failed to set socket option SO_REUSEPORT: {}",
Envoy::errorDetails(status.errno_));
return false;

if (enable_reuse_port_) {
status = socket.setSocketOption(SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
if (status.return_value_ < 0) {
ENVOY_LOG(critical, "Failed to set socket option SO_REUSEPORT: {}",
Envoy::errorDetails(status.errno_));
return false;
}
}
}

Expand Down Expand Up @@ -200,6 +205,8 @@ class SocketMarkOption : public Network::Socket::Option,
// connecting to IPv6 or IPv4 address, respectively.
Network::Address::InstanceConstSharedPtr ipv4_source_address_;
Network::Address::InstanceConstSharedPtr ipv6_source_address_;

bool enable_reuse_port_;
};

class SocketOption : public SocketMarkOption {
Expand All @@ -210,21 +217,22 @@ class SocketOption : public SocketMarkOption {
Network::Address::InstanceConstSharedPtr original_source_address,
Network::Address::InstanceConstSharedPtr ipv4_source_address,
Network::Address::InstanceConstSharedPtr ipv6_source_address,
const std::shared_ptr<PolicyResolver>& policy_id_resolver, uint32_t proxy_id)
const std::shared_ptr<PolicyResolver>& policy_id_resolver, uint32_t proxy_id,
bool enable_reuse_port)
: SocketMarkOption(mark, source_identity, original_source_address, ipv4_source_address,
ipv6_source_address),
ipv6_source_address, enable_reuse_port),
ingress_source_identity_(ingress_source_identity), initial_policy_(policy),
ingress_(ingress), is_l7lb_(l7lb), port_(port), pod_ip_(std::move(pod_ip)),
proxy_id_(proxy_id), policy_id_resolver_(policy_id_resolver) {
ENVOY_LOG(debug,
"Cilium SocketOption(): source_identity: {}, "
"ingress: {}, port: {}, pod_ip: {}, source_addresses: {}/{}/{}, mark: {:x} (magic "
"mark: {:x}, cluster: {}, ID: {}), proxy_id: {}",
"mark: {:x}, cluster: {}, ID: {}), proxy_id: {}, enable_reuse_port: {}",
identity_, ingress_, port_, pod_ip_,
original_source_address_ ? original_source_address_->asString() : "",
ipv4_source_address_ ? ipv4_source_address_->asString() : "",
ipv6_source_address_ ? ipv6_source_address_->asString() : "", mark_, mark & 0xff00,
mark & 0xff, mark >> 16, proxy_id_);
mark & 0xff, mark >> 16, proxy_id_, enable_reuse_port_);
ASSERT(initial_policy_ != nullptr);
}

Expand Down
27 changes: 21 additions & 6 deletions go/cilium/api/bpf_metadata.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions go/cilium/api/bpf_metadata.pb.validate.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/bpf_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ bool TestConfig::getMetadata(Network::ConnectionSocket& socket) {

socket.addOption(std::make_shared<Cilium::SocketOption>(
policy, 0, 0, source_identity, is_ingress_, false, port, std::move(pod_ip), nullptr, nullptr,
nullptr, shared_from_this(), 0));
nullptr, shared_from_this(), 0, true));

return true;
}
Expand Down

0 comments on commit 5da9cc8

Please sign in to comment.