diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c index aed3230fb7..e0bf397652 100644 --- a/src/nm-netlink-monitor.c +++ b/src/nm-netlink-monitor.c @@ -517,3 +517,78 @@ nm_netlink_monitor_disconnect_handler (GIOChannel *channel, return FALSE; } +typedef struct { + NMNetlinkMonitor *self; + struct rtnl_link *filter; + GError *error; + guint32 flags; +} GetFlagsInfo; + +static void +get_flags_sync_cb (struct nl_object *obj, void *arg) +{ + GetFlagsInfo *info = arg; + + /* Ensure this cache item matches our filter */ + if (nl_object_match_filter (obj, OBJ_CAST (info->filter)) != 0) + info->flags = rtnl_link_get_flags ((struct rtnl_link *) obj); +} + +gboolean +nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, + guint32 ifindex, + guint32 *ifflags, + GError **error) +{ + NMNetlinkMonitorPrivate *priv; + GetFlagsInfo info; + struct rtnl_link *filter; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); + g_return_val_if_fail (ifflags != NULL, FALSE); + + priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); + + /* Update the link cache with the latest information */ + if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) { + g_set_error (error, + NM_NETLINK_MONITOR_ERROR, + NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, + _("error updating link cache: %s"), + nl_geterror ()); + return FALSE; + } + + /* Set up the filter */ + filter = rtnl_link_alloc (); + if (!filter) { + g_set_error (error, + NM_NETLINK_MONITOR_ERROR, + NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, + _("error processing netlink message: %s"), + nl_geterror ()); + return FALSE; + } + rtnl_link_set_ifindex (filter, ifindex); + + memset (&info, 0, sizeof (info)); + info.self = self; + info.filter = filter; + info.error = NULL; + nl_cache_foreach_filter (priv->nlh_link_cache, NULL, get_flags_sync_cb, &info); + + rtnl_link_put (filter); + + if (info.error) { + if (error) + *error = info.error; + else + g_error_free (info.error); + return FALSE; + } else + *ifflags = info.flags; + + return TRUE; /* success */ +} + diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h index 0cb4bea83e..115eccaaa3 100644 --- a/src/nm-netlink-monitor.h +++ b/src/nm-netlink-monitor.h @@ -74,6 +74,11 @@ void nm_netlink_monitor_attach (NMNetlinkMonitor *monitor void nm_netlink_monitor_detach (NMNetlinkMonitor *monitor); gboolean nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor, GError **error); +gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor, + guint32 ifindex, + guint32 *ifflags, + GError **error); + G_END_DECLS #endif /* NM_NETLINK_MONITOR_H */