netlink: fix checking multicast groups

Got the flags wrong in the previous commit; MULTI isn't about
multicast/unicast, but about multi-part packets.  Instead we need
to check the netlink sockaddr structure for the group mask.
This commit is contained in:
Dan Williams
2010-04-21 01:05:08 -07:00
parent df3f09b633
commit 7cec17fcce

View File

@@ -132,6 +132,7 @@ netlink_event_input (struct nl_msg *msg, void *arg)
NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);
struct nlmsghdr *hdr = nlmsg_hdr (msg); struct nlmsghdr *hdr = nlmsg_hdr (msg);
struct ucred *creds = nlmsg_get_creds (msg); struct ucred *creds = nlmsg_get_creds (msg);
const struct sockaddr_nl *snl;
guint32 local_port; guint32 local_port;
gboolean accept_msg = FALSE; gboolean accept_msg = FALSE;
@@ -142,15 +143,18 @@ netlink_event_input (struct nl_msg *msg, void *arg)
return NL_STOP; return NL_STOP;
} }
snl = nlmsg_get_src (msg);
g_assert (snl);
/* Accept any messages from the kernel */ /* Accept any messages from the kernel */
if (hdr->nlmsg_pid == 0) if (hdr->nlmsg_pid == 0 || snl->nl_pid == 0)
accept_msg = TRUE; accept_msg = TRUE;
/* And any multicast message directed to our netlink PID, since multicast /* And any multicast message directed to our netlink PID, since multicast
* currently requires CAP_ADMIN to use. * currently requires CAP_ADMIN to use.
*/ */
local_port = nl_socket_get_local_port (priv->nlh); local_port = nl_socket_get_local_port (priv->nlh);
if ((hdr->nlmsg_pid == local_port) && (hdr->nlmsg_flags & NLM_F_MULTI)) if ((hdr->nlmsg_pid == local_port) && snl->nl_groups)
accept_msg = TRUE; accept_msg = TRUE;
if (accept_msg == FALSE) { if (accept_msg == FALSE) {
@@ -268,6 +272,14 @@ nm_netlink_monitor_open_connection (NMNetlinkMonitor *self, GError **error)
goto error; goto error;
} }
if (nl_socket_recv_pktinfo (priv->nlh, 1) < 0) {
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT,
_("unable to enable netlink handle packet info: %s"),
nl_geterror ());
goto error;
}
#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
/* Work around apparent libnl bug; rtnl_addr requires that all /* Work around apparent libnl bug; rtnl_addr requires that all
* addresses have the "peer" attribute set in order to be compared * addresses have the "peer" attribute set in order to be compared
@@ -292,8 +304,6 @@ nm_netlink_monitor_open_connection (NMNetlinkMonitor *self, GError **error)
goto error; goto error;
} }
nl_cache_mngt_provide (priv->link_cache);
fd = nl_socket_get_fd (priv->nlh); fd = nl_socket_get_fd (priv->nlh);
priv->io_channel = g_io_channel_unix_new (fd); priv->io_channel = g_io_channel_unix_new (fd);