Skip to content

Commit

Permalink
SWPTP-1510: track reasons for the lacp bypass sockets failing
Browse files Browse the repository at this point in the history
  • Loading branch information
jfeather-amd committed Sep 23, 2024
1 parent 2b80dd3 commit 123ce97
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 5 deletions.
31 changes: 31 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 @@ -632,6 +660,9 @@ struct ptpd_transport {
* 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
47 changes: 42 additions & 5 deletions src/ptp/ptpd2/sfptpd_lacp.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,44 @@ 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;
}
Expand All @@ -92,9 +109,16 @@ void createBondSocks(struct ptpd_transport *transport, int transportAF)

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 +220,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 Down

0 comments on commit 123ce97

Please sign in to comment.