virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
{
int ret = -1;
- int fd;
- struct ifreq ifr;
+ int sock = -1;
+ virIfreq ifr;
- if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0)
- return ret;
+ sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ virReportSystemError(errno, "%s", _("Cannot open control socket"));
+ goto cleanup;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, ifname);
ifr.ifr_data = cmd;
- ret = ioctl(fd, SIOCETHTOOL, &ifr);
+ ret = ioctl(sock, SIOCETHTOOL, &ifr);
+ if (ret != 0) {
+ switch (errno) {
+ case EPERM:
+ VIR_DEBUG("ethtool ioctl: permission denied");
+ break;
+ case EINVAL:
+ VIR_DEBUG("ethtool ioctl: invalid request");
+ break;
+ case EOPNOTSUPP:
+ VIR_DEBUG("ethtool ioctl: request not supported");
+ break;
+ default:
+ virReportSystemError(errno, "%s", _("ethtool ioctl error"));
+ goto cleanup;
+ }
+ }
- VIR_FORCE_CLOSE(fd);
+ cleanup:
+ if (sock)
+ VIR_FORCE_CLOSE(sock);
return ret;
}
static int
virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
{
+ int ret = -1;
+
cmd = (void*)cmd;
- if (virNetDevSendEthtoolIoctl(ifname, cmd) < 0) {
- virReportSystemError(errno, _("Cannot get device %s flags"), ifname);
- return -1;
- }
- return cmd->data > 0 ? 1 : 0;
+ if (!virNetDevSendEthtoolIoctl(ifname, cmd))
+ ret = cmd->data > 0 ? 1 : 0;
+ return ret;
}
static int
virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd)
{
+ int ret = -1;
+
cmd = (void*)cmd;
- if (virNetDevSendEthtoolIoctl(ifname, cmd) < 0) {
- virReportSystemError(errno, _("Cannot get device %s generic features"), ifname);
- return -1;
- }
- return FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active);
+ if (!virNetDevSendEthtoolIoctl(ifname, cmd))
+ ret = FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active);
+ return ret;
}
# endif