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

socket_options: small cleanup regarding setting socket options (IP_TRANSPARENT & SO_REUSEADDR) #1071

Merged
Merged
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
59 changes: 26 additions & 33 deletions cilium/socket_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,52 +92,45 @@ class SocketMarkOption : public Network::Socket::Option,
// identity is zero for the listener socket itself, set transparent and reuse options also for
// the listener socket.
if (source_address || identity_ == 0) {
// Allow reuse of the original source address. This may by needed for
// retries to not fail on "address already in use" when using a specific
// source address and port.

// Set ip transparent option based on the socket address family
if (*ipVersion == Network::Address::IpVersion::v4) {
auto status = cilium_calls.setsockopt(socket.ioHandle().fdDoNotUse(), SOL_IP,
IP_TRANSPARENT, &one, sizeof(one));
if (status.return_value_ < 0) {
if (status.errno_ == EPERM) {
// Do not assert out in this case so that we can run tests without
// CAP_NET_ADMIN.
ENVOY_LOG(critical,
"Failed to set socket option IP_TRANSPARENT, capability "
"CAP_NET_ADMIN needed: {}",
Envoy::errorDetails(status.errno_));
} else {
ENVOY_LOG(critical, "Socket option failure. Failed to set IP_TRANSPARENT: {}",
Envoy::errorDetails(status.errno_));
return false;
}
{
// Set ip transparent option based on the socket address family
auto ip_socket_level = SOL_IP;
auto ip_transparent_socket_option = IP_TRANSPARENT;
auto ip_transparent_socket_option_name = "IP_TRANSPARENT";
if (*ipVersion == Network::Address::IpVersion::v6) {
ip_socket_level = SOL_IPV6;
ip_transparent_socket_option = IPV6_TRANSPARENT;
ip_transparent_socket_option_name = "IPV6_TRANSPARENT";
}
} else if (*ipVersion == Network::Address::IpVersion::v6) {
auto status = cilium_calls.setsockopt(socket.ioHandle().fdDoNotUse(), SOL_IPV6,
IPV6_TRANSPARENT, &one, sizeof(one));

auto status = cilium_calls.setsockopt(socket.ioHandle().fdDoNotUse(), ip_socket_level,
ip_transparent_socket_option, &one, sizeof(one));
if (status.return_value_ < 0) {
if (status.errno_ == EPERM) {
// Do not assert out in this case so that we can run tests without
// CAP_NET_ADMIN.
ENVOY_LOG(critical,
"Failed to set socket option IPV6_TRANSPARENT, capability "
"Failed to set socket option {}, capability "
"CAP_NET_ADMIN needed: {}",
Envoy::errorDetails(status.errno_));
ip_transparent_socket_option_name, Envoy::errorDetails(status.errno_));
} else {
ENVOY_LOG(critical, "Socket option failure. Failed to set IPV6_TRANSPARENT: {}",
Envoy::errorDetails(status.errno_));
ENVOY_LOG(critical, "Socket option failure. Failed to set {}: {}",
ip_transparent_socket_option_name, Envoy::errorDetails(status.errno_));
return false;
}
}
}

auto status = socket.setSocketOption(SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (status.return_value_ < 0) {
ENVOY_LOG(critical, "Failed to set socket option SO_REUSEADDR: {}",
Envoy::errorDetails(status.errno_));
return false;
// Allow reuse of the original source address. This may by needed for
// retries to not fail on "address already in use" when using a specific
// source address and port.
{
auto status = socket.setSocketOption(SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (status.return_value_ < 0) {
ENVOY_LOG(critical, "Failed to set socket option SO_REUSEADDR: {}",
Envoy::errorDetails(status.errno_));
return false;
}
}
}

Expand Down
Loading