virnetdev: Use virNetDevSetupControl in virNetDevSendEthtoolIoctl

Use virNetDevSetupControl instead of open coding using socket(AF_LOCAL...)
and clearing virIfreq.

By using virNetDevSetupControl, the socket is then opened using
AF_PACKET which requires being privileged (effectively root) in
order to complete successfully.  Since that's now a requirement,
then the ioctl(SIOCETHTOOL) should not fail with EPERM, thus it
is removed from the filtered listed of failure codes.

Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
John Ferlan 2015-11-04 10:48:24 -05:00
parent d0a3a1ff92
commit edc88e2084

View File

@ -3151,24 +3151,19 @@ static int
virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
{
int ret = -1;
int sock = -1;
virIfreq ifr;
int fd = -1;
struct ifreq ifr;
sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (sock < 0) {
virReportSystemError(errno, "%s", _("Cannot open control socket"));
goto cleanup;
}
/* Ultimately uses AF_PACKET for socket which requires privileged
* daemon support.
*/
if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0)
return ret;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ifname);
ifr.ifr_data = cmd;
ret = ioctl(sock, SIOCETHTOOL, &ifr);
ret = ioctl(fd, SIOCETHTOOL, &ifr);
if (ret != 0) {
switch (errno) {
case EPERM: /* attempt to call SIOCETHTOOL from unprivileged code */
VIR_DEBUG("ethtool ioctl: permission denied");
break;
case EINVAL: /* kernel doesn't support SIOCETHTOOL */
VIR_DEBUG("ethtool ioctl: invalid request");
break;
@ -3182,8 +3177,7 @@ virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
}
cleanup:
if (sock)
VIR_FORCE_CLOSE(sock);
VIR_FORCE_CLOSE(fd);
return ret;
}