Example #1
0
/**
 * Add cache to cache manager
 * @arg mngr		Cache manager.
 * @arg name		Name of cache to keep track of
 * @arg cb		Function to be called upon changes.
 * @arg data		Argument passed on to change callback
 * @arg result		Pointer to store added cache (optional)
 *
 * Allocates a new cache of the specified type and adds it to the manager.
 * The operation will trigger a full dump request from the kernel to
 * initially fill the contents of the cache. The manager will subscribe
 * to the notification group of the cache and keep track of any further
 * changes.
 *
 * The user is responsible for calling nl_cache_mngr_poll() or monitor
 * the socket and call nl_cache_mngr_data_ready() to allow the library
 * to process netlink notification events.
 *
 * @see nl_cache_mngr_poll()
 * @see nl_cache_mngr_data_ready()
 *
 * @return 0 on success or a negative error code.
 * @return -NLE_NOCACHE Unknown cache type
 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
 * 			       cache type
 * @return -NLE_OPNOTSUPP Cache type does not support updates
 * @return -NLE_EXIST Cache of this type already being managed
 */
int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
		      change_func_t cb, void *data, struct nl_cache **result)
{
	struct nl_cache_ops *ops;
	struct nl_cache *cache;
	int err;

	ops = nl_cache_ops_lookup_safe(name);
	if (!ops)
		return -NLE_NOCACHE;

	cache = nl_cache_alloc(ops);
	nl_cache_ops_put(ops);
	if (!cache)
		return -NLE_NOMEM;

	err = nl_cache_mngr_add_cache(mngr, cache, cb, data);
	if (err < 0)
		goto errout_free_cache;

	*result = cache;
	return 0;

errout_free_cache:
	nl_cache_free(cache);

	return err;
}
Example #2
0
/**
 * Add cache to cache manager
 * @arg mngr		Cache manager.
 * @arg cache		Cache to be added to cache manager
 * @arg cb		V2 function to be called upon changes.
 * @arg data		Argument passed on to change callback
 *
 * Adds cache to the manager. The operation will trigger a full
 * dump request from the kernel to initially fill the contents
 * of the cache. The manager will subscribe to the notification group
 * of the cache and keep track of any further changes.
 *
 * The user is responsible for calling nl_cache_mngr_poll() or monitor
 * the socket and call nl_cache_mngr_data_ready() to allow the library
 * to process netlink notification events.
 *
 * @see nl_cache_mngr_poll()
 * @see nl_cache_mngr_data_ready()
 *
 * @return 0 on success or a negative error code.
 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
 * 			       cache type
 * @return -NLE_OPNOTSUPP Cache type does not support updates
 * @return -NLE_EXIST Cache of this type already being managed
 */
int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache,
		      change_func_v2_t cb, void *data) {
	int err;
	err = nl_cache_mngr_add_cache(mngr, cache, NULL, NULL);
	if (err < 0)
		return err;

	return nl_cache_mngr_set_change_func_v2(mngr, cache, cb, data);
}
void NetlinkManager::registerWNetlink() {
  initDumpParams();

  nlResources_ = std::make_unique<NlResources>();
  auto errCode = nl_cache_mngr_add_cache(
      nlResources_->manager,
      nlResources_->routeCache,
      netlinkRouteUpdated,
      this);
  checkError(errCode, "Failed to add route cache to cache manager");
  VLOG(1) << "Added route cache to cache manager";
  return;
}
Example #4
0
static J4statusPluginContext *
_j4status_nl_init(J4statusCoreInterface *core)
{
    gchar **interfaces = NULL;
    guint64 addresses = ADDRESSES_ALL;

    GKeyFile *key_file;
    key_file = j4status_config_get_key_file("Netlink");
    if ( key_file != NULL )
    {
        interfaces = g_key_file_get_string_list(key_file, "Netlink", "Interfaces", NULL, NULL);
        j4status_config_key_file_get_enum(key_file, "Netlink", "Addresses", _j4status_nl_addresses, G_N_ELEMENTS(_j4status_nl_addresses), &addresses);

        g_key_file_free(key_file);
    }

    if ( interfaces == NULL )
    {
        g_message("No interface to monitor, aborting");
        return NULL;
    }

    gint err;
    J4statusPluginContext *self;

    self = g_new0(J4statusPluginContext, 1);
    self->addresses = addresses;

    self->sections = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _j4status_nl_section_free);

    self->source = g_water_nl_source_new_cache_mngr(NULL, NETLINK_ROUTE, NL_AUTO_PROVIDE, &err);
    if ( self->source == NULL )
    {
        g_warning("Couldn't subscribe to events: %s", nl_geterror(err));
        goto error;
    }
    self->sock = g_water_nl_source_get_sock(self->source);
    self->cache_mngr = g_water_nl_source_get_cache_mngr(self->source);

    err = rtnl_link_alloc_cache(self->sock, AF_UNSPEC, &self->link_cache);
    if ( err < 0 )
    {
        g_warning("Couldn't allocate links cache: %s", nl_geterror(err));
        goto error;
    }

    err = nl_cache_mngr_add_cache(self->cache_mngr, self->link_cache, _j4status_nl_cache_change, self);
    if ( err < 0 )
    {
        g_warning("Couldn't manage links cache: %s", nl_geterror(err));
        goto error;
    }

    err = rtnl_addr_alloc_cache(self->sock, &self->addr_cache);
    if ( err < 0 )
    {
        g_warning("Couldn't allocate addresses cache: %s", nl_geterror(err));
        goto error;
    }

    err = nl_cache_mngr_add_cache(self->cache_mngr, self->addr_cache, _j4status_nl_cache_change, self);
    if ( err < 0 )
    {
        g_warning("Couldn't manage addresses cache: %s", nl_geterror(err));
        goto error;
    }

    gchar **interface;
    for ( interface = interfaces ; *interface != NULL ; ++interface )
    {
        J4statusNlSection *section;
        section = _j4status_nl_section_new(self, core, *interface);
        if ( section != NULL )
            g_hash_table_insert(self->sections, GINT_TO_POINTER(section->ifindex), section);
        else
            g_free(*interface);
    }

    g_free(interfaces);


    if ( g_hash_table_size(self->sections) < 1 )
        goto error;

    self->formats.up   = j4status_format_string_parse(NULL, _j4status_nl_format_up_tokens, G_N_ELEMENTS(_j4status_nl_format_up_tokens), J4STATUS_NL_DEFAULT_UP_FORMAT,   NULL);
    self->formats.down = j4status_format_string_parse(NULL, NULL,                          0,                                           J4STATUS_NL_DEFAULT_DOWN_FORMAT, NULL);


    return self;

error:
    _j4status_nl_uninit(self);
    return NULL;
}