qga: Move HW address getting to a separate function
In the next patch FreeBSD support for guest-network-get-interfaces will be added. Previously move Linux-specific code of HW address getting to a separate functions and add a dumb function to commands-bsd.c. Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com> Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
This commit is contained in:
parent
4fd0642e84
commit
a124109422
@ -167,3 +167,19 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FSFREEZE */
|
#endif /* CONFIG_FSFREEZE */
|
||||||
|
|
||||||
|
#ifdef HAVE_GETIFADDRS
|
||||||
|
/*
|
||||||
|
* Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
|
||||||
|
* buffer with ETHER_ADDR_LEN length at least.
|
||||||
|
*
|
||||||
|
* Returns false in case of an error, otherwise true. "obtained" arguument
|
||||||
|
* is true if a MAC address was obtained successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
|
||||||
|
bool *obtained, Error **errp)
|
||||||
|
{
|
||||||
|
*obtained = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_GETIFADDRS */
|
||||||
|
@ -56,6 +56,12 @@ int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints,
|
|||||||
int qmp_guest_fsfreeze_do_thaw(Error **errp);
|
int qmp_guest_fsfreeze_do_thaw(Error **errp);
|
||||||
#endif /* CONFIG_FSFREEZE */
|
#endif /* CONFIG_FSFREEZE */
|
||||||
|
|
||||||
|
#ifdef HAVE_GETIFADDRS
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
|
||||||
|
bool *obtained, Error **errp);
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct GuestFileHandle GuestFileHandle;
|
typedef struct GuestFileHandle GuestFileHandle;
|
||||||
|
|
||||||
GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp);
|
GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp);
|
||||||
|
@ -41,20 +41,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
/*
|
|
||||||
* The code under HAVE_GETIFADDRS condition can't be compiled in FreeBSD.
|
|
||||||
* Fix it in one of the following patches.
|
|
||||||
*/
|
|
||||||
#undef HAVE_GETIFADDRS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETIFADDRS
|
#ifdef HAVE_GETIFADDRS
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <ifaddrs.h>
|
|
||||||
#ifdef CONFIG_SOLARIS
|
#ifdef CONFIG_SOLARIS
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#endif
|
#endif
|
||||||
@ -2889,6 +2881,57 @@ static int guest_get_network_stats(const char *name,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __FreeBSD__
|
||||||
|
/*
|
||||||
|
* Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
|
||||||
|
* buffer with ETHER_ADDR_LEN length at least.
|
||||||
|
*
|
||||||
|
* Returns false in case of an error, otherwise true. "obtained" argument
|
||||||
|
* is true if a MAC address was obtained successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
|
||||||
|
bool *obtained, Error **errp)
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
int sock;
|
||||||
|
|
||||||
|
*obtained = false;
|
||||||
|
|
||||||
|
/* we haven't obtained HW address yet */
|
||||||
|
sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1) {
|
||||||
|
error_setg_errno(errp, errno, "failed to create socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name);
|
||||||
|
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
|
||||||
|
/*
|
||||||
|
* We can't get the hw addr of this interface, but that's not a
|
||||||
|
* fatal error.
|
||||||
|
*/
|
||||||
|
if (errno == EADDRNOTAVAIL) {
|
||||||
|
/* The interface doesn't have a hw addr (e.g. loopback). */
|
||||||
|
g_debug("failed to get MAC address of %s: %s",
|
||||||
|
ifa->ifa_name, strerror(errno));
|
||||||
|
} else{
|
||||||
|
g_warning("failed to get MAC address of %s: %s",
|
||||||
|
ifa->ifa_name, strerror(errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef CONFIG_SOLARIS
|
||||||
|
memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
|
||||||
|
#else
|
||||||
|
memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
|
||||||
|
#endif
|
||||||
|
*obtained = true;
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build information about guest interfaces
|
* Build information about guest interfaces
|
||||||
*/
|
*/
|
||||||
@ -2909,9 +2952,8 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
|
|||||||
GuestNetworkInterfaceStat *interface_stat = NULL;
|
GuestNetworkInterfaceStat *interface_stat = NULL;
|
||||||
char addr4[INET_ADDRSTRLEN];
|
char addr4[INET_ADDRSTRLEN];
|
||||||
char addr6[INET6_ADDRSTRLEN];
|
char addr6[INET6_ADDRSTRLEN];
|
||||||
int sock;
|
unsigned char mac_addr[ETHER_ADDR_LEN];
|
||||||
struct ifreq ifr;
|
bool obtained;
|
||||||
unsigned char *mac_addr;
|
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
g_debug("Processing %s interface", ifa->ifa_name);
|
g_debug("Processing %s interface", ifa->ifa_name);
|
||||||
@ -2926,45 +2968,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!info->has_hardware_address) {
|
if (!info->has_hardware_address) {
|
||||||
/* we haven't obtained HW address yet */
|
if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) {
|
||||||
sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
||||||
if (sock == -1) {
|
|
||||||
error_setg_errno(errp, errno, "failed to create socket");
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (obtained) {
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name);
|
|
||||||
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
|
|
||||||
/*
|
|
||||||
* We can't get the hw addr of this interface, but that's not a
|
|
||||||
* fatal error. Don't set info->hardware_address, but keep
|
|
||||||
* going.
|
|
||||||
*/
|
|
||||||
if (errno == EADDRNOTAVAIL) {
|
|
||||||
/* The interface doesn't have a hw addr (e.g. loopback). */
|
|
||||||
g_debug("failed to get MAC address of %s: %s",
|
|
||||||
ifa->ifa_name, strerror(errno));
|
|
||||||
} else{
|
|
||||||
g_warning("failed to get MAC address of %s: %s",
|
|
||||||
ifa->ifa_name, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
#ifdef CONFIG_SOLARIS
|
|
||||||
mac_addr = (unsigned char *) &ifr.ifr_addr.sa_data;
|
|
||||||
#else
|
|
||||||
mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
|
|
||||||
#endif
|
|
||||||
info->hardware_address =
|
info->hardware_address =
|
||||||
g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
|
g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
(int) mac_addr[0], (int) mac_addr[1],
|
(int) mac_addr[0], (int) mac_addr[1],
|
||||||
(int) mac_addr[2], (int) mac_addr[3],
|
(int) mac_addr[2], (int) mac_addr[3],
|
||||||
(int) mac_addr[4], (int) mac_addr[5]);
|
(int) mac_addr[4], (int) mac_addr[5]);
|
||||||
|
|
||||||
info->has_hardware_address = true;
|
info->has_hardware_address = true;
|
||||||
}
|
}
|
||||||
close(sock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifa->ifa_addr &&
|
if (ifa->ifa_addr &&
|
||||||
|
Loading…
Reference in New Issue
Block a user