Skip to content

Commit

Permalink
Merge branch 'v3_8'
Browse files Browse the repository at this point in the history
  • Loading branch information
abower-amd committed Sep 23, 2024
2 parents f0cc62e + 373add9 commit 7bd7998
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 10 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

## [3.8.0.1002] - 2024-09-30
## [3.8.0.1002] - 2024-09-30 [Feature Release]

### Added

Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ uninstall:
flat_install: SBINDIR=bin
flat_install: prefix=
flat_install: install
cd $(DESTDIR) && ln -sf $(SBINDIR)/* .

# Prevent make from removing any build targets, including intermediate ones

Expand Down
4 changes: 2 additions & 2 deletions mk/install.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ SBINDIR ?= sbin

ifneq (,$(wildcard /etc/debian_version))
DEFAULT_DEFAULTSDIR := default
DEFAULT_UNITPREFIX :=
DEFAULT_UNITPREFIX =
else
DEFAULT_DEFAULTSDIR := sysconfig
DEFAULT_UNITPREFIX := $(prefix)
DEFAULT_UNITPREFIX = $(prefix)
endif

# Installation variables
Expand Down
35 changes: 35 additions & 0 deletions src/ptp/ptpd2/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,34 @@ struct socket_ifindex {
};


/* A unique reason for why a given bond socket has been invalidated. */
enum bond_sock_invalid_reason {
BOND_SOCK_INVALID_REASON_SOCKET,
BOND_SOCK_INVALID_REASON_BIND,
BOND_SOCK_INVALID_REASON_SETSOCKOPT,
BOND_SOCK_INVALID_REASON_ADD_TO_EPOLL_SET,
BOND_SOCK_INVALID_REASON_SHUTDOWN
};


/* A more in-depth description about why a bond socket has been invalidated */
union bond_sock_invalid_description {
struct {
enum bond_sock_invalid_reason reason;
} anonymous, shutdown;
struct {
enum bond_sock_invalid_reason reason;
int rc;
} socket, bind, add_to_epoll_set;
struct {
enum bond_sock_invalid_reason reason;
int rc;
int level;
int sockopt;
} setsockopt;
};


/* A structure containing IP transport information. There is one of these
per interface object. It is defined separately because different
types of transport implementation may in future be required so it is
Expand All @@ -628,10 +656,17 @@ struct ptpd_transport {

const struct sfptpd_ptp_bond_info *bond_info;
int bondSocks[SFPTP_BOND_BYPASS_SOCK_COUNT];
/* This keeps track of how many sockets we tried creating, and is only
* used for diagnostics. See `bondSocksValidMask` for checking which
* entires in `bondSocks` are usable. */
int bondSocksCreatedCount;
/* A mask of the above array for those sockets which are valid. Here,
* valid means that we were able to create and set all of the socket
* options that we wanted. */
uint64_t bondSocksValidMask;
/* A collection of reasons why a given bond socket is invalid, useful
* for diagnostics purposes. */
union bond_sock_invalid_description bondSocksInvalidDescriptions[SFPTP_BOND_BYPASS_SOCK_COUNT];
/* A mapping of socket fd to the physical ifindex the socket will send
* out of for a multicast message. */
struct socket_ifindex multicastBondSocks[SFPTP_MAX_PHYSICAL_IFS];
Expand Down
133 changes: 128 additions & 5 deletions src/ptp/ptpd2/sfptpd_lacp.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,41 +60,69 @@ void createBondSocks(struct ptpd_transport *transport, int transportAF)
assert(sockCount <= SFPTP_BOND_BYPASS_SOCK_COUNT);
for (i = 0; i < sockCount; i++) {
int sockfd, rc;
union bond_sock_invalid_description *invalid_desc =
&transport->bondSocksInvalidDescriptions[i];

assert(transport->bondSocks[i] == 0);

sockfd = socket(transportAF, SOCK_DGRAM, 0);
if (sockfd < 0)
if (sockfd < 0) {
invalid_desc->socket.reason =
BOND_SOCK_INVALID_REASON_SOCKET;
invalid_desc->socket.rc = sockfd;
continue;
}

rc = bind(sockfd, &localAddr, sizeof(localAddr));
if (rc < 0) {
invalid_desc->bind.reason =
BOND_SOCK_INVALID_REASON_BIND;
invalid_desc->bind.rc = rc;
close(sockfd);
continue;
}

rc = setsockopt(sockfd, level, opt, &one, sizeof(one));
if (rc < 0) {
invalid_desc->setsockopt.reason =
BOND_SOCK_INVALID_REASON_SETSOCKOPT;
invalid_desc->setsockopt.rc = rc;
invalid_desc->setsockopt.level = level;
invalid_desc->setsockopt.sockopt = opt;
close(sockfd);
continue;
}

rc = sfptpd_thread_user_fd_add(sockfd, true, false);
if (rc != 0) {
invalid_desc->add_to_epoll_set.reason =
BOND_SOCK_INVALID_REASON_ADD_TO_EPOLL_SET;
invalid_desc->add_to_epoll_set.rc = rc;
close(sockfd);
continue;
}

transport->bondSocks[i] = sockfd;
transport->bondSocksValidMask |= (1 << i);
}

/* We want to include even those that might have failed for the sake of
* being able to log which sockets have been invalidated. */
transport->bondSocksCreatedCount = sockCount;
}

void destroyBondSocks(struct ptpd_transport *transport)
{
FOR_EACH_MASK_IDX(transport->bondSocksValidMask, idx)
FOR_EACH_MASK_IDX(transport->bondSocksValidMask, idx) {
union bond_sock_invalid_description *invalid_desc =
&transport->bondSocksInvalidDescriptions[idx];

invalidateBondBypassSocket(transport, idx);

invalid_desc->shutdown.reason =
BOND_SOCK_INVALID_REASON_SHUTDOWN;
}

/* Should already be true but doesn't hurt to do it here too */
transport->bondSocksValidMask = 0ull;
transport->multicastBondSocksLen = 0;
Expand Down Expand Up @@ -196,10 +224,23 @@ int bondSockFdIndexInSockPool(struct ptpd_transport *transport, int sockfd)
void setBondSockopt(struct ptpd_transport *transport, int level, int optname,
const void *optval, socklen_t optlen)
{
FOR_EACH_MASK_IDX(transport->bondSocksValidMask, idx)
if (setsockopt(transport->bondSocks[idx], level, optname,
optval, optlen) < 0)
int rc;
FOR_EACH_MASK_IDX(transport->bondSocksValidMask, idx) {
if ((rc = setsockopt(transport->bondSocks[idx], level, optname,
optval, optlen)) < 0) {
union bond_sock_invalid_description *invalid_desc =
&transport->bondSocksInvalidDescriptions[idx];

invalidateBondBypassSocket(transport, idx);

invalid_desc->setsockopt.reason =
BOND_SOCK_INVALID_REASON_SETSOCKOPT;
invalid_desc->setsockopt.rc = rc;
invalid_desc->setsockopt.level = level;
invalid_desc->setsockopt.sockopt = optname;
}

}
}

void copyMulticastTTLToBondSocks(struct ptpd_transport *transport)
Expand All @@ -216,3 +257,85 @@ void copyTimestampingToBondSocks(struct ptpd_transport *transport,
setBondSockopt(transport, SOL_SOCKET, tsSetupMethod->sockopt,
&flags, sizeof(flags));
}

#define BOND_SOCK_INVALID_REASON_STRLEN 39
void getBondSockInvalidReason(struct ptpd_transport *transport, int idx,
char *reason)
{
union bond_sock_invalid_description *invalid_desc =
&transport->bondSocksInvalidDescriptions[idx];

switch (invalid_desc->anonymous.reason) {
case BOND_SOCK_INVALID_REASON_SOCKET:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: socket = %d",
invalid_desc->socket.rc);
break;
case BOND_SOCK_INVALID_REASON_BIND:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: bind = %d",
invalid_desc->bind.rc);
break;
case BOND_SOCK_INVALID_REASON_SETSOCKOPT:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: setsockopt(%d, %d) = %d",
invalid_desc->setsockopt.level,
invalid_desc->setsockopt.sockopt,
invalid_desc->setsockopt.rc);
break;
case BOND_SOCK_INVALID_REASON_ADD_TO_EPOLL_SET:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: add_to_epoll = %d",
invalid_desc->add_to_epoll_set.rc);
break;
case BOND_SOCK_INVALID_REASON_SHUTDOWN:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: shutdown");
break;
default:
snprintf(reason, BOND_SOCK_INVALID_REASON_STRLEN,
"INVALID: unknown reason");
break;
}
}

void bondSocksDumpState(struct ptpd_intf_context *intf, int sev)
{
const char *header[] = { "#", "fd", "port", "mcast ifindex" };
const char *formatHeader = "| %-2s | %-10s | %-10s | %-13s |\n";
const char *formatRecordValid = "| %-2d | %-10d | %-10d | %-13d |\n";
const char *formatRecordInvalid =
"| %-2d | %-" STRINGIFY(BOND_SOCK_INVALID_REASON_STRLEN) "s |\n";
const char *separator =
"|----+------------+------------+---------------|\n";
char invalidReason[BOND_SOCK_INVALID_REASON_STRLEN];
struct ptpd_transport *transport = &intf->transport;
int i;

if (transport->bondSocksCreatedCount <= 0)
return;

TRACE_LX(sev, "LACP bypass sockets state for interface %s:\n",
transport->bond_info->bond_if);
TRACE_LX(sev, formatHeader, header[0], header[1], header[2], header[3]);
TRACE_LX(sev, separator);
for (i = 0; i < transport->bondSocksCreatedCount; i++) {
if (transport->bondSocksValidMask & (1 << i)) {
int fd = transport->bondSocks[i];
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
int getsockname_rc;
struct socket_ifindex *mapping;

getsockname_rc = getsockname(fd, &addr, &addrlen);
mapping = bondSockFindMulticastMappingByFd(transport, fd);

TRACE_LX(sev, formatRecordValid, i, fd,
(getsockname_rc == 0) ? ntohs(addr.sin_port) : 0,
(mapping) ? mapping->ifindex : 0);
} else {
getBondSockInvalidReason(transport, i, invalidReason);
TRACE_LX(sev, formatRecordInvalid, i, invalidReason);
}
}
}
2 changes: 2 additions & 0 deletions src/ptp/ptpd2/sfptpd_lacp.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,6 @@ void copyMulticastTTLToBondSocks(struct ptpd_transport *transport);
void copyTimestampingToBondSocks(struct ptpd_transport *transport,
TsSetupMethod *tsMethodVerbose);

void bondSocksDumpState(struct ptpd_intf_context *intf, int sev);

#endif /* _SFPTPD_LACP_H */
4 changes: 3 additions & 1 deletion src/ptp/sfptpd_ptp_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -3986,8 +3986,10 @@ static void on_dump_tables(struct sfptpd_ptp_module *ptp,
{
struct sfptpd_ptp_intf *interface;

for (interface = ptp->intf_list; interface; interface = interface->next)
for (interface = ptp->intf_list; interface; interface = interface->next) {
ptpd_process_intf_stats(interface->ptpd_intf_private, true);
bondSocksDumpState(interface->ptpd_intf_private, 0);
}

SFPTPD_MSG_FREE(msg);
}
Expand Down

0 comments on commit 7bd7998

Please sign in to comment.