aboutsummaryrefslogtreecommitdiffstats
path: root/extras/libmemif
diff options
context:
space:
mode:
authorJakub Grajciar <jgrajcia@cisco.com>2019-07-01 14:24:48 +0200
committerDamjan Marion <dmarion@me.com>2019-07-02 14:06:46 +0000
commit12df497bb6b7f60513f48c0dacca9ad99d717192 (patch)
tree71b219bc3a369a54fe119a65b1597c2d03337b86 /extras/libmemif
parent312758f9af526d3d498219cf84e58887d6740687 (diff)
libmemif: version 3.0
Add support for multi-thread connection establishment. - control_fd_update() callback now passes private context associated with updated file descriptor. File descriptor can belong to memif socket, memif connection or timerfd. In case of timerfd the context is NULL. - memif_create_socket() new API. Creates memif socket handle to be passed to memif_create() in memif_conn_args_t. This API allows to pass private context whenever the file descriptor is updated. - memif_delete_socket() new API. Deletes memif socket. Socket must not be in use by any interface. Type: feature Change-Id: I7ca4e4349595d4477195f1c32403d3e3a6eb5361 Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
Diffstat (limited to 'extras/libmemif')
-rw-r--r--extras/libmemif/docs/buildinstructions_doc.md58
-rw-r--r--extras/libmemif/examples/icmp_responder-eb/main.c6
-rw-r--r--extras/libmemif/examples/icmp_responder-epoll/main.c10
-rw-r--r--extras/libmemif/examples/icmp_responder-mt/main.c2
-rw-r--r--extras/libmemif/examples/icmp_responder-zero-copy-slave/main.c12
-rw-r--r--extras/libmemif/src/libmemif.h48
-rw-r--r--extras/libmemif/src/main.c579
-rw-r--r--extras/libmemif/src/memif_private.h19
-rw-r--r--extras/libmemif/src/socket.c19
-rw-r--r--extras/libmemif/test/main_test.c5
-rw-r--r--extras/libmemif/test/unit_test.c2
-rw-r--r--extras/libmemif/test/unit_test.h2
12 files changed, 423 insertions, 339 deletions
diff --git a/extras/libmemif/docs/buildinstructions_doc.md b/extras/libmemif/docs/buildinstructions_doc.md
index a226856b2b6..c2eecba4d96 100644
--- a/extras/libmemif/docs/buildinstructions_doc.md
+++ b/extras/libmemif/docs/buildinstructions_doc.md
@@ -1,53 +1,47 @@
## Build Instructions {#libmemif_build_doc}
-Install dependencies
+#### Install dependencies
```
-# sudo apt-get install -y git autoconf pkg_config libtool check
+# sudo apt-get install -y git cmake autoconf pkg_config libtool check
```
Libmemif is now part of VPP repository. Follow fd.io wiki to pull source code from VPP repository.
[https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches](https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches)
-Libmemif is located under extras/libmemif.
-For debug build:
+Libmemif is located under extras/libmemif. From extras/libmemif:
```
-# ./bootstrap
-# ./configure
-# make
+# mkdir build
+# cd build
+# cmake ..
# make install
```
-For release build:
+#### Verify installation:
```
-# ./bootstrap
-# ./configure
-# make release
-# make install
-```
-Verify installation:
+build# ./examples/icmpr-epoll
```
-# ./.libs/icmpr-epoll
-```
-> Make sure to run the binary file from ./.libs. File ./icmp\_responder in libmemif root directory is script that links the library, so it only verifies successful build. Default install path is /usr/lib.
Use _help_ command to display build information and commands:
```
-ICMP_Responder:add_epoll_fd:233: fd 0 added to epoll
-ICMP_Responder:add_epoll_fd:233: fd 5 added to epoll
-LIBMEMIF EXAMPLE APP: ICMP_Responder (debug)
+LIBMEMIF EXAMPLE APP: ICMP_Responder
==============================
-libmemif version: 2.0 (debug)
+libmemif version: 3.0
memif version: 512
-commands:
- help - prints this help
- exit - exit app
- conn <index> <mode> [<interrupt-desc>] - create memif. index is also used as interface id, mode 0 = slave 1 = master, interrupt-desc none = default 0 = if ring is full wait 1 = handle only ARP requests
- del <index> - delete memif
- show - show connection details
- ip-set <index> <ip-addr> - set interface ip address
- rx-mode <index> <qid> <polling|interrupt> - set queue rx mode
- sh-count - print counters
- cl-count - clear counters
- send <index> <tx> <ip> <mac> - send icmp
+ use CTRL+C to exit
+MEMIF DETAILS
+==============================
+ interface name: memif_connection
+ app name: ICMP_Responder
+ remote interface name:
+ remote app name:
+ id: 0
+ secret: (null)
+ role: slave
+ mode: ethernet
+ socket filename: /run/vpp/memif.sock
+ socket filename: /run/vpp/memif.sock
+ rx queues:
+ tx queues:
+ link: down
```
#### Examples
diff --git a/extras/libmemif/examples/icmp_responder-eb/main.c b/extras/libmemif/examples/icmp_responder-eb/main.c
index 646a6ca0511..0e8b8f304c0 100644
--- a/extras/libmemif/examples/icmp_responder-eb/main.c
+++ b/extras/libmemif/examples/icmp_responder-eb/main.c
@@ -375,7 +375,7 @@ on_disconnect (memif_conn_handle_t conn, void *private_ctx)
}
int
-control_fd_update (int fd, uint8_t events)
+control_fd_update (int fd, uint8_t events, void *ctx)
{
/* convert memif event definitions to epoll events */
if (events & MEMIF_FD_EVENT_DEL)
@@ -562,7 +562,7 @@ error:
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
- DBG ("freed %d buffers. %u/%u alloc/free buffers", fb, c->rx_buf_num,
+ DBG ("freed %d buffers. %u/%u alloc/free buffers", rx, c->rx_buf_num,
MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
@@ -637,7 +637,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
diff --git a/extras/libmemif/examples/icmp_responder-epoll/main.c b/extras/libmemif/examples/icmp_responder-epoll/main.c
index ecc05a41e77..0e9d96eec98 100644
--- a/extras/libmemif/examples/icmp_responder-epoll/main.c
+++ b/extras/libmemif/examples/icmp_responder-epoll/main.c
@@ -304,7 +304,7 @@ on_disconnect (memif_conn_handle_t conn, void *private_ctx)
/* user needs to watch new fd or stop watching fd that is about to be closed.
control fd will be modified during connection establishment to minimize CPU usage */
int
-control_fd_update (int fd, uint8_t events)
+control_fd_update (int fd, uint8_t events, void *ctx)
{
/* convert memif event definitions to epoll events */
if (events & MEMIF_FD_EVENT_DEL)
@@ -436,7 +436,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
@@ -521,7 +521,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
rx -= j;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, rx, MAX_MEMIF_BUFS - rx);
+ rx, rx, MAX_MEMIF_BUFS - rx);
/* transmit allocated buffers */
err = memif_tx_burst (c->conn, qid, c->tx_bufs, j, &tx);
@@ -545,7 +545,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
@@ -612,7 +612,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
diff --git a/extras/libmemif/examples/icmp_responder-mt/main.c b/extras/libmemif/examples/icmp_responder-mt/main.c
index bc2f71dd328..5c03823c68b 100644
--- a/extras/libmemif/examples/icmp_responder-mt/main.c
+++ b/extras/libmemif/examples/icmp_responder-mt/main.c
@@ -565,7 +565,7 @@ on_disconnect (memif_conn_handle_t conn, void *private_ctx)
/* user needs to watch new fd or stop watching fd that is about to be closed.
control fd will be modified during connection establishment to minimize CPU usage */
int
-control_fd_update (int fd, uint8_t events)
+control_fd_update (int fd, uint8_t events, void *ctx)
{
/* convert memif event definitions to epoll events */
if (events & MEMIF_FD_EVENT_DEL)
diff --git a/extras/libmemif/examples/icmp_responder-zero-copy-slave/main.c b/extras/libmemif/examples/icmp_responder-zero-copy-slave/main.c
index 7913588299a..b342c512fbe 100644
--- a/extras/libmemif/examples/icmp_responder-zero-copy-slave/main.c
+++ b/extras/libmemif/examples/icmp_responder-zero-copy-slave/main.c
@@ -296,7 +296,7 @@ on_disconnect (memif_conn_handle_t conn, void *private_ctx)
/* user needs to watch new fd or stop watching fd that is about to be closed.
control fd will be modified during connection establishment to minimize CPU usage */
int
-control_fd_update (int fd, uint8_t events)
+control_fd_update (int fd, uint8_t events, void *ctx)
{
/* convert memif event definitions to epoll events */
if (events & MEMIF_FD_EVENT_DEL)
@@ -371,7 +371,7 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, rx, MAX_MEMIF_BUFS - rx);
+ rx, rx, MAX_MEMIF_BUFS - rx);
/* transmit allocated buffers */
err = memif_tx_burst (c->conn, qid, c->bufs, rx, &tx);
@@ -393,7 +393,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num = 0;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
@@ -450,7 +450,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
c->rx_buf_num -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, rx, MAX_MEMIF_BUFS - rx);
+ rx, rx, MAX_MEMIF_BUFS - rx);
/* transmit allocated buffers */
err = memif_tx_burst (c->conn, qid, c->bufs, i, &tx);
@@ -472,7 +472,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num = 0;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
@@ -538,7 +538,7 @@ error:
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num = 0;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
- fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+ rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
return 0;
}
diff --git a/extras/libmemif/src/libmemif.h b/extras/libmemif/src/libmemif.h
index 9fc2a70f94b..cdbf04aea0d 100644
--- a/extras/libmemif/src/libmemif.h
+++ b/extras/libmemif/src/libmemif.h
@@ -23,7 +23,7 @@
#define _LIBMEMIF_H_
/** Libmemif version. */
-#define LIBMEMIF_VERSION "2.1"
+#define LIBMEMIF_VERSION "3.0"
/** Default name of application using libmemif. */
#define MEMIF_DEFAULT_APP_NAME "libmemif-app"
@@ -101,6 +101,11 @@ typedef enum
*/
typedef void *memif_conn_handle_t;
+/** \brief Memif socket handle
+ pointer of type void, pointing to internal structure
+*/
+typedef void *memif_socket_handle_t;
+
/** \brief Memif allocator alloc
@param size - requested allocation size
@@ -138,7 +143,8 @@ typedef void (memif_free_t) (void *ptr);
This callback is called when there is new fd to watch for events on
or if fd is about to be closed (user mey want to stop watching for events on this fd).
*/
-typedef int (memif_control_fd_update_t) (int fd, uint8_t events);
+typedef int (memif_control_fd_update_t) (int fd, uint8_t events,
+ void *private_ctx);
/** \brief Memif connection status update (callback function)
@param conn - memif connection handle
@@ -240,7 +246,7 @@ typedef enum
#endif /* _MEMIF_H_ */
/** \brief Memif connection arguments
- @param socket_filename - socket filename
+ @param socket - memif socket handle, if NULL default socket will be used
@param secret - otional parameter used as interface autenthication
@param num_s2m_rings - number of slave to master rings
@param num_m2s_rings - number of master to slave rings
@@ -253,7 +259,7 @@ typedef enum
*/
typedef struct
{
- uint8_t *socket_filename; /*!< default = /run/vpp/memif.sock */
+ memif_socket_handle_t socket; /*!< default = /run/vpp/memif.sock */
uint8_t secret[24]; /*!< optional (interface authentication) */
uint8_t num_s2m_rings; /*!< default = 1 */
@@ -468,7 +474,7 @@ int memif_init (memif_control_fd_update_t * on_control_fd_update,
int memif_cleanup ();
/** \brief Memory interface create function
- @param conn - connection handle for user app
+ @param conn - connection handle for client app
@param args - memory interface connection arguments
@param on_connect - inform user about connected status
@param on_disconnect - inform user about disconnected status
@@ -625,7 +631,7 @@ int memif_cancel_poll_event ();
\return memif_err_t
*/
-int memif_set_connection_request_timer(struct itimerspec timer);
+int memif_set_connection_request_timer (struct itimerspec timer);
/** \brief Send connection request
@param conn - memif connection handle
@@ -634,7 +640,35 @@ int memif_set_connection_request_timer(struct itimerspec timer);
\return memif_err_t
*/
-int memif_request_connection(memif_conn_handle_t conn);
+int memif_request_connection (memif_conn_handle_t conn);
+
+/** \brief Create memif socket
+ @param sock - socket handle for client app
+ @param filename - path to socket file
+ @param private_ctx - private context
+
+ The first time an interface is assigned a socket, its type is determined.
+ For master role it's 'listener', for slave role it's 'client'. Each interface
+ requires socket of its respective type. Default socket is creted if no
+ socket handle is passed to memif_create(). It's private context is NULL.
+ If all interfaces using this socket are deleted, the socket returns
+ to its default state.
+
+ \return memif_err_t
+*/
+int memif_create_socket (memif_socket_handle_t * sock, const char * filename,
+ void * private_ctx);
+
+/** \brief Delete memif socket
+ @param sock - socket handle for client app
+
+ When trying to free socket in use, socket will not be freed and
+ MEMIF_ERR_INVAL_ARG is returned.
+
+ \return memif_err_t
+*/
+int memif_delete_socket (memif_socket_handle_t * sock);
+
/** @} */
#endif /* _LIBMEMIF_H_ */
diff --git a/extras/libmemif/src/main.c b/extras/libmemif/src/main.c
index 46a57da3a71..f3d8f9a55ef 100644
--- a/extras/libmemif/src/main.c
+++ b/extras/libmemif/src/main.c
@@ -298,7 +298,7 @@ memif_del_epoll_fd (int fd)
}
int
-memif_control_fd_update (int fd, uint8_t events)
+memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
{
if (events & MEMIF_FD_EVENT_DEL)
return memif_del_epoll_fd (fd);
@@ -319,8 +319,9 @@ int
add_list_elt (memif_list_elt_t * e, memif_list_elt_t ** list, uint16_t * len)
{
libmemif_main_t *lm = &libmemif_main;
-
+ memif_list_elt_t *tmp;
int i;
+
for (i = 0; i < *len; i++)
{
if ((*list)[i].data_struct == NULL)
@@ -330,7 +331,7 @@ add_list_elt (memif_list_elt_t * e, memif_list_elt_t ** list, uint16_t * len)
return i;
}
}
- memif_list_elt_t *tmp;
+
tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
if (tmp == NULL)
return -1;
@@ -354,12 +355,13 @@ int
get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
int key)
{
+ int i;
if (key == -1)
{
*e = NULL;
return -1;
}
- int i;
+
for (i = 0; i < len; i++)
{
if (list[i].key == key)
@@ -452,7 +454,7 @@ memif_free_register (memif_free_t * mf)
}
int
-memif_set_connection_request_timer(struct itimerspec timer)
+memif_set_connection_request_timer (struct itimerspec timer)
{
libmemif_main_t *lm = &libmemif_main;
int err = MEMIF_ERR_SUCCESS;
@@ -523,13 +525,13 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
DBG ("eventfd: %s", strerror (err));
return memif_syscall_error_handler (err);
}
- lm->control_fd_update (poll_cancel_fd, MEMIF_FD_EVENT_READ);
+ lm->control_fd_update (poll_cancel_fd, MEMIF_FD_EVENT_READ, NULL);
DBG ("libmemif event polling initialized");
}
lm->control_list_len = 2;
lm->interrupt_list_len = 2;
- lm->listener_list_len = 1;
+ lm->socket_list_len = 1;
lm->pending_list_len = 1;
lm->control_list =
@@ -546,9 +548,9 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
err = MEMIF_ERR_NOMEM;
goto error;
}
- lm->listener_list =
- lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
- if (lm->listener_list == NULL)
+ lm->socket_list =
+ lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
+ if (lm->socket_list == NULL)
{
err = MEMIF_ERR_NOMEM;
goto error;
@@ -572,10 +574,10 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
lm->interrupt_list[i].key = -1;
lm->interrupt_list[i].data_struct = NULL;
}
- for (i = 0; i < lm->listener_list_len; i++)
+ for (i = 0; i < lm->socket_list_len; i++)
{
- lm->listener_list[i].key = -1;
- lm->listener_list[i].data_struct = NULL;
+ lm->socket_list[i].key = -1;
+ lm->socket_list[i].data_struct = NULL;
}
for (i = 0; i < lm->pending_list_len; i++)
{
@@ -597,7 +599,7 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
- if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
+ if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, NULL) < 0)
{
DBG ("callback type memif_control_fd_update_t error!");
err = MEMIF_ERR_CB_FDUPDATE;
@@ -644,6 +646,158 @@ memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
return MEMIF_ERR_SUCCESS;
}
+static int
+memif_socket_start_listening (memif_socket_t * ms)
+{
+ libmemif_main_t *lm = &libmemif_main;
+ memif_list_elt_t elt;
+ struct stat file_stat;
+ struct sockaddr_un un = { 0 };
+ int on = 1;
+ int err = MEMIF_ERR_SUCCESS;
+
+ if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
+ return MEMIF_ERR_INVAL_ARG;
+
+ /* check if file exists */
+ if (stat ((char *) ms->filename, &file_stat) == 0)
+ {
+ if (S_ISSOCK (file_stat.st_mode))
+ unlink ((char *) ms->filename);
+ else
+ return memif_syscall_error_handler (errno);
+ }
+
+ ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
+ if (ms->fd < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+
+ DBG ("socket %d created", ms->fd);
+ un.sun_family = AF_UNIX;
+ strncpy ((char *) un.sun_path, (char *) ms->filename,
+ sizeof (un.sun_path) - 1);
+ if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (listen (ms->fd, 1) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (stat ((char *) ms->filename, &file_stat) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+
+ /* add socket to libmemif main */
+ elt.key = ms->fd;
+ elt.data_struct = ms;
+ add_list_elt (&elt, &lm->socket_list, &lm->socket_list_len);
+ lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, ms->private_ctx);
+
+ ms->type = MEMIF_SOCKET_TYPE_LISTENER;
+
+ return err;
+
+error:
+ if (ms->fd > 0)
+ {
+ close (ms->fd);
+ ms->fd = -1;
+ }
+ return err;
+}
+
+int
+memif_create_socket (memif_socket_handle_t * sock, const char *filename,
+ void *private_ctx)
+{
+ libmemif_main_t *lm = &libmemif_main;
+ memif_socket_t *ms = (memif_socket_t *) * sock;
+ int i, err = MEMIF_ERR_SUCCESS;
+
+ for (i = 0; i < lm->socket_list_len; i++)
+ {
+ if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
+ {
+ if (strncmp ((char *) ms->filename, filename,
+ strlen ((char *) ms->filename)) == 0)
+ return MEMIF_ERR_INVAL_ARG;
+ }
+ }
+
+ /* allocate memif_socket_t */
+ ms = NULL;
+ ms = lm->alloc (sizeof (memif_socket_t));
+ if (ms == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
+ memset (ms, 0, sizeof (memif_socket_t));
+ /* set filename */
+ ms->filename = lm->alloc (strlen (filename) + sizeof (char));
+ if (ms->filename == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
+ memset (ms->filename, 0, strlen (filename) + sizeof (char));
+ strncpy ((char *) ms->filename, filename, strlen (filename));
+
+ ms->type = MEMIF_SOCKET_TYPE_NONE;
+
+ ms->interface_list_len = 1;
+ ms->interface_list =
+ lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
+ if (ms->interface_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
+ ms->interface_list[0].key = -1;
+ ms->interface_list[0].data_struct = NULL;
+
+ *sock = ms;
+
+ return err;
+
+error:
+ if (ms != NULL)
+ {
+ if (ms->filename != NULL)
+ {
+ lm->free (ms->filename);
+ ms->filename = NULL;
+ }
+ if (ms->fd > 0)
+ {
+ close (ms->fd);
+ ms->fd = -1;
+ }
+ if (ms->interface_list != NULL)
+ {
+ lm->free (ms->interface_list);
+ ms->interface_list = NULL;
+ ms->interface_list_len = 0;
+ }
+ lm->free (ms);
+ *sock = ms = NULL;
+ }
+ return err;
+}
+
int
memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
memif_connection_update_t * on_connect,
@@ -651,9 +805,11 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
memif_interrupt_t * on_interrupt, void *private_ctx)
{
libmemif_main_t *lm = &libmemif_main;
- int err, i, index = 0, sockfd = -1;
- memif_list_elt_t list_elt;
+ int err, index = 0;
+ memif_list_elt_t elt;
memif_connection_t *conn = (memif_connection_t *) * c;
+ memif_socket_t *ms;
+
if (conn != NULL)
{
DBG ("This handle already points to existing memif.");
@@ -704,179 +860,53 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
l);
- /* allocate and initialize socket_filename so it can be copyed to sun_path
- without memory leaks */
- conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
- if (conn->args.socket_filename == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
+ if ((l = strlen ((char *) args->secret)) > 0)
+ strncpy ((char *) conn->args.secret, (char *) args->secret, l);
- if (args->socket_filename)
- {
- if (conn->args.socket_filename == NULL)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- strncpy ((char *) conn->args.socket_filename,
- (char *) args->socket_filename,
- strlen ((char *) args->socket_filename));
- }
+ if (args->socket != NULL)
+ conn->args.socket = args->socket;
else
{
- uint16_t sdl = strlen (MEMIF_DEFAULT_SOCKET_DIR);
- uint16_t sfl = strlen (MEMIF_DEFAULT_SOCKET_FILENAME);
- if (conn->args.socket_filename == NULL)
+ if (lm->default_socket == NULL)
{
- err = memif_syscall_error_handler (errno);
- goto error;
+ err =
+ memif_create_socket ((memif_socket_handle_t *) &
+ lm->default_socket,
+ MEMIF_DEFAULT_SOCKET_PATH, NULL);
+ if (err != MEMIF_ERR_SUCCESS)
+ goto error;
}
- strncpy ((char *) conn->args.socket_filename,
- MEMIF_DEFAULT_SOCKET_DIR, sdl);
- conn->args.socket_filename[sdl] = '/';
- strncpy ((char *) (conn->args.socket_filename + 1 + sdl),
- MEMIF_DEFAULT_SOCKET_FILENAME, sfl);
+ conn->args.socket = lm->default_socket;
}
+ ms = (memif_socket_t *) conn->args.socket;
- if ((l = strlen ((char *) args->secret)) > 0)
+ if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
+ (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
{
- strncpy ((char *) conn->args.secret, (char *) args->secret, l);
+ err = MEMIF_ERR_INVAL_ARG;
+ goto error;
}
+ elt.key = conn->args.interface_id;
+ elt.data_struct = conn;
+ add_list_elt (&elt, &ms->interface_list, &ms->interface_list_len);
+ ms->use_count++;
+
if (conn->args.is_master)
{
- conn->run_args.buffer_size = conn->args.buffer_size;
- memif_socket_t *ms;
- memif_list_elt_t elt;
- for (i = 0; i < lm->listener_list_len; i++)
- {
- if ((ms =
- (memif_socket_t *) lm->listener_list[i].data_struct) != NULL)
- {
- if (strncmp
- ((char *) ms->filename, (char *) conn->args.socket_filename,
- strlen ((char *) ms->filename)) == 0)
- {
- /* add interface to listener socket */
- elt.key = conn->args.interface_id;
- *c = elt.data_struct = conn;
- add_list_elt (&elt, &ms->interface_list,
- &ms->interface_list_len);
- ms->use_count++;
- conn->listener_fd = ms->fd;
- break;
- }
- }
- else
- {
- struct stat file_stat;
- if (stat ((char *) conn->args.socket_filename, &file_stat) == 0)
- {
- if (S_ISSOCK (file_stat.st_mode))
- unlink ((char *) conn->args.socket_filename);
- else
- return memif_syscall_error_handler (errno);
- }
- DBG ("creating socket file");
- ms = lm->alloc (sizeof (memif_socket_t));
- if (ms == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- ms->filename =
- lm->alloc (strlen ((char *) conn->args.socket_filename) +
- sizeof (char));
- if (ms->filename == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- memset (ms->filename, 0,
- strlen ((char *) conn->args.socket_filename) +
- sizeof (char));
- strncpy ((char *) ms->filename,
- (char *) conn->args.socket_filename,
- strlen ((char *) conn->args.socket_filename));
- ms->interface_list_len = 1;
- ms->interface_list =
- lm->alloc (sizeof (memif_list_elt_t) *
- ms->interface_list_len);
- if (ms->interface_list == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- ms->interface_list[0].key = -1;
- ms->interface_list[0].data_struct = NULL;
- struct sockaddr_un un = { 0 };
- int on = 1;
-
- ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
- if (ms->fd < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- DBG ("socket %d created", ms->fd);
- un.sun_family = AF_UNIX;
- strncpy ((char *) un.sun_path, (char *) ms->filename,
- sizeof (un.sun_path) - 1);
- DBG ("sockopt");
- if (setsockopt
- (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- DBG ("bind");
- if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- DBG ("listen");
- if (listen (ms->fd, 1) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- DBG ("stat");
- if (stat ((char *) ms->filename, &file_stat) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
-
- /* add interface to listener socket */
- elt.key = conn->args.interface_id;
- *c = elt.data_struct = conn;
- add_list_elt (&elt, &ms->interface_list,
- &ms->interface_list_len);
- ms->use_count = 1;
- conn->listener_fd = ms->fd;
-
- /* add listener socket to libmemif main */
- elt.key = ms->fd;
- elt.data_struct = ms;
- add_list_elt (&elt, &lm->listener_list, &lm->listener_list_len);
- lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ);
- break;
- }
- }
+ if (ms->type == MEMIF_SOCKET_TYPE_NONE)
+ err = memif_socket_start_listening (ms);
+ if (err != MEMIF_ERR_SUCCESS)
+ goto error;
}
else
{
lm->disconn_slaves++;
- list_elt.key = -1;
- *c = list_elt.data_struct = conn;
+ elt.key = -1;
+ elt.data_struct = conn;
if ((index =
- add_list_elt (&list_elt, &lm->control_list,
- &lm->control_list_len)) < 0)
+ add_list_elt (&elt, &lm->control_list, &lm->control_list_len)) < 0)
{
err = MEMIF_ERR_NOMEM;
goto error;
@@ -885,7 +915,7 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
conn->index = index;
/* try connectiong to master */
- err = memif_request_connection(conn);
+ err = memif_request_connection (conn);
if ((err < 0) && (lm->disconn_slaves == 1))
{
/* connection failed, arm reconnect timer (if not armed) */
@@ -897,14 +927,11 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
}
}
+ *c = conn;
+
return 0;
error:
- if (sockfd > 0)
- close (sockfd);
- sockfd = -1;
- if (conn->args.socket_filename)
- lm->free (conn->args.socket_filename);
if (conn != NULL)
lm->free (conn);
*c = conn = NULL;
@@ -912,15 +939,21 @@ error:
}
int
-memif_request_connection(memif_conn_handle_t c)
+memif_request_connection (memif_conn_handle_t c)
{
libmemif_main_t *lm = &libmemif_main;
memif_connection_t *conn = (memif_connection_t *) c;
+ memif_socket_t *ms;
int err = MEMIF_ERR_SUCCESS;
int sockfd = -1;
struct sockaddr_un sun;
- if (conn->args.is_master)
+ if (conn == NULL)
+ return MEMIF_ERR_NOCONN;
+
+ ms = (memif_socket_t *) conn->args.socket;
+
+ if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
return MEMIF_ERR_INVAL_ARG;
if (conn->fd > 0)
return MEMIF_ERR_ALRCONN;
@@ -934,11 +967,10 @@ memif_request_connection(memif_conn_handle_t c)
sun.sun_family = AF_UNIX;
- strncpy (sun.sun_path, (char *) conn->args.socket_filename,
- sizeof (sun.sun_path) - 1);
+ strncpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path) - 1);
if (connect (sockfd, (struct sockaddr *) &sun,
- sizeof (struct sockaddr_un)) == 0)
+ sizeof (struct sockaddr_un)) == 0)
{
conn->fd = sockfd;
conn->read_fn = memif_conn_fd_read_ready;
@@ -948,8 +980,8 @@ memif_request_connection(memif_conn_handle_t c)
lm->control_list[conn->index].key = conn->fd;
lm->control_fd_update (sockfd,
- MEMIF_FD_EVENT_READ |
- MEMIF_FD_EVENT_WRITE);
+ MEMIF_FD_EVENT_READ |
+ MEMIF_FD_EVENT_WRITE, conn->private_ctx);
lm->disconn_slaves--;
if (lm->disconn_slaves == 0)
@@ -964,12 +996,13 @@ memif_request_connection(memif_conn_handle_t c)
else
{
strcpy ((char *) conn->remote_disconnect_string,
- memif_strerror (memif_syscall_error_handler
- (errno)));
+ memif_strerror (memif_syscall_error_handler (errno)));
goto error;
}
- return err;
+ ms->type = MEMIF_SOCKET_TYPE_CLIENT;
+
+ return err;
error:
if (sockfd > 0)
@@ -993,7 +1026,7 @@ memif_control_fd_handler (int fd, uint8_t events)
size = read (fd, &b, sizeof (b));
if (size == -1)
- goto error;
+ goto error;
for (i = 0; i < lm->control_list_len; i++)
{
@@ -1003,7 +1036,9 @@ memif_control_fd_handler (int fd, uint8_t events)
conn = lm->control_list[i].data_struct;
if (conn->args.is_master)
continue;
- memif_request_connection(conn);
+ err = memif_request_connection (conn);
+ if (err != MEMIF_ERR_SUCCESS)
+ DBG ("memif_request_connection: %s", memif_strerror (err));
}
}
}
@@ -1035,10 +1070,13 @@ memif_control_fd_handler (int fd, uint8_t events)
}
return MEMIF_ERR_SUCCESS;
}
- get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
- if (e != NULL)
+ get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
+ if (e != NULL
+ && ((memif_socket_t *) e->data_struct)->type ==
+ MEMIF_SOCKET_TYPE_LISTENER)
{
- err = memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
+ err =
+ memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
return err;
}
@@ -1172,7 +1210,7 @@ memif_disconnect_internal (memif_connection_t * c)
if (c->fd > 0)
{
memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
- lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL);
+ lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, c->private_ctx);
close (c->fd);
}
get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
@@ -1217,7 +1255,8 @@ memif_disconnect_internal (memif_connection_t * c)
if (mq->int_fd > 0)
{
if (c->on_interrupt != NULL)
- lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL);
+ lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
+ c->private_ctx);
close (mq->int_fd);
}
free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
@@ -1273,19 +1312,38 @@ memif_disconnect_internal (memif_connection_t * c)
}
int
+memif_delete_socket (memif_socket_handle_t * sock)
+{
+ memif_socket_t *ms = (memif_socket_t *) * sock;
+ libmemif_main_t *lm = &libmemif_main;
+
+ /* check if socket is in use */
+ if (ms == NULL || ms->type != MEMIF_SOCKET_TYPE_NONE)
+ return MEMIF_ERR_INVAL_ARG;
+
+ lm->free (ms->interface_list);
+ ms->interface_list = NULL;
+ lm->free (ms->filename);
+ ms->filename = NULL;
+ lm->free (ms);
+ *sock = ms = NULL;
+
+ return MEMIF_ERR_SUCCESS;
+}
+
+int
memif_delete (memif_conn_handle_t * conn)
{
memif_connection_t *c = (memif_connection_t *) * conn;
+ libmemif_main_t *lm = &libmemif_main;
+ memif_socket_t *ms = NULL;
+ int err = MEMIF_ERR_SUCCESS;
+
if (c == NULL)
{
DBG ("no connection");
return MEMIF_ERR_NOCONN;
}
- libmemif_main_t *lm = &libmemif_main;
- memif_list_elt_t *e = NULL;
- memif_socket_t *ms = NULL;
-
- int err = MEMIF_ERR_SUCCESS;
if (c->fd > 0)
{
@@ -1297,33 +1355,25 @@ memif_delete (memif_conn_handle_t * conn)
free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
- if (c->args.is_master)
+ ms = (memif_socket_t *) c->args.socket;
+ ms->use_count--;
+ free_list_elt (ms->interface_list, ms->interface_list_len,
+ c->args.interface_id);
+ if (ms->use_count <= 0)
{
- get_list_elt (&e, lm->listener_list, lm->listener_list_len,
- c->listener_fd);
- if (e != NULL)
+ /* stop listening on this socket */
+ if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
{
- ms = (memif_socket_t *) e->data_struct;
- ms->use_count--;
- free_list_elt (ms->interface_list, ms->interface_list_len,
- c->args.interface_id);
- if (ms->use_count <= 0)
- {
- lm->control_fd_update (c->listener_fd, MEMIF_FD_EVENT_DEL);
- free_list_elt (lm->listener_list, lm->listener_list_len,
- c->listener_fd);
- close (c->listener_fd);
- c->listener_fd = ms->fd = -1;
- lm->free (ms->interface_list);
- ms->interface_list = NULL;
- lm->free (ms->filename);
- ms->filename = NULL;
- lm->free (ms);
- ms = NULL;
- }
+ lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, ms->private_ctx);
+ free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
+ close (ms->fd);
+ ms->fd = -1;
}
+ /* socket not in use */
+ ms->type = MEMIF_SOCKET_TYPE_NONE;
}
- else
+
+ if (!c->args.is_master)
{
lm->disconn_slaves--;
if (lm->disconn_slaves <= 0)
@@ -1336,10 +1386,6 @@ memif_delete (memif_conn_handle_t * conn)
}
}
- if (c->args.socket_filename)
- lm->free (c->args.socket_filename);
- c->args.socket_filename = NULL;
-
lm->free (c);
c = NULL;
@@ -1365,7 +1411,7 @@ memif_connect1 (memif_connection_t * c)
if (mr->is_external)
{
if (lm->get_external_region_addr == NULL)
- return 99; /* FIXME: proper error report */
+ return MEMIF_ERR_INVAL_ARG;
mr->addr =
lm->get_external_region_addr (mr->region_size, mr->fd,
c->private_ctx);
@@ -1418,7 +1464,8 @@ memif_connect1 (memif_connection_t * c)
}
}
- lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD);
+ lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
+ c->private_ctx);
return 0;
}
@@ -2028,12 +2075,14 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
{
libmemif_main_t *lm = &libmemif_main;
memif_connection_t *c = (memif_connection_t *) conn;
+ memif_socket_t *ms;
+ int err = MEMIF_ERR_SUCCESS, i;
+ ssize_t l0 = 0, l1;
+
if (c == NULL)
return MEMIF_ERR_NOCONN;
- int err = MEMIF_ERR_SUCCESS, i;
- ssize_t l0, l1;
- l0 = 0;
+ ms = (memif_socket_t *) c->args.socket;
l1 = strlen ((char *) c->args.interface_name);
if (l0 + l1 < buflen)
@@ -2091,11 +2140,11 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
md->role = (c->args.is_master) ? 0 : 1;
md->mode = c->args.mode;
- l1 = strlen ((char *) c->args.socket_filename);
+ l1 = strlen ((char *) ms->filename);
if (l0 + l1 < buflen)
{
md->socket_filename =
- (uint8_t *) strcpy (buf + l0, (char *) c->args.socket_filename);
+ (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
l0 += l1 + 1;
}
else
@@ -2117,13 +2166,13 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
{
md->regions = (memif_region_details_t *) (buf + l0);
for (i = 0; i < md->regions_num; i++)
- {
- md->regions[i].index = i;
- md->regions[i].addr = c->regions[i].addr;
- md->regions[i].size = c->regions[i].region_size;
- md->regions[i].fd = c->regions[i].fd;
- md->regions[i].is_external = c->regions[i].is_external;
- }
+ {
+ md->regions[i].index = i;
+ md->regions[i].addr = c->regions[i].addr;
+ md->regions[i].size = c->regions[i].region_size;
+ md->regions[i].fd = c->regions[i].fd;
+ md->regions[i].is_external = c->regions[i].is_external;
+ }
l0 += l1;
}
else
@@ -2138,15 +2187,15 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
{
md->rx_queues = (memif_queue_details_t *) (buf + l0);
for (i = 0; i < md->rx_queues_num; i++)
- {
- md->rx_queues[i].region = c->rx_queues[i].region;
- md->rx_queues[i].qid = i;
- md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
- md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
- md->rx_queues[i].head = c->rx_queues[i].ring->head;
- md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
- md->rx_queues[i].buffer_size = c->run_args.buffer_size;
- }
+ {
+ md->rx_queues[i].region = c->rx_queues[i].region;
+ md->rx_queues[i].qid = i;
+ md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
+ md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
+ md->rx_queues[i].head = c->rx_queues[i].ring->head;
+ md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
+ md->rx_queues[i].buffer_size = c->run_args.buffer_size;
+ }
l0 += l1;
}
else
@@ -2161,15 +2210,15 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
{
md->tx_queues = (memif_queue_details_t *) (buf + l0);
for (i = 0; i < md->tx_queues_num; i++)
- {
- md->tx_queues[i].region = c->tx_queues[i].region;
- md->tx_queues[i].qid = i;
- md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
- md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
- md->tx_queues[i].head = c->tx_queues[i].ring->head;
- md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
- md->tx_queues[i].buffer_size = c->run_args.buffer_size;
- }
+ {
+ md->tx_queues[i].region = c->tx_queues[i].region;
+ md->tx_queues[i].qid = i;
+ md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
+ md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
+ md->tx_queues[i].head = c->tx_queues[i].ring->head;
+ md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
+ md->tx_queues[i].buffer_size = c->run_args.buffer_size;
+ }
l0 += l1;
}
else
@@ -2184,12 +2233,15 @@ int
memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
{
memif_connection_t *c = (memif_connection_t *) conn;
+ uint8_t num;
+
*efd = -1;
if (c == NULL)
return MEMIF_ERR_NOCONN;
if (c->fd < 0)
return MEMIF_ERR_DISCONNECTED;
- uint8_t num =
+
+ num =
(c->args.is_master) ? c->run_args.num_s2m_rings : c->
run_args.num_m2s_rings;
if (qid >= num)
@@ -2204,15 +2256,18 @@ int
memif_cleanup ()
{
libmemif_main_t *lm = &libmemif_main;
+
+ memif_delete_socket ((memif_socket_handle_t *) &lm->default_socket);
+
if (lm->control_list)
lm->free (lm->control_list);
lm->control_list = NULL;
if (lm->interrupt_list)
lm->free (lm->interrupt_list);
lm->interrupt_list = NULL;
- if (lm->listener_list)
- lm->free (lm->listener_list);
- lm->listener_list = NULL;
+ if (lm->socket_list)
+ lm->free (lm->socket_list);
+ lm->socket_list = NULL;
if (lm->pending_list)
lm->free (lm->pending_list);
lm->pending_list = NULL;
diff --git a/extras/libmemif/src/memif_private.h b/extras/libmemif/src/memif_private.h
index 64d5bb80c86..eceac677752 100644
--- a/extras/libmemif/src/memif_private.h
+++ b/extras/libmemif/src/memif_private.h
@@ -35,8 +35,7 @@
_Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
"MEMIF_DEFAULT_APP_NAME max length is 32");
-#define MEMIF_DEFAULT_SOCKET_DIR "/run/vpp"
-#define MEMIF_DEFAULT_SOCKET_FILENAME "memif.sock"
+#define MEMIF_DEFAULT_SOCKET_PATH "/run/vpp/memif.sock"
#define MEMIF_DEFAULT_RING_SIZE 1024
#define MEMIF_DEFAULT_LOG2_RING_SIZE 10
#define MEMIF_DEFAULT_RX_QUEUES 1
@@ -67,6 +66,13 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
#define DBG(...)
#endif /* MEMIF_DBG */
+typedef enum
+{
+ MEMIF_SOCKET_TYPE_NONE = 0, /* unassigned, not used by any interface */
+ MEMIF_SOCKET_TYPE_LISTENER, /* listener socket, master interface assigned */
+ MEMIF_SOCKET_TYPE_CLIENT /* client socket, slave interface assigned */
+} memif_socket_type_t;
+
typedef struct
{
void *addr;
@@ -121,7 +127,6 @@ typedef struct memif_connection
memif_conn_run_args_t run_args;
int fd;
- int listener_fd;
memif_fn *write_fn, *read_fn, *error_fn;
@@ -158,8 +163,10 @@ typedef struct
{
int fd;
uint16_t use_count;
+ memif_socket_type_t type;
uint8_t *filename;
uint16_t interface_list_len;
+ void *private_ctx;
memif_list_elt_t *interface_list; /* memif master interfaces listening on this socket */
} memif_socket_t;
@@ -171,6 +178,8 @@ typedef struct
uint16_t disconn_slaves;
uint8_t app_name[MEMIF_NAME_LEN];
+ memif_socket_handle_t default_socket;
+
memif_add_external_region_t *add_external_region;
memif_get_external_region_addr_t *get_external_region_addr;
memif_del_external_region_t *del_external_region;
@@ -182,11 +191,11 @@ typedef struct
uint16_t control_list_len;
uint16_t interrupt_list_len;
- uint16_t listener_list_len;
+ uint16_t socket_list_len;
uint16_t pending_list_len;
memif_list_elt_t *control_list;
memif_list_elt_t *interrupt_list;
- memif_list_elt_t *listener_list;
+ memif_list_elt_t *socket_list;
memif_list_elt_t *pending_list;
} libmemif_main_t;
diff --git a/extras/libmemif/src/socket.c b/extras/libmemif/src/socket.c
index 495cef9ad43..6efcfb5b5f7 100644
--- a/extras/libmemif/src/socket.c
+++ b/extras/libmemif/src/socket.c
@@ -471,7 +471,7 @@ memif_msg_receive_init (memif_socket_t * ms, int fd, memif_msg_t * msg)
error:
memif_msg_send_disconnect (fd, err_string, 0);
- lm->control_fd_update (fd, MEMIF_FD_EVENT_DEL);
+ lm->control_fd_update (fd, MEMIF_FD_EVENT_DEL, c->private_ctx);
free_list_elt (lm->pending_list, lm->pending_list_len, fd);
close (fd);
fd = -1;
@@ -600,7 +600,8 @@ memif_msg_receive_connect (memif_connection_t * c, memif_msg_t * msg)
elt.data_struct = c;
add_list_elt (&elt, &lm->interrupt_list, &lm->interrupt_list_len);
- lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+ lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
+ c->private_ctx);
}
}
@@ -630,7 +631,8 @@ memif_msg_receive_connected (memif_connection_t * c, memif_msg_t * msg)
{
for (i = 0; i < c->run_args.num_s2m_rings; i++)
{
- lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+ lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
+ c->private_ctx);
}
}
@@ -808,8 +810,7 @@ memif_msg_receive (int ifd)
if (c != NULL)
c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
-/* libmemif_main_t *lm = &libmemif_main;
- lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD); */
+
return MEMIF_ERR_SUCCESS; /* 0 */
}
@@ -853,12 +854,7 @@ memif_conn_fd_write_ready (memif_connection_t * c)
c->msg_queue = c->msg_queue->next;
c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
-/*
- libmemif_main_t *lm = &libmemif_main;
- lm->control_fd_update (c->fd,
- MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
-*/
err = memif_msg_send (c->fd, &e->msg, e->fd);
lm->free (e);
goto done;
@@ -893,7 +889,8 @@ memif_conn_fd_accept_ready (memif_socket_t * ms)
elt.data_struct = ms;
add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
- lm->control_fd_update (conn_fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE);
+ lm->control_fd_update (conn_fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE,
+ ms->private_ctx);
return memif_msg_send_hello (conn_fd);
}
diff --git a/extras/libmemif/test/main_test.c b/extras/libmemif/test/main_test.c
index 6c29babcb2e..0a8e091f395 100644
--- a/extras/libmemif/test/main_test.c
+++ b/extras/libmemif/test/main_test.c
@@ -148,7 +148,6 @@ START_TEST (test_create)
ck_assert_ptr_ne (c->on_interrupt, NULL);
ck_assert_str_eq ((char *)c->args.interface_name, (char *)args.interface_name);
- ck_assert_str_eq ((char *)c->args.socket_filename, SOCKET_FILENAME);
struct itimerspec timer;
timerfd_gettime (lm->timerfd, &timer);
@@ -210,7 +209,6 @@ START_TEST (test_create_master)
ck_assert_ptr_ne (c->on_interrupt, NULL);
ck_assert_str_eq ((char *)c->args.interface_name, (char *)args.interface_name);
- ck_assert_str_eq ((char *)c->args.socket_filename, SOCKET_FILENAME);
struct stat file_stat;
@@ -295,9 +293,7 @@ START_TEST (test_create_mult)
ck_assert_ptr_ne (c1->on_interrupt, NULL);
ck_assert_str_eq ((char *)c->args.interface_name, (char *)args.interface_name);
- ck_assert_str_eq ((char *)c->args.socket_filename, SOCKET_FILENAME);
ck_assert_str_eq ((char *)c1->args.interface_name, (char *)args.interface_name);
- ck_assert_str_eq ((char *)c1->args.socket_filename, SOCKET_FILENAME);
struct itimerspec timer;
timerfd_gettime (lm->timerfd, &timer);
@@ -720,7 +716,6 @@ START_TEST (test_get_details)
ck_assert_str_eq ((char *)md.remote_if_name, (char *)c->remote_if_name);
ck_assert_str_eq ((char *)md.remote_inst_name, (char *)c->remote_name);
ck_assert_str_eq ((char *)md.secret, (char *)c->args.secret);
- ck_assert_str_eq ((char *)md.socket_filename, (char *)c->args.socket_filename);
ck_assert_uint_eq (md.id, c->args.interface_id);
ck_assert_uint_ne (md.role, c->args.is_master);
diff --git a/extras/libmemif/test/unit_test.c b/extras/libmemif/test/unit_test.c
index 9c9a8d4de66..0ae045b9573 100644
--- a/extras/libmemif/test/unit_test.c
+++ b/extras/libmemif/test/unit_test.c
@@ -37,7 +37,7 @@ on_interrupt (memif_conn_handle_t conn, void *ctx, uint16_t qid)
}
int
-control_fd_update (int fd, uint8_t events)
+control_fd_update (int fd, uint8_t events, void *ctx)
{
return 0;
}
diff --git a/extras/libmemif/test/unit_test.h b/extras/libmemif/test/unit_test.h
index a24887d7fca..3182c77e6e6 100644
--- a/extras/libmemif/test/unit_test.h
+++ b/extras/libmemif/test/unit_test.h
@@ -34,6 +34,6 @@ int on_disconnect (memif_conn_handle_t conn, void *ctx);
int on_interrupt (memif_conn_handle_t conn, void *ctx, uint16_t qid);
-int control_fd_update (int fd, uint8_t events);
+int control_fd_update (int fd, uint8_t events, void *ctx);
#endif /* _UNIT_TEST_H_ */