From: "D. Herrendoerfer" <d.herrendoerfer(a)herrendoerfer.name>
this patch adds the changes proposed by Laine Stump to
netlink event code.
Signed-off-by: D. Herrendoerfer <d.herrendoerfer(a)herrendoerfer.name>
---
src/util/virnetdevmacvlan.c | 47 +++++++++++++++++++++++++++++++++---------
src/util/virnetlink.c | 13 ++++++++++-
src/util/virnetlink.h | 7 ++++-
3 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index 4256349..155ce79 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -448,7 +448,7 @@ static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = {
/* Struct to hold the state and configuration of a 802.1qbg port */
struct virNetlinkCallbackData {
- char cr_ifname[64];
+ char *cr_ifname;
virNetDevVPortProfilePtr virtPortProfile;
const unsigned char *macaddress;
const char *linkdev;
@@ -606,15 +606,13 @@ virNetDevMacVLanVPortProfileCallback(unsigned char *msg,
if (memcmp(calld->macaddress, m, VIR_MAC_BUFLEN))
{
/* Repeat the same check for a broadcast mac */
- unsigned char broadcastmac[VIR_MAC_BUFLEN];
int i;
- for (i = 0;i < VIR_MAC_BUFLEN; i++)
- broadcastmac[i] = 0xFF;
-
- if (memcmp(calld->macaddress, broadcastmac, VIR_MAC_BUFLEN)) {
- VIR_DEBUG("MAC address match failed.");
- return;
+ for (i = 0;i < VIR_MAC_BUFLEN; i++) {
+ if (calld->macaddress[i] != 0xff) {
+ VIR_DEBUG("MAC address match failed (wasn't
broadcast)");
+ return;
+ }
}
}
}
@@ -728,6 +726,30 @@ virNetDevMacVLanVPortProfileCallback(unsigned char *msg,
}
/**
+ * virNetDevMacVLanVPortProfileDestroyCallback:
+ *
+ * @watch: watch whose handle to remove
+ * @macaddr: macaddr whose handle to remove
+ * @opaque: Contains vital information regarding the associated vm
+ *
+ * This function is called when a netlink message handler is terminated.
+ * The function frees locally allocated data referenced in the opaque
+ * data.
+ */
+static void
+virNetDevMacVLanVPortProfileDestroyCallback(int watch ATTRIBUTE_UNUSED,
+ const unsigned char *macaddr
ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virNetlinkCallbackDataPtr calld = opaque;
+
+ if (calld) {
+ VIR_FREE(calld->cr_ifname);
+ }
+}
+
+
+/**
* virNetDevMacVLanCreateWithVPortProfile:
* Create an instance of a macvtap device and open its tap character
* device.
@@ -879,7 +901,12 @@ create_name:
goto disassociate_exit;
}
- strncpy(calld->cr_ifname, cr_ifname, 64);
+ calld->cr_ifname=strdup(cr_ifname);
+ if (calld->cr_ifname == NULL) {
+ virReportOOMError();
+ goto disassociate_exit;
+ }
+
calld->virtPortProfile = virtPortProfile;
calld->macaddress = macaddress;
calld->linkdev = linkdev;
@@ -938,7 +965,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
ret = -1;
}
- virNetlinkEventRemoveClient(0, macaddr);
+ virNetlinkEventRemoveClient(0, macaddr,
virNetDevMacVLanVPortProfileDestroyCallback);
return ret;
}
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 751aa67..de6a135 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -446,6 +446,7 @@ error:
*
* @watch: watch whose handle to remove
* @macaddr: macaddr whose handle to remove
+ * &cb: callback for the destruction of local data
*
* Unregister a callback from a netlink monitor.
* The handler function referenced will no longer receive netlink messages.
@@ -454,7 +455,8 @@ error:
* returns -1 if the file handle was not registered, 0 upon success
*/
int
-virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr) {
+virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr,
+ virNetlinkEventRemoveCallback cb) {
int i;
int ret = -1;
virNetlinkEventSrvPrivatePtr srv = server;
@@ -474,6 +476,9 @@ virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr)
{
continue;
if (watch && srv->handles[i].watch == watch) {
+ void *cpopaque = srv->handles[i].opaque;
+ (cb)( watch, macaddr, cpopaque);
+
VIR_FREE(srv->handles[i].opaque);
srv->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
VIR_DEBUG("removed client: %d by index.",
@@ -482,6 +487,9 @@ virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr)
{
goto error;
}
if (!watch && memcmp(macaddr, srv->handles[i].macaddr, VIR_MAC_BUFLEN)
== 0) {
+ void *cpopaque = srv->handles[i].opaque;
+ (cb)( watch, macaddr, cpopaque);
+
VIR_FREE(srv->handles[i].opaque);
srv->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
VIR_DEBUG("removed client: %d by mac.",
@@ -567,7 +575,8 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback cb, void
*opaque,
/**
* virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
*/
-int virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr) {
+int virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr,
+ virNetlinkEventRemoveCallback cb) {
netlinkError(VIR_ERR_INTERNAL_ERROR,
"%s",
# if defined(__linux__) && !defined(HAVE_LIBNL)
diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h
index 1365afa..b787a8f 100644
--- a/src/util/virnetlink.h
+++ b/src/util/virnetlink.h
@@ -38,7 +38,9 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
unsigned char **respbuf, unsigned int *respbuflen,
int nl_pid);
-typedef void (*virNetlinkEventHandleCallback)( unsigned char *msg, int length, struct
sockaddr_nl *peer, bool *handled, void *opaque);
+typedef void (*virNetlinkEventHandleCallback)(unsigned char *msg, int length, struct
sockaddr_nl *peer, bool *handled, void *opaque);
+
+typedef void (*virNetlinkEventRemoveCallback)(int watch, const unsigned char *macaddr,
void *opaque);
/**
* stopNetlinkEventServer: stop the monitor to receive netlink messages for libvirtd
@@ -63,6 +65,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback cb, void
*opaque, con
/**
* virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
*/
-int virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr);
+int virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr,
+ virNetlinkEventRemoveCallback cb);
#endif /* __VIR_NETLINK_H__ */
--
1.7.7.6