summaryrefslogtreecommitdiff
path: root/lib/socket
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-05-07 11:06:03 +0200
committerStefan Metzmacher <metze@samba.org>2020-05-07 14:44:40 +0000
commitd39636acea4fda840b23646b021e24559681b0b0 (patch)
tree64d83dd5342391a3dcf8c7a05d1e6b150e795ab8 /lib/socket
parent4ccb58160936d13a06c74ed1c28c855564b50f22 (diff)
downloadsamba-d39636acea4fda840b23646b021e24559681b0b0.tar.gz
lib/socket: autodetect RSS using ETHTOOL_GRXRINGS
This is also used as part of 'ethtool -n rdma14' and 'ethtool -x rdma14'. ;#> ethtool -n rdma14 8 RX rings available rxclass: Cannot get RX class rule count: Operation not supported RX classification rule retrieval failed ;#> ethtool -x rdma14 RX flow hash indirection table for rdma14 with 8 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 0 1 2 3 4 5 6 7 RSS hash key: Operation not supported RSS hash function: toeplitz: on xor: off crc32: off Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'lib/socket')
-rw-r--r--lib/socket/interfaces.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/socket/interfaces.c b/lib/socket/interfaces.c
index 497bd945984..3157e0cef12 100644
--- a/lib/socket/interfaces.c
+++ b/lib/socket/interfaces.c
@@ -173,6 +173,42 @@ static void query_iface_speed_from_name(const char *name, uint64_t *speed)
done:
(void)close(fd);
}
+
+static void query_iface_rx_queues_from_name(const char *name,
+ uint64_t *rx_queues)
+{
+ int ret = 0;
+ struct ethtool_rxnfc rxcmd;
+ struct ifreq ifr;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (fd == -1) {
+ DBG_ERR("Failed to open socket.");
+ return;
+ }
+
+ if (strlen(name) >= IF_NAMESIZE) {
+ DBG_ERR("Interface name too long.");
+ goto done;
+ }
+
+ ZERO_STRUCT(ifr);
+ strlcpy(ifr.ifr_name, name, IF_NAMESIZE);
+
+ ifr.ifr_data = (void *)&rxcmd;
+ ZERO_STRUCT(rxcmd);
+ rxcmd.cmd = ETHTOOL_GRXRINGS;
+ ret = ioctl(fd, SIOCETHTOOL, &ifr);
+ if (ret == -1) {
+ goto done;
+ }
+
+ *rx_queues = rxcmd.data;
+
+done:
+ (void)close(fd);
+}
#endif
/****************************************************************************
@@ -217,6 +253,7 @@ static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
/* Loop through interfaces, looking for given IP address */
for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
uint64_t if_speed = 1000 * 1000 * 1000; /* 1Gbps */
+ uint64_t rx_queues = 1;
if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
continue;
@@ -278,9 +315,13 @@ static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
#ifdef HAVE_ETHTOOL
query_iface_speed_from_name(ifptr->ifa_name, &if_speed);
+ query_iface_rx_queues_from_name(ifptr->ifa_name, &rx_queues);
#endif
ifaces[total].linkspeed = if_speed;
ifaces[total].capability = FSCTL_NET_IFACE_NONE_CAPABLE;
+ if (rx_queues > 1) {
+ ifaces[total].capability |= FSCTL_NET_IFACE_RSS_CAPABLE;
+ }
if (strlcpy(ifaces[total].name, ifptr->ifa_name,
sizeof(ifaces[total].name)) >=