static int knet_cmd_interface(struct knet_vty *vty)
{
- int err = 0, paramlen = 0, paramoffset = 0, found = 0, requested_id;
+ int err = 0, paramlen = 0, paramoffset = 0, found = 0, requested_id, tapfd;
uint16_t baseport;
uint8_t *bport = (uint8_t *)&baseport;
char *param = NULL;
knet_iface->cfg_ring.base_port = baseport;
- knet_iface->cfg_ring.knet_h = knet_handle_new(requested_id, tap_get_fd(knet_iface->cfg_eth.tap), vty->logfd, vty->loglevel);
+ tapfd = tap_get_fd(knet_iface->cfg_eth.tap);
+
+ knet_iface->cfg_ring.knet_h = knet_handle_new(requested_id, &tapfd, vty->logfd, vty->loglevel);
if (!knet_iface->cfg_ring.knet_h) {
knet_vty_write(vty, "Error: Unable to create ring handle for device %s%s",
device, telnet_newline);
static pthread_mutex_t handle_config_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int _init_socketpair(knet_handle_t knet_h)
+{
+ if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, knet_h->sockpair) != 0) {
+ return -1;
+ }
+
+ if (_fdset_cloexec(knet_h->sockpair[0])) {
+ return -1;
+ }
+
+ if (_fdset_nonblock(knet_h->sockpair[0])) {
+ return -1;
+ }
+
+ if (_fdset_cloexec(knet_h->sockpair[1])) {
+ return -1;
+ }
+
+ if (_fdset_nonblock(knet_h->sockpair[1])) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void _close_socketpair(knet_handle_t knet_h)
+{
+ if (knet_h->sockpair[0]) {
+ close(knet_h->sockpair[0]);
+ knet_h->sockpair[0] = 0;
+ }
+ if (knet_h->sockpair[1]) {
+ close(knet_h->sockpair[1]);
+ knet_h->sockpair[1] = 0;
+ }
+}
+
static int _init_locks(knet_handle_t knet_h)
{
int savederrno = 0;
}
knet_handle_t knet_handle_new(uint16_t host_id,
- int datafd,
+ int *datafd,
int log_fd,
uint8_t default_log_level)
{
* validate incoming request
*/
- if (datafd <= 0) {
+ if (datafd == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (*datafd < 0) {
errno = EINVAL;
return NULL;
}
*/
knet_h->host_id = host_id;
- knet_h->sockfd = datafd;
+
+ if (*datafd == 0) {
+ if (_init_socketpair(knet_h)) {
+ savederrno = errno;
+ goto exit_fail;
+ }
+ knet_h->sockfd = knet_h->sockpair[0];
+ *datafd = knet_h->sockpair[1];
+ } else {
+ knet_h->sockfd = *datafd;
+ }
+
knet_h->logfd = log_fd;
if (knet_h->logfd > 0) {
memset(&knet_h->log_levels, default_log_level, KNET_MAX_SUBSYSTEMS);
crypto_fini(knet_h);
_destroy_locks(knet_h);
+ _close_socketpair(knet_h);
exit_nolock:
free(knet_h);
uint16_t host_id;
unsigned int enabled:1;
int sockfd;
+ int sockpair[2];
int logfd;
uint8_t log_levels[KNET_MAX_SUBSYSTEMS];
int hostpipefd[2];
int main(int argc, char *argv[])
{
- int sock, i;
+ int sock = 0, i;
knet_handle_t knet_h;
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ knet_h = knet_handle_new(1, &sock, 0, 0);
- if (sock < 0) {
- printf("Unable to create new socket\n");
- exit(EXIT_FAILURE);
- }
-
- knet_h = knet_handle_new(1, sock, 0, 0);
-
- for (i = 0; i < KNET_MAX_HOST; i++)
+ for (i = 0; i < KNET_MAX_HOST; i++) {
+ printf("add host: %d\n", i);
knet_host_add(knet_h, i);
+ }
- for (i = 0; i < KNET_MAX_HOST; i++)
+ for (i = 0; i < KNET_MAX_HOST; i++) {
+ printf("del host: %d\n", i);
knet_host_remove(knet_h, i);
+ }
if (knet_handle_free(knet_h) != 0) {
printf("Unable to free knet_handle\n");
* It is user responsibility to check that the value
* is unique, or bad might happen.
*
- * datafd - read/write file descriptor (must be > 0).
+ * datafd - read/write file descriptor.
* knet will read data here to send to the other hosts
* and will write data received from the network.
* Each data packet can be of max size KNET_MAX_PACKET_SIZE!
* Applications might be able to write more data at a time
* but they will be delivered in KNET_MAX_PACKET_SIZE chunks.
* Please refer to ping_test.c on how to setup socketpair.
+ * datafd can be 0, and knet_handle_new will create a properly
+ * populated socket pair the same way as ping_test, or a value
+ * higher than 0. Negative number will return error.
+ * knet_handle_new will take care to cleanup the socketpair
+ * only if it's been created by knet_handle_new, when calling
+ * knet_handle_free.
*
* log_fd - write file descriptor. If set to a value > 0, it will be used
* to write log packets (see below) from libknet to the application.
*/
knet_handle_t knet_handle_new(uint16_t host_id,
- int datafd,
+ int *datafd,
int log_fd,
uint8_t default_log_level);
#define KNET_RING_DEFPORT 50000
-static int knet_sock[2];
+static int knet_sock = 0;
static knet_handle_t knet_h;
static struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
static uint8_t loglevel = KNET_LOG_INFO;
exit(EXIT_FAILURE);
}
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, knet_sock) != 0) {
- printf("Unable to create socket\n");
- exit(EXIT_FAILURE);
- }
-
if (pipe(logpipefd)) {
printf("Unable to create log pipe\n");
exit(EXIT_FAILURE);
set_debug(argc, argv);
- if ((knet_h = knet_handle_new(1, knet_sock[0], logfd, loglevel)) == NULL) {
+ if ((knet_h = knet_handle_new(1, &knet_sock, logfd, loglevel)) == NULL) {
printf("Unable to create new knet_handle_t\n");
exit(EXIT_FAILURE);
}
snprintf(hello_world, sizeof(hello_world), "Hello world!");
-
switch(big) {
case 0: /* hello world */
iov_out[0].iov_base = (void *)hello_world;
break;
}
- wlen = writev(knet_sock[1], iov_out, 1);
+ wlen = writev(knet_sock, iov_out, 1);
if (wlen != iov_out[0].iov_len) {
printf("Unable to send messages to socket\n");
exit(1);
select_loop:
FD_ZERO(&rfds);
- FD_SET(knet_sock[1], &rfds);
+ FD_SET(knet_sock, &rfds);
FD_SET(logpipefd[0], &rfds);
len = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
if (len < 0) {
printf("Unable select over knet_handle_t\n");
exit(EXIT_FAILURE);
- } else if (FD_ISSET(knet_sock[1], &rfds)) {
+ } else if (FD_ISSET(knet_sock, &rfds)) {
struct iovec iov_in;
ssize_t rlen = 0;
iov_in.iov_base = (void *)recvbuff;
iov_in.iov_len = sizeof(recvbuff);
- rlen = readv(knet_sock[1], &iov_in, 1);
+ rlen = readv(knet_sock, &iov_in, 1);
if (!rlen) {
printf("EOF\n");