[libvirt] [PATCH 6/6] qemu: change macvtap device MAC address in response to NIC_RX_FILTER_CHANGED
John Ferlan
jferlan at redhat.com
Thu Sep 25 02:19:44 UTC 2014
On 09/24/2014 05:50 AM, Laine Stump wrote:
> This patch fills in the functionality of
> processNicRxFilterChangedEvent(). It now checks if it is appropriate
> to respond to the NIC_RX_FILTER_CHANGED event (based on device type
> and configuration) and takes appropriate action. Currently it checks
> if the guest interface has been configured with
> trustGuestRxFilters='yes', and if the host side device is macvtap. If
> so, and the MAC address on the guest has changed, the MAC address of
> the macvtap device is changed to match.
>
> The result of this is that networking from the guest will continue to
> work if the mac address of a macvtap-connected network device is
> changed from within the guest, as long as trustGuestRxFilters='yes'
> (previously changing the MAC address in the guest would break
> networking).
> ---
> src/qemu/qemu_driver.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 64f1d45..7801d91 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4146,8 +4146,13 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
> char *devAlias)
> {
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> + qemuDomainObjPrivatePtr priv = vm->privateData;
> virDomainDeviceDef dev;
> virDomainNetDefPtr def;
> + virNetDevRxFilterPtr filter = NULL;
> + virMacAddr oldMAC;
> + char newMacStr[VIR_MAC_STRING_BUFLEN];
> + int ret;
>
> VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
> "from domain %p %s",
> @@ -4175,11 +4180,55 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
> }
> def = dev.data.net;
>
> + if (!virDomainNetGetActualTrustGuestRxFilters(def)) {
> + VIR_WARN("ignore NIC_RX_FILTER_CHANGED event for network "
> + "device %s in domain %s",
> + def->info.alias, vm->def->name);
So how often could this be emitted? Do we need some sort of "filter" to
only message once per life of the domain?
> + /* not sending "query-rx-filter" will also suppress any
> + * further NIC_RX_FILTER_CHANGED events for this device
> + */
> + goto endjob;
> + }
> +
> /* handle the event - send query-rx-filter and respond to it. */
>
> VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
> "device %s in domain %s", def->info.alias, vm->def->name);
>
There's no capabilities check necessary? What if the command doesn't
exist in the underlying qemu?
> + qemuDomainObjEnterMonitor(driver, vm);
> + ret = qemuMonitorQueryRxFilter(priv->mon, devAlias, &filter);
> + qemuDomainObjExitMonitor(driver, vm);
> + if (ret < 0)
> + goto endjob;
You filled in a lot of data from the qemuMonitorQueryRxFilter(), but
you're only using filter->mac (e.g. main-mac).
Or am I missing something?
John
> +
> + virMacAddrFormat(&filter->mac, newMacStr);
> +
> + if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +
> + /* For macvtap connections, set the macvtap device's MAC
> + * address to match that of the guest device.
> + */
> +
> + if (virNetDevGetMAC(def->ifname, &oldMAC) < 0) {
> + VIR_WARN("Couldn't get current MAC address of device %s "
> + "while responding to NIC_RX_FILTER_CHANGED",
> + def->ifname);
> + goto endjob;
> + }
> +
> + if (virMacAddrCmp(&oldMAC, &filter->mac)) {
> + /* set new MAC address from guest to associated macvtap device */
> + if (virNetDevSetMAC(def->ifname, &filter->mac) < 0) {
> + VIR_WARN("Couldn't set new MAC address %s to device %s "
> + "while responding to NIC_RX_FILTER_CHANGED",
> + newMacStr, def->ifname);
> + } else {
> + VIR_DEBUG("device %s MAC address set to %s",
> + def->ifname, newMacStr);
> + }
> + }
> + }
> +
> endjob:
> /* We had an extra reference to vm before starting a new job so ending the
> * job is guaranteed not to remove the last reference.
> @@ -4187,6 +4236,7 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
> ignore_value(qemuDomainObjEndJob(driver, vm));
>
> cleanup:
> + virNetDevRxFilterFree(filter);
> VIR_FREE(devAlias);
> virObjectUnref(cfg);
> }
>
More information about the libvir-list
mailing list