Commit bee1130c authored by Tomasz Kulasek's avatar Tomasz Kulasek Committed by Jim Harris
Browse files

net/vpp: prepare vpp 19.01 to move to 19.04



No functional changes done, just reordering for next patch in series.

Change-Id: I32022fddffbc7b00eeecb29a2fcbaa85fbf2e99f
Signed-off-by: default avatarTomasz Kulasek <tomaszx.kulasek@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462473


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 093bc339
Loading
Loading
Loading
Loading
+188 −194
Original line number Diff line number Diff line
@@ -141,56 +141,6 @@ struct spdk_vpp_sock_group_impl {
#define __vpp_session(sock) ((struct spdk_vpp_session *)sock)
#define __vpp_group_impl(group) ((struct spdk_vpp_sock_group_impl *)group)

static int
vpp_queue_poller(void *ctx)
{
	uword msg;

	if (g_svm.vl_output_queue->cursize > 0 &&
	    !svm_queue_sub_raw(g_svm.vl_output_queue, (u8 *)&msg)) {
		vl_msg_api_handler((void *)msg);
	}

	return 0;
}

static int
app_queue_poller(void *ctx)
{
	svm_msg_q_msg_t msg;
	if (!svm_msg_q_is_empty(g_svm.app_event_queue)) {
		svm_msg_q_sub(g_svm.app_event_queue, &msg, SVM_Q_WAIT, 0);
		svm_msg_q_free_msg(g_svm.app_event_queue, &msg);
	}

	return 0;
}

/* This is required until sock.c API changes to asynchronous */
static int
_wait_for_session_state_change(struct spdk_vpp_session *session, enum spdk_vpp_session_state state)
{
	time_t start = time(NULL);
	while (time(NULL) - start < 10) {
		if (session->app_session.session_state == VPP_SESSION_STATE_FAILED) {
			errno = EADDRNOTAVAIL;
			return -1;
		}
		if (session->app_session.session_state == state) {
			errno = 0;
			return 0;
		}
		if (spdk_get_thread() == g_svm.init_thread) {
			usleep(100000);
			app_queue_poller(NULL);
			vpp_queue_poller(NULL);
		}
	}
	/* timeout */
	errno = ETIMEDOUT;
	return -1;
}

/******************************************************************************
 * Session management
 */
@@ -331,8 +281,67 @@ enum spdk_vpp_create_type {
};

/******************************************************************************
 * Connect
 * VPP message handlers
 */
static void
vl_api_accept_session_t_handler(vl_api_accept_session_t *mp)
{
	svm_fifo_t *rx_fifo, *tx_fifo;
	struct spdk_vpp_session *client_session, *listen_session;

	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "listeners handle is %" PRIu64 "\n", mp->listener_handle);

	pthread_mutex_lock(&g_svm.session_get_lock);
	listen_session = _spdk_vpp_session_get_by_handle(mp->listener_handle, true);
	pthread_mutex_unlock(&g_svm.session_get_lock);
	if (!listen_session) {
		SPDK_ERRLOG("Listener not found\n");
		return;
	}

	/* Allocate local session for a client and set it up */
	client_session = _spdk_vpp_session_create();
	if (client_session == NULL) {
		SPDK_ERRLOG("Cannot create new session\n");
		return;
	}

	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Accept session %p (%d) on %p (%d/%" PRIu64 ")\n",
		      client_session, client_session->id, listen_session, listen_session->id,
		      listen_session->handle);

	rx_fifo = uword_to_pointer(mp->server_rx_fifo, svm_fifo_t *);
	rx_fifo->client_session_index = client_session->id;
	tx_fifo = uword_to_pointer(mp->server_tx_fifo, svm_fifo_t *);
	tx_fifo->client_session_index = client_session->id;

	client_session->handle = mp->handle;
	client_session->context = mp->context;
	client_session->app_session.rx_fifo = rx_fifo;
	client_session->app_session.tx_fifo = tx_fifo;
	client_session->app_session.vpp_evt_q = uword_to_pointer(mp->vpp_event_queue_address,
						svm_msg_q_t *);

	client_session->is_server = true;
	client_session->app_session.transport.rmt_port = mp->port;
	client_session->app_session.transport.is_ip4 = mp->is_ip4;
	memcpy(&client_session->app_session.transport.rmt_ip, mp->ip, sizeof(mp->ip));

	client_session->app_session.transport.lcl_port = listen_session->app_session.transport.lcl_port;
	memcpy(&client_session->app_session.transport.lcl_ip, &listen_session->app_session.transport.lcl_ip,
	       sizeof(listen_session->app_session.transport.lcl_ip));
	client_session->app_session.transport.is_ip4 = listen_session->app_session.transport.is_ip4;

	client_session->app_session.session_state = VPP_SESSION_STATE_READY;

	pthread_mutex_lock(&listen_session->accept_session_lock);

	clib_fifo_add1(listen_session->accept_session_index_fifo,
		       client_session->id);

	pthread_mutex_unlock(&listen_session->accept_session_lock);
}

static void
vl_api_connect_session_reply_t_handler(vl_api_connect_session_reply_t *mp)
{
@@ -370,53 +379,6 @@ vl_api_connect_session_reply_t_handler(vl_api_connect_session_reply_t *mp)
	session->app_session.session_state = VPP_SESSION_STATE_READY;
}

static int
_spdk_vpp_session_connect(struct spdk_vpp_session *session)
{
	vl_api_connect_sock_t *cmp;

	cmp = vl_msg_api_alloc(sizeof(*cmp));
	if (cmp == NULL) {
		return -ENOMEM;
	}
	memset(cmp, 0, sizeof(*cmp));

	cmp->_vl_msg_id = ntohs(VL_API_CONNECT_SOCK);
	cmp->client_index = g_svm.my_client_index;
	cmp->context = session->id;

	cmp->vrf = 0 /* VPPCOM_VRF_DEFAULT */;
	cmp->is_ip4 = (session->app_session.transport.is_ip4);
	memcpy(cmp->ip, &session->app_session.transport.rmt_ip, sizeof(cmp->ip));
	cmp->port = session->app_session.transport.rmt_port;
	cmp->proto = TRANSPORT_PROTO_TCP;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&cmp);

	return _wait_for_session_state_change(session, VPP_SESSION_STATE_READY);
}

static void
vl_api_disconnect_session_reply_t_handler(vl_api_disconnect_session_reply_t *mp)
{
	struct spdk_vpp_session *session;

	if (mp->retval) {
		SPDK_ERRLOG("Disconnecting session failed (%d).\n", ntohl(mp->retval));
		return;
	}

	pthread_mutex_lock(&g_svm.session_get_lock);
	session = _spdk_vpp_session_get_by_handle(mp->handle, false);
	if (session == NULL) {
		SPDK_ERRLOG("Invalid session handler (%" PRIu64 ").\n", mp->handle);
		pthread_mutex_unlock(&g_svm.session_get_lock);
		return;
	}
	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Session disconnected %p (%d)\n", session, session->id);
	session->app_session.session_state = VPP_SESSION_STATE_CLOSE;
	pthread_mutex_unlock(&g_svm.session_get_lock);
}

static void
vl_api_disconnect_session_t_handler(vl_api_disconnect_session_t *mp)
{
@@ -436,44 +398,6 @@ vl_api_disconnect_session_t_handler(vl_api_disconnect_session_t *mp)
	pthread_mutex_unlock(&g_svm.session_get_lock);
}

static int
_spdk_vpp_session_disconnect(struct spdk_vpp_session *session)
{
	int rv = 0;
	vl_api_disconnect_session_t *dmp;
	vl_api_disconnect_session_reply_t *rmp;

	if (session->app_session.session_state == VPP_SESSION_STATE_DISCONNECT) {
		SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Session is already in disconnecting state %p (%d)\n",
			      session, session->id);

		rmp = vl_msg_api_alloc(sizeof(*rmp));
		if (rmp == NULL) {
			return -ENOMEM;
		}
		memset(rmp, 0, sizeof(*rmp));

		rmp->_vl_msg_id = ntohs(VL_API_DISCONNECT_SESSION_REPLY);
		rmp->retval = rv;
		rmp->handle = session->handle;
		vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&rmp);
		return 0;
	}
	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Disconnect session %p (%d)\n", session, session->id);

	dmp = vl_msg_api_alloc(sizeof(*dmp));
	if (dmp == NULL) {
		return -ENOMEM;
	}
	memset(dmp, 0, sizeof(*dmp));
	dmp->_vl_msg_id = ntohs(VL_API_DISCONNECT_SESSION);
	dmp->client_index = g_svm.my_client_index;
	dmp->handle = session->handle;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&dmp);

	return _wait_for_session_state_change(session, VPP_SESSION_STATE_CLOSE);
}

static void
vl_api_reset_session_t_handler(vl_api_reset_session_t *mp)
{
@@ -504,9 +428,6 @@ vl_api_reset_session_t_handler(vl_api_reset_session_t *mp)
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&rmp);
}

/******************************************************************************
 * Bind
 */
static void
vl_api_bind_sock_reply_t_handler(vl_api_bind_sock_reply_t *mp)
{
@@ -558,87 +479,160 @@ vl_api_unbind_sock_reply_t_handler(vl_api_unbind_sock_reply_t *mp)
}

static int
_spdk_send_unbind_sock(struct spdk_vpp_session *session)
vpp_queue_poller(void *ctx)
{
	vl_api_unbind_sock_t *ump;
	uword msg;

	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Unbind session %p (%d) request\n", session, session->id);
	if (g_svm.vl_output_queue->cursize > 0 &&
	    !svm_queue_sub_raw(g_svm.vl_output_queue, (u8 *)&msg)) {
		vl_msg_api_handler((void *)msg);
	}

	ump = vl_msg_api_alloc(sizeof(*ump));
	if (ump == NULL) {
	return 0;
}

static int
app_queue_poller(void *ctx)
{
	svm_msg_q_msg_t msg;
	if (!svm_msg_q_is_empty(g_svm.app_event_queue)) {
		svm_msg_q_sub(g_svm.app_event_queue, &msg, SVM_Q_WAIT, 0);
		svm_msg_q_free_msg(g_svm.app_event_queue, &msg);
	}

	return 0;
}

/* This is required until sock.c API changes to asynchronous */
static int
_wait_for_session_state_change(struct spdk_vpp_session *session, enum spdk_vpp_session_state state)
{
	time_t start = time(NULL);
	while (time(NULL) - start < 10) {
		if (session->app_session.session_state == VPP_SESSION_STATE_FAILED) {
			errno = EADDRNOTAVAIL;
			return -1;
		}
		if (session->app_session.session_state == state) {
			errno = 0;
			return 0;
		}
		if (spdk_get_thread() == g_svm.init_thread) {
			usleep(100000);
			app_queue_poller(NULL);
			vpp_queue_poller(NULL);
		}
	}
	/* timeout */
	errno = ETIMEDOUT;
	return -1;
}

static int
_spdk_vpp_session_connect(struct spdk_vpp_session *session)
{
	vl_api_connect_sock_t *cmp;

	cmp = vl_msg_api_alloc(sizeof(*cmp));
	if (cmp == NULL) {
		return -ENOMEM;
	}
	memset(ump, 0, sizeof(*ump));
	memset(cmp, 0, sizeof(*cmp));

	ump->_vl_msg_id = ntohs(VL_API_UNBIND_SOCK);
	ump->client_index = g_svm.my_client_index;
	ump->handle = session->handle;
	ump->context = session->id;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&ump);
	cmp->_vl_msg_id = ntohs(VL_API_CONNECT_SOCK);
	cmp->client_index = g_svm.my_client_index;
	cmp->context = session->id;

	return _wait_for_session_state_change(session, VPP_SESSION_STATE_CLOSE);
	cmp->vrf = 0 /* VPPCOM_VRF_DEFAULT */;
	cmp->is_ip4 = (session->app_session.transport.is_ip4);
	memcpy(cmp->ip, &session->app_session.transport.rmt_ip, sizeof(cmp->ip));
	cmp->port = session->app_session.transport.rmt_port;
	cmp->proto = TRANSPORT_PROTO_TCP;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&cmp);

	return _wait_for_session_state_change(session, VPP_SESSION_STATE_READY);
}

/******************************************************************************
 * Accept session
 */
static void
vl_api_accept_session_t_handler(vl_api_accept_session_t *mp)
vl_api_disconnect_session_reply_t_handler(vl_api_disconnect_session_reply_t *mp)
{
	svm_fifo_t *rx_fifo, *tx_fifo;
	struct spdk_vpp_session *client_session, *listen_session;
	struct spdk_vpp_session *session;

	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "listeners handle is %" PRIu64 "\n", mp->listener_handle);
	if (mp->retval) {
		SPDK_ERRLOG("Disconnecting session failed (%d).\n", ntohl(mp->retval));
		return;
	}

	pthread_mutex_lock(&g_svm.session_get_lock);
	listen_session = _spdk_vpp_session_get_by_handle(mp->listener_handle, true);
	session = _spdk_vpp_session_get_by_handle(mp->handle, false);
	if (session == NULL) {
		SPDK_ERRLOG("Invalid session handler (%" PRIu64 ").\n", mp->handle);
		pthread_mutex_unlock(&g_svm.session_get_lock);
	if (!listen_session) {
		SPDK_ERRLOG("Listener not found\n");
		return;
	}

	/* Allocate local session for a client and set it up */
	client_session = _spdk_vpp_session_create();
	if (client_session == NULL) {
		SPDK_ERRLOG("Cannot create new session\n");
		return;
	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Session disconnected %p (%d)\n", session, session->id);
	session->app_session.session_state = VPP_SESSION_STATE_CLOSE;
	pthread_mutex_unlock(&g_svm.session_get_lock);
}

	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Accept session %p (%d) on %p (%d/%" PRIu64 ")\n",
		      client_session, client_session->id, listen_session, listen_session->id,
		      listen_session->handle);
static int
_spdk_vpp_session_disconnect(struct spdk_vpp_session *session)
{
	int rv = 0;
	vl_api_disconnect_session_t *dmp;
	vl_api_disconnect_session_reply_t *rmp;

	rx_fifo = uword_to_pointer(mp->server_rx_fifo, svm_fifo_t *);
	rx_fifo->client_session_index = client_session->id;
	tx_fifo = uword_to_pointer(mp->server_tx_fifo, svm_fifo_t *);
	tx_fifo->client_session_index = client_session->id;
	if (session->app_session.session_state == VPP_SESSION_STATE_DISCONNECT) {
		SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Session is already in disconnecting state %p (%d)\n",
			      session, session->id);

	client_session->handle = mp->handle;
	client_session->context = mp->context;
	client_session->app_session.rx_fifo = rx_fifo;
	client_session->app_session.tx_fifo = tx_fifo;
	client_session->app_session.vpp_evt_q = uword_to_pointer(mp->vpp_event_queue_address,
						svm_msg_q_t *);
		rmp = vl_msg_api_alloc(sizeof(*rmp));
		if (rmp == NULL) {
			return -ENOMEM;
		}
		memset(rmp, 0, sizeof(*rmp));

	client_session->is_server = true;
	client_session->app_session.transport.rmt_port = mp->port;
	client_session->app_session.transport.is_ip4 = mp->is_ip4;
	memcpy(&client_session->app_session.transport.rmt_ip, mp->ip, sizeof(mp->ip));
		rmp->_vl_msg_id = ntohs(VL_API_DISCONNECT_SESSION_REPLY);
		rmp->retval = rv;
		rmp->handle = session->handle;
		vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&rmp);
		return 0;
	}
	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Disconnect session %p (%d)\n", session, session->id);

	client_session->app_session.transport.lcl_port = listen_session->app_session.transport.lcl_port;
	memcpy(&client_session->app_session.transport.lcl_ip, &listen_session->app_session.transport.lcl_ip,
	       sizeof(listen_session->app_session.transport.lcl_ip));
	client_session->app_session.transport.is_ip4 = listen_session->app_session.transport.is_ip4;
	dmp = vl_msg_api_alloc(sizeof(*dmp));
	if (dmp == NULL) {
		return -ENOMEM;
	}
	memset(dmp, 0, sizeof(*dmp));
	dmp->_vl_msg_id = ntohs(VL_API_DISCONNECT_SESSION);
	dmp->client_index = g_svm.my_client_index;
	dmp->handle = session->handle;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&dmp);

	client_session->app_session.session_state = VPP_SESSION_STATE_READY;
	return _wait_for_session_state_change(session, VPP_SESSION_STATE_CLOSE);
}

	pthread_mutex_lock(&listen_session->accept_session_lock);
static int
_spdk_send_unbind_sock(struct spdk_vpp_session *session)
{
	vl_api_unbind_sock_t *ump;

	clib_fifo_add1(listen_session->accept_session_index_fifo,
		       client_session->id);
	SPDK_DEBUGLOG(SPDK_SOCK_VPP, "Unbind session %p (%d) request\n", session, session->id);

	pthread_mutex_unlock(&listen_session->accept_session_lock);
	ump = vl_msg_api_alloc(sizeof(*ump));
	if (ump == NULL) {
		return -ENOMEM;
	}
	memset(ump, 0, sizeof(*ump));

	ump->_vl_msg_id = ntohs(VL_API_UNBIND_SOCK);
	ump->client_index = g_svm.my_client_index;
	ump->handle = session->handle;
	ump->context = session->id;
	vl_msg_api_send_shmem(g_svm.vl_input_queue, (u8 *)&ump);

	return _wait_for_session_state_change(session, VPP_SESSION_STATE_CLOSE);
}

static int