Skip to content

Commit

Permalink
Allow to allocate cache manager with custom refill socket
Browse files Browse the repository at this point in the history
Cache managers use two sockets: one for cache refill operation,
and another one for notifications.

In order to simulate NETLINK events by reading data from files,
we need to be able to overwrite callbacks for both sockets.

This new function allows us to set up refill socket any way we want.
It does have requirement that the refill socket be blocking.
  • Loading branch information
ievenbach committed Apr 29, 2024
1 parent 96ddcd9 commit d80a836
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
9 changes: 7 additions & 2 deletions include/netlink/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,17 @@ extern struct nl_cache * __nl_cache_mngt_require(const char *);

struct nl_cache_mngr;

#define NL_AUTO_PROVIDE 1
#define NL_ALLOCATED_SOCK 2 /* For internal use only, do not use */
#define NL_AUTO_PROVIDE 1
#define NL_ALLOCATED_SOCK 2 /* For internal use only, do not use */
#define NL_ALLOCATED_SYNC_SOCK 4 /* For internal use only, do not use */

extern int nl_cache_mngr_alloc(struct nl_sock *,
int, int,
struct nl_cache_mngr **);
extern int nl_cache_mngr_alloc_ex(struct nl_sock *,
struct nl_sock *,
int, int,
struct nl_cache_mngr **);
extern int nl_cache_mngr_add(struct nl_cache_mngr *,
const char *,
change_func_t,
Expand Down
51 changes: 38 additions & 13 deletions lib/cache_mngr.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,46 @@ static int event_input(struct nl_msg *msg, void *arg)
*/
int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
struct nl_cache_mngr **result)
{
return nl_cache_mngr_alloc_ex(sk, NULL, protocol, flags, result);
}

/**
* Allocate new cache manager, with custom callback on refill socket
* @arg sk Netlink socket or NULL to auto allocate
* @arg sync_sk Blocking Netlink socket for cache refills
* @arg protocol Netlink protocol this manager is used for
* @arg flags Flags (\c NL_AUTO_PROVIDE)
* @arg result Result pointer
*
* Same as \f nl_cache_mngr_alloc, but sets custom refill socket
* Note: ownership of the sync_sk passes to the cache manager
*/
int nl_cache_mngr_alloc_ex(struct nl_sock *sk, struct nl_sock *sync_sk, int protocol, int flags,
struct nl_cache_mngr **result)
{
struct nl_cache_mngr *mngr;
int err = -NLE_NOMEM;

/* Catch abuse of flags */
if (flags & NL_ALLOCATED_SOCK)
if (flags & (NL_ALLOCATED_SOCK|NL_ALLOCATED_SYNC_SOCK))
BUG();

mngr = calloc(1, sizeof(*mngr));
if (!mngr)
if (!mngr) {
return -NLE_NOMEM;
}

if(!sync_sk) {
if (!(sync_sk = nl_socket_alloc()))
goto errout;

flags |= NL_ALLOCATED_SOCK;
}
/* have to assign before calling nl_connect, so that it gets freed in case
* of an nl_socket_allock error for sk
*/
mngr->cm_sync_sock = sync_sk;

if (!sk) {
if (!(sk = nl_socket_alloc()))
Expand All @@ -176,6 +205,10 @@ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
if (!mngr->cm_assocs)
goto errout;

if ((err = nl_connect(sync_sk, protocol)) < 0) {
goto errout;
}

/* Required to receive async event notifications */
nl_socket_disable_seq_check(mngr->cm_sock);

Expand All @@ -185,23 +218,13 @@ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0)
goto errout;

/* Create and allocate socket for sync cache fills */
mngr->cm_sync_sock = nl_socket_alloc();
if (!mngr->cm_sync_sock) {
err = -NLE_NOMEM;
goto errout;
}
if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0)
goto errout_free_sync_sock;

NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
mngr, protocol, mngr->cm_nassocs);

*result = mngr;
return 0;

errout_free_sync_sock:
nl_socket_free(mngr->cm_sync_sock);
errout:
nl_cache_mngr_free(mngr);
return err;
Expand Down Expand Up @@ -624,9 +647,11 @@ void nl_cache_mngr_free(struct nl_cache_mngr *mngr)

if (mngr->cm_sync_sock) {
nl_close(mngr->cm_sync_sock);
nl_socket_free(mngr->cm_sync_sock);
}

if (mngr->cm_flags & NL_ALLOCATED_SYNC_SOCK)
nl_socket_free(mngr->cm_sync_sock);

if (mngr->cm_flags & NL_ALLOCATED_SOCK)
nl_socket_free(mngr->cm_sock);

Expand Down
1 change: 1 addition & 0 deletions libnl-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ global:
nl_cache_mngr_add;
nl_cache_mngr_add_cache;
nl_cache_mngr_alloc;
nl_cache_mngr_alloc_ex;
nl_cache_mngr_data_ready;
nl_cache_mngr_free;
nl_cache_mngr_get_fd;
Expand Down

0 comments on commit d80a836

Please sign in to comment.