diff options
Diffstat (limited to 'stacks/lwip_stack/lwip_src/api')
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_api.c | 51 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_api_msg.c | 3329 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_netbuf.c | 58 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_netifapi.c | 288 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_sbr.c | 495 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/api/spl_tcpip.c | 1547 |
6 files changed, 0 insertions, 5768 deletions
diff --git a/stacks/lwip_stack/lwip_src/api/spl_api.c b/stacks/lwip_stack/lwip_src/api/spl_api.c deleted file mode 100644 index 5c8af7d..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_api.c +++ /dev/null @@ -1,51 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "nsfw_init.h" -//#include "sockets.h" -//#include <netinet/in.h> - -#include "stackx_spl_share.h" -#include "stackx/spl_api.h" -//#include "stackx/ip.h" -#include "sharedmemory.h" -#include "spl_hal.h" -#include "hal_api.h" -#include "alarm_api.h" -#include "nsfw_mt_config.h" -#include "nsfw_recycle_api.h" -#include "nstack_dmm_adpt.h" - -/* main entry for stackx */ -int -spl_main_init (void *args) -{ - (void) args; - if (init_by_main_thread () < 0) - { - return -1; - } - - return 0; -} - -/* *INDENT-OFF* */ -NSFW_MODULE_NAME ("STACKX_MAIN") -NSFW_MODULE_PRIORITY (10) -NSFW_MODULE_DEPENDS (NSFW_ALARM_MODULE) -NSFW_MODULE_DEPENDS (NSTACK_DMM_MODULE) -NSFW_MODULE_INIT (spl_main_init) -/* *INDENT-ON* */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_api_msg.c b/stacks/lwip_stack/lwip_src/api/spl_api_msg.c deleted file mode 100644 index b7ea24b..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_api_msg.c +++ /dev/null @@ -1,3329 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "nsfw_msg.h" -#include "spl_opt.h" -#include "spl_ip_addr.h" -//#include "stackx_socket.h" -#include "cpuid.h" -//#include "sockets.h" -#include <netinet/in.h> -#include <errno.h> -#include <netinet/tcp.h> - -#include "stackx_prot_com.h" -#include "spl_api.h" -//#include "stackx/ip.h" -#include "sc_dpdk.h" -#include "spl_sbr.h" -//#include "maintain/spl_dfx.h" -#include "stackx_tx_box.h" -#include "spl_instance.h" -#include "spl_sockets.h" - -#include "nstack_dmm_adpt.h" - -#include "tcp.h" -#include "udp.h" -#include "pbuf.h" -#include "tcp_priv.h" -#include "init.h" -#include "timeouts.h" - -#include "stackx_pbuf_comm.h" -#include "spl_netbuf.h" -#include "spl_hal.h" -#include "sys_arch.h" -#include "tcpip.h" -#include "debug.h" -#ifdef HAL_LIB -#else -#include "rte_memcpy.h" -#endif - -extern struct tcp_pcb *tcp_bound_pcbs; -extern union tcp_listen_pcbs_t tcp_listen_pcbs; -extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a - state in which they accept or send - data. */ -extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ -extern struct tcp_pcb **const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; -extern stackx_instance *p_def_stack_instance; -extern u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; - -#define TCP_FN_NULL 0 -#define TCP_FN_DEFAULT 1 -#define TCP_FN_STACKX 2 -#define TCP_FN_MAX 3 - -struct callback_fn tcp_fn[TCP_FN_MAX] = { - {NULL, NULL, NULL, NULL, NULL, NULL, NULL}, - {NULL, spl_tcp_recv_null, NULL, NULL, NULL, NULL}, - {spl_sent_tcp, spl_recv_tcp, spl_do_connected, spl_poll_tcp, spl_err_tcp, - NULL, spl_accept_function}, -}; - -// extern int nstack_get_nstack_fd_snapshot_from_proto_fd(int proto_fd); -extern void tcp_drop_conn (spl_netconn_t * conn); -extern void unlink_pcb (struct common_pcb *cpcb); -extern struct queue *get_msgbox (int tos); - -#define SPL_SET_NONBLOCKING_CONNECT(conn, val) \ -do { \ - if (val) \ - { \ - (conn)->flags |= SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ - } \ - else \ - { \ - (conn)->flags &= ~SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ - } \ - } while (0) - -#define SPL_IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) - -extern int tcpip_thread_control; - -void -spl_event_callback (struct spl_netconn *conn, enum spl_netconn_evt evt, - int postFlag) -{ - NSPOL_LOGDBG (SOCK_INFO, "Get event]conn=%p,evt=%d,postFlag=%d", conn, evt, - postFlag); - /* Get socket */ - if (!conn) - { - NSPOL_LOGDBG (SOCK_INFO, "conn=NULL"); - return; - } - - switch (evt) - { - case SPL_NETCONN_EVT_RCVPLUS: - __sync_fetch_and_add (&conn->rcvevent, 1); - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); - } - break; - case SPL_NETCONN_EVT_RCVMINUS: // This will never be reached - __sync_fetch_and_sub (&conn->rcvevent, 1); - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); - } - break; - case SPL_NETCONN_EVT_SENDPLUS: - conn->sendevent = 1; - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLOUT); - } - break; - case SPL_NETCONN_EVT_SENDMINUS: - conn->sendevent = 0; - - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLOUT); - } - break; - case SPL_NETCONN_EVT_ERROR: - conn->errevent |= EPOLLERR; - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); - conn->errevent = 0; - } - break; -#if 1 - case SPL_NETCONN_EVT_ACCEPT: - __sync_fetch_and_add (&conn->rcvevent, 1); - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); - } - break; - - case SPL_NETCONN_EVT_HUP: - conn->errevent |= EPOLLHUP; - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); - conn->errevent = 0; - } - break; - case SPL_NETCONN_EVT_RDHUP: - conn->errevent |= EPOLLRDHUP; - if ((conn->epoll_flag) && (postFlag)) - { - nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); - conn->errevent = 0; - } - break; -#endif - - default: - NSTCP_LOGERR ("unknown event]conn=%p,event=%d", conn, evt); - return; - } - return; -} - -u8 -get_shut_op (data_com_msg * m) -{ - if (m && m->param.module_type == MSG_MODULE_SBR - && m->param.major_type == SPL_TCPIP_NEW_MSG_API) - { - if (m->param.minor_type == SPL_API_DO_CLOSE) - return ((msg_close *) (m->buffer))->shut; - - if (m->param.minor_type == SPL_API_DO_DELCON) - return ((msg_delete_netconn *) (m->buffer))->shut; - } - - return SPL_NETCONN_SHUT_RDWR; -} - -/* - Never using head/tail to judge whether need to do enque/deque, just do enque&deque, the return val will tell you ring is full/empty or not - rtp_perf_ring never provid ring_full/ring_empty function; - one more thing the rtp_ring_enque/deque result must be checked. -*/ -err_t -accept_enqueue (spl_netconn_t * conn, void *p) -{ - if (conn == NULL) - { - NSPOL_LOGERR ("accept_enqueue: invalid input]conn=%p", conn); - return ERR_VAL; - } - - NSPOL_LOGDBG (NEW_RING_DEBUG, "accept_enqueue]conn=%p,p=%p", conn, p); - mring_handle ring = conn->recv_ring; - if (NULL == ring) - { - NSPOL_LOGERR ("conn=%p accept new conn=%p enqueue ring addr is null", - conn, p); - return ERR_VAL; - } - - err_t retVal = ERR_MEM; - int enQSucCnt = 0; - int nTryCnt = 0; - do - { - enQSucCnt = nsfw_mem_ring_enqueue (ring, (void *) p); - if (1 == enQSucCnt) - { - retVal = ERR_OK; - break; - } - else if (0 == enQSucCnt) - { - sys_sleep_ns (0, 3000); - nTryCnt++; - } - else - { - retVal = ERR_VAL; - break; - } - } - while (nTryCnt < MAX_TRY_GET_MEMORY_TIMES); - - return retVal; -} - -err_t -accept_dequeue (spl_netconn_t * lconn, void **new_buf, - u32_t timeout /*miliseconds */ ) -{ - struct timespec starttm; - struct timespec endtm; - long timediff; - long timediff_sec; - u32_t timeout_sec = timeout / 1000; - -#define FAST_SLEEP_TIME 10000 -#define SLOW_SLEEP_TIME 500000 -#define FAST_RETRY_COUNT 100 - unsigned int retry_count = 0; - - if (NULL == lconn || NULL == new_buf) - { - NSPOL_LOGERR ("accept_dequeue invalid input]conn=%p,newbuf=%p", lconn, - new_buf); - return ERR_ARG; - } - - if (timeout != 0) - { - /* Handle system time change side-effects */ - if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm))) - { - //NSPOL_LOGERR("Failed to get time]errno=%d", errno); - } - } - - mring_handle ring = lconn->recv_ring; - if (ring == NULL) - { - NSPOL_LOGERR ("Get rtp_perf_ring failed]conn=%p", lconn); - return ERR_ARG; - } - - int nDequeRt; - int retVal; - while (1) - { - if ((lconn->shut_status) && (-1 != (int) timeout)) - { - retVal = ERR_VAL; - break; - } - - nDequeRt = nsfw_mem_ring_dequeue (ring, new_buf); - if (nDequeRt == 1) - { - retVal = ERR_OK; - break; - } - else if (nDequeRt == 0) - { - if ((int) timeout == -1) - { - retVal = ERR_WOULDBLOCK; - break; - } - - if (timeout != 0) - { - /* Handle system time change side-effects */ - if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &endtm))) - { - //NSPOL_LOGERR("Failed to get time, errno = %d", errno); - } - timediff_sec = endtm.tv_sec - starttm.tv_sec; - if (timediff_sec >= timeout_sec) - { - timediff = endtm.tv_nsec > starttm.tv_nsec ? - (timediff_sec * 1000) + (endtm.tv_nsec - - starttm.tv_nsec) / - USEC_TO_SEC : (timediff_sec * 1000) - - ((starttm.tv_nsec - endtm.tv_nsec) / USEC_TO_SEC); - - /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value - will be negetive if still 0.5 ms is not elapsed. this is intended and we should - not typecast to any unsigned type during this below if check */ - if (timediff > (long) timeout) - { - retVal = ERR_TIMEOUT; - break; - } - } - } - - /* reduce CPU usage in blocking mode */ - if (retry_count < FAST_RETRY_COUNT) - { - sys_sleep_ns (0, FAST_SLEEP_TIME); - retry_count++; - } - else - { - sys_sleep_ns (0, SLOW_SLEEP_TIME); - } - - continue; - } - else - { - retVal = ERR_VAL; - break; - } - } - - return retVal; -} - -err_t -sp_enqueue (struct common_pcb * cpcb, void *p) -{ - mring_handle ring = NULL; - spl_netconn_t *conn = NULL; - int enQueRet = 0; - - if (cpcb == NULL || (NULL == (conn = cpcb->conn))) - { - NSTCP_LOGERR ("conn NULL!"); - return ERR_VAL; - } - - NSPOL_LOGDBG (NEW_RING_DEBUG, "]conn=%p,buf=%p", cpcb->conn, p); - ring = conn->recv_ring; - if (NULL == ring) - { - NSPOL_LOGERR ("Get rtp_perf_ring failed]conn=%p.", conn); - return ERR_CLSD; - } - - /* clear LOOP_SEND_FLAG to indicate that this pbuf has been given to upper layer */ - struct spl_pbuf *tmpbuf = p; - while (tmpbuf) - { - tmpbuf->res_chk.u8Reserve &= ~LOOP_SEND_FLAG; - tmpbuf = tmpbuf->next; - } - - enQueRet = nsfw_mem_ring_enqueue (ring, p); - if (1 != enQueRet) - { - NS_LOG_CTRL (LOG_CTRL_RECV_QUEUE_FULL, LOGTCP, "NSTCP", NSLOG_WAR, - "ringvbox_enqueue buf is full]conn=%p.", conn); - - return ERR_MEM; - } - - return ERR_OK; -} - -/** - * Receive callback function for UDP netconns. - * Posts the packet to conn->recvmbox or deletes it on memory error. - * - * @see udp.h (struct udp_pcb.recv) for parameters - */ - -static void -spl_recv_udp (void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t * ipaddr, u16_t port) -{ - struct spl_netbuf *buf; - spl_netconn_t *conn = (spl_netconn_t *) arg; - struct spl_pbuf *spl_pb = NULL; //?? - - if (NULL == pcb) - { - NSPOL_LOGERR ("recv_udp must have a pcb argument"); - pbuf_free (p); - return; - } - - if (NULL == arg) - { - NSPOL_LOGERR ("recv_udp must have an argument"); - pbuf_free (p); - return; - } - /* //@TODO: malloc and Copy splbuf */ - struct common_pcb *cpcb = (struct common_pcb *) (conn->comm_pcb_data); - - u16_t proc_id = spl_get_lcore_id (); - - spl_pb = spl_pbuf_alloc_hugepage (SPL_PBUF_TRANSPORT, - p->tot_len + - g_offSetArry[SPL_PBUF_TRANSPORT], - SPL_PBUF_HUGE, proc_id, conn); - - if (!spl_pb) - { - NSPOL_LOGINF (TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); - return; - } - - pbuf_to_splpbuf_copy (spl_pb, p); - pbuf_free (p); - - buf = (struct spl_netbuf *) ((char *) spl_pb + sizeof (struct spl_pbuf)); - buf->p = spl_pb; - spl_ip_addr_set (&buf->addr, ipaddr); - buf->port = port; - - err_t ret = sp_enqueue (cpcb, (void *) spl_pb); - if (ret != ERR_OK) - { - NSPOL_LOGDBG (UDP_DEBUG, "mbox post failed"); - spl_netbuf_delete (buf); - return; - } - else - { - /* Register event with callback */ - NSPOL_LOGDBG (UDP_DEBUG | LWIP_DBG_TRACE, - "recv a udp packet: and api_event"); - SPL_API_EVENT (cpcb->conn, SPL_NETCONN_EVT_RCVPLUS, 1); - } -} - -/** - * Receive callback function for TCP netconns. - * Posts the packet to conn->recvmbox, but doesn't delete it on errors. - * - * @see tcp.h (struct tcp_pcb.recv) for parameters and return value - */ - -err_t -spl_recv_tcp (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct spl_pbuf *spl_pb = NULL; - u32_t len; - - if (NULL == pcb) - { - NSTCP_LOGERR ("recv_tcp must have a pcb argument"); - pbuf_free (p); - return ERR_ARG; - } - - if (NULL == arg) - { - NSTCP_LOGERR ("must have an argument]pcb=%p", pcb); - pbuf_free (p); - return ERR_ARG; - } - - spl_netconn_t *conn = (spl_netconn_t *) arg; - - /* Unlike for UDP or RAW pcbs, don't check for available space - using recv_avail since that could break the connection - (data is already ACKed) */ - /* don't overwrite fatal errors! */ - (void) err; - if (p == NULL) - { - return ERR_OK; - } - - len = p->tot_len; - - u16_t proc_id = spl_get_lcore_id (); - - spl_pb = spl_pbuf_alloc_hugepage (SPL_PBUF_TRANSPORT, - p->tot_len + - g_offSetArry[SPL_PBUF_TRANSPORT], - SPL_PBUF_HUGE, proc_id, conn); - - if (!spl_pb) - { - NSPOL_LOGINF (TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); - return ERR_MEM; - } - - pbuf_to_splpbuf_copy (spl_pb, p); - pbuf_free (p); - - if (sp_enqueue ((struct common_pcb *) conn->comm_pcb_data, (void *) spl_pb) - != ERR_OK) - { - NSPOL_LOGDBG (TCP_DEBUG, "sp_enqueue!=ERR_OK]conn=%p", conn); - spl_pbuf_free (spl_pb); - return ERR_MEM; - } - - SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 1); - conn->recv_avail_prod += len; - - return ERR_OK; -} - -/** - * Poll callback function for TCP netconns. - * Wakes up an application thread that waits for a connection to close - * or data to be sent. The application thread then takes the - * appropriate action to go on. - * - * Signals the conn->sem. - * netconn_close waits for conn->sem if closing failed. - * - * @see tcp.h (struct tcp_pcb.poll) for parameters and return value - */ -err_t -spl_poll_tcp (void *arg, struct tcp_pcb * pcb) -{ - spl_netconn_t *conn = (spl_netconn_t *) arg; - struct tcp_pcb *tpcb = NULL; - - if (NULL == conn) - { - NSPOL_LOGERR ("conn==NULL"); - return ERR_VAL; - } - - if (conn->state == SPL_NETCONN_WRITE) - { - (void) do_writemore (conn); - - /* do_close_internal, can release th PCB - and connection CB. so checking NETCONN_FLAG_CHECK_WRITESPACE should not be - done after do_close_internal. anyway this flag is used with data send.(do_writemore) */ - /* Did a nonblocking write fail before? Then check available write-space. */ - if (conn->flags & SPL_NETCONN_FLAG_CHECK_WRITESPACE) - { - tpcb = (struct tcp_pcb *) conn->private_data; - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((tpcb != NULL) && (tcp_sndbuf (tpcb) > TCP_SNDLOWAT) && - (tcp_sndqueuelen (tpcb) < TCP_SNDQUEUELOWAT)) - { - conn->flags &= ~SPL_NETCONN_FLAG_CHECK_WRITESPACE; - SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); - } - } - } - else if (conn->state == SPL_NETCONN_CLOSE) - { - (void) do_close_internal ((struct common_pcb *) conn->comm_pcb_data, 0); - } - - /* @todo: implement connect timeout here? */ - return ERR_OK; -} - -/** - * Default receive callback that is called if the user didn't register - * a recv callback for the pcb. - */ -err_t -spl_tcp_recv_null (void *arg, struct tcp_pcb * pcb, struct pbuf * p, - err_t err) -{ - LWIP_UNUSED_ARG (arg); - - if (p != NULL) - { - tcp_recved (pcb, p->tot_len); - pbuf_free (p); - } - else if (err == ERR_OK) - { - return tcp_close (pcb); - } - - return ERR_OK; -} - -/** - * Sent callback function for TCP netconns. - * Signals the conn->sem and calls API_EVENT. - * netconn_write waits for conn->sem if send buffer is low. - * - * @see tcp.h (struct tcp_pcb.sent) for parameters and return value - */ -err_t -spl_sent_tcp (void *arg, struct tcp_pcb * pcb, u16_t len) -{ - spl_netconn_t *conn = (spl_netconn_t *) arg; - - if (NULL == conn) - { - NSPOL_LOGERR ("conn==NULL"); - return ERR_VAL; - } - - if (conn->state == SPL_NETCONN_WRITE) - { - (void) do_writemore (conn); - } - else if (conn->state == SPL_NETCONN_CLOSE) - { - (void) do_close_internal ((struct common_pcb *) conn->comm_pcb_data, 0); - } - - /* conn is already checked for NULL above with ASSERT */ - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if (pcb->snd_buf > TCP_SNDLOWAT) - { - conn->flags &= ~SPL_NETCONN_FLAG_CHECK_WRITESPACE; - if (((struct common_pcb *) conn->comm_pcb_data)->model == SOCKET_STACKX) - SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); - } - - return ERR_OK; -} - -/** - * Error callback function for TCP netconns. - * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. - * The application thread has then to decide what to do. - * - * @see tcp.h (struct tcp_pcb.err) for parameters - */ -void -spl_err_tcp (void *arg, err_t err) -{ - spl_netconn_t *conn; - enum spl_netconn_state old_state; - data_com_msg *forFree = NULL; - - struct common_pcb *cpcb; - - NSTCP_LOGINF ("Enter err_tcp."); - - conn = (spl_netconn_t *) arg; - cpcb = (struct common_pcb *) (conn->comm_pcb_data); - - old_state = conn->state; - conn->state = SPL_NETCONN_NONE; - - /* Call unlink pcb no matter what */ - unlink_pcb (cpcb); - if (old_state == SPL_NETCONN_CLOSE) - { - /* RST during close: let close return success & dealloc the netconn */ - err = ERR_OK; - SPL_NETCONN_SET_SAFE_ERR (conn, ERR_OK); - } - else - { - SPL_NETCONN_SET_SAFE_ERR (conn, err); - } - - NSTCP_LOGWAR ("inform HUP and ERROR event."); - SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 0); - SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 0); - SPL_API_EVENT (conn, SPL_NETCONN_EVT_ERROR, 0); - SPL_API_EVENT (conn, SPL_NETCONN_EVT_HUP, 1); - - if ((old_state == SPL_NETCONN_WRITE) || (old_state == SPL_NETCONN_CLOSE) - || (old_state == SPL_NETCONN_CONNECT)) - { - int was_nonblocking_connect = spl_netconn_is_nonblocking (conn); - SPL_SET_NONBLOCKING_CONNECT (conn, 0); - - if (!was_nonblocking_connect) - { - /* set error return code */ - if (NULL == cpcb->current_msg) - { - NSPOL_LOGERR ("conn->current_msg==NULL"); - return; - } - - /* current msg could be connect msg or write_buf_msg */ - SET_MSG_ERR (cpcb->current_msg, err); - /* signal app to exit */ - if (old_state == SPL_NETCONN_CONNECT - && !spl_netconn_is_nonblocking (conn)) - { - SYNC_MSG_ACK (cpcb->current_msg); - } - - /* no matter it's connect msg or write msg, we will no process it any more */ - cpcb->current_msg = NULL; - - /* but, if msg is write_buf_msg, then we should release the pbuf in msg */ - if (cpcb->msg_head != NULL) - { - /* current_msg should be write_buf_msg */ - msg_write_buf *tmp_msg = cpcb->msg_head; - while (tmp_msg != NULL) - { - - forFree = MSG_ENTRY (tmp_msg, data_com_msg, buffer); - spl_pbuf_free (tmp_msg->p); - tmp_msg = tmp_msg->next; - - // free msg - ASYNC_MSG_FREE (forFree); - } - cpcb->current_msg = NULL; - cpcb->msg_head = cpcb->msg_tail = NULL; - } - } - } - else - { - - } -} - -/** - * Setup a tcp_pcb with the correct callback function pointers - * and their arguments. - * - * @param conn the TCP netconn to setup - */ -NSTACK_STATIC void -setup_tcp (struct tcp_pcb *pcb, spl_netconn_t * conn) -{ - struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; - - /* callback have the same value as cpcb->conn */ - cpcb->conn = conn; - tcp_arg (pcb, (void *) conn); - tcp_recv (pcb, tcp_fn[TCP_FN_STACKX].recv_fn); - tcp_sent (pcb, tcp_fn[TCP_FN_STACKX].sent_fn); - tcp_poll (pcb, tcp_fn[TCP_FN_STACKX].poll_fn, 4); - tcp_err (pcb, tcp_fn[TCP_FN_STACKX].err_fn); - -} - -/** - * Accept callback function for TCP netconns. - * Allocates a new netconn and posts that to conn->acceptmbox. - * - * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value - */ -err_t -spl_accept_function (void *arg, struct tcp_pcb *newpcb, err_t err) -{ - spl_netconn_t *newconn; - spl_netconn_t *lconn = (spl_netconn_t *) arg; /* listen conneciton */ - struct common_pcb *cpcb = NULL; - - NSPOL_LOGDBG (API_MSG_DEBUG, "]state=%s", - tcp_debug_state_str (newpcb->state)); - - if (lconn == NULL) - { - NSPOL_LOGERR ("accept_function: conn is NULL"); - return ERR_VAL; - } - - /* We have to set the callback here even though - * the new socket is unknown. conn->socket is marked as -1. */ - newconn = ss_malloc_conn (lconn->conn_pool, SPL_NETCONN_TCP); - if (newconn == NULL) - { - NSPOL_LOGERR ("conn alloc failed"); - return ERR_MEM; - } - - cpcb = alloc_common_pcb (SPL_NETCONN_TCP); - if (cpcb == NULL) - { - return ERR_MEM; - } - - /* used by application to recycle conn */ - newconn->recycle.accept_from = lconn; - newconn->conn_pool = lconn->conn_pool; - - newconn->recv_obj = (i64) & newconn->private_data; - newconn->private_data = (i64) newpcb; - newconn->comm_pcb_data = (i64) cpcb; - - NSFW_LOGINF ("alloc accept conn]conn=%p,pcb=%p,lconn=%p", newconn, newpcb, - lconn); - newconn->shut_status = 0xFFFF; - newconn->last_err = ERR_OK; - newconn->CanNotReceive = 0; - newconn->flags = 0; - - newconn->state = SPL_NETCONN_NONE; - newconn->mss = newpcb->mss; - newconn->remote_ip.addr = newpcb->remote_ip.addr; - newconn->remote_port = newpcb->remote_port; - ss_set_local_ip (newconn, newpcb->local_ip.addr); - ss_set_local_port (newconn, newpcb->local_port); - - setup_tcp (newpcb, newconn); - newpcb->state = ESTABLISHED; - update_tcp_state (newconn, ESTABLISHED); - - /*Initialize flow control variables */ - newconn->tcp_sndbuf = CONN_TCP_MEM_DEF_LINE; - newconn->tcp_wmem_alloc_cnt = 0; - newconn->tcp_wmem_sbr_free_cnt = 0; - newconn->tcp_wmem_spl_free_cnt = 0; - newconn->snd_buf = 0; - - newconn->bind_thread_index = lconn->bind_thread_index; - ss_set_msg_box (newconn, - ss_get_instance_msg_box (newconn->bind_thread_index, 0)); - - /* no protection: when creating the pcb, the netconn is not yet known - to the application thread */ - newconn->last_err = err; - - NSPOL_LOGDBG (TCP_DEBUG, - "trypost]newconn=%p, tcp=%p state=%d conn state=%d ", newconn, - newpcb, newpcb->state, newconn->state); - if (accept_enqueue (lconn, (void *) newconn) != ERR_OK) - { - /* remove all references to this netconn from the pcb */ - NSPOL_LOGERR ("sp_enqueue!=ERR_OK]ring = %p", newconn->recv_ring); - - tcp_arg (newpcb, NULL); - tcp_recv (newpcb, tcp_fn[TCP_FN_NULL].recv_fn); - tcp_sent (newpcb, tcp_fn[TCP_FN_NULL].sent_fn); - tcp_poll (newpcb, tcp_fn[TCP_FN_NULL].poll_fn, 0); - tcp_err (newpcb, tcp_fn[TCP_FN_NULL].err_fn); - /* drop conn */ - tcp_drop_conn (newconn); - return ERR_MEM; - } - - SPL_API_EVENT (lconn, SPL_NETCONN_EVT_ACCEPT, 1); - /* tcp_accepted_with_return_value(newpcb); */ - - return ERR_OK; -} - -int -common_pcb_init (struct common_pcb *cpcb) -{ - // u32 threadnum = p_lwip_instance->rss_queue_id + 1;//0 for app - - cpcb->hostpid = get_sys_pid (); - - cpcb->socket = 0; - /* run and close repeatly nstackmain coredum */ - cpcb->close_progress = 0; - cpcb->model = SOCKET_STACKX; - cpcb->current_msg = NULL; - cpcb->msg_head = cpcb->msg_tail = NULL; - cpcb->write_offset = 0; - - cpcb->recv_timeout = cpcb->send_timeout = 0; - - cpcb->sk_rcvlowat = 1; - - cpcb->l4_tick = 0; - cpcb->dataSentFlag = 0; - cpcb->recv_ring_not_empty = 0; - - return 0; -} - -int -common_pcb_reset (struct common_pcb *cpcb) -{ - cpcb->conn = NULL; - cpcb->hostpid = 0; - - cpcb->socket = 0; - /* run and close repeatly nstackmain coredum */ - cpcb->close_progress = 0; - cpcb->model = 0; - cpcb->current_msg = NULL; - cpcb->msg_head = cpcb->msg_tail = NULL; - cpcb->write_offset = 0; - - cpcb->recv_timeout = cpcb->send_timeout = 0; - - cpcb->sk_rcvlowat = 0; - - cpcb->l4_tick = 0; - cpcb->dataSentFlag = 0; - cpcb->recv_ring_not_empty = 0; - - return 0; -} - -void -unlink_pcb (struct common_pcb *cpcb) -{ - if (cpcb && cpcb->conn) - { - /* whatever the private data will be reset */ - cpcb->conn->private_data = 0; - update_tcp_state (cpcb->conn, CLOSED); - } - else - { - NSPOL_LOGINF (API_MSG_DEBUG, "conn is detached already!"); - } -} - -void -unlink_recv_ring (spl_netconn_t * conn) -{ - if (conn) - conn->recv_ring_valid = 0; -} - -void -recycle_tmr (void *arg) -{ - if (arg == NULL) - { - NSPOL_LOGERR ("recycle_message is NULL!"); - } - else - { - (void) ss_recycle_conn (arg, do_try_delconn); - } -} - -/** - * Create a new pcb of a specific type. - * Called from do_newconn(). - * - * @param msg the api_msg_msg describing the connection type - * @return msg->conn->err, but the return value is currently ignored - */ -int -spl_pcb_new (msg_new_netconn * pmsg) -{ - u16_t thread_index = spl_get_lcore_id (); - struct common_pcb *cpcb = NULL; - enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; - - /* Allocate a PCB for this connection */ - switch (SPL_NETCONNTYPE_GROUP (pmsg->type)) - { - case SPL_NETCONN_UDP: - { - struct udp_pcb *u = udp_new_ip_type (iptype); - if (u == NULL) - { - return ERR_MEM; - } - - if (pmsg->type == SPL_NETCONN_UDPNOCHKSUM) - { - udp_setflags (u, UDP_FLAGS_NOCHKSUM); - } - - cpcb = (struct common_pcb *) alloc_common_pcb (SPL_NETCONN_UDP); - if (cpcb == NULL) - { - return ERR_MEM; - } - - pmsg->conn->comm_pcb_data = (i64) cpcb; - pmsg->conn->private_data = (i64) u; - udp_recv (u, spl_recv_udp, (void *) pmsg->conn); - break; - } - - case SPL_NETCONN_TCP: - { - struct tcp_pcb *t = tcp_new_ip_type (iptype); - if (t == NULL) - { - return ERR_MEM; - } - - cpcb = alloc_common_pcb (SPL_NETCONN_TCP); - if (cpcb == NULL) - { - return ERR_MEM; - } - - pmsg->conn->comm_pcb_data = (i64) cpcb; - pmsg->conn->private_data = (i64) t; - setup_tcp (t, pmsg->conn); - break; - } - - default: - /* Unsupported netconn type, e.g. protocol disabled */ - NSPOL_LOGERR ("Unsupported netconn type!"); - return ERR_VAL; - } - - /* type and socket value for all type */ - cpcb->socket = pmsg->socket; - cpcb->conn = pmsg->conn; - cpcb->bind_thread_index = thread_index; - - /* used to find pcb when a msg is received */ - return ERR_OK; -} - -/** - * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in - * these mboxes - * - * @param conn the netconn to free - * @bytes_drained bytes drained from recvmbox - * @accepts_drained pending connections drained from acceptmbox - */ -int -netconn_drain (enum spl_netconn_type type, spl_netconn_t * conn) -{ - int i, n; - mring_handle ring = NULL; - void *addr[32] = { 0 }; - int not_empty = 0; - - /* This runs in tcpip_thread, so we don't need to lock against rx packets */ - ring = conn->recv_ring; - do - { - /*every times get atmost 32 to release */ - n = nsfw_mem_ring_dequeuev (ring, addr, 32); - for (i = 0; i < n; i++) - { - /* if the con is UDP, buffer type also is struct spl_netbuf,it is same as RAW */ - if ((type == SPL_NETCONN_RAW) || (type == SPL_NETCONN_UDP)) - { - spl_pbuf_free ((struct spl_pbuf *) addr[i]); - if (type == SPL_NETCONN_UDP) - { - UDP_STATS_INC (udp.drop); - } - } - else - { - spl_pbuf_free ((struct spl_pbuf *) addr[i]); - } - - if (not_empty == 0) - not_empty = 1; - } - } - while (0 != n); - return not_empty; -} - -/* need free mbuf inside recv ring before free conn */ -void -free_conn_by_spl (spl_netconn_t * conn) -{ - struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; - - free_common_pcb (cpcb); - - (void) netconn_drain (conn->type, conn); - ss_free_conn (conn); -} - -int -do_close_finished (struct common_pcb *cpcb, u8_t close_finished, u8_t shut, - err_t err, int OpShutDown) -{ - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - spl_netconn_t *conn = cpcb->conn; - - if (!close_finished) - { - /* Closing succeeded */ - /* Closing failed, restore some of the callbacks */ - /* Closing of listen pcb will never fail! */ - if (LISTEN == tpcb->state) - { - NSPOL_LOGERR ("Closing a listen pcb may not fail!"); - return ERR_VAL; - } - - tcp_sent (tpcb, tcp_fn[TCP_FN_STACKX].sent_fn); - tcp_poll (tpcb, tcp_fn[TCP_FN_STACKX].poll_fn, 1); - tcp_err (tpcb, tcp_fn[TCP_FN_STACKX].err_fn); - tcp_arg (tpcb, conn); - /* don't restore recv callback: we don't want to receive any more data */ - } - else - { - /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ - if (cpcb->current_msg) - { - SET_MSG_ERR (cpcb->current_msg, err); - cpcb->current_msg = NULL; - } - - conn->state = SPL_NETCONN_NONE; - NSTCP_LOGINF ("release pcb]conn=%p,pcb=%p", conn, tpcb); - unlink_pcb (cpcb); - } - - return ERR_OK; -} - -NSTACK_STATIC void -reset_tcp_callback (struct tcp_pcb *tpcb, struct common_pcb *cpcb, u8 shut) -{ - spl_netconn_t *conn = cpcb->conn; - - /* some callbacks have to be reset if tcp_close is not successful */ - if (shut & SPL_NETCONN_SHUT_RD) - { - conn->CanNotReceive = 1; - tcp_recv (tpcb, tcp_fn[TCP_FN_NULL].recv_fn); - tcp_accept (tpcb, tcp_fn[TCP_FN_NULL].accept_fn); - } - - if (shut & SPL_NETCONN_SHUT_WR) - { - tcp_sent (tpcb, tcp_fn[TCP_FN_NULL].sent_fn); - } - - if (shut == SPL_NETCONN_SHUT_RDWR) - { - tcp_poll (tpcb, tcp_fn[TCP_FN_NULL].poll_fn, 0); - tcp_err (tpcb, tcp_fn[TCP_FN_NULL].err_fn); - } -} - -/** - * Internal helper function to close a TCP netconn: since this sometimes - * doesn't work at the first attempt, this function is called from multiple - * places. - * - * @param conn the TCP netconn to close - */ -err_t -do_close_internal (struct common_pcb *cpcb, int OpShutDown) -{ - err_t err; - u8_t shut, ucclose; - u8_t close_finished = 0; - - if (NULL == cpcb) - { - NSTCP_LOGERR ("invalid conn"); - return ERR_ARG; - } - - spl_netconn_t *conn = cpcb->conn; - if (SPL_NETCONN_TCP != cpcb->type || SPL_NETCONN_CLOSE != conn->state) - { - NSTCP_LOGERR ("conn=%p, err_type=%d, error_state=%d", - conn, cpcb->type, conn->state); - return ERR_VAL; - } - - struct tcp_pcb *tpcb = (struct tcp_pcb *) (conn->private_data); - - if (cpcb->current_msg != NULL) - shut = get_shut_op (cpcb->current_msg); - else - shut = SPL_NETCONN_SHUT_RDWR; - - /* shutting down both ends is the same as closing */ - ucclose = (shut == SPL_NETCONN_SHUT_RDWR); - - /* Set back some callback pointers */ - if (ucclose) - { - conn->CanNotReceive = 1; - tcp_arg (tpcb, conn); - } - - if (tpcb->state == LISTEN) - { - tcp_accept (tpcb, tcp_fn[TCP_FN_NULL].accept_fn); - } - else - { - reset_tcp_callback (tpcb, cpcb, shut); - } - - /* Try to close the connection */ - if (shut == SPL_NETCONN_SHUT_RDWR && !OpShutDown) - { - err = tcp_close (tpcb); - } - else - { - err = - tcp_shutdown (tpcb, shut & SPL_NETCONN_SHUT_RD, - shut & SPL_NETCONN_SHUT_WR); - } - - if (err == ERR_OK) - { - close_finished = 1; - } - else - { - if (err == ERR_MEM) - { - /* Blocking close, check the timeout */ - close_finished = 1; - if (ucclose) - { - /* in this case, we want to RST the connection */ - tcp_abort (tpcb); - err = ERR_OK; - } - } - else - { - /* Closing failed for a non-memory error: give up */ - close_finished = 1; - } - } - - err_t err1 = do_close_finished (cpcb, close_finished, - shut, err, OpShutDown); - if (err1 != ERR_OK) - { - NSTCP_LOGERR ("return err1]pcb=%p,err1=%d", tpcb, err1); - return err1; - } - return err; - - /* If closing didn't succeed, we get called again either - from poll_tcp or from sent_tcp */ -} - -void -do_try_delconn (void *close_data, u32 delay_sec) -{ - msg_delete_netconn *dmsg = (msg_delete_netconn *) close_data; - data_com_msg *m = MSG_ENTRY (dmsg, data_com_msg, buffer); - struct common_pcb *cpcb = NULL; - - spl_netconn_t *conn = dmsg->conn; - - /* no receiver in some recycle cases */ - if (0 == m->param.comm_receiver) - { - if (NULL == conn) - { - NSFW_LOGERR ("release err conn!]pid=%d", dmsg->pid); - /* need to free pbufs which are attached to msg */ - do_pbuf_free (dmsg->buf); - return; - } - - cpcb = (struct common_pcb *) conn->comm_pcb_data; - } - else - { - cpcb = COMM_PRIVATE_PTR (m); - } - - /* no pcb in some recycle cases */ - if (conn->private_data == 0) - { - /* though pcb is gone, still need to clean the mbox */ - if (conn != NULL) - (void) netconn_drain (conn->type, conn); - - NSFW_LOGWAR ("release conn pcb null]pcb=%p", m->param.receiver); - /* need to free pbufs which are attached to msg */ - do_pbuf_free (dmsg->buf); - return; - } - - if (delay_sec) - { - NSFW_LOGWAR ("delay to recycle!]pcb=%p, msg=%d", cpcb, dmsg); - sys_timeout (delay_sec * 1000, recycle_tmr, dmsg); - return; - } - - do_delconn (cpcb, dmsg); - - /* after the do_delconn, the PCB maybe released, but the conn is ok */ - sys_sem_s_signal (&dmsg->conn->close_completed); - - return; -} - -/** - * Delete the pcb inside a netconn. - * Called from netconn_delete. - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_delconn (struct common_pcb *cpcb, msg_delete_netconn * dmsg) -{ - spl_netconn_t *conn = cpcb->conn; - data_com_msg *pmsg = MSG_ENTRY (dmsg, data_com_msg, buffer); - - /*if already close, just return */ - /* run and close repeatly nstackmain coredum */ - if (1 == cpcb->close_progress) - { - SET_MSG_ERR (pmsg, ERR_OK); - return; - } - cpcb->close_progress = 1; - - /* Pbuf free should be done in network stack */ - do_pbuf_free (dmsg->buf); - - /* @todo TCP: abort running write/connect? */ - if ((conn->state != SPL_NETCONN_NONE) - && (conn->state != SPL_NETCONN_LISTEN) - && (conn->state != SPL_NETCONN_CONNECT)) - { - /* this only happens for TCP netconns */ - if (SPL_NETCONN_TCP != cpcb->type) - { - NSTCP_LOGERR ("msg->conn->type error!]conn=%p,msg->conn->type=%d", - conn, cpcb->type); - SET_MSG_ERR (pmsg, ERR_VAL); - return; - } - NSPOL_LOGINF (SOCK_INFO, "conn is not for free state]conn=%p,state=%d", - conn, conn->state); - - //need to release pcb - if (cpcb->current_msg != NULL && cpcb->msg_tail != NULL) - { - NSPOL_LOGINF (SOCK_INFO, - "conn there is data in conn->current_msg when close the conn]conn=%p,state=%d", - conn, conn->state); - (void) do_writemore (cpcb->conn); - } - } - - /* - the accpet connections waiting in listen queue will be clear in - netconn_drain. - */ - if (conn->state == SPL_NETCONN_LISTEN) - { - /* This function does nothing in original code. */ - } - else - { - /* Drain pbuf from non-listen mboxes */ - if (netconn_drain (cpcb->type, conn)) - { - cpcb->recv_ring_not_empty = 1; - - NSPOL_LOGWAR (SOCK_INFO, - "still some data leave in recv ring when close"); - } - } - - /* conn will be released outside */ - - switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) - { - - case SPL_NETCONN_UDP: - { - struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; - upcb->recv_arg = NULL; - udp_remove (upcb); - break; - } - - case SPL_NETCONN_TCP: - { - conn->state = SPL_NETCONN_CLOSE; - dmsg->shut = SPL_NETCONN_SHUT_RDWR; - cpcb->current_msg = pmsg; - - if (ERR_INPROGRESS == do_close_internal (cpcb, 0)) - { - return; - } - } - default: - break; - } - - /* tcp netconns don't come here! */ - -} - -/** - * Bind a pcb contained in a netconn - * Called from netconn_bind. - * - * @param msg the api_msg_msg pointing to the connection and containing - * the IPaddress and port to bind to - */ -void -do_bind (struct common_pcb *cpcb, msg_bind * bmsg) -{ - spl_netconn_t *conn = cpcb->conn; - data_com_msg *pmsg = MSG_ENTRY (bmsg, data_com_msg, buffer); - ip_addr_t stIpaddr; - - stIpaddr.addr = bmsg->ipaddr.addr; - - if (SPL_ERR_IS_FATAL (conn->last_err) - && ERR_CANTASSIGNADDR != conn->last_err) - { - NSTCP_LOGERR ("bind but conn has err]pcb=%p,conn=%p,err=%d", cpcb, conn, - conn->last_err); - SET_MSG_ERR (pmsg, conn->last_err); - } - else - { - if (!ip_addr_isany (&bmsg->ipaddr) - && !ip_addr_ismulticast (&bmsg->ipaddr)) - { - if (!get_netif_by_ip (bmsg->ipaddr.addr) - && !netif_check_broadcast_addr (&bmsg->ipaddr)) - { - NSPOL_LOGERR ("ip is not exist]pcb=%p,ip=%u", cpcb, - bmsg->ipaddr.addr); - SET_MSG_ERR (pmsg, ERR_CANTASSIGNADDR); - return; - } - } - - SET_MSG_ERR (pmsg, ERR_VAL); - switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) - { - case SPL_NETCONN_UDP: - SET_MSG_ERR (pmsg, - udp_bind ((struct udp_pcb *) (cpcb-> - conn->private_data), - &stIpaddr, bmsg->port)); - - /* Set local Ip, willbe used during connect */ - struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; - ss_set_local_ip (cpcb->conn, upcb->local_ip.addr); - ss_set_local_port (cpcb->conn, upcb->local_port); - NSTCP_LOGINF ("updated Ip to spl_netconn_t] %x", - upcb->local_ip.addr); - - NSUDP_LOGINF - ("udp_bind return]pcb=%p,IP=%u.%u.%u.%u,port=%u,err=%d", - (struct udp_pcb *) cpcb->conn->private_data, - &bmsg->ipaddr == NULL ? 0 : ip4_addr1_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr2_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr3_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr4_16 (&stIpaddr), bmsg->port, - GET_MSG_ERR (pmsg)); - break; - - case SPL_NETCONN_TCP: - SET_MSG_ERR (pmsg, - tcp_bind ((struct tcp_pcb *) cpcb->conn->private_data, - &stIpaddr, bmsg->port)); - - /* Set local Ip, willbe used during connect */ - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - NSTCP_LOGINF ("updated Ip to spl_netconn_t] %x", - tpcb->local_ip.addr); - ss_set_local_ip (cpcb->conn, tpcb->local_ip.addr); - ss_set_local_port (cpcb->conn, tpcb->local_port); - - NSTCP_LOGINF - ("tcp_bind return]pcb=%p,IP=%u.%u.%u.%u,port=%u,err=%d", - (struct tcp_pcb *) cpcb->conn->private_data, - &bmsg->ipaddr == NULL ? 0 : ip4_addr1_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr2_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr3_16 (&stIpaddr), - &bmsg->ipaddr == NULL ? 0 : ip4_addr4_16 (&stIpaddr), bmsg->port, - GET_MSG_ERR (pmsg)); - break; - default: - break; - } - } - - conn->last_err = GET_MSG_ERR (pmsg); - NSPOL_LOGDBG (TESTSOCKET_DEBUG | LWIP_DBG_TRACE, "the msg is doing bind"); - NSTCP_LOGINF ("the msg is doing bind"); -} - -/** - * TCP callback function if a connection (opened by tcp_connect/do_connect) has - * been established (or reset by the remote host). - * - * @see tcp.h (struct tcp_pcb.connected) for parameters and return values - */ -err_t -spl_do_connected (void *arg, struct tcp_pcb *pcb, err_t err) -{ - spl_netconn_t *conn = (spl_netconn_t *) arg; - struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; - data_com_msg *m = cpcb->current_msg; - int was_blocking; - - if (conn == NULL) - { - NSTCP_LOGERR ("conn is NULL!]arg=%p", arg); - return ERR_ARG; - } - - if (SPL_NETCONN_CONNECT != conn->state) - { - NSTCP_LOGERR ("conn->state error!]conn=%p,state=%d", conn, conn->state); - return ERR_VAL; - } - - if ((NULL == m) && (0 == spl_netconn_is_nonblocking (conn))) - { - NSTCP_LOGERR ("conn->current_msg!]conn=%p,current_msg=%p", conn, m); - return ERR_VAL; - } - - if (m != NULL) - { - SET_MSG_ERR (m, err); - } - - if ((cpcb->type == SPL_NETCONN_TCP) && (err == ERR_OK)) - { - setup_tcp (pcb, conn); - } - - ss_set_local_ip (conn, pcb->local_ip.addr); - ss_set_local_port (conn, pcb->local_port); - conn->remote_ip.addr = pcb->remote_ip.addr; - conn->remote_port = pcb->remote_port; - - conn->mss = pcb->mss; - cpcb->current_msg = NULL; - - was_blocking = !SPL_IN_NONBLOCKING_CONNECT (conn); - SPL_SET_NONBLOCKING_CONNECT (conn, 0); - conn->state = SPL_NETCONN_NONE; - SPL_NETCONN_SET_SAFE_ERR (conn, ERR_OK); - - update_tcp_state (pcb->callback_arg, ESTABLISHED); - SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); - - if (was_blocking && m != NULL) - { - SYNC_MSG_ACK (m); - } - - return ERR_OK; -} - -int -do_internal_tcp_connect (struct common_pcb *cpcb, struct tcp_pcb *tpcb, - msg_connect * cmsg) -{ - spl_netconn_t *conn = cpcb->conn; - data_com_msg *pmsg = MSG_ENTRY (cmsg, data_com_msg, buffer); - ip_addr_t ip_addr; - - ip_addr.addr = cmsg->ipaddr.addr; - - /* Prevent connect while doing any other action. */ - if (conn->state != SPL_NETCONN_NONE) - { - if (conn->state == SPL_NETCONN_CONNECT - || conn->state == SPL_NETCONN_WRITE) - { - if (tpcb->state != ESTABLISHED) - { - SET_MSG_ERR (pmsg, ERR_ALREADY); - } - else - { - SET_MSG_ERR (pmsg, ERR_ISCONN); - } - } - else - { - SET_MSG_ERR (pmsg, ERR_ISCONN); - } - - NSTCP_LOGINF - ("tcp_connect]pcb=%p,state=%d,remote_ip=%u.%u.%u.%u,remote_port=%u,local_ip=%u.%u.%u.%u,local_port=%u,err=%d", - tpcb, conn->state, ip4_addr1_16 (&ip_addr), ip4_addr2_16 (&ip_addr), - ip4_addr3_16 (&ip_addr), ip4_addr4_16 (&ip_addr), cmsg->port, - ip4_addr1_16 (&tpcb->local_ip), ip4_addr2_16 (&tpcb->local_ip), - ip4_addr3_16 (&tpcb->local_ip), ip4_addr4_16 (&tpcb->local_ip), - tpcb->local_port, GET_MSG_ERR (pmsg)); - } - else - { - setup_tcp (tpcb, conn); - SET_MSG_ERR (pmsg, - tcp_connect (tpcb, &ip_addr, cmsg->port, - tcp_fn[TCP_FN_STACKX].connected_fn)); - conn->mss = tpcb->mss; - SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); - SPL_API_EVENT (conn, NETCONN_EVT_RCVMINUS, 1); - - NSTCP_LOGINF - ("tcp_connect]pcb=%p,state=%d,remote_ip=%u.%u.%u.%u,remote_port=%u,local_ip=%u.%u.%u.%u,local_port=%u,err=%d", - tpcb, conn->state, ip4_addr1_16 (&ip_addr), ip4_addr2_16 (&ip_addr), - ip4_addr3_16 (&ip_addr), ip4_addr4_16 (&ip_addr), cmsg->port, - ip4_addr1_16 (&tpcb->local_ip), ip4_addr2_16 (&tpcb->local_ip), - ip4_addr3_16 (&tpcb->local_ip), ip4_addr4_16 (&tpcb->local_ip), - tpcb->local_port, GET_MSG_ERR (pmsg)); - if (GET_MSG_ERR (pmsg) == ERR_OK) - { - int nonblock = spl_netconn_is_nonblocking (conn); - SPL_SET_NONBLOCKING_CONNECT (conn, nonblock); - conn->state = SPL_NETCONN_CONNECT; - if (nonblock) - { - SET_MSG_ERR (pmsg, ERR_INPROGRESS); - } - else - { - cpcb->current_msg = pmsg; - /* sys_sem_signal() is called from do_connected (or err_tcp()), - * when the connection is established! */ - return -1; - } - } - } - - return 0; -} - -/** - * Connect a pcb contained inside a netconn - * Called from netconn_connect. - * - * @param msg the api_msg_msg pointing to the connection and containing - * the IPaddress and port to connect to - */ -void -do_connect (struct common_pcb *cpcb, msg_connect * cmsg) -{ - data_com_msg *pmsg = MSG_ENTRY (cmsg, data_com_msg, buffer); - ip_addr_t ipaddr; - - SET_MSG_ERR (pmsg, ERR_OK); - - if (cpcb == NULL) - { - /* This may happen when calling netconn_connect() a second time */ - NSTCP_LOGERR ("conn connect but conn has err]msg=%p", pmsg); - SET_MSG_ERR (pmsg, ERR_CLSD); - return; - } - - ipaddr.addr = cmsg->ipaddr.addr; - switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) - { - case SPL_NETCONN_UDP: - { - struct udp_pcb *upcb = (struct udp_pcb *) (cpcb->conn->private_data); - if (ip_addr_isany (&upcb->local_ip)) - { - upcb->local_ip.addr = cmsg->local_ip.addr; - ss_set_local_ip (cpcb->conn, upcb->local_ip.addr); - } - - SET_MSG_ERR (pmsg, udp_connect (upcb, &ipaddr, cmsg->port)); - if (ERR_OK == pmsg->param.err) - { - cpcb->conn->remote_ip.addr = cmsg->ipaddr.addr; - cpcb->conn->remote_port = cmsg->port; - } - break; - } - case SPL_NETCONN_TCP: - { - struct tcp_pcb *tpcb = (struct tcp_pcb *) (cpcb->conn->private_data); - if (ip_addr_isany (&tpcb->local_ip)) - { - tpcb->local_ip.addr = cmsg->local_ip.addr; - ss_set_local_ip (cpcb->conn, tpcb->local_ip.addr); - } - - if (0 != do_internal_tcp_connect (cpcb, tpcb, cmsg)) - { - return; - } - - } - break; - default: - NSPOL_LOGERR ("Invalid netconn type]type=%d", cpcb->type); - SET_MSG_ERR (pmsg, ERR_VAL); - break; - } - - /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), - so use TCPIP_APIMSG_ACK() here. - Do as lwip-2.0.0. set conn->last_error here. */ - SPL_NETCONN_SET_SAFE_ERR (cpcb->conn, GET_MSG_ERR (pmsg)); -} - -/* Pbuf free should be done in network stack */ -void -do_pbuf_free (struct spl_pbuf *buf) -{ - if (buf) - { - struct spl_pbuf *pCur = buf; - while (buf) - { - pCur = buf; - buf = buf->freeNext; - spl_pbuf_free (pCur); - } - } -} - -/** - * Set a TCP pcb contained in a netconn into listen mode - * Called from netconn_listen. - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_listen (struct common_pcb *cpcb, msg_listen * lmsg) -{ - err_t err = ERR_OK; - spl_netconn_t *conn = cpcb->conn; - data_com_msg *pmsg = MSG_ENTRY (lmsg, data_com_msg, buffer); - - if (SPL_ERR_IS_FATAL (conn->last_err)) - { - NSTCP_LOGERR ("conn listern but conn has err]conn=%p,err=%d", - conn, conn->last_err); - SET_MSG_ERR (pmsg, conn->last_err); - } - else - { - SET_MSG_ERR (pmsg, ERR_CONN); - - if (cpcb->type == SPL_NETCONN_TCP) - { - if (conn->state == SPL_NETCONN_NONE) - { - struct tcp_pcb *lpcb; - if (((struct tcp_pcb *) (cpcb->conn->private_data))->state != - CLOSED) - { - /* connection is not closed, cannot listen */ - SET_MSG_ERR (pmsg, ERR_VAL);; - } - else - { - u8_t backlog = TCP_DEFAULT_LISTEN_BACKLOG; - - lpcb = - tcp_listen_with_backlog_and_err ((struct tcp_pcb - *) (cpcb-> - conn->private_data), - backlog, &err); - if (lpcb == NULL) - { - /* in this case, the old pcb is still allocated */ - SET_MSG_ERR (pmsg, err); - } - else - { - SET_MSG_ERR (pmsg, ERR_OK); - /* conn now is put on lpcb */ - conn->state = SPL_NETCONN_LISTEN; - - /* NOTE: pmsg->conn->comm_pcb_data == (i64)cpcb; should be already same. */ - conn->private_data = (i64) lpcb; - - tcp_arg (lpcb, conn); - tcp_accept (lpcb, tcp_fn[TCP_FN_STACKX].accept_fn); - - SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); - SPL_API_EVENT (conn, NETCONN_EVT_RCVMINUS, 1); - } - } - } - else if (conn->state == SPL_NETCONN_LISTEN) - { - SET_MSG_ERR (pmsg, ERR_OK); - } - } - NSTCP_LOGINF ("listen]conn=%p,pcb=%p,connstate=%d,err=%d", - conn, cpcb, conn->state, GET_MSG_ERR (pmsg)); - - } - -} - -/** - * Send some data on UDP pcb contained in a netconn - * Called from do_send - * - * @param msg the api_msg_msg pointing to the connection - */ -void -spl_udp_send (struct common_pcb *cpcb, msg_send_buf * smsg) -{ - struct spl_pbuf *p_from = smsg->p; - spl_netconn_t *conn = cpcb->conn; - struct udp_pcb *upcb = (struct udp_pcb *) (cpcb->conn->private_data); - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - struct pbuf *p_to = NULL; - err_t err = ERR_OK; - - //allocate pbuf and copy spl_pbuf, send , free pbuf and spl_pbuf - do - { - p_to = pbuf_alloc (PBUF_TRANSPORT, p_from->len, PBUF_RAM); - if (NULL == p_to) - { - NSPOL_LOGERR ("pbuf is NULL]conn=%p,pcb=%p", conn, upcb); - return; - } - - err = splpbuf_to_pbuf_transport_copy (p_to, p_from); - if (err != ERR_OK) - { - SET_MSG_ERR (m, conn->last_err); - return; - } - - if (ip_addr_isany (&smsg->addr)) - { - SET_MSG_ERR (m, udp_send (upcb, p_to)); - } - else - { - SET_MSG_ERR (m, - udp_sendto (upcb, p_to, (ip_addr_t *) & smsg->addr, - smsg->port)); - } - - p_from = (struct spl_pbuf *) ADDR_SHTOL (p_from->next_a); - } - while (p_from != NULL); - -} - -/** - * Send some data on a RAW or UDP pcb contained in a netconn - * Called from netconn_send - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_send (struct common_pcb *cpcb, msg_send_buf * smsg) -{ - struct spl_pbuf *p = smsg->p; - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - spl_netconn_t *conn = cpcb->conn; - - pbuf_set_recycle_flg (p, MBUF_HLD_BY_SPL); /* release buf hold by app on abnormal exit */ - - if (SPL_ERR_IS_FATAL (conn->last_err)) - { - SET_MSG_ERR (m, conn->last_err); - NSPOL_LOGERR ("Invalid param]msg->conn=%p", conn); - goto err_return; - } - - switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) - { - case SPL_NETCONN_UDP: - { - struct udp_pcb *upcb = (struct udp_pcb *) (cpcb->conn->private_data); - if (ip_addr_isany (&upcb->local_ip)) - { - upcb->local_ip.addr = smsg->local_ip.addr; - ss_set_local_ip (conn, smsg->local_ip.addr); - } - - spl_udp_send (cpcb, smsg); - - break; - } - - default: - SET_MSG_ERR (m, ERR_CONN); - break; - } - -err_return: - pbuf_free_safe (smsg->p); - ASYNC_MSG_FREE (m); - - return; -} - -/** - * Indicate data has been received from a TCP pcb contained in a netconn - * Called from netconn_recv - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_recv (struct common_pcb *cpcb, msg_recv_buf * rmsg) -{ - data_com_msg *m = MSG_ENTRY (rmsg, data_com_msg, buffer); - SET_MSG_ERR (m, ERR_OK); - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - - if (NULL == tpcb) - { - if (rmsg->p) - { - NSPOL_LOGDBG (TCP_DEBUG, - "When pcb was freed: do recv, and free pbuf"); - spl_pbuf_free (rmsg->p); - rmsg->p = NULL; - } - - return; - } - - if (cpcb->conn->type == SPL_NETCONN_TCP) - { - /* Pbuf free should be done in network stack */ - if (rmsg->p) - { - NSPOL_LOGDBG (TCP_DEBUG, "do recv, and free pbuf"); - spl_pbuf_free (rmsg->p); - rmsg->p = NULL; - } - tcp_recved (tpcb, rmsg->len * TCP_MSS); - } -} - -/** - * See if more data needs to be written from a previous call to netconn_write. - * Called initially from do_write. If the first call can't send all data - * (because of low memory or empty send-buffer), this function is called again - * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the - * blocking application thread (waiting in netconn_write) is released. - * - * @param conn netconn (that is currently in state NETCONN_WRITE) to process - * @return ERR_OK - * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished - */ - -/** - * See if more data needs to be written from a previous call to netconn_write. - * Called initially from do_write. If the first call can't send all data - * (because of low memory or empty send-buffer), this function is called again - * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the - * blocking application thread (waiting in netconn_write) is released. - * - * @param conn netconn (that is currently in state NETCONN_WRITE) to process - * @return ERR_OK - * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished - */ -err_t -do_writemore (struct spl_netconn *conn) -{ - err_t err = ERR_OK; - u16_t len = 0, available; - u8_t write_finished = 0; - struct tcp_pcb *tpcb = (struct tcp_pcb *) conn->private_data; - common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; - size_t diff; - const void *dataptr; - - if ((NULL == tpcb) || (NULL == conn) || (SPL_NETCONN_WRITE != conn->state) - || (NULL == cpcb->current_msg)) - { - NSPOL_LOGERR ("conn=NULL"); - return ERR_ARG; - } - - msg_write_buf *wmsg = (msg_write_buf *) cpcb->current_msg->buffer; -start_write: - - if (NULL == wmsg->p) - { - NSPOL_LOGERR ("wmsg->p is NULL]conn=%p,pcb=%p", conn, tpcb); - return ERR_VAL; - } - - u8_t apiflags = wmsg->apiflags; - struct spl_pbuf *current_w_pbuf = wmsg->p; - current_w_pbuf->res_chk.u8Reserve |= NEED_ACK_FLAG; - wmsg->p = current_w_pbuf->next; - current_w_pbuf->next = NULL; - - dataptr = (const u8_t *) current_w_pbuf->payload + cpcb->write_offset; - diff = current_w_pbuf->len - cpcb->write_offset; - - if (diff > 0xffffUL) - { - len = 0xffff; - apiflags |= TCP_WRITE_FLAG_MORE; - } - else - { - len = (u16_t) diff; - } - - available = tcp_sndbuf (tpcb); - if (!available) - { - err = ERR_MEM; - goto err_mem; - } - - if (available < len) - { - /* don't try to write more than sendbuf */ - len = available; - apiflags |= TCP_WRITE_FLAG_MORE; - } - - err = tcp_write (tpcb, dataptr, len, apiflags); - if ((err == ERR_OK) || (err == ERR_MEM)) - { - err_mem: - if ((tcp_sndbuf (tpcb) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen (tpcb) >= TCP_SNDQUEUELOWAT)) - { - SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); - } - } - if (err == ERR_OK) - { - cpcb->write_offset += len; - tcp_output (tpcb); - - if (cpcb->write_offset == current_w_pbuf->len) - { - cpcb->write_offset = 0; - spl_pbuf_free (current_w_pbuf); - if (NULL == wmsg->p) - { - /* this message is finished */ - cpcb->write_offset = 0; - SET_MSG_ERR (cpcb->current_msg, err); - - /* go to next msg */ - data_com_msg *forFreemsg = cpcb->current_msg; - msg_write_buf *msg_head_prev = cpcb->msg_head; - cpcb->msg_head = cpcb->msg_head->next; - - /* no msg remain */ - if (cpcb->msg_head == NULL) - { - write_finished = 1; - if (cpcb->msg_tail != NULL - && msg_head_prev != cpcb->msg_tail) - { - NSPOL_LOGWAR (TCP_DEBUG, - "err maybe lost one mesg]conn=%p,pcb=%p", - conn, tpcb); - } - cpcb->msg_tail = NULL; - cpcb->current_msg = NULL; - conn->state = SPL_NETCONN_NONE; - } - else /* go to handle next message */ - { - - cpcb->current_msg = - MSG_ENTRY (cpcb->msg_head, data_com_msg, buffer); - wmsg = cpcb->msg_head; - write_finished = 0; - } - - ASYNC_MSG_FREE (forFreemsg); - } - - } - else - { - if (cpcb->write_offset > current_w_pbuf->len) - { - NSPOL_LOGERR ("Big trouble write_offset > current_w_pbuf->len"); - } - - current_w_pbuf->next = wmsg->p; - wmsg->p = current_w_pbuf; - } - if ((write_finished == 0) && (NULL != wmsg->p)) - { - goto start_write; - } - } - else if (err == ERR_MEM) - { - current_w_pbuf->next = wmsg->p; - wmsg->p = current_w_pbuf; - tcp_output (tpcb); - } - else - { - NSPOL_LOGERR ("]pcb=%p, error when send %d", tpcb, err); - write_finished = 1; - cpcb->write_offset = 0; - current_w_pbuf->next = wmsg->p; - wmsg->p = current_w_pbuf; - tcp_abort (tpcb); - return err; - } - NSTCP_LOGINF ("do_writemore finished with err %d", err); - return ERR_OK; -} - -/** - * Send some data on a TCP pcb contained in a netconn - * Called from netconn_write - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_write (struct common_pcb *cpcb, msg_write_buf * wmsg) -{ - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - spl_netconn_t *conn = cpcb->conn; - data_com_msg *m = MSG_ENTRY (wmsg, data_com_msg, buffer); - - pbuf_set_recycle_flg (wmsg->p, MBUF_HLD_BY_SPL); /* release buf hold by app on abnormal exit */ - - int tcpState = -1; - - /* if msg->conn is null, then return */ - if (NULL == conn) - { - NSPOL_LOGERR ("Invalid param]msg->conn=%p", conn); - SET_MSG_ERR (m, ERR_VAL); - goto err_return; - } - - tcpState = tpcb->state; - - if ((SPL_ERR_IS_FATAL (conn->last_err)) - && !((ERR_CLSD == conn->last_err) && (CLOSE_WAIT == tcpState))) - { - SET_MSG_ERR (m, conn->last_err); - } - else - { - if (cpcb->type == SPL_NETCONN_TCP) - { - if (cpcb->current_msg != NULL) - { - if (NULL == cpcb->msg_head || NULL == cpcb->msg_tail) - { - /* if possible only if connect is not finished and it's - blocking, then the current_msg is connect msg. - */ - NSPOL_LOGERR ("netconn do_write msg is null]msg_type=%d", - cpcb->current_msg->param.minor_type); - goto err_return; - } - - /* only msg_write_buf will be in msg_head-msg_tail queue */ - wmsg->next = NULL; - cpcb->msg_tail->next = wmsg; - cpcb->msg_tail = wmsg; - (void) do_writemore (conn); - NSTCP_LOGINF ("do_write finished...."); - return; - } - - if (conn->state != SPL_NETCONN_NONE) - { - /* netconn is connecting, closing or in blocking write */ - NSPOL_LOGINF (TCP_DEBUG, - "msg->conn->state != SPL_NETCONN_NONE..netconn is connecting, " - "closing or in blocking write]conn=%p", conn); - SET_MSG_ERR (m, ERR_INPROGRESS); - } - /* this means we should start to process this message */ - else if (tpcb != NULL) - { - conn->state = SPL_NETCONN_WRITE; - - /* set all the variables used by do_writemore */ - if (0 != cpcb->write_offset) - { - NSPOL_LOGERR ("already writing or closing]conn=%p", conn); - goto err_return; - } - - if (0 == wmsg->len) - { - NSPOL_LOGERR ("msg->msg.w.len=0]conn=%p", conn); - goto err_return; - } - - /* record the msg will be processed */ - cpcb->current_msg = m; - if (cpcb->msg_head != NULL || cpcb->msg_tail != NULL) - { - NSPOL_LOGERR ("error maybe lost mesg]conn=%p", conn); - } - cpcb->msg_head = cpcb->msg_tail = wmsg; - wmsg->next = NULL; - cpcb->write_offset = 0; - - (void) do_writemore (conn); - - if ((conn->snd_buf) > TCP_SNDLOWAT) - { - if (cpcb->model == SOCKET_STACKX) - SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); - } - NSTCP_LOGINF ("do_write finished %d", conn->snd_buf); - - /* for both cases: if do_writemore was called, don't ACK the APIMSG - since do_writemore ACKs it! */ - return; - } - else - { - SET_MSG_ERR (m, ERR_CONN); - } - } - else - { - SET_MSG_ERR (m, ERR_VAL); - } - } - NSTCP_LOGINF ("do_write finished"); - -err_return: - pbuf_free_safe (wmsg->p); - ASYNC_MSG_FREE (m); - - return; -} - -void -do_getsockname (struct common_pcb *cpcb, msg_getaddrname * amsg) -{ - spl_netconn_t *conn; - struct tcp_pcb *tcp; - struct udp_pcb *udp; - struct sockaddr_in *paddr = (struct sockaddr_in *) &amsg->sock_addr; - - data_com_msg *m = MSG_ENTRY (amsg, data_com_msg, buffer); - - if ((NULL == cpcb) || !(conn = cpcb->conn)) - { - NSTCP_LOGERR ("failed to get sock"); - paddr->sin_family = 0; - paddr->sin_port = 0; - paddr->sin_addr.s_addr = 0; - SET_MSG_ERR (m, ERR_CONN); - return; - } - - NS_LOG_CTRL (LOG_CTRL_GETSOCKNAME, LOGTCP, "NSTCP", NSLOG_DBG, - "cpcb=%p,conn=%p,cmd=%u", cpcb, cpcb->conn, amsg->cmd); - - paddr->sin_family = AF_INET; - SET_MSG_ERR (m, ERR_OK); - - if (amsg->cmd == 0) - { - if (cpcb->type == SPL_NETCONN_TCP) - { - tcp = (struct tcp_pcb *) cpcb->conn->private_data; - /* add judgement:(NETCONN_LISTEN == conn->state) in following if words */ - /* If connect is not done in TCP then the remote address will not be there so need to update proper error code - if the application call the getpeername in TCP mode */ - if ((SPL_NETCONN_LISTEN == conn->state) - || (tcp->remote_ip.addr == 0) || (tcp->remote_port == 0)) - { - paddr->sin_family = 0; - paddr->sin_port = 0; - paddr->sin_addr.s_addr = 0; - SET_MSG_ERR (m, ERR_CONN); - } - else - { - paddr->sin_port = spl_htons (tcp->remote_port); - paddr->sin_addr.s_addr = tcp->remote_ip.addr; - } - } - else if (cpcb->type == SPL_NETCONN_UDP) - { - udp = (struct udp_pcb *) cpcb->conn->private_data; - /* If connect is not done in UDP then the remote address will not be there so need to update proper error code - if the application call the getpeername in UDP mode - */ - if ((udp->remote_ip.addr == 0) || (udp->remote_port == 0)) - { - paddr->sin_family = 0; - paddr->sin_port = 0; - paddr->sin_addr.s_addr = 0; - SET_MSG_ERR (m, ERR_CONN); - } - else - { - paddr->sin_port = spl_htons (udp->remote_port); - paddr->sin_addr.s_addr = udp->remote_ip.addr; - } - } - } - else - { - if (cpcb->type == SPL_NETCONN_TCP) - { - tcp = (struct tcp_pcb *) cpcb->conn->private_data; - paddr->sin_port = spl_htons (tcp->local_port); - paddr->sin_addr.s_addr = tcp->local_ip.addr; - } - else if (cpcb->type == SPL_NETCONN_UDP) - { - udp = (struct udp_pcb *) cpcb->conn->private_data; - paddr->sin_port = spl_htons (udp->local_port); - paddr->sin_addr.s_addr = udp->local_ip.addr; - } - } -} - -/** - * Close a TCP pcb contained in a netconn - * Called from netconn_close - * - * @param msg the api_msg_msg pointing to the connection - */ -void -do_close (struct common_pcb *cpcb, msg_close * cmsg) -{ - spl_netconn_t *conn = cpcb->conn; - data_com_msg *m = MSG_ENTRY (cmsg, data_com_msg, buffer); - - NSTCP_LOGDBG ("msg->conn=%p,state=%d", conn, conn->state); - - /* @todo: abort running write/connect? */ - if ((conn->state != SPL_NETCONN_NONE) - && (conn->state != SPL_NETCONN_LISTEN) - && (conn->state != SPL_NETCONN_CONNECT)) - { - if (SPL_NETCONN_TCP != cpcb->type) - { - NSTCP_LOGERR ("msg->conn=%p,type=%d", conn, cpcb->type); - return; - } - NSTCP_LOGWAR ("msg->conn=%p,state=%d", conn, conn->state); - SET_MSG_ERR (m, ERR_INPROGRESS); - } - else if (cpcb->type == SPL_NETCONN_TCP) //clear codeDEX warning , CID:24336, cpcb can't be null. - { - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - - if (tpcb == NULL) - { - NSTCP_LOGERR ("tpcb null msg->conn=%p,type=%d", conn, cpcb->type); - return; - } - if ((cmsg->shut != SPL_NETCONN_SHUT_RDWR) - && (conn->state == SPL_NETCONN_LISTEN)) - { - /* LISTEN doesn't support half shutdown */ - NSTCP_LOGERR - ("LISTEN doesn't support half shutdown!]conn=%p,pcb=%p,state=%d", - conn, tpcb, conn->state); - SET_MSG_ERR (m, ERR_CONN); - } - else - { - if (cmsg->shut & SPL_NETCONN_SHUT_RD) - { - /* Drain and delete mboxes */ - (void) netconn_drain (cpcb->type, conn); - unlink_recv_ring (conn); - } - - if (((NULL != cpcb->current_msg) - && (conn->state != SPL_NETCONN_CONNECT)) - || (0 != cpcb->write_offset)) - { - NSTCP_LOGERR - ("already writing or closing]conn=%p,pcb=%p,offset=%zu,curmsg=%p", - conn, tpcb, cpcb->write_offset, cpcb->current_msg); - SET_MSG_ERR (m, ERR_CONN); - return; - } - - if (conn->state == SPL_NETCONN_CONNECT) - { - if (cpcb->current_msg != NULL - && cpcb->current_msg->param.minor_type == - SPL_API_DO_CONNECT) - { - SET_MSG_ERR (m, ERR_RST); - SYNC_MSG_ACK (cpcb->current_msg); - } - else - { - NSTCP_LOGINF - ("already in connecting]conn=%p,cpcb=%p,msg=%p", conn, - cpcb, cpcb->current_msg); - } - /* maybe need to clean cpcb->msg_head */ - } - - conn->state = SPL_NETCONN_CLOSE; - cpcb->current_msg = m; - (void) do_close_internal (cpcb, 1); - - if (SPL_NETCONN_SHUT_RD == cmsg->shut - || SPL_NETCONN_SHUT_RDWR == cmsg->shut) - { - SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 1); - } - - return; - } - } - else - { - SET_MSG_ERR (m, ERR_VAL); - } -} - -/*trans kerner option to stackx option*/ -int -ks_to_stk_opt (int opt) -{ - int stack_opt = opt; - switch (opt) - { - case SO_DEBUG: - stack_opt = SOF_DEBUG; - break; - case SO_ACCEPTCONN: - stack_opt = SOF_ACCEPTCONN; - break; - case SO_BROADCAST: - stack_opt = SOF_BROADCAST; - break; - case SO_KEEPALIVE: - stack_opt = SOF_KEEPALIVE; - break; - case SO_REUSEADDR: - stack_opt = SOF_REUSEADDR; - break; - case SO_DONTROUTE: - stack_opt = SOF_DONTROUTE; - break; - case SO_USELOOPBACK: - stack_opt = SOF_USELOOPBACK; - break; - case SO_OOBINLINE: - stack_opt = SOF_OOBINLINE; - break; - default: - stack_opt = opt; - break; - } - return stack_opt; -} - -void -do_get_tcpproto_getsockopt_internal (struct common_pcb *cpcb, - msg_setgetsockopt * smsg) -{ - int optname; - void *optval; - struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - - optname = smsg->optname; - optval = &smsg->optval; - - switch (optname) - { - case SPL_TCP_NODELAY: - *(int *) optval = tcp_nagle_disabled (tpcb); - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,TCP_NODELAY=%s", - cpcb->socket, (*(int *) optval) ? "on" : "off"); - break; - - case SPL_TCP_KEEPIDLE: - *(int *) optval = (int) (tpcb->keep_idle / 1000); - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPIDLE=%d", - cpcb->socket, *(int *) optval); - break; - case SPL_TCP_KEEPINTVL: - *(int *) optval = (int) (tpcb->keep_intvl / 1000); - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPINTVL=%d", - cpcb->socket, *(int *) optval); - break; - case SPL_TCP_KEEPCNT: - *(int *) optval = (int) tpcb->keep_cnt; - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPCNT=%d", - cpcb->socket, *(int *) optval); - break; - case SPL_TCP_INFO: - ((struct tcp_info *) optval)->tcpi_total_retrans = (int) tpcb->nrtx; - ((struct tcp_info *) optval)->tcpi_snd_mss = (int) tpcb->mss; - ((struct tcp_info *) optval)->tcpi_rtt = (int) tpcb->sa; - ((struct tcp_info *) optval)->tcpi_snd_cwnd = (int) tpcb->cwnd; - break; - default: - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); - SET_MSG_ERR (m, EOPNOTSUPP); - break; - } -} - -void -do_get_ipproto_getsockopt_internal (struct common_pcb *cpcb, - msg_setgetsockopt * smsg) -{ - int optname; - u32_t optlen; - void *optval; - - struct ip_pcb *ipcb = (struct ip_pcb *) (cpcb); - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - - optname = smsg->optname; - optval = &smsg->optval; - optlen = smsg->optlen; - - switch (optname) - { - case IP_TTL: - *(int *) optval = ipcb->ttl; - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,IP_TTL=%d", - cpcb->socket, *(int *) optval); - break; - case IP_TOS: - smsg->optlen = - (optlen < sizeof (u32_t)) ? sizeof (u8_t) : sizeof (u32_t); - if (smsg->optlen == sizeof (u8_t)) - { - *(u8_t *) optval = ipcb->tos; - } - else - { - *(u32_t *) optval = (u32_t) ipcb->tos; - } - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,IP_TOS=%d", - cpcb->socket, *(int *) optval); - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); - break; - } -} - -void -do_get_solsocket_getsockopt_internal (struct common_pcb *cpcb, - msg_setgetsockopt * smsg) -{ - int optname; - void *optval; - struct tcp_pcb *tpcb = NULL; - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - struct tcp_pcb *pcb = (struct tcp_pcb *) cpcb->conn->private_data; - - optname = smsg->optname; - optval = &smsg->optval; - - switch (optname) - { - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: - case SO_REUSEADDR: - *(int *) optval = - (ip_get_option ((struct ip_pcb *) cpcb, ks_to_stk_opt (optname))) ? 1 - : 0; - NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,optname=%d,optval=%s", - cpcb->socket, optname, (*(int *) optval ? "on" : "off")); - break; - case SO_ACCEPTCONN: - tpcb = (struct tcp_pcb *) cpcb->conn->private_data; - if ((smsg->optlen < sizeof (int)) || (NULL == tpcb)) - { - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, - "(SOL_SOCKET, SO_ACCEPTCONN) failed]fd=%d,tcp=%p,optlen=%u", - cpcb->socket, cpcb, smsg->optlen); - break; - } - if (tpcb->state == LISTEN) - { - *(int *) optval = 1; - } - else - { - *(int *) optval = 0; - } - NSPOL_LOGDBG (SOCKETS_DEBUG, - "(SOL_SOCKET, SO_ACCEPTCONN)]fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - break; - case SO_TYPE: - switch (cpcb->type) - { - case SPL_NETCONN_RAW: - *(int *) optval = SOCK_RAW; - break; - case SPL_NETCONN_TCP: - *(int *) optval = SOCK_STREAM; - break; - case SPL_NETCONN_UDP: - *(int *) optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int *) optval = cpcb->type; - NSPOL_LOGDBG (SOCKETS_DEBUG, - "(SOL_SOCKET, SO_TYPE): unrecognized socket type]fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - } /* switch (sock->conn->type) */ - NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_TYPE)]fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - break; - case SO_RCVTIMEO: - (*(struct timeval *) optval).tv_sec = - spl_netconn_get_recvtimeout (cpcb) / 1000; - (*(struct timeval *) optval).tv_usec = - (spl_netconn_get_recvtimeout (cpcb) % 1000) * 1000; - NSPOL_LOGDBG (SOCKETS_DEBUG, - "stackx_getsockopt(SOL_SOCKET, SO_RCVTIMEO)]fd=%d,sec=%ld,usec=%ld", - cpcb->socket, (*(struct timeval *) optval).tv_sec, - (*(struct timeval *) optval).tv_usec); - break; - case SO_SNDTIMEO: - (*(struct timeval *) optval).tv_sec = - spl_netconn_get_sendtimeout (cpcb) / 1000; - (*(struct timeval *) optval).tv_usec = - (spl_netconn_get_sendtimeout (cpcb) % 1000) * 1000; - NSPOL_LOGDBG (SOCKETS_DEBUG, - "(SOL_SOCKET, SO_SNDTIMEO)]fd=%dsec=%ld,usec=%ld", - cpcb->socket, (*(struct timeval *) optval).tv_sec, - (*(struct timeval *) optval).tv_usec); - break; - case SO_SNDBUF: - { - u16_t mss = (pcb->mss > TCP_MSS - || pcb->mss == 0) ? TCP_MSS : pcb->mss; - *(int *) optval = spl_netconn_get_sendbufsize (cpcb->conn) * mss; - /*If user has not configured any sendbuffer value then we should return minimum - promissed for the connection based on the flow control. */ - if (*(int *) optval == 0) - { - *(int *) optval = CONN_TCP_MEM_MIN_LINE * mss; - } - NSPOL_LOGDBG (SOCKETS_DEBUG, - "(SOL_SOCKET, SO_SNDBUF)]fd=%d,optval=%d", cpcb->socket, - *(int *) optval); - break; - } - case SO_NO_CHECK: - *(int *) optval = - (udp_flags ((struct udp_pcb *) cpcb->conn->private_data) & - UDP_FLAGS_NOCHKSUM) ? 1 : 0; - NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_NO_CHECK)fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - break; - case SO_SNDLOWAT: - *(int *) optval = 1; - NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_SNDLOWAT)fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - break; - - case SO_RCVLOWAT: - *(int *) optval = spl_netconn_get_reclowbufsize (cpcb); - NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_RCVLOWAT)fd=%d,optval=%d", - cpcb->socket, *(int *) optval); - break; - case SO_ERROR: - *(int *) optval = GET_MSG_ERR (m); - SET_MSG_ERR (m, 0); - NSPOL_LOGDBG (SOCKETS_DEBUG, "SOL_SOCKET]fd=%d,optval=%d", cpcb->socket, - *(int *) optval); - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported opt]optname=%d", optname); - break; - } -} - -void -do_getsockopt_internal (struct common_pcb *cpcb, msg_setgetsockopt * smsg) -{ - int level; - - if (NULL == smsg) - { - NSTCP_LOGERR ("arg NULL"); - return; - } - - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - - level = smsg->level; - switch (level) - { - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - do_get_solsocket_getsockopt_internal (cpcb, smsg); - - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - do_get_ipproto_getsockopt_internal (cpcb, smsg); - - break; - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - do_get_tcpproto_getsockopt_internal (cpcb, smsg); - - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported level]level=%d", level); - break; - } /* switch (level) */ -} - -void -do_tcpsock_setsockopt (spl_netconn_t * conn, msg_setgetsockopt * smsg) -{ - const void *optval; - int optname; - struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; - struct tcp_pcb *tpcb = (struct tcp_pcb *) conn->private_data; - - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - - optname = smsg->optname; - optval = &smsg->optval; - - switch (optname) - { - case SPL_TCP_NODELAY: - if (*(int *) optval) - { - tcp_nagle_disable (tpcb); - } - else - { - tcp_nagle_enable (tpcb); - } - - NSTCP_LOGDBG ("IPPROTO_TCP, TCP_NODELAY]fd=%d,optval=%s", - cpcb->socket, (*(int *) optval) ? "on" : "off"); - break; - - case SPL_TCP_KEEPIDLE: - /* CID 52121 (#2 of 3): Other violation (HW_VPP_C_FIND_OPERATORS_2_1_1_3) */ - if ((u32_t) (*(int *) optval) >= INT_MAX / 1000) - { - NSTCP_LOGWAR ("optval too big]optval=%u", - (u32_t) (*(int *) optval)); - *(int *) optval = INT_MAX / 1000; - } - - tpcb->keep_idle = 1000 * (u32_t) (*(int *) optval); - - if (tpcb->keep_idle > TCP_KEEPIDLE_DEFAULT) - { - NSTCP_LOGWAR - ("(%d, IPPROTO_TCP, SPL_TCP_KEEPIDLE. value bigger than 7200000UL so setting to default 7200000UL) requested is -> %" - U32_F " ", cpcb->socket, tpcb->keep_idle); - tpcb->keep_idle = TCP_KEEPIDLE_DEFAULT; - } - - NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPIDLE](fd=%d,keep_idle=%" U32_F - " ", cpcb->socket, tpcb->keep_idle); - - /* Not required lwip_slowtmr will take care about timer. */ - break; - case SPL_TCP_KEEPINTVL: - /* CID 52121 (#1 of 3): Other violation (HW_VPP_C_FIND_OPERATORS_2_1_1_3) */ - if ((u32_t) (*(int *) optval) >= INT_MAX / 1000) - { - NSTCP_LOGWAR ("optval too big]optval=%u", - (u32_t) (*(int *) optval)); - *(int *) optval = INT_MAX / 1000; - } - - tpcb->keep_intvl = 1000 * (u32_t) (*(int *) optval); - - if (tpcb->keep_intvl > TCP_KEEPIDLE_DEFAULT) /*max timer value supported */ - { - NSTCP_LOGWAR - ("(%d, IPPROTO_TCP, SPL_TCP_KEEPINTVL. value bigger than 7200000UL so setting to default 7200000UL) requested is -> %" - U32_F " ", cpcb->socket, tpcb->keep_intvl); - tpcb->keep_intvl = TCP_KEEPIDLE_DEFAULT; - } - NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPINTVL]fd=%d,keep_intvl=%" U32_F - " ", cpcb->socket, tpcb->keep_intvl); - break; - case SPL_TCP_KEEPCNT: - tpcb->keep_cnt = (u32_t) (*(int *) optval); - NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPCNT]fd=%d,keep_cnt=%" U32_F " ", - cpcb->socket, tpcb->keep_cnt); - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); - break; - } -} - -void -do_ipsock_setsockopt (struct common_pcb *cpcb, msg_setgetsockopt * smsg) -{ - const void *optval; - u32_t optlen; - int optname; - - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - - struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; - struct ip_pcb *ipcb = (struct ip_pcb *) upcb; - - optname = smsg->optname; - optval = &smsg->optval; - optlen = smsg->optlen; - - int val = 0; - int bNotAllowSet = 0; - switch (optname) - { - case IP_TTL: - ipcb->ttl = (u8_t) (*(int *) optval); - NSIP_LOGDBG ("IPPROTO_IP,IP_TTL]fd=%d,ttl=%u", cpcb->socket, ipcb->ttl); - break; - case IP_TOS: - bNotAllowSet = (cpcb->dataSentFlag != 0) - && ((SPL_NETCONN_TCP == cpcb->type) - || (SPL_NETCONN_UDP == cpcb->type) - || (SPL_NETCONN_RAW == cpcb->type)); - /*not allow set tos value when sending data */ - if (bNotAllowSet) - { - SET_MSG_ERR (m, ERR_VAL); - break; - } - - if (optlen >= sizeof (u32_t)) - { - val = (int) (*(const int *) optval); - } - else if (optlen >= sizeof (u8_t)) - { - val = (int) (*(const u8_t *) optval); - } - - if (SPL_NETCONN_TCP == cpcb->type) - { - val &= ~INET_ECN_MASK; - val |= ipcb->tos & INET_ECN_MASK; - } - ipcb->tos = (u8_t) (val); - - smsg->msg_box = (get_msgbox ((u8_t) val))->llring; - - NSIP_LOGDBG ("IPPROTO_IP,IP_TOS]]fd=%d,tos=%u", cpcb->socket, - ipcb->tos); - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); - break; - } -} - - /*Made seperate functions to reduce code complexity */ -void -do_setsockopt_recvtimeout_internal (const void *optval, - struct common_pcb *cpcb) -{ - if ((*(struct timeval *) optval).tv_sec < 0) - { - spl_netconn_set_recvtimeout (cpcb, 0); - } - else - { - spl_netconn_set_recvtimeout (cpcb, MAX_WAIT_TIMEOUT); - if ((*(struct timeval *) optval).tv_sec != 0 - || (*(struct timeval *) optval).tv_usec != 0) - { - if ((*(struct timeval *) optval).tv_sec < - ((MAX_WAIT_TIMEOUT / 1000) - 1)) - { - spl_netconn_set_recvtimeout (cpcb, - (*(struct timeval *) optval).tv_sec - * 1000 + - (*(struct timeval *) - optval).tv_usec / 1000); - } - } - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, - "SOL_SOCKET, SO_RCVTIMEO]conn=%p,fd=%d,optval=%d", cpcb, - cpcb->socket, cpcb->recv_timeout); -} - -void -do_setsockopt_sndtimeout_internal (const void *optval, - struct common_pcb *cpcb) -{ - if ((*(struct timeval *) optval).tv_sec < 0) - { - spl_netconn_set_sendtimeout (cpcb, 0); - } - else - { - spl_netconn_set_sendtimeout (cpcb, MAX_WAIT_TIMEOUT); - if ((*(struct timeval *) optval).tv_sec != 0 - || (*(struct timeval *) optval).tv_usec != 0) - { - if ((*(struct timeval *) optval).tv_sec < - ((MAX_WAIT_TIMEOUT / 1000) - 1)) - { - spl_netconn_set_sendtimeout (cpcb, - (*(struct timeval *) optval).tv_sec - * 1000 + - (*(struct timeval *) - optval).tv_usec / 1000); - } - } - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, - "SOL_SOCKET, SO_SNDTIMEO]conn=%p,fd=%d,optval=%d", cpcb, - cpcb->socket, cpcb->send_timeout); -} - -#define IS_TCP_PCB(cpcb) (cpcb && (cpcb->conn) && (SPL_NETCONN_TCP == cpcb->conn->type)) -NSTACK_STATIC inline void -set_opt_sol_socket (struct common_pcb *cpcb, struct tcp_pcb *pcb, - data_com_msg * m, int level, int optname, - const void *optval) -{ - switch (optname) - { - /* The option flags */ - case SO_BROADCAST: - - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - case SO_REUSEADDR: - - if (NULL == pcb) - { - NSPOL_LOGERR ("conn->pcb.ip is null"); - break; - } - - if (*(const int *) optval) - { - ip_set_option ((struct ip_pcb *) pcb, ks_to_stk_opt (optname)); - } - else - { - ip_reset_option ((struct ip_pcb *) pcb, ks_to_stk_opt (optname)); - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, "]conn=%p,fd=%d,optname=0x%x,optval=%s", - cpcb, cpcb->socket, optname, - (*(const int *) optval ? "on" : "off")); - - /* No use now, since tcp_slowtmr will take care about not sending/sending of keepalive */ - break; - - case SO_RCVLOWAT: - spl_netconn_set_reclowbufsize (cpcb, *(int *) optval); - NSPOL_LOGDBG (SOCKETS_DEBUG, - "SOL_SOCKET, SO_RCVLOWAT]conn=%p,fd=%d,optval=%d", cpcb, - cpcb->socket, cpcb->sk_rcvlowat); - break; - - case SO_RCVTIMEO: - /*to reduce code complexity */ - do_setsockopt_recvtimeout_internal (optval, cpcb); - break; - - case SO_SNDTIMEO: - /*to reduce code complexity */ - do_setsockopt_sndtimeout_internal (optval, cpcb); - break; - - case SO_SNDBUF: - { - /* udp pcb invalid access will cause coredump */ - if (!IS_TCP_PCB (cpcb)) - { - NSPOL_LOGDBG (SOCKETS_DEBUG, - "not support for non tcp socket]optname=%d, level=%d", - optname, level); - return; - } - - u16_t mss = (pcb->mss > TCP_MSS - || pcb->mss == 0) ? TCP_MSS : pcb->mss; - - if (*(int *) optval < (int) mss) - { - /*set value of one TCP_MSS */ - spl_netconn_set_sendbufsize (cpcb->conn, 1); - } - else - { - spl_netconn_set_sendbufsize (cpcb->conn, - (*(int *) optval) / (int) mss); - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, - "SOL_SOCKET, SO_SNDBUF]conn=%p,fd=%d,optval=%d", cpcb, - cpcb->socket, cpcb->conn->send_bufsize * mss); - break; - } - - case SO_NO_CHECK: - /* How udp is coming here.. ?? @TODO: May be move to someother function.? */ - /* solve segment issue when the PCB is not exist */ - if (NULL == cpcb) - { - NSPOL_LOGERR ("conn->pcb.udp is null"); - break; - } - - struct udp_pcb *upcb = (struct udp_pcb *) pcb; - - if (*(int *) optval) - { - udp_setflags (upcb, udp_flags (upcb) | UDP_FLAGS_NOCHKSUM); - } - else - { - udp_setflags (upcb, udp_flags (upcb) & ~UDP_FLAGS_NOCHKSUM); - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, - "SOL_SOCKET, SO_NO_CHECK]conn=%p,fd=%d,optval=0x%x", cpcb, - cpcb->socket, upcb->flags); - break; - - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); - break; - } /* switch (optname) */ - -} - -void -do_setsockopt_internal (struct common_pcb *cpcb, msg_setgetsockopt * smsg) -{ - int level, optname; - const void *optval; - - data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); - struct tcp_pcb *pcb = (struct tcp_pcb *) cpcb->conn->private_data; - - if (NULL == smsg) - { - NSTCP_LOGERR ("arg null!"); - return; - } - - level = smsg->level; - optname = smsg->optname; - optval = &smsg->optval; - - switch (level) - { - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - set_opt_sol_socket (cpcb, pcb, m, SOL_SOCKET, optname, optval); - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - - if (NULL == cpcb) - { - NSPOL_LOGERR ("conn->pcb.ip is null"); - break; - } - - do_ipsock_setsockopt (cpcb, smsg); - - break; - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* udp pcb invalid access will cause coredump */ - if (!IS_TCP_PCB (cpcb)) - { - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, - "not support for non tcp socket]optname=%d,level=%d", - optname, level); - return; - } - - if (NULL == cpcb) - { - NSPOL_LOGERR ("conn->pcb.tcp is null"); - break; - } - - do_tcpsock_setsockopt (cpcb->conn, smsg); - - break; - default: - SET_MSG_ERR (m, ERR_VAL); - NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]level=%d", level); - break; - } /* switch (level) */ -} - -/*app send its version info to nStackMain */ -void -do_app_touch (msg_app_touch * smsg) -{ - //write app version info to running.log - NSPOL_LOGINF (SOCKETS_DEBUG, "hostpid=%u,app_version=%s", smsg->hostpid, - smsg->app_version); -} - -void -tcp_free_accept_ring (spl_netconn_t * conn) -{ - err_t de_err = ERR_OK; - spl_netconn_t *newconn; - while (1) - { - newconn = NULL; - /* -1 means nonblocking */ - de_err = accept_dequeue (conn, (void **) &newconn, (u32_t) - 1); - if (de_err == ERR_WOULDBLOCK || newconn == NULL) - return; - - tcp_drop_conn (newconn); - } -} - -void -tcp_drop_conn (spl_netconn_t * conn) -{ - /* usually we should not access pcb by recv_obj, but no choice */ - struct tcp_pcb *pcb = (struct tcp_pcb *) conn->private_data; - - /* free conn first, even pcb is NULL */ - free_conn_by_spl (conn); - - if (pcb == NULL) - { - NSTCP_LOGWAR - ("a tcp connection in accept queue without pcb!]newconn=%p", conn); - return; - } - - /* tell peer conneciton is reset */ - NSTCP_LOGWAR ("sending RST in accept waiting queue!]pcb=%p", pcb); - - tcp_rst (pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port); - - tcp_pcb_remove (&tcp_active_pcbs, pcb); - memp_free (MEMP_TCP_PCB, pcb); -} - -void -update_tcp_state (spl_netconn_t * conn, enum tcp_state state) -{ - spl_tcp_state_t spl_state; - - if (conn != NULL) - { - switch (state) - { - case CLOSED: - spl_state = SPL_CLOSED; - break; - case LISTEN: - spl_state = SPL_LISTEN; - break; - case SYN_SENT: - spl_state = SPL_SYN_SENT; - break; - case SYN_RCVD: - spl_state = SPL_SYN_RCVD; - break; - case ESTABLISHED: - spl_state = SPL_ESTABLISHED; - break; - case FIN_WAIT_1: - spl_state = SPL_FIN_WAIT_1; - break; - case FIN_WAIT_2: - spl_state = SPL_FIN_WAIT_2; - break; - case CLOSE_WAIT: - spl_state = SPL_CLOSE_WAIT; - break; - case CLOSING: - spl_state = SPL_CLOSING; - break; - case LAST_ACK: - spl_state = SPL_LAST_ACK; - break; - case TIME_WAIT: - spl_state = SPL_TIME_WAIT; - break; - default: - spl_state = SPL_CLOSED; - break; - } - if (conn->tcp_state != spl_state) - { - conn->tcp_state = spl_state; - NSTCP_LOGINF ("conn=%p,private_data=%p,state=%d", conn, - conn->private_data, spl_state); - } - } -} - -void -do_update_pcbstate () -{ - struct tcp_pcb *tpcb; - int i; - for (i = 0; i < NUM_TCP_PCB_LISTS; i++) - { - for (tpcb = *tcp_pcb_lists[i]; tpcb != NULL; tpcb = tpcb->next) - { - if (tpcb->callback_arg) - { - update_tcp_state ((spl_netconn_t *) tpcb->callback_arg, - tpcb->state); - } - } - } - - return; -} - -void -init_stackx_lwip () -{ - lwip_init (); - sys_timeouts_init (); - return; -} - -void -free_common_pcb (struct common_pcb *cpcb) -{ - if (res_free (&cpcb->res_chk)) - { - NSFW_LOGERR ("conn refree!]conn=%p", cpcb->conn); - return; - } - - common_pcb_reset (cpcb); - - mring_handle pool = p_def_stack_instance->cpcb_seg; - if (nsfw_mem_ring_enqueue (pool, (void *) cpcb) != 1) - { - NSSBR_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); - } - return; -} - -struct common_pcb * -alloc_common_pcb (enum spl_netconn_type type) -{ - struct common_pcb *cpcb = NULL; - - if (nsfw_mem_ring_dequeue (p_def_stack_instance->cpcb_seg, (void **) &cpcb) - != 1) - { - NSSBR_LOGERR ("malloc conn failed"); - return NULL; - } - - NSFW_LOGINF ("alloc_common_pcb]cpcb=%p", cpcb); - - common_pcb_init (cpcb); - cpcb->type = type; - - res_alloc (&cpcb->res_chk); - return cpcb; -} diff --git a/stacks/lwip_stack/lwip_src/api/spl_netbuf.c b/stacks/lwip_stack/lwip_src/api/spl_netbuf.c deleted file mode 100644 index 9c682fc..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_netbuf.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels <adam@sics.se> - * - */ -//#include "sc_dpdk.h" -#include "spl_netbuf.h" - -void -spl_netbuf_delete (struct spl_netbuf *buf) -{ - if (likely (buf != NULL)) - { - spl_pbuf_free (PTR_SHTOL (struct spl_pbuf *, buf->p)); - } -} diff --git a/stacks/lwip_stack/lwip_src/api/spl_netifapi.c b/stacks/lwip_stack/lwip_src/api/spl_netifapi.c deleted file mode 100644 index ab1446a..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_netifapi.c +++ /dev/null @@ -1,288 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "spl_opt.h" - -#if STACKX_NETIF_API - -#include "nsfw_msg_api.h" -#include "netifapi.h" -#include <sys/socket.h> -//#include <netinet/in.h> - -#include "stackx_spl_share.h" -#include "spl_sbr.h" -#include "stackx/spl_api.h" -#include "tcpip.h" -#include "sc_dpdk.h" -#include "spl_instance.h" -#include "spl_hal.h" -#include "spl_def.h" -#include <inet.h> - -struct netifExt *gNetifExt = NULL; - -/** - * common operation for sbr message. - * - * @param msg the api_msg_msg describing the connection type - */ -int -do_halmsg (data_com_msg * m) -{ - NSPOL_LOGDBG (TESTSOCKET_DEBUG | STACKX_DBG_TRACE, - "the msg is from HAL module, minor(%u)", m->param.minor_type); - return 0; -} - -static int -_do_add_netif (data_com_msg * m) -{ - NSPOL_LOGINF (NETIF_DEBUG, "_do_add_netif\n"); - - m->param.err = ERR_OK; - msg_add_netif *_m = (msg_add_netif *) m->buffer; - _m->function (_m); - SYNC_MSG_ACK (m); - return 0; -} - -struct netif * -find_netif_by_if_name (char *if_name) -{ - - struct netifExt *netifEx = gNetifExt; - struct netif *netif = NULL; - - while (netifEx != NULL) - { - if (!(strcmp (netifEx->if_name, if_name))) - { - for (netif = netif_list; netif != NULL; netif = netif->next) - { - if (netifEx->id == netif->num) - return netif; - } - - } - netifEx = netifEx->next; - } - - return NULL; -} - -/*@TODO: May be moved to some other file ? Like HAL*/ -struct netif * -get_netif_by_ip (unsigned int ip) -{ - struct netif *netif; - - if (ip == 0) - { - return NULL; - } - - for (netif = netif_list; netif != NULL; netif = netif->next) - { - if (ip == netif->ip_addr.addr) - { - NSPOL_LOGINF (NETIF_DEBUG, "netif_find: found %x %c %c", ip, - netif->name[0], netif->name[1]); - return netif; - } - } - NSPOL_LOGINF (NETIF_DEBUG, "netif_find: Not found %x", ip); - return NULL; -} - -/* -@TODO: -*/ -struct netif * -netif_check_broadcast_addr (spl_ip_addr_t * addr) -{ - return NULL; -} - -struct netifExt * -getNetifExt (u16_t id) -{ - - struct netifExt *netifEx; - netifEx = gNetifExt; - - while (netifEx != NULL) - { - if (netifEx->id == id) - { - return netifEx; - } - netifEx = netifEx->next; - } - - return NULL; -} - -int -netifExt_add (struct netif *netif) -{ - - /* If Netif Ext already created for it then just return sucess */ - if (getNetifExt (netif->num)) - return 0; - - struct netifExt *netifEx = malloc (sizeof (struct netifExt)); - if (!netifEx) - { - return -1; - } - - if (memset (netifEx, 0, sizeof (struct netifExt)) < 0) - { - return -1; - } - - NSPOL_LOGINF (NETIF_DEBUG, "netifExt_added \n"); - - netifEx->id = netif->num; - - /* add this netif to the list */ - netifEx->next = gNetifExt; - gNetifExt = netifEx; - return 0; -} - -void -do_netifapi_netif_add (msg_add_netif * pmsg) -{ - struct netif *netif = NULL; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gw; - - data_com_msg *m = MSG_ENTRY (pmsg, data_com_msg, buffer); - ipaddr.addr = pmsg->ipaddr->addr; - netmask.addr = pmsg->netmask->addr; - gw.addr = pmsg->gw->addr; - - NSPOL_LOGINF (NETIF_DEBUG, "do_netifapi_netif_add \n"); - netif = netif_add (pmsg->netif, - &ipaddr, - &netmask, &gw, pmsg->state, pmsg->init, pmsg->input); - - if (NULL == netif) - { - SET_MSG_ERR (m, ERR_IF); - } - else - { - - SET_MSG_ERR (m, ERR_OK); - NSPOL_LOGINF (NETIF_DEBUG, "netif created name %c%c%d\n", - netif->name[0], netif->name[1], netif->num); - pmsg->voidfunc (pmsg->netif); - add_disp_netif (pmsg->netif); - } - -} - -err_t -spl_netifapi_netif_add (struct netif *pnetif, - spl_ip_addr_t * ipaddr, - spl_ip_addr_t * netmask, - spl_ip_addr_t * gw, - void *state, - netif_init_fn init, - netif_input_fn input, netifapi_void_fn voidfunc) -{ - msg_add_netif stmsg; - - stmsg.function = do_netifapi_netif_add; - stmsg.netif = pnetif; - stmsg.ipaddr = ipaddr; - stmsg.netmask = netmask; - stmsg.gw = gw; - stmsg.state = state; - stmsg.init = init; - stmsg.input = input; - stmsg.voidfunc = voidfunc; - return tcpip_netif_add (&stmsg); -} - -int -add_netif_ip (char *netif_name, unsigned int ip, unsigned int mask) -{ - struct netif *pnetif; - int retval; - - if (get_netif_by_ip (ip)) - { - NSPOL_LOGERR ("ip is exist]IP=%s", inet_ntoa (ip)); - return -1; - } - NSPOL_LOGINF (NETIF_DEBUG, "add_netif_ip] IP=%s", inet_ntoa (ip)); - - pnetif = find_netif_by_if_name (netif_name); - if (pnetif == NULL) - { - return -1; - } - - pnetif->ip_addr.addr = ip; - pnetif->netmask.addr = mask; - - if (ip) - { - retval = etharp_request (pnetif, &pnetif->ip_addr); - - if (ERR_OK != retval) - { - NSPOL_LOGERR ("etharp_request failed]retval=%d,netif=%p,ip=%u", retval, pnetif, pnetif->ip_addr.addr); //inet_ntoa is not thread-safe, print u32 instead. - } - } - - NSPOL_LOGINF (NETIF_DEBUG, "add_netif_ip]netif_name=%s,IP=%s,mask=0x%08x", - netif_name, inet_ntoa (ip), spl_htonl (mask)); - return 0; -} - -/*lint -e438*/ -int -del_netif_ip (char *netif_name, unsigned int ip) -{ - struct netif *pnetif; - //struct netif* vnetif = NULL; - //struct netif** ref; - - pnetif = find_netif_by_if_name (netif_name); - if (NULL == pnetif) - { - return -1; - } - - NSPOL_LOGINF (NETIF_DEBUG, "del_netif_ip] IP=%s", inet_ntoa (ip)); - - pnetif->ip_addr.addr = 0; - pnetif->netmask.addr = 0; - return 0; -} - -REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_HAL, SPL_TCPIP_MSG_NETIFAPI, - do_halmsg); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_HAL, SPL_TCPIP_MSG_NETIFAPI, - NETIF_DO_ADD, _do_add_netif); - -#endif /* STACKX_NETIF_API */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_sbr.c b/stacks/lwip_stack/lwip_src/api/spl_sbr.c deleted file mode 100644 index 4c1be2f..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_sbr.c +++ /dev/null @@ -1,495 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "stackx_spl_share.h" -#include "spl_api.h" -#include "ip.h" -#include "spl_api_msg.h" -#include "stackx_spl_msg.h" -#include "internal_msg.h" -#include "spl_sbr.h" -#include "spl_pbuf.h" - -/** - * common operation for sbr message. - * - * @param msg the api_msg_msg describing the connection type - */ -int -do_sbrmsg (data_com_msg * m) -{ - return 0; -} - -/** - * Create a new pcb of a specific type inside a netconn. - * Called from netconn_new_with_proto_and_callback. - * - * @param msg the api_msg_msg describing the connection type - */ -static int -_do_newconn (data_com_msg * m) -{ - m->param.err = ERR_OK; - - msg_new_netconn *_m = (msg_new_netconn *) m->buffer; - m->param.err = spl_pcb_new (_m); - - if (ERR_OK != m->param.err) - { - NSPOL_LOGERR ("pcb_new err]conn=%p,pid=%u,err=%d", _m->conn, - m->param.recycle_pid, m->param.err); - goto ERROR; - } - - NSFW_LOGINF ("alloc pcb]conn=%p,pcb=%p,pid=%u", _m->conn, - _m->conn->private_data, m->param.recycle_pid); - - /* sbr use it to set receiver after new connction */ - m->param.receiver = (i64) & _m->conn->private_data; - m->param.comm_receiver = (i64) & _m->conn->comm_pcb_data; - _m->conn->recv_obj = m->param.receiver; - - SYNC_MSG_ACK (m); - return 0; - -ERROR: - SYNC_MSG_ACK (m); - return 0; -} - -int -_do_connect (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - m->param.err = ERR_CLSD; - SYNC_MSG_ACK (m); - return 0; - } - - msg_connect *_m = (msg_connect *) m->buffer; - do_connect (cpcb, _m); - - /** - * err == ERR_OK only applies for blocking connction, so others mean - * in progress for nonblocking connection or failed to connect - * cpcb may be NULL, so don't change the order of the 2 ifs. - */ - if (m->param.err != ERR_OK || cpcb->type != SPL_NETCONN_TCP) - SYNC_MSG_ACK (m); - - return 0; -} - -/** - * Close a TCP pcb contained in a netconn - * Called from netconn_close - * - * @param msg the api_msg_msg pointing to the connection - */ -int -_do_close (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb != NULL) - { - msg_close *_m = (msg_close *) m->buffer; - do_close (cpcb, _m); - } - - /* if cpcb == NULL, assuming the close is okay, err = ERR_OK */ - SYNC_MSG_ACK (m); - - return 0; -} - -/** - * Delete the pcb inside a netconn. - * Called from netconn_delete. - * - * @param msg the data_com_msg to handle - */ -static int -_do_delconn (data_com_msg * m) -{ - m->param.err = ERR_OK; - msg_delete_netconn *_m = (msg_delete_netconn *) m->buffer; - - if (0 == (--_m->msg_box_ref)) - { - /* the aync msg is released inside */ - ss_recycle_conn ((void *) _m, do_try_delconn); - } - - return 0; -} - -/** - * handle message to send UDP packets. - * - * @param msg the data_com_msg to handle - */ -static int -_do_send (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - msg_send_buf *_m = (msg_send_buf *) m->buffer; - if (cpcb == NULL) - { - NS_LOG_CTRL (LOG_CTRL_SEND, STACKX, "NSLWIP", NSLOG_ERR, - "failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - spl_pbuf_free (_m->p); - _m->p = NULL; - ASYNC_MSG_FREE (m); - return -1; - } - - do_send (cpcb, _m); - - ASYNC_MSG_FREE (m); - - return 0; -} - -/** - * handle message to send TCP packets. - * - * @param msg the data_com_msg to handle - */ -static int -_do_write (data_com_msg * m) -{ - m->param.err = ERR_OK; - - void *tpcb = TCP_PRIVATE_PTR (m); - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - - msg_write_buf *_m = (msg_write_buf *) m->buffer; - if ((tpcb == NULL) || (cpcb == NULL)) - { - NS_LOG_CTRL (LOG_CTRL_WRITE, STACKX, "NSLWIP", NSLOG_ERR, - "failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - spl_pbuf_free (_m->p); - _m->p = NULL; - ASYNC_MSG_FREE (m); - return -1; - } - - do_write (cpcb, _m); - - return 0; -} - -/** - * handle message to receive. - * - * @param msg the data_com_msg to handle - */ -static int -_do_recv (data_com_msg * m) -{ - m->param.err = ERR_OK; - - msg_recv_buf *_m = (msg_recv_buf *) m->buffer; - void *tpcb = TCP_PRIVATE_PTR (m); - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - - if ((tpcb == NULL) || (cpcb == NULL)) - { - NS_LOG_CTRL (LOG_CTRL_RECV, STACKX, "NSLWIP", NSLOG_ERR, - "failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - spl_pbuf_free (_m->p); - _m->p = NULL; - ASYNC_MSG_FREE (m); - return -1; - } - - do_recv (cpcb, _m); - ASYNC_MSG_FREE (m); - return 0; -} - -/** - * handle message to bind local address. - * - * @param msg the data_com_msg to handle - */ -static int -_do_bind (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - NSPOL_LOGERR ("failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - m->param.err = ERR_VAL; - SYNC_MSG_ACK (m); - return -1; - } - - msg_bind *_m = (msg_bind *) m->buffer; - do_bind (cpcb, _m); - - SYNC_MSG_ACK (m); - - return 0; -} - -/** - * handle message to listen for new connection. - * - * @param msg the data_com_msg to handle - */ -static int -_do_listen (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - NSPOL_LOGERR ("failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - m->param.err = ERR_CONN; - SYNC_MSG_ACK (m); - return -1; - } - - msg_listen *_m = (msg_listen *) m->buffer; - do_listen (cpcb, _m); - - /* Update since pcb may have been changed */ - //m->param.receiver = (i64)&_m->conn->private_data; - SYNC_MSG_ACK (m); - return 0; -} - -/** - * handle message to set socket option. - * - * @param msg the data_com_msg to handle - */ -static int -_do_setsockopt (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - - NSPOL_LOGERR ("failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - m->param.err = ERR_VAL; - SYNC_MSG_ACK (m); - return -1; - } - - msg_setgetsockopt *_m = (msg_setgetsockopt *) m->buffer; - do_setsockopt_internal (cpcb, _m); - - SYNC_MSG_ACK (m); - - return 0; -} - -/** - * handle message to get socket option. - * - * @param msg the data_com_msg to handle - */ -static int -_do_getsockopt (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - NSPOL_LOGERR ("failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - m->param.err = ERR_VAL; - SYNC_MSG_ACK (m); - return -1; - } - - msg_setgetsockopt *_m = (msg_setgetsockopt *) m->buffer; - do_getsockopt_internal (cpcb, _m); - - SYNC_MSG_ACK (m); - - return 0; -} - -/** - * handle message to free pbuf which never used afterwards by application. - * - * @param msg the data_com_msg to handle - */ - -static int -_do_pbuf_free (data_com_msg * m) -{ - m->param.err = ERR_OK; - - msg_free_buf *_m = (msg_free_buf *) m->buffer; - do_pbuf_free (_m->buf); - - ASYNC_MSG_FREE (m); - - return 0; -} - -static int -_do_getsock_name (data_com_msg * m) -{ - m->param.err = ERR_OK; - - struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); - if (cpcb == NULL) - { - NSPOL_LOGERR ("failed to find target pcb, drop the message]" - "module=%u, major=%u, minor=%u", - m->param.module_type, - m->param.major_type, m->param.minor_type); - - m->param.err = ERR_VAL; - SYNC_MSG_ACK (m); - return -1; - } - - msg_getaddrname *_m = (msg_getaddrname *) m->buffer; - do_getsockname (cpcb, _m); - - SYNC_MSG_ACK (m); - - return 0; -} - -/* app send its version info to nStackMain */ -static int -_do_app_touch (data_com_msg * m) -{ - m->param.err = ERR_OK; - - msg_app_touch *_m = (msg_app_touch *) m->buffer; - do_app_touch (_m); - - ASYNC_MSG_FREE (m); - return 0; -} - -/** - * process message from sbr module, all the processing function - * is registered when nstack is up. - * - * @param msg the api_msg_msg pointing to the connection - */ -int -spl_sbr_process (data_com_msg * m) -{ - if (m == NULL) - { - NSPOL_LOGERR ("message is NULL"); - return -1; - } - - return call_msg_fun (m); -} - -int -spl_unsupport_process (data_com_msg * m) -{ - NSPOL_LOGINF (TCPIP_DEBUG, "module_type=%u,major_type=%u,minor_type=%u", - m->param.module_type, m->param.major_type, - m->param.minor_type); - if (MSG_SYN_POST == m->param.op_type) - { - m->param.err = ERR_EPROTONOSUPPORT; - SYNC_MSG_ACK (m); - } - else - { - ASYNC_MSG_FREE (m); - } - - return -1; -} - -REGIST_MSG_UNSUPPORT_FUN (spl_unsupport_process); -REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - do_sbrmsg); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_NEWCONN, _do_newconn); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_CONNECT, _do_connect); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_CLOSE, _do_close); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_DELCON, _do_delconn); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_SEND, _do_send); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_WRITE, _do_write); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_RECV, _do_recv); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_BIND, _do_bind); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_LISTEN, _do_listen); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_GET_SOCK_OPT, _do_getsockopt); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_SET_SOCK_OPT, _do_setsockopt); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_PBUF_FREE, _do_pbuf_free); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, - SPL_API_DO_GETSOCK_NAME, _do_getsock_name); -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_APP_TOUCH, _do_app_touch); /* app send its version info to nStackMain */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_tcpip.c b/stacks/lwip_stack/lwip_src/api/spl_tcpip.c deleted file mode 100644 index b0b588a..0000000 --- a/stacks/lwip_stack/lwip_src/api/spl_tcpip.c +++ /dev/null @@ -1,1547 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "spl_opt.h" -#include <pthread.h> -#include <sched.h> -#include <signal.h> -#include "memp.h" -#include "mem.h" -#include "spl_pbuf.h" -//#include "sockets.h" -//#include <netinet/in.h> - -#include "stackx_spl_share.h" -#include "spl_api.h" -#include "spl_tcpip.h" -#include "init.h" -#include "stackx/internal_msg.h" -#include "netif/sc_dpdk.h" -#include "sharedmemory.h" -#include "stackx_instance.h" -#include "netif/common.h" -//#include "nettool/nettool.h" -#include "nstack_log.h" -#include "nstack_securec.h" -#include "spl_hal.h" -#include "spl_sbr.h" -#include "spl_tcpip.h" - -#include "spl_instance.h" -#include "nsfw_mem_api.h" -#include "nsfw_msg_api.h" -#include "configuration_reader.h" - -#include "nsfw_ps_api.h" -#include "alarm_api.h" -#include "nstack_share_res.h" -#include "spl_timers.h" - -#include "etharp.h" -#include "raw.h" -#include "udp.h" -#include "tcp.h" -#include "igmp.h" -#include "memp.h" -#include "inet.h" -#include "sys_arch.h" - -#include "sys.h" - -#define NSTACK_MAIN_MAX_PARA 32 -#define NSTACK_MAIN_MIN_PARA 1 - -#define DPDK_DEFAULT_EAL_MEM_SIZE (1024) - -#define OPT_EAL_MEM_SIZE "--eal-mem-size=" - -/********************/ -/* extern variables */ -/********************/ -extern mring_handle spl_get_msg_pool (); -extern mring_handle spl_get_conn_pool (); -extern u32 spl_get_conn_num (); -extern err_t ethernet_input (struct pbuf *p, struct netif *netif); - -/* tcpip main thread sleep time, configured by user(nStackMain "-sleep" option) */ -extern int g_tcpip_thread_sleep_time; - -/* netif related */ -extern struct stackx_port_info *head_used_port_list; - -extern u32_t uStackArgIndex; - -extern int g_tcpip_thread_stat; - -/********************/ -/* global variables */ -/********************/ - -/* timer thread id */ -sys_thread_t g_timerThread_id = 0; - -/*Add an associative mapping relationship to p_stackx_instance based on lcore_id */ - -int globalArgc = 0; - -/* Set different mem args to PAL and EAL */ -char **gArgv = NULL; - -int g_dpdk_argc = 0; -char **g_dpdk_argv = NULL; - -/*The sum of the four queue processing messages does not exceed TASK_BURST*/ -static u32 g_highestMboxNum = 12; -static u32 g_mediumMboxNum = 8; -static u32 g_lowestMboxNum = 4; -static u32 g_primaryMboxNum = 8; - -/* [set ip_tos2prio size to IPTOS_TOS_MASK >> 1) + 1] */ -u8_t ip_tos2prio[(IPTOS_TOS_MASK >> 1) + 1] = { - TC_PRIO_BESTEFFORT, - ECN_OR_COST (FILLER), - TC_PRIO_BESTEFFORT, - ECN_OR_COST (BESTEFFORT), - TC_PRIO_BULK, - ECN_OR_COST (BULK), - TC_PRIO_BULK, - ECN_OR_COST (BULK), - TC_PRIO_INTERACTIVE, - ECN_OR_COST (INTERACTIVE), - TC_PRIO_INTERACTIVE, - ECN_OR_COST (INTERACTIVE), - TC_PRIO_INTERACTIVE_BULK, - ECN_OR_COST (INTERACTIVE_BULK), - TC_PRIO_INTERACTIVE_BULK, - ECN_OR_COST (INTERACTIVE_BULK) -}; - -/********************/ -/* extern functions */ -/********************/ -extern err_t ethernetif_init (struct netif *pnetif); -extern int nstack_stackx_init (int flag); -extern void tcp_sys_rmem_init (); -extern void ethernetif_packets_input (struct netif *pstnetif); - -/********************************/ -/* function forward declaration */ -/********************************/ - -static inline u32 priority_sched_mbox (struct stackx_stack *share_memory, - void **box, u32 n); -static inline char -rt_tos2priority (u8_t tos) -{ - return ip_tos2prio[IPTOS_TOS (tos) >> 1]; -} - -u64 -timer_get_threadid () -{ - return g_timerThread_id; -} - -#if (DPDK_MODULE != 1) -NSTACK_STATIC inline void -do_recv_task (struct disp_netif_list *dnlist, u16 index_task) -{ - struct netifExt *pnetifExt = NULL; - - while (dnlist) - { - struct netif *currentNetif = dnlist->netif; - dnlist = dnlist->next; - - pnetifExt = getNetifExt (currentNetif->num); - if (NULL == pnetifExt) - return; - - if (currentNetif != NULL && pnetifExt->num_packets_recv > index_task) - { - ethernetif_packets_input (currentNetif); - } - } -} - -static inline int -is_valid_sleep_time (int sleep_time) -{ -#define TCP_IP_THREAD_MAX_SLEEP_TIME 500 - if ((sleep_time < 0) || (sleep_time > TCP_IP_THREAD_MAX_SLEEP_TIME)) - { - return 0; - } - - return 1; -} - -static int -thread_init () -{ - sigset_t mask; - - if (0 != sigemptyset (&mask)) - { - NSTCP_LOGERR ("sigemptyset function call error"); - return -1; - } - - if (0 != sigaddset (&mask, SIGRTMIN)) - { - NSTCP_LOGERR ("sigaddset function call error"); - return -1; - } - - if ((pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0) - || (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0)) - { - NSTCP_LOGERR ("pthread setcancel function call error"); - return -1; - } - - if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0) - { - NSPOL_LOGERR ("pthread_sigmask function call error"); - return -1; - } - - return 0; -} - -alarm_result -spl_socket_resource_check_func (void) -{ - - mring_handle conn_ring = spl_get_conn_pool (); - unsigned int rate_use = 0; - alarm_result ret_alarm; - u32 ring_size = 0, ring_not_used_count = 0; - u32 socket_num = spl_get_conn_num (); - - ring_size = nsfw_mem_ring_size (conn_ring); - - if (0 == socket_num) - { - /* assign a valid id, then return */ - ret_alarm.alarm_id_get = ALARM_EVENT_MAX; - return ret_alarm; - } - - ring_not_used_count = nsfw_mem_ring_using_count (conn_ring); - - rate_use = (ring_size - ring_not_used_count) * 100 / socket_num; - - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - - if (rate_use >= USEAGE_HIGHT) - { - ret_alarm.alarm_flag_get = ALARM_PRODUCT; - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - NSPOL_LOGWAR (TCPIP_DEBUG, - "app using too much socket resources,the rate is bigger than 80%"); - } - else if (rate_use <= USEAGE_LOW) - { - ret_alarm.alarm_flag_get = ALARM_CLEAN; - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - } - else - { - ret_alarm.alarm_id_get = ALARM_EVENT_MAX; - } - - ret_alarm.alarm_reason_get = ALARM_REASON_SOCKET; - - return ret_alarm; - -} - -alarm_result -spl_msg_buf_resource_check_func (void) -{ - - mring_handle msg_ring = spl_get_msg_pool (); - unsigned int rate_use = 0; - alarm_result ret_alarm; - u32 ring_size = 0, ring_not_used_count = 0; - - ring_size = nsfw_mem_ring_size (msg_ring); - - if (0 == ring_size) - { - /* assign a valid id, then return */ - ret_alarm.alarm_id_get = ALARM_EVENT_MAX; - return ret_alarm; - } - - ring_not_used_count = nsfw_mem_ring_using_count (msg_ring); - - rate_use = (ring_size - ring_not_used_count) * 100 / ring_size; - - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - - if (rate_use >= USEAGE_HIGHT) - { - ret_alarm.alarm_flag_get = ALARM_PRODUCT; - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - } - else if (rate_use <= USEAGE_LOW) - { - ret_alarm.alarm_flag_get = ALARM_CLEAN; - ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; - } - else - { - ret_alarm.alarm_id_get = ALARM_EVENT_MAX; - } - - ret_alarm.alarm_reason_get = ALARM_REASON_MSG_BUF; - - return ret_alarm; - -} - -NSTACK_STATIC int -tcpip_thread_init () -{ - if (thread_init () != 0) - { - return -1; - } - - if (!is_valid_sleep_time (g_tcpip_thread_sleep_time)) - { - g_tcpip_thread_sleep_time = 0; - } - - alarm_para tcp_alarm_para; - tcp_alarm_para.period_alarm.time_length = 5; /* 5 second period */ - tcp_alarm_para.alarm_reason_count = 2; /*both resource */ - tcp_alarm_para.func_alarm_check_period[0] = spl_socket_resource_check_func; - tcp_alarm_para.alarm_reason_set[0] = ALARM_REASON_SOCKET; - tcp_alarm_para.func_alarm_check_period[1] = spl_msg_buf_resource_check_func; - tcp_alarm_para.alarm_reason_set[1] = ALARM_REASON_MSG_BUF; - (void) ns_reg_alarm (ALARM_EVENT_NSTACK_RESOURCE_ALARM, ALARM_PERIOD_CHECK, - &tcp_alarm_para); - - ns_send_init_alarm (ALARM_EVENT_NSTACK_RESOURCE_ALARM); - - printmeminfo (); - return 0; -} - -sys_mbox_t -get_primary_box () -{ - return &p_def_stack_instance->lstack.primary_mbox; -} - -NSTACK_STATIC inline u16 -tcpip_netif_recv (struct disp_netif_list * nif_list) -{ - - u16 num_recv_task = 0, netif_packet_num; - - struct netif *tmpnetif = NULL; - struct netifExt *pnetifExt = NULL; - - while (nif_list) - { - tmpnetif = nif_list->netif; - - netif_packet_num = spl_hal_recv (tmpnetif, 0); - pnetifExt = getNetifExt (tmpnetif->num); - if (NULL == pnetifExt) - return 0; - - /* store the packet number in each netif */ - pnetifExt->num_packets_recv = netif_packet_num; - - /** - * num_recv_task is the maximum packets of the netif among - * all the netifs. - */ - if (num_recv_task < netif_packet_num) - { - num_recv_task = netif_packet_num; - } - - nif_list = nif_list->next; - } - - return num_recv_task; -} - -NSTACK_STATIC inline void -no_task_in_one_loop () -{ -} - -#endif - -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet, p->payload pointing to the Ethernet header or - * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or - * SPL_NETIF_FLAG_ETHERNET flags) - * @param inp the network interface on which the packet was received - */ -err_t -spl_tcpip_input (struct pbuf *p, struct netif *inp) -{ - err_t ret; - NSPOL_LOGINF (TCPIP_DEBUG, "PACKET]p=%p,inp=%p", (void *) p, (void *) inp); - print_pbuf_payload_info (p, false); - - /* every netif has been set NETIF_FLAG_ETHARP flag, no need else branch */ - ret = ethernet_input (p, inp); - return ret; -} - -int -_do_spl_callback_msg (data_com_msg * m) -{ - NSPOL_LOGDBG (TCPIP_DEBUG, "tcpip_thread: CALLBACK]msg=%p", (void *) m); - - m->param.err = ERR_OK; - - msg_internal_callback *callback = (msg_internal_callback *) (m->buffer); - if (!callback->function) - { - NSTCP_LOGERR ("function ptr is null in SPL_TCPIP_MSG_CALLBACK msg"); - ASYNC_MSG_FREE (m); - return 0; - } - - callback->function (callback->ctx); - ASYNC_MSG_FREE (m); - - return 0; -} - -/***************************************************************************** -* Prototype : get_msgbox -* Description : According to the socket tos value to determine which priority queue to send -* Input : struct stackx_stack *sharedmemory, struct netconn *conn, enum api_msg_type type -* Output : Queue pointer -* Return Value : Queue pointer -* Calls : -* Called By : -* -*****************************************************************************/ -struct queue * -get_msgbox (int tos) -{ - struct stackx_stack *sharedmemory = &p_def_stack_instance->lstack; - - if ((MSG_PRIO_QUEUE_NUM < 3) || (0 == tos)) - { - return &sharedmemory->primary_mbox; - } - - char prio = rt_tos2priority ((u8_t) tos); - if ((TC_PRIO_INTERACTIVE == prio)) - { - NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the highest mbox....."); - return &sharedmemory->priority_mbox[0]; - } - else if ((TC_PRIO_BESTEFFORT == prio) || (TC_PRIO_INTERACTIVE_BULK == prio)) - { - NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the medium mbox....."); - return &sharedmemory->priority_mbox[1]; - } - else if ((TC_PRIO_BULK == prio) || (TC_PRIO_FILLER == prio)) - { - NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the lowest mbox....."); - return &sharedmemory->priority_mbox[2]; - } - - NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the primary mbox....."); - return &sharedmemory->primary_mbox; -} - -/***************************************************************************** -* Prototype : priority_sched_mbox -* Description : According to the priority from the message queue to take -* the message to deal with each cycle to take the total number of messages -* not exceed to TASK_BURST -* Input : struct stackx_stack *sharedmemory, struct netconn *conn, enum api_msg_type type -* Output : Queue pointer -* Return Value : Queue pointer -* Calls : -* Called By : -* -*****************************************************************************/ -static inline u32 -priority_sched_mbox (struct stackx_stack *share_memory, void **box, u32 n) -{ - /* high:primary:medium:low -> 3:2:2:1(total:TASK_BURST) */ - if (unlikely - ((g_highestMboxNum + g_mediumMboxNum + g_primaryMboxNum + - g_lowestMboxNum) != n)) - { - g_mediumMboxNum = n >> 2; - g_lowestMboxNum = n >> 3; - g_primaryMboxNum = n >> 2; - g_highestMboxNum = - n - g_mediumMboxNum - g_primaryMboxNum - g_lowestMboxNum; - } - - u32 highestMboxNum = g_highestMboxNum; - u32 primaryMboxNum = g_primaryMboxNum; - u32 lowestMboxNum = g_lowestMboxNum; - u32 mediumMboxNum = g_mediumMboxNum; - - u32 totalNum = 0; - u32 num = 0; - u32 oldLowestNum = 0; - - num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[0].llring, - (box + totalNum), highestMboxNum); - if (unlikely (num > highestMboxNum)) - { - num = highestMboxNum; - NSTCP_LOGERR - ("something wrong:num>highestMboxNum]num=%u,highestMboxNum=%u", num, - highestMboxNum); - } - - totalNum += num; - - u32 temp = highestMboxNum - num; - /* bisect the left number of highest */ - primaryMboxNum += (temp >> 1); - mediumMboxNum += temp - (temp >> 1); - - num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[1].llring, - (box + totalNum), mediumMboxNum); - if (unlikely (num > mediumMboxNum)) - { - num = mediumMboxNum; - NSTCP_LOGERR - ("something wrong.num>mediumMboxNum]num=%u,mediumMboxNum=%u", num, - mediumMboxNum); - } - - totalNum += num; - primaryMboxNum += mediumMboxNum - num; //occupy the left number of medium - - /* dynamically adjust g_mediumMboxNum and g_highestMboxNum, according to 'num' */ - oldLowestNum = g_mediumMboxNum; - if (0 == num) - { - g_mediumMboxNum = 1; - } - else if (num < g_mediumMboxNum) - { - g_mediumMboxNum = num; - } - else - { - g_mediumMboxNum = n >> 2; - } - - g_highestMboxNum += oldLowestNum - g_mediumMboxNum; - - num = nsfw_mem_ring_dequeuev (share_memory->primary_mbox.llring, - (box + totalNum), primaryMboxNum); - if (unlikely (num > primaryMboxNum)) - { - num = primaryMboxNum; - NSTCP_LOGERR - ("something wrong.num>primaryMboxNum]num=%u,primaryMboxNum=%u", num, - primaryMboxNum); - } - - totalNum += num; - lowestMboxNum += primaryMboxNum - num; //occupy the left number of primary - - /* dynamically adjust g_primaryMboxNum and g_highestMboxNum, according to 'num' */ - oldLowestNum = g_primaryMboxNum; - if (0 == num) - { - g_primaryMboxNum = 1; - } - else if (num < g_primaryMboxNum) - { - g_primaryMboxNum = num; - } - else - { - g_primaryMboxNum = n >> 2; - } - - g_highestMboxNum += oldLowestNum - g_primaryMboxNum; - - if (lowestMboxNum > (n - totalNum)) - { - lowestMboxNum = n - totalNum; - } - - num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[2].llring, - (box + totalNum), lowestMboxNum); - if (unlikely (num > lowestMboxNum)) - { - num = lowestMboxNum; - NSTCP_LOGERR - ("something wrong.num>lowestMboxNum]num=%u,lowestMboxNum=%u", num, - lowestMboxNum); - } - - totalNum += num; - - /* dynamically adjust g_lowestMboxNum and g_highestMboxNum, according to 'num' */ - oldLowestNum = g_lowestMboxNum; - if (0 == num) - { - g_lowestMboxNum = 1; - } - else if (num < g_lowestMboxNum) - { - g_lowestMboxNum = num; - } - else - { - g_lowestMboxNum = n >> 3; - } - - g_highestMboxNum += oldLowestNum - g_lowestMboxNum; - - return totalNum; -} - -/** - * call ltt_apimsg in STACKX TIMER THREAD - * - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return error code given back by the function that was called - */ -err_t -ltt_apimsg (sys_timeout_handler h, void *arg) -{ - data_com_msg *p_msg_entry; - sys_mbox_t mbox = get_primary_box (); - if (sys_mbox_valid (&mbox)) - { - if (-1 == spl_msg_malloc (&p_msg_entry)) - { - NSPOL_LOGERR ("ltt_apimsg:spl_msg_malloc failed."); - return -1; - } - - p_msg_entry->param.module_type = MSG_MODULE_TIMER; - p_msg_entry->param.major_type = SPL_TCPIP_MSG_TIMER; - p_msg_entry->param.minor_type = TIMER_MSG_TIMEOUT; - p_msg_entry->param.op_type = MSG_ASYN_POST; - - sys_sem_init (&p_msg_entry->param.op_completed); - - msg_timer *tmsg = (msg_timer *) (p_msg_entry->buffer); - tmsg->act = h; - tmsg->arg = arg; - - if (msg_post (p_msg_entry, mbox->llring) < 0) - { - NSPOL_LOGERR - ("msg post is failed]module_type=%u, major_type=%u, minor_type=%u", - p_msg_entry->param.module_type, p_msg_entry->param.major_type, - p_msg_entry->param.minor_type); - spl_msg_free (p_msg_entry); - return ERR_VAL; - } - - return ERR_OK; - } - - NSPOL_LOGERR ("mbox is invalid"); - return ERR_VAL; -} - -int -_do_spl_timer_msg (data_com_msg * m) -{ - NSPOL_LOGDBG (TESTSOCKET_DEBUG | STACKX_DBG_TRACE, - "the msg is from TIMER module, minor(%u)", - m->param.minor_type); - return 0; -} - -static int -_do_timeout_handle (data_com_msg * m) -{ - m->param.err = ERR_OK; - msg_timer *tmo_msg = (msg_timer *) m->buffer; - if (!tmo_msg->act) - { - NSTCP_LOGERR ("TIMER_MSG_TIMEOUT msg act is NULL"); - ASYNC_MSG_FREE (m); - return -1; - } - - timeout_phandler (tmo_msg->act, tmo_msg->arg); - ASYNC_MSG_FREE (m); - return 0; -} - -static int -_do_clear_timer (data_com_msg * m) -{ - NSTCP_LOGDBG ("TIMER_CLEAR API]msg=%p", (void *) m); - - msg_timer *handle = (msg_timer *) (m->buffer); - if (!handle->act) - { - NSTCP_LOGERR ("function ptr is null in TIMER_MSG_CLEAR msg"); - SET_MSG_ERR (m, ERR_VAL); - return 0; - } - - //stackxTcpPcbClearTimer((struct tcp_pcb *)handle->act, (unsigned long)handle->arg); - spl_msg_free (m); - - return 0; -} - -err_t -ltt_clearTmrmsg (void *pcb, void *arg) -{ - data_com_msg *p_msg_entry; - sys_mbox_t mbox = get_primary_box (); - if (sys_mbox_valid (&mbox)) - { - if (-1 == spl_msg_malloc (&p_msg_entry) || (NULL == p_msg_entry)) - { - NSPOL_LOGERR ("ltt_clearTmrmsg:spl_msg_malloc failed."); - return -1; - } - - p_msg_entry->param.module_type = MSG_MODULE_TIMER; - p_msg_entry->param.major_type = SPL_TCPIP_MSG_TIMER; - p_msg_entry->param.minor_type = TIMER_MSG_CLEAR; - p_msg_entry->param.op_type = MSG_ASYN_POST; - p_msg_entry->param.receiver = 0; - sys_sem_init (&p_msg_entry->param.op_completed); - - msg_timer *tmo = (msg_timer *) (p_msg_entry->buffer); - tmo->act = pcb; - tmo->arg = arg; - - if (msg_post (p_msg_entry, mbox->llring) < 0) - { - NSPOL_LOGERR - ("msg post is failed]module_type=%u, major_type=%u, minor_type=%u", - p_msg_entry->param.module_type, p_msg_entry->param.major_type, - p_msg_entry->param.minor_type); - spl_msg_free (p_msg_entry); - return ERR_VAL; - } - - return ERR_OK; - } - - NSPOL_LOGERR ("mbox is invalid"); - return ERR_VAL; -} - -#if STACKX_NETIF_API -err_t -tcpip_netif_post (data_com_msg * m) -{ - err_t err = ERR_OK; - sys_mbox_t mbox = get_primary_box (); - - if (NULL == mbox || !sys_mbox_valid (&mbox)) - { - NSPOL_LOGERR ("mbox not initialed well"); - err = ERR_MEM; - goto err_exit; - } - - if (NULL == mbox->llring) - { - int tryCount = 0; -#define TCP_NETIF_WAITINIT_MAX_COUNT 10 - NSPOL_LOGWAR (TCPIP_DEBUG, "mbox->llring not initialed yet..."); - sys_sleep_ns (0, 100000000); - while (!mbox->llring && (++tryCount < TCP_NETIF_WAITINIT_MAX_COUNT)) - { - NSPOL_LOGWAR (TCPIP_DEBUG, "mbox->llring not initialed yet..."); - sys_sleep_ns (0, 100000000); - } - - if (NULL == mbox->llring) - { - NSPOL_LOGERR ("failed to get a valid mbox->llring"); - err = ERR_MEM; - goto err_exit; - } - } - - NSPOL_LOGINF (TCPIP_DEBUG, "post tcpip_netif_msg..."); - - if (msg_post_with_lock_rel (m, mbox->llring) < 0) - { - err = ERR_VAL; - } - else - { - err = m->param.err; - } - -err_exit: - /* it's a sync message */ - spl_msg_free (m); - return err; -} - -/** - * Much like tcpip_apimsg, but calls the lower part of a netifapi_* - * function. - * - * @param netifapimsg a struct containing the function to call and its parameters - * @return error code given back by the function that was called - */ -err_t -tcpip_netif_add (msg_add_netif * tmp) -{ - data_com_msg *p_msg_entry = NULL; - msg_add_netif *nmsg = NULL; - - if (spl_msg_malloc (&p_msg_entry) == -1) - { - NSPOL_LOGERR ("tcpip_netifapi:spl_msg_malloc failed."); - return ERR_MEM; - } - - p_msg_entry->param.module_type = MSG_MODULE_HAL; - p_msg_entry->param.major_type = SPL_TCPIP_MSG_NETIFAPI; - p_msg_entry->param.minor_type = NETIF_DO_ADD; - p_msg_entry->param.op_type = MSG_SYN_POST; - p_msg_entry->param.receiver = 0; - sys_sem_init (&p_msg_entry->param.op_completed); - - nmsg = (msg_add_netif *) p_msg_entry->buffer; - nmsg->function = tmp->function; - nmsg->netif = tmp->netif; - nmsg->ipaddr = tmp->ipaddr; - nmsg->netmask = tmp->netmask; - nmsg->gw = tmp->gw; - nmsg->state = tmp->state; - nmsg->init = tmp->init; - nmsg->input = tmp->input; - nmsg->voidfunc = tmp->voidfunc; - - return tcpip_netif_post (p_msg_entry); -} - -#endif /* STACKX_NETIF_API */ - -/* Added for congestion control, maybe not used end */ - -extern err_t init_ptimer (void); -extern struct cfg_item_info g_cfg_item_info[CFG_SEG_MAX][MAX_CFG_ITEM]; - -/*=========== set share config for nStackMain =============*/ -static inline mzone_handle -create_mem_zone (nsfw_mem_zone * zone_info) -{ - return nsfw_mem_zone_create (zone_info); -} - -static inline int -set_zone_info (nsfw_mem_zone * zone_info, nsfw_mem_name * name_info, u32 len) -{ - if (EOK != - MEMCPY_S (&(zone_info->stname), sizeof (nsfw_mem_name), name_info, - sizeof (nsfw_mem_name))) - { - NSPOL_DUMP_LOGERR ("create pool failed, MEMCPY_S failed."); - return -1; - } - - zone_info->length = len; - zone_info->isocket_id = NSFW_SOCKET_ANY; - - return 0; -} - -int -set_share_config () -{ - static nsfw_mem_name g_cfg_mem_info = - { NSFW_SHMEM, NSFW_PROC_MAIN, NSTACK_SHARE_CONFIG }; - - nsfw_mem_zone zone_info; - if (set_zone_info (&zone_info, &g_cfg_mem_info, get_cfg_share_mem_size ()) < - 0) - { - return -1; - } - - mzone_handle base_cfg_mem = create_mem_zone (&zone_info); - if (NULL == base_cfg_mem) - { - NSPOL_LOGERR ("get config share mem failed."); - return -1; - } - - if (set_share_cfg_to_mem (base_cfg_mem) < 0) - { - NSPOL_LOGERR ("set share config failed."); - return -1; - } - - return 0; -} - -int -init_by_tcpip_thread () -{ - if (spl_init_app_res () != 0) - { - NSPOL_LOGERR ("spl_init_app_res failed"); - return -1; - } - - if (init_instance () != 0) - { - return -1; - } - if (tcpip_thread_init () != 0) - { - NSTCP_LOGERR ("tcpip_thread_init failed!"); - return -1; - } - - init_stackx_lwip (); - - return 0; -} - -void -spl_tcpip_thread (void *arg) -{ - g_tcpip_thread_stat = 1; - - if (init_by_tcpip_thread () != 0) - { - return; - } - - struct stackx_stack *share_memory = &p_def_stack_instance->lstack; - struct disp_netif_list **iflist = &p_def_stack_instance->netif_list; - - u32 run_count = 0; - u16 task_loop; - u16 num_recv_task = 0, num_send_timer_task = 0; - u16 index_task = 0; - //int tcpip_thread_sleep_interval = g_tcpip_thread_sleep_time * 1000; - void *task_queue[TASK_BURST]; - data_com_msg *msg; - - while (1) - { - /* try to receive packet from hal layer */ - num_recv_task = tcpip_netif_recv (*iflist); - - /* try to receive message from sbr layer */ - num_send_timer_task = priority_sched_mbox (share_memory, - task_queue, TASK_BURST); - - if (num_recv_task) - { - NSPOL_LOGINF (TCPIP_DEBUG, "num_recv_task %d", num_recv_task); - } - - /* Statistics the total number of messages */ - - /* Separate statistics on socket api messages */ - /* handle the request from upper layer and lower layer one by one */ - task_loop = (num_send_timer_task > num_recv_task ? - num_send_timer_task : num_recv_task); - if (task_loop == 0) - { - no_task_in_one_loop (); - - if (run_count++ > 20) - { - //sys_sleep_ns (0, tcpip_thread_sleep_interval); - } - continue; - } - - run_count = 0; - index_task = 0; - - /* at least one task to be handled */ - while (task_loop > index_task) - { - /* handle one packet from hal layer (for multi-nic case, do it for each) */ - if (num_recv_task > index_task) - { - do_recv_task (*iflist, index_task); - } - - /* handle one message from sbr layer */ - if (num_send_timer_task > index_task) - { - msg = (data_com_msg *) (task_queue[index_task]); - - spl_process (msg); - } - - do_update_pcbstate (); - - index_task++; - } - } -} - -int -create_tcpip_thread () -{ - int ret; - u64 arg = 0; - - /* main tcpip thread */ - char thread_name[32] = TCPIP_THREAD_NAME; - - sys_thread_t thread = sys_thread_new (thread_name, spl_tcpip_thread, - (void *) arg, - TCPIP_THREAD_STACKSIZE, - g_cfg_item_info[CFG_SEG_PRI] - [CFG_SEG_THREAD_PRI_PRI].value); - - cpu_set_t cpuset; - CPU_ZERO (&cpuset); /*lint !e534 */ - CPU_SET (g_nstack_bind_cpu, &cpuset); /*lint !e522 */ - ret = pthread_setaffinity_np (thread, sizeof (cpuset), &cpuset); - if (ret != 0) - { - NSPOL_LOGERR ("pthread_setaffinity_np failed]thread_name=%s,ret=%d", - TCPIP_THREAD_NAME, ret); - } - - return 0; -} - -int -create_timer_thread () -{ -#if 1 - if (init_ptimer () != ERR_OK) - { - NSPOL_LOGERR ("init_ptimer failed"); - return -1; - } - - sys_thread_t thread_timer = - sys_thread_new (PTIMER_THREAD_NAME, ptimer_thread, NULL, - TCPIP_THREAD_STACKSIZE, 0); - cpu_set_t cpuset_timer; - CPU_ZERO (&cpuset_timer); - CPU_SET (1, &cpuset_timer); - int ret = pthread_setaffinity_np (thread_timer, sizeof (cpuset_timer), - &cpuset_timer); - if (ret != 0) - { - NSPOL_LOGERR ("TCP init Timer Trhead Failed!"); - } - - g_timerThread_id = thread_timer; -#endif - return 0; -} - -int -init_ip_module_reader () -{ - output_api api = { 0 }; - api.post_to = post_ip_module_msg; - api.add_netif_ip = add_netif_ip; - api.del_netif_ip = del_netif_ip; - regist_output_api (&api); - - if (init_configuration_reader () < 0) - { - NSPOL_LOGERR ("init_configuration_reader failed"); - return -1; - } - - return 0; -} - -extern int init_unmatch_version (void); -extern int init_stackx_global_tick (void); - -int -init_by_main_thread () -{ - NSPOL_LOGINF (TCPIP_DEBUG, "init_by_main_thread start version 1.4"); - - uStackArgIndex++; - if (spl_hal_init (g_dpdk_argc, (char **) g_dpdk_argv) < 0) - { - NSPOL_LOGERR ("spl_hal_init failed"); - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 1"); - - if (init_unmatch_version () != 0) - { - return -1; - } - - NSPOL_LOGINF (TCPIP_DEBUG, "stage 2"); - if (init_stackx_global_tick () != 0) - { - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 3"); - - if (spl_init_group_array () != 0) - { - NSPOL_LOGERR ("spl_init_group_array failed"); - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 4"); - - if (set_share_config () != 0) - { - NSPOL_LOGERR ("set_share_config failed."); - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 5"); - - if (create_timer_thread () != 0) - { - //NSPOL_LOGERR(TCPIP_DEBUG,"init_timer_thread failed."); - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 6"); - - if (create_tcpip_thread () != 0) - { - NSPOL_LOGERR ("init_tcpip_thread failed."); - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage 7"); - - if (init_ip_module_reader () != 0) - { - return -1; - } - NSPOL_LOGINF (TCPIP_DEBUG, "stage end"); - - return 0; -} - -void -create_netif (struct stackx_port_info *p_port_info) -{ - int ret; - struct spl_ip_addr ip, mask, gw; - struct netifExt *netifEx = NULL; - struct netif *netif = malloc (sizeof (struct netif)); - if (!netif) - { - NSPOL_LOGERR ("malloc failed"); - return; - } - - if (MEMSET_S (netif, sizeof (struct netif), 0, sizeof (struct netif)) < 0) - { - NSPOL_LOGERR ("MEMSET_S failed"); - goto error; - } - - NSPOL_LOGINF (TCPIP_DEBUG, "I get netif]ip=%s,gw=%s,mask=%s,name=%c %c", - p_port_info->linux_ip.ip_addr_linux, - p_port_info->linux_ip.ip_addr_linux, - p_port_info->linux_ip.mask_linux, - netif->name[0], netif->name[1]); - - if (inet_aton (p_port_info->linux_ip.ip_addr_linux, &ip) - && inet_aton (p_port_info->linux_ip.ip_addr_linux, &gw) - && inet_aton (p_port_info->linux_ip.mask_linux, &mask)) - { - ret = - spl_netifapi_netif_add (netif, &ip, &mask, &gw, NULL, ethernetif_init, - spl_tcpip_input, netif_set_up); - if (ERR_OK != ret) - { - NSPOL_LOGERR ("netifapi_netif_add failed]ret=%d", ret); - goto error; - } -#if 1 - if (0 != netifExt_add (netif)) - return; - -#endif - netifEx = getNetifExt (netif->num); - if (NULL == netifEx) - return; - - netifEx->hdl = p_port_info->linux_ip.hdl; - ret = - STRCPY_S (netifEx->if_name, sizeof (netifEx->if_name), - p_port_info->linux_ip.if_name); - if (EOK != ret) - { - NSPOL_LOGERR ("STRCPY_S failed]ret=%d", ret); - goto error; - } - return; - } - -error: - free (netif); -} - -int -post_ip_module_msg (void *arg, ip_module_type Type, - ip_module_operate_type operate_type) -{ - data_com_msg *p_msg_entry; - msg_ip_module *imsg; - sys_mbox_t mbox = get_primary_box (); - - if (!mbox) - { - NSOPR_LOGERR ("get_cur_mbox failed"); - return ERR_MEM; - } - - if (sys_mbox_valid (&mbox)) - { - if (spl_msg_malloc (&p_msg_entry) == -1) - { - NSOPR_LOGERR ("ip_route_apimsg:spl_msg_malloc failed."); - return ERR_MEM; - } - - sys_sem_init (&p_msg_entry->param.op_completed); - p_msg_entry->param.module_type = MSG_MODULE_IP; - p_msg_entry->param.op_type = MSG_SYN_POST; - - imsg = (msg_ip_module *) (p_msg_entry->buffer); - imsg->arg = arg; - imsg->type = Type; - imsg->operate_type = operate_type; - - NSOPR_LOGINF ("post ip_module msg to tcpip_thread]action=%d,type=%d", - operate_type, Type); - - if (msg_post (p_msg_entry, mbox->llring) != 0) - { - NSOPR_LOGERR - ("msg_post failed,this can not happen]action=%d,type=%d", - operate_type, Type); - } - - spl_msg_free (p_msg_entry); - - return ERR_OK; - } - - NSOPR_LOGERR ("mbox is invalid"); - return ERR_VAL; -} - -int -process_ip_module_msg (void *arg, ip_module_type module_type, - ip_module_operate_type operate_type) -{ - int retval = process_configuration (arg, module_type, operate_type); - - NSOPR_LOGINF ("tcpip_thread: ip_module cmd exec over, send SYNC_MSG_ACK"); - return retval; -} - -int -init_new_network_configuration () -{ - if (spl_hal_port_init () < 0) - { - return -1; - } - - return 0; -} - -static int -_process_ip_module_msg (data_com_msg * m) -{ - m->param.err = ERR_OK; - msg_ip_module *_m = (msg_ip_module *) m->buffer; - int ret = process_ip_module_msg (_m->arg, _m->type, _m->operate_type); - SYNC_MSG_ACK (m); - return ret; -} - -int -spl_post_msg (u16 mod, u16 maj, u16 min, u16 op, char *data, u16 data_len, - u32 src_pid) -{ - data_com_msg *p_msg_entry; - - sys_mbox_t mbox = get_primary_box (); - if (!sys_mbox_valid (&mbox)) - { - NSPOL_LOGERR - ("get mbox null!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", mod, maj, - min, op, data, data_len); - return ERR_MEM; - } - - if (spl_msg_malloc (&p_msg_entry) == -1) - { - NSPOL_LOGERR ("get msg null!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", - mod, maj, min, op, data, data_len); - return ERR_MEM; - } - - sys_sem_init (&p_msg_entry->param.op_completed); - p_msg_entry->param.module_type = mod; - p_msg_entry->param.major_type = maj; - p_msg_entry->param.minor_type = min; - p_msg_entry->param.op_type = op; - p_msg_entry->param.src_pid = src_pid; - - int retVal; - if (NULL != data) - { - retVal = - MEMCPY_S ((char *) p_msg_entry->buffer, sizeof (p_msg_entry->buffer), - data, data_len); - if (EOK != retVal) - { - NSPOL_LOGERR ("MEMCPY_S failed %d.", retVal); - spl_msg_free (p_msg_entry); - return ERR_MEM; - } - } - - if (msg_post_with_lock_rel (p_msg_entry, mbox->llring) != 0) - { - NSPOL_LOGERR - ("post msg error!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", mod, - maj, min, op, data, data_len); - spl_msg_free (p_msg_entry); - return ERR_MEM; - } - - if (MSG_SYN_POST == op) - { - spl_msg_free (p_msg_entry); - } - - NSOPR_LOGDBG ("post msg suc!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", - mod, maj, min, op, data, data_len); - return ERR_OK; -} - -/* -* Added by eliminate duplicated code degree, the function is moved to the public places -*adjust memory size for pal and eal mem size: this func do the following things: -*1. copy argv to gArgv and g_dpdk_argv -*2. remove OPT_EAL_MEM_SIZE option so that the rtp and rte options process won't reprt unrecognized option error. -*3. set eal mem size and pal_mem_size = mem - eal_mem_size -*/ -int -adjust_mem_arg (int argc, char *argv[]) -{ - int i = 0; - int j = 0; - int retVal; - char *tmp = NULL; - char *tmp2 = NULL; - int arg_mem_index = -1; - char *saveptr1 = NULL; - int mem_size = 0; - int mem_size_parsed = 0; // if multi -m argument is set, then only deal with the first one - int eal_mem_size = DPDK_DEFAULT_EAL_MEM_SIZE; // Default - - if ((argc < NSTACK_MAIN_MIN_PARA) || (argc > NSTACK_MAIN_MAX_PARA)) - { - NSPOL_LOGERR ("The number of parameters is incorrect"); - return -1; - } - - globalArgc = argc; - g_dpdk_argc = argc; - gArgv = (char **) malloc (sizeof (char *) * argc); - if (gArgv == NULL) - { - NSPOL_LOGERR ("Failed to alloc memory for adjust mem args\n"); - goto ERROR_INIT; - } - - g_dpdk_argv = (char **) malloc (sizeof (char *) * argc); - if (g_dpdk_argv == NULL) - { - NSPOL_LOGERR ("Failed to alloc memory for adjust mem args\n"); - goto ERROR_INIT; - } - - retVal = - MEMSET_S (gArgv, sizeof (char *) * argc, 0, sizeof (char *) * argc); - if (EOK != retVal) - { - NSPOL_LOGERR ("MEMSET_S failed %d.", retVal); - goto ERROR_INIT; - } - retVal = - MEMSET_S (g_dpdk_argv, sizeof (char *) * argc, 0, sizeof (char *) * argc); - if (EOK != retVal) - { - NSPOL_LOGERR ("MEMSET_S failed %d.", retVal); - goto ERROR_INIT; - } - - for (i = 0; i < argc; i++) - { - if (!strcmp ("-m", argv[i]) && !mem_size_parsed && (i + 1 < argc)) - { - gArgv[j] = argv[i]; - g_dpdk_argv[j] = argv[i]; - i++; - j++; - gArgv[j] = (char *) malloc (32); - g_dpdk_argv[j] = (char *) malloc (32); - /* gArgv[j] is NULL and g_dpdk_argv[j] isnot NULL, need free g_dpdk_argv[j] */ - arg_mem_index = j; - if ((!gArgv[j]) || (!g_dpdk_argv[j])) - { - NSPOL_LOGERR ("malloc failed."); - goto ERROR_PARSE_MALLOC; - } - mem_size = atoi (argv[i]); - /* add memory range check,avoid handle wrongly later begin */ - if (mem_size < 0) - { - goto ERROR_PARSE_MALLOC; - } - - j++; - mem_size_parsed = 1; - } - else - if (!strncmp (OPT_EAL_MEM_SIZE, argv[i], strlen (OPT_EAL_MEM_SIZE))) - { - tmp = strdup (argv[i]); - if (tmp == NULL) - { - goto ERROR_PARSE_MALLOC; - } - /* Always use re-entrant functions in multi-threaded environments */ - tmp2 = strtok_r (tmp, "=", &saveptr1); - tmp2 = strtok_r (NULL, "=", &saveptr1); - if (tmp2) - { - eal_mem_size = atoi (tmp2); - /* add memory range check,avoid handle wrongly later */ - if (eal_mem_size < 0) - { - free (tmp); - goto ERROR_PARSE_MALLOC; - } - } - free (tmp); - tmp = NULL; - /*remove this option since dpdk can't recognize it and may cause error. */ - /*so we should deduct the count by 1. */ - globalArgc -= 1; - g_dpdk_argc -= 1; - } - else - { - gArgv[j] = argv[i]; - g_dpdk_argv[j] = argv[i]; - j++; - } - } - - /* -m arg is set */ - if (arg_mem_index >= 0) - { - retVal = - SPRINTF_S (gArgv[arg_mem_index], 32, "%d", mem_size - eal_mem_size); - if (-1 == retVal) - { - NSPOL_LOGERR ("SPRINTF_S failed]ret=%d", retVal); - goto ERROR_PARSE_MALLOC; - } - retVal = SPRINTF_S (g_dpdk_argv[arg_mem_index], 32, "%d", eal_mem_size); - if (-1 == retVal) - { - NSPOL_LOGERR ("SPRINTF_S failed]ret=%d", retVal); - goto ERROR_PARSE_MALLOC; - } - } - else - { - // do nothing for no mem arg and leave it for default process of pal and eal. - } - - return 0; -ERROR_PARSE_MALLOC: - if (arg_mem_index >= 0 && gArgv[arg_mem_index]) - { - free (gArgv[arg_mem_index]); - gArgv[arg_mem_index] = NULL; - } - - if (arg_mem_index >= 0 && g_dpdk_argv[arg_mem_index]) - { - free (g_dpdk_argv[arg_mem_index]); - g_dpdk_argv[arg_mem_index] = NULL; - } - -ERROR_INIT: - if (gArgv) - { - free (gArgv); - gArgv = NULL; - globalArgc = 0; - } - - if (g_dpdk_argv) - { - free (g_dpdk_argv); - g_dpdk_argv = NULL; - g_dpdk_argc = 0; - } - - return -1; -} - -REGIST_MSG_MODULE_FUN (MSG_MODULE_IP, _process_ip_module_msg); - -REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_SPL, SPL_TCPIP_MSG_CALLBACK, - _do_spl_callback_msg); - -REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, - _do_spl_timer_msg); - -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, - TIMER_MSG_TIMEOUT, _do_timeout_handle); - -REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, - TIMER_MSG_CLEAR, _do_clear_timer); |