summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/lwip_stack/lwip_src/common/stackx_pbuf.c')
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_pbuf.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c
new file mode 100644
index 0000000..b1478b8
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c
@@ -0,0 +1,220 @@
+/*
+*
+* 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 "stackx_pbuf.h"
+#include "common_mem_mbuf.h"
+#include "nstack_securec.h"
+#include "nsfw_maintain_api.h"
+#include "stackx_tcp_opt.h"
+#ifdef HAL_LIB
+#else
+#include "rte_memcpy.h"
+#endif
+#include "nsfw_shmem_mng.h"
+/*****************************************************************************
+* Prototype : sbr_malloc_pbuf
+* Description : malloc spl_pbuf,use it in app
+* Input : mpool_handle mp
+* u16 len
+* u32 mbuf_data_size
+* u16 offset
+* Output : None
+* Return Value : struct pbuf*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+struct spl_pbuf *sbr_malloc_pbuf(mpool_handle mp, u16 len, u32 mbuf_data_size,
+ u16 offset)
+{
+ if ((len < offset) || (len > mbuf_data_size))
+ {
+ NSSBR_LOGERR("len is invalid]len=%u", len);
+ return NULL;
+ }
+
+ struct common_mem_mbuf *mbuf = NULL;
+ struct spl_pbuf *buf = NULL;
+
+ mbuf = nsfw_shmem_mbfalloc(mp);
+ if (unlikely(mbuf == NULL))
+ {
+ NS_LOG_CTRL(LOG_CTRL_HUGEPAGE_ALLOC_FAIL, LOGSBR, "NSSBR", NSLOG_WAR,
+ "alloc mbuf failed");
+ return NULL;
+ }
+
+ mbuf->data_len = len;
+ mbuf->next = NULL;
+ mbuf->nb_segs = 1;
+ mbuf->pkt_len = len;
+ buf =
+ (struct spl_pbuf *) ((char *) mbuf + sizeof(struct common_mem_mbuf));
+ res_alloc(&buf->res_chk);
+ buf->next = 0;
+ void *tmp = common_pktmbuf_mtod(mbuf, void *);
+ buf->payload = (void *) (ADDR_LTOSH(tmp) + offset);
+ buf->tot_len = len - offset;
+ buf->len = len - offset;
+ buf->type = SPL_PBUF_HUGE;
+ buf->flags = 0;
+ buf->freeNext = NULL;
+ buf->conn_a = 0;
+ buf->proto_type = SPL_PBUF_PROTO_NONE;
+ NSSBR_LOGDBG("malloc pbuf ok]buf=%p,PRIMARY_ADDR=%p", buf,
+ ADDR_LTOSH(buf));
+ return buf;
+}
+
+u32_t
+spl_pbuf_copy_partial(struct spl_pbuf * buf, void *dataptr, u32_t len,
+ u32_t offset)
+{
+ struct spl_pbuf *p = buf;
+ u32_t buf_copy_len;
+ u32_t copied_total = 0;
+ char *databuf = (char *) dataptr;
+
+ /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+ for (p = buf; len != 0 && p != NULL;
+ p = PTR_SHTOL(struct spl_pbuf *, p->next_a))
+ {
+ if (offset != 0 && offset >= p->len)
+ {
+ /* don't copy from this buffer -> on to the next */
+ offset -= p->len;
+ }
+ else if (p->len - offset > len)
+ {
+ /* copy from this buffer. maybe only partially. */
+ (void) common_memcpy(databuf, ADDR_SHTOL(p->payload_a + offset),
+ len);
+ copied_total += len;
+ break;
+ }
+ else
+ {
+ buf_copy_len = p->len - offset;
+ /* copy the necessary parts of the buffer */
+ (void) common_memcpy(databuf, ADDR_SHTOL(p->payload_a + offset),
+ buf_copy_len);
+
+ copied_total += buf_copy_len;
+ databuf += buf_copy_len;
+ len -= buf_copy_len;
+ offset = 0;
+ }
+ }
+
+ return copied_total;
+}
+
+int spl_tx_force_buf_free(void *data)
+{
+ struct common_mem_mbuf *mbuf = data;
+ if (NULL == mbuf)
+ {
+ return FALSE;
+ }
+
+ struct spl_pbuf *p_buf =
+ (struct spl_pbuf *) (((char *) mbuf) +
+ sizeof(struct common_mem_mbuf));
+ u8 tempflag = p_buf->res_chk.u8Reserve;
+ if ((mbuf->refcnt == 0) || (tempflag & DPDK_SEND_FLAG))
+ {
+ return FALSE;
+ }
+
+ NSFW_LOGINF("free mbuf]%p", data);
+ (void) nsfw_shmem_mbffree((mbuf_handle) mbuf);
+ return TRUE;
+}
+
+int spl_force_buf_free(void *data)
+{
+ struct common_mem_mbuf *mbuf = data;
+
+ if (NULL == mbuf || (mbuf->refcnt == 0))
+ {
+ return FALSE;
+ }
+
+ NSFW_LOGINF("free mbuf]%p", data);
+ (void) nsfw_shmem_mbffree((mbuf_handle) mbuf);
+ return TRUE;
+}
+
+int spl_reg_res_tx_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_tx_force_buf_free
+ };
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}
+
+int spl_reg_res_rxmt_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_tx_force_buf_free
+ }; /*Can use same function for time */
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}
+
+int spl_reg_res_txrx_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_force_buf_free
+ };
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}